mirror of
https://github.com/holub/mame
synced 2025-06-17 01:38:59 +03:00
Merge pull request #394 from Happy-yappH/master
Fix to allow mips3 exceptions to detect branch delay slots for settin…
This commit is contained in:
commit
134f684964
@ -95,8 +95,6 @@ static const UINT8 fpmode_source[4] =
|
|||||||
uml::ROUND_FLOOR
|
uml::ROUND_FLOOR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
MEMORY ACCESSORS
|
MEMORY ACCESSORS
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -130,6 +128,7 @@ mips3_device::mips3_device(const machine_config &mconfig, device_type type, cons
|
|||||||
, m_ppc(0)
|
, m_ppc(0)
|
||||||
, m_nextpc(0)
|
, m_nextpc(0)
|
||||||
, m_pcbase(0)
|
, m_pcbase(0)
|
||||||
|
, m_delayslot(false)
|
||||||
, m_op(0)
|
, m_op(0)
|
||||||
, m_interrupt_cycles(0)
|
, m_interrupt_cycles(0)
|
||||||
, m_ll_value(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 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_nextpc = ~0;
|
||||||
m_core->cpr[0][COP0_EPC] -= 4;
|
m_core->cpr[0][COP0_EPC] -= 4;
|
||||||
CAUSE |= 0x80000000;
|
CAUSE |= 0x80000000;
|
||||||
@ -2767,12 +2767,16 @@ void mips3_device::execute_run()
|
|||||||
/* adjust for next PC */
|
/* adjust for next PC */
|
||||||
if (m_nextpc != ~0)
|
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_core->pc = m_nextpc;
|
||||||
m_nextpc = ~0;
|
m_nextpc = ~0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
m_delayslot = false;
|
||||||
m_core->pc += 4;
|
m_core->pc += 4;
|
||||||
|
}
|
||||||
/* parse the instruction */
|
/* parse the instruction */
|
||||||
const int switch_val = (op >> 26) & 0x3f;
|
const int switch_val = (op >> 26) & 0x3f;
|
||||||
|
|
||||||
@ -2910,6 +2914,8 @@ void mips3_device::execute_run()
|
|||||||
case 0x3f: /* SD */ WDOUBLE(SIMMVAL+RSVAL32, RTVAL64); break;
|
case 0x3f: /* SD */ WDOUBLE(SIMMVAL+RSVAL32, RTVAL64); break;
|
||||||
default: /* ??? */ invalid_instruction(op); 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--;
|
m_core->icount--;
|
||||||
|
|
||||||
} while (m_core->icount > 0 || m_nextpc != ~0);
|
} while (m_core->icount > 0 || m_nextpc != ~0);
|
||||||
|
@ -366,6 +366,7 @@ private:
|
|||||||
UINT32 m_nextpc;
|
UINT32 m_nextpc;
|
||||||
UINT32 m_pcbase;
|
UINT32 m_pcbase;
|
||||||
UINT8 m_cf[4][8];
|
UINT8 m_cf[4][8];
|
||||||
|
bool m_delayslot;
|
||||||
int m_op;
|
int m_op;
|
||||||
int m_interrupt_cycles;
|
int m_interrupt_cycles;
|
||||||
UINT32 m_ll_value;
|
UINT32 m_ll_value;
|
||||||
|
@ -556,9 +556,9 @@ void n64_periphs::sp_dma(int direction)
|
|||||||
length = (length + 7) & ~7;
|
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)
|
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_status(status & ~DP_STATUS_START_VALID);
|
||||||
state->m_rdp->set_current(state->m_rdp->get_start());
|
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);
|
g_profiler.start(PROFILER_USER1);
|
||||||
state->m_rdp->process_command_list();
|
state->m_rdp->process_command_list();
|
||||||
g_profiler.stop();
|
g_profiler.stop();
|
||||||
@ -985,7 +985,7 @@ WRITE32_MEMBER( n64_periphs::dp_reg_w )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state->m_rdp->set_end(data & ~ 7);
|
state->m_rdp->set_end(data & ~7);
|
||||||
g_profiler.start(PROFILER_USER1);
|
g_profiler.start(PROFILER_USER1);
|
||||||
state->m_rdp->process_command_list();
|
state->m_rdp->process_command_list();
|
||||||
g_profiler.stop();
|
g_profiler.stop();
|
||||||
|
Loading…
Reference in New Issue
Block a user