mirror of https://github.com/PCSX2/pcsx2.git
IPU: Tidy up some DMA and FIFO behaviour
This commit is contained in:
parent
8335b3ee77
commit
242655bac9
|
@ -296,7 +296,6 @@ void ipuSoftReset()
|
||||||
ipu_cmd.clear();
|
ipu_cmd.clear();
|
||||||
ipuRegs.cmd.BUSY = 0;
|
ipuRegs.cmd.BUSY = 0;
|
||||||
ipuRegs.cmd.DATA = 0; // required for Enthusia - Professional Racing after fix, or will freeze at start of next video.
|
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);
|
memzero(g_BP);
|
||||||
hwIntcIrq(INTC_IPU); // required for FightBox
|
hwIntcIrq(INTC_IPU); // required for FightBox
|
||||||
}
|
}
|
||||||
|
@ -370,11 +369,9 @@ static void ipuBCLR(u32 val)
|
||||||
psHu32(DMAC_STAT) &= ~(1 << DMAC_TO_IPU);
|
psHu32(DMAC_STAT) &= ~(1 << DMAC_TO_IPU);
|
||||||
|
|
||||||
ipu_fifo.in.clear();
|
ipu_fifo.in.clear();
|
||||||
|
|
||||||
memzero(g_BP);
|
memzero(g_BP);
|
||||||
g_BP.BP = val & 0x7F;
|
g_BP.BP = val & 0x7F;
|
||||||
|
|
||||||
ipuRegs.ctrl.BUSY = 0;
|
|
||||||
ipuRegs.cmd.BUSY = 0;
|
ipuRegs.cmd.BUSY = 0;
|
||||||
IPU_LOG("Clear IPU input FIFO. Set Bit offset=0x%X", g_BP.BP);
|
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);
|
ipuBCLR(val);
|
||||||
hwIntcIrq(INTC_IPU); //DMAC_TO_IPU
|
hwIntcIrq(INTC_IPU); //DMAC_TO_IPU
|
||||||
ipuRegs.ctrl.BUSY = 0;
|
ipuRegs.ctrl.BUSY = 0;
|
||||||
|
|
||||||
IPU1Status.DataRequested = true;
|
|
||||||
if (ipu1ch.chcr.STR && cpuRegs.eCycle[4] == 0x9999)
|
|
||||||
{
|
|
||||||
CPU_INT(DMAC_TO_IPU, 32);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case SCE_IPU_SETTH:
|
case SCE_IPU_SETTH:
|
||||||
|
@ -890,8 +881,6 @@ __fi void IPUCMD_WRITE(u32 val)
|
||||||
ipuRegs.ctrl.BUSY = 0;
|
ipuRegs.ctrl.BUSY = 0;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case SCE_IPU_IDEC:
|
case SCE_IPU_IDEC:
|
||||||
g_BP.Advance(val & 0x3F);
|
g_BP.Advance(val & 0x3F);
|
||||||
ipuIDEC(val);
|
ipuIDEC(val);
|
||||||
|
@ -912,7 +901,6 @@ __fi void IPUCMD_WRITE(u32 val)
|
||||||
case SCE_IPU_FDEC:
|
case SCE_IPU_FDEC:
|
||||||
IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, CHCR 0x%x",
|
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);
|
val & 0x3f, g_BP.IFC, g_BP.BP, ipu1ch.chcr._u32);
|
||||||
|
|
||||||
g_BP.Advance(val & 0x3F);
|
g_BP.Advance(val & 0x3F);
|
||||||
ipuRegs.SetDataBusy();
|
ipuRegs.SetDataBusy();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -121,15 +121,16 @@ struct alignas(16) tIPU_BP {
|
||||||
|
|
||||||
__fi bool FillBuffer(u32 bits)
|
__fi bool FillBuffer(u32 bits)
|
||||||
{
|
{
|
||||||
while (FP <= ((BP + bits) / 128))
|
while ((FP * 128) < (BP + bits))
|
||||||
{
|
{
|
||||||
if (ipu_fifo.in.read(&internal_qwc[FP]) == 0)
|
if (ipu_fifo.in.read(&internal_qwc[FP]) == 0)
|
||||||
{
|
{
|
||||||
// Here we *try* to fill the entire internal QWC buffer; however that may not necessarily
|
// 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
|
// 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.
|
// 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;
|
++FP;
|
||||||
|
|
|
@ -38,6 +38,13 @@ void IPU_Fifo_Input::clear()
|
||||||
ipuRegs.ctrl.IFC = 0;
|
ipuRegs.ctrl.IFC = 0;
|
||||||
readpos = 0;
|
readpos = 0;
|
||||||
writepos = 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()
|
void IPU_Fifo_Output::clear()
|
||||||
|
@ -88,9 +95,10 @@ int IPU_Fifo_Input::read(void *value)
|
||||||
if (g_BP.IFC <= 1)
|
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
|
// 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 );
|
CPU_INT( DMAC_TO_IPU, 32 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,15 +260,8 @@ void IPU0dma()
|
||||||
break;
|
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
|
__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
|
// 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.
|
// 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.
|
// 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
|
__fi void dmaIPU1() // toIPU
|
||||||
|
@ -314,7 +309,7 @@ __fi void dmaIPU1() // toIPU
|
||||||
}
|
}
|
||||||
|
|
||||||
IPU1Status.DMAMode = DMA_MODE_CHAIN;
|
IPU1Status.DMAMode = DMA_MODE_CHAIN;
|
||||||
if(ipuRegs.ctrl.BUSY || IPU1Status.DataRequested)
|
if(IPU1Status.DataRequested)
|
||||||
IPU1dma();
|
IPU1dma();
|
||||||
else
|
else
|
||||||
cpuRegs.eCycle[4] = 0x9999;
|
cpuRegs.eCycle[4] = 0x9999;
|
||||||
|
@ -325,7 +320,7 @@ __fi void dmaIPU1() // toIPU
|
||||||
IPU1Status.InProgress = true;
|
IPU1Status.InProgress = true;
|
||||||
IPU1Status.DMAFinished = true;
|
IPU1Status.DMAFinished = true;
|
||||||
IPU1Status.DMAMode = DMA_MODE_NORMAL;
|
IPU1Status.DMAMode = DMA_MODE_NORMAL;
|
||||||
if (ipuRegs.ctrl.BUSY || IPU1Status.DataRequested)
|
if (IPU1Status.DataRequested)
|
||||||
IPU1dma();
|
IPU1dma();
|
||||||
else
|
else
|
||||||
cpuRegs.eCycle[4] = 0x9999;
|
cpuRegs.eCycle[4] = 0x9999;
|
||||||
|
|
Loading…
Reference in New Issue