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:
116
pymlac/Ptp.py
116
pymlac/Ptp.py
@@ -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
|
||||
|
||||
|
||||
157
pymlac/Ptr.py
157
pymlac/Ptr.py
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user