mirror of
https://github.com/holub/mame
synced 2025-07-01 16:19:38 +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 */
|
/* translate our fake fill exceptions into real exceptions */
|
||||||
if (exception == EXCEPTION_TLBLOAD_FILL || exception == EXCEPTION_TLBSTORE_FILL)
|
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;
|
exception = (exception - EXCEPTION_TLBLOAD_FILL) + EXCEPTION_TLBLOAD;
|
||||||
}
|
}
|
||||||
else if (exception == EXCEPTION_INTERRUPT && m_flavor == MIPS3_TYPE_R5900)
|
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;
|
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 */
|
/* put the cause in the low 8 bits and clear the branch delay flag */
|
||||||
CAUSE = (CAUSE & ~0x800000ff) | (exception << 2);
|
CAUSE = (CAUSE & ~0x800000ff) | (exception << 2);
|
||||||
|
|
||||||
@ -308,31 +307,26 @@ void mips3_device::generate_exception(int exception, int backup)
|
|||||||
CAUSE |= m_badcop_value << 28;
|
CAUSE |= m_badcop_value << 28;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we were in a branch delay slot, adjust */
|
/* check if exception within another exception */
|
||||||
if ((m_nextpc != ~0) || (m_delayslot))
|
if (!(SR & SR_EXL))
|
||||||
{
|
{
|
||||||
m_delayslot = false;
|
/* if we were in a branch delay slot, adjust */
|
||||||
m_nextpc = ~0;
|
if ((m_nextpc != ~0) || (m_delayslot))
|
||||||
m_core->cpr[0][COP0_EPC] -= 4;
|
{
|
||||||
CAUSE |= 0x80000000;
|
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 */
|
/* set the exception level */
|
||||||
SR |= SR_EXL;
|
SR |= SR_EXL;
|
||||||
|
}
|
||||||
|
|
||||||
/* based on the BEV bit, we either go to ROM or RAM */
|
/* based on the BEV bit, we either go to ROM or RAM */
|
||||||
m_core->pc = (SR & SR_BEV) ? 0xbfc00200 : 0x80000000;
|
m_core->pc = ((SR & SR_BEV) ? 0xbfc00200 : 0x80000000) + offset;
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
useful for tracking interrupts
|
useful for tracking interrupts
|
||||||
|
Loading…
Reference in New Issue
Block a user