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

61
bus.cpp
View file

@ -563,6 +563,38 @@ bool bus::get_use_data_space(const int run_mode) const
return !!(MMR3 & di_ena_mask[run_mode]);
}
std::pair<trap_action_t, int> bus::get_trap_action(const int run_mode, const bool d, const int apf, const bool is_write)
{
const int access_control = pages[run_mode][d][apf].pdr & 7;
trap_action_t trap_action = T_PROCEED;
if (access_control == 0)
trap_action = T_ABORT_4;
else if (access_control == 1)
trap_action = is_write ? T_ABORT_4 : T_TRAP_250;
else if (access_control == 2) {
if (is_write)
trap_action = T_ABORT_4;
}
else if (access_control == 3)
trap_action = T_ABORT_4;
else if (access_control == 4)
trap_action = T_TRAP_250;
else if (access_control == 5) {
if (is_write)
trap_action = T_TRAP_250;
}
else if (access_control == 6) {
// proceed
}
else if (access_control == 7) {
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;
@ -586,32 +618,9 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c
if (trap_on_failure) {
{
const int access_control = pages[run_mode][d][apf].pdr & 7;
enum { T_PROCEED, T_ABORT_4, T_TRAP_250 } trap_action { T_PROCEED };
if (access_control == 0)
trap_action = T_ABORT_4;
else if (access_control == 1)
trap_action = is_write ? T_ABORT_4 : T_TRAP_250;
else if (access_control == 2) {
if (is_write)
trap_action = T_ABORT_4;
}
else if (access_control == 3)
trap_action = T_ABORT_4;
else if (access_control == 4)
trap_action = T_TRAP_250;
else if (access_control == 5) {
if (is_write)
trap_action = T_TRAP_250;
}
else if (access_control == 6) {
// proceed
}
else if (access_control == 7) {
trap_action = T_ABORT_4;
}
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 (is_write)

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 { T_PROCEED, T_ABORT_4, T_TRAP_250 } trap_action_t;
typedef struct {
uint16_t virtual_address;
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; }
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);
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)
{
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 + 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)