diff --git a/docs/source/images/alter_copy_wp.png b/docs/source/images/alter_copy_wp.png new file mode 100644 index 0000000..797ed85 Binary files /dev/null and b/docs/source/images/alter_copy_wp.png differ diff --git a/docs/source/log.rst b/docs/source/log.rst index 1adde2b..1e89d23 100644 --- a/docs/source/log.rst +++ b/docs/source/log.rst @@ -644,3 +644,13 @@ and the other windows for device-specific inspection. :align: center Separate logging for io, printer and disk + + ... and used it to fix the crashing bug. Now multiple fplooy images + are supported and we can test the **COPY** utility: + + .. figure:: images/alter_copy_wp.png + :width: 400 + :align: center + + Using **ALTER** to write protect **SCR**, then failing attempt to **COPY** **DINDEX** + from drive 1 to **SCR** on drive 2 due to protection. diff --git a/src/devices/disk.py b/src/devices/disk.py index 8ca9dc8..ab3e949 100644 --- a/src/devices/disk.py +++ b/src/devices/disk.py @@ -14,24 +14,18 @@ def __init__(self, type, drives): self.selected_drive = -1 self.numdrives = len(drives) self.drives = [] - self.write_ena = False for i, fs in enumerate(drives): + udptx.send(f'append {self.type} Drive({i})') self.drives.append(Drive(i, fs)) - - - def isdriveavailable(self): - return 0 < self.selected_drive <= self.numdrives + for i in range(self.numdrives, 8): + udptx.send(f'append (unavailable) {self.type} Drive({i})') + self.drives.append(Drive(i, drives[0], avail=False)) def getdrive(self): return self.selected_drive - def deselect_drive(self): - self.selected_drive = -1 - self.drive = "" - - def select_drive(self, i): drive = i & 0x7f if drive == 0: @@ -39,12 +33,9 @@ def select_drive(self, i): return self.selected_drive = drive # allow selection of unavailable drives - if drive <= len(self.drives): - udptx.send(f'select_drive: {self.type}/{drive} - available') - self.drive = self.drives[drive - 1] - else: - udptx.send(f'select_drive: {self.type}/{drive} - unavailable') - self.drive = 'unavailable' + self.drive = self.drives[drive - 1] + udptx.send(f'Disk.select_drive() - {self.type}/{drive}, active: {self.drive.avail}') + assert self.selected_drive in [1, 2, 3, 4, 5, 6, 7] @@ -79,16 +70,16 @@ def isbusy(self): def status(self) -> int: if self.type != 'floppy': - udptx.send(f'disk.status: {self.type} drive not available') + udptx.send(f'Disk.status: {self.type} drive not available') return 0 - if not self.isdriveavailable(): - udptx.send(f'status: drive {self.selected_drive} not valid') + if not self.drive.avail: + udptx.send(f'Disk.status: drive {self.selected_drive} not valid') return 0 return self.drive.status() class Drive: - def __init__(self, driveno, fs): # + def __init__(self, driveno, fs, avail=True): # self.udp = udp.UdpTx(port=5006) self.driveno = driveno self.tracks = fs.tracks @@ -97,6 +88,7 @@ def __init__(self, driveno, fs): # self.marks = fs.marks self.current_track = 0 self.current_byte = 0 + self.avail = avail def dump(self, track): @@ -130,6 +122,7 @@ def step(self, direction): def readbyte(self): track = self.current_track byte = self.current_byte + #udptx.send(f'Drive.readbyte() - driveno {self.driveno}, trk {track}, byte {byte}') assert 0 <= track < self.tracks assert 0 <= byte < self.bytes_per_track, byte self.current_byte = (self.current_byte + 1) % self.bytes_per_track @@ -158,6 +151,9 @@ def isbusy(self): def status(self): + if not self.avail: + udptx.send(f'this disk {self.driveno} is unavailable (status 0)') + return 0 status = statusbits["sdready"] if self.isindex(): status += statusbits["index"] @@ -194,7 +190,6 @@ def control1(self, val): drive = val & 0x7f side = val >> 7 if drive == 0: - self.disk.deselect_drive() return assert drive in [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40], f'val: 0x{drive:02x}' @@ -205,6 +200,7 @@ def control1(self, val): drive /= 2 i += 1 assert i in [1, 2, 3, 4, 5, 6, 7] + udptx.send(f'Control.control1(): drive selected: {i}') self.disk.select_drive(i) diff --git a/src/devices/z80io.py b/src/devices/z80io.py index aa5764f..cf40376 100644 --- a/src/devices/z80io.py +++ b/src/devices/z80io.py @@ -18,7 +18,7 @@ def isprintable(c): class IO: def __init__(self, m, floppys, hds): self.floppy = disk.Control('floppy', floppys) - self.hdd = disk.Control('hdd', hds) + #self.hdd = disk.Control('hdd', hds) self.display = display.Display() self.printer = printer.SerialImpactPrinter() @@ -27,7 +27,6 @@ def __init__(self, m, floppys, hds): self.m = m self.incb = {} self.outcb = {} - self.keyincount = 0 self.keyin = 0 self.go = 0 self.stop = 0 @@ -44,7 +43,7 @@ def __init__(self, m, floppys, hds): # Serial impact printer self.register_in_cb( 0x05, self.handle_printer_in_5) - self.register_out_cb( 0x05, self.handle_printer_out_5) + self.register_out_cb(0x05, self.handle_printer_out_5) self.register_out_cb(0x06, self.handle_printer_out_6) self.register_out_cb(0x07, self.handle_printer_out_7) @@ -85,7 +84,8 @@ def handle_io_in(self, value) -> int: if inaddr in self.incb: return self.incb[inaddr]() - udptx.send(f'0x{inaddr:02x} - unregistered input address at pc {self.m.pc:04x}, exiting') + msg = f'0x{inaddr:02x} - unregistered input address at pc {self.m.pc:04x}, exiting' + udptx.send(msg) print(msg) print() sys.exit() @@ -149,7 +149,8 @@ def handle_key_in(self) -> int: if self.stop: retval = 0x0f self.stop = 0 - udptx.send(f'0x01 in - key: 0x{retval:02x}') + if retval: + udptx.send(f'0x01 in - key: 0x{retval:02x}') return retval @@ -226,16 +227,18 @@ def handle_disk_out_0b(self, val): def handle_disk_out_09(self, val): - udptx.send(f'0x09 out - floppy (data) - (0x{val:02x})') + #udptx.send(f'0x09 out - floppy (data) - (0x{val:02x})') self.floppy.data_out(val) def handle_disk_in_0a(self): retval = self.floppy.status() + #udptx.send(f'0x0a in - floppy status - (0x{retval:02x})') return retval def handle_disk_in_09(self): retval = self.floppy.data_in() + #udptx.send(f'0x09 in - floppy (data) - (0x{retval:02x})') return retval @@ -260,23 +263,28 @@ def handle_unkn_out_0c(self, val): ### Disk 2 Data and Control ### From "Q1 Assembler" p. 52 - 54 def handle_disk_in_19(self): - retval = self.hdd.data_in() - udptx.send(f'0x19 in - hdd (data): {retval}') - return retval + # retval = self.hdd.data_in() + # udptx.send(f'0x19 in - hdd (data): {retval}') + # return retval + return 0 + def handle_disk_in_1a(self): - retval = self.hdd.status() - udptx.send(f'0x1a in - hdd (status): {retval}') - return retval + # retval = self.hdd.status() + # udptx.send(f'0x1a in - hdd (status): {retval}') + # return retval + return 0 def handle_disk_out_1a(self, val): - if val: - udptx.send(f'0x1a out - hdd (control 1 ) - (0x{val:02x})') - self.hdd.control1(val) + # if val: + # udptx.send(f'0x1a out - hdd (control 1 ) - (0x{val:02x})') + # self.hdd.control1(val) + pass def handle_disk_out_1b(self, val): - if val != 0: - udptx.send(f'0x1b out - hdd (control 2 ) - (0x{val:02x})') - self.hdd.control2(val) + # if val != 0: + # udptx.send(f'0x1b out - hdd (control 2 ) - (0x{val:02x})') + # self.hdd.control2(val) + pass diff --git a/src/emulator.py b/src/emulator.py index 181bfb1..c2c76ea 100644 --- a/src/emulator.py +++ b/src/emulator.py @@ -8,6 +8,7 @@ import ros as r import devices.z80io as z80io import progs.programs as prg +import utils.misc as misc import disks.debugdisk.image as debugdisk import disks.datamuseum.image as datamuseum from timeit import default_timer as timer @@ -74,10 +75,10 @@ def kbd_input(self): kc = self.kc if self.key.kbhit(): ch = ord(self.key.getch()) - # if misc.isprintable(ch): - # print(f'{chr(ch)}') - # else: - # print(f'{ch}') + if misc.isprintable(ch): + print(f'{chr(ch)}') + else: + print(f'{ch}') if ch == 0x222b: # opt-b -> hexdump self.cpu.mem.hexdump(0x2000, 0x10000 - 0x2000) diff --git a/src/utils/logdisk b/src/utils/logdisk index 61b0049..d43fb50 100755 --- a/src/utils/logdisk +++ b/src/utils/logdisk @@ -1,3 +1,4 @@ +clear printf "\e]1337;SetBadgeFormat=%s\a" \ $(echo "Q1 Disk" | base64) diff --git a/src/utils/logio b/src/utils/logio index 2142c06..0f1728a 100755 --- a/src/utils/logio +++ b/src/utils/logio @@ -1,3 +1,4 @@ +clear printf "\e]1337;SetBadgeFormat=%s\a" \ $(echo "Q1 IO" | base64) diff --git a/src/utils/logprt b/src/utils/logprt index 1b05837..4645b34 100755 --- a/src/utils/logprt +++ b/src/utils/logprt @@ -1,3 +1,4 @@ +clear printf "\e]1337;SetBadgeFormat=%s\a" \ $(echo "Q1 PRINTER" | base64)