diff options
author | 2015-09-07 22:14:16 -0600 | |
---|---|---|
committer | 2015-09-07 22:14:16 -0600 | |
commit | 3cb8f5d368628b98acd74d1672017d0f5ba9e8de (patch) | |
tree | 719c6d8db9c6a7f44ceb3a74382562608137ada1 /src/emu/cpu/mips/mips3.c | |
parent | 9b3b4cdf053a8696ce2a570ed6700835fc1f8c0f (diff) |
N64 driver improvements.
Add coprocessor unusable exceptions for LWC1/SWC1/LDC1/SDC1.
Change PI DMA granularity from eight bytes to two bytes.
Add delay timer for SI DMA.
Change behavior for interlaced video to be more useful, but still needing revision.
Simplify/remove some AI DMA interrupt signals.
Removed line that cleared EEPROM contents with every machine reset (warm or cold).
Diffstat (limited to 'src/emu/cpu/mips/mips3.c')
-rw-r--r-- | src/emu/cpu/mips/mips3.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/src/emu/cpu/mips/mips3.c b/src/emu/cpu/mips/mips3.c index ce8466b2b21..00e3d7bc1c0 100644 --- a/src/emu/cpu/mips/mips3.c +++ b/src/emu/cpu/mips/mips3.c @@ -2845,11 +2845,23 @@ void mips3_device::execute_run() case 0x2e: /* SWR */ (this->*m_swr)(op); break; case 0x2f: /* CACHE */ /* effective no-op */ break; case 0x30: /* LL */ if (RWORD(SIMMVAL+RSVAL32, &temp) && RTREG) RTVAL64 = (UINT32)temp; m_ll_value = RTVAL32; break; - case 0x31: /* LWC1 */ if (RWORD(SIMMVAL+RSVAL32, &temp)) set_cop1_reg32(RTREG, temp); break; + case 0x31: /* LWC1 */ + if (!(SR & SR_COP1)) + { + m_badcop_value = 1; + generate_exception(EXCEPTION_BADCOP, 1); + } + if (RWORD(SIMMVAL+RSVAL32, &temp)) set_cop1_reg32(RTREG, temp); break; case 0x32: /* LWC2 */ if (RWORD(SIMMVAL+RSVAL32, &temp)) set_cop2_reg(RTREG, temp); break; case 0x33: /* PREF */ /* effective no-op */ break; case 0x34: /* LLD */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG) RTVAL64 = temp64; m_lld_value = temp64; break; - case 0x35: /* LDC1 */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64)) set_cop1_reg64(RTREG, temp64); break; + case 0x35: /* LDC1 */ + if (!(SR & SR_COP1)) + { + m_badcop_value = 1; + generate_exception(EXCEPTION_BADCOP, 1); + } + if (RDOUBLE(SIMMVAL+RSVAL32, &temp64)) set_cop1_reg64(RTREG, temp64); break; case 0x36: /* LDC2 */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64)) set_cop2_reg(RTREG, temp64); break; case 0x37: /* LD */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG) RTVAL64 = temp64; break; case 0x38: /* SC */ if (RWORD(SIMMVAL+RSVAL32, &temp) && RTREG) @@ -2865,7 +2877,13 @@ void mips3_device::execute_run() } } break; - case 0x39: /* SWC1 */ WWORD(SIMMVAL+RSVAL32, get_cop1_reg32(RTREG)); break; + case 0x39: /* SWC1 */ + if (!(SR & SR_COP1)) + { + m_badcop_value = 1; + generate_exception(EXCEPTION_BADCOP, 1); + } + WWORD(SIMMVAL+RSVAL32, get_cop1_reg32(RTREG)); break; case 0x3a: /* SWC2 */ WWORD(SIMMVAL+RSVAL32, get_cop2_reg(RTREG)); break; case 0x3b: /* SWC3 */ invalid_instruction(op); break; case 0x3c: /* SCD */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG) @@ -2881,7 +2899,13 @@ void mips3_device::execute_run() } } break; - case 0x3d: /* SDC1 */ WDOUBLE(SIMMVAL+RSVAL32, get_cop1_reg64(RTREG)); break; + case 0x3d: /* SDC1 */ + if (!(SR & SR_COP1)) + { + m_badcop_value = 1; + generate_exception(EXCEPTION_BADCOP, 1); + } + WDOUBLE(SIMMVAL+RSVAL32, get_cop1_reg64(RTREG)); break; case 0x3e: /* SDC2 */ WDOUBLE(SIMMVAL+RSVAL32, get_cop2_reg(RTREG)); break; case 0x3f: /* SD */ WDOUBLE(SIMMVAL+RSVAL32, RTVAL64); break; default: /* ??? */ invalid_instruction(op); break; |