-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
This commit is contained in:
refraction 2010-06-30 00:55:22 +00:00
parent e035209623
commit 25887c62ee
5 changed files with 80 additions and 43 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
//

View File

@ -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;