qasm/diskimg/TwoImg.h
2023-02-04 15:34:50 -08:00

155 lines
4.6 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) :
fMagic(0),
fCreator(0),
fHeaderLen(0),
fVersion(0),
fImageFormat(0),
fFlags(0),
fNumBlocks(0),
fDataOffset(0),
fDataLen(0),
fCmtOffset(0),
fCmtLen(0),
fCreatorOffset(0),
fCreatorLen(0),
fSpare(),
fDOSVolumeNum(-1),
fMagicStr(),
fCreatorStr(),
fComment(NULL),
fCreatorChunk(NULL)
{}
virtual ~TwoImgHeader(void) {
delete[] fComment;
delete[] fCreatorChunk;
}
/*
* Header fields.
*/
//char fMagic[4];
//char fCreator[4];
uint32_t fMagic;
uint32_t fCreator;
uint16_t fHeaderLen;
uint16_t fVersion;
uint32_t fImageFormat;
uint32_t fFlags; // may include DOS volume num
uint32_t fNumBlocks; // 512-byte blocks
uint32_t fDataOffset;
uint32_t fDataLen;
uint32_t fCmtOffset;
uint32_t fCmtLen;
uint32_t fCreatorOffset;
uint32_t fCreatorLen;
uint32_t 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, uint32_t imageSize, uint32_t imageBlockCount);
int ReadHeader(FILE* fp, uint32_t totalLength);
int ReadHeader(GenericFD* pGFD, uint32_t 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; }
int16_t 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 uint8_t* buf, uint32_t totalLength);
void PackHeader(uint8_t* 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);
int16_t fDOSVolumeNum; // 8-bit volume number, or -1
char fMagicStr[5];
char fCreatorStr[5];
char* fComment;
char* fCreatorChunk;
};
} // namespace DiskImgLib
#endif /*DISKIMG_TWOIMG_H*/