@@ -147,31 +147,52 @@ def read_to_scp(args):
147147# write_from_scp:
148148# Writes the specified Supercard Pro image file to floppy disk.
149149def write_from_scp (args ):
150- factor = usb .sample_freq / scp_freq
150+
151+ if args .adjust_speed :
152+ # @drive_ticks is the time in Gresaeweazle ticks between index pulses.
153+ # We will adjust the flux intervals per track to allow for this.
154+ usb .read_track (3 )
155+ index_times = usb .get_index_times (3 )
156+ drive_ticks = (index_times [1 ] + index_times [2 ]) / 2
157+ else :
158+ # Simple ratio between the Greaseweazle and SCP sample frequencies.
159+ factor = usb .sample_freq / scp_freq
160+
161+ # Parse the SCP image header.
151162 with open (args .file , "rb" ) as f :
152163 dat = f .read ()
153164 header = struct .unpack ("<3s9BI" , dat [0 :16 ])
154165 assert header [0 ] == b"SCP"
155166 trk_offs = struct .unpack ("<168I" , dat [16 :0x2b0 ])
167+
156168 if args .single_sided :
157169 track_range = range (args .scyl , args .ecyl + 1 )
158170 nr_sides = 1
159171 else :
160172 track_range = range (args .scyl * 2 , (args .ecyl + 1 )* 2 )
161173 nr_sides = 2
174+
162175 for i in track_range :
163176 cyl = i >> (nr_sides - 1 )
164177 side = i & (nr_sides - 1 )
165178 print ("\r Writing Track %u.%u..." % (cyl , side ), end = "" )
166179 if trk_offs [i ] == 0 :
167180 continue
168181 usb .seek (cyl , side )
182+
183+ # Parse the SCP track header and extract the flux data.
169184 thdr = struct .unpack ("<3sBIII" , dat [trk_offs [i ]:trk_offs [i ]+ 16 ])
170- (sig ,_ ,_ ,samples ,off ) = thdr
185+ (sig ,_ ,track_ticks ,samples ,off ) = thdr
171186 assert sig == b"TRK"
172187 tdat = dat [trk_offs [i ]+ off :trk_offs [i ]+ off + samples * 2 ]
188+
189+ # Decode the SCP flux data into a simple list of flux times.
173190 flux = []
174191 rem = 0.0
192+ if args .adjust_speed :
193+ # @factor adjusts flux times for speed variations between the
194+ # read-in and write-out drives.
195+ factor = drive_ticks / track_ticks
175196 for i in range (0 ,len (tdat ),2 ):
176197 x = tdat [i ]* 256 + tdat [i + 1 ]
177198 if x == 0 :
@@ -181,15 +202,18 @@ def write_from_scp(args):
181202 val = int (round (y ))
182203 rem = y - val
183204 flux .append (val )
205+
206+ # Encode the flux times for Greaseweazle, and write them out.
184207 enc_flux = usb .encode_flux (flux )
185208 for retry in range (1 , 5 ):
186209 ack = usb .write_track (enc_flux )
187210 if ack == USB .Ack .Okay :
188211 break
189- elif ack == USB .Ack .FluxUnderflow and retry < 5 :
212+ elif ack == usb .Ack .FLUX_UNDERFLOW and retry < 5 :
190213 print ("Retry #%u..." % (retry ))
191214 else :
192215 raise CmdError (ack )
216+
193217 print ()
194218
195219
@@ -254,7 +278,10 @@ def _main(argv):
254278 help = "first cylinder to read/write" )
255279 parser .add_argument ("--ecyl" , type = int , default = 81 ,
256280 help = "last cylinder to read/write" )
257- parser .add_argument ("--single-sided" , action = "store_true" )
281+ parser .add_argument ("--single-sided" , action = "store_true" ,
282+ help = "read/write a single-sided image" )
283+ parser .add_argument ("--adjust-speed" , action = "store_true" ,
284+ help = "adjust write-flux times for drive speed" )
258285 parser .add_argument ("file" , help = "in/out filename" )
259286 parser .add_argument ("device" , help = "serial device" )
260287 args = parser .parse_args (argv [1 :])
0 commit comments