mirror of https://github.com/PCSX2/pcsx2.git
GIF: Handle PATH2 ending when VIF not running
This commit is contained in:
parent
c2af477758
commit
7966c27246
|
@ -108,11 +108,14 @@ int GIF_Fifo::write_fifo(u32* pMem, int size)
|
|||
|
||||
int writePos = fifoSize * 4;
|
||||
|
||||
GIF_LOG("GIF FIFO Adding %d QW to GIF FIFO at offset %d FIFO now contains %d QW", transferSize, writePos, fifoSize);
|
||||
|
||||
|
||||
memcpy(&data[writePos], pMem, transferSize * 16);
|
||||
|
||||
fifoSize += transferSize;
|
||||
|
||||
GIF_LOG("GIF FIFO Adding %d QW to GIF FIFO at offset %d FIFO now contains %d QW", transferSize, writePos, fifoSize);
|
||||
|
||||
gifRegs.stat.FQC = fifoSize;
|
||||
CalculateFIFOCSR();
|
||||
|
||||
|
@ -185,6 +188,13 @@ void incGifChAddr(u32 qwc)
|
|||
|
||||
__fi void gifCheckPathStatus(bool calledFromGIF)
|
||||
{
|
||||
// If GIF is running on it's own, let it handle its own timing.
|
||||
if (calledFromGIF && gifch.chcr.STR)
|
||||
{
|
||||
if(gif_fifo.fifoSize == 16)
|
||||
GifDMAInt(16);
|
||||
return;
|
||||
}
|
||||
if (gifRegs.stat.APATH == 3)
|
||||
{
|
||||
gifRegs.stat.APATH = 0;
|
||||
|
@ -222,7 +232,7 @@ __fi void gifCheckPathStatus(bool calledFromGIF)
|
|||
|
||||
__fi void gifInterrupt()
|
||||
{
|
||||
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);
|
||||
GIF_LOG("gifInterrupt caught qwc=%d fifo=%d(%d) apath=%d oph=%d state=%d!", gifch.qwc, gifRegs.stat.FQC, gif_fifo.fifoSize, gifRegs.stat.APATH, gifRegs.stat.OPH, gifUnit.gifPath[GIF_PATH_3].state);
|
||||
gifCheckPathStatus(false);
|
||||
|
||||
if (gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE)
|
||||
|
@ -280,8 +290,9 @@ __fi void gifInterrupt()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (((gifch.qwc > 0) || (!gif.gspath3done)) && gif_fifo.fifoSize)
|
||||
// If the dma has data waiting and there's something in the fifo, drain the fifo
|
||||
// If the GIF is currently paused, check if the FIFO is full, otherwise fill it
|
||||
if (((gifch.qwc > 0) || (!gif.gspath3done)) && (CheckPaths() || gif_fifo.fifoSize == 16 || readSize))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -791,7 +802,9 @@ void gifMFIFOInterrupt()
|
|||
}
|
||||
}
|
||||
|
||||
if (((gifch.qwc > 0) || (!gif.gspath3done)) && gif_fifo.fifoSize)
|
||||
// If the dma has data waiting and there's something in the fifo, drain the fifo
|
||||
// If the GIF is currently paused, check if the FIFO is full, otherwise fill it
|
||||
if (((gifch.qwc > 0) || (!gif.gspath3done)) && (CheckPaths() || gif_fifo.fifoSize == 16 || readSize))
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -327,6 +327,7 @@ struct Gif_Path
|
|||
if (curOffset + 16 > curSize)
|
||||
{
|
||||
//GUNIT_LOG("Path Buffer: Not enough data for gif tag! [%d]", curSize-curOffset);
|
||||
GUNIT_WARN("PATH %d not enough data pre tag, available %d wanted %d", gifRegs.stat.APATH, curSize - curOffset, 16);
|
||||
return gsPack;
|
||||
}
|
||||
|
||||
|
@ -339,11 +340,12 @@ struct Gif_Path
|
|||
gifTag.setTag(&buffer[curOffset], 1);
|
||||
|
||||
state = (GIF_PATH_STATE)(gifTag.tag.FLG + 1);
|
||||
|
||||
GUNIT_WARN("PATH %d New tag State %d FLG %d EOP %d NLOOP %d", gifRegs.stat.APATH, gifRegs.stat.APATH, state, gifTag.tag.FLG, gifTag.tag.EOP, gifTag.tag.NLOOP);
|
||||
// We don't have enough data for a complete GS packet
|
||||
if (!gifTag.hasAD && curOffset + 16 + gifTag.len > curSize)
|
||||
{
|
||||
gifTag.isValid = false; // So next time we test again
|
||||
GUNIT_WARN("PATH %d not enough data, available %d wanted %d", gifRegs.stat.APATH, curSize - curOffset, 16 + gifTag.len);
|
||||
return gsPack;
|
||||
}
|
||||
|
||||
|
@ -357,7 +359,10 @@ struct Gif_Path
|
|||
while (gifTag.nLoop && !dblSIGNAL)
|
||||
{
|
||||
if (curOffset + 16 > curSize)
|
||||
{
|
||||
GUNIT_WARN("PATH %d not enough data AD, available %d wanted %d", gifRegs.stat.APATH, curSize - curOffset, 16);
|
||||
return gsPack; // Exit Early
|
||||
}
|
||||
if (gifTag.curReg() == GIF_REG_A_D)
|
||||
{
|
||||
if (!isMTVU())
|
||||
|
@ -367,8 +372,11 @@ struct Gif_Path
|
|||
gifTag.packedStep();
|
||||
}
|
||||
if (dblSIGNAL && !(gifTag.tag.EOP && !gifTag.nLoop))
|
||||
{
|
||||
GUNIT_WARN("PATH %d early exit (double signal)", gifRegs.stat.APATH);
|
||||
return gsPack; // Exit Early
|
||||
}
|
||||
}
|
||||
else
|
||||
incTag(curOffset, gsPack.size, gifTag.len); // Data length
|
||||
|
||||
|
@ -384,7 +392,7 @@ struct Gif_Path
|
|||
|
||||
gsPack.Reset();
|
||||
gsPack.offset = curOffset;
|
||||
|
||||
GUNIT_WARN("EOP PATH %d", gifRegs.stat.APATH);
|
||||
//Path 3 Masking is timing sensitive, we need to simulate its length! (NFSU2/Outrun 2006)
|
||||
|
||||
if ((gifRegs.stat.APATH - 1) == GIF_PATH_3)
|
||||
|
@ -707,6 +715,7 @@ struct Gif_Unit
|
|||
return 0;
|
||||
}
|
||||
bool didPath3 = false;
|
||||
bool path3Check = isPath3;
|
||||
int curPath = stat.APATH > 0 ? stat.APATH - 1 : 0; //Init to zero if no path is already set.
|
||||
gifPath[2].dmaRewind = 0;
|
||||
stat.OPH = 1;
|
||||
|
@ -756,30 +765,43 @@ struct Gif_Unit
|
|||
}
|
||||
if (!gsSIGNAL.queued && !gifPath[0].isDone())
|
||||
{
|
||||
GUNIT_WARN("Swapping to PATH 1");
|
||||
stat.APATH = 1;
|
||||
stat.P1Q = 0;
|
||||
curPath = 0;
|
||||
}
|
||||
else if (!gsSIGNAL.queued && !gifPath[1].isDone())
|
||||
{
|
||||
GUNIT_WARN("Swapping to PATH 2");
|
||||
stat.APATH = 2;
|
||||
stat.P2Q = 0;
|
||||
curPath = 1;
|
||||
}
|
||||
else if (!gsSIGNAL.queued && !gifPath[2].isDone() && !Path3Masked())
|
||||
{
|
||||
GUNIT_WARN("Swapping to PATH 3");
|
||||
stat.APATH = 3;
|
||||
stat.P3Q = 0;
|
||||
stat.IP3 = 0;
|
||||
curPath = 2;
|
||||
path3Check = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUNIT_WARN("Finished Processing");
|
||||
// If PATH3 was stalled due to another transfer but the DMA ended, it'll never check this
|
||||
// So lets quickly check if it's currently set to path3
|
||||
if (stat.APATH == 3 || path3Check)
|
||||
gifCheckPathStatus(true);
|
||||
if (isResume || curPath == 0)
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
stat.APATH = 0;
|
||||
stat.OPH = 0;
|
||||
}
|
||||
|
|
|
@ -230,7 +230,10 @@ vifOp(vifCode_Flush)
|
|||
vif1.vifstalled.value = VIF_TIMING_BREAK;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
||||
if (vif1.waitforvu)
|
||||
return 0;
|
||||
|
||||
vif1.cmd = 0;
|
||||
vif1.pass = 0;
|
||||
}
|
||||
|
@ -258,6 +261,10 @@ vifOp(vifCode_FlushA)
|
|||
vif1.vifstalled.value = VIF_TIMING_BREAK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vif1.waitforvu)
|
||||
return 0;
|
||||
|
||||
vif1.cmd = 0;
|
||||
vif1.pass = 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue