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 ///
|
/// 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
15
bus.h
|
@ -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
82
mmu.cpp
|
@ -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
31
mmu.h
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue