Skip to content

Commit

Permalink
better parsing of disk data in filesys.info, extracted a PL/1 program…
Browse files Browse the repository at this point in the history
…, documentation
  • Loading branch information
mortenjc committed Nov 16, 2024
1 parent 76b3d03 commit b54cce7
Show file tree
Hide file tree
Showing 6 changed files with 259 additions and 16 deletions.
7 changes: 7 additions & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ from ROMs.
filesys


.. toctree::
:caption: PL/1
:maxdepth: 3
:hidden:

pl1

.. toctree::
:caption: Emulator
:maxdepth: 3
Expand Down
171 changes: 171 additions & 0 deletions docs/source/pl1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@



The (partial) Q1 disk images available to us seem to be related to accounting.



.. code-block:: text
DCL VER FIXED (8) INIT (84020611);
/* PROGRAM-ID. V10RGENA.
DATE-WRITTEN. 1984-02-06.
AUTHOR. OLLE.
UPP EN TABELL I X-LED MED 10 ST VALFRIA KONTON
I Y-LED L[GGER DEN SJ[LV UPP TILL 39 ST IK-
SLAG SOM DEN FINNER KONTERADE F\R ANGIVNA
KONTON. POSTENS BELOPP ADDERAS TILL PASSANDE
TABELLEN. KONTON L[GGES IN MED FORM XKTOFORM
XKTOFIL. PARAMETERN F\R KONTON SKALL TILL-
DELAS ETT NAMN P] TRE TECKEN.
840206. OBg. */
DCL RKONTO1 CHAR (3) INIT ('---'),
RKONTO2 CHAR (3) INIT ('---'),
DATUM2 CHAR(6),
DAT1BIN BINARY,
DAT2BIN BINARY,
SPTYP BINARY, /* 1 = PERDAG 2 = BOKDAG */
STAB(11) BINARY;
DCL 1 TSTR,
2 VERNRT FIXED(5),
2 TEXT CHAR(13),
2 ANTVERP BINARY;
DCL PK POINTER,
1 BSTR BASED(PK),
2 KONTONR CHAR(11);
DCL PB POINTER,
1 BELSTR BASED(PB),
2 VERNR BINARY,
2 PDATUM BINARY,
2 BELOPP FIXED(11);
DCL 1 AREA,
2 CH(255) CHAR(61);
/* 15 555 BYTES */
DCL 1 IKPOST,
DCL 1 IKPOST,
2 SDATUM3 FIXED (6),
2 IKTEXT CHAR (32),
2 UHMARK CHAR (1);
DCL 1 XKTOPOST,
2 XOK CHAR (3),
2 XKONTO FIXED (5),
2 XTEXT1 CHAR (14),
2 XTEXT2 CHAR (14),
2 XTEXT3 CHAR (14),
2 XTEXT4 CHAR (14),
2 XTEXT5 CHAR (14);
DCL 1 YKTOPOST,
2 YKTO FIXED (3),
2 YTEXT CHAR (12);
DCL 1 RYTEXT (40),
2 YRADTEXT CHAR (12),
2 YRADKTO FIXED (3);
DCL IK POINTER,
1 RYTEXTREDEF BASED (IK),
2 YRADTEXTREDEF CHAR (12),
2 YRADKTOREDEF FIXED (3);
DCL XKTO (10) CHAR (5),
IKSLAG CHAR (3),
SOK CHAR (3);
DCL VERTEXT FILE,
VERBELOP FILE,
KSKONTOP FILE,
XKTOFIL FILE,
YKTOFIL FILE;
And the first (of seven tracks) of the file **V10RGENA** from the 'fluxsample' disk.

