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
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;
}
@ -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");
}
else {
// DOLOG(debug, false, "no MMU (read physical address %08o)", 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;
}
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
{
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);
// 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_sp_set(const uint8_t set, const uint16_t value);
uint16_t lowlevel_register_get(const uint8_t set, const uint8_t reg);
void lowlevel_psw_set(const uint16_t value) { psw = value; }

View file

@ -2,15 +2,28 @@
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):
@ -29,21 +42,25 @@ class PDP1170_wrapper(PDP1170):
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
@ -69,15 +86,17 @@ class test_generator:
out = { }
p = PDP1170_wrapper(loglevel='DEBUG')
addr = random.randint(0, 65536) & ~3
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)))
@ -129,8 +148,6 @@ class test_generator:
out['memory-after'][a] = mem_transactions[a]
# TODO originele geheugeninhouden checken
# TODO check if mem_transactions affects I/O, then return None
return out
except PDPTraps.ReservedInstruction as pri:
@ -146,11 +163,15 @@ fh = open(sys.argv[1], 'w')
t = test_generator()
tests = []
for i in range(0, 131072):
try:
for i in range(0, 10072):
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()

View file

@ -106,13 +106,23 @@ int run_cpu_validation(const std::string & filename)
start_pc = json_integer_value(b_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();
disassemble(c, nullptr, c->getPC(), false);
disassemble(c, nullptr, start_pc, false);
auto disas_data = c->disassemble(start_pc);
c->step_b();
uint16_t new_pc = c->getPC();
// validate
{
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");
assert(a_pc);
uint16_t should_be_pc = json_integer_value(a_pc);
if (c->getPC() != 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);
if (new_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;
}
}
@ -179,8 +189,7 @@ int run_cpu_validation(const std::string & filename)
if (c->is_it_a_trap())
DOLOG(warning, true, "Error by TRAP");
else {
auto data = c->disassemble(start_pc);
DOLOG(warning, true, "Error by instruction %s", data["instruction-text"].at(0).c_str());
DOLOG(warning, true, "Error by instruction %s", disas_data["instruction-text"].at(0).c_str());
}
char *js = json_dumps(test, 0);
@ -188,6 +197,7 @@ int run_cpu_validation(const std::string & filename)
free(js);
}
else {
DOLOG(info, true, "\n"); // \n!
n_ok++;
}
}