trap action

This commit is contained in:
folkert van heusden 2024-04-13 11:22:59 +02:00
parent 6941b44ace
commit 078bf2da43
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
3 changed files with 58 additions and 26 deletions

55
bus.cpp
View file

@ -563,32 +563,11 @@ bool bus::get_use_data_space(const int run_mode) const
return !!(MMR3 & di_ena_mask[run_mode]); return !!(MMR3 & di_ena_mask[run_mode]);
} }
uint32_t bus::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) std::pair<trap_action_t, int> bus::get_trap_action(const int run_mode, const bool d, const int apf, const bool is_write)
{
uint32_t m_offset = a;
if ((MMR0 & 1) || (is_write && (MMR0 & (1 << 8)))) {
const uint8_t apf = a >> 13; // active page field
bool d = space == d_space && get_use_data_space(run_mode) ? space == d_space : false;
uint16_t p_offset = a & 8191; // page offset
m_offset = pages[run_mode][d][apf].par * 64; // memory offset
m_offset += p_offset;
if ((MMR3 & 16) == 0) // off is 18bit
m_offset &= 0x3ffff;
uint32_t io_base = get_io_base();
bool is_io = m_offset >= io_base;
if (trap_on_failure) {
{ {
const int access_control = pages[run_mode][d][apf].pdr & 7; const int access_control = pages[run_mode][d][apf].pdr & 7;
enum { T_PROCEED, T_ABORT_4, T_TRAP_250 } trap_action { T_PROCEED }; trap_action_t trap_action = T_PROCEED;
if (access_control == 0) if (access_control == 0)
trap_action = T_ABORT_4; trap_action = T_ABORT_4;
@ -613,6 +592,36 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c
trap_action = T_ABORT_4; trap_action = T_ABORT_4;
} }
return { trap_action, access_control };
}
uint32_t bus::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)
{
uint32_t m_offset = a;
if ((MMR0 & 1) || (is_write && (MMR0 & (1 << 8)))) {
const uint8_t apf = a >> 13; // active page field
bool d = space == d_space && get_use_data_space(run_mode) ? space == d_space : false;
uint16_t p_offset = a & 8191; // page offset
m_offset = pages[run_mode][d][apf].par * 64; // memory offset
m_offset += p_offset;
if ((MMR3 & 16) == 0) // off is 18bit
m_offset &= 0x3ffff;
uint32_t io_base = get_io_base();
bool is_io = m_offset >= io_base;
if (trap_on_failure) {
{
auto rc = get_trap_action(run_mode, d, apf, is_write);
auto trap_action = rc.first;
int access_control = rc.second;
if (trap_action != T_PROCEED) { if (trap_action != T_PROCEED) {
if (is_write) if (is_write)
pages[run_mode][d][apf].pdr |= 1 << 7; pages[run_mode][d][apf].pdr |= 1 << 7;

3
bus.h
View file

@ -69,6 +69,8 @@ typedef enum { wm_word = 0, wm_byte = 1 } word_mode_t;
typedef enum { rm_prev, rm_cur } rm_selection_t; typedef enum { rm_prev, rm_cur } rm_selection_t;
typedef enum { T_PROCEED, T_ABORT_4, T_TRAP_250 } trap_action_t;
typedef struct { typedef struct {
uint16_t virtual_address; uint16_t virtual_address;
uint8_t apf; // active page field uint8_t apf; // active page field
@ -184,6 +186,7 @@ public:
uint32_t get_io_base() const { return MMR0 & 1 ? (MMR3 & 16 ? 017760000 : 0760000) : 0160000; } uint32_t get_io_base() const { return MMR0 & 1 ? (MMR3 & 16 ? 017760000 : 0760000) : 0160000; }
bool is_psw(const uint16_t addr, const int run_mode, const d_i_space_t space) const; 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); 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);
bool get_use_data_space(const int run_mode) const; bool get_use_data_space(const int run_mode) const;

View file

@ -621,6 +621,18 @@ void mmu_dump(console *const cnsl, bus *const b, const bool verbose)
} }
} }
const char *trap_action_to_str(const trap_action_t ta)
{
if (ta == T_PROCEED)
return "proceed";
if (ta == T_ABORT_4)
return "abort (trap 4)";
if (ta == T_TRAP_250)
return "trap 250";
return "?";
}
void mmu_resolve(console *const cnsl, bus *const b, const uint16_t va) void mmu_resolve(console *const cnsl, bus *const b, const uint16_t va)
{ {
int run_mode = b->getCpu()->getPSW_runmode(); int run_mode = b->getCpu()->getPSW_runmode();
@ -647,6 +659,14 @@ void mmu_resolve(console *const cnsl, bus *const b, const uint16_t va)
dump_par_pdr(cnsl, b, ADDR_PDR_U_START, ADDR_PAR_U_START, "user i-space", 0, data.apf); dump_par_pdr(cnsl, b, ADDR_PDR_U_START, ADDR_PAR_U_START, "user i-space", 0, data.apf);
dump_par_pdr(cnsl, b, ADDR_PDR_U_START + 020, ADDR_PAR_U_START + 020, "user d-space", 1 + (!!(mmr3 & 4)), data.apf); dump_par_pdr(cnsl, b, ADDR_PDR_U_START + 020, ADDR_PAR_U_START + 020, "user d-space", 1 + (!!(mmr3 & 4)), data.apf);
} }
for(int i=0; i<2; i++) {
auto ta_i = b->get_trap_action(run_mode, false, data.apf, i);
auto ta_d = b->get_trap_action(run_mode, true, data.apf, i);
cnsl->put_string_lf(format("Instruction action: %s (%s)", trap_action_to_str(ta_i.first), i ? "write" : "read"));
cnsl->put_string_lf(format("Data action : %s (%s)", trap_action_to_str(ta_d.first), i ? "write" : "read"));
}
} }
void reg_dump(console *const cnsl, cpu *const c) void reg_dump(console *const cnsl, cpu *const c)