diff --git a/pcsx2/IPU/IPU.h b/pcsx2/IPU/IPU.h index 626990d52c..fe92040df6 100644 --- a/pcsx2/IPU/IPU.h +++ b/pcsx2/IPU/IPU.h @@ -91,6 +91,8 @@ struct alignas(16) tIPU_BP { __fi void Advance(uint bits) { + FillBuffer(bits); + BP += bits; pxAssume( BP <= 256 ); @@ -112,10 +114,10 @@ struct alignas(16) tIPU_BP { // if FP == 0 then an already-drained buffer is being advanced, and we need to drop a // quadword from the IPU FIFO. - if (!FP) - ipu_fifo.in.read(&internal_qwc[0]); - - FP = 0; + if (ipu_fifo.in.read(&internal_qwc[0])) + FP = 1; + else + FP = 0; } } } diff --git a/pcsx2/IPU/IPU_Fifo.cpp b/pcsx2/IPU/IPU_Fifo.cpp index 1425aace96..8507174b75 100644 --- a/pcsx2/IPU/IPU_Fifo.cpp +++ b/pcsx2/IPU/IPU_Fifo.cpp @@ -86,6 +86,9 @@ int IPU_Fifo_Input::write(u32* pMem, int size) pMem += 4; } + if (g_BP.IFC == 8) + IPU1Status.DataRequested = false; + return firsttrans; } @@ -99,7 +102,7 @@ int IPU_Fifo_Input::read(void *value) if(ipu1ch.chcr.STR && cpuRegs.eCycle[4] == 0x9999) { - CPU_INT( DMAC_TO_IPU, 32 ); + CPU_INT( DMAC_TO_IPU, 4); } if (g_BP.IFC == 0) return 0; @@ -135,7 +138,7 @@ int IPU_Fifo_Output::write(const u32 *value, uint size) } /*} while(true);*/ if(ipu0ch.chcr.STR) - IPU_INT_FROM(64); + IPU_INT_FROM(ipuRegs.ctrl.OFC * BIAS); return origsize - size; } diff --git a/pcsx2/IPU/IPUdma.cpp b/pcsx2/IPU/IPUdma.cpp index 9c94a5a1b8..1e11ea6fbb 100644 --- a/pcsx2/IPU/IPUdma.cpp +++ b/pcsx2/IPU/IPUdma.cpp @@ -121,7 +121,7 @@ void IPU1dma() if(totalqwc == 0 || (IPU1Status.DMAFinished && !IPU1Status.InProgress)) { totalqwc = std::max(4, totalqwc); - IPU_INT_TO(totalqwc); + IPU_INT_TO(totalqwc * BIAS); } else { @@ -133,18 +133,18 @@ void IPU1dma() } else { - IPU_INT_TO(totalqwc*BIAS); + IPU_INT_TO(totalqwc * BIAS); } } - IPUProcessInterrupt(); + CPU_INT(IPU_PROCESS, totalqwc * BIAS); IPU_LOG("Completed Call IPU1 DMA QWC Remaining %x Finished %d In Progress %d tadr %x", ipu1ch.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1ch.tadr); } void IPU0dma() { - if(!ipuRegs.ctrl.OFC) + if(!ipuRegs.ctrl.OFC) { IPUProcessInterrupt(); return; @@ -181,6 +181,9 @@ void IPU0dma() } IPU_INT_FROM( readsize * BIAS ); + + if (ipu0ch.qwc > 0) + CPU_INT(IPU_PROCESS, 4); } __fi void dmaIPU0() // fromIPU @@ -256,6 +259,11 @@ __fi void dmaIPU1() // toIPU } } +void ipuCMDProcess() +{ + IPUProcessInterrupt(); +} + void ipu0Interrupt() { IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle); diff --git a/pcsx2/IPU/IPUdma.h b/pcsx2/IPU/IPUdma.h index 0c22788a89..9f7db0f37e 100644 --- a/pcsx2/IPU/IPUdma.h +++ b/pcsx2/IPU/IPUdma.h @@ -23,6 +23,7 @@ struct IPUStatus { bool DataRequested; }; +extern void ipuCMDProcess(); extern void ipu0Interrupt(); extern void ipu1Interrupt(); diff --git a/pcsx2/R5900.cpp b/pcsx2/R5900.cpp index 2d5c0653cf..54498a1d0b 100644 --- a/pcsx2/R5900.cpp +++ b/pcsx2/R5900.cpp @@ -297,7 +297,7 @@ static __fi void _cpuTestInterrupts() TESTINT(DMAC_GIF, gifInterrupt); TESTINT(DMAC_SIF0, EEsif0Interrupt); TESTINT(DMAC_SIF1, EEsif1Interrupt); - + TESTINT(IPU_PROCESS, ipuCMDProcess); // Profile-guided Optimization (sorta) // The following ints are rarely called. Encasing them in a conditional // as follows helps speed up most games. diff --git a/pcsx2/R5900.h b/pcsx2/R5900.h index b60c69d3fa..5fa6bce73c 100644 --- a/pcsx2/R5900.h +++ b/pcsx2/R5900.h @@ -413,7 +413,8 @@ enum EE_EventType DMAC_GIF_UNIT, VIF_VU0_FINISH, - VIF_VU1_FINISH + VIF_VU1_FINISH, + IPU_PROCESS }; extern void CPU_INT( EE_EventType n, s32 ecycle );