|
@@ -20,10 +20,9 @@ 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):
|
|
|
- nr_sides = 1 if args.single_sided else 2
|
|
|
- scp = SCP(args.scyl, nr_sides)
|
|
|
+ scp = SCP(args.scyl, args.nr_sides)
|
|
|
for cyl in range(args.scyl, args.ecyl+1):
|
|
|
- for side in range(0, nr_sides):
|
|
|
+ for side in range(0, args.nr_sides):
|
|
|
print("\rReading Track %u.%u..." % (cyl, side), end="")
|
|
|
usb.seek(cyl, side)
|
|
|
for retry in range(1, 5):
|
|
@@ -55,66 +54,48 @@ def write_from_scp(usb, args):
|
|
|
elif ack != USB.Ack.FluxOverflow or retry >= 5:
|
|
|
raise CmdError(ack)
|
|
|
drive_ticks = (index_list[1] + index_list[2]) / 2
|
|
|
- else:
|
|
|
- # Simple ratio between the Greaseweazle and SCP sample frequencies.
|
|
|
- factor = usb.sample_freq / SCP.sample_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 track in track_range:
|
|
|
- cyl = track >> (nr_sides - 1)
|
|
|
- side = track & (nr_sides - 1)
|
|
|
- print("\rWriting Track %u.%u..." % (cyl, side), end="")
|
|
|
- trk_off = trk_offs[track]
|
|
|
- if trk_off == 0:
|
|
|
- continue
|
|
|
- usb.seek(cyl, side)
|
|
|
-
|
|
|
- # Parse the SCP track header and extract the flux data.
|
|
|
- thdr = struct.unpack("<3sBIII", dat[trk_off:trk_off+16])
|
|
|
- sig, _, track_ticks, samples, off = thdr
|
|
|
- assert sig == b"TRK"
|
|
|
- tdat = dat[trk_off+off:trk_off+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:
|
|
|
- rem += 65536.0
|
|
|
+ scp = SCP.from_file(f.read())
|
|
|
+
|
|
|
+ for cyl in range(args.scyl, args.ecyl+1):
|
|
|
+ for side in range(0, args.nr_sides):
|
|
|
+
|
|
|
+ flux = scp.get_track(cyl, side, writeout=True)
|
|
|
+ if not flux:
|
|
|
continue
|
|
|
- y = x * factor + rem
|
|
|
- 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:
|
|
|
- print("Retry #%u..." % (retry))
|
|
|
+ print("\rWriting Track %u.%u..." % (cyl, side), end="")
|
|
|
+ usb.seek(cyl, side)
|
|
|
+
|
|
|
+ if args.adjust_speed:
|
|
|
+ # @factor adjusts flux times for speed variations between the
|
|
|
+ # read-in and write-out drives.
|
|
|
+ factor = drive_ticks / flux.index_list[0]
|
|
|
else:
|
|
|
- raise CmdError(ack)
|
|
|
+ # Simple ratio between the GW and SCP sample frequencies.
|
|
|
+ factor = usb.sample_freq / flux.sample_freq
|
|
|
+
|
|
|
+ # Convert the flux samples to Greaseweazle sample frequency.
|
|
|
+ rem = 0.0
|
|
|
+ flux_list = []
|
|
|
+ for x in flux.list:
|
|
|
+ y = x * factor + rem
|
|
|
+ val = int(round(y))
|
|
|
+ rem = y - val
|
|
|
+ flux_list.append(val)
|
|
|
+
|
|
|
+ # Encode the flux times for Greaseweazle, and write them out.
|
|
|
+ enc_flux = usb.encode_flux(flux_list)
|
|
|
+ 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:
|
|
|
+ print("Retry #%u..." % (retry))
|
|
|
+ else:
|
|
|
+ raise CmdError(ack)
|
|
|
|
|
|
print()
|
|
|
|
|
@@ -187,6 +168,7 @@ def _main(argv):
|
|
|
parser.add_argument("file", help="in/out filename")
|
|
|
parser.add_argument("device", help="serial device")
|
|
|
args = parser.parse_args(argv[1:])
|
|
|
+ args.nr_sides = 1 if args.single_sided else 2
|
|
|
|
|
|
if not args.action in actions:
|
|
|
print("** Action \"%s\" is not recognised" % args.action)
|