summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/mips/r3000.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/mips/r3000.cpp')
-rw-r--r--src/devices/cpu/mips/r3000.cpp42
1 files changed, 28 insertions, 14 deletions
diff --git a/src/devices/cpu/mips/r3000.cpp b/src/devices/cpu/mips/r3000.cpp
index fd906584aa7..b84147483d2 100644
--- a/src/devices/cpu/mips/r3000.cpp
+++ b/src/devices/cpu/mips/r3000.cpp
@@ -635,10 +635,10 @@ void r3000_device::writecache_le_dword(offs_t offset, uint32_t data)
EXECEPTION HANDLING
***************************************************************************/
-inline void r3000_device::generate_exception(int exception)
+inline void r3000_device::generate_exception(int exception, bool backup)
{
// set the exception PC
- m_cpr[0][COP0_EPC] = (exception == EXCEPTION_SYSCALL ? m_ppc : m_pc);
+ m_cpr[0][COP0_EPC] = backup ? m_ppc : m_pc;
// put the cause in the low 8 bits and clear the branch delay flag
CAUSE = (CAUSE & ~0x800000ff) | (exception << 2);
@@ -668,7 +668,7 @@ inline void r3000_device::generate_exception(int exception)
inline void r3000_device::invalid_instruction()
{
- generate_exception(EXCEPTION_INVALIDOP);
+ generate_exception(EXCEPTION_INVALIDOP, true);
}
@@ -679,7 +679,7 @@ inline void r3000_device::invalid_instruction()
void r3000_device::check_irqs()
{
if ((CAUSE & SR & 0xff00) && (SR & SR_IEc))
- generate_exception(EXCEPTION_INTERRUPT);
+ generate_exception(EXCEPTION_INTERRUPT, false);
}
@@ -756,7 +756,7 @@ inline void r3000_device::set_cop0_creg(int idx, uint32_t val)
inline void r3000_device::handle_cop0()
{
if (!(SR & SR_COP0) && (SR & SR_KUc))
- generate_exception(EXCEPTION_BADCOP);
+ generate_exception(EXCEPTION_BADCOP, true);
switch (RSREG)
{
@@ -833,7 +833,7 @@ inline void r3000_device::set_cop1_creg(int idx, uint32_t val)
inline void r3000_device::handle_cop1()
{
if (!(SR & SR_COP1))
- generate_exception(EXCEPTION_BADCOP);
+ generate_exception(EXCEPTION_BADCOP, true);
if (!m_hasfpu)
return;
@@ -901,7 +901,7 @@ inline void r3000_device::set_cop2_creg(int idx, uint32_t val)
inline void r3000_device::handle_cop2()
{
if (!(SR & SR_COP2))
- generate_exception(EXCEPTION_BADCOP);
+ generate_exception(EXCEPTION_BADCOP, true);
switch (RSREG)
{
@@ -967,7 +967,7 @@ inline void r3000_device::set_cop3_creg(int idx, uint32_t val)
inline void r3000_device::handle_cop3()
{
if (!(SR & SR_COP3))
- generate_exception(EXCEPTION_BADCOP);
+ generate_exception(EXCEPTION_BADCOP, true);
switch (RSREG)
{
@@ -1076,6 +1076,20 @@ void r3000_device::execute_run()
m_ppc = m_pc;
debugger_instruction_hook(m_pc);
+ if ((m_pc & 0x1fffffff) == 0x00012C48 || (m_pc & 0x1fffffff) == 0x0001420C || (m_pc & 0x1fffffff) == 0x0001430C)
+ {
+ uint32_t ptr = m_r[5];
+ uint32_t length = m_r[6];
+ if (length >= 4096)
+ length = 4095;
+ while (length)
+ {
+ printf("%c", (char)RBYTE(ptr));
+ ptr++;
+ length--;
+ }
+ fflush(stdout);
+ }
// instruction fetch
m_op = readop(m_pc);
@@ -1102,9 +1116,9 @@ void r3000_device::execute_run()
case 0x07: /* SRAV */ if (RDREG) RDVAL = (int32_t)RTVAL >> (RSVAL & 31); break;
case 0x08: /* JR */ SETPC(RSVAL); break;
case 0x09: /* JALR */ SETPCL(RSVAL, RDREG); break;
- case 0x0c: /* SYSCALL */ generate_exception(EXCEPTION_SYSCALL); break;
- case 0x0d: /* BREAK */ generate_exception(EXCEPTION_BREAK); break;
- case 0x0f: /* SYNC */ invalid_instruction(); break;
+ case 0x0c: /* SYSCALL */ generate_exception(EXCEPTION_SYSCALL, true); break;
+ case 0x0d: /* BREAK */ generate_exception(EXCEPTION_BREAK, true); break;
+ case 0x0f: /* SYNC */ invalid_instruction(); break;
case 0x10: /* MFHI */ if (RDREG) RDVAL = m_hi; break;
case 0x11: /* MTHI */ m_hi = RSVAL; break;
case 0x12: /* MFLO */ if (RDREG) RDVAL = m_lo; break;
@@ -1138,12 +1152,12 @@ void r3000_device::execute_run()
m_icount -= 34;
break;
case 0x20: /* ADD */
- if (ENABLE_OVERFLOWS && RSVAL > ~RTVAL) generate_exception(EXCEPTION_OVERFLOW);
+ if (ENABLE_OVERFLOWS && RSVAL > ~RTVAL) generate_exception(EXCEPTION_OVERFLOW, true);
else RDVAL = RSVAL + RTVAL;
break;
case 0x21: /* ADDU */ if (RDREG) RDVAL = RSVAL + RTVAL; break;
case 0x22: /* SUB */
- if (ENABLE_OVERFLOWS && RSVAL < RTVAL) generate_exception(EXCEPTION_OVERFLOW);
+ if (ENABLE_OVERFLOWS && RSVAL < RTVAL) generate_exception(EXCEPTION_OVERFLOW, true);
else RDVAL = RSVAL - RTVAL;
break;
case 0x23: /* SUBU */ if (RDREG) RDVAL = RSVAL - RTVAL; break;
@@ -1191,7 +1205,7 @@ void r3000_device::execute_run()
case 0x06: /* BLEZ */ if ((int32_t)RSVAL <= 0) ADDPC(SIMMVAL); break;
case 0x07: /* BGTZ */ if ((int32_t)RSVAL > 0) ADDPC(SIMMVAL); break;
case 0x08: /* ADDI */
- if (ENABLE_OVERFLOWS && RSVAL > ~SIMMVAL) generate_exception(EXCEPTION_OVERFLOW);
+ if (ENABLE_OVERFLOWS && RSVAL > ~SIMMVAL) generate_exception(EXCEPTION_OVERFLOW, true);
else if (RTREG) RTVAL = RSVAL + SIMMVAL;
break;
case 0x09: /* ADDIU */ if (RTREG) RTVAL = RSVAL + SIMMVAL; break;