Skip to content

Commit

Permalink
gw write: New option --hard-sectors
Browse files Browse the repository at this point in the history
Allows to write hard-sectored disks in a single pass per track.
Requires new device firmware for an extended WriteFlux command.
  • Loading branch information
keirf committed Sep 27, 2024
1 parent 6865f30 commit 130d887
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
26 changes: 23 additions & 3 deletions src/greaseweazle/tools/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,22 @@ def open_image(args, image_class: Type[image.Image]) -> image.Image:
# Writes the specified image file to floppy disk.
def write_from_image(usb: USB.Unit, args, image: image.Image) -> None:

hard_sector_ticks = 0

# Measure drive RPM.
# We will adjust the flux intervals per track to allow for this.
no_index = args.fake_index is not None
if no_index:
drive_ticks_per_rev = args.fake_index * usb.sample_freq
elif args.hard_sectors:
flux = usb.read_track(revs = 0, ticks = int(usb.sample_freq / 2))
flux.identify_hard_sectors()
assert flux.sector_list is not None # mypy
drive_ticks_per_rev = flux.ticks_per_rev
args.hard_sectors = len(flux.sector_list[-1])
hard_sector_ticks = int(drive_ticks_per_rev / args.hard_sectors)
print(f'Drive reports {args.hard_sectors} hard sectors')
del flux
else:
drive_ticks_per_rev = usb.read_track(2).ticks_per_rev

Expand Down Expand Up @@ -110,7 +121,8 @@ def write_from_image(usb: USB.Unit, args, image: image.Image) -> None:
print(s)
usb.write_track(flux_list = wflux_list,
cue_at_index = wflux.index_cued,
terminate_at_index = wflux.terminate_at_index)
terminate_at_index = wflux.terminate_at_index,
hard_sector_ticks = hard_sector_ticks)
verify: Optional[HasVerify] = None
no_verify = (args.no_verify
or not isinstance(track, MasterTrack)
Expand All @@ -124,6 +136,9 @@ def write_from_image(usb: USB.Unit, args, image: image.Image) -> None:
if isinstance(v_revs, float):
v_ticks = int(drive_ticks_per_rev * v_revs)
v_revs = 2
if args.hard_sectors:
v_ticks = 0
v_revs = cast(int, (args.hard_sectors + 1) * 2)
if no_index:
drive_tpr = int(drive_ticks_per_rev)
pre_index = int(usb.sample_freq * 0.5e-3)
Expand All @@ -139,6 +154,8 @@ def write_from_image(usb: USB.Unit, args, image: image.Image) -> None:
v_flux._ticks_per_rev = drive_ticks_per_rev
if args.reverse:
v_flux.reverse()
if args.hard_sectors:
v_flux.identify_hard_sectors()
verified = verify.verify_track(v_flux)
if verified:
verified_count += 1
Expand Down Expand Up @@ -209,8 +226,11 @@ def main(argv) -> None:
help="erase tracks before writing (default: no)")
parser.add_argument("--erase-empty", action="store_true",
help="erase empty tracks (default: skip)")
parser.add_argument("--fake-index", type=util.period, metavar="SPEED",
help="fake index pulses at SPEED")
index_group = parser.add_mutually_exclusive_group(required=False)
index_group.add_argument("--fake-index", type=util.period, metavar="SPEED",
help="fake index pulses at SPEED")
index_group.add_argument("--hard-sectors", action="store_true",
help="write to a hard-sectored disk")
parser.add_argument("--no-verify", action="store_true",
help="disable verify")
parser.add_argument("--retries", type=util.uint, default=3, metavar="N",
Expand Down
15 changes: 11 additions & 4 deletions src/greaseweazle/usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,8 @@ def read_track(self, revs:int, ticks:int=0, nr_retries:int=5) -> Flux:
## write_track:
## Write the given flux stream to the current track via Greaseweazle.
def write_track(self, flux_list, terminate_at_index,
cue_at_index=True, nr_retries=5) -> None:
cue_at_index=True, nr_retries=5,
hard_sector_ticks=0) -> None:

# Create encoded data stream.
dat = self._encode_flux(flux_list)
Expand All @@ -500,9 +501,15 @@ def write_track(self, flux_list, terminate_at_index,
while True:
try:
# Write the flux stream to the track via Greaseweazle.
self._send_cmd(struct.pack("4B", Cmd.WriteFlux, 4,
int(cue_at_index),
int(terminate_at_index)))
if hard_sector_ticks != 0:
self._send_cmd(struct.pack("4BI", Cmd.WriteFlux, 8,
int(cue_at_index),
int(terminate_at_index),
hard_sector_ticks))
else:
self._send_cmd(struct.pack("4B", Cmd.WriteFlux, 4,
int(cue_at_index),
int(terminate_at_index)))
self.ser.write(dat)
self.ser.read(1) # Sync with Greaseweazle
self._send_cmd(struct.pack("2B", Cmd.GetFluxStatus, 2))
Expand Down

0 comments on commit 130d887

Please sign in to comment.