diff options
author | 2015-10-20 09:25:37 -0400 | |
---|---|---|
committer | 2015-10-20 09:25:37 -0400 | |
commit | 134f684964905376842cbeb521c3b22b7feff9ad (patch) | |
tree | 30c543f26ce32bfbe812a97817cec50b57d6ecfe | |
parent | a93a5f53efd0cc391a606530a6241cd8592c15f2 (diff) | |
parent | 07602e737d93fa9a4ff417698f94a540a93d06dc (diff) |
Merge pull request #394 from Happy-yappH/master
Fix to allow mips3 exceptions to detect branch delay slots for settin…
-rw-r--r-- | src/devices/cpu/mips/mips3.c | 14 | ||||
-rw-r--r-- | src/devices/cpu/mips/mips3.h | 1 | ||||
-rw-r--r-- | src/mame/machine/n64.c | 8 |
3 files changed, 15 insertions, 8 deletions
diff --git a/src/devices/cpu/mips/mips3.c b/src/devices/cpu/mips/mips3.c index 7ee13632695..907adfb2926 100644 --- a/src/devices/cpu/mips/mips3.c +++ b/src/devices/cpu/mips/mips3.c @@ -95,8 +95,6 @@ static const UINT8 fpmode_source[4] = uml::ROUND_FLOOR }; - - /*************************************************************************** MEMORY ACCESSORS ***************************************************************************/ @@ -130,6 +128,7 @@ mips3_device::mips3_device(const machine_config &mconfig, device_type type, cons , m_ppc(0) , m_nextpc(0) , m_pcbase(0) + , m_delayslot(false) , m_op(0) , m_interrupt_cycles(0) , m_ll_value(0) @@ -255,8 +254,9 @@ void mips3_device::generate_exception(int exception, int backup) } /* if we were in a branch delay slot, adjust */ - if (m_nextpc != ~0) + if ((m_nextpc != ~0) || (m_delayslot)) { + m_delayslot = false; m_nextpc = ~0; m_core->cpr[0][COP0_EPC] -= 4; CAUSE |= 0x80000000; @@ -2767,12 +2767,16 @@ void mips3_device::execute_run() /* adjust for next PC */ if (m_nextpc != ~0) { + /* Exceptions need to be able to see delayslot, since nextpc gets cleared before instruction execution */ + m_delayslot = true; m_core->pc = m_nextpc; m_nextpc = ~0; } else + { + m_delayslot = false; m_core->pc += 4; - + } /* parse the instruction */ const int switch_val = (op >> 26) & 0x3f; @@ -2910,6 +2914,8 @@ void mips3_device::execute_run() case 0x3f: /* SD */ WDOUBLE(SIMMVAL+RSVAL32, RTVAL64); break; default: /* ??? */ invalid_instruction(op); break; } + /* Clear this flag once instruction execution is finished, will interfere with interrupt exceptions otherwise */ + m_delayslot = false; m_core->icount--; } while (m_core->icount > 0 || m_nextpc != ~0); diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h index b8d9330cffb..4ae8398dac0 100644 --- a/src/devices/cpu/mips/mips3.h +++ b/src/devices/cpu/mips/mips3.h @@ -366,6 +366,7 @@ private: UINT32 m_nextpc; UINT32 m_pcbase; UINT8 m_cf[4][8]; + bool m_delayslot; int m_op; int m_interrupt_cycles; UINT32 m_ll_value; diff --git a/src/mame/machine/n64.c b/src/mame/machine/n64.c index bcdba51e104..fda94a7fde8 100644 --- a/src/mame/machine/n64.c +++ b/src/mame/machine/n64.c @@ -556,9 +556,9 @@ void n64_periphs::sp_dma(int direction) length = (length + 7) & ~7; } - if (sp_mem_addr & 0x3) + if (sp_mem_addr & 0x7) { - sp_mem_addr = sp_mem_addr & ~3; + sp_mem_addr = sp_mem_addr & ~7; } if (sp_dram_addr & 0x7) { @@ -977,7 +977,7 @@ WRITE32_MEMBER( n64_periphs::dp_reg_w ) { state->m_rdp->set_status(status & ~DP_STATUS_START_VALID); state->m_rdp->set_current(state->m_rdp->get_start()); - state->m_rdp->set_end(data & ~ 7); + state->m_rdp->set_end(data & ~7); g_profiler.start(PROFILER_USER1); state->m_rdp->process_command_list(); g_profiler.stop(); @@ -985,7 +985,7 @@ WRITE32_MEMBER( n64_periphs::dp_reg_w ) } else { - state->m_rdp->set_end(data & ~ 7); + state->m_rdp->set_end(data & ~7); g_profiler.start(PROFILER_USER1); state->m_rdp->process_command_list(); g_profiler.stop(); |