diff --git a/bus.cpp b/bus.cpp index 5b90ac8..f6e27a2 100644 --- a/bus.cpp +++ b/bus.cpp @@ -305,7 +305,7 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, int run_mode = (c->getPSW() >> (use_prev ? 12 : 14)) & 3; - uint32_t m_offset = calculate_physical_address(run_mode, a, !peek_only); + uint32_t m_offset = calculate_physical_address(run_mode, a, !peek_only, false); if (word_mode) temp = m -> readByte(m_offset); @@ -317,7 +317,7 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, return temp; } -uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure) +uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write) { uint32_t m_offset = 0; @@ -331,11 +331,30 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c m_offset += p_offset; - uint16_t pdr_len = (((pages[run_mode][0][apf].pdr >> 8) & 127) + 1) * 64; // TODO: D/I - - bool direction = pages[run_mode][0][apf].pdr & 8; // TODO: D/I - if (trap_on_failure) { + int access_control = pages[run_mode][0][apf].pdr & 7; + + if (is_write && access_control != 6) { // write + c->schedule_trap(04); // invalid address + + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + + throw 1; + } + else if (!is_write) { // read + if (access_control == 0 || access_control == 1 || access_control == 3 || access_control == 4 || access_control == 7) { + c->schedule_trap(04); // invalid address + + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + + throw 1; + } + } + + uint16_t pdr_len = (((pages[run_mode][0][apf].pdr >> 8) & 127) + 1) * 64; // TODO: D/I + + bool direction = pages[run_mode][0][apf].pdr & 8; // TODO: D/I + if (m_offset >= n_pages * 8192) { D(fprintf(stderr, "bus::calculate_physical_address %o >= %o\n", m_offset, n_pages * 8192);) c->schedule_trap(04); // invalid address @@ -640,7 +659,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons int run_mode = (c->getPSW() >> (use_prev ? 12 : 14)) & 3; - uint32_t m_offset = calculate_physical_address(run_mode, a, true); + uint32_t m_offset = calculate_physical_address(run_mode, a, true, true); D(fprintf(stderr, "WRITE to %06o/%07o: %o\n", a, m_offset, value);) diff --git a/bus.h b/bus.h index 6d9a52a..4ba3ac9 100644 --- a/bus.h +++ b/bus.h @@ -77,5 +77,5 @@ public: uint16_t get_switch_register() const { return switch_register; } - uint32_t calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure); + uint32_t calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write); }; diff --git a/console.cpp b/console.cpp index 07e63bf..fa54d1f 100644 --- a/console.cpp +++ b/console.cpp @@ -195,11 +195,13 @@ void console::operator()() if (c == -1) continue; - if (c == 3) // ^c + bool running_flag = *get_running_flag(); + + if (running_flag == false && c == 3) // ^c *interrupt_emulation = *terminate = true; - else if (c == 5) // ^e + else if (running_flag == true && c == 5) // ^e *interrupt_emulation = true; - else if (c == 12) // ^l + else if (running_flag == false && c == 12) // ^l refresh_virtual_terminal(); else { input_buffer.push_back(c); diff --git a/console_ncurses.cpp b/console_ncurses.cpp index 66735c4..9049a19 100644 --- a/console_ncurses.cpp +++ b/console_ncurses.cpp @@ -138,7 +138,7 @@ void console_ncurses::panel_update_thread() int run_mode = current_PSW >> 14; uint16_t current_PC = c->getPC(); - uint32_t full_addr = b->calculate_physical_address(run_mode, current_PC, false); + uint32_t full_addr = b->calculate_physical_address(run_mode, current_PC, false, false); uint16_t current_instr = b->readWord(current_PC); diff --git a/debugger.cpp b/debugger.cpp index ddefb13..923b484 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -173,6 +173,8 @@ void debugger(console *const cnsl, bus *const b, std::atomic_bool *const interru c->emulation_start(); + *cnsl->get_running_flag() = true; + while(!event && !*interrupt_emulation) { if (tracing || single_step) disassemble(c, single_step ? cnsl : nullptr, c->getPC(), false); @@ -188,6 +190,8 @@ void debugger(console *const cnsl, bus *const b, std::atomic_bool *const interru break; } + *cnsl->get_running_flag() = false; + if (!single_step) { auto speed = c->get_mips_rel_speed(); cnsl->debug("MIPS: %.2f, relative speed: %.2f%%", speed.first, speed.second); diff --git a/main.cpp b/main.cpp index ba1610e..196953d 100644 --- a/main.cpp +++ b/main.cpp @@ -262,8 +262,6 @@ int main(int argc, char *argv[]) sigaction(SIGTERM, &sa, nullptr); sigaction(SIGINT , &sa, nullptr); - *running = true; - // loadbin(b, 0, "test.dat"); // c->setRegister(7, 0); @@ -274,6 +272,8 @@ int main(int argc, char *argv[]) else { c->emulation_start(); // for statistics + *running = true; + while(!event) { if (interrupt_emulation) { if (terminate) @@ -282,9 +282,9 @@ int main(int argc, char *argv[]) c->step(); } - } - *running = false; + *running = false; + } terminate = true;