testing tweaks

This commit is contained in:
folkert van heusden 2024-03-28 22:00:12 +01:00
parent 0bc17c628a
commit 1e91bb9814
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
6 changed files with 2332 additions and 17 deletions

View file

@ -428,7 +428,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
else else
temp = m->readWord(m_offset); temp = m->readWord(m_offset);
if (!peek_only) DOLOG(debug, false, "READ from %06o/%07o %c %c: %o", addr_in, m_offset, space == d_space ? 'D' : 'I', word_mode ? 'B' : 'W', temp); if (!peek_only) DOLOG(debug, false, "READ from %06o/%07o %c %c: %o (%s)", addr_in, m_offset, space == d_space ? 'D' : 'I', word_mode ? 'B' : 'W', temp, mode_selection == rm_prev ? "prev" : "cur");
return temp; return temp;
} }
@ -644,6 +644,9 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c
DOLOG(debug, !peek_only, "virtual address %06o maps to physical address %08o (run_mode: %d, apf: %d, par: %08o, poff: %o, AC: %d, %s)", a, m_offset, run_mode, apf, pages[run_mode][d][apf].par * 64, p_offset, pages[run_mode][d][apf].pdr & 7, d ? "D" : "I"); DOLOG(debug, !peek_only, "virtual address %06o maps to physical address %08o (run_mode: %d, apf: %d, par: %08o, poff: %o, AC: %d, %s)", a, m_offset, run_mode, apf, pages[run_mode][d][apf].par * 64, p_offset, pages[run_mode][d][apf].pdr & 7, d ? "D" : "I");
} }
else {
// DOLOG(debug, false, "no MMU (read physical address %08o)", m_offset);
}
return m_offset; return m_offset;
} }

View file

