mirror of
https://github.com/holub/mame
synced 2025-07-01 00:09:18 +03:00
mips3: exception handling fixes (nw)
* nested exceptions shouldn't overwrite the EPC * nested tlb exceptions go to the general exception vector * remove breakpoint for tlb exceptions and branch to proper vector
This commit is contained in:
parent
4148447f3a
commit
f0f23e29a1
@ -288,7 +288,9 @@ void mips3_device::generate_exception(int exception, int backup)
|
||||
/* translate our fake fill exceptions into real exceptions */
|
||||
if (exception == EXCEPTION_TLBLOAD_FILL || exception == EXCEPTION_TLBSTORE_FILL)
|
||||
{
|
||||
offset = 0;
|
||||
/* don't use the tlb exception offset if within another exception */
|
||||
if (!(SR & SR_EXL))
|
||||
offset = 0;
|
||||
exception = (exception - EXCEPTION_TLBLOAD_FILL) + EXCEPTION_TLBLOAD;
|
||||
}
|
||||
else if (exception == EXCEPTION_INTERRUPT && m_flavor == MIPS3_TYPE_R5900)
|
||||
@ -296,9 +298,6 @@ void mips3_device::generate_exception(int exception, int backup)
|
||||
offset = 0x200;
|
||||
}
|
||||
|
||||
/* set the exception PC */
|
||||
m_core->cpr[0][COP0_EPC] = m_core->pc;
|
||||
|
||||
/* put the cause in the low 8 bits and clear the branch delay flag */
|
||||
CAUSE = (CAUSE & ~0x800000ff) | (exception << 2);
|
||||
|
||||
@ -308,31 +307,26 @@ void mips3_device::generate_exception(int exception, int backup)
|
||||
CAUSE |= m_badcop_value << 28;
|
||||
}
|
||||
|
||||
/* if we were in a branch delay slot, adjust */
|
||||
if ((m_nextpc != ~0) || (m_delayslot))
|
||||
/* check if exception within another exception */
|
||||
if (!(SR & SR_EXL))
|
||||
{
|
||||
m_delayslot = false;
|
||||
m_nextpc = ~0;
|
||||
m_core->cpr[0][COP0_EPC] -= 4;
|
||||
CAUSE |= 0x80000000;
|
||||
}
|
||||
/* if we were in a branch delay slot, adjust */
|
||||
if ((m_nextpc != ~0) || (m_delayslot))
|
||||
{
|
||||
m_delayslot = false;
|
||||
m_nextpc = ~0;
|
||||
m_core->cpr[0][COP0_EPC] = m_core->pc - 4;
|
||||
CAUSE |= 0x80000000;
|
||||
}
|
||||
else
|
||||
m_core->cpr[0][COP0_EPC] = m_core->pc;
|
||||
|
||||
/* set the exception level */
|
||||
SR |= SR_EXL;
|
||||
/* set the exception level */
|
||||
SR |= SR_EXL;
|
||||
}
|
||||
|
||||
/* based on the BEV bit, we either go to ROM or RAM */
|
||||
m_core->pc = (SR & SR_BEV) ? 0xbfc00200 : 0x80000000;
|
||||
|
||||
/* most exceptions go to offset 0x180, except for TLB stuff */
|
||||
if (exception >= EXCEPTION_TLBMOD && exception <= EXCEPTION_TLBSTORE)
|
||||
{
|
||||
fprintf(stderr, "TLB miss @ %08X\n", (uint32_t)m_core->cpr[0][COP0_BadVAddr]);
|
||||
machine().debug_break();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_core->pc += offset;
|
||||
}
|
||||
m_core->pc = ((SR & SR_BEV) ? 0xbfc00200 : 0x80000000) + offset;
|
||||
|
||||
/*
|
||||
useful for tracking interrupts
|
||||
|
Loading…
Reference in New Issue
Block a user