calculate_physical_address moves to mmu

This commit is contained in:
folkert van heusden 2024-05-03 19:39:28 +02:00
parent 8860b04045
commit de293967a2
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
5 changed files with 52 additions and 51 deletions

46
bus.cpp
View file

@ -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
View file

@ -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);
};

View file

@ -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
View file

@ -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
View file

@ -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; }