diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index 7e965f5bae..afdd6a9191 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -296,7 +296,6 @@ void ipuSoftReset() ipu_cmd.clear(); ipuRegs.cmd.BUSY = 0; ipuRegs.cmd.DATA = 0; // required for Enthusia - Professional Racing after fix, or will freeze at start of next video. - IPU1Status.DataRequested = true; memzero(g_BP); hwIntcIrq(INTC_IPU); // required for FightBox } @@ -370,11 +369,9 @@ static void ipuBCLR(u32 val) psHu32(DMAC_STAT) &= ~(1 << DMAC_TO_IPU); ipu_fifo.in.clear(); - memzero(g_BP); g_BP.BP = val & 0x7F; - ipuRegs.ctrl.BUSY = 0; ipuRegs.cmd.BUSY = 0; IPU_LOG("Clear IPU input FIFO. Set Bit offset=0x%X", g_BP.BP); } @@ -876,12 +873,6 @@ __fi void IPUCMD_WRITE(u32 val) ipuBCLR(val); hwIntcIrq(INTC_IPU); //DMAC_TO_IPU ipuRegs.ctrl.BUSY = 0; - - IPU1Status.DataRequested = true; - if (ipu1ch.chcr.STR && cpuRegs.eCycle[4] == 0x9999) - { - CPU_INT(DMAC_TO_IPU, 32); - } return; case SCE_IPU_SETTH: @@ -890,8 +881,6 @@ __fi void IPUCMD_WRITE(u32 val) ipuRegs.ctrl.BUSY = 0; return; - - case SCE_IPU_IDEC: g_BP.Advance(val & 0x3F); ipuIDEC(val); @@ -912,7 +901,6 @@ __fi void IPUCMD_WRITE(u32 val) case SCE_IPU_FDEC: IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, CHCR 0x%x", val & 0x3f, g_BP.IFC, g_BP.BP, ipu1ch.chcr._u32); - g_BP.Advance(val & 0x3F); ipuRegs.SetDataBusy(); break; diff --git a/pcsx2/IPU/IPU.h b/pcsx2/IPU/IPU.h index 42da83e1d0..993a07f154 100644 --- a/pcsx2/IPU/IPU.h +++ b/pcsx2/IPU/IPU.h @@ -121,15 +121,16 @@ struct alignas(16) tIPU_BP { __fi bool FillBuffer(u32 bits) { - while (FP <= ((BP + bits) / 128)) + while ((FP * 128) < (BP + bits)) { if (ipu_fifo.in.read(&internal_qwc[FP]) == 0) { // Here we *try* to fill the entire internal QWC buffer; however that may not necessarily // be possible -- so if the fill fails we'll only return 0 if we don't have enough // remaining bits in the FIFO to fill the request. + // Used to do ((FP!=0) && (BP + bits) <= 128) if we get here there's defo not enough data now though - return ((FP!=0) && (BP + bits) <= 128); + return false; } ++FP; diff --git a/pcsx2/IPU/IPU_Fifo.cpp b/pcsx2/IPU/IPU_Fifo.cpp index 89ed049d62..e2f961515b 100644 --- a/pcsx2/IPU/IPU_Fifo.cpp +++ b/pcsx2/IPU/IPU_Fifo.cpp @@ -38,6 +38,13 @@ void IPU_Fifo_Input::clear() ipuRegs.ctrl.IFC = 0; readpos = 0; writepos = 0; + + // Because the FIFO is drained it will request more data immediately + IPU1Status.DataRequested = true; + if (ipu1ch.chcr.STR && cpuRegs.eCycle[4] == 0x9999) + { + CPU_INT(DMAC_TO_IPU, 32); + } } void IPU_Fifo_Output::clear() @@ -88,9 +95,10 @@ int IPU_Fifo_Input::read(void *value) if (g_BP.IFC <= 1) { // IPU FIFO is empty and DMA is waiting so lets tell the DMA we are ready to put data in the FIFO - if(cpuRegs.eCycle[4] == 0x9999) + IPU1Status.DataRequested = true; + + if(ipu1ch.chcr.STR && cpuRegs.eCycle[4] == 0x9999) { - IPU1Status.DataRequested = true; CPU_INT( DMAC_TO_IPU, 32 ); } diff --git a/pcsx2/IPU/IPUdma.cpp b/pcsx2/IPU/IPUdma.cpp index 3f96bb1d47..a7e3e7d232 100644 --- a/pcsx2/IPU/IPUdma.cpp +++ b/pcsx2/IPU/IPUdma.cpp @@ -260,15 +260,8 @@ void IPU0dma() break; } } - //Fixme ( voodoocycles ): - //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 ); - if (ipuRegs.ctrl.IFC > 0) { IPUProcessInterrupt(); } - //return readsize; + IPU_INT_FROM( readsize * BIAS ); } __fi void dmaIPU0() // fromIPU @@ -282,7 +275,9 @@ __fi void dmaIPU0() // fromIPU // This is because the game sends bad DMA information, starts an IDEC, then sets it to the correct values // but because our IPU is too quick, it messes up the sync between the DMA and IPU. // So this will do until (if) we sort the timing out of IPU, shouldn't cause any problems for games for now. - IPU_INT_FROM( 160 ); + //IPU_INT_FROM( 160 ); + // Update 22/12/2021 - Doesn't seem to need this now after fixing some FIFO/DMA behaviour + IPU0dma(); } __fi void dmaIPU1() // toIPU @@ -314,7 +309,7 @@ __fi void dmaIPU1() // toIPU } IPU1Status.DMAMode = DMA_MODE_CHAIN; - if(ipuRegs.ctrl.BUSY || IPU1Status.DataRequested) + if(IPU1Status.DataRequested) IPU1dma(); else cpuRegs.eCycle[4] = 0x9999; @@ -325,7 +320,7 @@ __fi void dmaIPU1() // toIPU IPU1Status.InProgress = true; IPU1Status.DMAFinished = true; IPU1Status.DMAMode = DMA_MODE_NORMAL; - if (ipuRegs.ctrl.BUSY || IPU1Status.DataRequested) + if (IPU1Status.DataRequested) IPU1dma(); else cpuRegs.eCycle[4] = 0x9999;