From 75789de56d474699d4faf9121d1bf3906513af16 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 19 Oct 2023 12:05:53 +0100 Subject: [PATCH] Kryoflux, SCP: Allow number of revolutions to be specified in output eg gw convert a.ipf a.scp::revs=3 --- src/greaseweazle/flux.py | 30 ++++++++++++++++++++++++++++++ src/greaseweazle/image/kryoflux.py | 21 ++++++++++++++++++++- src/greaseweazle/image/scp.py | 19 ++++++++++++++++++- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/greaseweazle/flux.py b/src/greaseweazle/flux.py index a581955b..1575fcd0 100644 --- a/src/greaseweazle/flux.py +++ b/src/greaseweazle/flux.py @@ -85,6 +85,36 @@ def cue_at_index(self) -> None: self.index_cued = True + def set_nr_revs(self, revs:int) -> None: + + self.cue_at_index() + error.check(self.index_list, + 'Need at least one revolution to adjust # revolutions') + + if len(self.index_list) > revs: + self.index_list = self.index_list[:revs] + to_index = sum(self.index_list) + for i in range(len(self.list)): + to_index -= self.list[i] + if to_index < 0: + self.list = self.list[:i] + break + + while len(self.index_list) < revs: + nr = min(revs - len(self.index_list), len(self.index_list)) + to_index = sum(self.index_list[:nr]) + l = self.list + for i in range(len(l)): + to_index -= l[i] + if to_index < 0: + to_index += l[i] + l = l[:i] + break + if self.list: + self.list = l + [to_index + self.list[0]] + self.list[1:] + self.index_list = self.index_list[:nr] + self.index_list + + def flux_for_writeout(self, cue_at_index) -> WriteoutFlux: # Splice at index unless we know better. diff --git a/src/greaseweazle/image/kryoflux.py b/src/greaseweazle/image/kryoflux.py index 2461fba9..cf9c2874 100644 --- a/src/greaseweazle/image/kryoflux.py +++ b/src/greaseweazle/image/kryoflux.py @@ -5,6 +5,8 @@ # This is free and unencumbered software released into the public domain. # See the file COPYING for more details, or visit . +from typing import Optional + import struct, re, math, os, datetime import itertools as it @@ -34,12 +36,14 @@ class OOB: class KFOpts(ImageOpts): """sck: Sample clock to use for flux timings. Suffix 'm' for MHz. For example: sck=72m + revs: Number of revolutions to output per track. """ - w_settings = [ 'sck' ] + w_settings = [ 'sck', 'revs' ] def __init__(self) -> None: self._sck: float = def_sck + self._revs: Optional[int] = None @property def sck(self) -> float: @@ -55,6 +59,18 @@ def sck(self, sck: str): except ValueError: raise error.Fatal("Kryoflux: Bad sck value: '%s'\n" % sck) + @property + def revs(self) -> Optional[int]: + return self._revs + @revs.setter + def revs(self, revs: str) -> None: + try: + self._revs = int(revs) + if self._revs < 1: + raise ValueError + except ValueError: + raise error.Fatal("Kryoflux: Invalid revs: '%s'" % revs) + class KryoFlux(Image): @@ -230,6 +246,9 @@ def emit(f): # So let's give it what it wants. flux.cue_at_index() + if self.opts.revs is not None: + flux.set_nr_revs(self.opts.revs) + factor = sck / flux.sample_freq dat = bytearray() diff --git a/src/greaseweazle/image/scp.py b/src/greaseweazle/image/scp.py index b06ab98b..0d0ab454 100644 --- a/src/greaseweazle/image/scp.py +++ b/src/greaseweazle/image/scp.py @@ -71,13 +71,15 @@ class SCPHeaderFlags(IntFlag): class SCPOpts(ImageOpts): """legacy_ss: Set to True to generate (incorrect) legacy single-sided SCP image. + revs: Number of revolutions to output per track. """ - w_settings = [ 'disktype', 'legacy_ss' ] + w_settings = [ 'disktype', 'legacy_ss', 'revs' ] def __init__(self) -> None: self.legacy_ss = False self._disktype = 0x80 # Other + self._revs: Optional[int] = None @property def disktype(self) -> int: @@ -95,6 +97,18 @@ def disktype(self, disktype): raise error.Fatal("Bad SCP disktype: '%s'\n" % disktype + 'Valid types:\n' + util.columnify(l)) + @property + def revs(self) -> Optional[int]: + return self._revs + @revs.setter + def revs(self, revs: str) -> None: + try: + self._revs = int(revs) + if self._revs < 1: + raise ValueError + except ValueError: + raise error.Fatal("Kryoflux: Invalid revs: '%s'" % revs) + class SCPTrack: @@ -279,6 +293,9 @@ def emit_track(self, cyl: int, side: int, track) -> None: # what they want. flux.cue_at_index() + if self.opts.revs is not None: + flux.set_nr_revs(self.opts.revs) + if not flux.index_cued: self.index_cued = False