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
This commit is contained in:
refraction 2010-11-27 00:11:52 +00:00
parent 5f1ccc767e
commit 533bb0846b
4 changed files with 29 additions and 12 deletions

View File

@ -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:

View File

@ -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;
}

View File

@ -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;

View File

@ -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();