.. code-block:: text
DCL BSTRL BINARY INIT(61),
MAX BINARY,
BLOCKANT BINARY,
JK BINARY,
JJ BINARY,
LISTTYP BINARY, /* 1 = KONTOUTDRAG, 2 = SALDOBESKED */
RCODE BINARY,
KONTOG CHAR(11),
SIDA BINARY INIT(1),
R BINARY INIT(0),
NAMN(2) CHAR(10) INIT('KVV/KWAROS','AROSKRAFT'),
T15BELRED CHAR (15),
KONSTANT BINARY,
BUFF CHAR(20),
T1 CHAR(1),
T61 CHAR(6),
T62 CHAR(6),
T11 CHAR(11),
T13 CHAR(13),
T14 CHAR(14),
T15 CHAR (15),
RUBTEXT CHAR (70),
LASNYCKEL CHAR (1) INIT ('0'),
SWFORSTA CHAR (1) INIT ('J'),
KT8 CHAR(8),
FX6 FIXED(6),
TYP1 BINARY INIT(0),
TYP2 BINARY INIT(0),
OFFSET BINARY INIT(1),
LENGD BINARY INIT(0),
SUMMA (39,10) FIXED (11) INIT ((39)0),
SSUMMA FIXED (11,2),
XL BINARY, /* KOORDINAT I X-LED SUMMATAB */
YL BINARY, /* KOORDINAT I Y-LED SUMMATAB */
XANT BINARY,
UANT BINARY,
???????????????????????????????????????????????????????????????????????????????
KIND BINARY,
OKEY CHAR (1),
P POINTER,
D CHAR(6) BASED(P),
DATUM CHAR(6),
PP POINTER,
1 STR BASED(PP),
2 X CHAR(2),
2 Y CHAR(2), /* 6 = UKTO, 7 = IKSLAG */
2 FIRMA CHAR (1),
2 OP_KOD BINARY,
2 RADANT BINARY,
T4 CHAR(4),
ANTAL_KONT BINARY INIT(0),
TOT_ANTAL_KONT BINARY INIT(0),
VERSION CHAR(47) INIT(' TR10KOLJA Version 1.1 830603');
RUB:PROC;
RUB10:
IF FIRMA = '8' THEN DO;
???????????????????????????????????????????????????????????????????????????????
END;
IF FIRMA = '9' THEN DO;
PUT SKIP (2) EDIT ('AROS') (A(40));
END;
???????????????????????????????????????????????????????????????????????????????
(A(8)) (DATUM) (A(6));
DO J = 1 TO 5;
IF J = 2 THEN DO;
PUT SKIP EDIT ('PARA:') (A) (SUBSTR(SOK,1,2)) (A(4));
???????????????????????????????????????????????????????????????????????????????
IF SUBSTR (SOK,1,1) = 'O' THEN PUT EDIT ('OLJA') (A(4));
PUT EDIT (' ') (A(6));
GO TO RUB20;
END;
IF J = 3 THEN DO;
PUT SKIP EDIT ('BEST-NR: ') (A) (RKONTO1) (A(3)) ('-') (A)
(RKONTO2 - '001') (P'999') (' ') (A(3));
GO TO RUB20;
END;
IF J = 4 THEN DO;
2 changes: 2 additions & 0 deletions src/disks/datamuseum/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
track.info(8, fs.data[8], 19, 255)
track.info(9, fs.data[9], 19, 255)
track.info(70, fs.data[70], 126, 20)
track.info(71, fs.data[71], 126, 20)
track.info(73, fs.data[72], 126, 20)
6 changes: 4 additions & 2 deletions src/disks/fluxsamples/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
from disks.fluxsamples import t0, t1, t2
import filesys

tracks = [t0.data, t1.data, t2.data]

fs = filesys.FileSys()
fs.loadtracks([t0.data, t1.data, t2.data]) #
fs.loadtracks(tracks) #


if __name__ == '__main__':
track = filesys.Track()
track.info(1, fs.data[1], 82, 79)
track.info(0, fs.data[0], 16, 40)
track.info(1, fs.data[1], 77, 79)
track.info(2, fs.data[2], 82, 79)
2 changes: 1 addition & 1 deletion src/emulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def kbd_input(self):
elif ch == 8224: # opt-t
args.decode = not args.decode
elif ch == 170: # opt-a misc debug FDs, floppy dump
self.io.floppy.disk.drives[1].dump(0)
self.io.floppy.disk.drives[2].dump(0)
# self.ros.index()
# self.ros.file()
# self.ros.disk()
Expand Down
87 changes: 74 additions & 13 deletions src/filesys.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@


class Track:
def __init__(self):
self.overhead = 12 # besides record size: markers, ckecksum 0x10, etc.
self.offset_0x9e = 7

# Handle INDEX track which has fixed size
def index(self, data, records, record_size):
assert record_size == 40
d = data
for record in range(records):
overhead = 8
i = 0
offset = record * (record_size + overhead)
offset = record * (record_size + self.overhead)
assert d[offset + i] == 0x9e, f'{i=}, {d[offset + i]=}'
i += 5
i += self.offset_0x9e
assert d[offset + i] == 0x9b
i += 1

Expand All @@ -20,23 +25,22 @@ def index(self, data, records, record_size):
disk = d[offset + i + 15]
ftrack = d[offset + i + 16] + (d[offset + i + 17] << 8)
ltrack = d[offset + i + 18] + (d[offset + i + 19] << 8)
assert recno == 0
#assert recno == 0
if nrecs:
print(f'{filename}: nrecs {nrecs:2}, record size {recsz:3}, recs/trk: {rpt:3}, disk {disk}, first track {ftrack:2}, last track {ltrack:2}')


def info(self, track, data, records, record_size):
if track == 0:
self.index(data, records, record_size)
print(f'{filename}: recno {recno}, nrecs {nrecs:2}, record size {recsz:3}, recs/trk: {rpt:3}, disk {disk}, first track {ftrack:2}, last track {ltrack:2}')

# Handle case where segments are loaded according to ROS manual
# separator, address, number of bytes, ....
def loadable(self, track, data, records, record_size):
assert record_size == 255
d = data
for record in range(records):
overhead = 8
print(f'record {record}')
firstline = False
i = 0
offset = record * (record_size + overhead)
offset = record * (record_size + self.overhead)
assert d[offset + i] == 0x9e, f'{i=}, {d[offset + i]=}'
i += 5
i += self.offset_0x9e
assert d[offset + i] == 0x9b
i += 1
while 255 - i >= 5:
Expand Down Expand Up @@ -78,6 +82,63 @@ def info(self, track, data, records, record_size):
print()


def program(self, track, data, records, record_size):
d = data
for record in range(records):
i = 0
offset = record * (record_size + self.overhead)
assert d[offset + i] == 0x9e, f'{i=}, {d[offset + i]=}'
i += self.offset_0x9e
assert d[offset + i] == 0x9b
i += 1

ch = d[offset + i: offset + i + record_size]
print(''.join(list(map(chr, ch))))


def rawdata(self, track, data, records, record_size):
d = data
for record in range(records):
i = 0
offset = record * (record_size + self.overhead)
assert d[offset + i] == 0x9e, f'{i=}, {d[offset + i]=}'
i += self.offset_0x9e
assert d[offset + i] == 0x9b
i += 1

ch = d[offset + i: offset + i + record_size]
#print(''.join(list(map(chr, ch))))
cha = [ chr(x) if 32 <= x < 127 else '.' for x in ch]
print(f'{record:03}', ''.join(cha))

# this output can be filtered for more condensed output:
# python3 image.py | grep -v '\.\.\.\.\.\.\.' | grep -v ' '

# INDEX track handled separately
# Currently only works for loadable tracks (record size 255)
def info(self, track, data, records, record_size):
print(f'\nTrack information for track {track}\n')
if track == 0:
self.index(data, records, record_size)
return

if record_size == 255:
self.loadable(track, data, records, record_size)
return

if record_size == 79:
self.program(track, data, records, record_size)
return

if record_size == 20:
self.rawdata(track, data, records, record_size)
return

print('unsupported record type')




class FileSys:

# Possibilities according to "Q1 Lite system overview"
Expand Down

0 comments on commit b54cce7

Please sign in to comment.