From 8860b04045c2bdc6d88ee05e2e9c9467c60e4a14 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Fri, 3 May 2024 19:32:08 +0200 Subject: [PATCH] the check if odd-address access is performed is done by the mmu --- bus.cpp | 42 ++++++++++-------------------------------- bus.h | 1 - cpu.cpp | 2 +- mmu.cpp | 11 +++++++++++ mmu.h | 2 ++ 5 files changed, 24 insertions(+), 34 deletions(-) diff --git a/bus.cpp b/bus.cpp index aaa8c17..d8e6b72 100644 --- a/bus.cpp +++ b/bus.cpp @@ -212,18 +212,6 @@ void bus::init() mmu_->setMMR3(0); } -void bus::trap_odd(const uint16_t a) -{ - uint16_t temp = mmu_->getMMR0(); - - temp &= ~(7 << 1); - temp |= (a >> 13) << 1; - - mmu_->setMMR0(temp); - - c->trap(004); // invalid access -} - uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm_selection_t mode_selection, const bool peek_only, const d_i_space_t space) { int run_mode = mode_selection == rm_cur ? c->getPSW_runmode() : c->getPSW_prev_runmode(); @@ -270,9 +258,9 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm ///^ registers ^/// if (!peek_only) { - if ((a & 1) && word_mode == wm_word) { + if ((a & 1) && word_mode == wm_word) [[unlikely]] { DOLOG(debug, false, "READ-I/O odd address %06o UNHANDLED", a); - trap_odd(a); + mmu_->trap_if_odd(addr_in, run_mode, space, false); throw 0; return 0; } @@ -507,8 +495,8 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm } if (peek_only == false && word_mode == wm_word && (addr_in & 1)) { - if (!peek_only) DOLOG(debug, false, "READ from %06o - odd address!", addr_in); - trap_odd(addr_in); + DOLOG(debug, false, "READ from %06o - odd address!", addr_in); + mmu_->trap_if_odd(addr_in, run_mode, space, false); throw 2; return 0; } @@ -534,18 +522,6 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm return temp; } -void bus::check_odd_addressing(const uint16_t a, const int run_mode, const d_i_space_t space, const bool is_write) -{ - if (a & 1) { - if (is_write) - mmu_->set_page_trapped(run_mode, space == d_space, a >> 13); - - trap_odd(a); - - throw 4; - } -} - 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 @@ -1011,10 +987,11 @@ 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()); - if (word_mode == wm_word && (a & 1)) { + if (word_mode == wm_word && (a & 1)) [[unlikely]] { DOLOG(debug, false, "WRITE-I/O to %08o (value: %06o) - odd address!", m_offset, value); - trap_odd(a); + mmu_->trap_if_odd(a, run_mode, space, true); + throw 8; } @@ -1023,10 +1000,11 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 throw 9; } - if (word_mode == wm_word && (addr_in & 1)) { + if (word_mode == wm_word && (addr_in & 1)) [[unlikely]] { DOLOG(debug, false, "WRITE to %06o (value: %06o) - odd address!", addr_in, value); - trap_odd(addr_in); + mmu_->trap_if_odd(addr_in, run_mode, space, true); + throw 10; } diff --git a/bus.h b/bus.h index 43138aa..7ea9fc1 100644 --- a/bus.h +++ b/bus.h @@ -140,7 +140,6 @@ public: void writePhysical(const uint32_t a, const uint16_t value); void check_odd_addressing(const uint16_t a, const int run_mode, const d_i_space_t space, const bool is_write); - void trap_odd(const uint16_t a); 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; diff --git a/cpu.cpp b/cpu.cpp index 18854a6..d5be197 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1361,7 +1361,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) } else { auto a = getGAM(dst_mode, dst_reg, word_mode, rm_cur); - addToMMR1(a); + addToMMR1(a); uint16_t vl = a.value.value(); uint16_t v = (vl << 1) & (word_mode == wm_byte ? 0xff : 0xffff); diff --git a/mmu.cpp b/mmu.cpp index ddd376b..3e90b8d 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -213,6 +213,17 @@ void mmu::write_byte(const uint16_t a, const uint8_t value) write_par(a, 3, value, wm_byte); } +void mmu::trap_if_odd(const uint16_t a, const int run_mode, const d_i_space_t space, const bool is_write) +{ + int page = a >> 13; + + if (is_write) + set_page_trapped(run_mode, space == d_space, page); + + MMR0 &= ~(7 << 1); + MMR0 |= page << 1; +} + #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 e8edc75..f8be6e8 100644 --- a/mmu.h +++ b/mmu.h @@ -88,6 +88,8 @@ public: void setMMR0Bit(const int bit); void clearMMR0Bit(const int bit); + void trap_if_odd(const uint16_t a, const int run_mode, const d_i_space_t space, const bool is_write); + uint16_t getCPUERR() const { return CPUERR; } void setCPUERR(const uint16_t v) { CPUERR = v; }