GIF: Implement GIF FIFO on GIF MFIFO mode.

-Removed some obsolete code
-Tiny optimisation for the gifUnit
-Fixed a tiny bug on GIF MFIFO
This commit is contained in:
refractionpcsx2 2016-05-13 23:45:14 +01:00 committed by Gregory Hainaut
parent 71601b88ff
commit 2734f53a79
6 changed files with 198 additions and 156 deletions

View File

@ -57,25 +57,11 @@ void gsReset()
static __fi void gsCSRwrite( const tGS_CSR& csr )
{
if (csr.RESET) {
#if USE_OLD_GIF == 1 // ...
// perform a soft reset -- which is a clearing of all GIFpaths -- and fall back to doing
// a full reset if the plugin doesn't support soft resets.
if (GSgifSoftReset != NULL) {
GIFPath_Clear( GIF_PATH_1 );
GIFPath_Clear( GIF_PATH_2 );
GIFPath_Clear( GIF_PATH_3 );
}
else GetMTGS().SendSimplePacket( GS_RINGTYPE_RESET, 0, 0, 0 );
SIGNAL_IMR_Pending = false;
#else
GUNIT_WARN("GUNIT_WARN: csr.RESET");
//Console.Warning( "csr.RESET" );
//gifUnit.Reset(true); // Don't think gif should be reset...
gifUnit.gsSIGNAL.queued = false;
GetMTGS().SendSimplePacket(GS_RINGTYPE_RESET, 0, 0, 0);
#endif
CSRreg.Reset();
GSIMR = 0x7F00; //This is bits 14-8 thats all that should be 1

View File

@ -33,8 +33,32 @@ static bool gifmfifoirq = false;
__aligned16 GIF_Fifo gif_fifo;
static __fi void GifDMAInt(int cycles) {
if (dmacRegs.ctrl.MFD == MFD_GIF) {
if (!(cpuRegs.interrupt & (1 << DMAC_MFIFO_GIF)) || cpuRegs.eCycle[DMAC_MFIFO_GIF] < (u32)cycles)
{
CPU_INT(DMAC_MFIFO_GIF, cycles);
}
} else if (!(cpuRegs.interrupt & (1 << DMAC_GIF)) || cpuRegs.eCycle[DMAC_GIF] < (u32)cycles)
{
CPU_INT(DMAC_GIF, cycles);
}
}
static __fi void clearFIFOstuff(bool full) {
CSRreg.FIFO = full ? CSR_FIFO_FULL : CSR_FIFO_EMPTY;
CSRreg.FIFO = full ? CSR_FIFO_FULL : CSR_FIFO_EMPTY;
}
//I suspect this is GS side which should really be handled by the GS plugin which also doesn't current have a fifo, but we can guess from our fifo
static __fi void CalculateFIFOCSR() {
if (gifRegs.stat.FQC >= 15) {
CSRreg.FIFO = CSR_FIFO_FULL;
}
else if (gifRegs.stat.FQC == 0) {
CSRreg.FIFO = CSR_FIFO_EMPTY;
}
else {
CSRreg.FIFO = CSR_FIFO_NORMAL;
}
}
void GIF_Fifo::init()
@ -50,6 +74,10 @@ void GIF_Fifo::init()
int GIF_Fifo::write(u32* pMem, int size)
{
if (gifRegs.stat.FQC == 16) {
//DevCon.Warning("Full");
return 0;
}
int transsize;
int firsttrans = std::min(size, 16 - (int)gifRegs.stat.FQC);
@ -64,32 +92,28 @@ int GIF_Fifo::write(u32* pMem, int size)
pMem += 4;
}
CalculateFIFOCSR();
return firsttrans;
}
int GIF_Fifo::read(bool calledFromDMA)
{
if (!gifUnit.CanDoPath3() || gifRegs.stat.FQC == 0)
{
//DevCon.Warning("Path3 not masked");
if (gifch.chcr.STR == true && !(cpuRegs.interrupt & (1 << DMAC_GIF)) && calledFromDMA == false) {
GifDMAInt(16);
}
//DevCon.Warning("P3 Masked");
return 0;
}
int valueWritePos = 0;
uint sizeRead;
uint fifoSize = gifRegs.stat.FQC;
int oldReadPos = readpos;
if (!gifUnit.CanDoPath3())
{
//DevCon.Warning("P3 Masked");
return 0;
}
if (gifRegs.stat.FQC == 0)
{
//If the GIF isn't stalled and it is waiting to go, fire it off (usually after a path3 mask)
if (gifch.chcr.STR == true && !(cpuRegs.interrupt & (1 << DMAC_GIF)) && calledFromDMA == false) {
CPU_INT(DMAC_GIF, 16);
}
return 0;
}
valueWritePos = 0;
while (gifRegs.stat.FQC) {
CopyQWC(&readdata[valueWritePos], &data[readpos]);
readpos = (readpos + 4) & 63;
@ -101,13 +125,14 @@ int GIF_Fifo::read(bool calledFromDMA)
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;
gifRegs.stat.FQC = fifoSize - sizeRead;
}
if (calledFromDMA == false) {
CPU_INT(DMAC_GIF, 16);
}
GifDMAInt(sizeRead * BIAS);
}
CalculateFIFOCSR();
return gifRegs.stat.FQC;
}
@ -121,6 +146,7 @@ void incGifChAddr(u32 qwc) {
}
__fi void gifCheckPathStatus() {
if (gifRegs.stat.APATH == 3)
{
gifRegs.stat.APATH = 0;
@ -129,13 +155,13 @@ __fi void gifCheckPathStatus() {
{
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;
}
__fi void gifInterrupt()
{
GIF_LOG("gifInterrupt caught!");
@ -151,8 +177,10 @@ __fi void gifInterrupt()
//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.
if(!gifUnit.Path3Masked() || gifch.qwc == 0)
CPU_INT(DMAC_GIF, 16);
//This must trigger after VIF retriggers as VIf might instantly mask Path3
if (!gifUnit.Path3Masked() || gifch.qwc == 0) {
GifDMAInt(16);
}
return;
}
@ -166,25 +194,31 @@ __fi void gifInterrupt()
if (CHECK_GIFFIFOHACK) {
if (gif_fifo.read(true)) {
CPU_INT(DMAC_GIF, 128);
}
if (int amtRead = gif_fifo.read(true)) {
if (!gifUnit.CanDoPath3() && gifRegs.stat.FQC == 16)
{
if (gifch.qwc > 0 || gspath3done == false) {
if (!gifUnit.Path3Masked()) {
CPU_INT(DMAC_GIF, 128);
}
if (!gifUnit.Path3Masked() || gifRegs.stat.FQC < 16) {
GifDMAInt(amtRead * BIAS);
return;
}
}
else {
if (!gifUnit.CanDoPath3() && gifRegs.stat.FQC == 16)
{
if (gifch.qwc > 0 || gspath3done == false) {
if (!gifUnit.Path3Masked()) {
GifDMAInt(128);
}
return;
}
}
}
}
if (gifUnit.gsSIGNAL.queued) {
GIF_LOG("Path 3 Paused");
CPU_INT(DMAC_GIF, 128);
GifDMAInt(128);
return;
}
@ -194,7 +228,7 @@ __fi void gifInterrupt()
if (!dmacRegs.ctrl.DMAE) {
Console.Warning("gs dma masked, re-scheduling...");
// re-raise the int shortly in the future
CPU_INT( DMAC_GIF, 64 );
GifDMAInt( 64 );
return;
}
GIFdma();
@ -215,11 +249,15 @@ __fi void gifInterrupt()
}
}
}
if (!CHECK_GIFFIFOHACK)gifRegs.stat.FQC = 0;
if (!CHECK_GIFFIFOHACK)
{
gifRegs.stat.FQC = 0;
clearFIFOstuff(false);
}
gscycles = 0;
gspath3done = false;
gifch.chcr.STR = false;
clearFIFOstuff(false);
hwDmacIrq(DMAC_GIF);
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);
}
@ -252,11 +290,6 @@ int _GIFchain()
pMem = dmaGetAddr(gifch.madr, false);
if (pMem == NULL) {
#if USE_OLD_GIF == 1 // d
// reset path3, fixes dark cloud 2
GIFPath_Clear( GIF_PATH_3 );
#endif
//must increment madr and clear qwc, else it loops
gifch.madr += gifch.qwc * 16;
gifch.qwc = 0;
@ -291,8 +324,8 @@ static __fi tDMA_TAG* ReadTag()
if (!(gifch.transfer("Gif", ptag))) return NULL;
gifch.madr = ptag[1]._u32; //MADR = ADDR field + SPR
gscycles += 2; // Add 1 cycles from the QW read for the tag
gifch.madr = ptag[1]._u32; //MADR = ADDR field + SPR
gscycles += 2; // Add 1 cycles from the QW read for the tag
gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID);
return ptag;
@ -309,14 +342,14 @@ static __fi tDMA_TAG* ReadTag2()
return ptag;
}
bool CheckPaths(EE_EventType Channel) {
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");
CPU_INT(Channel, 128);
GifDMAInt(128);
}
return false;
}
@ -331,14 +364,14 @@ void GIFdma()
if (gifRegs.ctrl.PSE) { // temporarily stop
Console.WriteLn("Gif dma temp paused? (non MFIFO GIF)");
CPU_INT(DMAC_GIF, 16);
GifDMAInt(16);
return;
}
if ((dmacRegs.ctrl.STD == STD_GIF) && (prevcycles != 0)) {
//Console.WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3, gifch.madr, psHu32(DMAC_STADR));
if ((gifch.madr + (gifch.qwc * 16)) > dmacRegs.stadr.ADDR) {
CPU_INT(DMAC_GIF, 4);
GifDMAInt(4);
gscycles = 0;
return;
}
@ -365,7 +398,7 @@ void GIFdma()
gifch.tadr -= 16;
gifch.qwc = 0;
hwDmacIrq(DMAC_STALL_SIS);
CPU_INT(DMAC_GIF, gscycles);
GifDMAInt(gscycles);
gscycles = 0;
return;
}
@ -378,36 +411,27 @@ void GIFdma()
Console.WriteLn("GIF DMA Stall in Normal mode not implemented - Report which game to PCSX2 Team");
}
clearFIFOstuff(true);
if (!CHECK_GIFFIFOHACK)gifRegs.stat.FQC = std::min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
#if USE_OLD_GIF == 1 // ...
if (vif1Regs.mskpath3 || gifRegs.mode.M3R) {
if (GSTransferStatus.PTH3 == STOPPED_MODE) {
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;
}
if (!CHECK_GIFFIFOHACK) {
gifRegs.stat.FQC = std::min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
clearFIFOstuff(true);
}
#endif
// Transfer Dn_QWC from Dn_MADR to GIF
if (gifch.qwc > 0) // Normal Mode
{
if (!CHECK_GIFFIFOHACK)gifRegs.stat.FQC = std::min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
if (!CheckPaths(DMAC_GIF)) return;
if (CheckPaths() == false) return;
GIFchain(); //Transfers the data set by the switch
CPU_INT(DMAC_GIF, gscycles);
//if (gscycles < 8) DevCon.Warning("GSCycles = %d", gscycles);
GifDMAInt(gscycles);
return;
} else if(!gspath3done) GIFdma(); //Loop round if there was a blank tag, causes hell otherwise with P3 masking games.
//QWC == 0 && gspath3done == true - End of DMA
prevcycles = 0;
CPU_INT(DMAC_GIF, gscycles);
if (!CHECK_GIFFIFOHACK)gifRegs.stat.FQC = std::min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // OPH=1 | APATH=3]
//if (gscycles < 8) DevCon.Warning("1 GSCycles = %d", gscycles);
GifDMAInt(16);
}
void dmaGIF()
@ -418,12 +442,15 @@ void dmaGIF()
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 ;)
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
gspath3done = true;
}
clearFIFOstuff(true);
if(gifch.chcr.MOD == CHAIN_MODE && gifch.qwc > 0) {
//DevCon.Warning(L"GIF QWC on Chain " + gifch.chcr.desc());
@ -461,29 +488,43 @@ static __fi bool mfifoGIFrbTransfer()
u16 mfifoqwc = std::min(QWCinGIFMFIFO(gifch.madr), gifch.qwc);
if (mfifoqwc == 0) return true; //Lets skip all this, we don't have the data
if(!gifUnit.CanDoPath3()) {
/*if(!gifUnit.CanDoPath3()) {
DevCon.Warning("mfifoGIFrbTransfer() - Can't do path3");
GifDMAInt(16);
return true; // Skip if can't do path3
}
}*/
bool needWrap = (gifch.madr + (mfifoqwc * 16u)) > (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16u);
uint s1 = ((dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16) - gifch.madr) >> 4;
uint s2 = mfifoqwc - s1;
uint s3 = needWrap ? s1 : mfifoqwc;
u32 t1, t2;
gifch.madr = dmacRegs.rbor.ADDR + (gifch.madr & dmacRegs.rbsr.RMSK);
u8* src = (u8*)PSM(gifch.madr);
if (src == NULL) return false;
u32 t1 = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, src, s3*16) / 16; // First part
if (CHECK_GIFFIFOHACK) {
t1 = gif_fifo.write((u32*)src, s3);
}
else {
t1 = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, src, s3 * 16) / 16; // First part
}
incGifChAddr(t1);
mfifocycles += t1 * 2; // guessing
if (needWrap && t1) { // Need to do second transfer to wrap around
if (needWrap && t1 == s1) { // Need to do second transfer to wrap around
GUNIT_WARN("mfifoGIFrbTransfer() - Wrap");
src = (u8*)PSM(dmacRegs.rbor.ADDR);
gifch.madr = dmacRegs.rbor.ADDR;
if (src == NULL) return false;
u32 t2 = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, src, s2*16) / 16; // Second part
if (CHECK_GIFFIFOHACK) {
t2 = gif_fifo.write((u32*)src, s2);
}
else {
t2 = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, src, s2 * 16) / 16; // First part
}
incGifChAddr(t2);
mfifocycles += t2 * 2; // guessing
}
@ -494,9 +535,9 @@ static __fi bool mfifoGIFchain()
{
/* Is QWC = 0? if so there is nothing to transfer */
if (gifch.qwc == 0) return true;
if (gifch.madr == (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16u)) DevCon.Warning("Edge Case?");
if (gifch.madr >= dmacRegs.rbor.ADDR &&
gifch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16u))
gifch.madr < (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16u))
{
bool ret = true;
// if(gifch.madr == (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16)) DevCon.Warning("Edge GIF");
@ -557,14 +598,17 @@ void mfifoGIFtransfer(int qwc)
tDMA_TAG *ptag;
mfifocycles = 0;
gifmfifoirq = false;
DevCon.Warning("GIF MFIFO");
//DevCon.Warning("GIF MFIFO");
if (qwc > 0 ) {
if ((gifstate & GIF_STATE_EMPTY)) {
if(gifch.chcr.STR && !(cpuRegs.interrupt & (1<<DMAC_MFIFO_GIF)))
CPU_INT(DMAC_MFIFO_GIF, 4);
gifstate &= ~GIF_STATE_EMPTY;
GifDMAInt(4);
gifstate &= ~GIF_STATE_EMPTY;
}
if (!CHECK_GIFFIFOHACK)
{
gifRegs.stat.FQC = 16;
clearFIFOstuff(true);
}
gifRegs.stat.FQC = 16;
return;
}
@ -604,26 +648,13 @@ void mfifoGIFtransfer(int qwc)
if (QWCinGIFMFIFO(gifch.tadr) == 0) gifstate |= GIF_STATE_EMPTY;
}
#if USE_OLD_GIF == 1 // ...
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;
}
}
#endif
if (!mfifoGIFchain()) {
Console.WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", gifch.qwc, gifch.madr, gifch.tadr);
gifstate = GIF_STATE_STALL;
}
if ((gifch.qwc == 0) && (gifstate & GIF_STATE_DONE)) gifstate |= GIF_STATE_STALL;
CPU_INT(DMAC_MFIFO_GIF,mfifocycles);
GifDMAInt(mfifocycles);
SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gifch.chcr._u32, gifch.madr, gifch.tadr);
}
@ -633,34 +664,48 @@ void gifMFIFOInterrupt()
GIF_LOG("gifMFIFOInterrupt");
mfifocycles = 0;
if( gifRegs.stat.APATH == 3 )
gifCheckPathStatus();
if (gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE)
{
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 (vif1Regs.stat.VGW)
{
if(gifUnit.checkPaths(1,1,0)) gifUnit.Execute(false, true);
//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
if (!gifUnit.Path3Masked() || gifch.qwc == 0) {
GifDMAInt(16);
}
return;
}
}
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE;
if (CHECK_GIFFIFOHACK) {
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 (int amtRead = gif_fifo.read(true)) {
if(!gifUnit.Path3Masked())
CPU_INT(DMAC_MFIFO_GIF, 16);
if(!gspath3done || gifch.qwc > 0) return;
if (!gifUnit.Path3Masked() || gifRegs.stat.FQC < 16) {
GifDMAInt(amtRead * BIAS);
return;
}
}
else {
if (!gifUnit.CanDoPath3() && gifRegs.stat.FQC == 16)
{
if (gifch.qwc > 0 || gspath3done == false) {
if (!gifUnit.Path3Masked()) {
GifDMAInt(128);
}
return;
}
}
}
}
if (dmacRegs.ctrl.MFD != MFD_GIF) {
@ -670,12 +715,14 @@ void gifMFIFOInterrupt()
if (gifUnit.gsSIGNAL.queued) {
//DevCon.WriteLn("Path 3 Paused");
CPU_INT(DMAC_MFIFO_GIF, 128);
GifDMAInt(128);
return;
}
if((gifstate & GIF_STATE_EMPTY)) {
FireMFIFOEmpty();
if (CHECK_GIFFIFOHACK)
GifDMAInt(128);
if(!(gifstate & GIF_STATE_STALL)) return;
}
@ -691,7 +738,9 @@ void gifMFIFOInterrupt()
if (QWCinGIFMFIFO(gifch.tadr) == 0) {
gifstate |= GIF_STATE_EMPTY;
CPU_INT(DMAC_MFIFO_GIF, 4);
GifDMAInt(4);
if (CHECK_GIFFIFOHACK)
GifDMAInt(128);
return;
}
mfifoGIFtransfer(0);
@ -703,20 +752,41 @@ void gifMFIFOInterrupt()
return;
}
if (gifRegs.stat.FQC > 0) {
//DevCon.Warning("GIF Ending with stuff still in it?");
GifDMAInt(16);
return;
}
//if(gifqwc > 0) Console.WriteLn("GIF MFIFO ending with stuff in it %x", gifqwc);
if (!gifmfifoirq) gifqwc = 0;
gspath3done = false;
gscycles = 0;
gifRegs.stat.FQC = 0;
if (!CHECK_GIFFIFOHACK)
{
gifRegs.stat.FQC = 0;
clearFIFOstuff(false);
}
//vif1Regs.stat.VGW = false; // old code had this
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.
if (!(cpuRegs.interrupt & (1 << DMAC_VIF1)))
CPU_INT(DMAC_VIF1, 1);
}
}
gifch.chcr.STR = false;
gifstate = GIF_STATE_READY;
hwDmacIrq(DMAC_GIF);
DMA_LOG("GIF MFIFO DMA End");
clearFIFOstuff(false);
}
void SaveStateBase::gifDmaFreeze() {

View File

@ -15,7 +15,6 @@
#pragma once
#define USE_OLD_GIF 0
#define COPY_GS_PACKET_TO_MTGS 0
#define PRINT_GIF_PACKET 0

View File

@ -592,12 +592,11 @@ struct Gif_Unit {
break; // Not finished with GS packet
}
//DevCon.WriteLn("Adding GS Packet for path %d", stat.APATH);
AddCompletedGSPacket(gsPack, (GIF_PATH)(stat.APATH-1));
/*if (path.curSize == path.curOffset)
curPath = 0;*/
if (gifPath[curPath].state == GIF_PATH_WAIT || gifPath[curPath].state == GIF_PATH_IDLE) {
AddCompletedGSPacket(gsPack, (GIF_PATH)(stat.APATH - 1));
}
}
if (!gsSIGNAL.queued && !gifPath[0].isDone()) {
stat.APATH = 1;
stat.P1Q = 0;
@ -623,11 +622,10 @@ struct Gif_Unit {
break;
}
}
//Some loaders/Refresh Rate selectors and things dont issue "End of Packet" commands
//So we look and see if the end of the last tag is all there, if so, stick it in the buffer for the GS :)
//(Invisible Screens on Terminator 3 and Growlanser 2/3)
if(gifPath[curPath].curOffset == gifPath[curPath].curSize)
if(gifPath[curPath].curOffset == gifPath[curPath].curSize)
{
FlushToMTGS();
}

