1
0
mirror of https://github.com/rzzzwilson/pymlac.git synced 2025-06-10 09:32:41 +00:00
Files
rzzzwilson.pymlac/pymlac/pymlac
2016-01-20 15:09:27 +07:00

207 lines
7.2 KiB
Python
Executable File

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
A simulator for an Imlac PDS-1 or PDS-4.
Usage: pymlac [ <option> ]*
That is, the user may specify zero or more options interspersed in any manner
required. The options are:
-b (ptr | tty | none) sets the bootstrap ROM code:
ptr uses the papertape bootstrap ROM
tty uses the teletype bootstrap ROM
none uses no bootstrap ROM
-c clears core including bootstrap ROM, if write enabled
-cf <filename> sets the name of the core file to read and write
(default file is 'pymlac.core')
-d <value> sets the console data switches to the <value>
-h prints this help
-ptp <file> loads a file on to the papertape punch device
-ptr <file> loads a file on to the papertape reader device
-r (<address> | pc) executes from <address> or the current PC contents
-s <setfile> sets memory adress values from <setfile>
-t (<addr1> [,<addr2>] | off) controls the execution trace:
-t 0100 trace from address 0100 (octal)
-t 0100,200 trace from 0100 octal to 200 decimal
-t off turns trace off
-ttyin <file> loads a file on to the teletype reader device
-ttyout <file> loads a file on to the teletype writer device
-v <viewfile> views contents of memory addresses from file
-w (on | off) controls ROM write property:
-w on ROM addresses are writable
-w off ROM addresses are write protected
"""
import sys
import getopt
def str2int(s):
"""Convert a strinf to an integer value.
s the string to convert
The string may indicate a decimal or octal value.
None is returned if the string cannot be converted.
"""
return None
def usage(msg=None):
if msg:
print('*'*60)
print(msg)
print('*'*60)
print(__doc__)
def main():
"""Main function of the simulator. Mostly interpret CLI args."""
print('sys.argv=%s' % str(sys.argv))
len_sys_argv = len(sys.argv)
ndx = 1
while ndx < len_sys_argv:
opt = sys.argv[ndx]
ndx += 1
print('opt=%s' % opt)
if opt[0] != '-':
usage("Bad option: '%s'" % str(opt))
if opt == '-b':
if ndx >= len_sys_argv:
usage("'-b' option needs a following device name")
sys.exit(10)
dev = sys.argv[ndx].lower()
ndx += 1
if dev == 'ptr':
set_bootrom('PTR')
elif dev == 'tty':
set_bootrom('TTYIN')
elif dev == 'none':
set_bootrom(None)
else:
usage("-b option must be followed by 'ptr', 'tty' or 'none'")
sys.exit(10)
elif opt == '-c':
clear_core()
elif opt == '-cf':
if ndx >= len_sys_argv:
usage("'-cf' option needs a following filename")
sys.exit(10)
filename = sys.argv[ndx]
ndx += 1
set_core_file(filename)
elif opt == '-d':
if ndx >= len_sys_argv:
usage("'-d' option needs a following data switch value")
sys.exit(10)
value = str2int(sys.argv[ndx])
ndx += 1
if value is None:
usage("The '-d' option must be followed by a decimal or octal value")
sys.exit(10)
set_data_switch(value)
elif opt == '-h':
usage()
sys.exit(0)
elif opt == '-ptp':
if ndx >= len_sys_argv:
usage("'-ptp' option needs a following PTP filename")
sys.exit(10)
filename = sys.argv[ndx]
ndx += 1
set_ptp_filename(filename)
elif opt == '-ptr':
if ndx >= len_sys_argv:
usage("'-ptr' option needs a following PTR filename")
sys.exit(10)
filename = sys.argv[ndx]
ndx += 1
set_ptr_filename(filename)
elif opt == '-r':
if ndx >= len_sys_argv:
usage("'-r' option needs a following address or 'pc'")
sys.exit(10)
address = sys.argv[ndx].lower()
ndx += 1
if address != 'pc':
addr_value = str2int(address)
if addr_value is None:
usage("'-r' option needs a following address or 'pc'")
sys.exit(10)
set_pc(addr_value)
start_running()
elif opt == '-s':
if ndx >= len_sys_argv:
usage("'-s' option needs a following data filename")
sys.exit(10)
filename = sys.argv[ndx]
ndx += 1
set_mem_from_file(filename)
elif opt == '-t':
if ndx >= len_sys_argv:
usage("'-t' option needs a following address range or 'off'")
sys.exit(10)
r = sys.argv[ndx]
ndx += 1
if r == 'off':
set_trace_off()
else:
if ',' in r:
rr = r.split(',')
if len(rr) != 2:
usage("'-r' option may be followed by only two addresses")
sys.exit(10)
(start, stop) = rr
start_addr = str2int(start)
stop_addr = str2int(stop)
else:
start_addr = str2int(r)
stop_addr = None
set_trace_on(star_addr, stop_addr)
elif opt == '-ttyin':
if ndx >= len_sys_argv:
usage("'-ttyin' option needs a following data filename")
sys.exit(10)
filename = sys.argv[ndx]
ndx += 1
set_tty_in(filename)
elif opt == '-ttyout':
if ndx >= len_sys_argv:
usage("'-ttyout' option needs a following data filename")
sys.exit(10)
filename = sys.argv[ndx]
ndx += 1
set_tty_out(filename)
elif opt == '-v':
if ndx >= len_sys_argv:
usage("'-v' option needs a following address filename")
sys.exit(10)
filename = sys.argv[ndx]
ndx += 1
view_mem(filename)
elif opt == '-w':
if ndx >= len_sys_argv:
usage("'-v' option needs a following 'on' or 'off'")
sys.exit(10)
state = sys.argv[ndx]
ndx += 1
if state == 'on':
state = True
elif state == 'off':
state = False
else:
usage("'-v' option needs a following 'on' or 'off'")
sys.exit(10)
set_rom_write(state)
if __name__ == '__main__':
main()