123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- import struct
- from greaseweazle.flux import Flux
- from greaseweazle.bitcell import Bitcell
- from bitarray import bitarray
- class HFE:
- def __init__(self, start_cyl, nr_sides):
- self.start_cyl = start_cyl
- self.nr_sides = nr_sides
- self.bitrate = 250
-
-
- self.track_list = []
- @classmethod
- def from_file(cls, dat):
- (sig, f_rev, nr_cyls, nr_sides, t_enc, bitrate,
- _, _, _, tlut_base) = struct.unpack("<8s4B2H2BH", dat[:20])
- assert sig != b"HXCHFEV3", "HFEv3 is not supported"
- assert sig == b"HXCPICFE" and f_rev <= 1, "Not a valid HFE file"
- assert 0 < nr_cyls
- assert 0 < nr_sides < 3
- assert bitrate != 0
-
- hfe = cls(0, nr_sides)
- hfe.bitrate = bitrate
- tlut = dat[tlut_base*512:tlut_base*512+nr_cyls*4]
-
- for cyl in range(nr_cyls):
- for side in range(nr_sides):
- offset, length = struct.unpack("<2H", tlut[cyl*4:(cyl+1)*4])
- todo = length // 2
- tdat = bytes()
- while todo:
- d_off = offset*512 + side*256
- d_nr = 256 if todo > 256 else todo
- tdat += dat[d_off:d_off+d_nr]
- todo -= d_nr
- offset += 1
- hfe.track_list.append((len(tdat)*8, tdat))
- return hfe
- def get_track(self, cyl, side, writeout=False):
- if side >= self.nr_sides or cyl < self.start_cyl:
- return None
- off = cyl * self.nr_sides + side
- if off >= len(self.track_list):
- return None
- bitlen, rawbytes = self.track_list[off]
- tdat = bitarray(endian='little')
- tdat.frombytes(rawbytes)
- tdat = tdat[:bitlen]
- return Flux.from_bitarray(tdat, self.bitrate * 2000)
- def append_track(self, flux):
- bc = Bitcell()
- bc.clock = 0.0005 / self.bitrate
- bc.from_flux(flux)
- bits = bc.revolution_list[0][0]
- bits.bytereverse()
- self.track_list.append((len(bits), bits.tobytes()))
- def get_image(self):
-
- n_cyl = self.start_cyl + len(self.track_list) // self.nr_sides
- header = struct.pack("<8s4B2H2BH",
- b"HXCPICFE",
- 0,
- n_cyl,
- self.nr_sides,
- 0xff,
- self.bitrate,
- 0,
- 0xff,
- 1,
- 1)
-
- tlut = bytearray()
- tdat = bytearray()
-
- for i in range(self.start_cyl):
- nr_bytes = 100 * self.bitrate
- tlut += struct.pack("<2H", len(tdat)//512 + 2, nr_bytes)
- tdat += bytes([0x88] * (nr_bytes+0x1ff & ~0x1ff))
-
- for i in range(0, len(self.track_list), self.nr_sides):
- bc = [self.track_list[i],
- self.track_list[i+1] if self.nr_sides > 1 else (0,bytes())]
- nr_bytes = max(len(t[1]) for t in bc)
- nr_blocks = (nr_bytes + 0xff) // 0x100
- tlut += struct.pack("<2H", len(tdat)//512 + 2, 2 * nr_bytes)
- for b in range(nr_blocks):
- for t in bc:
- slice = t[1][b*256:(b+1)*256]
- tdat += slice + bytes([0x88] * (256 - len(slice)))
-
- header += bytes([0xff] * (0x200 - len(header)))
- tlut += bytes([0xff] * (0x200 - len(tlut)))
- return header + tlut + tdat
|