POC
This commit is contained in:
parent
72ee580d19
commit
93119054fa
6 changed files with 132 additions and 21 deletions
12
bus.cpp
12
bus.cpp
|
@ -269,7 +269,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
|
|||
return temp;
|
||||
}
|
||||
if (a == ADDR_KERNEL_SP) { // kernel SP
|
||||
uint16_t temp = c->getStackPointer(0) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||
uint16_t temp = c->get_stackpointer(0) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||
TRACE("READ-I/O kernel SP: %06o", temp);
|
||||
return temp;
|
||||
}
|
||||
|
@ -279,12 +279,12 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
|
|||
return temp;
|
||||
}
|
||||
if (a == ADDR_SV_SP) { // supervisor SP
|
||||
uint16_t temp = c->getStackPointer(1) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||
uint16_t temp = c->get_stackpointer(1) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||
TRACE("READ-I/O supervisor SP: %06o", temp);
|
||||
return temp;
|
||||
}
|
||||
if (a == ADDR_USER_SP) { // user SP
|
||||
uint16_t temp = c->getStackPointer(3) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||
uint16_t temp = c->get_stackpointer(3) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||
TRACE("READ-I/O user SP: %06o", temp);
|
||||
return temp;
|
||||
}
|
||||
|
@ -625,7 +625,7 @@ bool bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint16_t va
|
|||
}
|
||||
if (a == ADDR_KERNEL_SP) { // kernel SP
|
||||
TRACE("WRITE-I/O kernel SP: %06o", value);
|
||||
c->setStackPointer(0, value);
|
||||
c->set_stackpointer(0, value);
|
||||
return false;
|
||||
}
|
||||
if (a == ADDR_PC) { // PC
|
||||
|
@ -635,12 +635,12 @@ bool bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint16_t va
|
|||
}
|
||||
if (a == ADDR_SV_SP) { // supervisor SP
|
||||
TRACE("WRITE-I/O supervisor sp: %06o", value);
|
||||
c->setStackPointer(1, value);
|
||||
c->set_stackpointer(1, value);
|
||||
return false;
|
||||
}
|
||||
if (a == ADDR_USER_SP) { // user SP
|
||||
TRACE("WRITE-I/O user sp: %06o", value);
|
||||
c->setStackPointer(3, value);
|
||||
c->set_stackpointer(3, value);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
console_posix::console_posix(std::atomic_uint32_t *const stop_event): console(stop_event)
|
||||
{
|
||||
#if !defined(_WIN32)
|
||||
if (tcgetattr(STDIN_FILENO, &org_tty_opts) == -1)
|
||||
if (tcgetattr(STDIN_FILENO, &org_tty_opts) == -1 && errno != ENOTTY)
|
||||
error_exit(true, "console_posix: tcgetattr failed");
|
||||
|
||||
struct termios tty_opts_raw { };
|
||||
cfmakeraw(&tty_opts_raw);
|
||||
|
||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw) == -1)
|
||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw) == -1 && errno != ENOTTY)
|
||||
error_exit(true, "console_posix: tcsetattr failed");
|
||||
|
||||
setvbuf(stdin, nullptr, _IONBF, 0);
|
||||
|
@ -37,7 +37,7 @@ console_posix::~console_posix()
|
|||
stop_thread();
|
||||
|
||||
#if !defined(_WIN32)
|
||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &org_tty_opts) == -1)
|
||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &org_tty_opts) == -1 && errno != ENOTTY)
|
||||
error_exit(true, "~console_posix: tcsetattr failed");
|
||||
#endif
|
||||
}
|
||||
|
@ -66,7 +66,6 @@ int console_posix::wait_for_char_ll(const short timeout)
|
|||
void console_posix::put_char_ll(const char c)
|
||||
{
|
||||
printf("%c", c);
|
||||
|
||||
fflush(nullptr);
|
||||
}
|
||||
|
||||
|
|
12
cpu.cpp
12
cpu.cpp
|
@ -98,10 +98,8 @@ uint64_t cpu::get_instructions_executed_count() const
|
|||
std::tuple<double, double, uint64_t, uint32_t, double> cpu::get_mips_rel_speed(const std::optional<uint64_t> & instruction_count, const std::optional<uint64_t> & t_diff_in) const
|
||||
{
|
||||
uint64_t instr_count = instruction_count.has_value() ? instruction_count.value() : get_instructions_executed_count();
|
||||
|
||||
uint64_t t_diff = t_diff_in.has_value() ? t_diff_in.value() : (get_us() - running_since - wait_time);
|
||||
|
||||
double mips = t_diff ? instr_count / double(t_diff) : 0;
|
||||
uint64_t t_diff = t_diff_in.has_value() ? t_diff_in.value() : (get_us() - running_since - wait_time);
|
||||
double mips = t_diff ? instr_count / double(t_diff) : 0;
|
||||
|
||||
return { mips, mips * 100 / pdp11_estimated_mips, instr_count, t_diff, wait_time };
|
||||
}
|
||||
|
@ -117,7 +115,6 @@ void cpu::add_to_stack_trace(const uint16_t p)
|
|||
auto da = disassemble(p);
|
||||
|
||||
stacktrace.push_back({ p, da["instruction-text"][0] });
|
||||
|
||||
while (stacktrace.size() >= max_stacktrace_depth)
|
||||
stacktrace.erase(stacktrace.begin());
|
||||
}
|
||||
|
@ -136,11 +133,14 @@ std::vector<std::pair<uint16_t, std::string> > cpu::get_stack_trace() const
|
|||
void cpu::reset()
|
||||
{
|
||||
memset(regs0_5, 0x00, sizeof regs0_5);
|
||||
memset(sp, 0x00, sizeof sp);
|
||||
memset(sp, 0x00, sizeof sp );
|
||||
pc = 0;
|
||||
psw = 0; // 7 << 5;
|
||||
fpsr = 0;
|
||||
init_interrupt_queue();
|
||||
|
||||
it_is_a_trap = false;
|
||||
processing_trap_depth = 0;
|
||||
}
|
||||
|
||||
uint16_t cpu::get_register(const int nr) const
|
||||
|
|
7
cpu.h
7
cpu.h
|
@ -179,8 +179,10 @@ public:
|
|||
uint16_t getStackLimitRegister() { return stackLimitRegister; }
|
||||
void setStackLimitRegister(const uint16_t v) { stackLimitRegister = v; }
|
||||
|
||||
uint16_t getStackPointer(const int which) const { assert(which >= 0 && which < 4); return sp[which]; }
|
||||
uint16_t get_stackpointer(const int which) const { assert(which >= 0 && which < 4); return sp[which]; }
|
||||
uint16_t getPC() const { return pc; }
|
||||
void set_stackpointer(const int which, const uint16_t value) { assert(which >= 0 && which < 4); sp[which] = value; }
|
||||
void setPC(const uint16_t value) { pc = value; }
|
||||
|
||||
void set_register(const int nr, const uint16_t value);
|
||||
void set_registerLowByte(const int nr, const word_mode_t word_mode, const uint16_t value);
|
||||
|
@ -191,9 +193,6 @@ public:
|
|||
void lowlevel_psw_set(const uint16_t value) { psw = value; }
|
||||
uint16_t lowlevel_register_sp_get(const uint8_t nr) const { return sp[nr]; }
|
||||
|
||||
void setStackPointer(const int which, const uint16_t value) { assert(which >= 0 && which < 4); sp[which] = value; }
|
||||
void setPC(const uint16_t value) { pc = value; }
|
||||
|
||||
uint16_t get_register(const int nr) const;
|
||||
|
||||
bool put_result(const gam_rc_t & g, const uint16_t value);
|
||||
|
|
37
debugger.cpp
37
debugger.cpp
|
@ -729,6 +729,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
int32_t trace_start_addr = -1;
|
||||
int n_single_step = 1;
|
||||
bool turbo = false;
|
||||
bool marker = false;
|
||||
std::optional<int> t_rl; // trace runlevel
|
||||
|
||||
cpu *const c = b->getCpu();
|
||||
|
@ -739,6 +740,9 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
|
||||
while(*stop_event != EVENT_TERMINATE) {
|
||||
try {
|
||||
if (marker)
|
||||
cnsl->put_string_lf("---");
|
||||
|
||||
std::string cmd = cnsl->read_line(format("%d", stop_event->load()));
|
||||
auto parts = split(cmd, " ");
|
||||
auto kv = split(parts, "=");
|
||||
|
@ -751,7 +755,9 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
|
||||
*stop_event = EVENT_NONE;
|
||||
}
|
||||
else if (parts[0] == "single" || parts[0] == "s") {
|
||||
else if (cmd == "marker")
|
||||
marker = !marker;
|
||||
else if (parts[0] == "single" || parts[0] == "s" || parts[0] == "step") {
|
||||
single_step = true;
|
||||
|
||||
if (parts.size() == 2)
|
||||
|
@ -860,6 +866,32 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
|
||||
continue;
|
||||
}
|
||||
else if (parts[0] == "setstack") {
|
||||
if (parts.size() == 3) {
|
||||
int reg = std::stoi(parts.at(1));
|
||||
uint16_t val = std::stoi(parts.at(2), nullptr, 8);
|
||||
if (reg < 4) {
|
||||
c->set_stackpointer(reg, val);
|
||||
cnsl->put_string_lf(format("Set stack register %d to %06o", reg, val));
|
||||
}
|
||||
}
|
||||
else {
|
||||
cnsl->put_string_lf("setstack requires a register and an octal value");
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (parts[0] == "getstack") {
|
||||
if (parts.size() == 2) {
|
||||
int reg = std::stoi(parts.at(1));
|
||||
cnsl->put_string_lf(format("REG %d = %06o", reg, c->get_stackpointer(reg)));
|
||||
}
|
||||
else {
|
||||
cnsl->put_string_lf("getreg requires a stack register");
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (parts[0] == "setpsw") {
|
||||
if (parts.size() == 2) {
|
||||
uint16_t val = std::stoi(parts.at(1), nullptr, 8);
|
||||
|
@ -1031,6 +1063,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
else if (cmd == "reset" || cmd == "r") {
|
||||
*stop_event = EVENT_NONE;
|
||||
b->reset();
|
||||
cnsl->put_string_lf("resetted");
|
||||
continue;
|
||||
}
|
||||
else if (cmd == "cfgdisk") {
|
||||
|
@ -1285,6 +1318,8 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
"getpc -",
|
||||
"setreg x y - set register x to value y (octal)",
|
||||
"getreg x -",
|
||||
"setstack x y - set stack register x to value y (octal)",
|
||||
"getstack x -",
|
||||
"setpsw x - set PSW value y (octal)",
|
||||
"getpsw -",
|
||||
"setmem ... - set memory (a=) to value (v=), both in octal, one byte",
|
||||
|
|
78
run-json.py
Executable file
78
run-json.py
Executable file
|
@ -0,0 +1,78 @@
|
|||
#! /usr/bin/python3
|
||||
|
||||
import json
|
||||
from subprocess import Popen, PIPE
|
||||
import sys
|
||||
|
||||
debug = False
|
||||
|
||||
def docmd(p, str):
|
||||
p.stdin.write((str + "\n").encode('ascii'))
|
||||
|
||||
pl = None
|
||||
while True:
|
||||
line = p.stdout.readline()
|
||||
line = line.decode('ascii', 'ignore').rstrip('\n').strip('\r')
|
||||
if debug:
|
||||
print(f'|{line}|')
|
||||
|
||||
if line == '---':
|
||||
return pl
|
||||
|
||||
pl = line
|
||||
|
||||
process = Popen(['./build/kek', '-d', '-L', 'emergency,debug', '-t', '-l', sys.argv[2]], stdin=PIPE, stdout=PIPE, stderr=PIPE, bufsize=0)
|
||||
docmd(process, 'marker')
|
||||
|
||||
test_file = sys.argv[1]
|
||||
j = json.loads(open(test_file, 'rb').read())
|
||||
|
||||
error_nr = 0
|
||||
test_nr = 0
|
||||
diffs = []
|
||||
|
||||
for set in j:
|
||||
test_nr += 1
|
||||
if not 'id' in set:
|
||||
continue
|
||||
name = set['id']
|
||||
|
||||
print(name)
|
||||
|
||||
# initialize
|
||||
|
||||
docmd(process, 'reset')
|
||||
before = set['before']
|
||||
|
||||
before_mem = before['memory']
|
||||
for m_entry in before_mem:
|
||||
for key, val in m_entry.items():
|
||||
addr = int(key, 8)
|
||||
docmd(process, f'setmem a={addr:o} v={val & 255:o}')
|
||||
docmd(process, f'setmem a={addr + 1:o} v={val >> 8:o}')
|
||||
|
||||
docmd(process, f'setpc {int(before["PC"]):o}')
|
||||
docmd(process, f'setpsw {int(before["PSW"]):o}')
|
||||
|
||||
#for s in range(0, 2):
|
||||
s = 0
|
||||
for reg in range(0, 6):
|
||||
key = f'reg-{reg}.{s}'
|
||||
docmd(process, f'setreg {reg} {int(before[key]):o}')
|
||||
|
||||
docmd(process, f'setstack 0 {int(before["stack-0"]):o}')
|
||||
docmd(process, f'setstack 1 {int(before["stack-1"]):o}')
|
||||
docmd(process, f'setstack 2 {int(before["stack-2"]):o}')
|
||||
docmd(process, f'setstack 3 {int(before["stack-3"]):o}')
|
||||
|
||||
# invoke!
|
||||
docmd(process, 'step')
|
||||
|
||||
# check
|
||||
|
||||
process.stdin.write(("q\n").encode('ascii'))
|
||||
process.terminate()
|
||||
time.sleep(0.5)
|
||||
process.kill()
|
||||
|
||||
sys.exit(1 if error_nr > 0 else 0)
|
Loading…
Add table
Reference in a new issue