Event handling (stop/interrupt) clean-up
This commit is contained in:
parent
f6824ececf
commit
8d8af7153b
12 changed files with 47 additions and 51 deletions
15
console.cpp
15
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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
4
cpu.cpp
4
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
|
||||
|
|
4
cpu.h
4
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();
|
||||
|
|
23
debugger.cpp
23
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<std::string, std::string> split(const std::vector<std::string> & 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
2
gen.h
2
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
|
||||
|
|
28
main.cpp
28
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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue