GIF Unit: Gave it some timing, kind of. Well the APATH and OPH flags in GIF Stat will now pretend it's transferring anyway, this makes games that read these flags and expect to see them busy very happy indeed. (187 Ride or Die as an example).

I'm expecting something to break, it's my code, it's bound to. But i have tested some 40 games without problems, so my hopes are high!

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5551 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
refraction@gmail.com 2013-02-08 23:41:28 +00:00
parent b1536a755f
commit b51f0b01dd
5 changed files with 55 additions and 7 deletions

View File

@ -110,7 +110,7 @@ static __fi void gsCSRwrite( const tGS_CSR& csr )
}
else CSRreg.SIGNAL = false;
gifUnit.gsSIGNAL.queued = false;
gifUnit.Execute(false); // Resume paused transfers
gifUnit.Execute(false, true); // Resume paused transfers
}
if(csr.FINISH) CSRreg.FINISH = false;

View File

@ -50,7 +50,17 @@ void incGifChAddr(u32 qwc) {
__fi void gifInterrupt()
{
GIF_LOG("gifInterrupt caught!");
//Required for Path3 Masking timing!
if( gifRegs.stat.APATH == 3 )
{
gifRegs.stat.APATH = 0;
gifRegs.stat.OPH = 0;
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE || gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
{
if(gifUnit.checkPaths(1,1,0)) gifUnit.Execute(false, true);
}
}
//Required for Path3 Masking timing!
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
{
gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE;
@ -456,6 +466,17 @@ void gifMFIFOInterrupt()
GIF_LOG("gifMFIFOInterrupt");
mfifocycles = 0;
if( gifRegs.stat.APATH == 3 )
{
gifRegs.stat.APATH = 0;
gifRegs.stat.OPH = 0;
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE || gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
{
if(gifUnit.checkPaths(1,1,0)) gifUnit.Execute(false, true);
}
}
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
{
gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE;

View File

@ -473,7 +473,7 @@ struct Gif_Unit {
}
if (tranType == GIF_TRANS_MTVU) { // This is on the EE thread
path1.mtvu.fakePackets++;
if (CanDoGif()) Execute(false);
if (CanDoGif()) Execute(false, true);
return 0;
}
}
@ -481,7 +481,7 @@ struct Gif_Unit {
GUNIT_LOG("%s - [path=%d][size=%d]", Gif_TransferStr[(tranType>>8)&0xf], (tranType&3)+1, size);
if (size == 0) { GUNIT_WARN("Gif Unit - Size == 0"); return 0; }
if(!CanDoGif()) { GUNIT_WARN("Gif Unit - Signal or PSE Set or Dir = GS to EE"); }
pxAssertDev((stat.APATH==0) || checkPaths(1,1,1), "Gif Unit - APATH wasn't cleared?");
//pxAssertDev((stat.APATH==0) || checkPaths(1,1,1), "Gif Unit - APATH wasn't cleared?");
lastTranType = tranType;
if (tranType == GIF_TRANS_FIFO) {
@ -502,7 +502,7 @@ struct Gif_Unit {
}
gifPath[tranType&3].CopyGSPacketData(pMem, size, aligned);
size -= Execute(tranType == GIF_TRANS_DMA);
size -= Execute(tranType == GIF_TRANS_DMA, false);
return size;
}
@ -540,7 +540,7 @@ struct Gif_Unit {
// Processes gif packets and performs path arbitration
// on EOPs or on Path 3 Images when IMT is set.
int Execute(bool isPath3) {
int Execute(bool isPath3, bool isResume) {
if (!CanDoGif()) { DevCon.Error("Gif Unit - Signal or PSE Set or Dir = GS to EE"); return 0; }
bool didPath3 = false;
int curPath = stat.APATH > 0 ? stat.APATH-1 : 0; //Init to zero if no path is already set.
@ -584,7 +584,7 @@ struct Gif_Unit {
elif (!gsSIGNAL.queued && !gifPath[1].isDone()) { stat.APATH = 2; stat.P2Q = 0; curPath = 1; }
elif (!gsSIGNAL.queued && !gifPath[2].isDone() && !Path3Masked() /*&& !stat.P2Q*/)
{ stat.APATH = 3; stat.P3Q = 0; stat.IP3 = 0; curPath = 2; }
else { stat.APATH = 0; stat.OPH = 0; break; }
else { if(isResume) { stat.APATH = 0; stat.OPH = 0; } break; }
}
//Some loaders/Refresh Rate selectors and things dont issue "End of Packet" commands

View File

@ -230,6 +230,18 @@ __fi void vif1VUFinish()
vif1Regs.stat.VEW = false;
VIF_LOG("VU1 finished");
if( gifRegs.stat.APATH == 1 )
{
VIF_LOG("Clear APATH1");
gifRegs.stat.APATH = 0;
gifRegs.stat.OPH = 0;
if(!vif1.waitforvu)
{
if(gifUnit.checkPaths(0,1,1)) gifUnit.Execute(false, true);
}
}
if(vif1.waitforvu == true)
{
vif1.waitforvu = false;
@ -253,6 +265,13 @@ __fi void vif1Interrupt()
g_vif1Cycles = 0;
if( gifRegs.stat.APATH == 2 && gifUnit.gifPath[1].isDone())
{
gifRegs.stat.APATH = 0;
gifRegs.stat.OPH = 0;
if(gifUnit.checkPaths(1,0,1)) gifUnit.Execute(false, true);
}
//Some games (Fahrenheit being one) start vif first, let it loop through blankness while it sets MFIFO mode, so we need to check it here.
if (dmacRegs.ctrl.MFD == MFD_VIF1) {
//Console.WriteLn("VIFMFIFO\n");

View File

@ -250,6 +250,14 @@ void vifMFIFOInterrupt()
g_vif1Cycles = 0;
VIF_LOG("vif mfifo interrupt");
if( gifRegs.stat.APATH == 2 && gifUnit.gifPath[1].isDone())
{
gifRegs.stat.APATH = 0;
gifRegs.stat.OPH = 0;
if(gifUnit.checkPaths(1,0,1)) gifUnit.Execute(false, true);
}
if (dmacRegs.ctrl.MFD != MFD_VIF1) {
DevCon.Warning("Not in VIF MFIFO mode! Stopping VIF MFIFO");
return;