From b8e4a35de632ddbe254fe3475092a6b399a3b04d Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Fri, 5 Dec 2008 05:02:52 +0000 Subject: [PATCH] Major Fix: Found and fixed a big vmhack / COP0 bug. This should fix several games, including those in Issue 49, Issue 58, and possibly Issue 59 as well (testing of those issues and a confirmation is needed). Code cleanup to iHw.c : Removed some rampant abuse of macros and quite a bit of unnecessary code bloat. git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@393 a6443dda-0b58-4228-96e9-037be469359c --- pcsx2/COP0.c | 13 +- pcsx2/Hw.c | 4 +- pcsx2/R5900.c | 11 +- pcsx2/Sif.c | 5 +- pcsx2/x86/iCP0.c | 61 ++++++++-- pcsx2/x86/iHw.c | 308 ++++++++++++++++++++++------------------------- 6 files changed, 216 insertions(+), 186 deletions(-) diff --git a/pcsx2/COP0.c b/pcsx2/COP0.c index 83250851ce..a2a1699646 100644 --- a/pcsx2/COP0.c +++ b/pcsx2/COP0.c @@ -134,8 +134,7 @@ void MTC0() { } int CPCOND0() { - if(((psHu16(DMAC_STAT) & psHu16(DMAC_PCR)) & 0x3ff) == (psHu16(DMAC_PCR) & 0x3ff)) return 1; - else return 0; + return (((psHu16(DMAC_STAT) & psHu16(DMAC_PCR)) & 0x3ff) == (psHu16(DMAC_PCR) & 0x3ff)); } //#define CPCOND0 1 @@ -147,10 +146,12 @@ int CPCOND0() { void BC0F() { BC0(== 0); + COP0_LOG( "COP0 > BC0F\n" ); } void BC0T() { BC0(== 1); + COP0_LOG( "COP0 > BC0T\n" ); } #define BC0L(cond) \ @@ -160,10 +161,12 @@ void BC0T() { void BC0FL() { BC0L(== 0); + COP0_LOG( "COP0 > BC0FL\n" ); } void BC0TL() { BC0L(== 1); + COP0_LOG( "COP0 > BCOTL\n" ); } void TLBR() { @@ -176,7 +179,7 @@ void TLBR() { // if( !bExecBIOS ) // __Log("TLBR %d\n", cpuRegs.CP0.n.Index&0x1f); - SysPrintf("COP0_TLBR\n"); + COP0_LOG("COP0 > TLBR\n"); cpuRegs.CP0.n.PageMask = tlb[i].PageMask; cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi&~(tlb[i].PageMask|0x1f00); cpuRegs.CP0.n.EntryLo0 = (tlb[i].EntryLo0&~1)|((tlb[i].EntryHi>>12)&1); @@ -219,6 +222,8 @@ void WriteTLB(int i) { u32 mask, addr; u32 saddr, eaddr; + COP0_LOG( "COP0 > WriteTLB" ); + tlb[i].PageMask = cpuRegs.CP0.n.PageMask; tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi; tlb[i].EntryLo0 = cpuRegs.CP0.n.EntryLo0; @@ -340,7 +345,7 @@ void DI() { if (cpuRegs.CP0.n.Status.b._EDI || cpuRegs.CP0.n.Status.b.EXL || cpuRegs.CP0.n.Status.b.ERL || (cpuRegs.CP0.n.Status.b.KSU == 0)) { cpuRegs.CP0.n.Status.b.EIE = 0; - UpdateCP0Status(); + //UpdateCP0Status(); // ints are disabled so checking for them is kinda silly... } } diff --git a/pcsx2/Hw.c b/pcsx2/Hw.c index c7bdae4ea9..5a9849ce31 100644 --- a/pcsx2/Hw.c +++ b/pcsx2/Hw.c @@ -1160,7 +1160,7 @@ __forceinline void intcInterrupt() { } // fixme: dead/unused code? -void dmacTestInterrupt() { +/*void dmacTestInterrupt() { cpuRegs.interrupt &= ~(1 << 31); if ((cpuRegs.CP0.n.Status.val & 0x800) != 0x800) return; @@ -1168,7 +1168,7 @@ void dmacTestInterrupt() { psHu16(0xe010) & 0x8000) == 0) return; if((psHu32(DMAC_CTRL) & 0x1) == 0) return; -} +}*/ __forceinline void dmacInterrupt() { diff --git a/pcsx2/R5900.c b/pcsx2/R5900.c index 571d5cc316..43924dd40b 100644 --- a/pcsx2/R5900.c +++ b/pcsx2/R5900.c @@ -414,6 +414,11 @@ static __forceinline void _cpuTestTIMR() cpuRegs.CP0.n.Count += cpuRegs.cycle-s_iLastCOP0Cycle; s_iLastCOP0Cycle = cpuRegs.cycle; + // fixme: this looks like a hack to make up for the fact that the TIMR + // doesn't yet have a proper mecahnism for setting itself up on a nextBranchCycle. + // A proper fix would schedule the TIMR to trigger at a specific cycle anytime + // the Count or Compare registers are modified. + if ( (cpuRegs.CP0.n.Status.val & 0x8000) && cpuRegs.CP0.n.Count >= cpuRegs.CP0.n.Compare && cpuRegs.CP0.n.Count < cpuRegs.CP0.n.Compare+1000 ) { SysPrintf("timr intr: %x, %x\n", cpuRegs.CP0.n.Count, cpuRegs.CP0.n.Compare); @@ -440,7 +445,7 @@ static __forceinline void _cpuTestPERF() // Maximum wait between branches. Lower values provide a tighter synchronization between // the EE and the IOP, but incur more execution overhead. -#define EE_WAIT_CYCLE 512 // 2048 is still unstable due to COP0 +#define EE_WAIT_CYCLE 1024 // 2048 is probably stable now, but starting low first // if cpuRegs.cycle is greater than this cycle, should check cpuBranchTest for updates u32 g_nextBranchCycle = 0; @@ -463,9 +468,9 @@ static __forceinline void _cpuBranchTest_Shared() if( cpuTestCycle( nextsCounter, nextCounter ) ) { rcntUpdate(); + _cpuTestPERF(); } - _cpuTestPERF(); _cpuTestTIMR(); //#ifdef CPU_LOG @@ -496,7 +501,7 @@ static __forceinline void _cpuBranchTest_Shared() if( iopBranchAction ) { //if( EEsCycle < -500 ) - // SysPrintf( " IOP ahead by: %d\n", -EEsCycle ); + // SysPrintf( " IOP ahead by: %d cycles\n", -EEsCycle ); psxCpu->ExecuteBlock(); } diff --git a/pcsx2/Sif.c b/pcsx2/Sif.c index 43b143ba3e..2f76f27407 100644 --- a/pcsx2/Sif.c +++ b/pcsx2/Sif.c @@ -516,13 +516,13 @@ __forceinline void sif1Interrupt() { __forceinline void EEsif0Interrupt() { sif0dma->chcr &= ~0x100; - hwDmacIrq(5); + hwDmacIrq(DMAC_SIF0); cpuRegs.interrupt &= ~(1 << 5); } __forceinline void EEsif1Interrupt() { - hwDmacIrq(6); + hwDmacIrq(DMAC_SIF1); sif1dma->chcr &= ~0x100; cpuRegs.interrupt &= ~(1 << 6); @@ -578,7 +578,6 @@ _inline void dmaSIF1() { } -// fixme: Unused code _inline void dmaSIF2() { SIF_LOG("dmaSIF2 chcr = %lx, madr = %lx, qwc = %lx\n", sif2dma->chcr, sif2dma->madr, sif2dma->qwc); diff --git a/pcsx2/x86/iCP0.c b/pcsx2/x86/iCP0.c index c5fd2bd765..3206d819a2 100644 --- a/pcsx2/x86/iCP0.c +++ b/pcsx2/x86/iCP0.c @@ -16,6 +16,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +// Important Note to Future Developers: +// None of the COP0 instructions are really critical performance items, +// so don't waste time converting any more them into recompiled code +// unless it can make them nicely compact. Calling the C versions will +// suffice. + #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) #include "Common.h" @@ -47,8 +53,6 @@ REC_SYS(EI); #else -//////////////////////////////////////////////////// -//REC_SYS(MTC0); //////////////////////////////////////////////////// REC_SYS(BC0F); //////////////////////////////////////////////////// @@ -65,12 +69,6 @@ REC_SYS(TLBWI); REC_SYS(TLBWR); //////////////////////////////////////////////////// REC_SYS(TLBP); -//////////////////////////////////////////////////// -REC_SYS(ERET); -//////////////////////////////////////////////////// -REC_SYS(DI); -//////////////////////////////////////////////////// -REC_SYS(EI); //////////////////////////////////////////////////// extern u32 s_iLastCOP0Cycle; @@ -329,6 +327,47 @@ void recMTC0() } } +void recERET() +{ + // Must branch immediately after ERET! + branch = 2; + MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code ); + MOV32MtoR( ECX, (uptr)&cpuRegs.cycle ); + MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc ); + MOV32RtoM( (uptr)&g_nextBranchCycle, ECX ); + iFlushCall(FLUSH_EVERYTHING); + CALLFunc( (uptr)ERET ); +} + +void recEI() +{ + // Must branch immediately after enabling ints! + branch = 2; + + MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code ); + MOV32MtoR( ECX, (uptr)&cpuRegs.cycle ); + MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc ); + MOV32RtoM( (uptr)&g_nextBranchCycle, ECX ); + + iFlushCall(FLUSH_EVERYTHING); + CALLFunc( (uptr)EI ); +} + +void recDI() +{ + // No need to branch after disabling interrupts... + + //branch = 2; + //MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code ); + MOV32MtoR( ECX, (uptr)&cpuRegs.cycle ); + //MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc ); + MOV32RtoM( (uptr)&g_nextBranchCycle, ECX ); + + iFlushCall(FLUSH_EVERYTHING); + CALLFunc( (uptr)DI ); +} + + /*void rec(COP0) { } @@ -354,11 +393,7 @@ void rec(TLBWR) { } void rec(TLBP) { -} - -void rec(ERET) { -} -*/ +}*/ #endif diff --git a/pcsx2/x86/iHw.c b/pcsx2/x86/iHw.c index b2dc37522f..db9ddea7a3 100644 --- a/pcsx2/x86/iHw.c +++ b/pcsx2/x86/iHw.c @@ -455,36 +455,38 @@ void hwConstRead128(u32 mem, int xmmreg) { } // when writing imm -#define recDmaExecI8(name, num) { \ - MOV8ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]); \ - if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 1 ) { \ - TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \ - j8Ptr[6] = JZ8(0); \ - CALLFunc((uptr)dma##name); \ - x86SetJ8( j8Ptr[6] ); \ - } \ -} \ +static void recDmaExecI8(void (*name)(), u32 mem, int mmreg) +{ + MOV8ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]); + if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 1 ) { + TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); + j8Ptr[6] = JZ8(0); + CALLFunc((uptr)name); + x86SetJ8( j8Ptr[6] ); + } +} -#define recDmaExec8(name, num) { \ - iFlushCall(0); \ - if( IS_EECONSTREG(mmreg) ) { \ - recDmaExecI8(name, num); \ - } \ - else { \ - _eeMoveMMREGtoR(EAX, mmreg); \ - _eeWriteConstMem8((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \ - \ - TEST8ItoR(EAX, 1); \ - j8Ptr[5] = JZ8(0); \ - TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \ - j8Ptr[6] = JZ8(0); \ - \ - CALLFunc((uptr)dma##name); \ - \ - x86SetJ8( j8Ptr[5] ); \ - x86SetJ8( j8Ptr[6] ); \ - } \ -} \ +static void recDmaExec8(void (*name)(), u32 mem, int mmreg) +{ + iFlushCall(0); + if( IS_EECONSTREG(mmreg) ) { + recDmaExecI8(name, mem, mmreg); + } + else { + _eeMoveMMREGtoR(EAX, mmreg); + _eeWriteConstMem8((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); + + TEST8ItoR(EAX, 1); + j8Ptr[5] = JZ8(0); + TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); + j8Ptr[6] = JZ8(0); + + CALLFunc((uptr)name); + + x86SetJ8( j8Ptr[5] ); + x86SetJ8( j8Ptr[6] ); + } +} static void PrintDebug(u8 value) { @@ -536,51 +538,51 @@ void hwConstWrite8(u32 mem, int mmreg) CONSTWRITE_TIMERS(8) case 0x1000f180: - _recPushReg(mmreg); \ + _recPushReg(mmreg); iFlushCall(0); CALLFunc((uptr)PrintDebug); ADD32ItoR(ESP, 4); break; case 0x10008001: // dma0 - vif0 - recDmaExec8(VIF0, 0); + recDmaExec8(dmaVIF0, mem, mmreg); break; case 0x10009001: // dma1 - vif1 - recDmaExec8(VIF1, 1); + recDmaExec8(dmaVIF1, mem, mmreg); break; case 0x1000a001: // dma2 - gif - recDmaExec8(GIF, 2); + recDmaExec8(dmaGIF, mem, mmreg); break; case 0x1000b001: // dma3 - fromIPU - recDmaExec8(IPU0, 3); + recDmaExec8(dmaIPU0, mem, mmreg); break; case 0x1000b401: // dma4 - toIPU - recDmaExec8(IPU1, 4); + recDmaExec8(dmaIPU1, mem, mmreg); break; case 0x1000c001: // dma5 - sif0 //if (value == 0) psxSu32(0x30) = 0x40000; - recDmaExec8(SIF0, 5); + recDmaExec8(dmaSIF0, mem, mmreg); break; case 0x1000c401: // dma6 - sif1 - recDmaExec8(SIF1, 6); + recDmaExec8(dmaSIF1, mem, mmreg); break; case 0x1000c801: // dma7 - sif2 - recDmaExec8(SIF2, 7); + recDmaExec8(dmaSIF2, mem, mmreg); break; case 0x1000d001: // dma8 - fromSPR - recDmaExec8(SPR0, 8); + recDmaExec8(dmaSPR0, mem, mmreg); break; case 0x1000d401: // dma9 - toSPR - recDmaExec8(SPR1, 9); + recDmaExec8(dmaSPR1, mem, mmreg); break; case 0x1000f592: // DMAC_ENABLEW @@ -636,79 +638,81 @@ void hwConstWrite8(u32 mem, int mmreg) } } -#define recDmaExecI16(name, num) { \ - MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]); \ - if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 0x100 ) { \ - TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \ - j8Ptr[6] = JZ8(0); \ - CALLFunc((uptr)dma##name); \ - x86SetJ8( j8Ptr[6] ); \ - } \ -} \ +static void recDmaExecI16( void (*name)(), u32 mem, int mmreg ) +{ + MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]); + if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 0x100 ) { + TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); + j8Ptr[6] = JZ8(0); + CALLFunc((uptr)name); + x86SetJ8( j8Ptr[6] ); + } +} -#define recDmaExec16(name, num) { \ - iFlushCall(0); \ - if( IS_EECONSTREG(mmreg) ) { \ - recDmaExecI16(name, num); \ - } \ - else { \ - _eeMoveMMREGtoR(EAX, mmreg); \ - _eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \ - \ - TEST16ItoR(EAX, 0x100); \ - j8Ptr[5] = JZ8(0); \ - TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \ - j8Ptr[6] = JZ8(0); \ - \ - CALLFunc((uptr)dma##name); \ - \ - x86SetJ8( j8Ptr[5] ); \ - x86SetJ8( j8Ptr[6] ); \ - } \ -} \ +static void recDmaExec16(void (*name)(), u32 mem, int mmreg) +{ + iFlushCall(0); + if( IS_EECONSTREG(mmreg) ) { + recDmaExecI16(name, mem, mmreg); + } + else { + _eeMoveMMREGtoR(EAX, mmreg); + _eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); + + TEST16ItoR(EAX, 0x100); + j8Ptr[5] = JZ8(0); + TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); + j8Ptr[6] = JZ8(0); + + CALLFunc((uptr)name); + + x86SetJ8( j8Ptr[5] ); + x86SetJ8( j8Ptr[6] ); + } +} void hwConstWrite16(u32 mem, int mmreg) { switch(mem) { CONSTWRITE_TIMERS(16) case 0x10008000: // dma0 - vif0 - recDmaExec16(VIF0, 0); + recDmaExec16(dmaVIF0, mem, mmreg); break; case 0x10009000: // dma1 - vif1 - chcr - recDmaExec16(VIF1, 1); + recDmaExec16(dmaVIF1, mem, mmreg); break; case 0x1000a000: // dma2 - gif - recDmaExec16(GIF, 2); + recDmaExec16(dmaGIF, mem, mmreg); break; case 0x1000b000: // dma3 - fromIPU - recDmaExec16(IPU0, 3); + recDmaExec16(dmaIPU0, mem, mmreg); break; case 0x1000b400: // dma4 - toIPU - recDmaExec16(IPU1, 4); + recDmaExec16(dmaIPU1, mem, mmreg); break; case 0x1000c000: // dma5 - sif0 //if (value == 0) psxSu32(0x30) = 0x40000; - recDmaExec16(SIF0, 5); + recDmaExec16(dmaSIF0, mem, mmreg); break; case 0x1000c002: //? break; case 0x1000c400: // dma6 - sif1 - recDmaExec16(SIF1, 6); + recDmaExec16(dmaSIF1, mem, mmreg); break; case 0x1000c800: // dma7 - sif2 - recDmaExec16(SIF2, 7); + recDmaExec16(dmaSIF2, mem, mmreg); break; case 0x1000c802: //? break; case 0x1000d000: // dma8 - fromSPR - recDmaExec16(SPR0, 8); + recDmaExec16(dmaSPR0, mem, mmreg); break; case 0x1000d400: // dma9 - toSPR - recDmaExec16(SPR1, 9); + recDmaExec16(dmaSPR1, mem, mmreg); break; case 0x1000f592: // DMAC_ENABLEW _eeWriteConstMem16((uptr)&PS2MEM_HW[0xf522], mmreg); @@ -781,57 +785,59 @@ void hwConstWrite16(u32 mem, int mmreg) } // when writing an Imm -#define recDmaExecI(name, num) { \ - u32 c = g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]; \ - /* Keep the old tag if in chain mode and hw doesnt set it*/ \ - if( (c & 0xc) == 0x4 && (c&0xffff0000) == 0 ) { \ - MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c); \ - } \ - else MOV32ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c); \ - if( c & 0x100 ) { \ - TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \ - j8Ptr[6] = JZ8(0); \ - CALLFunc((uptr)dma##name); \ - x86SetJ8( j8Ptr[6] ); \ - } \ -} \ -#define recDmaExec(name, num) { \ - iFlushCall(0); \ - if( IS_EECONSTREG(mmreg) ) { \ - recDmaExecI(name, num); \ - } \ - else { \ - _eeMoveMMREGtoR(EAX, mmreg); \ - TEST32ItoR(EAX, 0xffff0000); \ - j8Ptr[6] = JNZ8(0); \ - MOV32RtoR(ECX, EAX); \ - AND32ItoR(ECX, 0xc); \ - CMP32ItoR(ECX, 4); \ - j8Ptr[7] = JNE8(0); \ - if( IS_XMMREG(mmreg) || IS_MMXREG(mmreg) ) { \ - MOV16RtoM((uptr)&PS2MEM_HW[(mem) & 0xffff], EAX); \ - } \ - else { \ - _eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \ - } \ - j8Ptr[8] = JMP8(0); \ - x86SetJ8(j8Ptr[6]); \ - x86SetJ8(j8Ptr[7]); \ - _eeWriteConstMem32((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \ - x86SetJ8(j8Ptr[8]); \ - \ - TEST16ItoR(EAX, 0x100); \ - j8Ptr[5] = JZ8(0); \ - TEST32ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \ - j8Ptr[6] = JZ8(0); \ - \ - CALLFunc((uptr)dma##name); \ - \ - x86SetJ8( j8Ptr[5] ); \ - x86SetJ8( j8Ptr[6] ); \ - } \ -} \ +static void recDmaExecI( void (*name)(), u32 mem, int mmreg ) +{ + u32 c = g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]; + /* Keep the old tag if in chain mode and hw doesnt set it*/ + if( (c & 0xc) == 0x4 && (c&0xffff0000) == 0 ) { + MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c); + } + else MOV32ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c); + if( c & 0x100 ) { + TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); + j8Ptr[6] = JZ8(0); + CALLFunc((uptr)name); + x86SetJ8( j8Ptr[6] ); + } +} + +static void recDmaExec( void (*name)(), u32 mem, int mmreg ) +{ + iFlushCall(0); + if( IS_EECONSTREG(mmreg) ) { + recDmaExecI(name, mem, mmreg); + } + else { + _eeMoveMMREGtoR(EAX, mmreg); + TEST32ItoR(EAX, 0xffff0000); + j8Ptr[6] = JNZ8(0); + MOV32RtoR(ECX, EAX); + AND32ItoR(ECX, 0xc); + CMP32ItoR(ECX, 4); + j8Ptr[7] = JNE8(0); + if( IS_XMMREG(mmreg) || IS_MMXREG(mmreg) ) { + MOV16RtoM((uptr)&PS2MEM_HW[(mem) & 0xffff], EAX); + } + else { + _eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); + } + j8Ptr[8] = JMP8(0); + x86SetJ8(j8Ptr[6]); + x86SetJ8(j8Ptr[7]); + _eeWriteConstMem32((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); + x86SetJ8(j8Ptr[8]); + + TEST16ItoR(EAX, 0x100); + j8Ptr[5] = JZ8(0); + TEST32ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); + j8Ptr[6] = JZ8(0); + + CALLFunc((uptr)name); + x86SetJ8( j8Ptr[5] ); + x86SetJ8( j8Ptr[6] ); + } +} #define CONSTWRITE_CALLTIMER32(name, index, bit) { \ _recPushReg(mmreg); \ @@ -925,42 +931,42 @@ void hwConstWrite32(u32 mem, int mmreg) return; case 0x10008000: // dma0 - vif0 - recDmaExec(VIF0, 0); + recDmaExec(dmaVIF0, mem, mmreg); break; case 0x10009000: // dma1 - vif1 - chcr - recDmaExec(VIF1, 1); + recDmaExec(dmaVIF1, mem, mmreg); break; case 0x1000a000: // dma2 - gif - recDmaExec(GIF, 2); + recDmaExec(dmaGIF, mem, mmreg); break; case 0x1000b000: // dma3 - fromIPU - recDmaExec(IPU0, 3); + recDmaExec(dmaIPU0, mem, mmreg); break; case 0x1000b400: // dma4 - toIPU - recDmaExec(IPU1, 4); + recDmaExec(dmaIPU1, mem, mmreg); break; case 0x1000c000: // dma5 - sif0 //if (value == 0) psxSu32(0x30) = 0x40000; - recDmaExec(SIF0, 5); + recDmaExec(dmaSIF0, mem, mmreg); break; case 0x1000c400: // dma6 - sif1 - recDmaExec(SIF1, 6); + recDmaExec(dmaSIF1, mem, mmreg); break; case 0x1000c800: // dma7 - sif2 - recDmaExec(SIF2, 7); + recDmaExec(dmaSIF2, mem, mmreg); break; case 0x1000d000: // dma8 - fromSPR - recDmaExec(SPR0, 8); + recDmaExec(dmaSPR0, mem, mmreg); break; case 0x1000d400: // dma9 - toSPR - recDmaExec(SPR1, 9); + recDmaExec(dmaSPR1, mem, mmreg); break; case 0x1000e010: // DMAC_STAT @@ -972,12 +978,7 @@ void hwConstWrite32(u32 mem, int mmreg) SHR32ItoR(EAX, 16); XOR16RtoM((uptr)&PS2MEM_HW[0xe012], EAX); - - // cpuRegs.CP0.n.Status.val is checked by cpuTestDMACInts. - //MOV32MtoR(EAX, (uptr)&cpuRegs.CP0.n.Status.val); - //AND32ItoR(EAX, 0x10807); - //CMP32ItoR(EAX, 0x10801); - //j8Ptr[5] = JNE8(0); + CALLFunc((uptr)cpuTestDMACInts); //x86SetJ8( j8Ptr[5] ); @@ -985,29 +986,14 @@ void hwConstWrite32(u32 mem, int mmreg) case 0x1000f000: // INTC_STAT _eeWriteConstMem32OP((uptr)&PS2MEM_HW[0xf000], mmreg, 2); - // note: cpuRegs.CP0.n.Status.val conditional is done by cpuTestINTCInts. - //MOV32MtoR(EAX, (uptr)&cpuRegs.CP0.n.Status.val); - //AND32ItoR(EAX, 0x10407); - //CMP32ItoR(EAX, 0x10401); - //j8Ptr[5] = JNE8(0); CALLFunc((uptr)cpuTestINTCInts); - - //x86SetJ8( j8Ptr[5] ); break; case 0x1000f010: // INTC_MASK _eeMoveMMREGtoR(EAX, mmreg); iFlushCall(0); XOR16RtoM((uptr)&PS2MEM_HW[0xf010], EAX); - - // note: cpuRegs.CP0.n.Status.val conditional is done by cpuTestINTCInts. - //MOV32MtoR(EAX, (uptr)&cpuRegs.CP0.n.Status.val); - //AND32ItoR(EAX, 0x10407); - //CMP32ItoR(EAX, 0x10401); - //j8Ptr[5] = JNE8(0); CALLFunc((uptr)cpuTestINTCInts); - - //x86SetJ8( j8Ptr[5] ); break; case 0x1000f130: @@ -1174,7 +1160,7 @@ void hwConstWrite64(u32 mem, int mmreg) return; case 0x1000a000: // dma2 - gif - recDmaExec(GIF, 2); + recDmaExec(dmaGIF, mem, mmreg); break; case 0x1000e010: // DMAC_STAT