trap action
This commit is contained in:
parent
6941b44ace
commit
078bf2da43
3 changed files with 58 additions and 26 deletions
55
bus.cpp
55
bus.cpp
|
@ -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
3
bus.h
|
@ -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;
|
||||||
|
|
20
debugger.cpp
20
debugger.cpp
|
@ -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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue