mmu is now of device type

This commit is contained in:
folkert van heusden 2024-04-25 13:24:32 +02:00
parent 4cfb01a014
commit 20fbb25aed
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
4 changed files with 120 additions and 67 deletions

59
bus.cpp
View file

@ -244,18 +244,17 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
} }
/// MMU /// /// MMU ///
if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) if ((a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) ||
return mmu_->read_pdr(a, 1, word_mode, peek_only); (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) ||
else if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) ||
return mmu_->read_par(a, 1, word_mode, peek_only); (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) ||
else if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) ||
return mmu_->read_pdr(a, 0, word_mode, peek_only); (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END)) {
else if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) if (word_mode == wm_word)
return mmu_->read_par(a, 0, word_mode, peek_only); return mmu_->readWord(a);
else if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END)
return mmu_->read_pdr(a, 3, word_mode, peek_only); return mmu_->readByte(a);
else if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) }
return mmu_->read_par(a, 3, word_mode, peek_only);
/////////// ///////////
if (a >= 0177740 && a <= 0177753) { // cache control register and others 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 /// /// MMU ///
// supervisor // supervisor
if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) { if ((a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) ||
mmu_->write_pdr(a, 1, value, word_mode); (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) ||
return { false }; (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) ||
} (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) ||
if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) { (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) ||
mmu_->write_par(a, 1, value, word_mode); (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END)) {
return { false }; 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 }; 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 if (a >= 0177740 && a <= 0177753) { // cache control register and others
// TODO // TODO

15
bus.h
View file

@ -38,21 +38,6 @@
#define ADDR_KW11P 0172540 #define ADDR_KW11P 0172540
#define ADDR_LP11CSR 0177514 // printer #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_PSW 0177776
#define ADDR_STACKLIM 0177774 #define ADDR_STACKLIM 0177774
#define ADDR_KERNEL_R 0177700 #define ADDR_KERNEL_R 0177700

82
mmu.cpp
View file

@ -22,28 +22,22 @@ void mmu::reset()
CPUERR = MMR0 = MMR1 = MMR2 = MMR3 = PIR = CSR = 0; 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; int page = (a >> 1) & 7;
bool is_d = a & 16; bool is_d = a & 16;
uint16_t t = pages[run_mode][is_d][page].pdr; uint16_t t = pages[run_mode][is_d][page].pdr;
if (!peek_only) return t;
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;
} }
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; int page = (a >> 1) & 7;
bool is_d = a & 16; bool is_d = a & 16;
uint16_t t = pages[run_mode][is_d][page].par; uint16_t t = pages[run_mode][is_d][page].par;
if (!peek_only) return t;
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;
} }
void mmu::setMMR0(uint16_t value) 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); 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);
}

31
mmu.h
View file

@ -2,13 +2,30 @@
#include <cstdint> #include <cstdint>
#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 { typedef struct {
uint16_t par; uint16_t par;
uint16_t pdr; uint16_t pdr;
} page_t; } page_t;
class mmu class mmu : public device
{ {
private: private:
// 8 pages, D/I, 3 modes and 1 invalid mode // 8 pages, D/I, 3 modes and 1 invalid mode
@ -26,7 +43,7 @@ public:
mmu(); mmu();
virtual ~mmu(); virtual ~mmu();
void reset(); void reset() override;
bool is_enabled() const { return MMR0 & 1; } bool is_enabled() const { return MMR0 & 1; }
bool is_locked() const { return !!(MMR0 & 0160000); } bool is_locked() const { return !!(MMR0 & 0160000); }
@ -63,9 +80,15 @@ public:
uint16_t getPIR() const { return PIR; }; uint16_t getPIR() const { return PIR; };
void setPIR(const uint16_t v) { PIR = v; } 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_par(const uint32_t a, const int run_mode);
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_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_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); 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;
}; };