Files
010templates/SCP.bt

176 lines
4.0 KiB
Plaintext

//------------------------------------------------
//--- 010 Editor v7.0 Binary Template
//
// File: SCP.bt
// Authors: Vasyl Tsvirkunov
// Natalia Portillo
// Version: 0.3
// Purpose: SuperCard Pro dump file format
// based on official format document.
// Category: Misc
// File Mask: *.scp
// ID Bytes: 53 43 50 //SCP
// History:
// 0.3 2017-12-05 Natalia Portillo: Updated for v1.6 file format
// 0.2 2016-03-29 Vasyl Tsvirkunov: Updated for v7 compliancy
// 0.1 2014-11-08 Vasyl Tsvirkunov: Initial release
//------------------------------------------------
LittleEndian();
char signature[3];
byte version <read=ReadVersion>;
string ReadVersion(byte& v)
{
string s;
SPrintf(s, "%d.%d", v>>4, v&0x0f);
return s;
}
enum <unsigned byte> DiskType
{
disk_C64 = 0x00,
disk_Amiga = 0x04,
disk_AtariFMSS = 0x10,
disk_AtariFMDS = 0x11,
disk_AtariFMEx = 0x12,
disk_AtariSTSS = 0x14,
disk_AtariSTDS = 0x15,
disk_AppleII = 0x20,
disk_AppleIIPro = 0x21,
disk_Apple400K = 0x24,
disk_Apple800K = 0x25,
disk_Apple144 = 0x26,
disk_PC360K = 0x30,
disk_PC720K = 0x31,
disk_PC12M = 0x32,
disk_PC144M = 0x33,
disk_TRS80SSSD = 0x40,
disk_TRS80SSDD = 0x41,
disk_TRS80DSSD = 0x42,
disk_TRS80DSDD = 0x43,
disk_TI994A = 0x50,
disk_D20 = 0x60
};
DiskType disk_type;
byte revolutions;
unsigned byte start_track;
unsigned byte end_track;
unsigned byte flags <read=ReadFlags>;
string ReadFlags(unsigned byte f)
{
string s;
SPrintf(s, "%s, %s, %s, %s, %s, %s",
f & 0x01 ? "flux data starts at index" : "no index reference",
f & 0x02 ? "96TPI" : "48TPI",
f & 0x04 ? "360 RPM" : "300 RPM",
f & 0x08 ? "normalized flux" : "original flux data",
f & 0x10 ? "read/write" : "read only",
f & 0x20 ? "has footer" : "has no footer");
return s;
}
byte cell_width;
byte number_of_heads;
byte reserved;
long checksum;
long track_offset[end_track-start_track+1];
typedef struct
{
long duration;
long cell_count;
long offset;
} RevInfo;
typedef struct
{
char signature[3];
unsigned byte track_num;
RevInfo rev_info[revolutions];
} TrackHeader;
typedef struct
{
BigEndian(); // sic!
if(cell_width == 0 || cell_width == 16)
short flux[track_header.rev_info[rev].cell_count];
else
byte flux[track_header.rev_info[rev].cell_count];
LittleEndian();
} FluxData;
local int track, rev;
for(track=0; track<end_track-start_track+1; track++)
{
FSeek(track_offset[track]);
TrackHeader track_header;
for(rev=0; rev<revolutions; rev++)
{
FSeek(track_offset[track]+track_header.rev_info[rev].offset);
FluxData flux;
}
}
local long timestampPosition = FTell();
local long footerPosition = 0;
wstring ReadPStringUTF8(uint pos)
{
if(pos == 0)
return "";
FSeek(pos);
ushort strLen = ReadUShort();
char str[] = ReadString(pos + 2, strLen);
return StringToWString(str, CHARSET_UTF8);
}
typedef struct
{
uint manufacturer <read=ReadPStringUTF8>;
uint model <read=ReadPStringUTF8>;
uint serial <read=ReadPStringUTF8>;
uint creator <read=ReadPStringUTF8>;
uint application <read=ReadPStringUTF8>;
uint comments <read=ReadPStringUTF8>;
time_t creationTime;
uint ctime_2038;
time_t modificationTime;
uint mtime_2038;
byte applicationVersion <read=ReadVersion>;
byte hardwareVersion <read=ReadVersion>;
byte firmwareVersion <read=ReadVersion>;
byte imageVersion <read=ReadVersion>;
char footerMagic[4];
} Footer;
local uint footerSignature = 0x53435046;
if(flags & 0x20)
{
FSeek(FileSize() - 4);
local int foo;
for(foo = 0;FTell() > timestampPosition; FSkip(-4))
{
local uint sig = ReadUInt();
if(sig == footerSignature)
{
FSkip(-44);
footerPosition = FTell();
Footer footer;
break;
}
}
}
else
{
string timestamp;
}