1
0
mirror of https://github.com/rzzzwilson/pymlac.git synced 2025-06-10 09:32:41 +00:00

ptp/ptr now use classes

This commit is contained in:
Ross Wilson
2015-06-21 20:17:42 +07:00
parent 9645eda74c
commit e8adb2a187
3 changed files with 197 additions and 186 deletions

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python
"""
Emulate the Paper Tape Punch (PTP).
@@ -8,79 +8,83 @@ Emulate the Paper Tape Punch (PTP).
from Globals import *
# define various internal states
MOTOR_ON = 1
MOTOR_OFF = 0
DEVICE_NOT_READY = 0
DEVICE_READY = 1
PTP_CHARS_PER_SECOND = 30
DEVICE_NOT_READY_CYCLES = int(CYCLES_PER_SECOND / PTP_CHARS_PER_SECOND)
class Ptp(object):
# module-level state variables
motor_state = MOTOR_OFF
device_state = DEVICE_NOT_READY
filename = None
open_file = None
cycle_count = None
def init():
global motor_state, device_state, filename, open_file
# define various internal states
MOTOR_ON = 1
MOTOR_OFF = 0
DEVICE_NOT_READY = 0
DEVICE_READY = 1
PTP_CHARS_PER_SECOND = 30
DEVICE_NOT_READY_CYCLES = int(CYCLES_PER_SECOND / PTP_CHARS_PER_SECOND)
# module-level state variables
motor_state = MOTOR_OFF
device_state = DEVICE_NOT_READY
filename = None
open_file = None
cycle_count = None
def mount(ptp_filename):
global motor_state, device_state, filename, open_file
motor_state = MOTOR_OFF
device_state = DEVICE_NOT_READY
filename = ptp_filename
open_file = open(filename, 'w')
def init(self):
"""Initialize the punch."""
def dismount():
global motor_state, device_state, filename, open_file
self.motor_state = self.MOTOR_OFF
self.device_state = self.DEVICE_NOT_READY
self.filename = None
self.open_file = None
motor_state = MOTOR_OFF
device_state = DEVICE_NOT_READY
if open_file:
open_file.close()
filename = None
open_file = None
def mount(self, ptp_filename):
"""Mount a file on the punch."""
def start():
global motor_state, device_state, cycle_count
self.motor_state = self.MOTOR_OFF
self.device_state = self.DEVICE_NOT_READY
self.filename = ptp_filename
self.open_file = open(self.filename, 'w')
motor_state = MOTOR_ON
device_state = DEVICE_NOT_READY
cycle_count = DEVICE_NOT_READY_CYCLES
def dismount(self):
"""Dismount the file from the punch."""
def stop():
global motor_state, device_state
self.motor_state = self.MOTOR_OFF
self.device_state = self.DEVICE_NOT_READY
if self.open_file:
self.open_file.close()
self.filename = None
self.open_file = None
motor_state = MOTOR_OFF
device_state = DEVICE_NOT_READY
def start(self):
"""Start the punch motor."""
def write(ch):
global device_state, open_file, cycle_count
self.motor_state = self.MOTOR_ON
self.device_state = self.DEVICE_NOT_READY
self.cycle_count = self.DEVICE_NOT_READY_CYCLES
device_state = DEVICE_NOT_READY
cycle_count = DEVICE_NOT_READY_CYCLES
open_file.write(ch)
def stop(self):
"""Stop the punch motor."""
def tick(cycles):
global motor_state, device_state, open_file, cycle_count
self.motor_state = self.MOTOR_OFF
self.device_state = self.DEVICE_NOT_READY
if motor_state == MOTOR_OFF or not open_file:
device_state = DEVICE_NOT_READY
return
def write(self, ch):
"""Punch an 8 bit value to the tape file."""
cycle_count -= cycles
if cycle_count <= 0:
device_state = DEVICE_READY
self.device_state = self.DEVICE_NOT_READY
self.cycle_count = self.DEVICE_NOT_READY_CYCLES
self.open_file.write(ch)
def ready():
return device_state == DEVICE_READY
def tick(self, cycles):
"""Move the state of the punch along."""
if self.motor_state == self.MOTOR_OFF or not self.open_file:
self.device_state = self.DEVICE_NOT_READY
return
self.cycle_count -= cycles
if self.cycle_count <= 0:
self.device_state = self.DEVICE_READY
def ready(self):
"""Get the punch state."""
return self.device_state == self.DEVICE_READY

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python
"""
Emulate the imlac Paper Tape Reader (PTR).
@@ -11,29 +11,19 @@ the PTR object how many CPU cycles have passed (tick()).
from Globals import *
# number of chars per second we want
CharsPerSecond = 300
class Ptr(object):
# duty cycle for PTR is 30% ready and 70% not ready
ReadyCycles = int((CYCLES_PER_SECOND / CharsPerSecond) / 0.7) / 25
NotReadyCycles = int((CYCLES_PER_SECOND / CharsPerSecond) / 0.3) / 25
# number of chars per second we want
CharsPerSecond = 300
# no tape in reader, return 0377 (all holes see light)
PtrEOF = 0377
# duty cycle for PTR is 30% ready and 70% not ready
ReadyCycles = int((CYCLES_PER_SECOND / CharsPerSecond) / 0.7) / 25
NotReadyCycles = int((CYCLES_PER_SECOND / CharsPerSecond) / 0.3) / 25
# module-level state variables
motor_on = False
device_ready = False
open_file = None
filename = None
at_eof = True
value = PtrEOF
cycle_count = 0
def init():
global motor_on, device_ready, filename, at_eof, value, cycle_count, open_file
# no tape in reader, return 0377 (all holes see light)
PtrEOF = 0377
# module-level state variables
motor_on = False
device_ready = False
open_file = None
@@ -42,75 +32,92 @@ def init():
value = PtrEOF
cycle_count = 0
def mount(fname):
global motor_on, device_ready, filename, at_eof, value, cycle_count, open_file
motor_on = False
device_ready = False
filename = fname
open_file = open(filename, 'r')
at_eof = False
value = PtrEOF
def __init__(self):
"""Initialize the paertape reader device."""
def dismount():
global motor_on, device_ready, filename, at_eof, value, cycle_count, open_file
self.motor_on = False
self.device_ready = False
self.open_file = None
self.filename = None
self.at_eof = True
self.value = self.PtrEOF
self.cycle_count = 0
motor_on = False
device_ready = False
if filename:
open_file.close()
filename = None
at_eof = True
value = PtrEOF
def mount(self, fname):
"""Mount papertape file on the reader device."""
def start():
global motor_on, device_ready, filename, at_eof, value, cycle_count, open_file
self.motor_on = False
self.device_ready = False
self.filename = fname
self.open_file = open(self.filename, 'r')
self.at_eof = False
self.value = self.PtrEOF
motor_on = True
device_ready = False
cycle_count = NotReadyCycles
def dismount(self):
"""Dismount a papertape file."""
def stop():
global motor_on, device_ready, filename, at_eof, value, cycle_count, open_file
self.motor_on = False
self.device_ready = False
if self.filename:
self.open_file.close()
self.open_file = None
self.filename = None
self.at_eof = True
self.value = self.PtrEOF
motor_on = False
device_ready = False
cycle_count = NotReadyCycles
def start(self):
"""Turn papertape reader motor on."""
def read():
return value
self.motor_on = True
self.device_ready = False
self.cycle_count = self.ReadyCycles
def eof():
return at_eof
def stop(self):
"""Stop reader motor."""
def tick(cycles):
"""Called to push PTR state along.
self.motor_on = False
self.device_ready = False
self.cycle_count = self.ReadyCycles
cycles number of cycles passed since last tick
"""
def read(self):
"""Read papertape value."""
global motor_on, device_ready, filename, at_eof, value, cycle_count, open_file
return self.value
# if end of tape or motor off, do nothing, state remains unchanged
if at_eof or not motor_on:
return
def eof(self):
"""Return reader EOF status."""
cycle_count -= cycles
if cycle_count <= 0:
if device_ready:
device_ready = False
cycle_count += NotReadyCycles
else:
device_ready = True
cycle_count += ReadyCycles
value = open_file.read(1)
if len(value) < 1:
# EOF on input file, pretend end of tape
at_eof = True
value = PtrEOF
return self.at_eof
def tick(self, cycles):
"""Called to push PTR state along.
cycles number of cycles passed since last tick
"""
# if end of tape or motor off, do nothing, state remains unchanged
if self.at_eof or not self.motor_on:
return
self.cycle_count -= cycles
if self.cycle_count <= 0:
if self.device_ready:
self.device_ready = False
self.cycle_count += self.ReadyCycles
else:
value = ord(value)
self.device_ready = True
self.cycle_count += self.ReadyCycles
self.value = self.open_file.read(1)
if len(self.value) < 1:
# EOF on input file, pretend end of tape
self.at_eof = True
self.value = self.PtrEOF
else:
self.value = ord(self.value)
def ready():
return device_ready
def ready(self):
"""Test if reader is ready."""
return self.device_ready

