Skip to content

Instantly share code, notes, and snippets.

@damieng
Last active November 6, 2023 12:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save damieng/8267feab773cd69db7a2c318bf09656e to your computer and use it in GitHub Desktop.
Save damieng/8267feab773cd69db7a2c318bf09656e to your computer and use it in GitHub Desktop.
ImHex pattern for CPC/Spectrum DSK files
#pragma author DamienG
#pragma description Amstrad CPC/PCW, Sinclair ZX Spectrum +3 disk image
#pragma endian little
fn fdcSizeToByteCount(u8 sectorSize) {
return 2 << (sectorSize + 6);
};
fn getSectorDataSize(u8 sector) {
return parent.sectorInfo[sector].sectorDataSize;
};
#define StandardDSK "MV - CPCEMU Disk-File\r\nDisk-Info\r\n"
#define ExtendedDSK "EXTENDED CPC DSK File\r\nDisk-Info\r\n"
enum DataRate : u8 {
Unknown,
SingleOrDoubleDensity,
HighDensity,
ExtendedDensity
};
enum RecordingMode : u8 {
Unknown,
FM,
MFM
};
bitfield FDCStatus1 {
AddressMarkMissing: 1;
WriteProtectedDuringWrite: 1;
IDMissing: 1;
Unused1: 1;
Overrun: 1;
IDCRCError: 1;
Unused2: 1;
EndOfCylinder: 1;
};
bitfield FDCStatus2 {
DataAddressMarkMissing: 1;
BadCylinder: 1;
SectorNotFound: 1;
ScanEqualSatisfied: 1;
WrongCylinderDetected: 1;
DataCRCError: 1;
DataAddressMarkDeleted: 1;
Unused: 1;
};
struct Header {
char fileSignature[34];
char creator[14];
u8 trackCount;
u8 sideCount;
if (fileSignature == StandardDSK)
u16 trackSize;
else
padding[2];
padding[204];
};
struct SectorInfo {
u8 track;
u8 side;
u8 sectorID;
u8 sectorSize [[format("fdcSizeToByteCount")]];
FDCStatus1 fdcStatus1;
FDCStatus2 fdcStatus2;
if (header.fileSignature == ExtendedDSK)
padding[2];
else
u16 actualDataSize;
};
struct SectorData {
u32 data[128];
};
struct TrackInfo {
char trackSignature[13]; // "Track-Info\r\n"
padding[3];
u8 trackNumber;
u8 sideNumber;
if (header.fileSignature == StandardDSK)
padding[2];
else {
DataRate dataRate;
RecordingMode recordingMode;
}
u8 sectorSize [[format("fdcSizeToByteCount")]];
u8 sectorCount;
u8 gap3Length;
u8 fillerByte;
SectorInfo sectorInfo[29];
SectorData sectorData[sectorCount];
};
Header header @ 0x00;
TrackInfo tracks[header.trackCount] @ 0x100;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment