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

gw: Condense cyl/side/step cmdline arguments into 'tracks' arg.

Keir Fraser 4 жил өмнө
parent
commit
c0f3074f2e

+ 7 - 10
scripts/greaseweazle/tools/erase.py

@@ -22,10 +22,10 @@ def erase(usb, args):
     drive_ticks = (flux.index_list[0] + flux.index_list[1]) / 2
     del flux
 
-    for cyl in range(args.scyl, args.ecyl+1):
-        for side in range(0, args.nr_sides):
+    for cyl in range(args.tracks.cyl[0], args.tracks.cyl[1]+1):
+        for side in range(args.tracks.side[0], args.tracks.side[1]+1):
             print("\rErasing Track %u.%u..." % (cyl, side), end="")
-            usb.seek(cyl, side)
+            usb.seek((cyl, cyl*2)[args.tracks.double_step], side)
             usb.erase_track(drive_ticks * 1.1)
 
     print()
@@ -37,19 +37,16 @@ def main(argv):
     parser.add_argument("--device", help="greaseweazle device name")
     parser.add_argument("--drive", type=util.drive_letter, default='A',
                         help="drive to write (A,B,0,1,2)")
-    parser.add_argument("--scyl", type=int, default=0,
-                        help="first cylinder to write")
-    parser.add_argument("--ecyl", type=int, default=81,
-                        help="last cylinder to write")
-    parser.add_argument("--single-sided", action="store_true",
-                        help="single-sided write")
+    parser.add_argument("--tracks", type=util.trackset,
+                        default='c=0-81:s=0-1',
+                        help="which tracks to read")
     parser.description = description
     parser.prog += ' ' + argv[1]
     args = parser.parse_args(argv[2:])
-    args.nr_sides = 1 if args.single_sided else 2
 
     try:
         usb = util.usb_open(args.device)
+        print("Erasing %s" % (args.tracks))
         util.with_drive_selected(erase, usb, args)
     except USB.CmdError as error:
         print("Command Failed: %s" % error)

+ 15 - 29
scripts/greaseweazle/tools/read.py

@@ -81,14 +81,14 @@ def read_with_retry(usb, args, cyl, side, decoder):
 
 
 def print_summary(args, summary):
-    print("H. S: Cyls %d-%d -->" % (args.scyl, args.ecyl))
+    print("H. S: Cyls %d-%d -->" % args.tracks.cyl)
     tot_sec = good_sec = 0
-    for side in range(0, args.nr_sides):
+    for side in range(args.tracks.side[0], args.tracks.side[1]+1):
         nsec = max(x.nsec for x in summary[side])
         for sec in range(nsec):
             print("%d.%2d: " % (side, sec), end="")
-            for cyl in range(args.scyl, args.ecyl+1):
-                s = summary[side][cyl-args.scyl]
+            for cyl in range(args.tracks.cyl[0], args.tracks.cyl[1]+1):
+                s = summary[side][cyl-args.tracks.cyl[0]]
                 if sec > s.nsec:
                     print(" ", end="")
                 else:
@@ -106,9 +106,9 @@ def read_to_image(usb, args, image, decoder=None):
 
     summary = [[],[]]
 
-    for cyl in range(args.scyl, args.ecyl+1):
-        for side in range(0, args.nr_sides):
-            usb.seek((cyl, cyl*2)[args.double_step], side)
+    for cyl in range(args.tracks.cyl[0], args.tracks.cyl[1]+1):
+        for side in range(args.tracks.side[0], args.tracks.side[1]+1):
+            usb.seek((cyl, cyl*2)[args.tracks.double_step], side)
             dat = read_with_retry(usb, args, cyl, side, decoder)
             print("T%u.%u: %s" % (cyl, side, dat.summary_string()))
             summary[side].append(dat)
@@ -118,11 +118,6 @@ def read_to_image(usb, args, image, decoder=None):
         print_summary(args, summary)
 
 
-def range_str(s, e):
-    str = "%d" % s
-    if s != e: str += "-%d" % e
-    return str
-
 def main(argv):
 
     parser = util.ArgumentParser(usage='%(prog)s [options] file')
@@ -132,21 +127,14 @@ def main(argv):
     parser.add_argument("--format", help="disk format")
     parser.add_argument("--revs", type=int,
                         help="number of revolutions to read per track")
-    parser.add_argument("--scyl", type=int,
-                        help="first cylinder to read")
-    parser.add_argument("--ecyl", type=int,
-                        help="last cylinder to read")
-    parser.add_argument("--single-sided", action="store_true",
-                        help="single-sided read")
-    parser.add_argument("--double-step", action="store_true",
-                        help="double-step drive heads")
+    parser.add_argument("--tracks", type=util.trackset,
+                        help="which tracks to read")
     parser.add_argument("--rate", type=int, help="data rate (kbit/s)")
     parser.add_argument("--rpm", type=int, help="convert drive speed to RPM")
     parser.add_argument("file", help="output filename")
     parser.description = description
     parser.prog += ' ' + argv[1]
     args = parser.parse_args(argv[2:])
-    args.nr_sides = 1 if args.single_sided else 2
 
     args.file, args.file_opts = util.split_opts(args.file)
 
@@ -163,16 +151,14 @@ def main(argv):
                 decoder = mod.decode_track
             except (ModuleNotFoundError, AttributeError) as ex:
                 raise error.Fatal("Unknown format '%s'" % args.format) from ex
-            if args.scyl is None: args.scyl = mod.default_cyls[0]
-            if args.ecyl is None: args.ecyl = mod.default_cyls[1]
+            if args.tracks is None:
+                args.tracks = util.trackset('c=0-81:s=0-1')
+                args.tracks.cyl = mod.default_cyls
             if args.revs is None: args.revs = mod.default_revs
-        if args.scyl is None: args.scyl = 0
-        if args.ecyl is None: args.ecyl = 81
+        if args.tracks is None:
+            args.tracks = util.trackset('c=0-81:s=0-1')
         if args.revs is None: args.revs = 3
-        print("Reading c=%s s=%s revs=%d" %
-              (range_str(args.scyl, args.ecyl),
-               range_str(0, args.nr_sides-1),
-               args.revs))
+        print("Reading %s revs=%d" % (args.tracks, args.revs))
         with open_image(args, image_class) as image:
             util.with_drive_selected(read_to_image, usb, args, image,
                                      decoder=decoder)

+ 39 - 1
scripts/greaseweazle/tools/util.py

@@ -7,7 +7,7 @@
 # This is free and unencumbered software released into the public domain.
 # See the file COPYING for more details, or visit <http://unlicense.org>.
 
-import argparse, os, sys, serial, struct, time
+import argparse, os, sys, serial, struct, time, re
 import importlib
 import serial.tools.list_ports
 
@@ -46,6 +46,44 @@ def drive_letter(letter):
         raise argparse.ArgumentTypeError("invalid drive letter: '%s'" % letter)
     return types[letter.upper()]
 
+def range_str(s, e):
+    str = "%d" % s
+    if s != e: str += "-%d" % e
+    return str
+
+def trackset(tracks):
+    class TrackSet:
+        def __init__(self):
+            self.cyl = (0,79)
+            self.side = (0,1)
+            self.double_step = False
+        def __str__(self):
+            s = 'c=%s' % range_str(self.cyl[0], self.cyl[1])
+            if self.double_step:
+                s += 'x2'
+            s += ':s=%s' % range_str(self.side[0], self.side[1])
+            return s
+    ts = TrackSet()
+    for x in tracks.split(':'):
+        k,v = x.split('=')
+        if k == 'c':
+            m = re.match('(\d+)(-(\d+))?(x2)?', v)
+            if m is None: raise ValueError()
+            if m.group(3) is None:
+                ts.cyl = int(m.group(1)), int(m.group(1))
+            else:
+                ts.cyl = int(m.group(1)), int(m.group(3))
+            if m.group(4) is not None:
+                ts.double_step = True
+        elif k == 's':
+            m = re.match('(\d+)(-(\d+))?', v)
+            if m is None: raise ValueError()
+            if m.group(3) is None:
+                ts.side = int(m.group(1)), int(m.group(1))
+            else:
+                ts.side = int(m.group(1)), int(m.group(3))
+    return ts
+
 
 def split_opts(seq):
     """Splits a name from its list of options."""

+ 7 - 12
scripts/greaseweazle/tools/write.py

@@ -44,8 +44,8 @@ def write_from_image(usb, args, image):
 
     verified_count, not_verified_count = 0, 0
 
-    for cyl in range(args.scyl, args.ecyl+1):
-        for side in range(0, args.nr_sides):
+    for cyl in range(args.tracks.cyl[0], args.tracks.cyl[1]+1):
+        for side in range(args.tracks.side[0], args.tracks.side[1]+1):
 
             track = image.get_track(cyl, side)
             if track is None and not args.erase_empty:
@@ -54,7 +54,7 @@ def write_from_image(usb, args, image):
             print("\r%sing Track %u.%u..." %
                   ("Writ" if track is not None else "Eras", cyl, side),
                   end="", flush=True)
-            usb.seek((cyl, cyl*2)[args.double_step], side)
+            usb.seek((cyl, cyl*2)[args.tracks.double_step], side)
             
             if track is None:
                 usb.erase_track(drive_ticks * 1.1)
@@ -119,14 +119,9 @@ def main(argv):
     parser.add_argument("--device", help="greaseweazle device name")
     parser.add_argument("--drive", type=util.drive_letter, default='A',
                         help="drive to write (A,B,0,1,2)")
-    parser.add_argument("--scyl", type=int, default=0,
-                        help="first cylinder to write")
-    parser.add_argument("--ecyl", type=int, default=81,
-                        help="last cylinder to write")
-    parser.add_argument("--single-sided", action="store_true",
-                        help="single-sided write")
-    parser.add_argument("--double-step", action="store_true",
-                        help="double-step drive heads")
+    parser.add_argument("--tracks", type=util.trackset,
+                        default='c=0-81:s=0-1',
+                        help="which tracks to read")
     parser.add_argument("--erase-empty", action="store_true",
                         help="erase empty tracks (default: skip)")
     parser.add_argument("--no-verify", action="store_true",
@@ -135,11 +130,11 @@ def main(argv):
     parser.description = description
     parser.prog += ' ' + argv[1]
     args = parser.parse_args(argv[2:])
-    args.nr_sides = 1 if args.single_sided else 2
 
     try:
         usb = util.usb_open(args.device)
         image = open_image(args)
+        print("Writing %s" % (args.tracks))
         util.with_drive_selected(write_from_image, usb, args, image)
     except USB.CmdError as error:
         print("Command Failed: %s" % error)