diff --git a/bus.cpp b/bus.cpp index bed9dcb..5a15bc3 100644 --- a/bus.cpp +++ b/bus.cpp @@ -279,7 +279,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, false, peek_only); + uint32_t m_offset = calculate_physical_address(run_mode, a, !peek_only, false, peek_only, false); if (word_mode) temp = m -> readByte(m_offset); @@ -291,28 +291,30 @@ 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, 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 is_data) { uint32_t m_offset = 0; 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 + constexpr uint16_t di_ena_mask[4] = { 4, 2, 0, 1 }; + bool d = is_data & (!!(MMR3 & di_ena_mask[run_mode])) ? is_data : false; uint16_t p_offset = a & 8191; // page offset + m_offset = pages[run_mode][d][apf].par * 64; // memory offset TODO: handle 16b int-s + m_offset += p_offset; if (trap_on_failure) { if (MMR0 & (1 << 9)) { - int access_control = pages[run_mode][0][apf].pdr & 7; + int access_control = pages[run_mode][d][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 + pages[run_mode][d][apf].pdr |= 1 << 7; MMR0 |= 1 << 13; // read-only @@ -327,7 +329,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c 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 + pages[run_mode][d][apf].pdr |= 1 << 7; MMR0 |= 1 << 13; // read-only @@ -341,9 +343,9 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c } } - uint16_t pdr_len = (((pages[run_mode][0][apf].pdr >> 8) & 127) + 1) * 64; // TODO: D/I + uint16_t pdr_len = (((pages[run_mode][d][apf].pdr >> 8) & 127) + 1) * 64; - bool direction = pages[run_mode][0][apf].pdr & 8; // TODO: D/I + bool direction = pages[run_mode][d][apf].pdr & 8; if (m_offset >= n_pages * 8192) { DOLOG(debug, !peek_only, "bus::calculate_physical_address %o >= %o", m_offset, n_pages * 8192); @@ -351,7 +353,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c MMR0 |= 1 << 15; // non-resident - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + pages[run_mode][d][apf].pdr |= 1 << 7; throw 1; } @@ -362,13 +364,13 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c MMR0 |= 1 << 14; // length - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + pages[run_mode][d][apf].pdr |= 1 << 7; throw 1; } } - DOLOG(debug, !peek_only, "virtual address %06o maps to physical address %08o (run_mode: %d, apf: %d, par: %08o, poff)", a, m_offset, run_mode, apf, pages[run_mode][0][apf].par * 64, p_offset); // TODO: D/I + DOLOG(debug, !peek_only, "virtual address %06o maps to physical address %08o (run_mode: %d, apf: %d, par: %08o, poff)", a, m_offset, run_mode, apf, pages[run_mode][d][apf].par * 64, p_offset); } else { m_offset = a; @@ -664,7 +666,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, true, false); + uint32_t m_offset = calculate_physical_address(run_mode, a, true, true, false, false); DOLOG(debug, true, "WRITE to %06o/%07o: %o", a, m_offset, value); diff --git a/bus.h b/bus.h index eb50428..8dee308 100644 --- a/bus.h +++ b/bus.h @@ -86,5 +86,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 is_data); }; diff --git a/console_ncurses.cpp b/console_ncurses.cpp index a90b7b6..5720b85 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, false); uint16_t current_instr = b->readWord(current_PC);