KEK/json/produce-json.py
folkert van heusden 1d57cade27
reduce output
2024-03-29 09:49:24 +01:00

178 lines
5.4 KiB
Python
Executable file

#! /usr/bin/python3
import json
from machine import PDP1170
from mmio import MMIO
from pdptraps import PDPTrap, PDPTraps
import random
import sys
class MMIO_wrapper(MMIO):
def register(self, iofunc, offsetaddr, nwords, *, byte_writes=False, reset=False):
pass
def register_simpleattr(self, obj, attrname, addr, reset=False):
pass
def devicereset_register(self, func):
pass
class PDP1170_wrapper(PDP1170):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.logger.info('')
self.reset_mem_transactions_dict()
def reset_mem_transactions_dict(self):
self.mem_transactions = dict()
self.before = dict()
def get_mem_before(self):
return self.before
def get_mem_transactions_dict(self):
return self.mem_transactions
def put(self, physaddr, value):
self.before[physaddr] = value
super().physRW(physaddr, value)
def physRW(self, physaddr, value=None):
if value == None: # read
self.logger.info(f'Read from {physaddr:08o} (phys)')
if not physaddr in self.mem_transactions and not physaddr in self.before:
self.before[physaddr] = random.randint(0, 65536)
return super().physRW(physaddr, self.before[physaddr])
self.logger.info(f'Write to {physaddr:08o}: {value:06o} (phys)')
self.mem_transactions[physaddr] = value
return super().physRW(physaddr, value)
def physRW_N(self, physaddr, nwords, words=None):
temp_addr = physaddr
if words == None:
self.logger.info(f'Read {nwords} words from {physaddr:08o} (phys)')
for i in range(nwords):
self.physRW(temp_addr, random.randint(0, 65536))
temp_addr += 2
return super().physRW_N(physaddr, nwords)
self.logger.info(f'Write {nwords} ({len(words)}) words to {physaddr:08o} (phys)')
for w in words:
self.mem_transactions[temp_addr] = w
temp_addr += 2
return super().physRW_N(physaddr, nwords, words=words)
class test_generator:
def _invoke_bp(self, a, i):
return True
def put_registers(self, p, target, tag):
target[tag] = dict()
target[tag][0] = dict()
target[tag][1] = dict()
for set_ in range(0, 2):
for reg_ in range(0, 6):
target[tag][set_][reg_] = p.registerfiles[set_][reg_]
target[tag]['sp'] = p.stackpointers
target[tag]['pc'] = p.r[p.PC]
def create_test(self):
out = { }
p = PDP1170_wrapper(loglevel='DEBUG')
p.ub.mmio = MMIO_wrapper(p)
# TODO what is the maximum size of an instruction?
# non-mmu thus shall be below device range
addr = random.randint(0, 0o160000 - 8) & ~3
mem_kv = []
while True:
instr = random.randint(0, 65536 - 8)
if instr != 1: # TODO ignore 'WAIT' instruction
break
p.logger.info(f'emulating {instr:06o}')
mem_kv.append((addr + 0, instr))
mem_kv.append((addr + 2, random.randint(0, 65536 - 8)))
mem_kv.append((addr + 4, random.randint(0, 65536 - 8)))
mem_kv.append((addr + 6, random.randint(0, 65536 - 8)))
out['memory-before'] = dict()
for a, v in mem_kv:
p.put(a, v)
try:
# generate & set PSW
while True:
try:
p.psw = random.randint(0, 65536)
break
except PDPTraps.ReservedInstruction as ri:
pass
# generate other registers
reg_kv = []
for i in range(7):
reg_kv.append((i, random.randint(0, 65536)))
reg_kv.append((7, addr))
# set registers
set_ = (p.psw >> 11) & 1
for r, v in reg_kv:
p.registerfiles[set_][r] = v
p.registerfiles[1 - set_][r] = (~v) & 65535 # make sure it triggers errors
assert p.registerfiles[set_][r] == p.r[r]
p.r[6] = p.registerfiles[set_][6]
p.r[p.PC] = addr
p._syncregs()
self.put_registers(p, out, 'registers-before')
out['registers-before']['psw'] = p.psw
p.run_steps(pc=addr, steps=1)
self.put_registers(p, out, 'registers-after')
out['registers-after']['psw'] = p.psw
mb = p.get_mem_before()
for a in mb:
out['memory-before'][a] = mb[a]
out['memory-after'] = dict()
mem_transactions = p.get_mem_transactions_dict()
for a in mem_transactions:
out['memory-after'][a] = mem_transactions[a]
# TODO originele geheugeninhouden checken
return out
except PDPTraps.ReservedInstruction as pri:
return None
except Exception as e:
# handle PDP11 traps; store them
print(f'test failed {e}, line number: {e.__traceback__.tb_lineno}')
return None
fh = open(sys.argv[1], 'w')
t = test_generator()
tests = []
try:
for i in range(32768):
if (i & 63) == 0:
print(f'{i}\r', end='')
test = t.create_test()
if test != None:
tests.append(test)
except KeyboardInterrupt as ki:
pass
fh.write(json.dumps(tests, indent=4))
fh.close()