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

Getting close, found unwanted writes to address 0

This commit is contained in:
Ross Wilson 2015-06-12 14:17:55 +07:00
parent 01e22d09c8
commit f53ceca121
3 changed files with 242 additions and 58 deletions

View File

@ -1,26 +1,2 @@
# LAW
setreg ac 012345; setreg l 1; setreg pc 0100; setmem 0100 [LAW 0]; RUN
checkcycles 1; checkreg pc 0101; checkreg ac 0
setreg ac 012345; setreg l 0; setreg pc 0100; setmem 0100 [LAW 0]; RUN
checkcycles 1; checkreg pc 0101; checkreg ac 0
setreg ac 012345; setreg l 1; setreg pc 0100; setmem 0100 [LAW 0377]; RUN
checkcycles 1; checkreg pc 0101; checkreg ac 0377
setreg ac 012345; setreg l 0; setreg pc 0100; setmem 0100 [LAW 0377]; RUN
checkcycles 1; checkreg pc 0101; checkreg ac 0377
# LWC
setreg ac 012345; setreg l 1; setreg pc 0100; setmem 0100 [LWC 0]; RUN; checkcycles 1; checkreg pc 0101; checkreg ac 0177777
setreg ac 012345; setreg l 0; setreg pc 0100; setmem 0100 [LWC 0]; RUN; checkcycles 1; checkreg pc 0101; checkreg ac 0177777
setreg ac 012345; setreg l 1; setreg pc 0100; setmem 0100 [LWC 1]; RUN; checkcycles 1; checkreg pc 0101; checkreg ac 0177776
setreg ac 012345; setreg l 0; setreg pc 0100; setmem 0100 [LWC 1]; RUN; checkcycles 1; checkreg pc 0101; checkreg ac 0177776
# JMP
setreg ac 012345; setreg l 1; setreg pc 0100; setmem 0100 [JMP 0200]; RUN; checkcycles 2; checkreg pc 0200
setreg ac 012345; setreg l 0; setreg pc 0100; setmem 0100 [JMP 0110]; RUN; checkcycles 2; checkreg pc 0110
setreg ac 012345; setreg l 1; setreg pc 0100; setmem 0100 [JMP *0110]; setmem 0110 0120; RUN; checkcycles 3; checkreg pc 0120
setreg ac 012345; setreg l 1; setreg pc 0100; setmem 0100 [JMP *010]; setmem 010 0120; RUN checkcycles 3; checkreg pc 0120; checkmem 010 0121
# DAC
setreg ac 1; setreg l 1; setreg pc 0100; setmem 0100 [DAC 0110]; RUN
checkcycles 2; checkreg pc 0101; checkmem 0110 1
setreg ac 0177777; setreg l 0; setreg pc 0100; setmem 0100 [DAC *0110]; setmem 0110 0120; RUN
checkcycles 3; checkreg pc 0101; checkmem 0120 0177777
setreg ac 0177777; setreg l 1; setreg pc 0100; setmem 0100 [DAC *010]; setmem 010 0120; RUN
checkcycles 3; checkreg pc 0101; checkmem 0120 0177777; checkmem 010 0121
checkcycles 3; checkreg pc 0101; checkmem 0121 0177777; checkmem 010 0121

View File

