mirror of https://github.com/PCSX2/pcsx2.git
PATH3 Masking: Tweaks mainly for Path3Masking to fix TOCA3, This is the best Path3 masking is ever going to get, there might be an occasional glitch, but nothing major *fingers crossed*, Now have the ability to log Path3 stuff seperately which will help if problems do arise.
Cleaned up Gifdma a little, removing duplicate code. Disabled a few console writes we dont nee really. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4278 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
dd66d3ac5f
commit
3fb753d463
|
@ -275,6 +275,7 @@ struct SysTraceLogPack
|
|||
SysTraceLog_EE Memory;
|
||||
SysTraceLog_EE GIFtag;
|
||||
SysTraceLog_VIFcode VIFcode;
|
||||
SysTraceLog_EE MSKPATH3;
|
||||
|
||||
SysTraceLog_EE_Disasm R5900;
|
||||
SysTraceLog_EE_Disasm COP0;
|
||||
|
@ -371,6 +372,7 @@ extern void __Log( const char* fmt, ... );
|
|||
#define VIF_LOG macTrace(EE.VIF)
|
||||
#define SPR_LOG macTrace(EE.SPR)
|
||||
#define GIF_LOG macTrace(EE.GIF)
|
||||
#define MSKPATH3_LOG macTrace(EE.MSKPATH3)
|
||||
#define EECNT_LOG macTrace(EE.Counters)
|
||||
#define VifCodeLog macTrace(EE.VIFcode)
|
||||
#define GifTagLog macTrace(EE.GIFtag)
|
||||
|
|
172
pcsx2/Gif.cpp
172
pcsx2/Gif.cpp
|
@ -53,7 +53,7 @@ void gsPath1Interrupt()
|
|||
|
||||
|
||||
|
||||
if((gifRegs.stat.APATH <= GIF_APATH1 || (gifRegs.stat.IP3 == true && gifRegs.stat.APATH == GIF_APATH3)) && Path1WritePos > 0 && !gifRegs.stat.PSE && SIGNAL_IMR_Pending == false)
|
||||
if((gifRegs.stat.APATH <= GIF_APATH1 || (gifRegs.stat.IP3 == true)) && Path1WritePos > 0 && !gifRegs.stat.PSE && SIGNAL_IMR_Pending == false)
|
||||
{
|
||||
gifRegs.stat.P1Q = false;
|
||||
|
||||
|
@ -89,6 +89,11 @@ void gsPath1Interrupt()
|
|||
else
|
||||
{
|
||||
if(gifRegs.stat.PSE) DevCon.Warning("Path1 paused by GIF_CTRL");
|
||||
if(gifRegs.stat.P1Q == false && Path1ReadPos != Path1WritePos)
|
||||
{
|
||||
DevCon.Warning("Wa's Goin on ere then?");
|
||||
gifRegs.stat.P1Q = true;
|
||||
}
|
||||
//DevCon.Warning("Looping??? IP3 %x APATH %x OPH %x", gifRegs.stat.IP3, gifRegs.stat.APATH, gifRegs.stat.OPH);
|
||||
//if(!(cpuRegs.interrupt & (1<<28)) && Path1WritePos > 0)CPU_INT(28, 128);
|
||||
}
|
||||
|
@ -115,12 +120,16 @@ __fi void gsInterrupt()
|
|||
return;
|
||||
}
|
||||
|
||||
if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE && gifRegs.stat.APATH == GIF_APATH3 )
|
||||
{
|
||||
gifRegs.stat.OPH = false;
|
||||
if(GSTransferStatus.PTH3 == PENDINGSTOP_MODE)
|
||||
{
|
||||
GSTransferStatus.PTH3 = STOPPED_MODE;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
|
||||
if(gifRegs.stat.APATH == GIF_APATH3)
|
||||
{
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
gifRegs.stat.OPH = false;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -239,7 +248,7 @@ static __fi tDMA_TAG* ReadTag2()
|
|||
|
||||
bool CheckPaths(int Channel)
|
||||
{
|
||||
if(GSTransferStatus.PTH3 <= IMAGE_MODE && gifRegs.mode.IMT)
|
||||
if((GSTransferStatus.PTH3 == IMAGE_MODE && gifRegs.mode.IMT) || GSTransferStatus.PTH3 == WAITING_MODE)
|
||||
{
|
||||
if((gifRegs.stat.P1Q == true || gifRegs.stat.P2Q == true) || (gifRegs.stat.APATH > GIF_APATH_IDLE && gifRegs.stat.APATH < GIF_APATH3))
|
||||
{
|
||||
|
@ -253,13 +262,14 @@ bool CheckPaths(int Channel)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if((GSTransferStatus.PTH3 == IDLE_MODE)|| (GSTransferStatus.PTH3 == STOPPED_MODE))
|
||||
else if(GSTransferStatus.PTH3 == STOPPED_MODE)
|
||||
{
|
||||
//This should cover both scenarios, as DIRECTHL doesn't gain priority when image mode is running (PENDINGIMAGE_MODE == fininshed).
|
||||
if((gifRegs.stat.P1Q == true || gifRegs.stat.P2Q == true) || (gifRegs.stat.APATH > GIF_APATH_IDLE && gifRegs.stat.APATH < GIF_APATH3))
|
||||
if((gifRegs.stat.P1Q == true || gifRegs.stat.P2Q == true) || (gifRegs.stat.APATH > GIF_APATH_IDLE && gifRegs.stat.APATH < GIF_APATH3) || vif1Regs.stat.VGW == true)
|
||||
{
|
||||
//DevCon.Warning("GIF Stall 2 P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
gifRegs.stat.IP3 = true;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
CPU_INT(DMAC_GIF, 16);
|
||||
return false;
|
||||
}
|
||||
|
@ -297,86 +307,9 @@ void GIFdma()
|
|||
gifch.qwc = 0;
|
||||
}
|
||||
|
||||
clearFIFOstuff(true);
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
|
||||
|
||||
if (vif1Regs.mskpath3 || gifRegs.mode.M3R)
|
||||
{
|
||||
if (gifch.qwc == 0)
|
||||
{
|
||||
if ((gifch.chcr.MOD == CHAIN_MODE) && gifch.chcr.STR)
|
||||
{
|
||||
//DevCon.Warning("GIF Reading Tag Masked MSK = %x", vif1Regs.mskpath3);
|
||||
ptag = ReadTag();
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
if (ptag == NULL) return;
|
||||
GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx tadr=%lx", ptag[1]._u32, ptag[0]._u32, gifch.qwc, ptag->ID, gifch.madr, gifch.tadr);
|
||||
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (checkTieBit(ptag)) GIF_LOG("PATH3 MSK dmaIrq Set");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (GSTransferStatus.PTH3 == IDLE_MODE)
|
||||
{
|
||||
GIF_LOG("PTH3 MASK Paused by VIF QWC %x", gifch.qwc);
|
||||
|
||||
//DevCon.Warning("GIF Paused by Mask MSK = %x", vif1Regs.mskpath3);
|
||||
|
||||
if(gifch.qwc == 0) gsInterrupt();
|
||||
else gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
//Check with Path3 masking games
|
||||
if (gifch.qwc > 0) {
|
||||
gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||
if(CheckPaths(DMAC_GIF) == false) return;
|
||||
gifRegs.stat.clear_flags(GIF_STAT_P3Q);
|
||||
GIF_LOG("PTH3 MASK Transferring");
|
||||
GIFchain();
|
||||
/*if(GSTransferStatus.PTH3 == PENDINGSTOP_MODE && gifRegs.stat.APATH == GIF_APATH_IDLE)
|
||||
{
|
||||
GSTransferStatus.PTH3 = STOPPED_MODE;
|
||||
}*/
|
||||
}//else DevCon.WriteLn("GIFdma() case 1, but qwc = 0!"); //Don't do 0 GIFchain and then return
|
||||
CPU_INT(DMAC_GIF, gscycles);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Transfer Dn_QWC from Dn_MADR to GIF
|
||||
if ((gifch.chcr.MOD == NORMAL_MODE) || (gifch.qwc > 0)) // Normal Mode
|
||||
{
|
||||
|
||||
if ((dmacRegs.ctrl.STD == STD_GIF) && (gifch.chcr.MOD == NORMAL_MODE))
|
||||
{
|
||||
//Console.WriteLn("DMA Stall Control on GIF normal");
|
||||
}
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
//Check with Path3 masking games
|
||||
//DevCon.Warning("GIF Transferring Normal/ChainQWC MSK = %x", vif1Regs.mskpath3);
|
||||
|
||||
|
||||
|
||||
if (gifch.qwc > 0) {
|
||||
gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||
if(CheckPaths(DMAC_GIF) == false) return;
|
||||
gifRegs.stat.clear_flags(GIF_STAT_P3Q);
|
||||
GIFchain(); //Transfers the data set by the switch
|
||||
CPU_INT(DMAC_GIF, gscycles);
|
||||
return;
|
||||
} else DevCon.Warning("GIF Normalmode or QWC going to invalid case? CHCR %x", gifch.chcr._u32);
|
||||
|
||||
//else DevCon.WriteLn("GIFdma() case 2, but qwc = 0!"); //Don't do 0 GIFchain and then return, fixes Dual Hearts
|
||||
}
|
||||
|
||||
if ((gifch.chcr.MOD == CHAIN_MODE) && (!gspath3done)) // Chain Mode
|
||||
if ((gifch.chcr.MOD == CHAIN_MODE) && (!gspath3done) && gifch.qwc == 0) // Chain Mode
|
||||
{
|
||||
ptag = ReadTag();
|
||||
if (ptag == NULL) return;
|
||||
|
@ -392,12 +325,7 @@ void GIFdma()
|
|||
// 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));
|
||||
prevcycles = gscycles;
|
||||
//gifch.tadr -= 16;
|
||||
// Quake III revolution wants to see tadr move.
|
||||
// Simple Media System (homebrew) as well.
|
||||
// -16 also seems right (it shifts the bg image right if anything else).
|
||||
gifch.tadr -= 16;
|
||||
// Next line also needs to be here, according to ref
|
||||
gifch.qwc = 0;
|
||||
hwDmacIrq(DMAC_STALL_SIS);
|
||||
CPU_INT(DMAC_GIF, gscycles);
|
||||
|
@ -407,11 +335,38 @@ void GIFdma()
|
|||
}
|
||||
|
||||
checkTieBit(ptag);
|
||||
/*if(gifch.qwc == 0)
|
||||
}
|
||||
|
||||
clearFIFOstuff(true);
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
|
||||
if (vif1Regs.mskpath3 || gifRegs.mode.M3R)
|
||||
{
|
||||
if (GSTransferStatus.PTH3 == STOPPED_MODE)
|
||||
{
|
||||
gsInterrupt();
|
||||
MSKPATH3_LOG("Path3 Paused by VIF QWC %x", gifch.qwc);
|
||||
|
||||
if(gifch.qwc == 0) CPU_INT(DMAC_GIF, 4);
|
||||
else gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
// Transfer Dn_QWC from Dn_MADR to GIF
|
||||
if (gifch.qwc > 0) // Normal Mode
|
||||
{
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
|
||||
gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||
|
||||
if(CheckPaths(DMAC_GIF) == false)
|
||||
return;
|
||||
|
||||
gifRegs.stat.clear_flags(GIF_STAT_P3Q);
|
||||
|
||||
GIFchain(); //Transfers the data set by the switch
|
||||
CPU_INT(DMAC_GIF, gscycles);
|
||||
return;
|
||||
}
|
||||
|
||||
prevcycles = 0;
|
||||
|
@ -626,6 +581,19 @@ void mfifoGIFtransfer(int qwc)
|
|||
if (QWCinGIFMFIFO(gifch.tadr) == 0) gifstate |= GIF_STATE_EMPTY;
|
||||
}
|
||||
|
||||
if (vif1Regs.mskpath3 || gifRegs.mode.M3R)
|
||||
{
|
||||
if ((gifch.qwc == 0) && (gifstate & GIF_STATE_DONE)) gifstate |= GIF_STATE_STALL;
|
||||
|
||||
if (GSTransferStatus.PTH3 == STOPPED_MODE)
|
||||
{
|
||||
DevCon.Warning("GIFMFIFO PTH3 MASK Paused by VIF QWC %x");
|
||||
|
||||
MSKPATH3_LOG("Path3 Paused by VIF Idling");
|
||||
gifRegs.stat.set_flags(GIF_STAT_P3Q);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!mfifoGIFchain())
|
||||
{
|
||||
Console.WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", gifch.qwc, gifch.madr, gifch.tadr);
|
||||
|
@ -656,12 +624,16 @@ void gifMFIFOInterrupt()
|
|||
return;
|
||||
}
|
||||
|
||||
if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE && gifRegs.stat.APATH == GIF_APATH3 )
|
||||
{
|
||||
gifRegs.stat.OPH = false;
|
||||
if(GSTransferStatus.PTH3 == PENDINGSTOP_MODE)
|
||||
{
|
||||
GSTransferStatus.PTH3 = STOPPED_MODE;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
|
||||
if(gifRegs.stat.APATH == GIF_APATH3)
|
||||
{
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
gifRegs.stat.OPH = false;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
if((gifstate & GIF_STATE_EMPTY))
|
||||
|
|
|
@ -218,6 +218,12 @@ TLD_EE_VIFcode = {
|
|||
"VIF"
|
||||
},
|
||||
|
||||
TLD_EE_MSKPATH3 = {
|
||||
L"MSKPATH3", L"MSKPATH3",
|
||||
pxDt("All processing involved in Path3 Masking"),
|
||||
"MSKPATH3"
|
||||
},
|
||||
|
||||
TLD_EE_SPR = {
|
||||
L"MFIFO", L"Scratchpad MFIFO",
|
||||
pxDt("Scratchpad's MFIFO activity."),
|
||||
|
@ -335,6 +341,7 @@ SysTraceLogPack::EE_PACK::EE_PACK()
|
|||
, Memory (&TLD_EE_Memory)
|
||||
, GIFtag (&TLD_EE_GIFtag)
|
||||
, VIFcode (&TLD_EE_VIFcode)
|
||||
, MSKPATH3 (&TLD_EE_MSKPATH3)
|
||||
|
||||
, R5900 (&TLD_EE_R5900)
|
||||
, COP0 (&TLD_EE_COP0)
|
||||
|
|
|
@ -151,7 +151,7 @@ __fi void vif1FBRST(u32 value) {
|
|||
//DevCon.Warning("VIF FBRST Reset MSK = %x", vif1Regs.mskpath3);
|
||||
if(vif1Regs.mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE && gifch.chcr.STR == true)
|
||||
{
|
||||
//DevCon.Warning("VIF Path3 Resume on FBRST MSK = %x", vif1Regs.mskpath3);
|
||||
DevCon.Warning("VIF Path3 Resume on FBRST MSK = %x", vif1Regs.mskpath3);
|
||||
gsInterrupt();
|
||||
vif1Regs.mskpath3 = false;
|
||||
gifRegs.stat.M3P = 0;
|
||||
|
|
|
@ -258,7 +258,7 @@ bool CheckPath2GIF(EE_EventType channel)
|
|||
{
|
||||
if( vif1.GifWaitState == 0 ) //DIRECT/HL Check
|
||||
{
|
||||
if(GSTransferStatus.PTH3 < IDLE_MODE || gifRegs.stat.P1Q)
|
||||
if(GSTransferStatus.PTH3 < STOPPED_MODE || gifRegs.stat.P1Q)
|
||||
{
|
||||
if(gifRegs.stat.IMT && GSTransferStatus.PTH3 <= IMAGE_MODE && (vif1.cmd & 0x7f) == 0x50 && gifRegs.stat.P1Q == false)
|
||||
{
|
||||
|
@ -285,19 +285,18 @@ bool CheckPath2GIF(EE_EventType channel)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (GSTransferStatus.PTH3 < IDLE_MODE)
|
||||
if (GSTransferStatus.PTH3 < STOPPED_MODE)
|
||||
{
|
||||
//DevCon.Warning("VIF1-11 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
//DevCon.Warning("VIF1-11 stall P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
|
||||
//DevCon.Warning("PTH3 %x P1Q %x P3Q %x IP3 %x", GSTransferStatus.PTH3, gifRegs.stat.P1Q, gifRegs.stat.P3Q, gifRegs.stat.IP3 );
|
||||
CPU_INT(channel, 8);
|
||||
CPU_INT(channel, 128);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1Regs.stat.VGW = false;
|
||||
}
|
||||
|
||||
vif1Regs.stat.VGW = false;
|
||||
|
||||
}
|
||||
else if( vif1.GifWaitState == 3 ) // Else we're flushing path3 :), but of course waiting for the microprogram to finish
|
||||
else if( vif1.GifWaitState == 3 ) // Any futher GIF transfers are paused.
|
||||
{
|
||||
if (gifRegs.ctrl.PSE)
|
||||
{
|
||||
|
@ -305,10 +304,9 @@ bool CheckPath2GIF(EE_EventType channel)
|
|||
CPU_INT(channel, 128);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1Regs.stat.VGW = false;
|
||||
}
|
||||
|
||||
vif1Regs.stat.VGW = false;
|
||||
|
||||
}
|
||||
else //Normal Flush
|
||||
{
|
||||
|
@ -318,18 +316,18 @@ bool CheckPath2GIF(EE_EventType channel)
|
|||
CPU_INT(channel, 128);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1Regs.stat.VGW = false;
|
||||
}
|
||||
|
||||
vif1Regs.stat.VGW = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(SIGNAL_IMR_Pending == true && (vif1.cmd & 0x7e) == 0x50)
|
||||
{
|
||||
//DevCon.Warning("Path 2 Paused");
|
||||
CPU_INT(channel, 128);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
__fi void vif1Interrupt()
|
||||
|
@ -338,19 +336,24 @@ __fi void vif1Interrupt()
|
|||
|
||||
g_vifCycles = 0;
|
||||
|
||||
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2)
|
||||
{
|
||||
gifRegs.stat.OPH = false;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
|
||||
if (schedulepath3msk & 0x10)
|
||||
{
|
||||
MSKPATH3_LOG("Scheduled Path3 Mask Firing");
|
||||
Vif1MskPath3();
|
||||
CPU_INT(DMAC_VIF1, 8);
|
||||
return;
|
||||
}
|
||||
|
||||
if(GSTransferStatus.PTH2 == PENDINGSTOP_MODE)
|
||||
{
|
||||
GSTransferStatus.PTH2 = STOPPED_MODE;
|
||||
|
||||
if(gifRegs.stat.APATH == GIF_APATH2)
|
||||
{
|
||||
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
//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)
|
||||
{
|
||||
|
|
|
@ -261,17 +261,23 @@ void vifMFIFOInterrupt()
|
|||
return;
|
||||
}
|
||||
|
||||
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2)
|
||||
if(GSTransferStatus.PTH2 == PENDINGSTOP_MODE)
|
||||
{
|
||||
GSTransferStatus.PTH2 = STOPPED_MODE;
|
||||
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
/*gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;*/
|
||||
|
||||
if(gifRegs.stat.APATH == GIF_APATH2)
|
||||
{
|
||||
if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
|
||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
if (schedulepath3msk & 0x10) Vif1MskPath3();
|
||||
if (schedulepath3msk & 0x10)
|
||||
{
|
||||
MSKPATH3_LOG("Scheduled Path3 Mask Firing on MFIFO VIF");
|
||||
Vif1MskPath3();
|
||||
}
|
||||
|
||||
if(vif1ch.chcr.DIR && CheckPath2GIF(DMAC_MFIFO_VIF) == false)
|
||||
{
|
||||
|
|
|
@ -90,15 +90,22 @@ void Vif1MskPath3() {
|
|||
|
||||
if (!vif1Regs.mskpath3)
|
||||
{
|
||||
MSKPATH3_LOG("Disabling Path3 Mask");
|
||||
//if(GSTransferStatus.PTH3 > TRANSFER_MODE && gif->chcr.STR) GSTransferStatus.PTH3 = TRANSFER_MODE;
|
||||
//DevCon.Warning("Mask off");
|
||||
//if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE) GSTransferStatus.PTH3 = IDLE_MODE;
|
||||
if(gifRegs.stat.P3Q)
|
||||
{
|
||||
MSKPATH3_LOG("Path3 Waiting to Transfer, triggering");
|
||||
gsInterrupt();//gsInterrupt();
|
||||
}
|
||||
|
||||
}// else if(!gif->chcr.STR && GSTransferStatus.PTH3 == IDLE_MODE) GSTransferStatus.PTH3 = STOPPED_MODE;//else DevCon.Warning("Mask on");
|
||||
}
|
||||
else
|
||||
{
|
||||
MSKPATH3_LOG("Path3 Mask Enabled");
|
||||
}
|
||||
// else if(!gif->chcr.STR && GSTransferStatus.PTH3 == IDLE_MODE) GSTransferStatus.PTH3 = STOPPED_MODE;//else DevCon.Warning("Mask on");
|
||||
|
||||
schedulepath3msk = 0;
|
||||
}
|
||||
|
@ -137,7 +144,7 @@ template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDire
|
|||
pass2 {
|
||||
vif1Only();
|
||||
|
||||
if (GSTransferStatus.PTH3 < IDLE_MODE || gifRegs.stat.P1Q == true)
|
||||
if (GSTransferStatus.PTH3 < STOPPED_MODE || gifRegs.stat.P1Q == true)
|
||||
{
|
||||
if(gifRegs.stat.APATH == GIF_APATH2 || ((GSTransferStatus.PTH3 <= IMAGE_MODE && gifRegs.stat.IMT && (vif1.cmd & 0x7f) == 0x50)) && gifRegs.stat.P1Q == false)
|
||||
{
|
||||
|
@ -264,10 +271,10 @@ vifOp(vifCode_FlushA) {
|
|||
pass1 {
|
||||
vifFlush(idx);
|
||||
// Gif is already transferring so wait for it.
|
||||
if (gifRegs.stat.P1Q || GSTransferStatus.PTH3 <= PENDINGSTOP_MODE) {
|
||||
if (gifRegs.stat.P1Q || GSTransferStatus.PTH3 < STOPPED_MODE) {
|
||||
//DevCon.Warning("VIF FlushA Wait MSK = %x", vif1Regs.mskpath3);
|
||||
//
|
||||
|
||||
MSKPATH3_LOG("Waiting for Path3 to Flush");
|
||||
//DevCon.WriteLn("FlushA path3 Wait! PTH3 MD %x STR %x", GSTransferStatus.PTH3, gif->chcr.STR);
|
||||
vif1Regs.stat.VGW = true;
|
||||
vifX.GifWaitState = 1;
|
||||
|
@ -376,17 +383,15 @@ vifOp(vifCode_MSCNT) {
|
|||
// ToDo: FixMe
|
||||
vifOp(vifCode_MskPath3) {
|
||||
vif1Only();
|
||||
pass1 {
|
||||
//I Hate the timing sensitivity of this stuff
|
||||
if (vif1ch.chcr.STR && vif1.lastcmd != 0x13) {
|
||||
schedulepath3msk = 0x10 | ((vif1Regs.code >> 15) & 0x1);
|
||||
}
|
||||
else
|
||||
{
|
||||
schedulepath3msk = (vif1Regs.code >> 15) & 0x1;
|
||||
Vif1MskPath3();
|
||||
}
|
||||
if(vif1ch.chcr.STR)vif1.vifstalled = true;
|
||||
pass1 {
|
||||
MSKPATH3_LOG("Direct MSKPATH3");
|
||||
|
||||
schedulepath3msk = 0x10 | (vif1Regs.code >> 15) & 0x1;
|
||||
|
||||
|
||||
if(vif1ch.chcr.STR && vif1.lastcmd != 0x13)vif1.vifstalled = true;
|
||||
else Vif1MskPath3();
|
||||
|
||||
vif1.cmd = 0;
|
||||
}
|
||||
pass3 { VifCodeLog("MskPath3"); }
|
||||
|
|
|
@ -74,14 +74,14 @@ _vifT void vifTransferLoop(u32* &data) {
|
|||
|
||||
u32& pSize = vifX.vifpacketsize;
|
||||
int iBit = vifX.cmd >> 7;
|
||||
|
||||
|
||||
vifXRegs.stat.VPS |= VPS_TRANSFERRING;
|
||||
vifXRegs.stat.ER1 = false;
|
||||
|
||||
while (pSize > 0 && !vifX.vifstalled) {
|
||||
|
||||
if(!vifX.cmd) { // Get new VifCode
|
||||
vifX.lastcmd = (vifXRegs.code >> 24) & 0x7f;
|
||||
|
||||
vifXRegs.code = data[0];
|
||||
vifX.cmd = data[0] >> 24;
|
||||
iBit = data[0] >> 31;
|
||||
|
@ -95,6 +95,7 @@ _vifT void vifTransferLoop(u32* &data) {
|
|||
|
||||
vifCmdHandler[idx][vifX.cmd & 0x7f](0, data);
|
||||
data++; pSize--;
|
||||
vifX.lastcmd = (vifXRegs.code >> 24) & 0x7f;
|
||||
if (analyzeIbit<idx>(data, iBit)) break;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -138,6 +138,7 @@ static SysTraceLog * const traceLogList[] =
|
|||
&SysTrace.EE.IPU,
|
||||
&SysTrace.EE.GIFtag,
|
||||
&SysTrace.EE.VIFcode,
|
||||
&SysTrace.EE.MSKPATH3,
|
||||
|
||||
&SysTrace.EE.DMAC,
|
||||
&SysTrace.EE.Counters,
|
||||
|
|
|
@ -631,6 +631,8 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
uint& ringpos = GetMTGS().m_packet_writepos;
|
||||
const uint original_ringpos = ringpos;
|
||||
|
||||
|
||||
|
||||
u32 startSize = size; // Start Size
|
||||
|
||||
while (size > 0) {
|
||||
|
@ -639,7 +641,7 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
SetTag<Aligned>((u8*)pMem128);
|
||||
copyTag();
|
||||
|
||||
GifTagLog("\tSetTag: %ls", tag.ToString().c_str());
|
||||
GifTagLog("\tSetTag: %ls Path %d", tag.ToString().c_str(), pathidx + 1);
|
||||
|
||||
if(nloop > 0)
|
||||
{
|
||||
|
@ -654,30 +656,22 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
else GSTransferStatus.PTH2 = TRANSFER_MODE;
|
||||
break;
|
||||
case GIF_PATH_3:
|
||||
if(vif1Regs.mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE)
|
||||
{
|
||||
GSTransferStatus.PTH3 = IDLE_MODE;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tag.FLG & 2) GSTransferStatus.PTH3 = IMAGE_MODE;
|
||||
else GSTransferStatus.PTH3 = TRANSFER_MODE;
|
||||
}
|
||||
if(tag.FLG & 2) GSTransferStatus.PTH3 = IMAGE_MODE;
|
||||
else GSTransferStatus.PTH3 = TRANSFER_MODE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if(GSTransferStatus.PTH3 < PENDINGSTOP_MODE || pathidx != 2)
|
||||
{
|
||||
gifRegs.stat.OPH = true;
|
||||
gifRegs.stat.APATH = pathidx + 1;
|
||||
}
|
||||
|
||||
gifRegs.stat.OPH = true;
|
||||
gifRegs.stat.APATH = pathidx + 1;
|
||||
|
||||
|
||||
if(pathidx == GIF_PATH_3)
|
||||
if(nloop == 0 && tag.EOP)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -694,7 +688,7 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
case GIF_PATH_3:
|
||||
if(tag.FLG & 2) GSTransferStatus.PTH3 = IMAGE_MODE;
|
||||
else GSTransferStatus.PTH3 = TRANSFER_MODE;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
gifRegs.stat.APATH = pathidx + 1;
|
||||
|
@ -809,13 +803,26 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
case GIF_FLG_IMAGE2:
|
||||
{
|
||||
GifTagLog("IMAGE Mode EOP %x", tag.EOP);
|
||||
int len = aMin(size, nloop);
|
||||
if(pathidx == GIF_PATH_3 && gifRegs.stat.IMT)
|
||||
{
|
||||
int len = aMin((int)nloop, 8);
|
||||
MemCopy_WrappedDest( pMem128, RingBuffer.m_Ring, ringpos, RingBufferSize, len );
|
||||
|
||||
MemCopy_WrappedDest( pMem128, RingBuffer.m_Ring, ringpos, RingBufferSize, len );
|
||||
pMem128 += len;
|
||||
size -= len;
|
||||
nloop -= len;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
pMem128 += len;
|
||||
size -= len;
|
||||
nloop -= len;
|
||||
int len = aMin(size, nloop);
|
||||
MemCopy_WrappedDest( pMem128, RingBuffer.m_Ring, ringpos, RingBufferSize, len );
|
||||
|
||||
pMem128 += len;
|
||||
size -= len;
|
||||
nloop -= len;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -852,30 +859,8 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (tag.EOP && !nloop) break;
|
||||
|
||||
if (tag.EOP && !nloop)
|
||||
{
|
||||
if (CSRreg.FINISH)
|
||||
{
|
||||
// IMPORTANT: only signal FINISH if ALL THREE paths are stopped (nloop is zero and EOP is set)
|
||||
// FINISH is *not* a per-path register, and it seems to pretty clearly indicate that all active
|
||||
// drawing *and* image transfer actions must be finished before the IRQ raises.
|
||||
|
||||
if(gifRegs.stat.P1Q || gifRegs.stat.P2Q || gifRegs.stat.P3Q)
|
||||
{
|
||||
//GH3 and possibly others have path data queued waiting for another path to finish! we need to check they are done too
|
||||
//DevCon.Warning("Early FINISH signal! P1 %x P2 %x P3 %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.P3Q);
|
||||
}
|
||||
else if (!(GSIMR&0x200) && !s_gifPath.path[0].IsActive() && !s_gifPath.path[1].IsActive() && !s_gifPath.path[2].IsActive())
|
||||
{
|
||||
gsIrq();
|
||||
}
|
||||
}
|
||||
|
||||
// [TODO] : DMAC Arbitration rights should select the next queued GIF transfer here.
|
||||
|
||||
break;
|
||||
}
|
||||
if(SIGNAL_IMR_Pending == true)
|
||||
{
|
||||
//DevCon.Warning("Path %x", pathidx + 1);
|
||||
|
@ -895,14 +880,31 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
GSTransferStatus.PTH1 = STOPPED_MODE;
|
||||
break;
|
||||
case GIF_PATH_2:
|
||||
GSTransferStatus.PTH2 = STOPPED_MODE;
|
||||
GSTransferStatus.PTH2 = PENDINGSTOP_MODE;
|
||||
break;
|
||||
case GIF_PATH_3:
|
||||
//For huge chunks we may have delay problems, so we need to stall it till the interrupt, else we get desync (Lemmings)
|
||||
if(size > 8) GSTransferStatus.PTH3 = PENDINGSTOP_MODE;
|
||||
else GSTransferStatus.PTH3 = STOPPED_MODE;
|
||||
GSTransferStatus.PTH3 = PENDINGSTOP_MODE;
|
||||
MSKPATH3_LOG("Path3 Finishing GIFTag packet");
|
||||
break;
|
||||
}
|
||||
|
||||
if (CSRreg.FINISH)
|
||||
{
|
||||
// IMPORTANT: only signal FINISH if ALL THREE paths are stopped (nloop is zero and EOP is set)
|
||||
// FINISH is *not* a per-path register, and it seems to pretty clearly indicate that all active
|
||||
// drawing *and* image transfer actions must be finished before the IRQ raises.
|
||||
|
||||
if(gifRegs.stat.P1Q || gifRegs.stat.P2Q || gifRegs.stat.P3Q)
|
||||
{
|
||||
//GH3 and possibly others have path data queued waiting for another path to finish! we need to check they are done too
|
||||
//DevCon.Warning("Early FINISH signal! P1 %x P2 %x P3 %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.P3Q);
|
||||
}
|
||||
else if (!(GSIMR&0x200) && !s_gifPath.path[0].IsActive() && !s_gifPath.path[1].IsActive() && !s_gifPath.path[2].IsActive())
|
||||
{
|
||||
gsIrq();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( nloop == 0)
|
||||
{
|
||||
|
@ -917,7 +919,7 @@ __fi int GIFPath::CopyTag(const u128* pMem128, u32 size)
|
|||
GSTransferStatus.PTH2 = WAITING_MODE;
|
||||
break;
|
||||
case GIF_PATH_3:
|
||||
if(GSTransferStatus.PTH3 < IDLE_MODE) GSTransferStatus.PTH3 = WAITING_MODE;
|
||||
if(GSTransferStatus.PTH3 < STOPPED_MODE) GSTransferStatus.PTH3 = WAITING_MODE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -389,7 +389,7 @@ __fi bool dmacWrite32( u32 mem, mem32_t& value )
|
|||
//Which causes a CPCOND0 to fail.
|
||||
icase(DMAC_FAKESTAT)
|
||||
{
|
||||
DevCon.Warning("Midway fixup addr=%x writing %x for DMA_STAT", mem, value);
|
||||
//DevCon.Warning("Midway fixup addr=%x writing %x for DMA_STAT", mem, value);
|
||||
HW_LOG("Midways own DMAC_STAT Write 32bit %x", value);
|
||||
|
||||
// lower 16 bits: clear on 1
|
||||
|
@ -434,7 +434,7 @@ __fi bool dmacWrite32( u32 mem, mem32_t& value )
|
|||
{
|
||||
if((psHu32(mem & ~0xff) & 0x100) && dmacRegs.ctrl.DMAE && !psHu8(DMAC_ENABLER+2))
|
||||
{
|
||||
DevCon.Warning("Write to DMA addr %x while STR is busy! Ignoring", mem);
|
||||
//DevCon.Warning("Write to DMA addr %x while STR is busy! Ignoring", mem);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue