VIF: Fix some stalls getting stuck in situations, fixes #1658

Gif FIFO: Improve reliability a little bit, especially when MFIFO is in use.
This commit is contained in:
refractionpcsx2 2016-11-12 12:36:04 +00:00
parent 49d5c4260f
commit 1053234507
2 changed files with 40 additions and 33 deletions

View File

@ -164,7 +164,7 @@ __fi void gifCheckPathStatus() {
__fi void gifInterrupt() __fi void gifInterrupt()
{ {
GIF_LOG("gifInterrupt caught!"); GIF_LOG("gifInterrupt caught qwc=%d fifo=%d apath=%d oph=%d state=%d!", gifch.qwc, gifRegs.stat.FQC, gifRegs.stat.APATH, gifRegs.stat.OPH, gifUnit.gifPath[GIF_PATH_3].state);
gifCheckPathStatus(); gifCheckPathStatus();
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE) if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE)
@ -221,6 +221,20 @@ __fi void gifInterrupt()
GifDMAInt(128); GifDMAInt(128);
return; return;
} }
gifCheckPathStatus();
//Double check as we might have read the fifo as it's ending the DMA
if (gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE)
{
if (vif1Regs.stat.VGW)
{
//Check if VIF is in a cycle or is currently "idle" waiting for GIF to come back.
if (!(cpuRegs.interrupt & (1 << DMAC_VIF1))) {
CPU_INT(DMAC_VIF1, 1);
}
}
}
if (!(gifch.chcr.STR)) return; if (!(gifch.chcr.STR)) return;
@ -236,26 +250,14 @@ __fi void gifInterrupt()
return; return;
} }
//Double check as we might have read the fifo as it's ending the DMA
gifCheckPathStatus();
if (gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE)
{
if (vif1Regs.stat.VGW)
{
//Check if VIF is in a cycle or is currently "idle" waiting for GIF to come back.
if (!(cpuRegs.interrupt & (1 << DMAC_VIF1))) {
CPU_INT(DMAC_VIF1, 1);
}
}
}
if (!CHECK_GIFFIFOHACK) if (!CHECK_GIFFIFOHACK)
{ {
gifRegs.stat.FQC = 0; gifRegs.stat.FQC = 0;
clearFIFOstuff(false); clearFIFOstuff(false);
} }
gscycles = 0; gscycles = 0;
gspath3done = false;
gifch.chcr.STR = false; gifch.chcr.STR = false;
hwDmacIrq(DMAC_GIF); hwDmacIrq(DMAC_GIF);
@ -707,7 +709,26 @@ void gifMFIFOInterrupt()
} }
} }
} }
gifCheckPathStatus();
if (gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE)
{
if (vif1Regs.stat.VGW)
{
//Check if VIF is in a cycle or is currently "idle" waiting for GIF to come back.
if (!(cpuRegs.interrupt & (1 << DMAC_VIF1)))
CPU_INT(DMAC_VIF1, 1);
//Make sure it loops if the GIF packet is empty to prepare for the next packet
//or end if it was the end of a packet.
//This must trigger after VIF retriggers as VIf might instantly mask Path3
if (!gifUnit.Path3Masked() || gifch.qwc == 0) {
GifDMAInt(16);
}
return;
}
}
if (!gifch.chcr.STR) { if (!gifch.chcr.STR) {
Console.WriteLn("WTF GIFMFIFO"); Console.WriteLn("WTF GIFMFIFO");
cpuRegs.interrupt &= ~(1 << 11); cpuRegs.interrupt &= ~(1 << 11);
@ -760,10 +781,7 @@ void gifMFIFOInterrupt()
} }
} }
//if(gifqwc > 0) Console.WriteLn("GIF MFIFO ending with stuff in it %x", gifqwc); //if(gifqwc > 0) Console.WriteLn("GIF MFIFO ending with stuff in it %x", gifqwc);
if (!gifmfifoirq) gifqwc = 0;
gspath3done = false;
gscycles = 0;
if (!CHECK_GIFFIFOHACK) if (!CHECK_GIFFIFOHACK)
{ {
@ -772,17 +790,9 @@ void gifMFIFOInterrupt()
} }
//vif1Regs.stat.VGW = false; // old code had this //vif1Regs.stat.VGW = false; // old code had this
gifCheckPathStatus(); if (!gifmfifoirq) gifqwc = 0;
if (gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE) gscycles = 0;
{
if (vif1Regs.stat.VGW)
{
//Check if VIF is in a cycle or is currently "idle" waiting for GIF to come back.
if (!(cpuRegs.interrupt & (1 << DMAC_VIF1)))
CPU_INT(DMAC_VIF1, 1);
}
}
gifch.chcr.STR = false; gifch.chcr.STR = false;
gifstate = GIF_STATE_READY; gifstate = GIF_STATE_READY;

View File

@ -254,8 +254,6 @@ __fi void vif1FBRST(u32 value) {
if (cancel) if (cancel)
{ {
if (vif1.vifstalled.enabled && vif1.vifstalled.value == VIF_IRQ_STALL)
{
g_vif1Cycles = 0; g_vif1Cycles = 0;
// loop necessary for spiderman // loop necessary for spiderman
switch(dmacRegs.ctrl.MFD) switch(dmacRegs.ctrl.MFD)
@ -275,7 +273,6 @@ __fi void vif1FBRST(u32 value) {
} }
//vif1ch.chcr.STR = true; //vif1ch.chcr.STR = true;
}
} }
} }
} }