Skip to content

Commit

Permalink
New prefix directive in diskdef
Browse files Browse the repository at this point in the history
  • Loading branch information
keirf committed Sep 4, 2024
1 parent 623bd0f commit 8575148
Show file tree
Hide file tree
Showing 3 changed files with 221 additions and 167 deletions.
111 changes: 82 additions & 29 deletions src/greaseweazle/codec/codec.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# This is free and unencumbered software released into the public domain.
# See the file COPYING for more details, or visit <http://unlicense.org>.

from __future__ import annotations
from typing import Dict, List, Tuple, Optional

import os.path, re
Expand Down Expand Up @@ -128,16 +129,37 @@ def default_revs(self) -> float:
return max([x.default_revs for x in self.track_map.values()])



def read_diskdef_file_lines(filename: Optional[str]) -> Tuple[List[str], str]:
if filename is None:
filename = 'diskdefs.cfg'
with importlib.resources.open_text('greaseweazle.data', filename) as f:
lines = f.readlines()
else:
with open(os.path.expanduser(filename), 'r') as f:
lines = f.readlines()
return (lines, filename)
class DiskDef_File:
def __init__(self, name: Optional[str],
parent: Optional[DiskDef_File] = None,
prefix: Optional[str] = None) -> None:
self.linenr = 0
self.parent = parent
self.prefix = prefix
self.path: Optional[str] = None
self.name: str = 'diskdefs.cfg' if name is None else name
if name is None or (self.parent and not self.parent.path):
with importlib.resources.open_text('greaseweazle.data',
self.name) as f:
self.lines = f.readlines()
else:
if self.parent:
assert self.parent.path # mypy
self.path = os.path.join(os.path.dirname(self.parent.path),
self.name)
else:
self.path = os.path.expanduser(self.name)
with open(self.path, 'r') as f:
self.lines = f.readlines()

def full_prefix(self) -> str:
s: List[str] = []
p: Optional[DiskDef_File] = self
while p is not None:
if p.prefix:
s.insert(0, p.prefix)
p = p.parent
return '.'.join(s) + '.' if s else ''


# Import the TrackDef subclasses
Expand Down Expand Up @@ -177,18 +199,18 @@ class ParseMode:
Disk = 1
Track = 2

