Event handling (stop/interrupt) clean-up

This commit is contained in:
folkert van heusden 2022-06-10 20:59:36 +02:00
parent f6824ececf
commit 8d8af7153b
12 changed files with 47 additions and 51 deletions

View file

@ -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 {

View file

@ -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();

View file

@ -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

View file

@ -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;

View file

@ -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");

View file

@ -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;

View file

@ -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
View file

@ -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();

View file

@ -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;
}
}
}

View file

@ -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
View file

@ -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

View file

@ -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;