flashfloppy/scripts/edsk.py

106 lines
3.4 KiB
Python

# edsk.py
#
# Dump interesting per-sector info about an EDSK file
#
# Written & released by Keir Fraser <keir.xen@gmail.com>
#
# This is free and unencumbered software released into the public domain.
# See the file COPYING for more details, or visit <http://unlicense.org>.
import struct, sys, binascii
def main(argv):
in_f = open(argv[1], "rb")
in_dat = in_f.read()
in_len = len(in_dat)
x = struct.unpack("<34s14sBBH", in_dat[:52])
tracks = int(x[2])
sides = int(x[3])
tsz = in_dat[52:256]
populated = 0
ext = False
if x[0].startswith(b"EXTENDED CPC DSK File\r\nDisk-Info\r\n"):
print("Extended DSK")
ext = True
else:
assert x[0].startswith(b"MV - CPCEMU")
print("Standard DSK")
while tsz:
x = struct.unpack("B", tsz[:1])
if int(x[0]) != 0:
populated += 1
tsz = tsz[1:]
print("%u cylinders, %u sides, %u non-empty tracks"
% (tracks, sides, populated))
in_dat = in_dat[256:]
while True:
if not in_dat:
break
x = struct.unpack("<10s", in_dat[:10])
if x[0] != b'Track-Info':
in_dat = in_dat[256:]
continue
(track, side) = struct.unpack("BB", in_dat[16:18])
(n, nr, gap, filler) = struct.unpack("BBBB", in_dat[20:24])
print("T%u.%u: N=%u nr=%u gap=%u fill=%x"
% (track, side, n, nr, gap, filler))
sinfo = in_dat[24:256]
in_dat = in_dat[256:]
tot_dlen = 0
while sinfo and nr != 0:
(c,h,r,n,s1,s2,alen) = struct.unpack("<BBBBBBH", sinfo[:8])
if not ext:
alen = 128<<n
sdat = in_dat[:alen]
in_dat = in_dat[alen:]
tot_dlen += alen
special = []
_s1 = s1
_s2 = s2
_n = n
if _n > 8:
_n = 8
nsz = 128 << _n
if s2 & 0x01:
special += ['DAM Missing']
elif s1 & 0x01:
special += ['IDAM Missing']
s1 &= ~0x01
s2 &= ~0x01
if s1 & 0x20:
if s2 & 0x20:
special += ['Data CRC']
else:
special += ['ID CRC']
s1 &= ~0x20
s2 &= ~0x20
if s2 & 0x40:
special += ['DDAM']
s2 &= ~0x40
if s1 or s2:
special += ['XXXX-UNKNOWN']
if alen < nsz:
if alen % 0x80 == 0:
special += ['Incomplete']
else:
special += ['Small GAPS']
elif alen > nsz:
if alen % nsz == 0:
special += ['Weak (%u)' % (alen / nsz)]
else:
special += ['Large GAPS']
if alen % 0x80 != 0 and alen >= 13:
remainder = bytearray(sdat[-13:])
if remainder[0] != 0 and all([v == 0 for v in remainder[1:]]):
special += ["Pre-Sync??"]
print(" %u.%u id=%u n=%u(%u) stat=%02x:%02x %u crc=%08x\t"
% (c,h,r,n,nsz,_s1,_s2,alen,binascii.crc32(sdat)&0xffffffff)
+ str(special))
# print(binascii.hexlify(sdat))
sinfo = sinfo[8:]
nr -= 1
if tot_dlen % 256 != 0:
in_dat = in_dat[256 - (tot_dlen % 256) : ]
if __name__ == "__main__":
main(sys.argv)