| 
					
				 | 
			
			
				@@ -15,135 +15,30 @@ from greaseweazle import version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from greaseweazle import USB 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from greaseweazle.bitcell import Bitcell 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from greaseweazle.flux import Flux 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 40MHz 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-scp_freq = 40000000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# flux_to_scp: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# Converts Greaseweazle flux samples into a Supercard Pro Track. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# Returns the Track Data Header (TDH) and the SCP "bitcell" array. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-def flux_to_scp(flux, track, nr_revs): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    factor = scp_freq / flux.sample_freq 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    tdh = struct.pack("<3sB", b"TRK", track) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    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 Track Data Header for the previous full revolution 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            tdh += struct.pack("<III", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                               int(round(flux.index_list[rev]*factor)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                               (len(dat) - len_at_index) // 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                               4 + nr_revs*12 + len_at_index) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            # Set up for the next revolution 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            len_at_index = len(dat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            rev += 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if rev > nr_revs: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                # We're done: We simply discard any surplus flux samples 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return tdh, dat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            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("<III", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           int(round(flux.index_list[rev]*factor)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           (len(dat) - len_at_index) // 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           4 + nr_revs*12 + len_at_index) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        len_at_index = len(dat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        rev += 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return tdh, dat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+from greaseweazle.scp import SCP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # read_to_scp: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # Reads a floppy disk and dumps it into a new Supercard Pro image file. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 def read_to_scp(usb, args): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    trk_dat = bytearray() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    trk_offs = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if args.single_sided: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        track_range = range(args.scyl, args.ecyl+1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        nr_sides = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        track_range = range(args.scyl*2, (args.ecyl+1)*2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        nr_sides = 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for track in track_range: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cyl = track >> (nr_sides - 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        side = track & (nr_sides - 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print("\rReading Track %u.%u..." % (cyl, side), end="") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        trk_offs.append(len(trk_dat)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        usb.seek(cyl, side) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for retry in range(1, 5): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ack, index_list, enc_flux = usb.read_track(args.revs+1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if ack == USB.Ack.Okay: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            elif ack == USB.Ack.FluxOverflow and retry < 5: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print("Retry #%u..." % (retry)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                raise CmdError(ack) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        flux = Flux(index_list, usb.decode_flux(enc_flux), usb.sample_freq) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tdh, dat = flux_to_scp(flux, track, args.revs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        trk_dat += tdh 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        trk_dat += dat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    nr_sides = 1 if args.single_sided else 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    scp = SCP(args.scyl, nr_sides) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for cyl in range(args.scyl, args.ecyl+1): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for side in range(0, nr_sides): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            print("\rReading Track %u.%u..." % (cyl, side), end="") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            usb.seek(cyl, side) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for retry in range(1, 5): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ack, index_list, enc_flux = usb.read_track(args.revs+1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if ack == USB.Ack.Okay: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                elif ack == USB.Ack.FluxOverflow and retry < 5: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    print("Retry #%u..." % (retry)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    raise CmdError(ack) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            flux = Flux(index_list, usb.decode_flux(enc_flux), usb.sample_freq) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            scp.append_track(flux) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     print() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    csum = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for x in trk_dat: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        csum += x 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    trk_offs_dat = bytearray() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for x in trk_offs: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        trk_offs_dat += struct.pack("<I", 0x2b0 + x) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    trk_offs_dat += bytes(0x2a0 - len(trk_offs_dat)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for x in trk_offs_dat: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        csum += x 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ds_flag = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if args.single_sided: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ds_flag = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    header_dat = struct.pack("<3s9BI", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             b"SCP",    # Signature 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             0,         # Version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             0x80,      # DiskType = Other 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             args.revs, # Nr Revolutions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             track_range.start, # Start track 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             track_range.stop-1, # End track 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             0x01,      # Flags = Index 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             0,         # 16-bit cell width 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             ds_flag,   # Double Sided 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             0,         # 25ns capture 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             csum & 0xffffffff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     with open(args.file, "wb") as f: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        f.write(header_dat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        f.write(trk_offs_dat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        f.write(trk_dat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        f.write(scp.get_image()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # write_from_scp: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -162,7 +57,7 @@ def write_from_scp(usb, args): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         drive_ticks = (index_list[1] + index_list[2]) / 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Simple ratio between the Greaseweazle and SCP sample frequencies. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        factor = usb.sample_freq / scp_freq 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        factor = usb.sample_freq / SCP.sample_freq 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     # Parse the SCP image header. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     with open(args.file, "rb") as f: 
			 |