From fd1305e4da31ceead456ae3effe84e29a8cbde0c Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Sat, 24 Jul 2021 23:17:57 +0100 Subject: [PATCH] GIF: Reimplement GIF FIFO to kick in only when it is needed. Need to adjust GameDB entries for to remove ones no longer required, added EE Timing fix for SOCOM as that seems to fix it up like its sequel. Some misc changes too which are inconsequential (mostly formatting) --- bin/GameIndex.yaml | 64 ---- pcsx2/FiFo.cpp | 8 +- pcsx2/Gif.cpp | 507 +++++++++++++--------------- pcsx2/Gif.h | 7 +- pcsx2/Gif_Unit.h | 1 + pcsx2/Hw.cpp | 6 - pcsx2/HwWrite.cpp | 3 +- pcsx2/SPR.cpp | 3 +- pcsx2/SaveState.h | 2 +- pcsx2/Vif.cpp | 6 +- pcsx2/Vif1_Dma.cpp | 4 +- pcsx2/Vif_Codes.cpp | 7 +- pcsx2/gui/Panels/GameFixesPanel.cpp | 2 +- 13 files changed, 255 insertions(+), 365 deletions(-) diff --git a/bin/GameIndex.yaml b/bin/GameIndex.yaml index 477bdc2c1e..acf1af929a 100644 --- a/bin/GameIndex.yaml +++ b/bin/GameIndex.yaml @@ -31,8 +31,6 @@ GUST-00009: region: "NTSC-J" roundModes: eeRoundMode: 0 # Fixes jump issue. - gameFixes: - - GIFFIFOHack # Fixes flickering sprites. PAPX-90203: name: "Gran Turismo 2000 [Trial]" region: "NTSC-J" @@ -2210,8 +2208,6 @@ SCES-50928: region: "PAL-M6" clampModes: vuClampMode: 2 # Fixes bad shadows. - gameFixes: - - GIFFIFOHack # Resolves random sprite/HUD corruption. SCES-50934: name: "WRC II Extreme" region: "PAL-M7" @@ -2419,8 +2415,6 @@ SCES-51618: region: "PAL-M5" clampModes: vuClampMode: 2 # Fixes bad shadows. - gameFixes: - - GIFFIFOHack # Resolves random sprite/HUD corruption. SCES-51635: name: "Brave - The Search for Spirit Dancer" region: "PAL-M5" @@ -3678,8 +3672,6 @@ SCKA-24008: region: "NTSC-K" clampModes: vuClampMode: 2 # Fixes bad shadows. - gameFixes: - - GIFFIFOHack # Resolves random sprite/HUD corruption. SCKA-30001: name: "Gran Turismo 4" region: "NTSC-K" @@ -3997,8 +3989,6 @@ SCPS-15044: region: "NTSC-J" clampModes: vuClampMode: 2 # Fixes bad shadows. - gameFixes: - - GIFFIFOHack # Resolves random sprite/HUD corruption. SCPS-15045: name: "Ka (Mosquito) - Let's Go Hawaiian" region: "NTSC-J" @@ -5077,8 +5067,6 @@ SCUS-97134: compat: 5 clampModes: vuClampMode: 2 # Fixes bad shadows. - gameFixes: - - GIFFIFOHack # Resolves random sprite/HUD corruption. SCUS-97136: name: "NCAA Final Four 2002" region: "NTSC-U" @@ -5314,8 +5302,6 @@ SCUS-97205: region: "NTSC-U" clampModes: vuClampMode: 2 # Fixes bad shadows. - gameFixes: - - GIFFIFOHack # Resolves random sprite/HUD corruption. SCUS-97206: name: "PlayStation Underground Jampack Summer 2002" region: "NTSC-U" @@ -5399,8 +5385,6 @@ SCUS-97230: region: "NTSC-U" clampModes: vuClampMode: 2 # Fixes bad shadows. - gameFixes: - - GIFFIFOHack # Resolves random sprite/HUD corruption. SCUS-97231: name: "Arc the Lad - Twilight of the Spirits" region: "NTSC-U" @@ -8786,13 +8770,9 @@ SLES-51011: SLES-51013: name: "Blade II" region: "PAL-E" - gameFixes: - - GIFFIFOHack # Fixes flickering HUD. (originally was EE Timing Hack but required since r4821) SLES-51014: name: "Blade II" region: "PAL-F" - gameFixes: - - GIFFIFOHack # Fixes flickering HUD. (originally was EE Timing Hack but required since r4821) SLES-51017: name: "Scooby-Doo! and The Night of 100 Frights" region: "PAL-E" @@ -9537,8 +9517,6 @@ SLES-51372: compat: 5 clampModes: vuClampMode: 3 # Fixes minor SPS on characters. - gameFixes: - - GIFFIFOHack SLES-51374: name: "RoboCop" region: "PAL-M5" @@ -10409,8 +10387,6 @@ SLES-51877: SLES-51879: name: "Hot Wheels World Race" region: "PAL-E" - gameFixes: - - GIFFIFOHack SLES-51881: name: "Mercedes Bens World Racing" region: "PAL-F-G" @@ -10649,8 +10625,6 @@ SLES-51989: compat: 5 clampModes: vuClampMode: 3 # Fixes minor SPS on characters. - gameFixes: - - GIFFIFOHack SLES-51991: name: "Dance UK" region: "PAL-E" @@ -10726,8 +10700,6 @@ SLES-52026: compat: 5 clampModes: vuClampMode: 3 # Fixes minor SPS on characters. - gameFixes: - - GIFFIFOHack SLES-52028: name: "Junior Sports Basketball" region: "PAL-M5" @@ -14518,7 +14490,6 @@ SLES-53904: name: "DT Racer" region: "PAL-M5" gameFixes: - - GIFFIFOHack # Fixes corrupted graphics in the menus. - VUKickstartHack # Fixes TLB misses and collision bugs. SLES-53906: name: "50cent - Bulletproof" @@ -14668,8 +14639,6 @@ SLES-53979: SLES-53982: name: "Fight Night Round 3" region: "PAL-E-F" - gameFixes: - - GIFFIFOHack # Fixes corrupt textures. SLES-53984: name: "Ice Age 2 - The Meltdown" region: "PAL-M6" @@ -15533,8 +15502,6 @@ SLES-54396: SLES-54400: name: "SpongeBob SquarePants - Creature from the Krusty Krab" region: "PAL-M7" - gameFixes: - - GIFFIFOHack # Fixes bad graphics. SLES-54402: name: "Need for Speed - Carbon [Collector's Edition]" region: "PAL-F" @@ -16803,8 +16770,6 @@ SLES-54995: name: "Puzzle Quest - Challenge of the Warlords" region: "PAL-M5" compat: 5 - gameFixes: - - GIFFIFOHack # Fixes flickering black and white sprites. SLES-54996: name: "Golden Compass, The" region: "PAL-M5" @@ -17669,8 +17634,6 @@ SLES-55443: compat: 5 roundModes: eeRoundMode: 0 # Fixes jump issue. - gameFixes: - - GIFFIFOHack # Fixes flickering sprites. SLES-55444: name: "Ar tonelico II: Melody of Metafalica" region: "PAL-E" @@ -17876,8 +17839,6 @@ SLES-55576: SLES-55577: name: "DJ Hero" region: "PAL-M5" - gameFixes: - - GIFFIFOHack SLES-55578: name: "Band Hero" region: "PAL-M5" @@ -18908,8 +18869,6 @@ SLPM-20436: SLPM-55005: name: "Mana Khemia 2: Ochita Gakuen to Renkinjutsushi Tachi" region: "NTSC-J" - gameFixes: - - GIFFIFOHack # Fixes flickering sprites. SLPM-55008: name: "Sengoku Basara X" region: "NTSC-J" @@ -18954,8 +18913,6 @@ SLPM-55110: SLPM-55114: name: "Mana Khemia 2: Ochita Gakuen to Renkinjutsushi Tachi" region: "NTSC-J" - gameFixes: - - GIFFIFOHack # Fixes flickering sprites. SLPM-55118: name: "Galaxy Angel II - Eigou Kaiki no Koku [Disc1of2]" region: "NTSC-J" @@ -26303,8 +26260,6 @@ SLPM-66693: SLPM-66694: name: "Spongebob" region: "NTSC-J" - gameFixes: - - GIFFIFOHack # Fixes bad graphics. SLPM-66695: name: "Kono Aozora ni Yakusoku o - Melody of the Sun and Sea" region: "NTSC-J" @@ -33407,8 +33362,6 @@ SLUS-20360: name: "Blade II" region: "NTSC-U" compat: 5 - gameFixes: - - GIFFIFOHack # Fixes flickering HUD. (originally was EE Timing Hack but required since r4821) SLUS-20361: name: "Rally Fusion - Race of Champions" region: "NTSC-U" @@ -34666,8 +34619,6 @@ SLUS-20647: compat: 5 clampModes: vuClampMode: 3 # Fixes minor SPS on characters. - gameFixes: - - GIFFIFOHack SLUS-20648: name: "NBA Jam 2004" region: "NTSC-U" @@ -35018,8 +34969,6 @@ SLUS-20737: name: "Hot Wheels - World Race" region: "NTSC-U" compat: 5 - gameFixes: - - GIFFIFOHack SLUS-20738: name: "Van Helsing" region: "NTSC-U" @@ -36564,7 +36513,6 @@ SLUS-21095: region: "NTSC-U" compat: 5 gameFixes: - - GIFFIFOHack # Fixes corrupted graphics in the menus. - VUKickstartHack # Fixes TLB misses and collision bugs. SLUS-21096: name: "Ape Escape - Pumped & Primed" @@ -37880,8 +37828,6 @@ SLUS-21383: name: "Fight Night - Round 3" region: "NTSC-U" compat: 5 - gameFixes: - - GIFFIFOHack # Fixes corrupt textures. SLUS-21384: name: "Cabela's Alaskan Adventures" region: "NTSC-U" @@ -37917,8 +37863,6 @@ SLUS-21391: name: "SpongeBob SquarePants - Creature from the Krusty Krab" region: "NTSC-U" compat: 5 - gameFixes: - - GIFFIFOHack # Fixes bad graphics. SLUS-21392: name: "Shrek Smash and Crash" region: "NTSC-U" @@ -39083,8 +39027,6 @@ SLUS-21692: name: "Puzzle Quest - Challenge of the Warlords" region: "NTSC-U" compat: 5 - gameFixes: - - GIFFIFOHack # Fixes flickering black and white sprites. SLUS-21693: name: "7 Wonders of the Ancient World" region: "NTSC-U" @@ -39271,8 +39213,6 @@ SLUS-21735: compat: 5 roundModes: eeRoundMode: 0 # Fixes jump issue. - gameFixes: - - GIFFIFOHack # Fixes flickering sprites. SLUS-21736: name: "Wall-E" region: "NTSC-U" @@ -39878,8 +39818,6 @@ SLUS-21890: name: "Mana Khemia 2: Fall Of Alchemy" region: "NTSC-U" compat: 5 - gameFixes: - - GIFFIFOHack # Fixes flickering sprites. SLUS-21891: name: "G-Force" region: "NTSC-U" @@ -39952,8 +39890,6 @@ SLUS-21908: SLUS-21909: name: "DJ Hero" region: "NTSC-U" - gameFixes: - - GIFFIFOHack SLUS-21910: name: "Marvel Super Hero Squad" region: "NTSC-U" diff --git a/pcsx2/FiFo.cpp b/pcsx2/FiFo.cpp index 14b4836fdf..39aa782ac6 100644 --- a/pcsx2/FiFo.cpp +++ b/pcsx2/FiFo.cpp @@ -125,10 +125,10 @@ void __fastcall WriteFIFO_VIF1(const mem128_t *value) void __fastcall WriteFIFO_GIF(const mem128_t *value) { GUNIT_LOG("WriteFIFO_GIF()"); - if (CHECK_GIFFIFOHACK) { - gif_fifo.write((u32*)value, 1); - - gif_fifo.read(true); + if ((!gifUnit.CanDoPath3() || gif_fifo.fifoSize > 0)) { + //DevCon.Warning("GIF FIFO HW Write"); + gif_fifo.write_fifo((u32*)value, 1); + gif_fifo.read_fifo(); } else { gifUnit.TransferGSPacketData(GIF_TRANS_FIFO, (u8*)value, 16); diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index c5d83f1dc5..e987ad5d7e 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -57,12 +57,24 @@ static __fi void CalculateFIFOCSR() { } } + +bool CheckPaths() { + // Can't do Path 3, so try dma again later... + if (!gifUnit.CanDoPath3()) { + if (!gifUnit.Path3Masked()) + { + //DevCon.Warning("Path3 stalled APATH %x PSE %x DIR %x Signal %x", gifRegs.stat.APATH, gifRegs.stat.PSE, gifRegs.stat.DIR, gifUnit.gsSIGNAL.queued); + GifDMAInt(128); + } + return false; + } + return true; +} + void GIF_Fifo::init() { - readpos = 0; - writepos = 0; memzero(data); - memzero(readdata); + fifoSize = 0; gifRegs.stat.FQC = 0; CSRreg.FIFO = CSR_FIFO_EMPTY; gif.gifstate = GIF_STATE_READY; @@ -71,73 +83,81 @@ void GIF_Fifo::init() gif.gscycles = 0; gif.prevcycles = 0; gif.mfifocycles = 0; - gif.gifqwc = 0; } -int GIF_Fifo::write(u32* pMem, int size) +int GIF_Fifo::write_fifo(u32* pMem, int size) { - if (gifRegs.stat.FQC == 16) { - //DevCon.Warning("Full"); + if (fifoSize == 16) { + //GIF_LOG("GIF FIFO Full"); return 0; } - int transsize; - int firsttrans = std::min(size, 16 - (int)gifRegs.stat.FQC); - gifRegs.stat.FQC += firsttrans; - transsize = firsttrans; - - - while (transsize-- > 0) - { - CopyQWC(&data[writepos], pMem); - writepos = (writepos + 4) & 63; - pMem += 4; - } - + int transferSize = std::min(size, 16 - (int)fifoSize); + + 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; + gifRegs.stat.FQC = fifoSize; CalculateFIFOCSR(); - return firsttrans; + + return transferSize; } -int GIF_Fifo::read(bool calledFromDMA) +int GIF_Fifo::read_fifo() { - - if (!gifUnit.CanDoPath3() || gifRegs.stat.FQC == 0) + if (!fifoSize || !gifUnit.CanDoPath3()) { - //DevCon.Warning("Path3 not masked"); - if (gifch.chcr.STR == true && !(cpuRegs.interrupt & (1 << DMAC_GIF)) && calledFromDMA == false) { - GifDMAInt(16); + gifRegs.stat.FQC = fifoSize; + CalculateFIFOCSR(); + if (fifoSize) + { + GIF_LOG("GIF FIFO Can't read, GIF paused/busy. Waiting"); + GifDMAInt(128); } - //DevCon.Warning("P3 Masked"); return 0; } - int valueWritePos = 0; - uint sizeRead; - uint fifoSize = gifRegs.stat.FQC; - int oldReadPos = readpos; + int readpos = 0; + int sizeRead = 0; - while (gifRegs.stat.FQC) { - CopyQWC(&readdata[valueWritePos], &data[readpos]); - readpos = (readpos + 4) & 63; - valueWritePos = (valueWritePos + 4) & 63; - gifRegs.stat.FQC--; - } + sizeRead = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, (u8*)&data, fifoSize * 16) / 16; //returns the size actually read - sizeRead = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, (u8*)&readdata[0], fifoSize * 16) / 16; //returns the size actually read + GIF_LOG("GIF FIFO Read %d QW from FIFO Current Size %d", sizeRead, fifoSize); if (sizeRead < fifoSize) { - readpos = (oldReadPos + (sizeRead * 4)) & 63; //if we read less than what was in the fifo, move the read position back - gifRegs.stat.FQC = fifoSize - sizeRead; + if (sizeRead > 0) + { + int copyAmount = fifoSize - sizeRead; + readpos = sizeRead * 4; + + for (int i = 0; i < copyAmount; i++) + CopyQWC(&data[i * 4], &data[readpos + (i * 4)]); + + fifoSize = copyAmount; + + GIF_LOG("GIF FIFO rearranged to now only contain %d QW", fifoSize); + } + else + { + GIF_LOG("GIF FIFO not read"); + } } - - if (calledFromDMA == false) { - GifDMAInt(sizeRead * BIAS); + else + { + GIF_LOG("GIF FIFO now empty"); + fifoSize = 0; } + gifRegs.stat.FQC = fifoSize; CalculateFIFOCSR(); - return gifRegs.stat.FQC; + + return sizeRead; } void incGifChAddr(u32 qwc) { @@ -161,7 +181,7 @@ __fi void gifCheckPathStatus() { } } - //Required for Path3 Masking timing! + // Required for Path3 Masking timing! if (gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT) gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE; } @@ -175,143 +195,132 @@ __fi void gifInterrupt() { if(vif1Regs.stat.VGW) { - //Check if VIF is in a cycle or is currently "idle" waiting for GIF to come back. + // Check if VIF is in a cycle or is currently "idle" waiting for GIF to come back. if(!(cpuRegs.interrupt & (1< 0 || gif.gspath3done == false) { - if (!gifUnit.Path3Masked()) { - GifDMAInt(128); - } - return; - } - } - } } - if (gifUnit.gsSIGNAL.queued) { GIF_LOG("Path 3 Paused"); GifDMAInt(128); - return; + if(gif_fifo.fifoSize == 16) + 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 there's something in the FIFO and we can do PATH3, empty the FIFO. + if (gif_fifo.fifoSize > 0) { - if (vif1Regs.stat.VGW) + const int readSize = gif_fifo.read_fifo(); + + if (readSize) + GifDMAInt(readSize * BIAS); + + 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) { - //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 (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.qwc > 0) || (!gif.gspath3done)) && gif_fifo.fifoSize) + return; } - + if (!(gifch.chcr.STR)) return; if ((gifch.qwc > 0) || (!gif.gspath3done)) { if (!dmacRegs.ctrl.DMAE) { Console.Warning("gs dma masked, re-scheduling..."); - // re-raise the int shortly in the future + // Re-raise the int shortly in the future GifDMAInt( 64 ); return; } GIFdma(); - + return; } - - - if (!CHECK_GIFFIFOHACK) - { - gifRegs.stat.FQC = 0; - clearFIFOstuff(false); - } gif.gscycles = 0; gifch.chcr.STR = false; - + gifRegs.stat.FQC = gif_fifo.fifoSize; + CalculateFIFOCSR(); hwDmacIrq(DMAC_GIF); + + if(gif_fifo.fifoSize) + GifDMAInt(8 * BIAS); GIF_LOG("GIF DMA End QWC in fifo %x APATH = %x OPH = %x state = %x", gifRegs.stat.FQC, gifRegs.stat.APATH, gifRegs.stat.OPH, gifUnit.gifPath[GIF_PATH_3].state); } static u32 WRITERING_DMA(u32 *pMem, u32 qwc) { + u32 originalQwc = qwc; + if (gifRegs.stat.IMT) { - //Splitting by 8qw can be really slow, so on bigger packets be less picky. - //Some games like Wallace & Gromit like smaller packets to be split correctly, hopefully with little impact on speed. - //68 works for W&G but 128 is more of a safe point. + // Splitting by 8qw can be really slow, so on bigger packets be less picky. + // Some games like Wallace & Gromit like smaller packets to be split correctly, hopefully with little impact on speed. + // 68 works for W&G but 128 is more of a safe point. if (qwc > 128) qwc = std::min(qwc, 1024u); else qwc = std::min(qwc, 8u); } + uint size; - if (CHECK_GIFFIFOHACK) { - size = gif_fifo.write(pMem, qwc); - } - else { - size = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, (u8*)pMem, qwc * 16) / 16; + + if (CheckPaths() == false || ((qwc < 8 || gif_fifo.fifoSize > 0) && CHECK_GIFFIFOHACK)) + { + if (gif_fifo.fifoSize < 16) + { + size = gif_fifo.write_fifo((u32*)pMem, originalQwc); // Use original QWC here, the intermediate mode is for the GIF unit, not DMA + incGifChAddr(size); + return size; + } + return 4; // Arbitrary value, probably won't schedule a DMA anwyay since the FIFO is full and GIF is paused } + + size = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, (u8*)pMem, qwc * 16) / 16; incGifChAddr(size); return size; } -int _GIFchain() -{ - tDMA_TAG *pMem; +static __fi void GIFchain() { + tDMA_TAG* pMem; pMem = dmaGetAddr(gifch.madr, false); if (pMem == NULL) { - //must increment madr and clear qwc, else it loops + // Must increment madr and clear qwc, else it loops gifch.madr += gifch.qwc * 16; gifch.qwc = 0; Console.Warning("Hackfix - NULL GIFchain"); - return -1; + return; } - return WRITERING_DMA((u32*)pMem, gifch.qwc); -} + int transferred= WRITERING_DMA((u32*)pMem, gifch.qwc); + gif.gscycles += transferred * BIAS; -static __fi void GIFchain() { - // qwc check now done outside this function - // Voodoocycles - // >> 2 so Drakan and Tekken 5 don't mess up in some PATH3 transfer. Cycles to interrupt were getting huge.. - /*if (gifch.qwc)*/ - gif.gscycles+= _GIFchain() * BIAS; /* guessing */ + if (!gifUnit.Path3Masked() || (gif_fifo.fifoSize < 16)) + GifDMAInt(gif.gscycles); } static __fi bool checkTieBit(tDMA_TAG* &ptag) @@ -326,12 +335,12 @@ static __fi bool checkTieBit(tDMA_TAG* &ptag) static __fi tDMA_TAG* ReadTag() { - tDMA_TAG* ptag = dmaGetAddr(gifch.tadr, false); //Set memory pointer to TADR + tDMA_TAG* ptag = dmaGetAddr(gifch.tadr, false); // Set memory pointer to TADR if (!(gifch.transfer("Gif", ptag))) return NULL; - gifch.madr = ptag[1]._u32; //MADR = ADDR field + SPR - gif.gscycles += 2; // Add 1 cycles from the QW read for the tag + gifch.madr = ptag[1]._u32; // MADR = ADDR field + SPR + gif.gscycles += 2; // Add 1 cycles from the QW read for the tag gif.gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID); return ptag; @@ -339,7 +348,7 @@ static __fi tDMA_TAG* ReadTag() static __fi tDMA_TAG* ReadTag2() { - tDMA_TAG* ptag = dmaGetAddr(gifch.tadr, false); //Set memory pointer to TADR + tDMA_TAG* ptag = dmaGetAddr(gifch.tadr, false); // Set memory pointer to TADR gifch.unsafeTransfer(ptag); gifch.madr = ptag[1]._u32; @@ -348,28 +357,13 @@ static __fi tDMA_TAG* ReadTag2() return ptag; } -bool CheckPaths() { - // Can't do Path 3, so try dma again later... - if (!CHECK_GIFFIFOHACK) { - if (!gifUnit.CanDoPath3()) { - if (!gifUnit.Path3Masked()) - { - GIF_LOG("Path3 stalled"); - GifDMAInt(128); - } - return false; - } - } - return true; -} - void GIFdma() { while (gifch.qwc > 0 || !gif.gspath3done) { tDMA_TAG* ptag; gif.gscycles = gif.prevcycles; - if (gifRegs.ctrl.PSE) { // temporarily stop + if (gifRegs.ctrl.PSE) { // Temporarily stop Console.WriteLn("Gif dma temp paused? (non MFIFO GIF)"); GifDMAInt(16); return; @@ -392,7 +386,9 @@ void GIFdma() if (ptag == NULL) return; //DevCon.Warning("GIF Reading Tag MSK = %x", vif1Regs.mskpath3); GIF_LOG("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); - if (!CHECK_GIFFIFOHACK)gifRegs.stat.FQC = std::min((u32)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] + gifRegs.stat.FQC = std::min((u32)0x10, gifch.qwc); + CalculateFIFOCSR(); + if (dmacRegs.ctrl.STD == STD_GIF) { // there are still bugs, need to also check if gifch.madr +16*qwc >= stadr, if not, stall @@ -418,48 +414,28 @@ void GIFdma() Console.WriteLn("GIF DMA Stall in Normal mode not implemented - Report which game to PCSX2 Team"); } - - if (!CHECK_GIFFIFOHACK) { - gifRegs.stat.FQC = std::min((u32)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3] - clearFIFOstuff(true); - } - // Transfer Dn_QWC from Dn_MADR to GIF if (gifch.qwc > 0) // Normal Mode { - if (CheckPaths() == false) return; - - GIFchain(); //Transfers the data set by the switch - //if (gscycles < 8) DevCon.Warning("GSCycles = %d", gscycles); - GifDMAInt(gif.gscycles); + GIFchain(); // Transfers the data set by the switch return; } } - //QWC == 0 && gspath3done == true - End of DMA gif.prevcycles = 0; - //if (gscycles < 8) DevCon.Warning("1 GSCycles = %d", gscycles); GifDMAInt(16); } void dmaGIF() { - //We used to add wait time for the buffer to fill here, fixing some timing problems in path 3 masking - //It takes the time of 24 QW for the BUS to become ready - The Punisher And Streetball - //DevCon.Warning("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gifch.chcr._u32, gifch.madr, gifch.qwc, gifch.tadr, gifch.asr0, gifch.asr1); + // DevCon.Warning("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gifch.chcr._u32, gifch.madr, gifch.qwc, gifch.tadr, gifch.asr0, gifch.asr1); gif.gspath3done = false; // For some reason this doesn't clear? So when the system starts the thread, we will clear it :) - if (!CHECK_GIFFIFOHACK) { - gifRegs.stat.FQC |= 0x10; // hack ;) - clearFIFOstuff(true); - } - - if (gifch.chcr.MOD == NORMAL_MODE) { //Else it really is a normal transfer and we want to quit, else it gets confused with chains + if (gifch.chcr.MOD == NORMAL_MODE) { // Else it really is a normal transfer and we want to quit, else it gets confused with chains gif.gspath3done = true; } - if(gifch.chcr.MOD == CHAIN_MODE && gifch.qwc > 0) { //DevCon.Warning(L"GIF QWC on Chain " + gifch.chcr.desc()); if ((gifch.chcr.tag().ID == TAG_REFE) || (gifch.chcr.tag().ID == TAG_END) || (gifch.chcr.tag().IRQ && gifch.chcr.TIE)) { @@ -475,19 +451,19 @@ static u32 QWCinGIFMFIFO(u32 DrainADDR) u32 ret; SPR_LOG("GIF MFIFO Requesting %x QWC from the MFIFO Base %x, SPR MADR %x Drain %x", gifch.qwc, dmacRegs.rbor.ADDR, spr0ch.madr, DrainADDR); - //Calculate what we have in the fifo. + // Calculate what we have in the fifo. if (DrainADDR <= spr0ch.madr) { - //Drain is below the write position, calculate the difference between them + // Drain is below the write position, calculate the difference between them ret = (spr0ch.madr - DrainADDR) >> 4; } else { u32 limit = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16; - //Drain is higher than SPR so it has looped round, - //calculate from base to the SPR tag addr and what is left in the top of the ring + // Drain is higher than SPR so it has looped round, + // calculate from base to the SPR tag addr and what is left in the top of the ring ret = ((spr0ch.madr - dmacRegs.rbor.ADDR) + (limit - DrainADDR)) >> 4; } if (ret == 0) - gif.gifstate |= GIF_STATE_EMPTY; + gif.gifstate = GIF_STATE_EMPTY; SPR_LOG("%x Available of the %x requested", ret, gifch.qwc); return ret; @@ -496,9 +472,9 @@ static u32 QWCinGIFMFIFO(u32 DrainADDR) static __fi bool mfifoGIFrbTransfer() { u32 qwc = std::min(QWCinGIFMFIFO(gifch.madr), gifch.qwc); - if (qwc == 0) { - DevCon.Warning("GIF FIFO EMPTY before transfer (how?)"); - } + + if (qwc == 0) // Either gifch.qwc is 0 (shouldn't get here) or the FIFO is empty. + return true; u8* src = (u8*)PSM(gifch.madr); if (src == NULL) return false; @@ -508,84 +484,76 @@ static __fi bool mfifoGIFrbTransfer() u32 firstTransQWC = needWrap ? MFIFOUntilEnd : qwc; u32 transferred; - if (!CHECK_GIFFIFOHACK) - { - transferred = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, src, firstTransQWC * 16) / 16; // First part - } - else - { - transferred = gif_fifo.write((u32*)src, firstTransQWC); - } - - incGifChAddr(transferred); + transferred = WRITERING_DMA((u32*)src, firstTransQWC); // First part gifch.madr = dmacRegs.rbor.ADDR + (gifch.madr & dmacRegs.rbsr.RMSK); gifch.tadr = dmacRegs.rbor.ADDR + (gifch.tadr & dmacRegs.rbsr.RMSK); - if (needWrap && transferred == MFIFOUntilEnd) - { // Need to do second transfer to wrap around + if (needWrap && transferred == MFIFOUntilEnd) + { + // Need to do second transfer to wrap around u32 transferred2; uint secondTransQWC = qwc - MFIFOUntilEnd; src = (u8*)PSM(dmacRegs.rbor.ADDR); if (src == NULL) return false; - if (!CHECK_GIFFIFOHACK) { - transferred2 = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, src, secondTransQWC * 16) / 16; // Second part - } - else { - transferred2 = gif_fifo.write((u32*)src, secondTransQWC); - } + transferred2 = WRITERING_DMA((u32*)src, secondTransQWC); // Second part - incGifChAddr(transferred2); - gif.mfifocycles += (transferred2 + transferred) * 2; // guessing - } - else - { - gif.mfifocycles += transferred * 2; // guessing + gif.mfifocycles += (transferred2 + transferred) * 2; } + else + gif.mfifocycles += transferred * 2; return true; } -static __fi bool mfifoGIFchain() +static __fi void mfifoGIFchain() { - /* Is QWC = 0? if so there is nothing to transfer */ - if (gifch.qwc == 0) return true; + // Is QWC = 0? if so there is nothing to transfer + if (gifch.qwc == 0) + { + gif.mfifocycles += 4; + return; + } if ((gifch.madr & ~dmacRegs.rbsr.RMSK) == dmacRegs.rbor.ADDR) { - bool ret = true; - if (QWCinGIFMFIFO(gifch.madr) == 0) { SPR_LOG("GIF FIFO EMPTY before transfer"); gif.gifstate = GIF_STATE_EMPTY; gif.mfifocycles += 4; - if (CHECK_GIFFIFOHACK) - GifDMAInt(128); - return true; + return; } - if (!mfifoGIFrbTransfer()) ret = false; + if (!mfifoGIFrbTransfer()) + { + gif.mfifocycles += 4; + gifch.qwc = 0; + gif.gspath3done = true; + return; + } - //This ends up being done more often but it's safer :P - //Make sure we wrap the addresses, dont want it being stuck outside the ring when reading from the ring! + // This ends up being done more often but it's safer :P + // Make sure we wrap the addresses, dont want it being stuck outside the ring when reading from the ring! gifch.madr = dmacRegs.rbor.ADDR + (gifch.madr & dmacRegs.rbsr.RMSK); gifch.tadr = gifch.madr; - - return ret; } else { - int mfifoqwc; SPR_LOG("Non-MFIFO Location transfer doing %x Total QWC", gifch.qwc); tDMA_TAG *pMem = dmaGetAddr(gifch.madr, false); - if (pMem == NULL) return false; + if (pMem == NULL) + { + gif.mfifocycles += 4; + gifch.qwc = 0; + gif.gspath3done = true; + return; + } - mfifoqwc = WRITERING_DMA((u32*)pMem, gifch.qwc); - gif.mfifocycles += (mfifoqwc) * 2; /* guessing */ + gif.mfifocycles += WRITERING_DMA((u32*)pMem, gifch.qwc) * 2; } - return true; + return; } static u32 qwctag(u32 mask) { @@ -595,25 +563,25 @@ static u32 qwctag(u32 mask) { void mfifoGifMaskMem(int id) { switch (id) { - //These five transfer data following the tag, need to check its within the buffer (Front Mission 4) + // These five transfer data following the tag, need to check its within the buffer (Front Mission 4) case TAG_CNT: case TAG_NEXT: case TAG_CALL: case TAG_RET: case TAG_END: - if(gifch.madr < dmacRegs.rbor.ADDR) //probably not needed but we will check anyway. + if(gifch.madr < dmacRegs.rbor.ADDR) // Probably not needed but we will check anyway. { SPR_LOG("GIF MFIFO MADR below bottom of ring buffer, wrapping GIF MADR = %x Ring Bottom %x", gifch.madr, dmacRegs.rbor.ADDR); gifch.madr = qwctag(gifch.madr); } else - if(gifch.madr > (dmacRegs.rbor.ADDR + (u32)dmacRegs.rbsr.RMSK)) //Usual scenario is the tag is near the end (Front Mission 4) + if(gifch.madr > (dmacRegs.rbor.ADDR + (u32)dmacRegs.rbsr.RMSK)) // Usual scenario is the tag is near the end (Front Mission 4) { SPR_LOG("GIF MFIFO MADR outside top of ring buffer, wrapping GIF MADR = %x Ring Top %x", gifch.madr, (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK)+16); gifch.madr = qwctag(gifch.madr); } break; default: - //Do nothing as the MADR could be outside + // Do nothing as the MADR could be outside break; } } @@ -622,9 +590,8 @@ void mfifoGIFtransfer() { tDMA_TAG *ptag; gif.mfifocycles = 0; - - if (gifRegs.ctrl.PSE) { // temporarily stop + if (gifRegs.ctrl.PSE) { // Temporarily stop Console.WriteLn("Gif dma temp paused?"); CPU_INT(DMAC_MFIFO_GIF, 16); return; @@ -637,8 +604,6 @@ void mfifoGIFtransfer() SPR_LOG("GIF FIFO EMPTY before tag read"); gif.gifstate = GIF_STATE_EMPTY; GifDMAInt(4); - if (CHECK_GIFFIFOHACK) - GifDMAInt(128); return; } @@ -646,6 +611,9 @@ void mfifoGIFtransfer() gifch.unsafeTransfer(ptag); gifch.madr = ptag[1]._u32; + gifRegs.stat.FQC = std::min((u32)0x10, gifch.qwc); + CalculateFIFOCSR(); + gif.mfifocycles += 2; GIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x", @@ -667,12 +635,8 @@ void mfifoGIFtransfer() } } - if (!mfifoGIFchain()) { - Console.WriteLn("mfifoGIF dmaChain error size=%d, madr=%lx, tadr=%lx", gifch.qwc, gifch.madr, gifch.tadr); - gif.gspath3done = true; - gifch.qwc = 0; //Sanity - } - + mfifoGIFchain(); + GifDMAInt(std::max(gif.mfifocycles, (u32)4)); SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gifch.chcr._u32, gifch.madr, gifch.tadr); @@ -680,7 +644,7 @@ void mfifoGIFtransfer() void gifMFIFOInterrupt() { - GIF_LOG("gifMFIFOInterrupt"); + //DevCon.Warning("gifMFIFOInterrupt"); gif.mfifocycles = 0; if (dmacRegs.ctrl.MFD != MFD_GIF) { // GIF not in MFIFO anymore, come out. @@ -695,19 +659,18 @@ void gifMFIFOInterrupt() { if (vif1Regs.stat.VGW) { - //Check if VIF is in a cycle or is currently "idle" waiting for GIF to come back. + // 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 + // 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 (gifUnit.gsSIGNAL.queued) { @@ -715,40 +678,19 @@ void gifMFIFOInterrupt() return; } - if (CHECK_GIFFIFOHACK) - { - if (int amtRead = gif_fifo.read(true)) - { - if (!gifUnit.Path3Masked() || gifRegs.stat.FQC < 16) { - GifDMAInt(amtRead * BIAS); - return; - } - } - else { - if (!gifUnit.CanDoPath3() && gifRegs.stat.FQC == 16) - { - if (gifch.qwc > 0 || gif.gspath3done == false) { - if (!gifUnit.Path3Masked()) { - GifDMAInt(128); - } - return; - } - } - } - } 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. + // 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 + // 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); } @@ -756,41 +698,58 @@ void gifMFIFOInterrupt() } } - if (!gifch.chcr.STR) { - Console.WriteLn("WTF GIFMFIFO"); - cpuRegs.interrupt &= ~(1 << 11); - return; + // If there's something in the FIFO and we can do PATH3, empty the FIFO. + if (gif_fifo.fifoSize > 0) + { + const int readSize = gif_fifo.read_fifo(); + + if (readSize) + GifDMAInt(readSize * BIAS); + + 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.qwc > 0) || (!gif.gspath3done)) && gif_fifo.fifoSize) + return; } - if ((gif.gifstate & GIF_STATE_EMPTY)) { - FireMFIFOEmpty(); - if (CHECK_GIFFIFOHACK) - GifDMAInt(128); + if (!gifch.chcr.STR) return; + + if (spr0ch.madr == gifch.tadr || (gif.gifstate & GIF_STATE_EMPTY)) { + gif.gifstate = GIF_STATE_EMPTY; // In case of madr = tadr we need to set it + FireMFIFOEmpty(); + + if (gifch.qwc > 0 || !gif.gspath3done) + return; } if (gifch.qwc > 0 || !gif.gspath3done) { - if (!CheckPaths()) return; mfifoGIFtransfer(); return; } - if (!CHECK_GIFFIFOHACK) - { - gifRegs.stat.FQC = 0; - clearFIFOstuff(false); - } - - if (spr0ch.madr == gifch.tadr) { - FireMFIFOEmpty(); - } - gif.gscycles = 0; gifch.chcr.STR = false; gif.gifstate = GIF_STATE_READY; + gifRegs.stat.FQC = gif_fifo.fifoSize; + CalculateFIFOCSR(); hwDmacIrq(DMAC_GIF); + + if (gif_fifo.fifoSize) + GifDMAInt(8 * BIAS); DMA_LOG("GIF MFIFO DMA End"); } diff --git a/pcsx2/Gif.h b/pcsx2/Gif.h index 35d81927a2..0657416f05 100644 --- a/pcsx2/Gif.h +++ b/pcsx2/Gif.h @@ -80,11 +80,10 @@ extern __aligned16 gifStruct gif; struct GIF_Fifo { unsigned int data[64]; //16 QW FIFO - unsigned int readdata[64]; //16 QW Inline for reading - int readpos, writepos; + unsigned int fifoSize; - int write(u32* pMem, int size); - int read(bool calledFromDMA = false); + int write_fifo(u32* pMem, int size); + int read_fifo(); void init(); }; diff --git a/pcsx2/Gif_Unit.h b/pcsx2/Gif_Unit.h index e0ebc8f4d6..25653c9582 100644 --- a/pcsx2/Gif_Unit.h +++ b/pcsx2/Gif_Unit.h @@ -538,6 +538,7 @@ struct Gif_Unit gifRegs.stat.reset(); gifRegs.ctrl.reset(); gifRegs.mode.reset(); + gif_fifo.init(); } // Adds a finished GS Packet to the MTGS ring buffer diff --git a/pcsx2/Hw.cpp b/pcsx2/Hw.cpp index 6ec0fe1f0d..a30ca438ea 100644 --- a/pcsx2/Hw.cpp +++ b/pcsx2/Hw.cpp @@ -216,12 +216,6 @@ __ri void hwMFIFOResume(u32 transferred) { CPU_INT(DMAC_MFIFO_GIF, transferred * BIAS); gif.gifstate = GIF_STATE_READY; } - if (!CHECK_GIFFIFOHACK) - { - gifRegs.stat.FQC = 16; - //GIF FIFO - clearFIFOstuff(true); - } break; } default: diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index 0f2a459fd6..d7c88c15bf 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -111,9 +111,8 @@ void __fastcall _hwWrite32( u32 mem, u32 value ) icase(GIF_MODE) { gifRegs.mode.write(value); - //Need to kickstart the GIF if the M3R mask comes off - if (gifRegs.stat.M3R == 1 && gifRegs.mode.M3R == 0 && gifch.chcr.STR) + if (gifRegs.stat.M3R == 1 && gifRegs.mode.M3R == 0 && (gifch.chcr.STR || gif_fifo.fifoSize)) { DevCon.Warning("GIF Mode cancelling P3 Disable"); CPU_INT(DMAC_GIF, 8); diff --git a/pcsx2/SPR.cpp b/pcsx2/SPR.cpp index c568669090..0b516ffe09 100644 --- a/pcsx2/SPR.cpp +++ b/pcsx2/SPR.cpp @@ -313,12 +313,13 @@ void SPRFROMinterrupt() spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK); //Console.WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr); hwMFIFOResume(mfifotransferred); - mfifotransferred = 0; break; } default: break; } + + mfifotransferred = 0; } return; diff --git a/pcsx2/SaveState.h b/pcsx2/SaveState.h index d1c0302bff..5a63fec07d 100644 --- a/pcsx2/SaveState.h +++ b/pcsx2/SaveState.h @@ -31,7 +31,7 @@ enum class FreezeAction // the lower 16 bit value. IF the change is breaking of all compatibility with old // states, increment the upper 16 bit value, and clear the lower 16 bits to 0. -static const u32 g_SaveVersion = (0x9A21 << 16) | 0x0000; +static const u32 g_SaveVersion = (0x9A22 << 16) | 0x0000; // the freezing data between submodules and core // an interesting thing to note is that this dates back from before plugin diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index a6eebfc8de..9947993cb7 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -222,14 +222,14 @@ __fi void vif1FBRST(u32 value) { case MFD_VIF1: //Console.WriteLn("MFIFO Stall"); //MFIFO active and not empty - if(vif1ch.chcr.STR) CPU_INT(DMAC_MFIFO_VIF, 0); + if(vif1ch.chcr.STR && !vif1Regs.stat.test(VIF1_STAT_FDR)) CPU_INT(DMAC_MFIFO_VIF, 0); break; case NO_MFD: case MFD_RESERVED: case MFD_GIF: // Wonder if this should be with VIF? // Gets the timing right - Flatout - if(vif1ch.chcr.STR) CPU_INT(DMAC_VIF1, 0); + if(vif1ch.chcr.STR && !vif1Regs.stat.test(VIF1_STAT_FDR)) CPU_INT(DMAC_VIF1, 0); break; } @@ -256,6 +256,8 @@ __fi void vif1STAT(u32 value) { //position, as we clear it and set it to the end well before the interrupt, the game assumes it's finished, //then proceeds to reverse the dma before we have even done it ourselves. So lets just make sure VIF is ready :) if (vif1ch.qwc > 0 || isStalled == false){ + vif1ch.qwc = 0; + hwDmacIrq(DMAC_VIF1); vif1ch.chcr.STR = false; cpuRegs.interrupt &= ~((1 << DMAC_VIF1) | (1 << DMAC_MFIFO_VIF)); } diff --git a/pcsx2/Vif1_Dma.cpp b/pcsx2/Vif1_Dma.cpp index dfc5859833..dd2d0248b6 100644 --- a/pcsx2/Vif1_Dma.cpp +++ b/pcsx2/Vif1_Dma.cpp @@ -288,7 +288,7 @@ __fi void vif1Interrupt() g_vif1Cycles = 0; - if( gifRegs.stat.APATH == 2 && gifUnit.gifPath[GIF_PATH_2].isDone()) + if( gifRegs.stat.APATH == 2 && gifUnit.gifPath[GIF_PATH_2].isDone()) { gifRegs.stat.APATH = 0; gifRegs.stat.OPH = 0; @@ -427,7 +427,7 @@ __fi void vif1Interrupt() vif1.irqoffset.enabled = false; if(vif1.queued_program) vifExecQueue(1); g_vif1Cycles = 0; - DMA_LOG("VIF1 DMA End"); + VIF_LOG("VIF1 DMA End"); hwDmacIrq(DMAC_VIF1); } diff --git a/pcsx2/Vif_Codes.cpp b/pcsx2/Vif_Codes.cpp index f389fa2c5e..fdde320f4d 100644 --- a/pcsx2/Vif_Codes.cpp +++ b/pcsx2/Vif_Codes.cpp @@ -422,14 +422,13 @@ vifOp(vifCode_MSCNT) { // ToDo: FixMe vifOp(vifCode_MskPath3) { vif1Only(); - pass1 { + pass1 { vif1Regs.mskpath3 = (vif1Regs.code >> 15) & 0x1; gifRegs.stat.M3P = (vif1Regs.code >> 15) & 0x1; GUNIT_LOG("Vif1 - MskPath3 [p3 = %s]", vif1Regs.mskpath3 ? "masked" : "enabled"); if(!vif1Regs.mskpath3) { - GUNIT_WARN("Path3 triggering!"); - if(CHECK_GIFFIFOHACK)gif_fifo.read(false); - else gifInterrupt(); + GUNIT_WARN("VIF MSKPATH3 off Path3 triggering!"); + gifInterrupt(); } vif1.cmd = 0; vif1.pass = 0; diff --git a/pcsx2/gui/Panels/GameFixesPanel.cpp b/pcsx2/gui/Panels/GameFixesPanel.cpp index 203dd07c58..ce441e6107 100644 --- a/pcsx2/gui/Panels/GameFixesPanel.cpp +++ b/pcsx2/gui/Panels/GameFixesPanel.cpp @@ -81,7 +81,7 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) wxEmptyString }, { - _("Enable the GIF FIFO (slower but needed for Hotwheels, Wallace and Gromit, DJ Hero)"), + _("Force GIF PATH3 transfers through FIFO (Fifa Street 2)"), wxEmptyString }, {