summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/mips/mips3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/mips/mips3.cpp')
-rw-r--r--src/devices/cpu/mips/mips3.cpp44
1 files changed, 19 insertions, 25 deletions
diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp
index 039d4259e02..6989e262492 100644
--- a/src/devices/cpu/mips/mips3.cpp
+++ b/src/devices/cpu/mips/mips3.cpp
@@ -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