From 3fb753d463e226828acd3fd5a4818cfd7dc90f8c Mon Sep 17 00:00:00 2001 From: refraction Date: Tue, 1 Feb 2011 01:24:37 +0000 Subject: [PATCH] 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 --- pcsx2/DebugTools/Debug.h | 2 + pcsx2/Gif.cpp | 172 +++++++++++--------------- pcsx2/SourceLog.cpp | 7 ++ pcsx2/Vif.cpp | 2 +- pcsx2/Vif1_Dma.cpp | 55 ++++---- pcsx2/Vif1_MFIFO.cpp | 20 +-- pcsx2/Vif_Codes.cpp | 35 +++--- pcsx2/Vif_Transfer.cpp | 5 +- pcsx2/gui/Panels/LogOptionsPanels.cpp | 1 + pcsx2/ps2/GIFpath.cpp | 102 +++++++-------- pcsx2/ps2/LegacyDmac.cpp | 4 +- 11 files changed, 202 insertions(+), 203 deletions(-) diff --git a/pcsx2/DebugTools/Debug.h b/pcsx2/DebugTools/Debug.h index 0a144264b4..501e1d0820 100644 --- a/pcsx2/DebugTools/Debug.h +++ b/pcsx2/DebugTools/Debug.h @@ -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) diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index efbb8f9543..3bde0641d2 100644 --- a/pcsx2/Gif.cpp +++ b/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)) diff --git a/pcsx2/SourceLog.cpp b/pcsx2/SourceLog.cpp index c9a81ae268..b291339b47 100644 --- a/pcsx2/SourceLog.cpp +++ b/pcsx2/SourceLog.cpp @@ -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) diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index 6aff2b884a..79fb8752d8 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -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; diff --git a/pcsx2/Vif1_Dma.cpp b/pcsx2/Vif1_Dma.cpp index a20f5bd009..8bc9098902 100644 --- a/pcsx2/Vif1_Dma.cpp +++ b/pcsx2/Vif1_Dma.cpp @@ -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) { diff --git a/pcsx2/Vif1_MFIFO.cpp b/pcsx2/Vif1_MFIFO.cpp index 2d9254c329..cb399060fb 100644 --- a/pcsx2/Vif1_MFIFO.cpp +++ b/pcsx2/Vif1_MFIFO.cpp @@ -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) { diff --git a/pcsx2/Vif_Codes.cpp b/pcsx2/Vif_Codes.cpp index 708ac46c16..2b7149b1e0 100644 --- a/pcsx2/Vif_Codes.cpp +++ b/pcsx2/Vif_Codes.cpp @@ -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 __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"); } diff --git a/pcsx2/Vif_Transfer.cpp b/pcsx2/Vif_Transfer.cpp index ec3a8bcf73..c11e1d86d3 100644 --- a/pcsx2/Vif_Transfer.cpp +++ b/pcsx2/Vif_Transfer.cpp @@ -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(data, iBit)) break; continue; } diff --git a/pcsx2/gui/Panels/LogOptionsPanels.cpp b/pcsx2/gui/Panels/LogOptionsPanels.cpp index 3014736bc6..53141d8d78 100644 --- a/pcsx2/gui/Panels/LogOptionsPanels.cpp +++ b/pcsx2/gui/Panels/LogOptionsPanels.cpp @@ -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, diff --git a/pcsx2/ps2/GIFpath.cpp b/pcsx2/ps2/GIFpath.cpp index 9b2ebaac0d..ea498aee43 100644 --- a/pcsx2/ps2/GIFpath.cpp +++ b/pcsx2/ps2/GIFpath.cpp @@ -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((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; } } diff --git a/pcsx2/ps2/LegacyDmac.cpp b/pcsx2/ps2/LegacyDmac.cpp index 1b22b79f3a..a0ce46eb8d 100644 --- a/pcsx2/ps2/LegacyDmac.cpp +++ b/pcsx2/ps2/LegacyDmac.cpp @@ -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; } }