diff --git a/bus.cpp b/bus.cpp index d8e6b72..de41cb1 100644 --- a/bus.cpp +++ b/bus.cpp @@ -218,7 +218,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm uint32_t m_offset = calculate_physical_address(run_mode, addr_in, !peek_only, false, peek_only, space); - uint32_t io_base = get_io_base(); + uint32_t io_base = mmu_->get_io_base(); bool is_io = m_offset >= io_base; if (is_io) { @@ -485,7 +485,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm } if (!peek_only) { - DOLOG(debug, false, "READ-I/O UNHANDLED read %08o (%c), (base: %o)", m_offset, word_mode == wm_byte ? 'B' : ' ', get_io_base()); + DOLOG(debug, false, "READ-I/O UNHANDLED read %08o (%c), (base: %o)", m_offset, word_mode == wm_byte ? 'B' : ' ', mmu_->get_io_base()); c->trap(004); // no such i/o throw 1; @@ -522,41 +522,9 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm return temp; } -memory_addresses_t bus::calculate_physical_address(const int run_mode, const uint16_t a) const -{ - const uint8_t apf = a >> 13; // active page field - - if (mmu_->is_enabled() == false) { - bool is_psw = a == ADDR_PSW; - return { a, apf, a, is_psw, a, is_psw }; - } - - uint32_t physical_instruction = mmu_->get_physical_memory_offset(run_mode, 0, apf); - uint32_t physical_data = mmu_->get_physical_memory_offset(run_mode, 1, apf); - - uint16_t p_offset = a & 8191; // page offset - - physical_instruction += p_offset; - physical_data += p_offset; - - if ((mmu_->getMMR3() & 16) == 0) { // offset is 18bit - physical_instruction &= 0x3ffff; - physical_data &= 0x3ffff; - } - - if (mmu_->get_use_data_space(run_mode) == false) - physical_data = physical_instruction; - - uint32_t io_base = get_io_base(); - bool physical_instruction_is_psw = (physical_instruction - io_base + 0160000) == ADDR_PSW; - bool physical_data_is_psw = (physical_data - io_base + 0160000) == ADDR_PSW; - - return { a, apf, physical_instruction, physical_instruction_is_psw, physical_data, physical_data_is_psw }; -} - bool bus::is_psw(const uint16_t addr, const int run_mode, const d_i_space_t space) const { - auto meta = calculate_physical_address(run_mode, addr); + auto meta = mmu_->calculate_physical_address(run_mode, addr); if (space == d_space && meta.physical_data_is_psw) return true; @@ -570,7 +538,7 @@ bool bus::is_psw(const uint16_t addr, const int run_mode, const d_i_space_t spac void bus::mmudebug(const uint16_t a) { for(int rm=0; rm<4; rm++) { - auto ma = calculate_physical_address(rm, a); + auto ma = mmu_->calculate_physical_address(rm, a); DOLOG(debug, false, "RM %d, a: %06o, apf: %d, PI: %08o (PSW: %d), PD: %08o (PSW: %d)", rm, ma.virtual_address, ma.apf, ma.physical_instruction, ma.physical_instruction_is_psw, ma.physical_data, ma.physical_data_is_psw); } @@ -626,7 +594,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c if ((mmu_->getMMR3() & 16) == 0) // off is 18bit m_offset &= 0x3ffff; - uint32_t io_base = get_io_base(); + uint32_t io_base = mmu_->get_io_base(); bool is_io = m_offset >= io_base; if (trap_on_failure) [[unlikely]] { @@ -769,7 +737,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 uint32_t m_offset = calculate_physical_address(run_mode, addr_in, true, true, false, space); - uint32_t io_base = get_io_base(); + uint32_t io_base = mmu_->get_io_base(); bool is_io = m_offset >= io_base; if (is_io) { @@ -985,7 +953,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 /////////// - DOLOG(debug, false, "WRITE-I/O UNHANDLED %08o(%c): %06o (base: %o)", m_offset, word_mode == wm_byte ? 'B' : 'W', value, get_io_base()); + DOLOG(debug, false, "WRITE-I/O UNHANDLED %08o(%c): %06o (base: %o)", m_offset, word_mode == wm_byte ? 'B' : 'W', value, mmu_->get_io_base()); if (word_mode == wm_word && (a & 1)) [[unlikely]] { DOLOG(debug, false, "WRITE-I/O to %08o (value: %06o) - odd address!", m_offset, value); diff --git a/bus.h b/bus.h index 7ea9fc1..44461dd 100644 --- a/bus.h +++ b/bus.h @@ -54,15 +54,6 @@ class tty; typedef enum { T_PROCEED, T_ABORT_4, T_TRAP_250 } trap_action_t; -typedef struct { - uint16_t virtual_address; - uint8_t apf; // active page field - uint32_t physical_instruction; - bool physical_instruction_is_psw; - uint32_t physical_data; - bool physical_data_is_psw; -} memory_addresses_t; - typedef struct { bool is_psw; } write_rc_t; @@ -141,12 +132,10 @@ public: void check_odd_addressing(const uint16_t a, const int run_mode, const d_i_space_t space, const bool is_write); - uint32_t get_io_base() const { return mmu_->getMMR0() & 1 ? (mmu_->getMMR3() & 16 ? 017760000 : 0760000) : 0160000; } bool is_psw(const uint16_t addr, const int run_mode, const d_i_space_t space) const; std::pair get_trap_action(const int run_mode, const bool d, const int apf, const bool is_write); 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 d_i_space_t space); - memory_addresses_t calculate_physical_address(const int run_mode, const uint16_t a) const; void check_address(const bool trap_on_failure, const bool is_write, const memory_addresses_t & addr, const word_mode_t word_mode, const bool is_data, const int run_mode); }; diff --git a/debugger.cpp b/debugger.cpp index b28fb89..3c60733 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -498,7 +498,7 @@ void mmu_resolve(console *const cnsl, bus *const b, const uint16_t va) int run_mode = b->getCpu()->getPSW_runmode(); cnsl->put_string_lf(format("Run mode: %d, use data space: %d", run_mode, b->getMMU()->get_use_data_space(run_mode))); - auto data = b->calculate_physical_address(run_mode, va); + auto data = b->getMMU()->calculate_physical_address(run_mode, va); uint16_t page_offset = va & 8191; cnsl->put_string_lf(format("Active page field: %d, page offset: %o (%d)", data.apf, page_offset, page_offset)); diff --git a/mmu.cpp b/mmu.cpp index 3e90b8d..e995d2c 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -1,6 +1,7 @@ #include #include +#include "bus.h" // for (at least) ADDR_PSW #include "gen.h" #include "log.h" #include "mmu.h" @@ -224,6 +225,38 @@ void mmu::trap_if_odd(const uint16_t a, const int run_mode, const d_i_space_t sp MMR0 |= page << 1; } +memory_addresses_t mmu::calculate_physical_address(const int run_mode, const uint16_t a) const +{ + const uint8_t apf = a >> 13; // active page field + + if (is_enabled() == false) { + bool is_psw = a == ADDR_PSW; + return { a, apf, a, is_psw, a, is_psw }; + } + + uint32_t physical_instruction = get_physical_memory_offset(run_mode, 0, apf); + uint32_t physical_data = get_physical_memory_offset(run_mode, 1, apf); + + uint16_t p_offset = a & 8191; // page offset + + physical_instruction += p_offset; + physical_data += p_offset; + + if ((getMMR3() & 16) == 0) { // offset is 18bit + physical_instruction &= 0x3ffff; + physical_data &= 0x3ffff; + } + + if (get_use_data_space(run_mode) == false) + physical_data = physical_instruction; + + uint32_t io_base = get_io_base(); + bool physical_instruction_is_psw = (physical_instruction - io_base + 0160000) == ADDR_PSW; + bool physical_data_is_psw = (physical_data - io_base + 0160000) == ADDR_PSW; + + return { a, apf, physical_instruction, physical_instruction_is_psw, physical_data, physical_data_is_psw }; +} + #if IS_POSIX void mmu::add_par_pdr(json_t *const target, const int run_mode, const bool is_d, const std::string & name) const { diff --git a/mmu.h b/mmu.h index f8be6e8..1dd5ef0 100644 --- a/mmu.h +++ b/mmu.h @@ -22,6 +22,15 @@ #define ADDR_PAR_U_END 0177700 +typedef struct { + uint16_t virtual_address; + uint8_t apf; // active page field + uint32_t physical_instruction; + bool physical_instruction_is_psw; + uint32_t physical_data; + bool physical_data_is_psw; +} memory_addresses_t; + typedef struct { uint16_t par; uint16_t pdr; @@ -69,6 +78,8 @@ public: int get_pdr_direction (const int run_mode, const bool d, const int apf) { return pages[run_mode][d][apf].pdr & 8; } uint32_t get_physical_memory_offset(const int run_mode, const bool d, const int apf) const { return pages[run_mode][d][apf].par * 64; } bool get_use_data_space(const int run_mode) const; + memory_addresses_t calculate_physical_address(const int run_mode, const uint16_t a) const; + uint32_t get_io_base() const { return getMMR0() & 1 ? (getMMR3() & 16 ? 017760000 : 0760000) : 0160000; } uint16_t getMMR0() const { return MMR0; } uint16_t getMMR1() const { return MMR1; }