mmu is now of device type
This commit is contained in:
parent
4cfb01a014
commit
20fbb25aed
4 changed files with 120 additions and 67 deletions
59
bus.cpp
59
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
|
||||
|
|
15
bus.h
15
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
|
||||
|
|
82
mmu.cpp
82
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);
|
||||
}
|
||||
|
|
31
mmu.h
31
mmu.h
|
@ -2,13 +2,30 @@
|
|||
|
||||
#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 {
|
||||
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;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue