# greaseweazle/scp.py # # Written & released by Keir Fraser # # This is free and unencumbered software released into the public domain. # See the file COPYING for more details, or visit . import struct class SCP: # 40MHz sample_freq = 40000000 def __init__(self, start_cyl, nr_sides): self.start_cyl = start_cyl self.nr_sides = nr_sides self.nr_revs = None self.track_list = [] # append_track: # Converts a Flux object into a Supercard Pro Track and appends it to # the current image-in-progress. def append_track(self, flux): nr_revs = len(flux.index_list) - 1 if not self.nr_revs: self.nr_revs = nr_revs else: assert self.nr_revs == nr_revs factor = SCP.sample_freq / flux.sample_freq trknr = self.start_cyl * self.nr_sides + len(self.track_list) tdh = struct.pack("<3sB", b"TRK", trknr) dat = bytearray() len_at_index = rev = 0 to_index = flux.index_list[0] rem = 0.0 for x in flux.list: # Are we processing initial samples before the first revolution? if rev == 0: if to_index >= x: # Discard initial samples to_index -= x continue # Now starting the first full revolution rev = 1 to_index += flux.index_list[rev] # Does the next flux interval cross the index mark? while to_index < x: # Append to the TDH for the previous full revolution tdh += struct.pack(" nr_revs: # We're done: We simply discard any surplus flux samples self.track_list.append((tdh, dat)) return to_index += flux.index_list[rev] # Process the current flux sample into SCP "bitcell" format to_index -= x y = x * factor + rem val = int(round(y)) if (val & 65535) == 0: val += 1 rem = y - val while val >= 65536: dat.append(0) dat.append(0) val -= 65536 dat.append(val>>8) dat.append(val&255) # Header for last track(s) in case we ran out of flux timings. while rev <= nr_revs: tdh += struct.pack("