mirror of https://github.com/PCSX2/pcsx2.git
DMAC: Improve DMA Stall handling (#3701)
SIF: Implemented SIF0 and SIF1 DMA Stall handling Cleaned up some of the handling of DMA Stalls on the other channels
This commit is contained in:
parent
a5cc8efb10
commit
40d02400ca
|
@ -400,12 +400,12 @@ void GIFdma()
|
|||
{
|
||||
// stalled.
|
||||
// We really need to test this. Pay attention to prevcycles, as it used to trigger GIFchains in the code above. (rama)
|
||||
//Console.WriteLn("GS Stall Control start Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gifch.madr, psHu32(DMAC_STADR));
|
||||
//DevCon.Warning("GS Stall Control start Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gifch.madr, psHu32(DMAC_STADR));
|
||||
gif.prevcycles = gif.gscycles;
|
||||
gifch.tadr -= 16;
|
||||
gifch.qwc = 0;
|
||||
hwDmacIrq(DMAC_STALL_SIS);
|
||||
GifDMAInt(gif.gscycles);
|
||||
GifDMAInt(128);
|
||||
gif.gscycles = 0;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -226,8 +226,9 @@ void IPU0dma()
|
|||
ipu0ch.qwc -= readsize; // note: qwc is u16
|
||||
|
||||
|
||||
if (dmacRegs.ctrl.STS == STS_fromIPU) // STS == fromIPU
|
||||
if (dmacRegs.ctrl.STS == STS_fromIPU && ipu0ch.qwc == 0) // STS == fromIPU
|
||||
{
|
||||
//DevCon.Warning("fromIPU Stall Control");
|
||||
dmacRegs.stadr.ADDR = ipu0ch.madr;
|
||||
switch (dmacRegs.ctrl.STD)
|
||||
{
|
||||
|
@ -271,6 +272,10 @@ __fi void dmaIPU0() // fromIPU
|
|||
hwDmacIrq(DMAC_FROM_IPU);
|
||||
}
|
||||
//if (dmacRegs.ctrl.STS == STS_fromIPU) DevCon.Warning("DMA Stall enabled on IPU0");
|
||||
|
||||
if (dmacRegs.ctrl.STS == STS_fromIPU) // STS == fromIPU - Initial settings
|
||||
dmacRegs.stadr.ADDR = ipu0ch.madr;
|
||||
|
||||
IPU_INT_FROM( 64 );
|
||||
|
||||
|
||||
|
|
|
@ -138,7 +138,14 @@ int _SPR0chain()
|
|||
|
||||
}
|
||||
|
||||
|
||||
if (spr0ch.qwc == 0 && dmacRegs.ctrl.STS == STS_fromSPR)
|
||||
{
|
||||
if (spr0ch.chcr.MOD == NORMAL_MODE || ((spr0ch.chcr.TAG >> 28) & 0x7) == TAG_CNTS)
|
||||
{
|
||||
//DevCon.Warning("SPR0 %s Stall Control", spr0ch.chcr.MOD == NORMAL_MODE ? "Normal" : "Chain");
|
||||
dmacRegs.stadr.ADDR = spr0ch.madr; // Copy MADR to DMAC_STADR stall addr register
|
||||
}
|
||||
}
|
||||
|
||||
return (partialqwc); // Bus is 1/2 the ee speed
|
||||
}
|
||||
|
@ -188,17 +195,16 @@ void _SPR0interleave()
|
|||
spr0ch.sadr &= 0x3FFF; // Limited to 16K
|
||||
spr0ch.madr += (sqwc + spr0ch.qwc) * 16;
|
||||
}
|
||||
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR)
|
||||
{
|
||||
//DevCon.Warning("SPR0 Interleave Stall Control");
|
||||
dmacRegs.stadr.ADDR = spr0ch.madr; // Copy MADR to DMAC_STADR stall addr register
|
||||
}
|
||||
spr0ch.qwc = 0;
|
||||
}
|
||||
|
||||
static __fi void _dmaSPR0()
|
||||
{
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR)
|
||||
{
|
||||
DevCon.Warning("SPR0 stall %d", dmacRegs.ctrl.STS);
|
||||
}
|
||||
|
||||
// Transfer Dn_QWC from SPR to Dn_MADR
|
||||
switch(spr0ch.chcr.MOD)
|
||||
{
|
||||
|
@ -206,7 +212,7 @@ static __fi void _dmaSPR0()
|
|||
{
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR) // STS == fromSPR
|
||||
{
|
||||
DevCon.Warning("SPR stall control Normal not implemented");
|
||||
dmacRegs.stadr.ADDR = spr0ch.madr;
|
||||
}
|
||||
SPR0chain();
|
||||
spr0finished = true;
|
||||
|
@ -234,15 +240,13 @@ static __fi void _dmaSPR0()
|
|||
SPR_LOG("spr0 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
|
||||
ptag[1]._u32, ptag[0]._u32, spr0ch.qwc, ptag->ID, spr0ch.madr, spr0ch.sadr);
|
||||
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR) // STS == fromSPR
|
||||
{
|
||||
Console.WriteLn("SPR stall control");
|
||||
}
|
||||
|
||||
switch (ptag->ID)
|
||||
{
|
||||
case TAG_CNTS: // CNTS - Transfer QWC following the tag (Stall Control)
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR) dmacRegs.stadr.ADDR = spr0ch.madr + (spr0ch.qwc * 16); // Copy MADR to DMAC_STADR stall addr register
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR) // STS == fromSPR - Initial Value
|
||||
{
|
||||
dmacRegs.stadr.ADDR = spr0ch.madr;
|
||||
}
|
||||
break;
|
||||
|
||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||
|
@ -270,10 +274,6 @@ static __fi void _dmaSPR0()
|
|||
//case INTERLEAVE_MODE:
|
||||
default:
|
||||
{
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR) // STS == fromSPR
|
||||
{
|
||||
Console.WriteLn("SPR stall control interleave not implemented");
|
||||
}
|
||||
_SPR0interleave();
|
||||
spr0finished = true;
|
||||
break;
|
||||
|
|
|
@ -58,6 +58,13 @@ static __fi bool WriteFifoToEE()
|
|||
sif0.ee.cycles += readSize; // fixme : BIAS is factored in above
|
||||
sif0ch.qwc -= readSize;
|
||||
|
||||
if (sif0ch.qwc == 0 && dmacRegs.ctrl.STS == STS_SIF0)
|
||||
{
|
||||
//DevCon.Warning("SIF0 Stall Control");
|
||||
if ((sif0ch.chcr.MOD == NORMAL_MODE) || ((sif0ch.chcr.TAG >> 28) & 0x7) == TAG_CNTS)
|
||||
dmacRegs.stadr.ADDR = sif0ch.madr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -105,8 +112,8 @@ static __fi bool ProcessEETag()
|
|||
case TAG_CNT: break;
|
||||
|
||||
case TAG_CNTS:
|
||||
if (dmacRegs.ctrl.STS == STS_SIF0)
|
||||
dmacRegs.stadr.ADDR = sif0ch.madr + (sif0ch.qwc * 16);
|
||||
if (dmacRegs.ctrl.STS == STS_SIF0) // STS == SIF0 - Initial Value
|
||||
dmacRegs.stadr.ADDR = sif0ch.madr;
|
||||
break;
|
||||
|
||||
case TAG_END:
|
||||
|
@ -190,11 +197,6 @@ static __fi void HandleEETransfer()
|
|||
return;
|
||||
}
|
||||
|
||||
if (dmacRegs.ctrl.STS == STS_SIF0)
|
||||
{
|
||||
DevCon.Warning("SIF0 stall control not properly implemented");
|
||||
}
|
||||
|
||||
/*if (sif0ch.qwc == 0)
|
||||
if (sif0ch.chcr.MOD == NORMAL_MODE)
|
||||
if (!sif0.ee.end){
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
_sif sif1;
|
||||
|
||||
static bool done = false;
|
||||
static bool sif1_dma_stall = false;
|
||||
|
||||
static __fi void Sif1Init()
|
||||
{
|
||||
|
@ -186,10 +187,6 @@ static __fi void HandleEETransfer()
|
|||
sif1.ee.busy = false;
|
||||
return;
|
||||
}
|
||||
if (dmacRegs.ctrl.STD == STD_SIF1)
|
||||
{
|
||||
DevCon.Warning("SIF1 stall control Not Implemented"); // STD == fromSIF1
|
||||
}
|
||||
|
||||
/*if (sif1ch.qwc == 0)
|
||||
if (sif1ch.chcr.MOD == NORMAL_MODE)
|
||||
|
@ -216,6 +213,21 @@ static __fi void HandleEETransfer()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (dmacRegs.ctrl.STD == STD_SIF1)
|
||||
{
|
||||
if ((sif1ch.chcr.MOD == NORMAL_MODE) || ((sif1ch.chcr.TAG >> 28) & 0x7) == TAG_REFS)
|
||||
{
|
||||
//DevCon.Warning("SIF1 Stall Control");
|
||||
const int writeSize = std::min((s32)sif1ch.qwc, sif1.fifo.sif_free() >> 2);
|
||||
if ((sif1ch.madr + (writeSize * 16)) > dmacRegs.stadr.ADDR)
|
||||
{
|
||||
hwDmacIrq(DMAC_STALL_SIS);
|
||||
sif1_dma_stall = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//DevCon.Warning("SIF1 stall control Not Implemented"); // STD == fromSIF1
|
||||
}
|
||||
if (sif1.fifo.sif_free() > 0)
|
||||
{
|
||||
WriteEEtoFifo();
|
||||
|
@ -262,6 +274,15 @@ static __fi void Sif1End()
|
|||
__fi void SIF1Dma()
|
||||
{
|
||||
int BusyCheck = 0;
|
||||
|
||||
if (sif1_dma_stall)
|
||||
{
|
||||
const int writeSize = std::min((s32)sif1ch.qwc, sif1.fifo.sif_free() >> 2);
|
||||
if ((sif1ch.madr + (writeSize * 16)) > dmacRegs.stadr.ADDR)
|
||||
return;
|
||||
}
|
||||
|
||||
sif1_dma_stall = false;
|
||||
Sif1Init();
|
||||
|
||||
do
|
||||
|
@ -269,7 +290,7 @@ __fi void SIF1Dma()
|
|||
//I realise this is very hacky in a way but its an easy way of checking if both are doing something
|
||||
BusyCheck = 0;
|
||||
|
||||
if (sif1.ee.busy)
|
||||
if (sif1.ee.busy && !sif1_dma_stall)
|
||||
{
|
||||
if(sif1.fifo.sif_free() > 0 || (sif1.ee.end && sif1ch.qwc == 0))
|
||||
{
|
||||
|
|
|
@ -164,7 +164,7 @@ __fi void vif1SetupTransfer()
|
|||
if (!vif1.done && ((dmacRegs.ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1
|
||||
{
|
||||
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
|
||||
if ((vif1ch.madr + vif1ch.qwc * 16) >= dmacRegs.stadr.ADDR)
|
||||
if ((vif1ch.madr + vif1ch.qwc * 16) > dmacRegs.stadr.ADDR)
|
||||
{
|
||||
//DevCon.Warning("VIF1 DMA Stall");
|
||||
// stalled
|
||||
|
@ -437,13 +437,6 @@ void dmaVIF1()
|
|||
|
||||
g_vif1Cycles = 0;
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if (dmacRegs.ctrl.STD == STD_VIF1)
|
||||
{
|
||||
//DevCon.WriteLn("VIF Stall Control Source = %x, Drain = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vif1ch.qwc > 0) // Normal Mode
|
||||
{
|
||||
|
||||
|
|
|
@ -421,14 +421,50 @@ __fi bool dmacWrite32( u32 mem, mem32_t& value )
|
|||
{
|
||||
if (!QueuedDMA.empty()) StartQueuedDMA();
|
||||
}
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if ((oldvalue & 0x30) != (value & 0x30))
|
||||
{
|
||||
DevCon.Warning("32bit Stall Source Changed to %x", (value & 0x30) >> 4);
|
||||
std::string new_source;
|
||||
|
||||
switch ((value & 0x30) >> 4)
|
||||
{
|
||||
case 1:
|
||||
new_source = "SIF0";
|
||||
break;
|
||||
case 2:
|
||||
new_source = "fromSPR";
|
||||
break;
|
||||
case 3:
|
||||
new_source = "fromIPU";
|
||||
break;
|
||||
default:
|
||||
new_source = "None";
|
||||
break;
|
||||
}
|
||||
DevCon.Warning("32bit Stall Source Changed to %s", new_source.c_str());
|
||||
}
|
||||
if ((oldvalue & 0xC0) != (value & 0xC0))
|
||||
{
|
||||
DevCon.Warning("32bit Stall Destination Changed to %x", (value & 0xC0) >> 4);
|
||||
std::string new_dest;
|
||||
|
||||
switch ((value & 0xC0) >> 6)
|
||||
{
|
||||
case 1:
|
||||
new_dest = "VIF1";
|
||||
break;
|
||||
case 2:
|
||||
new_dest = "GIF";
|
||||
break;
|
||||
case 3:
|
||||
new_dest = "SIF1";
|
||||
break;
|
||||
default:
|
||||
new_dest = "None";
|
||||
break;
|
||||
}
|
||||
DevCon.Warning("32bit Stall Destination Changed to %s", new_dest.c_str());
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue