mirror of
https://github.com/rzzzwilson/pymlac.git
synced 2025-06-10 09:32:41 +00:00
New code to test PTR and PTP devices
This commit is contained in:
@@ -26,15 +26,16 @@ DIB = 0 # display CPU ???
|
||||
DX = 0 # display CPU draw X register
|
||||
DY = 0 # display CPU draw Y register
|
||||
|
||||
# state variables
|
||||
mode = MODE_NORMAL
|
||||
running = False
|
||||
|
||||
# global state variables
|
||||
Mode = MODE_NORMAL
|
||||
Running = False
|
||||
|
||||
|
||||
def init():
|
||||
mode = MODE_NORMAL
|
||||
running = False
|
||||
global Mode, Running
|
||||
|
||||
Mode = MODE_NORMAL
|
||||
Running = False
|
||||
|
||||
def DEIMdecode(byte):
|
||||
"""Decode a DEIM byte"""
|
||||
@@ -57,6 +58,7 @@ def DEIMdecode(byte):
|
||||
|
||||
def doDEIMByte(byte):
|
||||
global DPC, DX, DY, DRSindex
|
||||
global Mode
|
||||
|
||||
if byte & 0x80: # increment?
|
||||
prevDX = DX
|
||||
@@ -73,7 +75,7 @@ def doDEIMByte(byte):
|
||||
# display.draw(0, prevDX, prevDY, DX, DY)
|
||||
else: # micro instructions
|
||||
if byte & 0x40:
|
||||
mode = MODE_NORMAL
|
||||
Mode = MODE_NORMAL
|
||||
if byte & 0x20: # DRJM
|
||||
if DRSindex <= 0:
|
||||
Trace.comment('\nDRS stack underflow at display address %6.6o'
|
||||
@@ -92,18 +94,19 @@ def doDEIMByte(byte):
|
||||
|
||||
def execute_one_instruction():
|
||||
global DPC
|
||||
global Mode
|
||||
|
||||
if not running:
|
||||
if not Running:
|
||||
Trace.dtrace('')
|
||||
return 0
|
||||
|
||||
instruction = Memory.get(DPC, 0)
|
||||
DPC = MASK_MEM(DPC + 1)
|
||||
|
||||
if mode == MODE_DEIM:
|
||||
if Mode == MODE_DEIM:
|
||||
Trace.trace(DEIMdecode(instruction >> 8) + '\t')
|
||||
doDEIMByte(instruction >> 8)
|
||||
if mode == MODE_DEIM:
|
||||
if Mode == MODE_DEIM:
|
||||
Trace.trace(DEIMdecode(instruction & 0xff) + '\t')
|
||||
doDEIMByte(instruction & 0xff)
|
||||
else:
|
||||
@@ -114,14 +117,14 @@ def execute_one_instruction():
|
||||
address = instruction & 007777
|
||||
|
||||
if opcode == 000: return page00(instruction)
|
||||
elif opcode == 001: return i_DLXA(address)
|
||||
elif opcode == 002: return i_DLYA(address)
|
||||
elif opcode == 003: return i_DEIM(address)
|
||||
elif opcode == 004: return i_DLVH(address)
|
||||
elif opcode == 005: return i_DJMS(address)
|
||||
elif opcode == 006: return i_DJMP(address)
|
||||
elif opcode == 007: return illegal(instruction)
|
||||
else: illegal(instruction)
|
||||
elif opcode == 001: return i_DLXA(address)
|
||||
elif opcode == 002: return i_DLYA(address)
|
||||
elif opcode == 003: return i_DEIM(address)
|
||||
elif opcode == 004: return i_DLVH(address)
|
||||
elif opcode == 005: return i_DJMS(address)
|
||||
elif opcode == 006: return i_DJMP(address)
|
||||
elif opcode == 007: illegal(instruction)
|
||||
else: illegal(instruction)
|
||||
|
||||
def illegal(instruction=None):
|
||||
if instruction:
|
||||
@@ -133,7 +136,7 @@ def illegal(instruction=None):
|
||||
sys.exit(0)
|
||||
|
||||
def ison():
|
||||
return running
|
||||
return Running
|
||||
|
||||
def i_DDXM():
|
||||
global DX
|
||||
@@ -148,13 +151,15 @@ def i_DDYM():
|
||||
Trace.dtrace('DDYM')
|
||||
|
||||
def i_DEIM(address):
|
||||
mode = MODE_DEIM
|
||||
global Mode
|
||||
|
||||
Mode = MODE_DEIM
|
||||
Trace.deimtrace('DEIM', DEIMdecode(address & 0377))
|
||||
doDEIMByte(address & 0377)
|
||||
return 1
|
||||
|
||||
def i_DHLT():
|
||||
running = False
|
||||
Running = False
|
||||
Trace.dtrace('DHLT')
|
||||
|
||||
def i_DHVC():
|
||||
@@ -315,11 +320,11 @@ def page00(instruction):
|
||||
return 1
|
||||
|
||||
def start():
|
||||
global running
|
||||
global Running
|
||||
|
||||
running = True
|
||||
Running = True
|
||||
|
||||
def stop():
|
||||
global running
|
||||
global Running
|
||||
|
||||
running = False
|
||||
Running = False
|
||||
|
||||
@@ -21,6 +21,7 @@ motor_state = MOTOR_OFF
|
||||
device_state = DEVICE_NOT_READY
|
||||
filename = None
|
||||
open_file = None
|
||||
cycle_count = None
|
||||
|
||||
|
||||
def init():
|
||||
@@ -50,27 +51,27 @@ def dismount():
|
||||
open_file = None
|
||||
|
||||
def start():
|
||||
global motor_state, device_state, filename, open_file
|
||||
global motor_state, device_state, cycle_count
|
||||
|
||||
motor_state = MOTOR_ON
|
||||
device_state = DEVICE_NOT_READY
|
||||
cycle_count = DEVICE_NOT_READY_CYCLES
|
||||
|
||||
def stop():
|
||||
global motor_state, device_state, filename, open_file
|
||||
global motor_state, device_state
|
||||
|
||||
motor_state = MOTOR_OFF
|
||||
device_state = DEVICE_NOT_READY
|
||||
|
||||
def write(ch):
|
||||
global motor_state, device_state, filename, open_file
|
||||
global device_state, open_file, cycle_count
|
||||
|
||||
device_state = DEVICE_NOT_READY
|
||||
cycle_count = DEVICE_NOT_READY_CYCLES
|
||||
open_file.write(ch)
|
||||
|
||||
def tick(cycles):
|
||||
global motor_state, device_state, filename, open_file
|
||||
global motor_state, device_state, open_file, cycle_count
|
||||
|
||||
if motor_state == MOTOR_OFF or not open_file:
|
||||
device_state = DEVICE_NOT_READY
|
||||
|
||||
173
pymlac/test_PTR_PTP.py
Normal file
173
pymlac/test_PTR_PTP.py
Normal file
@@ -0,0 +1,173 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Test the pymlac papertape reader code.
|
||||
|
||||
Usage: test_PTR_PTP.py <options>
|
||||
|
||||
where <filename> is a papertape file (*.ptp)
|
||||
and <options> is zero or more of:
|
||||
-h print this help and stop
|
||||
"""
|
||||
|
||||
# We exercise the papertape reader module by:
|
||||
# 1. manipulating the device to test error conditions
|
||||
# 2. writing test *.ptp files which we mount and read
|
||||
|
||||
|
||||
import Ptr
|
||||
import Ptp
|
||||
|
||||
|
||||
# module global constants
|
||||
PtrFilename = '_#PTR#_.ptp'
|
||||
PtpFilename = '_#PTP#_.ptp'
|
||||
|
||||
|
||||
def read_no_tape():
|
||||
"""Read from device with no tape mounted."""
|
||||
|
||||
# read before turning on
|
||||
byte = Ptr.read()
|
||||
if byte != 0377:
|
||||
print('Error')
|
||||
Ptr.tick(1000000) # wait a long time
|
||||
byte = Ptr.read()
|
||||
if byte != 0377:
|
||||
print('Error')
|
||||
|
||||
# turn device on, still no tape
|
||||
Ptr.start()
|
||||
Ptr.tick(1000000) # wait a long time
|
||||
byte = Ptr.read()
|
||||
if byte != 0377:
|
||||
print('Error')
|
||||
Ptr.tick(1000000) # wait a long time
|
||||
byte = Ptr.read()
|
||||
if byte != 0377:
|
||||
print('Error')
|
||||
Ptr.stop()
|
||||
|
||||
def create_papertape(filename):
|
||||
"""Create a PTP file."""
|
||||
|
||||
# create a test papertape
|
||||
with open(filename, 'wb') as fd:
|
||||
# leader
|
||||
for _ in range(128):
|
||||
fd.write(chr(0))
|
||||
|
||||
for v in range(1, 256):
|
||||
fd.write(chr(v))
|
||||
|
||||
# trailer
|
||||
for _ in range(128):
|
||||
fd.write(chr(0))
|
||||
|
||||
def create_papertape_ptp(filename):
|
||||
"""Create a PTP file using the Ptp device."""
|
||||
|
||||
Ptp.mount(filename)
|
||||
Ptp.start()
|
||||
|
||||
# leader
|
||||
for _ in range(128):
|
||||
while not Ptp.ready():
|
||||
Ptp.tick(1)
|
||||
Ptp.write(chr(0))
|
||||
while Ptp.ready():
|
||||
Ptp.tick(1)
|
||||
|
||||
# body
|
||||
for v in range(1, 256):
|
||||
while not Ptp.ready():
|
||||
Ptp.tick(1)
|
||||
Ptp.write(chr(v))
|
||||
while Ptp.ready():
|
||||
Ptp.tick(1)
|
||||
|
||||
# trailer
|
||||
for _ in range(128):
|
||||
while not Ptp.ready():
|
||||
Ptp.tick(1)
|
||||
Ptp.write(chr(0))
|
||||
while Ptp.ready():
|
||||
Ptp.tick(1)
|
||||
|
||||
Ptp.stop()
|
||||
Ptp.dismount()
|
||||
|
||||
def read_tape(filename):
|
||||
"""Create tape and read it."""
|
||||
|
||||
# now mount and read tape
|
||||
Ptr.mount(filename)
|
||||
Ptr.start()
|
||||
|
||||
# read leader
|
||||
byte = None
|
||||
count = 0
|
||||
while True:
|
||||
while not Ptr.ready():
|
||||
Ptr.tick(1)
|
||||
byte = Ptr.read()
|
||||
while Ptr.ready():
|
||||
Ptr.tick(1)
|
||||
if byte != 0:
|
||||
break
|
||||
count += 1
|
||||
|
||||
print('%d bytes of leader' % count)
|
||||
|
||||
# read body, already read first byte
|
||||
byte = None
|
||||
count = 1
|
||||
while True:
|
||||
while not Ptr.ready():
|
||||
Ptr.tick(1)
|
||||
byte = Ptr.read()
|
||||
while Ptr.ready():
|
||||
Ptr.tick(1)
|
||||
if byte == 0:
|
||||
break
|
||||
count += 1
|
||||
|
||||
print('%d bytes of body' % count)
|
||||
|
||||
# read trailer, already read first byte
|
||||
byte = None
|
||||
count = 1
|
||||
while True:
|
||||
while not Ptr.ready():
|
||||
Ptr.tick(1)
|
||||
byte = Ptr.read()
|
||||
if byte != 0:
|
||||
break
|
||||
count += 1
|
||||
while Ptr.ready():
|
||||
Ptr.tick(1)
|
||||
|
||||
Ptr.stop()
|
||||
|
||||
print('%d bytes of trailer' % count)
|
||||
|
||||
def main():
|
||||
"""Test the papertape reader."""
|
||||
|
||||
Ptr.init()
|
||||
Ptp.init()
|
||||
|
||||
read_no_tape()
|
||||
create_papertape(PtrFilename)
|
||||
read_tape(PtrFilename)
|
||||
create_papertape_ptp(PtpFilename)
|
||||
read_tape(PtpFilename)
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user