View File

@@ -25,29 +25,29 @@ PtrFilename = '_#PTR#_.ptp'
PtpFilename = '_#PTP#_.ptp'
def read_no_tape():
def read_no_tape(ptr):
"""Read from device with no tape mounted."""
# read before turning on
byte = Ptr.read()
byte = ptr.read()
if byte != 0377:
print('Error')
Ptr.tick(1000000) # wait a long time
byte = Ptr.read()
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()
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()
ptr.tick(1000000) # wait a long time
byte = ptr.read()
if byte != 0377:
print('Error')
Ptr.stop()
ptr.stop()
def create_papertape(filename):
"""Create a PTP file."""
@@ -65,55 +65,55 @@ def create_papertape(filename):
for _ in range(128):
fd.write(chr(0))
def create_papertape_ptp(filename):
def create_papertape_ptp(ptp, filename):
"""Create a PTP file using the Ptp device."""
Ptp.mount(filename)
Ptp.start()
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)
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)
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)
while not ptp.ready():
ptp.tick(1)
ptp.write(chr(0))
while ptp.ready():
ptp.tick(1)
Ptp.stop()
Ptp.dismount()
ptp.stop()
ptp.dismount()
def read_tape(filename):
def read_tape(ptr, filename):
"""Create tape and read it."""
# now mount and read tape
Ptr.mount(filename)
Ptr.start()
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)
while not ptr.ready():
ptr.tick(1)
byte = ptr.read()
while ptr.ready():
ptr.tick(1)
if byte != 0:
break
count += 1
@@ -124,11 +124,11 @@ def read_tape(filename):
byte = None
count = 1
while True:
while not Ptr.ready():
Ptr.tick(1)
byte = Ptr.read()
while Ptr.ready():
Ptr.tick(1)
while not ptr.ready():
ptr.tick(1)
byte = ptr.read()
while ptr.ready():
ptr.tick(1)
if byte == 0:
break
count += 1
@@ -139,30 +139,30 @@ def read_tape(filename):
byte = None
count = 1
while True:
while not Ptr.ready():
Ptr.tick(1)
byte = Ptr.read()
while not ptr.ready():
ptr.tick(1)
byte = ptr.read()
if byte != 0:
break
count += 1
while Ptr.ready():
Ptr.tick(1)
while ptr.ready():
ptr.tick(1)
Ptr.stop()
ptr.stop()
print('%d bytes of trailer' % count)
def main():
"""Test the papertape reader."""
Ptr.init()
Ptp.init()
ptr = Ptr.Ptr()
ptp = Ptp.Ptp()
read_no_tape()
read_no_tape(ptr)
create_papertape(PtrFilename)
read_tape(PtrFilename)
create_papertape_ptp(PtpFilename)
read_tape(PtpFilename)
read_tape(ptr, PtrFilename)
create_papertape_ptp(ptp, PtpFilename)
read_tape(ptr, PtpFilename)