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

Getting Imlac machine running, test loading

This commit is contained in:
Ross Wilson
2016-02-25 14:56:55 +07:00
parent a24db94e2b
commit a5c48fb43e
6 changed files with 274 additions and 186 deletions

View File

@@ -169,7 +169,7 @@ class MainCPU(object):
return self.BlockBase | address
def execute_one_instruction(self):
"""Execute one MAIN instruction, return # cycles used"""
"""Execute one MAIN instruction, return # cycles used and if traced."""
if not self.running:
return 0
@@ -187,6 +187,7 @@ class MainCPU(object):
return self.main_decode.get(opcode, self.illegal)(indirect,
address,
instruction)
def illegal(self, indirect, address, instruction):
"""Handle an illegal instruction."""
@@ -208,33 +209,34 @@ class MainCPU(object):
instruction)
def i_LAW_LWC(self, indirect, address, instruction):
traced = False
if indirect:
self.AC = ~address & WORDMASK
trace.itrace('LWC', False, address)
traced = trace.itrace('LWC', False, address)
else:
self.AC = address
trace.itrace('LAW', False, address)
return 1
traced = trace.itrace('LAW', False, address)
return (1, traced)
def i_JMP(self, indirect, address, instruction):
address = self.memory.eff_address(address, indirect)
self.PC = address & PCMASK
trace.itrace('JMP', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('JMP', indirect, address)
return (3, traced) if indirect else (2, traced)
def i_DAC(self, indirect, address, instruction):
address = self.memory.eff_address(address, indirect)
self.memory.put(self.AC, address, False)
trace.itrace('DAC', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('DAC', indirect, address)
return (3, traced) if indirect else (2, traced)
def i_XAM(self, indirect, address, instruction):
address = self.memory.eff_address(address, indirect)
tmp = self.memory.fetch(address, False)
self.memory.put(self.AC, address, False)
self.AC = tmp
trace.itrace('XAM', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('XAM', indirect, address)
return (3, traced) if indirect else (2, traced)
def i_ISZ(self, indirect, address, instruction):
address = self.memory.eff_address(address, indirect)
@@ -242,43 +244,43 @@ class MainCPU(object):
self.memory.put(value, address, False)
if value == 0:
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('ISZ', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('ISZ', indirect, address)
return (3, traced) if indirect else (2, traced)
def i_JMS(self, indirect, address, instruction):
address = self.memory.eff_address(address, indirect)
self.memory.put(self.PC, address, False)
self.PC = (address + 1) & PCMASK
trace.itrace('JMS', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('JMS', indirect, address)
return (3, traced) if indirect else (2, traced)
def i_AND(self, indirect, address, instruction):
self.AC &= self.memory.fetch(address, indirect)
trace.itrace('AND', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('AND', indirect, address)
return (3, traced) if indirect else (2, traced)
def i_IOR(self, indirect, address, instruction):
self.AC |= self.memory.fetch(address, indirect)
trace.itrace('IOR', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('IOR', indirect, address)
return (3, traced) if indirect else (2, traced)
def i_XOR(self, indirect, address, instruction):
self.AC ^= self.memory.fetch(address, indirect)
trace.itrace('XOR', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('XOR', indirect, address)
return (3, traced) if indirect else (2, traced)
def i_LAC(self, indirect, address, instruction):
self.AC = self.memory.fetch(address, indirect)
trace.itrace('LAC', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('LAC', indirect, address)
return (3, traced) if indirect else (2, traced)
def i_ADD(self, indirect, address, instruction):
self.AC += self.memory.fetch(self.BLOCKADDR(address), indirect)
if self.AC & OVERFLOWMASK:
self.L = (~self.L) & 01
self.AC &= WORDMASK
trace.itrace('ADD', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('ADD', indirect, address)
return (3, traced) if indirect else (2, traced)
def i_SUB(self, indirect, address, instruction):
addit = self.memory.fetch(self.BLOCKADDR(address), indirect)
@@ -287,15 +289,15 @@ class MainCPU(object):
if self.AC & OVERFLOWMASK:
self.L = ~self.L
self.AC &= WORDMASK
trace.itrace('SUB', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('SUB', indirect, address)
return (3, traced) if indirect else (2, traced)
def i_SAM(self, indirect, address, instruction):
samaddr = self.BLOCKADDR(address)
if self.AC == self.memory.fetch(samaddr, indirect):
self.PC = (self.PC + 1) & PCMASK
trace.itrace('SAM', indirect, address)
return 3 if indirect else 2
traced = trace.itrace('SAM', indirect, address)
return (3, traced) if indirect else (2, traced)
def microcode(self, instruction):
# T1
@@ -336,149 +338,149 @@ class MainCPU(object):
if instruction & k:
combine.append(op)
trace.itrace('+'.join(combine), False)
return 1
traced = trace.itrace('+'.join(combine), False)
return (1, traced)
def i_DLA(self, indirect, address, instruction):
self.displaycpu.DPC = self.AC
trace.itrace('DLA')
return 1
traced = trace.itrace('DLA')
return (1, traced)
def i_CTB(self, indirect, address, instruction):
trace.itrace('CTB')
return 1
traced = trace.itrace('CTB')
return (1, traced)
def i_DOF(self, indirect, address, instruction):
self.displaycpu.stop()
trace.itrace('DOF')
return 1
traced = trace.itrace('DOF')
return (1, traced)
def i_KRB(self, indirect, address, instruction):
self.AC |= self.kbd.read()
trace.itrace('KRB')
return 1
traced = trace.itrace('KRB')
return (1, traced)
def i_KCF(self, indirect, address, instruction):
self.kbd.clear()
trace.itrace('KCF')
return 1
traced = trace.itrace('KCF')
return (1, traced)
def i_KRC(self, indirect, address, instruction):
self.AC |= self.kbd.read()
self.kbd.clear()
trace.itrace('KRC')
return 1
traced = trace.itrace('KRC')
return (1, traced)
def i_RRB(self, indirect, address, instruction):
self.AC |= self.ttyin.read()
trace.itrace('RRB')
return 1
traced = trace.itrace('RRB')
return (1, traced)
def i_RCF(self, indirect, address, instruction):
self.ttyin.clear()
trace.itrace('RCF')
return 1
traced = trace.itrace('RCF')
return (1, traced)
def i_RRC(self, indirect, address, instruction):
self.AC |= self.ttyin.read()
self.ttyin.clear()
trace.itrace('RRC')
return 1
traced = trace.itrace('RRC')
return (1, traced)
def i_TPR(self, indirect, address, instruction):
self.ttyout.write(self.AC & 0xff)
trace.itrace('TPR')
return 1
traced = trace.itrace('TPR')
return (1, traced)
def i_TCF(self, indirect, address, instruction):
self.ttyout.clear()
trace.itrace('TCF')
return 1
traced = trace.itrace('TCF')
return (1, traced)
def i_TPC(self, indirect, address, instruction):
self.ttyout.write(self.AC & 0xff)
self.ttyout.clear()
trace.itrace('TPC')
return 1
traced = trace.itrace('TPC')
return (1, traced)
def i_HRB(self, indirect, address, instruction):
self.AC |= self.ptrptp.read()
trace.itrace('HRB')
return 1
traced = trace.itrace('HRB')
return (1, traced)
def i_HOF(self, indirect, address, instruction):
self.ptrptp.stop()
trace.itrace('HOF')
return 1
traced = trace.itrace('HOF')
return (1, traced)
def i_HON(self, indirect, address, instruction):
self.ptrptp.start()
trace.itrace('HON')
return 1
traced = trace.itrace('HON')
return (1, traced)
def i_STB(self, indirect, address, instruction):
trace.itrace('STB')
return 1
traced = trace.itrace('STB')
return (1, traced)
def i_SCF(self, indirect, address, instruction):
self.Sync40Hz = 0
trace.itrace('SCF')
return 1
traced = trace.itrace('SCF')
return (1, traced)
def i_IOS(self, indirect, address, instruction):
trace.itrace('IOS')
return 1
traced = trace.itrace('IOS')
return (1, traced)
def i_IOT101(self, indirect, address, instruction):
trace.itrace('IOT101')
return 1
traced = trace.itrace('IOT101')
return (1, traced)
def i_IOT111(self, indirect, address, instruction):
trace.itrace('IOT111')
return 1
traced = trace.itrace('IOT111')
return (1, traced)
def i_IOT131(self, indirect, address, instruction):
trace.itrace('IOT131')
return 1
traced = trace.itrace('IOT131')
return (1, traced)
def i_IOT132(self, indirect, address, instruction):
trace.itrace('IOT132')
return 1
traced = trace.itrace('IOT132')
return (1, traced)
def i_IOT134(self, indirect, address, instruction):
trace.itrace('IOT134')
return 1
traced = trace.itrace('IOT134')
return (1, traced)
def i_IOT141(self, indirect, address, instruction):
trace.itrace('IOT141')
return 1
traced = trace.itrace('IOT141')
return (1, traced)
def i_IOF(self, indirect, address, instruction):
trace.itrace('IOF')
return 1
traced = trace.itrace('IOF')
return (1, traced)
def i_ION(self, indirect, address, instruction):
trace.itrace('ION')
return 1
traced = trace.itrace('ION')
return (1, traced)
def i_PPC(self, indirect, address, instruction):
self.ptrptp.punch(self.AC & 0xff)
trace.itrace('PPC')
return 1
traced = trace.itrace('PPC')
return (1, traced)
def i_PSF(self, indirect, address, instruction):
if self.ptrptp.ready():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('PSF')
return 1
traced = trace.itrace('PSF')
return (1, traced)
def i_RAL1(self, indirect, address, instruction):
newl = self.AC >> 15
newac = (self.AC << 1) | self.L
self.L = newl
self.AC = newac & WORDMASK
trace.itrace('RAL', False, 1)
return 1
traced = trace.itrace('RAL', False, 1)
return (1, traced)
def i_RAL2(self, indirect, address, instruction):
newl = self.AC >> 15
@@ -489,8 +491,8 @@ class MainCPU(object):
newac = (self.AC << 1) | self.L
self.L = newl
self.AC = newac & WORDMASK
trace.itrace('RAL', False, 2)
return 1
traced = trace.itrace('RAL', False, 2)
return (1, traced)
def i_RAL3(self, indirect, address, instruction):
newl = self.AC >> 15
@@ -505,16 +507,16 @@ class MainCPU(object):
newac = (self.AC << 1) | self.L
self.L = newl
self.AC = newac & WORDMASK
trace.itrace('RAL', False, 3)
return 1
traced = trace.itrace('RAL', False, 3)
return (1, traced)
def i_RAR1(self, indirect, address, instruction):
newl = self.AC & 1
newac = (self.AC >> 1) | (self.L << 15)
self.L = newl
self.AC = newac & WORDMASK
trace.itrace('RAR', False, 1)
return 1
traced = trace.itrace('RAR', False, 1)
return (1, traced)
def i_RAR2(self, indirect, address, instruction):
newl = self.AC & 1
@@ -525,8 +527,8 @@ class MainCPU(object):
newac = (self.AC >> 1) | (self.L << 15)
self.L = newl
self.AC = newac & WORDMASK
trace.itrace('RAR', False, 2)
return 1
traced = trace.itrace('RAR', False, 2)
return (1, traced)
def i_RAR3(self, indirect, address, instruction):
newl = self.AC & 1
@@ -541,162 +543,162 @@ class MainCPU(object):
newac = (self.AC >> 1) | (self.L << 15)
self.L = newl
self.AC = newac & WORDMASK
trace.itrace('RAR', False, 3)
return 1
traced = trace.itrace('RAR', False, 3)
return (1, traced)
def i_SAL1(self, indirect, address, instruction):
high_bit = self.AC & HIGHBITMASK
value = self.AC & 037777
self.AC = (value << 1) | high_bit
trace.itrace('SAL', False, 1)
return 1
traced = trace.itrace('SAL', False, 1)
return (1, traced)
def i_SAL2(self, indirect, address, instruction):
high_bit = self.AC & HIGHBITMASK
value = self.AC & 017777
self.AC = (value << 2) | high_bit
trace.itrace('SAL', False, 2)
return 1
traced = trace.itrace('SAL', False, 2)
return (1, traced)
def i_SAL3(self, indirect, address, instruction):
high_bit = self.AC & HIGHBITMASK
value = self.AC & 007777
self.AC = (value << 3) | high_bit
trace.itrace('SAL', False, 3)
return 1
traced = trace.itrace('SAL', False, 3)
return (1, traced)
def i_SAR1(self, indirect, address, instruction):
high_bit = self.AC & HIGHBITMASK
self.AC = (self.AC >> 1) | high_bit
trace.itrace('SAR', False, 1)
return 1
traced = trace.itrace('SAR', False, 1)
return (1, traced)
def i_SAR2(self, indirect, address, instruction):
high_bit = self.AC & HIGHBITMASK
self.AC = (self.AC >> 1) | high_bit
self.AC = (self.AC >> 1) | high_bit
trace.itrace('SAR', False, 2)
return 1
traced = trace.itrace('SAR', False, 2)
return (1, traced)
def i_SAR3(self, indirect, address, instruction):
high_bit = self.AC & HIGHBITMASK
self.AC = (self.AC >> 1) | high_bit
self.AC = (self.AC >> 1) | high_bit
self.AC = (self.AC >> 1) | high_bit
trace.itrace('SAR', False, 3)
return 1
traced = trace.itrace('SAR', False, 3)
return (1, traced)
def i_DON(self, indirect, address, instruction):
self.displaycpu.DRSindex = 0
self.displaycpu.start()
trace.itrace('DON')
return 1
traced = trace.itrace('DON')
return (1, traced)
def i_ASZ(self):
if self.AC == 0:
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('ASZ')
return 1
traced = trace.itrace('ASZ')
return (1, traced)
def i_ASN(self):
if self.AC != 0:
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('ASN')
return 1
traced = trace.itrace('ASN')
return (1, traced)
def i_ASP(self):
if not (self.AC & HIGHBITMASK):
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('ASP')
return 1
traced = trace.itrace('ASP')
return (1, traced)
def i_ASM(self):
if (self.AC & HIGHBITMASK):
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('ASM')
return 1
traced = trace.itrace('ASM')
return (1, traced)
def i_LSZ(self):
if self.L == 0:
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('LSZ')
return 1
traced = trace.itrace('LSZ')
return (1, traced)
def i_LSN(self):
if self.L != 0:
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('LSN')
return 1
traced = trace.itrace('LSN')
return (1, traced)
def i_DSF(self):
if self.displaycpu.ison():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('DSF')
return 1
traced = trace.itrace('DSF')
return (1, traced)
def i_DSN(self):
if not self.displaycpu.ison():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('DSN')
return 1
traced = trace.itrace('DSN')
return (1, traced)
def i_KSF(self):
if self.kbd.ready():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('KSF')
return 1
traced = trace.itrace('KSF')
return (1, traced)
def i_KSN(self):
if not self.kbd.ready():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('KSN')
return 1
traced = trace.itrace('KSN')
return (1, traced)
def i_RSF(self):
if self.ttyin.ready():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('RSF')
return 1
traced = trace.itrace('RSF')
return (1, traced)
def i_RSN(self):
if not self.ttyin.ready():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('RSN')
return 1
traced = trace.itrace('RSN')
return (1, traced)
def i_TSF(self):
if self.ttyout.ready():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('TSF')
return 1
traced = trace.itrace('TSF')
return (1, traced)
def i_TSN(self):
if not self.ttyout.ready():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('TSN')
return 1
traced = trace.itrace('TSN')
return (1, traced)
def i_SSF(self):
if self.display.ready(): # skip if 40Hz sync on
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('SSF')
return 1
traced = trace.itrace('SSF')
return (1, traced)
def i_SSN(self):
if not self.display.ready():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('SSN')
return 1
traced = trace.itrace('SSN')
return (1, traced)
def i_HSF(self):
if self.ptrptp.ready():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('HSF')
return 1
traced = trace.itrace('HSF')
return (1, traced)
def i_HSN(self):
if not self.ptrptp.ready():
self.PC = (self.PC + 1) & WORDMASK
trace.itrace('HSN')
return 1
traced = trace.itrace('HSN')
return (1, traced)

View File

@@ -263,6 +263,7 @@ class Memory(object):
try:
self.memory[address] = MASK_16(value)
print('Memory: setting address %06o to %06o' % (address, MASK_16(value)))
except IndexError:
raise RuntimeError('Bad address: %06o (max mem=%06o, ADDRMASK=%06o)'
% (address, len(self.memory), ADDRMASK))

View File

@@ -12,6 +12,7 @@ Based on the 'borg' recipe from [http://code.activestate.com/recipes/66531/].
"""
import os
import collections
from Globals import *
@@ -44,6 +45,13 @@ class Trace(object):
self.cpu = maincpu
self.dcpu = displaycpu
self.trace_map = collections.defaultdict(bool)
def set_trace_map(self, trace_map):
"""Set the trace address dict mapping."""
self.trace_map = trace_map
def add_maincpu(self, maincpu):
"""Add the main CPU object."""
@@ -91,16 +99,24 @@ class Trace(object):
opcode the main CPU opcode
indirect True if instruction was indirect
adress address for the instruction (if any)
address address for the instruction (if any)
Returns True if tracing, else False.
"""
if self.tracing:
# print('itrace: self.cpu.PC=%06o, self.trace_map[self.cpu.PC]=%s'
# % (self.cpu.PC-1, str(self.trace_map[self.cpu.PC-1])))
if self.tracing and self.trace_map[self.cpu.PC-1]:
char = '*' if indirect else ''
if address is None:
self.tracefile.write('%s\t%s\t' % (opcode, char))
else:
self.tracefile.write('%s\t%s%5.5o\t' % (opcode, char, address))
self.tracefile.flush()
return True
return False
def itraceend(self, dispon):
"""Trace at the end of one execution cycle.

View File

@@ -1,2 +1,2 @@
# test of loading simple code and dumping memory
bootrom ptr; mount ptr dumpmem_test.ptp; setreg pc 040; rununtil 0; dumpmem dumpmem_test.dump
bootrom ptr; mount ptr dumpmem_test.ptp; setreg pc 040; trace 040,077; rununtil 0; dumpmem dumpmem_test.dump

View File

@@ -22,10 +22,10 @@ required. The options are:
-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
-t (<range>[:<range>] | off) controls the execution trace:
-t 0100,0200 trace from 0100 octal to 200 decimal
-t 0100,0200:0210,0300 trace from 0100 to 0200 and 0210 to 0300
-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
@@ -36,10 +36,21 @@ required. The options are:
import sys
import getopt
import collections
from Globals import *
import MainCPU
import Memory
import PtrPtp
import TtyIn
import TtyOut
import Trace
trace = Trace.Trace(TRACE_FILENAME)
def str2int(s):
"""Convert a strinf to an integer value.
"""Convert a string to an integer value.
s the string to convert
@@ -47,8 +58,16 @@ def str2int(s):
None is returned if the string cannot be converted.
"""
return None
base = 10
if s[0] == '0':
base = 8
try:
value = int(s, base=base)
except:
return None
return value
def usage(msg=None):
if msg:
@@ -58,13 +77,40 @@ def usage(msg=None):
print(__doc__)
def start_running(cpu, memory, ptrptp):
"""Run the Imlac machine until it stops."""
cpu.running = True
while cpu.running:
(cycles, traced) = cpu.execute_one_instruction()
if traced:
trace.itraceend(False)
ptrptp.ptr_tick(cycles)
ptrptp.ptp_tick(cycles)
def main():
"""Main function of the simulator. Mostly interpret CLI args."""
# prepare the Imlac machine
imlac_memory = Memory.Memory()
imlac_ptrptp = PtrPtp.PtrPtp()
imlac_ttyin = TtyIn.TtyIn()
imlac_ttyout = TtyOut.TtyOut()
imlac_cpu = MainCPU.MainCPU(imlac_memory, None, None,
None, imlac_ttyin, imlac_ttyout, imlac_ptrptp)
imlac_cpu.running = True
imlac_display_state = False
# prepare the trace
trace.add_maincpu(imlac_cpu)
print('sys.argv=%s' % str(sys.argv))
len_sys_argv = len(sys.argv)
# trace_map defines addresses we are tracing at
# initially, no tracing
trace_map = collections.defaultdict(bool)
len_sys_argv = len(sys.argv)
ndx = 1
while ndx < len_sys_argv:
opt = sys.argv[ndx]
@@ -80,23 +126,28 @@ def main():
dev = sys.argv[ndx].lower()
ndx += 1
if dev == 'ptr':
set_bootrom('PTR')
# set_bootrom('PTR')
imlac_memory.set_ROM('ptr')
elif dev == 'tty':
set_bootrom('TTYIN')
# set_bootrom('TTYIN')
imlac_memory.set_ROM('tty')
elif dev == 'none':
set_bootrom(None)
# set_bootrom(None)
imlac_memory.set_ROM(None)
else:
usage("-b option must be followed by 'ptr', 'tty' or 'none'")
sys.exit(10)
elif opt == '-c':
clear_core()
# clear_core()
imlac_memory.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)
# set_core_file(filename)
imlac_memory.set_corefile(filename)
elif opt == '-d':
if ndx >= len_sys_argv:
usage("'-d' option needs a following data switch value")
@@ -106,7 +157,8 @@ def main():
if value is None:
usage("The '-d' option must be followed by a decimal or octal value")
sys.exit(10)
set_data_switch(value)
# set_data_switch(value)
imlac_cpu.DS = value
elif opt == '-h':
usage()
sys.exit(0)
@@ -116,14 +168,16 @@ def main():
sys.exit(10)
filename = sys.argv[ndx]
ndx += 1
set_ptp_filename(filename)
# set_ptp_filename(filename)
imlac_ptrptp.ptp_mount(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)
# set_ptr_filename(filename)
imlac_ptrptp.ptr_mount(filename)
elif opt == '-r':
if ndx >= len_sys_argv:
usage("'-r' option needs a following address or 'pc'")
@@ -135,8 +189,10 @@ def main():
if addr_value is None:
usage("'-r' option needs a following address or 'pc'")
sys.exit(10)
set_pc(addr_value)
start_running()
# set_pc(addr_value)
imlac_cpu.PC = addr_value
trace.set_trace_map(trace_map)
start_running(imlac_cpu, imlac_memory, imlac_ptrptp)
elif opt == '-s':
if ndx >= len_sys_argv:
usage("'-s' option needs a following data filename")
@@ -146,39 +202,44 @@ def main():
set_mem_from_file(filename)
elif opt == '-t':
if ndx >= len_sys_argv:
usage("'-t' option needs a following address range or 'off'")
usage("'-t' option needs following address ranges or 'off'")
sys.exit(10)
r = sys.argv[ndx]
ndx += 1
if r == 'off':
set_trace_off()
trace_map = collections.defaultdict(bool)
else:
if ',' in r:
rr = r.split(',')
if len(rr) != 2:
usage("'-r' option may be followed by only two addresses")
trace_map = collections.defaultdict(bool)
print('r=%s' % r)
for rng in r.split(':'):
print('rng=%s' % rng)
be = rng.split(',')
print('be=%s' % str(be))
if len(be) != 2:
usage("'-r' ranges must have form 'begin,end'")
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)
(begin, end) = be
begin = str2int(begin)
end = str2int(end)
print('begin=%s, end=%s' % (str(begin), str(end)))
for addr in range(begin, end+1):
trace_map[addr] = True
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)
# set_tty_in(filename)
imlac_ttyin.mount(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)
# set_tty_out(filename)
imlac_ttyout.mount(filename)
elif opt == '-v':
if ndx >= len_sys_argv:
usage("'-v' option needs a following address filename")
@@ -199,7 +260,8 @@ def main():
else:
usage("'-v' option needs a following 'on' or 'off'")
sys.exit(10)
set_rom_write(state)
# set_rom_write(state)
imlac_memory.set_ROM_writable(state)
if __name__ == '__main__':

View File

@@ -12,6 +12,7 @@ where <filename> is a file of test instructions and
"""
import time
import collections
# We implement a small interpreter to test the CPU.
# The DSL is documented here: [github.com/rzzzwilson/pymlac].
@@ -146,6 +147,7 @@ class TestCPU(object):
# dismount <device>
# checkfile <file1> <file2>
# dumpmem file begin,end
# cmpmem file
def setreg(self, name, value):
"""Set register to a value.
@@ -387,7 +389,7 @@ class TestCPU(object):
else:
return 'mount: bad device: %s' % device
def dismount(self, device):
def dismount(self, device, ignore):
"""Dismount a file from a device.
device name of device
@@ -441,6 +443,9 @@ class TestCPU(object):
with open(filename, 'wb') as handle:
json.dump(mem, handle)
def cmpmem(self, filename, ignore):
pass
# end of DSL primitives
def check_all_mem(self):
@@ -597,7 +602,9 @@ class TestCPU(object):
elif opcode == 'checkfile':
r = self.checkfile(fld1, fld2)
elif opcode == 'dumpmem':
r = self.checkfile(fld1, fld2)
r = self.dumpmem(fld1, fld2)
elif opcode == 'cmpmem':
r = self.cmpmem(fld1, fld2)
else:
print("Unrecognized opcode '%s' in: %s" % (opcode, test))
raise Exception("Unrecognized opcode '%s' in: %s" % (opcode, test))