calculate_physical_address moves to mmu
This commit is contained in:
parent
8860b04045
commit
de293967a2
5 changed files with 52 additions and 51 deletions
46
bus.cpp
46
bus.cpp
|
@ -218,7 +218,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
|
|||
|
||||
uint32_t m_offset = calculate_physical_address(run_mode, addr_in, !peek_only, false, peek_only, space);
|
||||
|
||||
uint32_t io_base = get_io_base();
|
||||
uint32_t io_base = mmu_->get_io_base();
|
||||
bool is_io = m_offset >= io_base;
|
||||
|
||||
if (is_io) {
|
||||
|
@ -485,7 +485,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
|
|||
}
|
||||
|
||||
if (!peek_only) {
|
||||
DOLOG(debug, false, "READ-I/O UNHANDLED read %08o (%c), (base: %o)", m_offset, word_mode == wm_byte ? 'B' : ' ', get_io_base());
|
||||
DOLOG(debug, false, "READ-I/O UNHANDLED read %08o (%c), (base: %o)", m_offset, word_mode == wm_byte ? 'B' : ' ', mmu_->get_io_base());
|
||||
|
||||
c->trap(004); // no such i/o
|
||||
throw 1;
|
||||
|
@ -522,41 +522,9 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
|
|||
return temp;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if (mmu_->is_enabled() == false) {
|
||||
bool is_psw = a == ADDR_PSW;
|
||||
return { a, apf, a, is_psw, a, is_psw };
|
||||
}
|
||||
|
||||
uint32_t physical_instruction = mmu_->get_physical_memory_offset(run_mode, 0, apf);
|
||||
uint32_t physical_data = mmu_->get_physical_memory_offset(run_mode, 1, apf);
|
||||
|
||||
uint16_t p_offset = a & 8191; // page offset
|
||||
|
||||
physical_instruction += p_offset;
|
||||
physical_data += p_offset;
|
||||
|
||||
if ((mmu_->getMMR3() & 16) == 0) { // offset is 18bit
|
||||
physical_instruction &= 0x3ffff;
|
||||
physical_data &= 0x3ffff;
|
||||
}
|
||||
|
||||
if (mmu_->get_use_data_space(run_mode) == false)
|
||||
physical_data = physical_instruction;
|
||||
|
||||
uint32_t io_base = get_io_base();
|
||||
bool physical_instruction_is_psw = (physical_instruction - io_base + 0160000) == ADDR_PSW;
|
||||
bool physical_data_is_psw = (physical_data - io_base + 0160000) == ADDR_PSW;
|
||||
|
||||
return { a, apf, physical_instruction, physical_instruction_is_psw, physical_data, physical_data_is_psw };
|
||||
}
|
||||
|
||||
bool bus::is_psw(const uint16_t addr, const int run_mode, const d_i_space_t space) const
|
||||
{
|
||||
auto meta = calculate_physical_address(run_mode, addr);
|
||||
auto meta = mmu_->calculate_physical_address(run_mode, addr);
|
||||
|
||||
if (space == d_space && meta.physical_data_is_psw)
|
||||
return true;
|
||||
|
@ -570,7 +538,7 @@ bool bus::is_psw(const uint16_t addr, const int run_mode, const d_i_space_t spac
|
|||
void bus::mmudebug(const uint16_t a)
|
||||
{
|
||||
for(int rm=0; rm<4; rm++) {
|
||||
auto ma = calculate_physical_address(rm, a);
|
||||
auto ma = mmu_->calculate_physical_address(rm, a);
|
||||
|
||||
DOLOG(debug, false, "RM %d, a: %06o, apf: %d, PI: %08o (PSW: %d), PD: %08o (PSW: %d)", rm, ma.virtual_address, ma.apf, ma.physical_instruction, ma.physical_instruction_is_psw, ma.physical_data, ma.physical_data_is_psw);
|
||||
}
|
||||
|
@ -626,7 +594,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c
|
|||
if ((mmu_->getMMR3() & 16) == 0) // off is 18bit
|
||||
m_offset &= 0x3ffff;
|
||||
|
||||
uint32_t io_base = get_io_base();
|
||||
uint32_t io_base = mmu_->get_io_base();
|
||||
bool is_io = m_offset >= io_base;
|
||||
|
||||
if (trap_on_failure) [[unlikely]] {
|
||||
|
@ -769,7 +737,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1
|
|||
|
||||
uint32_t m_offset = calculate_physical_address(run_mode, addr_in, true, true, false, space);
|
||||
|
||||
uint32_t io_base = get_io_base();
|
||||
uint32_t io_base = mmu_->get_io_base();
|
||||
bool is_io = m_offset >= io_base;
|
||||
|
||||
if (is_io) {
|
||||
|
@ -985,7 +953,7 @@ 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());
|
||||
DOLOG(debug, false, "WRITE-I/O UNHANDLED %08o(%c): %06o (base: %o)", m_offset, word_mode == wm_byte ? 'B' : 'W', value, mmu_->get_io_base());
|
||||
|
||||
if (word_mode == wm_word && (a & 1)) [[unlikely]] {
|
||||
DOLOG(debug, false, "WRITE-I/O to %08o (value: %06o) - odd address!", m_offset, value);
|
||||
|
|
11
bus.h
11
bus.h
|
@ -54,15 +54,6 @@ class tty;
|
|||
|
||||
typedef enum { T_PROCEED, T_ABORT_4, T_TRAP_250 } trap_action_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t virtual_address;
|
||||
uint8_t apf; // active page field
|
||||
uint32_t physical_instruction;
|
||||
bool physical_instruction_is_psw;
|
||||
uint32_t physical_data;
|
||||
bool physical_data_is_psw;
|
||||
} memory_addresses_t;
|
||||
|
||||
typedef struct {
|
||||
bool is_psw;
|
||||
} write_rc_t;
|
||||
|
@ -141,12 +132,10 @@ public:
|
|||
|
||||
void check_odd_addressing(const uint16_t a, const int run_mode, const d_i_space_t space, const bool is_write);
|
||||
|
||||
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;
|
||||
|
||||
std::pair<trap_action_t, int> get_trap_action(const int run_mode, const bool d, const int apf, const bool is_write);
|
||||
uint32_t calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const bool peek_only, const d_i_space_t space);
|
||||
|
||||
memory_addresses_t calculate_physical_address(const int run_mode, const uint16_t a) const;
|
||||
void check_address(const bool trap_on_failure, const bool is_write, const memory_addresses_t & addr, const word_mode_t word_mode, const bool is_data, const int run_mode);
|
||||
};
|
||||
|
|
|
@ -498,7 +498,7 @@ void mmu_resolve(console *const cnsl, bus *const b, const uint16_t va)
|
|||
int run_mode = b->getCpu()->getPSW_runmode();
|
||||
cnsl->put_string_lf(format("Run mode: %d, use data space: %d", run_mode, b->getMMU()->get_use_data_space(run_mode)));
|
||||
|
||||
auto data = b->calculate_physical_address(run_mode, va);
|
||||
auto data = b->getMMU()->calculate_physical_address(run_mode, va);
|
||||
|
||||
uint16_t page_offset = va & 8191;
|
||||
cnsl->put_string_lf(format("Active page field: %d, page offset: %o (%d)", data.apf, page_offset, page_offset));
|
||||
|
|
33
mmu.cpp
33
mmu.cpp
|
@ -1,6 +1,7 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "bus.h" // for (at least) ADDR_PSW
|
||||
#include "gen.h"
|
||||
#include "log.h"
|
||||
#include "mmu.h"
|
||||
|
@ -224,6 +225,38 @@ void mmu::trap_if_odd(const uint16_t a, const int run_mode, const d_i_space_t sp
|
|||
MMR0 |= page << 1;
|
||||
}
|
||||
|
||||
memory_addresses_t mmu::calculate_physical_address(const int run_mode, const uint16_t a) const
|
||||
{
|
||||
const uint8_t apf = a >> 13; // active page field
|
||||
|
||||
if (is_enabled() == false) {
|
||||
bool is_psw = a == ADDR_PSW;
|
||||
return { a, apf, a, is_psw, a, is_psw };
|
||||
}
|
||||
|
||||
uint32_t physical_instruction = get_physical_memory_offset(run_mode, 0, apf);
|
||||
uint32_t physical_data = get_physical_memory_offset(run_mode, 1, apf);
|
||||
|
||||
uint16_t p_offset = a & 8191; // page offset
|
||||
|
||||
physical_instruction += p_offset;
|
||||
physical_data += p_offset;
|
||||
|
||||
if ((getMMR3() & 16) == 0) { // offset is 18bit
|
||||
physical_instruction &= 0x3ffff;
|
||||
physical_data &= 0x3ffff;
|
||||
}
|
||||
|
||||
if (get_use_data_space(run_mode) == false)
|
||||
physical_data = physical_instruction;
|
||||
|
||||
uint32_t io_base = get_io_base();
|
||||
bool physical_instruction_is_psw = (physical_instruction - io_base + 0160000) == ADDR_PSW;
|
||||
bool physical_data_is_psw = (physical_data - io_base + 0160000) == ADDR_PSW;
|
||||
|
||||
return { a, apf, physical_instruction, physical_instruction_is_psw, physical_data, physical_data_is_psw };
|
||||
}
|
||||
|
||||
#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
|
||||
{
|
||||
|
|
11
mmu.h
11
mmu.h
|
@ -22,6 +22,15 @@
|
|||
#define ADDR_PAR_U_END 0177700
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t virtual_address;
|
||||
uint8_t apf; // active page field
|
||||
uint32_t physical_instruction;
|
||||
bool physical_instruction_is_psw;
|
||||
uint32_t physical_data;
|
||||
bool physical_data_is_psw;
|
||||
} memory_addresses_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t par;
|
||||
uint16_t pdr;
|
||||
|
@ -69,6 +78,8 @@ public:
|
|||
int get_pdr_direction (const int run_mode, const bool d, const int apf) { return pages[run_mode][d][apf].pdr & 8; }
|
||||
uint32_t get_physical_memory_offset(const int run_mode, const bool d, const int apf) const { return pages[run_mode][d][apf].par * 64; }
|
||||
bool get_use_data_space(const int run_mode) const;
|
||||
memory_addresses_t calculate_physical_address(const int run_mode, const uint16_t a) const;
|
||||
uint32_t get_io_base() const { return getMMR0() & 1 ? (getMMR3() & 16 ? 017760000 : 0760000) : 0160000; }
|
||||
|
||||
uint16_t getMMR0() const { return MMR0; }
|
||||
uint16_t getMMR1() const { return MMR1; }
|
||||
|
|
Loading…
Add table
Reference in a new issue