diff --git a/console.cpp b/console.cpp index 523ea84..2e5fe72 100644 --- a/console.cpp +++ b/console.cpp @@ -10,9 +10,8 @@ #include "utils.h" -console::console(std::atomic_bool *const terminate, std::atomic_bool *const interrupt_emulation, bus *const b) : - terminate(terminate), - interrupt_emulation(interrupt_emulation), +console::console(std::atomic_uint32_t *const stop_event, bus *const b) : + stop_event(stop_event), b(b) { memset(screen_buffer, ' ', sizeof screen_buffer); @@ -105,7 +104,7 @@ std::string console::read_line(const std::string & prompt) for(;;) { char c = wait_char(500); - if (*terminate || stop_thread_flag) + if (*stop_event == EVENT_TERMINATE) return ""; if (c == -1) @@ -208,9 +207,9 @@ void console::operator()() { D(fprintf(stderr, "Console thread started\n");) - set_thread_name("kek:console"); + set_thread_name("kek::console"); - while(!*terminate && !stop_thread_flag) { + while(*stop_event != EVENT_TERMINATE && !stop_thread_flag) { int c = wait_for_char_ll(100); if (c == -1) @@ -221,9 +220,9 @@ void console::operator()() // printf("%d %d\n", running_flag, c); if (running_flag == false && c == 3) // ^c - *interrupt_emulation = *terminate = true; + *stop_event = EVENT_TERMINATE; else if (running_flag == true && c == 5) // ^e - *interrupt_emulation = true; + *stop_event = EVENT_INTERRUPT; else if (running_flag == false && c == 12) // ^l refresh_virtual_terminal(); else { diff --git a/console.h b/console.h index 5ab1d2b..4aa32c5 100644 --- a/console.h +++ b/console.h @@ -19,8 +19,7 @@ private: std::mutex input_lock; protected: - std::atomic_bool *const terminate { nullptr }; - std::atomic_bool *const interrupt_emulation { nullptr }; + std::atomic_uint32_t *const stop_event { nullptr }; bus *const b { nullptr }; std::thread *th { nullptr }; @@ -41,7 +40,7 @@ protected: virtual void put_char_ll(const char c) = 0; public: - console(std::atomic_bool *const terminate, std::atomic_bool *const interrupt_emulation, bus *const b); + console(std::atomic_uint32_t *const stop_event, bus *const b); virtual ~console(); void start_thread(); diff --git a/console_ncurses.cpp b/console_ncurses.cpp index 6772319..79993e3 100644 --- a/console_ncurses.cpp +++ b/console_ncurses.cpp @@ -6,11 +6,12 @@ #include "console_ncurses.h" #include "cpu.h" #include "error.h" +#include "gen.h" #include "utils.h" -console_ncurses::console_ncurses(std::atomic_bool *const terminate, std::atomic_bool *const interrupt_emulation, bus *const b) : - console(terminate, interrupt_emulation, b) +console_ncurses::console_ncurses(std::atomic_uint32_t *const stop_event, bus *const b) : + console(stop_event, b) { init_ncurses(true); @@ -130,7 +131,7 @@ void console_ncurses::panel_update_thread() constexpr int refresh_rate = 50; - while(!*terminate) { + while(*stop_event != EVENT_TERMINATE) { myusleep(1000000 / refresh_rate); // note that these are approximately as there's no mutex on the emulation diff --git a/console_ncurses.h b/console_ncurses.h index 7f910c8..b8d7999 100644 --- a/console_ncurses.h +++ b/console_ncurses.h @@ -26,7 +26,7 @@ protected: void put_char_ll(const char c) override; public: - console_ncurses(std::atomic_bool *const terminate, std::atomic_bool *const interrupt_emulation, bus *const b); + console_ncurses(std::atomic_uint32_t *const stop_event, bus *const b); virtual ~console_ncurses(); void put_string_lf(const std::string & what) override; diff --git a/console_posix.cpp b/console_posix.cpp index 826232e..9d7b3b8 100644 --- a/console_posix.cpp +++ b/console_posix.cpp @@ -7,8 +7,8 @@ #include "error.h" -console_posix::console_posix(std::atomic_bool *const terminate, std::atomic_bool *const interrupt_emulation, bus *const b) : - console(terminate, interrupt_emulation, b) +console_posix::console_posix(std::atomic_uint32_t *const stop_event, bus *const b) : + console(stop_event, b) { if (tcgetattr(STDIN_FILENO, &org_tty_opts) == -1) error_exit(true, "console_posix: tcgetattr failed"); diff --git a/console_posix.h b/console_posix.h index 25954be..42890cd 100644 --- a/console_posix.h +++ b/console_posix.h @@ -14,7 +14,7 @@ protected: void put_char_ll(const char c) override; public: - console_posix(std::atomic_bool *const terminate, std::atomic_bool *const interrupt_emulation, bus *const b); + console_posix(std::atomic_uint32_t *const stop_event, bus *const b); virtual ~console_posix(); void resize_terminal() override; diff --git a/cpu.cpp b/cpu.cpp index 1a37fd1..f18fe8e 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -13,7 +13,7 @@ #define IS_0(x, wm) ((wm) ? ((x) & 0xff) == 0 : (x) == 0) -cpu::cpu(bus *const b, uint32_t *const event) : b(b), event(event) +cpu::cpu(bus *const b, std::atomic_uint32_t *const event) : b(b), event(event) { reset(); } @@ -1528,7 +1528,7 @@ bool cpu::misc_operations(const uint16_t instr) { switch(instr) { case 0b0000000000000000: // HALT - *event = 1; + *event = EVENT_HALT; return true; case 0b0000000000000001: // WAIT diff --git a/cpu.h b/cpu.h index 0d27c11..7380f99 100644 --- a/cpu.h +++ b/cpu.h @@ -34,7 +34,7 @@ private: bus *const b { nullptr }; - uint32_t *const event { nullptr }; + std::atomic_uint32_t *const event { nullptr }; bool check_queued_interrupts(); @@ -65,7 +65,7 @@ private: operand_parameters addressing_to_string(const uint8_t mode_register, const uint16_t pc, const bool word_mode) const; public: - explicit cpu(bus *const b, uint32_t *const event); + explicit cpu(bus *const b, std::atomic_uint32_t *const event); ~cpu(); bool check_breakpoint(); diff --git a/debugger.cpp b/debugger.cpp index 0295382..4836e7c 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -1,6 +1,7 @@ #include "bus.h" #include "console.h" #include "cpu.h" +#include "gen.h" #include "utils.h" @@ -8,9 +9,6 @@ void setBootLoader(bus *const b); #endif -extern uint32_t event; -extern std::atomic_bool terminate; - // returns size of instruction (in bytes) int disassemble(cpu *const c, console *const cnsl, const int pc, const bool instruction_only) { @@ -72,7 +70,7 @@ std::map split(const std::vector & kv_arr return out; } -void debugger(console *const cnsl, bus *const b, std::atomic_bool *const interrupt_emulation, const bool tracing_in) +void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const bool tracing_in) { int32_t trace_start_addr = -1; bool tracing = tracing_in; @@ -83,9 +81,8 @@ void debugger(console *const cnsl, bus *const b, std::atomic_bool *const interru bool single_step = false; - while(!terminate) { - bool temp = terminate; - std::string cmd = cnsl->read_line(format("%d%d", event, temp)); + while(*stop_event != EVENT_TERMINATE) { + std::string cmd = cnsl->read_line(format("%d", stop_event->load())); auto parts = split(cmd, " "); auto kv = split(parts, "="); @@ -184,9 +181,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_bool *const interru #if defined(ESP32) ESP.restart(); #else - terminate = false; - - event = 0; + *stop_event = EVENT_NONE; c->reset(); #endif @@ -222,7 +217,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_bool *const interru *cnsl->get_running_flag() = true; - while(!event && !*interrupt_emulation) { + while(*stop_event == EVENT_NONE) { c->step_a(); if (trace_start_addr != -1 && c->getPC() == trace_start_addr) @@ -249,12 +244,10 @@ void debugger(console *const cnsl, bus *const b, std::atomic_bool *const interru cnsl->debug("MIPS: %.2f, relative speed: %.2f%%", speed.first, speed.second); } - if (*interrupt_emulation) { + if (*stop_event == EVENT_INTERRUPT) { single_step = true; - event = 0; - - *interrupt_emulation = false; + *stop_event = EVENT_NONE; } } } diff --git a/debugger.h b/debugger.h index dd444f9..2fe3b8b 100644 --- a/debugger.h +++ b/debugger.h @@ -1,4 +1,4 @@ #include "bus.h" #include "console.h" -void debugger(console *const cnsl, bus *const b, std::atomic_bool *const interrupt_emulation, const bool tracing); +void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const bool tracing); diff --git a/gen.h b/gen.h index a5b3e2e..5b9423d 100644 --- a/gen.h +++ b/gen.h @@ -4,6 +4,8 @@ extern bool trace_output; +typedef enum { EVENT_NONE = 0, EVENT_HALT, EVENT_INTERRUPT, EVENT_TERMINATE } stop_event_t; + #if defined(ESP32) #define D(...) do { } while(0); #else diff --git a/main.cpp b/main.cpp index 5408588..602d8bf 100644 --- a/main.cpp +++ b/main.cpp @@ -24,8 +24,7 @@ typedef enum { BL_NONE, BL_RK05, BL_RL02 } bootloader_t; bool withUI { false }; -uint32_t event { 0 }; -std::atomic_bool terminate { false }; +std::atomic_uint32_t event { 0 }; std::atomic_bool *running { nullptr }; bool trace_output { false }; @@ -231,7 +230,7 @@ void sw_handler(int s) else { fprintf(stderr, "Terminating...\n"); - terminate = true; + event = EVENT_TERMINATE; } } @@ -342,13 +341,13 @@ int main(int argc, char *argv[]) std::atomic_bool interrupt_emulation { false }; if (withUI) - cnsl = new console_ncurses(&terminate, &interrupt_emulation, b); + cnsl = new console_ncurses(&event, b); else { fprintf(stderr, "This PDP-11 emulator is called \"kek\" (reason for that is forgotten) and was written by Folkert van Heusden.\n"); fprintf(stderr, "Built on: " __DATE__ " " __TIME__ "\n"); - cnsl = new console_posix(&terminate, &interrupt_emulation, b); + cnsl = new console_posix(&event, b); } if (rk05_files.empty() == false) @@ -390,19 +389,22 @@ int main(int argc, char *argv[]) cnsl->start_thread(); if (run_debugger) - debugger(cnsl, b, &interrupt_emulation, tracing); + debugger(cnsl, b, &event, tracing); else { c->emulation_start(); // for statistics *running = true; - // TODO combine event, interrupt_emulation and terminate into one thing - while(!event) { - if (interrupt_emulation) - break; + for(;;) { + while(!event) { + c->step_a(); + c->step_b(); + } - c->step_a(); - c->step_b(); + uint32_t stop_event = event.exchange(EVENT_NONE); + + if (stop_event == EVENT_HALT || stop_event == EVENT_INTERRUPT || stop_event == EVENT_TERMINATE) + break; } auto stats = c->get_mips_rel_speed(); @@ -412,7 +414,7 @@ int main(int argc, char *argv[]) *running = false; } - terminate = true; + event = EVENT_TERMINATE; delete cnsl;