testing tweaks
This commit is contained in:
parent
0bc17c628a
commit
1e91bb9814
6 changed files with 2332 additions and 17 deletions
5
bus.cpp
5
bus.cpp
|
@ -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;
|
||||
}
|
||||
|
|
6
cpu.cpp
6
cpu.cpp
|
@ -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
2274
cpu.cpp.new
Normal file
File diff suppressed because it is too large
Load diff
1
cpu.h
1
cpu.h
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
24
main.cpp
24
main.cpp
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue