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
This commit is contained in:
Jake.Stine 2008-12-05 05:02:52 +00:00 committed by Gregory Hainaut
parent e8366b171a
commit b8e4a35de6
6 changed files with 216 additions and 186 deletions

View File

@ -134,8 +134,7 @@ void MTC0() {
} }
int CPCOND0() { int CPCOND0() {
if(((psHu16(DMAC_STAT) & psHu16(DMAC_PCR)) & 0x3ff) == (psHu16(DMAC_PCR) & 0x3ff)) return 1; return (((psHu16(DMAC_STAT) & psHu16(DMAC_PCR)) & 0x3ff) == (psHu16(DMAC_PCR) & 0x3ff));
else return 0;
} }
//#define CPCOND0 1 //#define CPCOND0 1
@ -147,10 +146,12 @@ int CPCOND0() {
void BC0F() { void BC0F() {
BC0(== 0); BC0(== 0);
COP0_LOG( "COP0 > BC0F\n" );
} }
void BC0T() { void BC0T() {
BC0(== 1); BC0(== 1);
COP0_LOG( "COP0 > BC0T\n" );
} }
#define BC0L(cond) \ #define BC0L(cond) \
@ -160,10 +161,12 @@ void BC0T() {
void BC0FL() { void BC0FL() {
BC0L(== 0); BC0L(== 0);
COP0_LOG( "COP0 > BC0FL\n" );
} }
void BC0TL() { void BC0TL() {
BC0L(== 1); BC0L(== 1);
COP0_LOG( "COP0 > BCOTL\n" );
} }
void TLBR() { void TLBR() {
@ -176,7 +179,7 @@ void TLBR() {
// if( !bExecBIOS ) // if( !bExecBIOS )
// __Log("TLBR %d\n", cpuRegs.CP0.n.Index&0x1f); // __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.PageMask = tlb[i].PageMask;
cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi&~(tlb[i].PageMask|0x1f00); cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi&~(tlb[i].PageMask|0x1f00);
cpuRegs.CP0.n.EntryLo0 = (tlb[i].EntryLo0&~1)|((tlb[i].EntryHi>>12)&1); 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 mask, addr;
u32 saddr, eaddr; u32 saddr, eaddr;
COP0_LOG( "COP0 > WriteTLB" );
tlb[i].PageMask = cpuRegs.CP0.n.PageMask; tlb[i].PageMask = cpuRegs.CP0.n.PageMask;
tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi; tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi;
tlb[i].EntryLo0 = cpuRegs.CP0.n.EntryLo0; 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 || 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.ERL || (cpuRegs.CP0.n.Status.b.KSU == 0)) {
cpuRegs.CP0.n.Status.b.EIE = 0; cpuRegs.CP0.n.Status.b.EIE = 0;
UpdateCP0Status(); //UpdateCP0Status(); // ints are disabled so checking for them is kinda silly...
} }
} }

View File

@ -1160,7 +1160,7 @@ __forceinline void intcInterrupt() {
} }
// fixme: dead/unused code? // fixme: dead/unused code?
void dmacTestInterrupt() { /*void dmacTestInterrupt() {
cpuRegs.interrupt &= ~(1 << 31); cpuRegs.interrupt &= ~(1 << 31);
if ((cpuRegs.CP0.n.Status.val & 0x800) != 0x800) return; if ((cpuRegs.CP0.n.Status.val & 0x800) != 0x800) return;
@ -1168,7 +1168,7 @@ void dmacTestInterrupt() {
psHu16(0xe010) & 0x8000) == 0) return; psHu16(0xe010) & 0x8000) == 0) return;
if((psHu32(DMAC_CTRL) & 0x1) == 0) return; if((psHu32(DMAC_CTRL) & 0x1) == 0) return;
} }*/
__forceinline void dmacInterrupt() __forceinline void dmacInterrupt()
{ {

View File

@ -414,6 +414,11 @@ static __forceinline void _cpuTestTIMR()
cpuRegs.CP0.n.Count += cpuRegs.cycle-s_iLastCOP0Cycle; cpuRegs.CP0.n.Count += cpuRegs.cycle-s_iLastCOP0Cycle;
s_iLastCOP0Cycle = cpuRegs.cycle; 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) && if ( (cpuRegs.CP0.n.Status.val & 0x8000) &&
cpuRegs.CP0.n.Count >= cpuRegs.CP0.n.Compare && cpuRegs.CP0.n.Count < cpuRegs.CP0.n.Compare+1000 ) { 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); 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 // Maximum wait between branches. Lower values provide a tighter synchronization between
// the EE and the IOP, but incur more execution overhead. // 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 // if cpuRegs.cycle is greater than this cycle, should check cpuBranchTest for updates
u32 g_nextBranchCycle = 0; u32 g_nextBranchCycle = 0;
@ -463,9 +468,9 @@ static __forceinline void _cpuBranchTest_Shared()
if( cpuTestCycle( nextsCounter, nextCounter ) ) if( cpuTestCycle( nextsCounter, nextCounter ) )
{ {
rcntUpdate(); rcntUpdate();
_cpuTestPERF();
} }
_cpuTestPERF();
_cpuTestTIMR(); _cpuTestTIMR();
//#ifdef CPU_LOG //#ifdef CPU_LOG
@ -496,7 +501,7 @@ static __forceinline void _cpuBranchTest_Shared()
if( iopBranchAction ) if( iopBranchAction )
{ {
//if( EEsCycle < -500 ) //if( EEsCycle < -500 )
// SysPrintf( " IOP ahead by: %d\n", -EEsCycle ); // SysPrintf( " IOP ahead by: %d cycles\n", -EEsCycle );
psxCpu->ExecuteBlock(); psxCpu->ExecuteBlock();
} }

View File

@ -516,13 +516,13 @@ __forceinline void sif1Interrupt() {
__forceinline void EEsif0Interrupt() { __forceinline void EEsif0Interrupt() {
sif0dma->chcr &= ~0x100; sif0dma->chcr &= ~0x100;
hwDmacIrq(5); hwDmacIrq(DMAC_SIF0);
cpuRegs.interrupt &= ~(1 << 5); cpuRegs.interrupt &= ~(1 << 5);
} }
__forceinline void EEsif1Interrupt() { __forceinline void EEsif1Interrupt() {
hwDmacIrq(6); hwDmacIrq(DMAC_SIF1);
sif1dma->chcr &= ~0x100; sif1dma->chcr &= ~0x100;
cpuRegs.interrupt &= ~(1 << 6); cpuRegs.interrupt &= ~(1 << 6);
@ -578,7 +578,6 @@ _inline void dmaSIF1() {
} }
// fixme: Unused code
_inline void dmaSIF2() { _inline void dmaSIF2() {
SIF_LOG("dmaSIF2 chcr = %lx, madr = %lx, qwc = %lx\n", SIF_LOG("dmaSIF2 chcr = %lx, madr = %lx, qwc = %lx\n",
sif2dma->chcr, sif2dma->madr, sif2dma->qwc); sif2dma->chcr, sif2dma->madr, sif2dma->qwc);

View File

@ -16,6 +16,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 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)) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD))
#include "Common.h" #include "Common.h"
@ -47,8 +53,6 @@ REC_SYS(EI);
#else #else
////////////////////////////////////////////////////
//REC_SYS(MTC0);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(BC0F); REC_SYS(BC0F);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -65,12 +69,6 @@ REC_SYS(TLBWI);
REC_SYS(TLBWR); REC_SYS(TLBWR);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TLBP); REC_SYS(TLBP);
////////////////////////////////////////////////////
REC_SYS(ERET);
////////////////////////////////////////////////////
REC_SYS(DI);
////////////////////////////////////////////////////
REC_SYS(EI);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
extern u32 s_iLastCOP0Cycle; 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) { /*void rec(COP0) {
} }
@ -354,11 +393,7 @@ void rec(TLBWR) {
} }
void rec(TLBP) { void rec(TLBP) {
} }*/
void rec(ERET) {
}
*/
#endif #endif

View File

@ -455,36 +455,38 @@ void hwConstRead128(u32 mem, int xmmreg) {
} }
// when writing imm // when writing imm
#define recDmaExecI8(name, num) { \ 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 ) { \ MOV8ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]);
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \ if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 1 ) {
j8Ptr[6] = JZ8(0); \ TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
CALLFunc((uptr)dma##name); \ j8Ptr[6] = JZ8(0);
x86SetJ8( j8Ptr[6] ); \ CALLFunc((uptr)name);
} \ x86SetJ8( j8Ptr[6] );
} \ }
}
#define recDmaExec8(name, num) { \ static void recDmaExec8(void (*name)(), u32 mem, int mmreg)
iFlushCall(0); \ {
if( IS_EECONSTREG(mmreg) ) { \ iFlushCall(0);
recDmaExecI8(name, num); \ if( IS_EECONSTREG(mmreg) ) {
} \ recDmaExecI8(name, mem, mmreg);
else { \ }
_eeMoveMMREGtoR(EAX, mmreg); \ else {
_eeWriteConstMem8((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \ _eeMoveMMREGtoR(EAX, mmreg);
\ _eeWriteConstMem8((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg);
TEST8ItoR(EAX, 1); \
j8Ptr[5] = JZ8(0); \ TEST8ItoR(EAX, 1);
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \ j8Ptr[5] = JZ8(0);
j8Ptr[6] = JZ8(0); \ TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
\ j8Ptr[6] = JZ8(0);
CALLFunc((uptr)dma##name); \
\ CALLFunc((uptr)name);
x86SetJ8( j8Ptr[5] ); \
x86SetJ8( j8Ptr[6] ); \ x86SetJ8( j8Ptr[5] );
} \ x86SetJ8( j8Ptr[6] );
} \ }
}
static void PrintDebug(u8 value) static void PrintDebug(u8 value)
{ {
@ -536,51 +538,51 @@ void hwConstWrite8(u32 mem, int mmreg)
CONSTWRITE_TIMERS(8) CONSTWRITE_TIMERS(8)
case 0x1000f180: case 0x1000f180:
_recPushReg(mmreg); \ _recPushReg(mmreg);
iFlushCall(0); iFlushCall(0);
CALLFunc((uptr)PrintDebug); CALLFunc((uptr)PrintDebug);
ADD32ItoR(ESP, 4); ADD32ItoR(ESP, 4);
break; break;
case 0x10008001: // dma0 - vif0 case 0x10008001: // dma0 - vif0
recDmaExec8(VIF0, 0); recDmaExec8(dmaVIF0, mem, mmreg);
break; break;
case 0x10009001: // dma1 - vif1 case 0x10009001: // dma1 - vif1
recDmaExec8(VIF1, 1); recDmaExec8(dmaVIF1, mem, mmreg);
break; break;
case 0x1000a001: // dma2 - gif case 0x1000a001: // dma2 - gif
recDmaExec8(GIF, 2); recDmaExec8(dmaGIF, mem, mmreg);
break; break;
case 0x1000b001: // dma3 - fromIPU case 0x1000b001: // dma3 - fromIPU
recDmaExec8(IPU0, 3); recDmaExec8(dmaIPU0, mem, mmreg);
break; break;
case 0x1000b401: // dma4 - toIPU case 0x1000b401: // dma4 - toIPU
recDmaExec8(IPU1, 4); recDmaExec8(dmaIPU1, mem, mmreg);
break; break;
case 0x1000c001: // dma5 - sif0 case 0x1000c001: // dma5 - sif0
//if (value == 0) psxSu32(0x30) = 0x40000; //if (value == 0) psxSu32(0x30) = 0x40000;
recDmaExec8(SIF0, 5); recDmaExec8(dmaSIF0, mem, mmreg);
break; break;
case 0x1000c401: // dma6 - sif1 case 0x1000c401: // dma6 - sif1
recDmaExec8(SIF1, 6); recDmaExec8(dmaSIF1, mem, mmreg);
break; break;
case 0x1000c801: // dma7 - sif2 case 0x1000c801: // dma7 - sif2
recDmaExec8(SIF2, 7); recDmaExec8(dmaSIF2, mem, mmreg);
break; break;
case 0x1000d001: // dma8 - fromSPR case 0x1000d001: // dma8 - fromSPR
recDmaExec8(SPR0, 8); recDmaExec8(dmaSPR0, mem, mmreg);
break; break;
case 0x1000d401: // dma9 - toSPR case 0x1000d401: // dma9 - toSPR
recDmaExec8(SPR1, 9); recDmaExec8(dmaSPR1, mem, mmreg);
break; break;
case 0x1000f592: // DMAC_ENABLEW case 0x1000f592: // DMAC_ENABLEW
@ -636,79 +638,81 @@ void hwConstWrite8(u32 mem, int mmreg)
} }
} }
#define recDmaExecI16(name, num) { \ 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 ) { \ MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]);
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \ if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 0x100 ) {
j8Ptr[6] = JZ8(0); \ TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
CALLFunc((uptr)dma##name); \ j8Ptr[6] = JZ8(0);
x86SetJ8( j8Ptr[6] ); \ CALLFunc((uptr)name);
} \ x86SetJ8( j8Ptr[6] );
} \ }
}
#define recDmaExec16(name, num) { \ static void recDmaExec16(void (*name)(), u32 mem, int mmreg)
iFlushCall(0); \ {
if( IS_EECONSTREG(mmreg) ) { \ iFlushCall(0);
recDmaExecI16(name, num); \ if( IS_EECONSTREG(mmreg) ) {
} \ recDmaExecI16(name, mem, mmreg);
else { \ }
_eeMoveMMREGtoR(EAX, mmreg); \ else {
_eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \ _eeMoveMMREGtoR(EAX, mmreg);
\ _eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg);
TEST16ItoR(EAX, 0x100); \
j8Ptr[5] = JZ8(0); \ TEST16ItoR(EAX, 0x100);
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \ j8Ptr[5] = JZ8(0);
j8Ptr[6] = JZ8(0); \ TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
\ j8Ptr[6] = JZ8(0);
CALLFunc((uptr)dma##name); \
\ CALLFunc((uptr)name);
x86SetJ8( j8Ptr[5] ); \
x86SetJ8( j8Ptr[6] ); \ x86SetJ8( j8Ptr[5] );
} \ x86SetJ8( j8Ptr[6] );
} \ }
}
void hwConstWrite16(u32 mem, int mmreg) void hwConstWrite16(u32 mem, int mmreg)
{ {
switch(mem) { switch(mem) {
CONSTWRITE_TIMERS(16) CONSTWRITE_TIMERS(16)
case 0x10008000: // dma0 - vif0 case 0x10008000: // dma0 - vif0
recDmaExec16(VIF0, 0); recDmaExec16(dmaVIF0, mem, mmreg);
break; break;
case 0x10009000: // dma1 - vif1 - chcr case 0x10009000: // dma1 - vif1 - chcr
recDmaExec16(VIF1, 1); recDmaExec16(dmaVIF1, mem, mmreg);
break; break;
case 0x1000a000: // dma2 - gif case 0x1000a000: // dma2 - gif
recDmaExec16(GIF, 2); recDmaExec16(dmaGIF, mem, mmreg);
break; break;
case 0x1000b000: // dma3 - fromIPU case 0x1000b000: // dma3 - fromIPU
recDmaExec16(IPU0, 3); recDmaExec16(dmaIPU0, mem, mmreg);
break; break;
case 0x1000b400: // dma4 - toIPU case 0x1000b400: // dma4 - toIPU
recDmaExec16(IPU1, 4); recDmaExec16(dmaIPU1, mem, mmreg);
break; break;
case 0x1000c000: // dma5 - sif0 case 0x1000c000: // dma5 - sif0
//if (value == 0) psxSu32(0x30) = 0x40000; //if (value == 0) psxSu32(0x30) = 0x40000;
recDmaExec16(SIF0, 5); recDmaExec16(dmaSIF0, mem, mmreg);
break; break;
case 0x1000c002: case 0x1000c002:
//? //?
break; break;
case 0x1000c400: // dma6 - sif1 case 0x1000c400: // dma6 - sif1
recDmaExec16(SIF1, 6); recDmaExec16(dmaSIF1, mem, mmreg);
break; break;
case 0x1000c800: // dma7 - sif2 case 0x1000c800: // dma7 - sif2
recDmaExec16(SIF2, 7); recDmaExec16(dmaSIF2, mem, mmreg);
break; break;
case 0x1000c802: case 0x1000c802:
//? //?
break; break;
case 0x1000d000: // dma8 - fromSPR case 0x1000d000: // dma8 - fromSPR
recDmaExec16(SPR0, 8); recDmaExec16(dmaSPR0, mem, mmreg);
break; break;
case 0x1000d400: // dma9 - toSPR case 0x1000d400: // dma9 - toSPR
recDmaExec16(SPR1, 9); recDmaExec16(dmaSPR1, mem, mmreg);
break; break;
case 0x1000f592: // DMAC_ENABLEW case 0x1000f592: // DMAC_ENABLEW
_eeWriteConstMem16((uptr)&PS2MEM_HW[0xf522], mmreg); _eeWriteConstMem16((uptr)&PS2MEM_HW[0xf522], mmreg);
@ -781,57 +785,59 @@ void hwConstWrite16(u32 mem, int mmreg)
} }
// when writing an Imm // 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) { \ static void recDmaExecI( void (*name)(), u32 mem, int mmreg )
iFlushCall(0); \ {
if( IS_EECONSTREG(mmreg) ) { \ u32 c = g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0];
recDmaExecI(name, num); \ /* Keep the old tag if in chain mode and hw doesnt set it*/
} \ if( (c & 0xc) == 0x4 && (c&0xffff0000) == 0 ) {
else { \ MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c);
_eeMoveMMREGtoR(EAX, mmreg); \ }
TEST32ItoR(EAX, 0xffff0000); \ else MOV32ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c);
j8Ptr[6] = JNZ8(0); \ if( c & 0x100 ) {
MOV32RtoR(ECX, EAX); \ TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
AND32ItoR(ECX, 0xc); \ j8Ptr[6] = JZ8(0);
CMP32ItoR(ECX, 4); \ CALLFunc((uptr)name);
j8Ptr[7] = JNE8(0); \ x86SetJ8( j8Ptr[6] );
if( IS_XMMREG(mmreg) || IS_MMXREG(mmreg) ) { \ }
MOV16RtoM((uptr)&PS2MEM_HW[(mem) & 0xffff], EAX); \ }
} \
else { \ static void recDmaExec( void (*name)(), u32 mem, int mmreg )
_eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \ {
} \ iFlushCall(0);
j8Ptr[8] = JMP8(0); \ if( IS_EECONSTREG(mmreg) ) {
x86SetJ8(j8Ptr[6]); \ recDmaExecI(name, mem, mmreg);
x86SetJ8(j8Ptr[7]); \ }
_eeWriteConstMem32((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \ else {
x86SetJ8(j8Ptr[8]); \ _eeMoveMMREGtoR(EAX, mmreg);
\ TEST32ItoR(EAX, 0xffff0000);
TEST16ItoR(EAX, 0x100); \ j8Ptr[6] = JNZ8(0);
j8Ptr[5] = JZ8(0); \ MOV32RtoR(ECX, EAX);
TEST32ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \ AND32ItoR(ECX, 0xc);
j8Ptr[6] = JZ8(0); \ CMP32ItoR(ECX, 4);
\ j8Ptr[7] = JNE8(0);
CALLFunc((uptr)dma##name); \ if( IS_XMMREG(mmreg) || IS_MMXREG(mmreg) ) {
\ MOV16RtoM((uptr)&PS2MEM_HW[(mem) & 0xffff], EAX);
x86SetJ8( j8Ptr[5] ); \ }
x86SetJ8( j8Ptr[6] ); \ 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) { \ #define CONSTWRITE_CALLTIMER32(name, index, bit) { \
_recPushReg(mmreg); \ _recPushReg(mmreg); \
@ -925,42 +931,42 @@ void hwConstWrite32(u32 mem, int mmreg)
return; return;
case 0x10008000: // dma0 - vif0 case 0x10008000: // dma0 - vif0
recDmaExec(VIF0, 0); recDmaExec(dmaVIF0, mem, mmreg);
break; break;
case 0x10009000: // dma1 - vif1 - chcr case 0x10009000: // dma1 - vif1 - chcr
recDmaExec(VIF1, 1); recDmaExec(dmaVIF1, mem, mmreg);
break; break;
case 0x1000a000: // dma2 - gif case 0x1000a000: // dma2 - gif
recDmaExec(GIF, 2); recDmaExec(dmaGIF, mem, mmreg);
break; break;
case 0x1000b000: // dma3 - fromIPU case 0x1000b000: // dma3 - fromIPU
recDmaExec(IPU0, 3); recDmaExec(dmaIPU0, mem, mmreg);
break; break;
case 0x1000b400: // dma4 - toIPU case 0x1000b400: // dma4 - toIPU
recDmaExec(IPU1, 4); recDmaExec(dmaIPU1, mem, mmreg);
break; break;
case 0x1000c000: // dma5 - sif0 case 0x1000c000: // dma5 - sif0
//if (value == 0) psxSu32(0x30) = 0x40000; //if (value == 0) psxSu32(0x30) = 0x40000;
recDmaExec(SIF0, 5); recDmaExec(dmaSIF0, mem, mmreg);
break; break;
case 0x1000c400: // dma6 - sif1 case 0x1000c400: // dma6 - sif1
recDmaExec(SIF1, 6); recDmaExec(dmaSIF1, mem, mmreg);
break; break;
case 0x1000c800: // dma7 - sif2 case 0x1000c800: // dma7 - sif2
recDmaExec(SIF2, 7); recDmaExec(dmaSIF2, mem, mmreg);
break; break;
case 0x1000d000: // dma8 - fromSPR case 0x1000d000: // dma8 - fromSPR
recDmaExec(SPR0, 8); recDmaExec(dmaSPR0, mem, mmreg);
break; break;
case 0x1000d400: // dma9 - toSPR case 0x1000d400: // dma9 - toSPR
recDmaExec(SPR1, 9); recDmaExec(dmaSPR1, mem, mmreg);
break; break;
case 0x1000e010: // DMAC_STAT case 0x1000e010: // DMAC_STAT
@ -973,11 +979,6 @@ void hwConstWrite32(u32 mem, int mmreg)
SHR32ItoR(EAX, 16); SHR32ItoR(EAX, 16);
XOR16RtoM((uptr)&PS2MEM_HW[0xe012], EAX); 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); CALLFunc((uptr)cpuTestDMACInts);
//x86SetJ8( j8Ptr[5] ); //x86SetJ8( j8Ptr[5] );
@ -985,29 +986,14 @@ void hwConstWrite32(u32 mem, int mmreg)
case 0x1000f000: // INTC_STAT case 0x1000f000: // INTC_STAT
_eeWriteConstMem32OP((uptr)&PS2MEM_HW[0xf000], mmreg, 2); _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); CALLFunc((uptr)cpuTestINTCInts);
//x86SetJ8( j8Ptr[5] );
break; break;
case 0x1000f010: // INTC_MASK case 0x1000f010: // INTC_MASK
_eeMoveMMREGtoR(EAX, mmreg); _eeMoveMMREGtoR(EAX, mmreg);
iFlushCall(0); iFlushCall(0);
XOR16RtoM((uptr)&PS2MEM_HW[0xf010], EAX); 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); CALLFunc((uptr)cpuTestINTCInts);
//x86SetJ8( j8Ptr[5] );
break; break;
case 0x1000f130: case 0x1000f130:
@ -1174,7 +1160,7 @@ void hwConstWrite64(u32 mem, int mmreg)
return; return;
case 0x1000a000: // dma2 - gif case 0x1000a000: // dma2 - gif
recDmaExec(GIF, 2); recDmaExec(dmaGIF, mem, mmreg);
break; break;
case 0x1000e010: // DMAC_STAT case 0x1000e010: // DMAC_STAT