diff --git a/bus.cpp b/bus.cpp index 03ab696..f969719 100644 --- a/bus.cpp +++ b/bus.cpp @@ -285,10 +285,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; -// if (run_mode == 1 && is_11_34) -// run_mode = 3; - - uint32_t m_offset = calculate_physical_address(run_mode, a, !peek_only, false, peek_only); + uint32_t m_offset = calculate_physical_address(run_mode, a, !peek_only, false, peek_only, word_mode); if (word_mode) temp = m -> readByte(m_offset); @@ -339,12 +336,13 @@ void bus::setMMR2(const uint16_t value) MMR2 = value; } -uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const bool peek_only) +uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const bool peek_only, const bool word_mode) { uint32_t m_offset = 0; + const uint8_t apf = a >> 13; // active page field + if (MMR0 & 1) { - const uint8_t apf = a >> 13; // active page field // TODO: D/I m_offset = pages[run_mode][0][apf].par * 64; // memory offset TODO: handle 16b int-s @@ -466,6 +464,16 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c m_offset = a; } + if ((m_offset & 1) && word_mode == 0 && peek_only == false) { + DOLOG(debug, !peek_only, "bus::calculate_physical_address::m_offset %o", m_offset); + DOLOG(debug, true, "TRAP(004) (throw 5) on address %06o", a); + c->schedule_trap(004); // invalid access + + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + + throw 5; + } + return m_offset; } @@ -787,7 +795,7 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo return; } - uint32_t m_offset = calculate_physical_address(run_mode, a, true, true, false); + uint32_t m_offset = calculate_physical_address(run_mode, a, true, true, false, word_mode); DOLOG(debug, true, "WRITE to %06o/%07o: %o", a, m_offset, value); diff --git a/bus.h b/bus.h index b4c92d5..9b8cdd6 100644 --- a/bus.h +++ b/bus.h @@ -90,5 +90,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, const bool is_write, const bool peek_only); + uint32_t calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const bool peek_only, const bool word_mode); }; diff --git a/console_ncurses.cpp b/console_ncurses.cpp index a90b7b6..6a3555b 100644 --- a/console_ncurses.cpp +++ b/console_ncurses.cpp @@ -139,7 +139,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, false, true); + uint32_t full_addr = b->calculate_physical_address(run_mode, current_PC, false, false, true, true); uint16_t current_instr = b->readWord(current_PC); diff --git a/cpu.cpp b/cpu.cpp index 748d9b7..6d2c55b 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1657,7 +1657,7 @@ void cpu::trap(const uint16_t vector, const int new_ipl, const bool is_interrupt // make sure the trap vector is retrieved from kernel space psw &= 037777; // mask off 14/15 - if ((b->getMMR0() & 0160000) == 0) { + if ((b->getMMR0() & 0160000) == 0 && vector != 4) { b->setMMR2(vector); b->addToMMR1(-2, 6); b->addToMMR1(-2, 6); @@ -2161,7 +2161,12 @@ void cpu::step_a() b->clearMMR1(); if (scheduled_trap) { - trap(scheduled_trap, 7, true); + try { + trap(scheduled_trap, 7, true); + } + catch(const int exception) { + DOLOG(debug, true, "2nd-bus-trap during execution of command (%d)", exception); + } scheduled_trap = 0;