Эх сурвалжийг харах

gw: Add new option --adjust-speed to normalise flux times for
target drive speed.

Keir Fraser 5 жил өмнө
parent
commit
9e3d11f17f
1 өөрчлөгдсөн 31 нэмэгдсэн , 4 устгасан
  1. 31 4
      scripts/gw.py

+ 31 - 4
scripts/gw.py

@@ -147,18 +147,31 @@ def read_to_scp(args):
 # write_from_scp:
 # Writes the specified Supercard Pro image file to floppy disk.
 def write_from_scp(args):
-    factor = usb.sample_freq / scp_freq
+
+    if args.adjust_speed:
+        # @drive_ticks is the time in Gresaeweazle ticks between index pulses.
+        # We will adjust the flux intervals per track to allow for this.
+        usb.read_track(3)
+        index_times = usb.get_index_times(3)
+        drive_ticks = (index_times[1] + index_times[2]) / 2
+    else:
+        # Simple ratio between the Greaseweazle and SCP sample frequencies.
+        factor = usb.sample_freq / scp_freq
+
+    # Parse the SCP image header.
     with open(args.file, "rb") as f:
         dat = f.read()
     header = struct.unpack("<3s9BI", dat[0:16])
     assert header[0] == b"SCP"
     trk_offs = struct.unpack("<168I", dat[16:0x2b0])
+
     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 i in track_range:
         cyl = i >> (nr_sides - 1)
         side = i & (nr_sides - 1)
@@ -166,12 +179,20 @@ def write_from_scp(args):
         if trk_offs[i] == 0:
             continue
         usb.seek(cyl, side)
+
+        # Parse the SCP track header and extract the flux data.
         thdr = struct.unpack("<3sBIII", dat[trk_offs[i]:trk_offs[i]+16])
-        (sig,_,_,samples,off) = thdr
+        (sig,_,track_ticks,samples,off) = thdr
         assert sig == b"TRK"
         tdat = dat[trk_offs[i]+off:trk_offs[i]+off+samples*2]
+
+        # Decode the SCP flux data into a simple list of flux times.
         flux = []
         rem = 0.0
+        if args.adjust_speed:
+            # @factor adjusts flux times for speed variations between the
+            # read-in and write-out drives.
+            factor = drive_ticks / track_ticks
         for i in range(0,len(tdat),2):
             x = tdat[i]*256 + tdat[i+1]
             if x == 0:
@@ -181,15 +202,18 @@ def write_from_scp(args):
             val = int(round(y))
             rem = y - val
             flux.append(val)
+
+        # Encode the flux times for Greaseweazle, and write them out.
         enc_flux = usb.encode_flux(flux)
         for retry in range(1, 5):
             ack = usb.write_track(enc_flux)
             if ack == USB.Ack.Okay:
                 break
-            elif ack == USB.Ack.FluxUnderflow and retry < 5:
+            elif ack == usb.Ack.FLUX_UNDERFLOW and retry < 5:
                 print("Retry #%u..." % (retry))
             else:
                 raise CmdError(ack)
+
     print()
 
 
@@ -254,7 +278,10 @@ def _main(argv):
                         help="first cylinder to read/write")
     parser.add_argument("--ecyl", type=int, default=81,
                         help="last cylinder to read/write")
-    parser.add_argument("--single-sided", action="store_true")
+    parser.add_argument("--single-sided", action="store_true",
+                        help="read/write a single-sided image")
+    parser.add_argument("--adjust-speed", action="store_true",
+                        help="adjust write-flux times for drive speed")
     parser.add_argument("file", help="in/out filename")
     parser.add_argument("device", help="serial device")
     args = parser.parse_args(argv[1:])