@ -206,6 +206,12 @@ uint16_t cpu::lowlevel_register_get(const uint8_t set, const uint8_t reg)
return pc; return pc;
} }
void cpu::lowlevel_register_sp_set(const uint8_t set, const uint16_t value)
{
assert(set < 4);
sp[set] = value;
}
bool cpu::getBitPSW(const int bit) const bool cpu::getBitPSW(const int bit) const
{ {
return (psw >> bit) & 1; return (psw >> bit) & 1;

2274
cpu.cpp.new Normal file

File diff suppressed because it is too large Load diff

1
cpu.h
View file

@ -146,6 +146,7 @@ public:
void setRegisterLowByte(const int nr, const word_mode_t word_mode, const uint16_t value); void setRegisterLowByte(const int nr, const word_mode_t word_mode, const uint16_t value);
// used by 'main' for json-validation // used by 'main' for json-validation
void lowlevel_register_set(const uint8_t set, const uint8_t reg, const uint16_t value); void lowlevel_register_set(const uint8_t set, const uint8_t reg, const uint16_t value);
void lowlevel_register_sp_set(const uint8_t set, const uint16_t value);
uint16_t lowlevel_register_get(const uint8_t set, const uint8_t reg); uint16_t lowlevel_register_get(const uint8_t set, const uint8_t reg);
void lowlevel_psw_set(const uint16_t value) { psw = value; } void lowlevel_psw_set(const uint16_t value) { psw = value; }

View file

@ -2,15 +2,28 @@
import json import json
from machine import PDP1170 from machine import PDP1170
from mmio import MMIO
from pdptraps import PDPTrap, PDPTraps from pdptraps import PDPTrap, PDPTraps
import random import random
import sys 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): class PDP1170_wrapper(PDP1170):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.logger.info('')
self.reset_mem_transactions_dict() self.reset_mem_transactions_dict()
def reset_mem_transactions_dict(self): def reset_mem_transactions_dict(self):
@ -29,21 +42,25 @@ class PDP1170_wrapper(PDP1170):
def physRW(self, physaddr, value=None): def physRW(self, physaddr, value=None):
if value == None: # read 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: if not physaddr in self.mem_transactions and not physaddr in self.before:
self.before[physaddr] = random.randint(0, 65536) self.before[physaddr] = random.randint(0, 65536)
return super().physRW(physaddr, self.before[physaddr]) return super().physRW(physaddr, self.before[physaddr])
self.logger.info(f'Write to {physaddr:08o}: {value:06o} (phys)')
self.mem_transactions[physaddr] = value self.mem_transactions[physaddr] = value
return super().physRW(physaddr, value) return super().physRW(physaddr, value)
def physRW_N(self, physaddr, nwords, words=None): def physRW_N(self, physaddr, nwords, words=None):
temp_addr = physaddr temp_addr = physaddr
if words == None: if words == None:
self.logger.info(f'Read {nwords} words from {physaddr:08o} (phys)')
for i in range(nwords): for i in range(nwords):
self.physRW(temp_addr, random.randint(0, 65536)) self.physRW(temp_addr, random.randint(0, 65536))
temp_addr += 2 temp_addr += 2
return super().physRW_N(physaddr, nwords) return super().physRW_N(physaddr, nwords)
self.logger.info(f'Write {nwords} ({len(words)}) words to {physaddr:08o} (phys)')
for w in words: for w in words:
self.mem_transactions[temp_addr] = w self.mem_transactions[temp_addr] = w
temp_addr += 2 temp_addr += 2
@ -69,15 +86,17 @@ class test_generator:
out = { } out = { }
p = PDP1170_wrapper(loglevel='DEBUG') p = PDP1170_wrapper(loglevel='DEBUG')
p.ub.mmio = MMIO_wrapper(p)
addr = random.randint(0, 65536) & ~3
# TODO what is the maximum size of an instruction? # 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 = [] mem_kv = []
while True: while True:
instr = random.randint(0, 65536 - 8) instr = random.randint(0, 65536 - 8)
if instr != 1: # TODO ignore 'WAIT' instruction if instr != 1: # TODO ignore 'WAIT' instruction
break break
p.logger.info(f'emulating {instr:06o}')
mem_kv.append((addr + 0, instr)) mem_kv.append((addr + 0, instr))
mem_kv.append((addr + 2, random.randint(0, 65536 - 8))) mem_kv.append((addr + 2, random.randint(0, 65536 - 8)))
mem_kv.append((addr + 4, random.randint(0, 65536 - 8))) mem_kv.append((addr + 4, random.randint(0, 65536 - 8)))
@ -129,8 +148,6 @@ class test_generator:
out['memory-after'][a] = mem_transactions[a] out['memory-after'][a] = mem_transactions[a]
# TODO originele geheugeninhouden checken # TODO originele geheugeninhouden checken
# TODO check if mem_transactions affects I/O, then return None
return out return out
except PDPTraps.ReservedInstruction as pri: except PDPTraps.ReservedInstruction as pri:
@ -146,11 +163,15 @@ fh = open(sys.argv[1], 'w')
t = test_generator() t = test_generator()
tests = [] tests = []
for i in range(0, 131072): try:
print(f'{i}\r', end='') for i in range(0, 10072):
test = t.create_test() print(f'{i}\r', end='')
if test != None: test = t.create_test()
tests.append(test) if test != None:
tests.append(test)
except KeyboardInterrupt as ki:
pass
fh.write(json.dumps(tests, indent=4)) fh.write(json.dumps(tests, indent=4))
fh.close() fh.close()

View file

@ -106,13 +106,23 @@ int run_cpu_validation(const std::string & filename)
start_pc = json_integer_value(b_pc); start_pc = json_integer_value(b_pc);
c->setPC(start_pc); c->setPC(start_pc);
} }
{
// TODO SP[] json_t *b_sp = json_object_get(registers_before, "sp");
size_t array_size = json_array_size(b_sp);
assert(array_size == 4);
for(size_t i=0; i<array_size; i++) {
json_t *temp = json_array_get(b_sp, i);
c->lowlevel_register_sp_set(i, json_integer_value(temp));
}
}
c->step_a(); c->step_a();
disassemble(c, nullptr, c->getPC(), false); disassemble(c, nullptr, start_pc, false);
auto disas_data = c->disassemble(start_pc);
c->step_b(); c->step_b();
uint16_t new_pc = c->getPC();
// validate // validate
{ {
bool err = false; bool err = false;
@ -157,8 +167,8 @@ int run_cpu_validation(const std::string & filename)
json_t *a_pc = json_object_get(registers_after, "pc"); json_t *a_pc = json_object_get(registers_after, "pc");
assert(a_pc); assert(a_pc);
uint16_t should_be_pc = json_integer_value(a_pc); uint16_t should_be_pc = json_integer_value(a_pc);
if (c->getPC() != should_be_pc) { if (new_pc != should_be_pc) {
DOLOG(warning, true, "PC register mismatch (is: %06o (%d), should be: %06o (%d))", c->getPC(), c->getPC(), should_be_pc, should_be_pc); DOLOG(warning, true, "PC register mismatch (is: %06o (%d), should be: %06o (%d))", new_pc, new_pc, should_be_pc, should_be_pc);
err = true; err = true;
} }
} }
@ -179,8 +189,7 @@ int run_cpu_validation(const std::string & filename)
if (c->is_it_a_trap()) if (c->is_it_a_trap())
DOLOG(warning, true, "Error by TRAP"); DOLOG(warning, true, "Error by TRAP");
else { else {
auto data = c->disassemble(start_pc); DOLOG(warning, true, "Error by instruction %s", disas_data["instruction-text"].at(0).c_str());
DOLOG(warning, true, "Error by instruction %s", data["instruction-text"].at(0).c_str());
} }
char *js = json_dumps(test, 0); char *js = json_dumps(test, 0);
@ -188,6 +197,7 @@ int run_cpu_validation(const std::string & filename)
free(js); free(js);
} }
else { else {
DOLOG(info, true, "\n"); // \n!
n_ok++; n_ok++;
} }
} }