1
0
mirror of https://github.com/rzzzwilson/pymlac.git synced 2025-06-10 09:32:41 +00:00
Files
rzzzwilson.pymlac/pymlac/Ptr.py
2015-05-20 19:02:17 +07:00

117 lines
2.7 KiB
Python

#!/usr/bin/python
"""
Emulate the imlac Paper Tape Reader (PTR).
We take some pains to closely emulate the *real* PTR device, even
including misuse, such as no tape mounted. This means we must tell
the PTR object how many CPU cycles have passed (tick()).
"""
from Globals import *
# number of chars per second we want
CharsPerSecond = 300
# 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
# 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
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
motor_on = False
device_ready = False
open_file = None
filename = None
at_eof = True
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 dismount():
global motor_on, device_ready, filename, at_eof, value, cycle_count, open_file
motor_on = False
device_ready = False
if filename:
open_file.close()
filename = None
at_eof = True
value = PtrEOF
def start():
global motor_on, device_ready, filename, at_eof, value, cycle_count, open_file
motor_on = True
device_ready = False
cycle_count = NotReadyCycles
def stop():
global motor_on, device_ready, filename, at_eof, value, cycle_count, open_file
motor_on = False
device_ready = False
cycle_count = NotReadyCycles
def read():
return value
def eof():
return at_eof
def tick(cycles):
"""Called to push PTR state along.
cycles number of cycles passed since last tick
"""
global motor_on, device_ready, filename, at_eof, value, cycle_count, open_file
# if end of tape or motor off, do nothing, state remains unchanged
if at_eof or not motor_on:
return
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
else:
value = ord(value)
def ready():
return device_ready