View File

@ -200,15 +200,7 @@ __fi void vif1FBRST(u32 value) {
if(gifUnit.checkPaths(1,0,1)) gifUnit.Execute(false, true);
}
}
#if USE_OLD_GIF == 1 // ...
if(vif1Regs.mskpath3 == 1 && GSTransferStatus.PTH3 == STOPPED_MODE && gifch.chcr.STR) {
DevCon.Warning("VIF Path3 Resume on FBRST MSK = %x", vif1Regs.mskpath3);
gifInterrupt();
vif1Regs.mskpath3 = false;
gifRegs.stat.M3P = false;
}
#endif
GUNIT_WARN(Color_Red, "VIF FBRST Reset MSK = %x", vif1Regs.mskpath3);
vif1Regs.mskpath3 = false;
gifRegs.stat.M3P = 0;

View File

@ -406,14 +406,11 @@ vifOp(vifCode_MskPath3) {
pass1 {
vif1Regs.mskpath3 = (vif1Regs.code >> 15) & 0x1;
gifRegs.stat.M3P = (vif1Regs.code >> 15) & 0x1;
GUNIT_LOG("Vif1 - MskPath3 [p3 = %s]", vif1Regs.mskpath3 ? "disabled" : "enabled");
GUNIT_LOG("Vif1 - MskPath3 [p3 = %s]", vif1Regs.mskpath3 ? "masked" : "enabled");
if(!vif1Regs.mskpath3) {
//if(!gifUnit.gifPath[GIF_PATH_3].isDone() || gifRegs.stat.P3Q || gifRegs.stat.IP3) {
GUNIT_WARN("Path3 triggering!");
if(CHECK_GIFFIFOHACK)gif_fifo.read(false);
else gifInterrupt();
GIF_LOG("GIF state on mskpth3 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);
//}
GUNIT_WARN("Path3 triggering!");
if(CHECK_GIFFIFOHACK)gif_fifo.read(false);
else gifInterrupt();
}
vif1.cmd = 0;
vif1.pass = 0;