From 20fbb25aedbe25638e32de1dc0394ff7f3bbfc74 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Thu, 25 Apr 2024 13:24:32 +0200 Subject: [PATCH] mmu is now of device type --- bus.cpp | 59 +++++++++++++++-------------------------- bus.h | 15 ----------- mmu.cpp | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++------- mmu.h | 31 +++++++++++++++++++--- 4 files changed, 120 insertions(+), 67 deletions(-) diff --git a/bus.cpp b/bus.cpp index d4f065f..8198ae3 100644 --- a/bus.cpp +++ b/bus.cpp @@ -244,18 +244,17 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm } /// MMU /// - if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) - return mmu_->read_pdr(a, 1, word_mode, peek_only); - else if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) - return mmu_->read_par(a, 1, word_mode, peek_only); - else if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) - return mmu_->read_pdr(a, 0, word_mode, peek_only); - else if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) - return mmu_->read_par(a, 0, word_mode, peek_only); - else if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) - return mmu_->read_pdr(a, 3, word_mode, peek_only); - else if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) - return mmu_->read_par(a, 3, word_mode, peek_only); + if ((a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) || + (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) || + (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) || + (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) || + (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) || + (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END)) { + if (word_mode == wm_word) + return mmu_->readWord(a); + + return mmu_->readByte(a); + } /////////// if (a >= 0177740 && a <= 0177753) { // cache control register and others @@ -894,35 +893,19 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 /// MMU /// // supervisor - if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) { - mmu_->write_pdr(a, 1, value, word_mode); - return { false }; - } - if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) { - mmu_->write_par(a, 1, value, word_mode); - return { false }; - } + if ((a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) || + (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) || + (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) || + (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) || + (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) || + (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END)) { + if (word_mode == wm_word) + mmu_->writeWord(a, value); + else + mmu_->writeByte(a, value); - // kernel - if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) { - mmu_->write_pdr(a, 0, value, word_mode); return { false }; } - if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) { - mmu_->write_par(a, 0, value, word_mode); - return { false }; - } - - // user - if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) { - mmu_->write_pdr(a, 3, value, word_mode); - return { false }; - } - if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) { - mmu_->write_par(a, 3, value, word_mode); - return { false }; - } - //// if (a >= 0177740 && a <= 0177753) { // cache control register and others // TODO diff --git a/bus.h b/bus.h index dc85cee..e61243a 100644 --- a/bus.h +++ b/bus.h @@ -38,21 +38,6 @@ #define ADDR_KW11P 0172540 #define ADDR_LP11CSR 0177514 // printer -#define ADDR_PDR_SV_START 0172200 -#define ADDR_PDR_SV_END 0172240 -#define ADDR_PAR_SV_START 0172240 -#define ADDR_PAR_SV_END 0172300 - -#define ADDR_PDR_K_START 0172300 -#define ADDR_PDR_K_END 0172340 -#define ADDR_PAR_K_START 0172340 -#define ADDR_PAR_K_END 0172400 - -#define ADDR_PDR_U_START 0177600 -#define ADDR_PDR_U_END 0177640 -#define ADDR_PAR_U_START 0177640 -#define ADDR_PAR_U_END 0177700 - #define ADDR_PSW 0177776 #define ADDR_STACKLIM 0177774 #define ADDR_KERNEL_R 0177700 diff --git a/mmu.cpp b/mmu.cpp index 2cdb12c..b0083ab 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -22,28 +22,22 @@ void mmu::reset() CPUERR = MMR0 = MMR1 = MMR2 = MMR3 = PIR = CSR = 0; } -uint16_t mmu::read_pdr(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only) +uint16_t mmu::read_pdr(const uint32_t a, const int run_mode) { int page = (a >> 1) & 7; bool is_d = a & 16; uint16_t t = pages[run_mode][is_d][page].pdr; - if (!peek_only) - DOLOG(debug, false, "MMU READ-I/O PDR run-mode %d: %c for %d: %o", run_mode, is_d ? 'D' : 'I', page, t); - - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; + return t; } -uint16_t mmu::read_par(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only) +uint16_t mmu::read_par(const uint32_t a, const int run_mode) { int page = (a >> 1) & 7; bool is_d = a & 16; uint16_t t = pages[run_mode][is_d][page].par; - if (!peek_only) - DOLOG(debug, false, "MMU READ-I/O PAR run-mode %d: %c for %d: %o (phys: %07o)", run_mode, is_d ? 'D' : 'I', page, t, t * 64); - - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; + return t; } void mmu::setMMR0(uint16_t value) @@ -158,3 +152,71 @@ void mmu::write_par(const uint32_t a, const int run_mode, const uint16_t value, DOLOG(debug, false, "mmu WRITE-I/O PAR run-mode %d: %c for %d: %o (%07o)", run_mode, is_d ? 'D' : 'I', page, word_mode == wm_byte ? value & 0xff : value, pages[run_mode][is_d][page].par * 64); } + +uint16_t mmu::readWord(const uint16_t a) +{ + uint16_t v = 0; + + if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) + v = read_pdr(a, 1); + else if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) + v = read_par(a, 1); + else if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) + v = read_pdr(a, 0); + else if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) + v = read_par(a, 0); + else if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) + v = read_pdr(a, 3); + else if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) + v = read_par(a, 3); + + return v; +} + +uint8_t mmu::readByte(const uint16_t addr) +{ + uint16_t v = readWord(addr); + + if (addr & 1) + return v >> 8; + + return v; +} + +void mmu::writeWord(const uint16_t a, const uint16_t value) +{ + // supervisor + if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) + write_pdr(a, 1, value, wm_word); + else if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) + write_par(a, 1, value, wm_word); + // kernel + else if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) + write_pdr(a, 0, value, wm_word); + else if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) + write_par(a, 0, value, wm_word); + // user + else if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) + write_pdr(a, 3, value, wm_word); + else if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) + write_par(a, 3, value, wm_word); +} + +void mmu::writeByte(const uint16_t a, const uint8_t value) +{ + // supervisor + if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) + write_pdr(a, 1, value, wm_byte); + else if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) + write_par(a, 1, value, wm_byte); + // kernel + else if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) + write_pdr(a, 0, value, wm_byte); + else if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) + write_par(a, 0, value, wm_byte); + // user + else if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) + write_pdr(a, 3, value, wm_byte); + else if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) + write_par(a, 3, value, wm_byte); +} diff --git a/mmu.h b/mmu.h index f508b69..22ed44e 100644 --- a/mmu.h +++ b/mmu.h @@ -2,13 +2,30 @@ #include +#include "device.h" + +#define ADDR_PDR_SV_START 0172200 +#define ADDR_PDR_SV_END 0172240 +#define ADDR_PAR_SV_START 0172240 +#define ADDR_PAR_SV_END 0172300 + +#define ADDR_PDR_K_START 0172300 +#define ADDR_PDR_K_END 0172340 +#define ADDR_PAR_K_START 0172340 +#define ADDR_PAR_K_END 0172400 + +#define ADDR_PDR_U_START 0177600 +#define ADDR_PDR_U_END 0177640 +#define ADDR_PAR_U_START 0177640 +#define ADDR_PAR_U_END 0177700 + typedef struct { uint16_t par; uint16_t pdr; } page_t; -class mmu +class mmu : public device { private: // 8 pages, D/I, 3 modes and 1 invalid mode @@ -26,7 +43,7 @@ public: mmu(); virtual ~mmu(); - void reset(); + void reset() override; bool is_enabled() const { return MMR0 & 1; } bool is_locked() const { return !!(MMR0 & 0160000); } @@ -63,9 +80,15 @@ public: uint16_t getPIR() const { return PIR; }; void setPIR(const uint16_t v) { PIR = v; } - uint16_t read_par(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only); - uint16_t read_pdr(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only); + uint16_t read_par(const uint32_t a, const int run_mode); + uint16_t read_pdr(const uint32_t a, const int run_mode); void write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode); void write_par(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode); + + uint8_t readByte(const uint16_t addr) override; + uint16_t readWord(const uint16_t addr) override; + + void writeByte(const uint16_t addr, const uint8_t v) override; + void writeWord(const uint16_t addr, uint16_t v) override; };