ciderpress/diskimg/TwoImg.h

137 lines
4.3 KiB
C++

/*
* CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
/*
* Support for the "2MG"/"2IMG" disk image format.
*
* This gets its own header because CiderPress uses these definitions and
* functions directly.
*/
#ifndef DISKIMG_TWOIMG_H
#define DISKIMG_TWOIMG_H
#include "DiskImg.h"
namespace DiskImgLib {
/*
* 2IMG header definition (was on http://www.magnet.ch/emutech/Tech/,
* now on http://www.a2central.com/programming/filetypes/ftne00130.html
* as filetype $e0/$0130).
*
* Meaning of "flags":
* bit 31 : disk is "locked"; used by emulators as write-protect sticker.
* bit 8 : if set, bits 0-7 specify DOS 3.3 volume number
* bit 0-7: if bit 8 is set, use this as DOS volume; else use 254
*
* All values are stored little-endian.
*/
class DISKIMG_API TwoImgHeader {
public:
TwoImgHeader(void) : fDOSVolumeNum(-1), fComment(NULL), fCreatorChunk(NULL)
{}
virtual ~TwoImgHeader(void) {
delete[] fComment;
delete[] fCreatorChunk;
}
/*
* Header fields.
*/
//char fMagic[4];
//char fCreator[4];
unsigned long fMagic;
unsigned long fCreator;
short fHeaderLen;
short fVersion;
long fImageFormat;
unsigned long fFlags; // may include DOS volume num
long fNumBlocks; // 512-byte blocks
long fDataOffset;
long fDataLen;
long fCmtOffset;
long fCmtLen;
long fCreatorOffset;
long fCreatorLen;
long fSpare[4];
/*
* Related constants.
*/
enum {
// imageFormat
kImageFormatDOS = 0,
kImageFormatProDOS = 1,
kImageFormatNibble = 2,
// flags
kFlagLocked = (1L<<31),
kDOSVolumeSet = (1L<<8),
kDOSVolumeMask = (0xff),
kDefaultVolumeNum = 254,
// constants used when creating a new header
kOurHeaderLen = 64,
kOurVersion = 1,
kBlockSize = 512,
kMagic = 0x32494d47, // 2IMG
kCreatorCiderPress = 0x43647250, // CdrP
kCreatorSweet16 = 0x574f4f46, // WOOF
};
/*
* Basic functions.
*
* The read header function will read the comment, but the write
* header function will not. This is because the GenericFD functions
* don't allow seeking past the current EOF.
*
* ReadHeader/WriteHeader expect the file to be seeked to the initial
* offset. WriteFooter expects the file to be seeked just past the
* end of the data section. This is done in case the file has some
* sort of wrapper outside the 2MG header.
*/
int InitHeader(int imageFormat, long imageSize, long imageBlockCount);
int ReadHeader(FILE* fp, long totalLength);
int ReadHeader(GenericFD* pGFD, long totalLength);
int WriteHeader(FILE* fp) const;
int WriteHeader(GenericFD* pGFD) const;
int WriteFooter(FILE* fp) const;
int WriteFooter(GenericFD* pGFD) const;
void DumpHeader(void) const; // for debugging
/*
* Getters & setters.
*/
const char* GetMagicStr(void) const { return fMagicStr; }
const char* GetCreatorStr(void) const { return fCreatorStr; }
short GetDOSVolumeNum(void) const;
void SetDOSVolumeNum(short dosVolumeNum);
const char* GetComment(void) const { return fComment; }
void SetComment(const char* comment);
const void* GetCreatorChunk(void) const { return fCreatorChunk; }
void SetCreatorChunk(const void* creatorBlock, long len);
private:
int UnpackHeader(const unsigned char* buf, long totalLength);
void PackHeader(unsigned char* buf) const;
int GetChunk(GenericFD* pGFD, di_off_t relOffset, long len,
void** pBuf);
int GetChunk(FILE* fp, di_off_t relOffset, long len,
void** pBuf);
int fDOSVolumeNum;
char fMagicStr[5];
char fCreatorStr[5];
char* fComment;
char* fCreatorChunk;
};
} // namespace DiskImgLib
#endif /*DISKIMG_TWOIMG_H*/