From 25887c62eee45f9ad2480ef3c2e14b24c8df6f53 Mon Sep 17 00:00:00 2001 From: refraction Date: Wed, 30 Jun 2010 00:55:22 +0000 Subject: [PATCH] -Sorted some VIF problems causing unknown vifcmd errors (Enter the Matrix) -Fixed up some path3 masking stuff, trying a slightly different approach too. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3349 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/Gif.cpp | 12 +++++---- pcsx2/Vif0_Dma.cpp | 15 ++++++----- pcsx2/Vif1_Dma.cpp | 29 ++++++++++++--------- pcsx2/Vif_Codes.cpp | 8 +++--- pcsx2/ps2/GIFpath.cpp | 59 +++++++++++++++++++++++++++++++------------ 5 files changed, 80 insertions(+), 43 deletions(-) diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index 1319a64d6a..d1a2f78a0e 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -54,7 +54,7 @@ void gsPath1Interrupt() - if((gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.IP3 && gifRegs->stat.APATH == GIF_APATH3)) && Path1WritePos > 0 && !gifRegs->stat.PSE) + if((gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.IP3 == true && gifRegs->stat.APATH == GIF_APATH3)) && Path1WritePos > 0 && !gifRegs->stat.PSE) { Registers::Freeze(); while(Path1WritePos > 0) @@ -86,6 +86,7 @@ void gsPath1Interrupt() else { if(gifRegs->stat.PSE) DevCon.Warning("Path1 paused by GIF_CTRL"); + 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); } @@ -94,9 +95,10 @@ __forceinline void gsInterrupt() { GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle); - if(GSTransferStatus.PTH3 >= IDLE_MODE && gifRegs->stat.APATH == GIF_APATH3 ) + if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE && gifRegs->stat.APATH == GIF_APATH3 ) { gifRegs->stat.OPH = false; + GSTransferStatus.PTH3 = STOPPED_MODE; gifRegs->stat.APATH = GIF_APATH_IDLE; if(gifRegs->stat.P1Q) gsPath1Interrupt(); } @@ -240,7 +242,7 @@ bool CheckPaths(int Channel) } } } - else if((GSTransferStatus.PTH3 >= IDLE_MODE)) + else if((GSTransferStatus.PTH3 == IDLE_MODE)|| (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)) @@ -305,9 +307,9 @@ void GIFdma() } - if (GSTransferStatus.PTH3 == STOPPED_MODE) + if (GSTransferStatus.PTH3 == IDLE_MODE) { - GIF_LOG("PTH3 MASK Paused by VIF"); + GIF_LOG("PTH3 MASK Paused by VIF QWC %x", gif->qwc); //DevCon.Warning("GIF Paused by Mask MSK = %x", vif1Regs->mskpath3); diff --git a/pcsx2/Vif0_Dma.cpp b/pcsx2/Vif0_Dma.cpp index 079a2c5b82..71a6217389 100644 --- a/pcsx2/Vif0_Dma.cpp +++ b/pcsx2/Vif0_Dma.cpp @@ -103,7 +103,7 @@ __forceinline void vif0SetupTransfer() VIF_LOG("vif0 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", ptag[1]._u32, ptag[0]._u32, vif0ch->qwc, ptag->ID, vif0ch->madr, vif0ch->tadr); - vif0.inprogress = 1; + vif0.inprogress = 0; if (vif0ch->chcr.TTE) { @@ -124,6 +124,7 @@ __forceinline void vif0SetupTransfer() vif0.irqoffset = 0; vif0.done |= hwDmacSrcChainWithStack(vif0ch, ptag->ID); + if(vif0ch->qwc > 0) vif0.inprogress = 1; //Check TIE bit of CHCR and IRQ bit of tag if (vif0ch->chcr.TIE && ptag->IRQ) { @@ -217,21 +218,22 @@ void dmaVIF0() g_vifCycles = 0; g_vu0Cycles = 0; - if(vif0.irqoffset != 0 && vif0.vifstalled == true) DevCon.Warning("Offset on VIF0 start!"); - vif0.irqoffset = 0; + //if(vif0.irqoffset != 0 && vif0.vifstalled == true) DevCon.Warning("Offset on VIF0 start! offset %x, Progress %x", vif0.irqoffset, vif0.vifstalled); + /*vif0.irqoffset = 0; vif0.vifstalled = false; vif0.inprogress = 0; - vif0.done = false; + vif0.done = false;*/ if ((vif0ch->chcr.MOD == NORMAL_MODE) || vif0ch->qwc > 0) // Normal Mode { vif0.dmamode = VIF_NORMAL_TO_MEM_MODE; + vif0.done = false; + if(vif0ch->chcr.MOD == CHAIN_MODE && vif0ch->qwc > 0) { vif0.dmamode = VIF_CHAIN_MODE; - //DevCon.Warning(L"VIF0 QWC on Chain CHCR " + vif0ch->chcr.desc()); - vif0.inprogress |= 0x1; + DevCon.Warning(L"VIF0 QWC on Chain CHCR " + vif0ch->chcr.desc()); if ((vif0ch->chcr.tag().ID == TAG_REFE) || (vif0ch->chcr.tag().ID == TAG_END)) { @@ -242,6 +244,7 @@ void dmaVIF0() else { vif0.dmamode = VIF_CHAIN_MODE; + vif0.done = false; } vif0Regs->stat.FQC = min((u16)0x8, vif0ch->qwc); diff --git a/pcsx2/Vif1_Dma.cpp b/pcsx2/Vif1_Dma.cpp index 2f39ebe134..e649777828 100644 --- a/pcsx2/Vif1_Dma.cpp +++ b/pcsx2/Vif1_Dma.cpp @@ -221,7 +221,8 @@ __forceinline void vif1SetupTransfer() } } - vif1.inprogress = 1; + + vif1.inprogress = 0; if (vif1ch->chcr.TTE) { @@ -239,10 +240,12 @@ __forceinline void vif1SetupTransfer() } //else vif1.vifstalled = false; } - vif1.irqoffset = 0; + vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID); + if(vif1ch->qwc > 0) vif1.inprogress = 1; + //Check TIE bit of CHCR and IRQ bit of tag if (vif1ch->chcr.TIE && ptag->IRQ) { @@ -289,7 +292,7 @@ bool CheckPath2GIF(int channel) return false; } - if (GSTransferStatus.PTH3 < PENDINGSTOP_MODE) + if (GSTransferStatus.PTH3 < IDLE_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("PTH3 %x P1Q %x P3Q %x IP3 %x", GSTransferStatus.PTH3, gifRegs->stat.P1Q, gifRegs->stat.P3Q, gifRegs->stat.IP3 ); @@ -429,7 +432,7 @@ __forceinline void vif1Interrupt() return; //Dont want to end if vif is stalled. } #ifdef PCSX2_DEVBUILD - if (vif1ch->qwc > 0) Console.WriteLn("VIF1 Ending with %x QWC left"); + if (vif1ch->qwc > 0) Console.WriteLn("VIF1 Ending with %x QWC left", vif1ch->qwc); if (vif1.cmd != 0) Console.WriteLn("vif1.cmd still set %x tag size %x", vif1.cmd, vif1.tag.size); #endif @@ -454,14 +457,14 @@ void dmaVIF1() vif1ch->chcr._u32, vif1ch->madr, vif1ch->qwc, vif1ch->tadr, vif1ch->asr0, vif1ch->asr1); - vif1.done = false; +// vif1.done = false; - if(vif1.irqoffset != 0 && vif1.vifstalled == true) DevCon.Warning("Offset on VIF1 start!"); - vif1.irqoffset = 0; - vif1.vifstalled = false; + //if(vif1.irqoffset != 0 && vif1.vifstalled == true) DevCon.Warning("Offset on VIF1 start! offset %x, Progress %x", vif1.irqoffset, vif1.vifstalled); + /*vif1.irqoffset = 0; + vif1.vifstalled = false; + vif1.inprogress = 0;*/ g_vifCycles = 0; g_vu1Cycles = 0; - vif1.inprogress = 0; #ifdef PCSX2_DEVBUILD if (dmacRegs->ctrl.STD == STD_VIF1) @@ -481,11 +484,12 @@ void dmaVIF1() else vif1.dmamode = VIF_NORMAL_TO_MEM_MODE; + vif1.done = false; + if(vif1ch->chcr.MOD == CHAIN_MODE && vif1ch->qwc > 0) { vif1.dmamode = VIF_CHAIN_MODE; - //DevCon.Warning(L"VIF1 QWC on Chain CHCR " + vif1ch->chcr.desc()); - vif1.inprogress |= 0x1; + DevCon.Warning(L"VIF1 QWC on Chain CHCR " + vif1ch->chcr.desc()); if ((vif1ch->chcr.tag().ID == TAG_REFE) || (vif1ch->chcr.tag().ID == TAG_END)) { @@ -496,10 +500,11 @@ void dmaVIF1() else { vif1.dmamode = VIF_CHAIN_MODE; + vif1.done = false; } if (vif1ch->chcr.DIR) vif1Regs->stat.FQC = min((u16)0x10, vif1ch->qwc); // Chain Mode - vif1Interrupt(); + CPU_INT(DMAC_VIF1, 4); } diff --git a/pcsx2/Vif_Codes.cpp b/pcsx2/Vif_Codes.cpp index fe495c8d84..2163685c17 100644 --- a/pcsx2/Vif_Codes.cpp +++ b/pcsx2/Vif_Codes.cpp @@ -85,20 +85,20 @@ u8 schedulepath3msk = 0; void Vif1MskPath3() { vif1Regs->mskpath3 = schedulepath3msk & 0x1; - //Console.WriteLn("VIF MSKPATH3 %x gif str %x path3 status %x", vif1Regs->mskpath3, gif->chcr.STR, GSTransferStatus.PTH3); + GIF_LOG("VIF MSKPATH3 %x gif str %x path3 status %x", vif1Regs->mskpath3, gif->chcr.STR, GSTransferStatus.PTH3); gifRegs->stat.M3P = vif1Regs->mskpath3; if (!vif1Regs->mskpath3) { //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(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE) GSTransferStatus.PTH3 = IDLE_MODE; if(gifRegs->stat.P3Q) { gsInterrupt();//gsInterrupt(); } - } else if(!gif->chcr.STR && GSTransferStatus.PTH3 == IDLE_MODE) GSTransferStatus.PTH3 = STOPPED_MODE;//else DevCon.Warning("Mask on"); + }// else if(!gif->chcr.STR && GSTransferStatus.PTH3 == IDLE_MODE) GSTransferStatus.PTH3 = STOPPED_MODE;//else DevCon.Warning("Mask on"); schedulepath3msk = 0; } @@ -261,7 +261,7 @@ vifOp(vifCode_FlushA) { pass1 { vifFlush(idx); // Gif is already transferring so wait for it. - if (gifRegs->stat.P1Q == true || GSTransferStatus.PTH3 < PENDINGSTOP_MODE) { + if (gifRegs->stat.P1Q == true || GSTransferStatus.PTH3 <= PENDINGSTOP_MODE) { //DevCon.Warning("VIF FlushA Wait MSK = %x", vif1Regs->mskpath3); // diff --git a/pcsx2/ps2/GIFpath.cpp b/pcsx2/ps2/GIFpath.cpp index cf1ef255ea..cf56f64512 100644 --- a/pcsx2/ps2/GIFpath.cpp +++ b/pcsx2/ps2/GIFpath.cpp @@ -452,6 +452,43 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size) if(nloop > 0) { switch(pathidx) + { + case GIF_PATH_1: + if(tag.FLG & 2)GSTransferStatus.PTH1 = IMAGE_MODE; + else GSTransferStatus.PTH1 = TRANSFER_MODE; + break; + case GIF_PATH_2: + if(tag.FLG & 2)GSTransferStatus.PTH2 = IMAGE_MODE; + 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; + } + break; + } + if(GSTransferStatus.PTH3 < PENDINGSTOP_MODE || pathidx != 2) + { + gifRegs->stat.OPH = true; + gifRegs->stat.APATH = pathidx + 1; + } + } + + if(pathidx == GIF_PATH_3) + { + break; + } + } + else + { + switch(pathidx) { case GIF_PATH_1: if(tag.FLG & 2)GSTransferStatus.PTH1 = IMAGE_MODE; @@ -467,23 +504,12 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size) break; } - gifRegs->stat.OPH = true; - gifRegs->stat.APATH = pathidx + 1; - } - if(pathidx == GIF_PATH_3) - { - if(vif1Regs->mskpath3 == 1) break; - } - } - else - { - gifRegs->stat.APATH = pathidx + 1; gifRegs->stat.OPH = true; switch(tag.FLG) { case GIF_FLG_PACKED: - GIF_LOG("Packed Mode"); + GIF_LOG("Packed Mode EOP %x", tag.EOP); PrepPackedRegs(); if(DetectE > 0) { @@ -507,7 +533,7 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size) break; case GIF_FLG_REGLIST: { - GIF_LOG("Reglist Mode"); + GIF_LOG("Reglist Mode EOP %x", tag.EOP); numregs = ((tag.NREG-1)&0xf) + 1; size *= 2; @@ -523,7 +549,7 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size) case GIF_FLG_IMAGE: case GIF_FLG_IMAGE2: { - GIF_LOG("IMAGE Mode"); + GIF_LOG("IMAGE Mode EOP %x", tag.EOP); int len = aMin(size, nloop); incTag(( len * 16 ), len); nloop -= len; @@ -566,7 +592,6 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size) if (tag.EOP && nloop <= 16) { if(pathidx == 2 && nloop > 0) { - if(GSTransferStatus.PTH3 != IDLE_MODE) GSTransferStatus.PTH3 = PENDINGSTOP_MODE; if (gif->chcr.STR) { //Make sure we are really doing a DMA and not using FIFO //GIF_LOG("Path3 end EOP %x NLOOP %x Status %x", tag.EOP, nloop, GSTransferStatus.PTH3); gif->madr += size * 16; @@ -586,7 +611,9 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size) GSTransferStatus.PTH2 = STOPPED_MODE; break; case GIF_PATH_3: - if(GSTransferStatus.PTH3 != IDLE_MODE) GSTransferStatus.PTH3 = STOPPED_MODE; + //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; if (gif->chcr.STR) { //Make sure we are really doing a DMA and not using FIFO //GIF_LOG("Path3 end EOP %x NLOOP %x Status %x", tag.EOP, nloop, GSTransferStatus.PTH3); gif->madr += size * 16;