@ -221,7 +221,6 @@ def fetch(address, indirect):
return memory[address]
def eff_address(address, indirect):
#def get(address, indirect):
"""Get an effective memory address.
The address can be indirect, and may be through an

View File

@ -61,10 +61,56 @@ where <filename> is a file of test instructions and
# If any errors are found, print line followed by all errors.
import os
from Globals import *
import MainCPU
import Memory
import log
log = log.Log('test_CPU.log', log.Log.DEBUG)
# number of cycles used in previous instruction
UsedCycles = 0
# register+value explicitly set by test
RegValues = {}
# memory address+value explicitly set by test
MemValues = {}
# memory value all explicitly set to (shouldn't change)
MemAllValue = None
# registers value all explicitly set to (shouldn't change)
RegAllValue = None
# temporary assembler file and listfile prefix
AsmFilename = '_#ASM#_'
def assemble(addr, opcode):
"""Assemble a single instruction, return opcode."""
# create ASM file with instruction
with open(AsmFilename+'.asm', 'wb') as fd:
fd.write('\torg\t%07o\n' % addr)
fd.write('\t%s\n' % opcode[1:-1])
fd.write('\tend\n')
# now assemble file
os.system('../iasm/iasm -l %s.lst %s.asm' % (AsmFilename, AsmFilename))
# read the listing file to get assembled opcode
with open(AsmFilename+'.lst', 'rb') as fd:
lines = fd.readlines()
line = lines[1]
(opcode, _) = line.split(None, 1)
print('opcode=%07o' % int(opcode, base=8))
return int(opcode, base=8)
def setreg(name, value):
"""Set register to a value.
@ -72,20 +118,44 @@ def setreg(name, value):
Remember value to check later.
"""
log.debug('setreg: name=%s, value=%s' % (name, oct(value)))
global RegValues
RegValues[name] = value
log.debug('setreg: After, RegValues=%s' % str(RegValues))
exec "MainCPU.%s = %07o" % (name, value)
if name == 'ac':
MainCPU.AC = value
log.debug('setreg: After, AC=%s' % oct(MainCPU.AC))
elif name == 'l':
MainCPU.L = value & 1
log.debug('setreg: After, L=%s' % oct(MainCPU.L))
elif name == 'pc':
MainCPU.PC = value
log.debug('setreg: After, PC=%s' % oct(MainCPU.PC))
def setmem(addr, value):
"""Set memory location to a value."""
if isinstance(value, basestring):
log.debug('setmem: addr=%s, value=%s' % (oct(addr), value))
else:
log.debug('setmem: addr=%s, value=%s' % (oct(addr), oct(value)))
global MemValues
MemValues[addr] = value
# check if we must assemble var2
if isinstance(value, basestring) and value[0] == '[':
# assemble an instruction
value = assemble(addr, value)
log.debug('setmem: assembled opcode=%07o' % value)
Memory.memory[addr] = value
MemValues[addr] = value
log.debug('setmem: After, MemValues=%s' % str(MemValues))
Memory.put(value, addr, False)
log.debug('setmem: After, Memory at %07o is %07o' % (addr, Memory.fetch(addr, False)))
def allmem(value):
@ -98,9 +168,8 @@ def allmem(value):
MemAllValue = value
for mem in range(PCMASK):
print str(mem)
Memory.memory[mem] = value
for mem in range(MEMORY_SIZE):
Memory.put(mem, value, False)
def allreg(value):
"""Set all registers to a value."""
@ -113,12 +182,105 @@ def allreg(value):
MainCPU.L = value & 1
MainCPU.PC = value
def check_all_mem():
"""Check memory for unwanted changes."""
for mem in range(MEMORY_SIZE):
if mem in MemValues:
continue
value = Memory.fetch(mem, False)
if value != MemAllValue:
return ('Changed memory at address %07o, is %07o, should be %07o'
% (mem, value, MemAllValue))
def check_all_regs():
"""Check registers for unwanted changes."""
result = []
if 'ac' not in RegValues:
if MainCPU.AC != RegAllValue:
result.append('AC changed, is %07o, should be %07o'
% (MainCPU.AC, RegAllValue))
if 'l' not in RegValues:
if MainCPU.L != RegAllValue & 1:
result.append('L changed, is %02o, should be %02o'
% (MainCPU.L, RegAllValue & 1))
if 'pc' not in RegValues:
if MainCPU.PC != RegAllValue:
result.append('PC changed, is %07o, should be %07o'
% (MainCPU.PC, RegAllValue))
if result:
return result.join('\n')
def checkreg(reg, value):
"""Check register is as it should be."""
global RegValues
RegValues[reg] = value
log.debug('checkreg: After, RegValues=%s' % str(RegValues))
if reg == 'ac':
if MainCPU.AC != value:
return 'AC wrong, is %07o, should be %07o' % (MainCPU.AC, value)
elif reg == 'l':
if MainCPU.L != value:
return 'L wrong, is %07o, should be %07o' % (MainCPU.L, value)
elif reg == 'pc':
if MainCPU.PC != value:
return 'AC wrong, is %07o, should be %07o' % (MainCPU.PC, value)
else:
raise Exception('checkreg: bad register name: %s' % name)
def checkmem(addr, value):
"""Check a memory location is as it should be."""
global MemValues
MemValues[addr] = value
log.debug('checkmem: After, MemValues=%s' % str(MemValues))
memvalue = Memory.fetch(addr, False)
if memvalue != value:
return 'Memory wrong at address %07o, is %07o, should be %07o' % (addr, memvalue, value)
def checkcycles(cycles, var2=None):
"""Check that opcode cycles used is correct."""
if cycles != UsedCycles:
return 'Opcode used %d cycles, expected %d' % (UsedCycles, cycles)
def run(addr, var2):
"""Execute instruction."""
global UsedCycles
if addr is not None:
# force PC to given address
setreg('pc', addr)
UsedCycles = MainCPU.execute_one_instruction()
def debug_operation(op, var1, var2):
"""Write operation to log file."""
if var1:
if var2:
log.debug('Operation: %s %s %s' % (op, var1, var2))
else:
log.debug('Operation: %s %s' % (op, var1))
else:
log.debug('Operation: %s' % op)
def execute(test):
"""Execute test string in 'test'."""
global RegValues, MemValues
global RegAllValue, MemAllValue
global Test
# set globals
RegValues = {}
@ -126,11 +288,15 @@ def execute(test):
RegAllValue = {}
MemAllValue = {}
Test = test
result = []
MainCPU.init()
MainCPU.running = True
Memory.init()
# clear memory and registers to 0 first
# allmem(0)
# allreg(0)
allmem(0)
allreg(0)
# interpret the test instructions
instructions = test.split(';')
@ -146,35 +312,77 @@ def execute(test):
except IndexError:
var2 = None
try:
if op == 'setreg':
setreg(var1, var2)
elif op == 'setmem':
setmem(var1, var2)
elif op == 'run':
run(var1, var2)
elif op == 'checkcycles':
checkcycles(var1, var2)
elif op == 'checkreg':
checkreg(var1, var2)
elif op == 'checkmem':
checkmem(var1, var2)
elif op == 'allreg':
allreg(var1, var2)
elif op == 'allmem':
allmem(var1, var2)
debug_operation(op, var1, var2)
# change var strings into numeric values
if var1 and var1[0] in '0123456789':
if var1[0] == '0':
var1 = int(var1, base=8)
else:
error('Unrecognized operation: %s' % test)
except CPUError:
pass
var1 = int(var1)
if var2 and var2[0] in '0123456789':
if var2[0] == '0':
var2 = int(var2, base=8)
else:
var2 = int(var2)
if op == 'setreg':
r = setreg(var1, var2)
elif op == 'setmem':
r = setmem(var1, var2)
elif op == 'run':
r = run(var1, var2)
elif op == 'checkcycles':
r = checkcycles(var1, var2)
elif op == 'checkreg':
r = checkreg(var1, var2)
elif op == 'checkmem':
r = checkmem(var1, var2)
elif op == 'allreg':
r = allreg(var1, var2)
elif op == 'allmem':
r = allmem(var1, var2)
else:
error('Unrecognized operation: %s' % test)
if r is not None:
result.append(r)
# now check all memory and regs for changes
check_all_mem()
check_all_regs()
r = check_all_mem()
if r:
result.append(r)
r = check_all_regs()
if r:
result.append(r)
print(test)
if result:
print('\t' + '\n\t'.join(result))
memdump('core.txt', 0, 0200)
def memdump(filename, start, number):
"""Dump memory from 'start' into 'filename', 'number' words dumped."""
with open(filename, 'wb') as fd:
for addr in range(start, start+number, 8):
a = addr
llen = min(8, start+number - addr)
line = '%04o ' % addr
for _ in range(llen):
line += '%06o ' % Memory.fetch(a, False)
a += 1
fd.write('%s\n' % line)
def main(filename):
"""Execute CPU tests from 'filename'."""
log.debug("Running test file '%s'" % filename)
# get all tests from file
with open(filename, 'rb') as fd:
lines = fd.readlines()
@ -203,6 +411,7 @@ def main(filename):
# now do each test
for test in tests:
log.debug('Executing test: %s' % test)
execute(test)