From 29fe1673baaceb6bf839054e8e92e65333fe890f Mon Sep 17 00:00:00 2001 From: refraction Date: Wed, 11 Feb 2009 22:57:37 +0000 Subject: [PATCH] Fixed Fatal Frame once and for all due to a DMA issue which it shouldnt have been doing ;p Also fixed the COP0 condition for the Recompiler and Interpreter, this was stopping Mojib Ribbon and Shadow of Colossus (after the Fatal Frame fix) from running. Int some how worked but it was wrong lol :P Also fixed some Copy n Pasta typos git-svn-id: http://pcsx2.googlecode.com/svn/trunk@477 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/COP0.cpp | 2 +- pcsx2/HwRead.cpp | 4 ++-- pcsx2/HwWrite.cpp | 17 ++++++++++++++++- pcsx2/VifDma.cpp | 28 ++-------------------------- pcsx2/x86/iCOP0.cpp | 14 ++++++++------ 5 files changed, 29 insertions(+), 36 deletions(-) diff --git a/pcsx2/COP0.cpp b/pcsx2/COP0.cpp index 7258ae0a63..2be2e3802e 100644 --- a/pcsx2/COP0.cpp +++ b/pcsx2/COP0.cpp @@ -221,7 +221,7 @@ void MTC0() { } int CPCOND0() { - return (((psHu16(DMAC_STAT) & psHu16(DMAC_PCR)) & 0x3ff) == (psHu16(DMAC_PCR) & 0x3ff)); + return (((psHu16(DMAC_STAT) | ~psHu16(DMAC_PCR)) & 0x3ff) == 0x3ff); } //#define CPCOND0 1 diff --git a/pcsx2/HwRead.cpp b/pcsx2/HwRead.cpp index 8430a59b9f..97ff4386e7 100644 --- a/pcsx2/HwRead.cpp +++ b/pcsx2/HwRead.cpp @@ -197,7 +197,7 @@ mem32_t __fastcall hwRead32_page_0F(u32 mem) { case 0xf000: // This one is checked alot, so leave it commented out unless you love 600 meg logfiles. - //HW_LOG("DMAC_STAT Read 32bit %x\n", psHu32(0xe010)); + //HW_LOG("INTC_STAT Read 32bit %x\n", psHu32(0xf010)); break; case 0xf010: @@ -295,7 +295,7 @@ mem32_t __fastcall hwRead32_generic(u32 mem) case 0x0c: case 0x0d: case 0x0e: - if( mem == DMAC_STAT ) + if( mem == DMAC_STAT) HW_LOG("DMAC_STAT Read32, value=0x%x\n", psHu32(DMAC_STAT)); break; diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index 4573db269c..cb411830ce 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -40,6 +40,11 @@ using namespace R5900; // dark cloud2 uses 8 bit DMAs register writes static __forceinline void DmaExec8( void (*func)(), u32 mem, u8 value ) { + //Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC + if((value & 0x1) && (psHu8(mem) & 0x1) == 0x1 && (psHu32(DMAC_CTRL) & 0x1) == 1) { + DMA_LOG( "DMAExec8 Attempt to run DMA while one is already active mem = %x", mem ); + return; + } psHu8(mem) = (u8)value; if ((psHu8(mem) & 0x1) && (psHu32(DMAC_CTRL) & 0x1)) { @@ -50,6 +55,11 @@ static __forceinline void DmaExec8( void (*func)(), u32 mem, u8 value ) static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value ) { + //Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC + if((value & 0x100) && (psHu32(mem) & 0x100) == 0x100 && (psHu32(DMAC_CTRL) & 0x1) == 1) { + DMA_LOG( "DMAExec16 Attempt to run DMA while one is already active mem = %x", mem); + return; + } psHu16(mem) = (u16)value; if ((psHu16(mem) & 0x100) && (psHu32(DMAC_CTRL) & 0x1)) { @@ -60,6 +70,11 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value ) static void DmaExec( void (*func)(), u32 mem, u32 value ) { + //Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC + if((value & 0x100) && (psHu32(mem) & 0x100) == 0x100 && (psHu32(DMAC_CTRL) & 0x1) == 1) { + DMA_LOG( "DMAExec32 Attempt to run DMA while one is already active mem = %x", mem ); + return; + } /* Keep the old tag if in chain mode and hw doesnt set it*/ if( (value & 0xc) == 0x4 && (value & 0xffff0000) == 0) psHu32(mem) = (psHu32(mem) & 0xFFFF0000) | (u16)value; @@ -704,7 +719,7 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value ) return; //------------------------------------------------------------------ case 0x1000d400: // dma9 - toSPR - DMA_LOG("SPR0dma EXECUTE (toSPR), value=0x%x\n", value); + DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x\n", value); DmaExec(dmaSPR1, mem, value); return; } diff --git a/pcsx2/VifDma.cpp b/pcsx2/VifDma.cpp index 1e25761697..096efefc37 100644 --- a/pcsx2/VifDma.cpp +++ b/pcsx2/VifDma.cpp @@ -1043,14 +1043,7 @@ int _VIF0chain() { u32 *pMem; u32 ret; - //Hmm, it seems some games (Fatal Frame and Twisted Metal) Try to force the VIF to stop whatever its doing and do something else - //Okay... so in that case we will tell the vif to do so (Refraction) - if (vif0ch->qwc == 0 && vif0.vifstalled == 0) { - vif0Regs->stat &= ~VIF0_STAT_VPS; - vif0.cmd = 0; - vif0.tag.size = 0; - return 0; - } + if (vif0ch->qwc == 0 && vif0.vifstalled == 0) return 0; pMem = (u32*)dmaGetAddr(vif0ch->madr); if (pMem == NULL) @@ -1213,11 +1206,6 @@ void dmaVIF0() { vif0ch->chcr, vif0ch->madr, vif0ch->qwc, vif0ch->tadr, vif0ch->asr0, vif0ch->asr1 ); - if(vif0.done == 0) { - SysPrintf("VIF0 Double DMA issue, ignoring\n"); - return; - } - g_vifCycles = 0; @@ -1876,14 +1864,7 @@ int _VIF1chain() { //u32 qwc = vif1ch->qwc; u32 ret; - //Hmm, it seems some games (Fatal Frame and Twisted Metal) Try to force the VIF to stop whatever its doing and do something else - //Okay... so in that case we will tell the vif to do so (Refraction) - if (vif1ch->qwc == 0 && vif1.vifstalled == 0) { - vif1Regs->stat &= ~VIF1_STAT_VPS; - vif1.cmd = 0; - vif1.tag.size = 0; - return 0; - } + if (vif1ch->qwc == 0 && vif1.vifstalled == 0) return 0; pMem = (u32*)dmaGetAddr(vif1ch->madr); if (pMem == NULL) @@ -2032,11 +2013,6 @@ void dmaVIF1() vif1ch->chcr, vif1ch->madr, vif1ch->qwc, vif1ch->tadr, vif1ch->asr0, vif1ch->asr1 ); - if(vif1.done == 0 && (psHu32(DMAC_CTRL) & 0xC) != 0x8) { - SysPrintf("VIF1 Double DMA issue, ignoring\n"); - return; - } - vif1.done = 0; g_vifCycles = 0; diff --git a/pcsx2/x86/iCOP0.cpp b/pcsx2/x86/iCOP0.cpp index d634dbc059..29cb4be9bd 100644 --- a/pcsx2/x86/iCOP0.cpp +++ b/pcsx2/x86/iCOP0.cpp @@ -56,33 +56,35 @@ static void _setupBranchTest() // But using 32-bit loads here is ok (and faster), because we mask off // everything except the lower 10 bits away. - MOV32MtoR( EAX, (uptr)&psHu32(DMAC_STAT) ); - XOR32MtoR( EAX, (uptr)&psHu32(DMAC_PCR) ); + MOV32MtoR( EAX, (uptr)&psHu32(DMAC_PCR) ); + NOT32R( EAX ); + OR32MtoR( EAX, (uptr)&psHu32(DMAC_STAT) ); AND32ItoR( EAX, 0x3ff ); + CMP32ItoR( EAX, 0x3ff); } void recBC0F() { _setupBranchTest(); - recDoBranchImm(JNZ32(0)); + recDoBranchImm(JE32(0)); } void recBC0T() { _setupBranchTest(); - recDoBranchImm(JZ32(0)); + recDoBranchImm(JL32(0)); } void recBC0FL() { _setupBranchTest(); - recDoBranchImm_Likely(JNZ32(0)); + recDoBranchImm_Likely(JE32(0)); } void recBC0TL() { _setupBranchTest(); - recDoBranchImm_Likely(JZ32(0)); + recDoBranchImm_Likely(JL32(0)); } void recTLBR() { recCall( Interp::TLBR, -1 ); }