Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

D88: Add read support for multiple disks in one file. #362

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/greaseweazle/image/a2r.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def process_rwcp(self, dat: bytes) -> None:


@classmethod
def from_file(cls, name: str, _fmt) -> Image:
def from_file(cls, name: str, _fmt, _index: int = -1) -> Image:

splices = None

Expand Down
2 changes: 1 addition & 1 deletion src/greaseweazle/image/caps.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def get_track(self, cyl: int, head: int) -> Optional[MasterTrack]:
raise NotImplementedError

@classmethod
def from_file(cls, name: str, _fmt) -> Image:
def from_file(cls, name: str, _fmt, _index = -1) -> Image:

caps = cls()
errprefix = f'CAPS: {cls.imagetype}'
Expand Down
3 changes: 2 additions & 1 deletion src/greaseweazle/image/d64.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ def get_disk_id(self):
return disk_id

@classmethod
def from_file(cls, name: str, fmt: Optional[codec.DiskDef]) -> Image:
def from_file(cls, name: str, fmt: Optional[codec.DiskDef],
_index: int = -1) -> Image:
img = super().from_file(name, fmt)
assert isinstance(img, D64)
disk_id = img.get_disk_id()
Expand Down
33 changes: 26 additions & 7 deletions src/greaseweazle/image/d88.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,32 @@ def remove_duplicate_sectors(secs) -> List[Tuple[int,int,int,int,bytes]]:
return new_secs

@classmethod
def from_file(cls, name: str, _fmt) -> Image:
def from_file(cls, name: str, _fmt, index: int = -1) -> Image:

with open(name, "rb") as f:
f.seek(0, os.SEEK_END)
file_size = f.tell()
f.seek(0)
disk_offsets: List[int] = []
current_disk_index = 0
while 1:
disk_offsets.append(f.tell())
header = struct.unpack('<16sB9xBBL', f.read(32))
_, _, _, _, disk_size = header
if f.tell() + disk_size >= file_size:
break
f.seek(disk_offsets[current_disk_index] + disk_size)
current_disk_index += 1

if index < 0 and len(disk_offsets) > 1:
print('D88: Warning: Multiple disks found in image, '
'only using first.')
index = 0
if index >= len(disk_offsets):
raise error.Fatal("D88: No disk with index %d in image file."
% index)

f.seek(disk_offsets[index])
header = struct.unpack('<16sB9xBBL', f.read(32))
disk_name, terminator, write_prot, media_flag, disk_size = header
track_table = [x[0] for x in struct.iter_unpack('<L', f.read(640))]
Expand All @@ -47,18 +70,14 @@ def from_file(cls, name: str, _fmt) -> Image:
struct.iter_unpack('<L', f.read(16))])
elif track_table[0] != 672:
raise error.Fatal("D88: Unsupported track table length.")
f.seek(0, os.SEEK_END)
if f.tell() != disk_size:
print('D88: Warning: Multiple disks found in image, '
'only using first.')

d88 = cls(name)

for track_index, track_offset in enumerate(track_table):
if track_offset == 0:
continue
f.seek(track_offset)
if f.tell() >= disk_size:
f.seek(disk_offsets[index] + track_offset)
if f.tell() >= disk_offsets[index] + disk_size:
continue
cyl = track_index // 2
head = track_index % 2
Expand Down
2 changes: 1 addition & 1 deletion src/greaseweazle/image/dsk.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
class DSK(IMG):

@classmethod
def from_file(cls, name: str, fmt) -> Image:
def from_file(cls, name: str, fmt, _index: int = -1) -> Image:

with open(name, "rb") as f:
sig = f.read(16)
Expand Down
2 changes: 1 addition & 1 deletion src/greaseweazle/image/edsk.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ def addcrc(t,n):
return track

@classmethod
def from_file(cls, name: str, _fmt) -> Image:
def from_file(cls, name: str, _fmt, _index = -1) -> Image:

with open(name, "rb") as f:
dat = f.read()
Expand Down
2 changes: 1 addition & 1 deletion src/greaseweazle/image/hfe.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def __init__(self) -> None:


@classmethod
def from_file(cls, name: str, _fmt):
def from_file(cls, name: str, _fmt, _index = -1):

with open(name, "rb") as f:
dat = f.read()
Expand Down
3 changes: 2 additions & 1 deletion src/greaseweazle/image/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ def max_cylinder(self):

## Read support:
@classmethod
def from_file(cls, name: str, fmt: Optional[codec.DiskDef]) -> Image:
def from_file(cls, name: str, fmt: Optional[codec.DiskDef],
index: int = -1) -> Image:
raise NotImplementedError

def get_track(self, cyl: int, side: int) -> Optional[HasFlux]:
Expand Down
2 changes: 1 addition & 1 deletion src/greaseweazle/image/imd.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __init__(self, name: str, noclobber=False):


@classmethod
def from_file(cls, name: str, _fmt) -> Image:
def from_file(cls, name: str, _fmt, _index = -1) -> Image:

with open(name, "rb") as f:
dat = f.read()
Expand Down
2 changes: 1 addition & 1 deletion src/greaseweazle/image/img.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def track_list(self):


@classmethod
def from_file(cls, name: str, fmt: Optional[codec.DiskDef]) -> Image:
def from_file(cls, name: str, fmt: Optional[codec.DiskDef], _index: int = -1) -> Image:

with open(name, "rb") as f:
dat = f.read()
Expand Down
2 changes: 1 addition & 1 deletion src/greaseweazle/image/kryoflux.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def to_file(cls, name, fmt, noclobber):
return kf

@classmethod
def from_file(cls, name, _fmt):
def from_file(cls, name, _fmt, _index = -1):
# Check that the specified raw file actually exists.
with open(name, 'rb') as _:
pass
Expand Down
2 changes: 1 addition & 1 deletion src/greaseweazle/image/msa.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(self, name: str, fmt=None, noclobber=False):


@classmethod
def from_file(cls, name: str, _fmt) -> Image:
def from_file(cls, name: str, _fmt, _index = -1) -> Image:

with open(name, "rb") as f:
dat = f.read()
Expand Down
2 changes: 1 addition & 1 deletion src/greaseweazle/image/scp.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def side_count(self) -> List[int]:


@classmethod
def from_file(cls, name: str, _fmt) -> Image:
def from_file(cls, name: str, _fmt, _index = -1) -> Image:

splices = None

Expand Down
2 changes: 1 addition & 1 deletion src/greaseweazle/image/td0.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def __init__(self) -> None:


@classmethod
def from_file(cls, name: str, _fmt) -> Image:
def from_file(cls, name: str, _fmt, _index = -1) -> Image:

with open(name, "rb") as f:
dat = f.read()
Expand Down
4 changes: 3 additions & 1 deletion src/greaseweazle/tools/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
plls = track.plls

def open_input_image(args, image_class: Type[Image]) -> Image:
return image_class.from_file(args.in_file, args.fmt_cls)
return image_class.from_file(args.in_file, args.fmt_cls, int(args.disk_index))


def open_output_image(args, image_class: Type[Image]) -> Image:
Expand Down Expand Up @@ -117,6 +117,8 @@ def main(argv) -> None:
epilog=epilog)
parser.add_argument("--diskdefs", help="disk definitions file")
parser.add_argument("--format", help="disk format")
parser.add_argument("--disk-index", help="disk index within input "
"image file", default=-1)
parser.add_argument("--tracks", type=util.TrackSet,
help="which tracks to read & convert from input",
metavar="TSPEC")
Expand Down
4 changes: 3 additions & 1 deletion src/greaseweazle/tools/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

# Read and parse the image file.
def open_image(args, image_class: Type[image.Image]) -> image.Image:
return image_class.from_file(args.file, args.fmt_cls)
return image_class.from_file(args.file, args.fmt_cls, int(args.disk_index))

# write_from_image:
# Writes the specified image file to floppy disk.
Expand Down Expand Up @@ -188,6 +188,8 @@ def main(argv) -> None:
help="drive to read")
parser.add_argument("--diskdefs", help="disk definitions file")
parser.add_argument("--format", help="disk format")
parser.add_argument("--disk-index", help="disk index within image file",
default=-1)
parser.add_argument("--tracks", type=util.TrackSet, metavar="TSPEC",
help="which tracks to write")
parser.add_argument("--pre-erase", action="store_true",
Expand Down