From 533bb0846bb7d439c2d6a3f6dd212bbf81cf83dc Mon Sep 17 00:00:00 2001 From: refraction Date: Sat, 27 Nov 2010 00:11:52 +0000 Subject: [PATCH] IPU: Gave IPU0/Internal IPU a sense of timing rather than the whole lot being dumped out instantly then interrupted later, fixes issues with data being left in the fifo (mana khemia) and the IPU outstripping the other dma's (FFX Mess/Tearing on Digital Devil Saga videos). Will remove the hack later and clean up once im totally happy its ok. Note: This is technically still a hack, but it shouldnt break anything like the existing hack does, also it's closer to how it should be than anything we've done previous. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4058 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/IPU/IPU.cpp | 2 +- pcsx2/IPU/IPU_Fifo.cpp | 8 ++++---- pcsx2/IPU/IPUdma.cpp | 29 +++++++++++++++++++++++------ pcsx2/IPU/IPUdma.h | 2 +- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index b175067d2f..6dcdd387af 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -909,7 +909,7 @@ __noinline void IPUWorker() // CHECK!: IPU0dma remains when IDEC is done, so we need to clear it // Check Mana Khemia 1 "off campus" to trigger a GUST IDEC messup. // This hackfixes it :/ - if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt(); + //if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt(); break; case SCE_IPU_BDEC: diff --git a/pcsx2/IPU/IPU_Fifo.cpp b/pcsx2/IPU/IPU_Fifo.cpp index 5f03dc6983..cc35dc268c 100644 --- a/pcsx2/IPU/IPU_Fifo.cpp +++ b/pcsx2/IPU/IPU_Fifo.cpp @@ -109,11 +109,11 @@ int IPU_Fifo_Output::write(const u32 *value, uint size) pxAssumeMsg(size>0, "Invalid size==0 when calling IPU_Fifo_Output::write"); uint origsize = size; - do { - IPU0dma(); + /*do {*/ + //IPU0dma(); uint transsize = min(size, 8 - (uint)ipuRegs.ctrl.OFC); - if(!transsize) break; + if(!transsize) return 0; ipuRegs.ctrl.OFC = transsize; size -= transsize; @@ -124,7 +124,7 @@ int IPU_Fifo_Output::write(const u32 *value, uint size) value += 4; --transsize; } - } while(true); + /*} while(true);*/ return origsize - size; } diff --git a/pcsx2/IPU/IPUdma.cpp b/pcsx2/IPU/IPUdma.cpp index f430980df5..3060b771a6 100644 --- a/pcsx2/IPU/IPUdma.cpp +++ b/pcsx2/IPU/IPUdma.cpp @@ -293,15 +293,23 @@ int IPU1dma() return totalqwc; } -int IPU0dma() +void IPU0dma() { - if(!ipuRegs.ctrl.OFC) return 0; + if(!ipuRegs.ctrl.OFC) + { + IPU_INT_FROM( 64 ); + IPUProcessInterrupt(); + return; + } int readsize; tDMA_TAG* pMem; if ((!(ipu0dma.chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma.qwc == 0)) - return 0; + { + DevCon.Warning("How??"); + return; + } pxAssert(!(ipu0dma.chcr.TTE)); @@ -345,10 +353,11 @@ int IPU0dma() //This was IPU_INT_FROM(readsize*BIAS ); //This broke vids in Digital Devil Saga //Note that interrupting based on totalsize is just guessing.. - IPU_INT_FROM( readsize * BIAS ); } + IPU_INT_FROM( readsize * BIAS ); + if(ipuRegs.ctrl.IFC > 0) IPUProcessInterrupt(); - return readsize; + //return readsize; } __fi void dmaIPU0() // fromIPU @@ -364,7 +373,10 @@ __fi void dmaIPU0() // fromIPU hwDmacIrq(DMAC_FROM_IPU); } - IPUProcessInterrupt(); + IPU_INT_FROM( 64 ); + + + } __fi void dmaIPU1() // toIPU @@ -433,6 +445,11 @@ void ipu0Interrupt() { IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle); + if(ipu0dma.qwc > 0) + { + IPU0dma(); + return; + } if (g_nDMATransfer.FIREINT0) { g_nDMATransfer.FIREINT0 = false; diff --git a/pcsx2/IPU/IPUdma.h b/pcsx2/IPU/IPUdma.h index 9c62820d13..a832bcc5b7 100644 --- a/pcsx2/IPU/IPUdma.h +++ b/pcsx2/IPU/IPUdma.h @@ -87,7 +87,7 @@ extern void ipu1Interrupt(); extern void dmaIPU0(); extern void dmaIPU1(); -extern int IPU0dma(); +extern void IPU0dma(); extern int IPU1dma(); extern void ipuDmaReset();