def get_diskdef(
def _get_diskdef(
format_name: str,
diskdef_filename: Optional[str] = None
diskdef_file: DiskDef_File
) -> Optional[DiskDef]:

parse_mode = ParseMode.Outer
active = False
prefix = diskdef_file.full_prefix()
disk: Optional[DiskDef] = None
track: Optional[TrackDef] = None
lines, diskdef_filename = read_diskdef_file_lines(diskdef_filename)

for linenr, l in enumerate(lines, start=1):
for diskdef_file.linenr, l in enumerate(diskdef_file.lines, start=1):
try:
# Strip comments and whitespace.
match = re.match(r'\s*([^#]*)', l)
Expand All @@ -201,17 +223,28 @@ def get_diskdef(

if parse_mode == ParseMode.Outer:
disk_match = re.match(r'disk\s+([\w,.-]+)', t)
error.check(disk_match is not None, 'syntax error')
assert disk_match is not None # mypy
parse_mode = ParseMode.Disk
active = disk_match.group(1) == format_name
if active:
disk = DiskDef()
if disk_match:
parse_mode = ParseMode.Disk
active = prefix + disk_match.group(1) == format_name
if active:
disk = DiskDef()
else:
prefix_match = re.match(r'prefix\s+([\w,.-]+)\s+(\S+)', t)
error.check(prefix_match is not None, 'syntax error')
assert prefix_match is not None # mypy
disk = _get_diskdef(format_name, DiskDef_File(
name = prefix_match.group(2),
prefix = prefix_match.group(1),
parent = diskdef_file))
if disk:
break

elif parse_mode == ParseMode.Disk:
if t == 'end':
parse_mode = ParseMode.Outer
active = False
if disk:
break
continue
tracks_match = re.match(r'tracks\s+([0-9,.*-]+)'
'\s+([\w,.-]+)', t)
Expand Down Expand Up @@ -287,24 +320,44 @@ def get_diskdef(
keyval_match.group(2))

except Exception as err:
ctxt = "%s, line %d: " % (diskdef_filename, linenr)
err.args = (ctxt + err.args[0],) + err.args[1:]
if err.args and isinstance(x := err.args[0], str):
ctxt = f'At {diskdef_file.name}, line {diskdef_file.linenr}:'
ctxt += '\n' if x.startswith('At') else ' '
err.args = (ctxt + x,) + err.args[1:]
raise

return disk

def get_diskdef(
format_name: str,
diskdef_filename: Optional[str] = None
) -> Optional[DiskDef]:
diskdef_file = DiskDef_File(name = diskdef_filename)
disk = _get_diskdef(format_name, diskdef_file)
if disk is None:
return None
disk.finalise()

return disk


def print_formats(diskdef_filename: Optional[str] = None) -> str:
columns, sep, formats = 80, 2, []
lines, _ = read_diskdef_file_lines(diskdef_filename)
for l in lines:
def get_all_formats(diskdef_file: DiskDef_File) -> List[str]:
formats = []
prefix = diskdef_file.full_prefix()
for diskdef_file.linenr, l in enumerate(diskdef_file.lines, start=1):
disk_match = re.match(r'\s*disk\s+([\w,.-]+)', l)
if disk_match:
formats.append(disk_match.group(1))
formats.append(prefix + disk_match.group(1))
prefix_match = re.match(r'\s*prefix\s+([\w,.-]+)\s+(\S+)', l)
if prefix_match:
formats += get_all_formats(DiskDef_File(
name = prefix_match.group(2),
prefix = prefix_match.group(1),
parent = diskdef_file))
return formats

def print_formats(diskdef_filename: Optional[str] = None) -> str:
columns, sep = 80, 2
diskdef_file = DiskDef_File(name = diskdef_filename)
formats = get_all_formats(diskdef_file)
formats.sort()
return util.columnify(formats)

Expand Down
139 changes: 1 addition & 138 deletions src/greaseweazle/data/diskdefs.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -794,144 +794,7 @@ disk hp.mmfm.9895
end
end

disk ibm.160
cyls = 40
heads = 1
tracks * ibm.mfm
secs = 8
bps = 512
gap3 = 84
rate = 250
end
end

disk ibm.180
cyls = 40
heads = 1
tracks * ibm.mfm
secs = 9
bps = 512
gap3 = 84
rate = 250
end
end

disk ibm.320
cyls = 40
heads = 2
tracks * ibm.mfm
secs = 8
bps = 512
gap3 = 84
rate = 250
end
end

disk ibm.360
cyls = 40
heads = 2
tracks * ibm.mfm
secs = 9
bps = 512
gap3 = 84
rate = 250
end
end

disk ibm.720
cyls = 80
heads = 2
tracks * ibm.mfm
secs = 9
bps = 512
gap3 = 84
rate = 250
end
end

disk ibm.800
cyls = 80
heads = 2
tracks * ibm.mfm
secs = 10
bps = 512
gap3 = 30
rate = 250
end
end

disk ibm.1200
cyls = 80
heads = 2
tracks * ibm.mfm
secs = 15
bps = 512
gap3 = 84
rate = 500
rpm = 360
end
end

disk ibm.1440
cyls = 80
heads = 2
tracks * ibm.mfm
secs = 18
bps = 512
gap3 = 84
rate = 500
end
end

disk ibm.1680
cyls = 80
heads = 2
tracks * ibm.mfm
secs = 21
bps = 512
gap3 = 12
cskew = 3
interleave = 2
rate = 500
end
end

# alias for ibm.1680
disk ibm.dmf
cyls = 80
heads = 2
tracks * ibm.mfm
secs = 21
bps = 512
gap3 = 12
cskew = 3
interleave = 2
rate = 500
end
end

disk ibm.2880
cyls = 80
heads = 2
tracks * ibm.mfm
secs = 36
bps = 512
gap2 = 41
rate = 1000
end
end

# Generic IBM format codec which will scan a track for any valid FM/MFM
# sectors at standard rates (125kbps, 250kbps, 500kbps) and RPMs (300, 360).
disk ibm.scan
cyls = 80
heads = 2
tracks * ibm.scan
# Following options restrict the scanner's search
# rate = 250
# rpm = 300
end
end
prefix ibm diskdefs_ibm.cfg

disk mac.400
cyls = 80
Expand Down
Loading

0 comments on commit 8575148

Please sign in to comment.