diff --git a/bus.cpp b/bus.cpp index 1dc49cd..614272d 100644 --- a/bus.cpp +++ b/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; } diff --git a/console_posix.cpp b/console_posix.cpp index 0996dda..fa517d4 100644 --- a/console_posix.cpp +++ b/console_posix.cpp @@ -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); } diff --git a/cpu.cpp b/cpu.cpp index a02969f..89bbc72 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -98,10 +98,8 @@ uint64_t cpu::get_instructions_executed_count() const std::tuple cpu::get_mips_rel_speed(const std::optional & instruction_count, const std::optional & 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 > 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 diff --git a/cpu.h b/cpu.h index df2d89a..f0db784 100644 --- a/cpu.h +++ b/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); diff --git a/debugger.cpp b/debugger.cpp index 8d07ef3..b2a752a 100644 --- a/debugger.cpp +++ b/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 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", diff --git a/run-json.py b/run-json.py new file mode 100755 index 0000000..38789e7 --- /dev/null +++ b/run-json.py @@ -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)