mirror of https://github.com/PCSX2/pcsx2.git
More vif work to fix Shadowman 2 and improve the function of some parts. Gave vifstalled a more specific job and reasons for the stall. Also did some work with the irq offset, seperating it from the stalls.
Savestate bump needed. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5380 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
9e76c0ba49
commit
d465c18228
|
@ -71,7 +71,7 @@ void __fastcall WriteFIFO_VIF0(const mem128_t *value)
|
|||
VIF_LOG("WriteFIFO/VIF0 <- %ls", value->ToString().c_str());
|
||||
|
||||
vif0ch.qwc += 1;
|
||||
if(vif0.irqoffset != 0 && vif0.vifstalled == true) DevCon.Warning("Offset on VIF0 FIFO start!");
|
||||
if(vif0.irqoffset.value != 0 && vif0.vifstalled.enabled == true) DevCon.Warning("Offset on VIF0 FIFO start!");
|
||||
bool ret = VIF0transfer((u32*)value, 4);
|
||||
|
||||
if (vif0.cmd)
|
||||
|
@ -96,7 +96,7 @@ void __fastcall WriteFIFO_VIF1(const mem128_t *value)
|
|||
if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) ) {
|
||||
DevCon.Warning("writing to vif1 fifo when stalled");
|
||||
}
|
||||
if (vif1.irqoffset != 0 && vif1.vifstalled == true) {
|
||||
if (vif1.irqoffset.value != 0 && vif1.vifstalled.enabled == true) {
|
||||
DevCon.Warning("Offset on VIF1 FIFO start!");
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
// 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 = (0x9A08 << 16) | 0x0000;
|
||||
static const u32 g_SaveVersion = (0x9A09 << 16) | 0x0000;
|
||||
|
||||
// this function is meant to be used in the place of GSfreeze, and provides a safe layer
|
||||
// between the GS saving function and the MTGS's needs. :)
|
||||
|
|
|
@ -97,7 +97,8 @@ __fi void vif0FBRST(u32 value) {
|
|||
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
|
||||
psHu64(VIF0_FIFO) = 0;
|
||||
psHu64(VIF0_FIFO + 8) = 0;
|
||||
vif0.vifstalled = false;
|
||||
vif0.vifstalled.enabled = false;
|
||||
vif1.irqoffset.enabled = false;
|
||||
vif0.inprogress = 0;
|
||||
vif0.cmd = 0;
|
||||
vif0.done = true;
|
||||
|
@ -123,7 +124,8 @@ __fi void vif0FBRST(u32 value) {
|
|||
// just stoppin the VIF (linuz).
|
||||
vif0Regs.stat.VSS = true;
|
||||
vif0Regs.stat.VPS = VPS_IDLE;
|
||||
vif0.vifstalled = true;
|
||||
vif0.vifstalled.enabled = true;
|
||||
vif0.vifstalled.value = VIF_IRQ_STALL;
|
||||
}
|
||||
|
||||
if (value & 0x8) // Cancel Vif Stall.
|
||||
|
@ -138,8 +140,8 @@ __fi void vif0FBRST(u32 value) {
|
|||
VIF0_STAT_INT | VIF0_STAT_ER0 | VIF0_STAT_ER1);
|
||||
if (cancel)
|
||||
{
|
||||
if (vif0.vifstalled)
|
||||
{
|
||||
if (vif0.vifstalled.enabled && vif0.vifstalled.value == VIF_IRQ_STALL)
|
||||
{
|
||||
g_vif0Cycles = 0;
|
||||
|
||||
// loop necessary for spiderman
|
||||
|
@ -192,7 +194,8 @@ __fi void vif1FBRST(u32 value) {
|
|||
vif1Regs.err.reset();
|
||||
vif1.inprogress = 0;
|
||||
vif1.cmd = 0;
|
||||
vif1.vifstalled = false;
|
||||
vif1.vifstalled.enabled = false;
|
||||
vif1.irqoffset.enabled = false;
|
||||
vif1Regs.stat.FQC = 0;
|
||||
vif1Regs.stat.clear_flags(VIF1_STAT_FDR | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS);
|
||||
}
|
||||
|
@ -206,6 +209,8 @@ __fi void vif1FBRST(u32 value) {
|
|||
vif1Regs.stat.VFS = true;
|
||||
vif1Regs.stat.VPS = VPS_IDLE;
|
||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||
vif1.vifstalled.enabled = true;
|
||||
vif1.vifstalled.value = VIF_IRQ_STALL;
|
||||
Console.WriteLn("vif1 force break");
|
||||
}
|
||||
|
||||
|
@ -216,7 +221,8 @@ __fi void vif1FBRST(u32 value) {
|
|||
vif1Regs.stat.VSS = true;
|
||||
vif1Regs.stat.VPS = VPS_IDLE;
|
||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||
vif1.vifstalled = true;
|
||||
vif1.vifstalled.enabled = true;
|
||||
vif1.vifstalled.value = VIF_IRQ_STALL;
|
||||
}
|
||||
|
||||
if (FBRST(value).STC) // Cancel Vif Stall.
|
||||
|
@ -234,7 +240,7 @@ __fi void vif1FBRST(u32 value) {
|
|||
|
||||
if (cancel)
|
||||
{
|
||||
if (vif1.vifstalled)
|
||||
if (vif1.vifstalled.enabled && vif1.vifstalled.value == VIF_IRQ_STALL)
|
||||
{
|
||||
g_vif1Cycles = 0;
|
||||
// loop necessary for spiderman
|
||||
|
|
|
@ -83,6 +83,12 @@ enum vif_status
|
|||
VPS_TRANSFERRING = 3 // And decompressing.
|
||||
};
|
||||
|
||||
enum vif_stallreasons
|
||||
{
|
||||
VIF_TIMING_BREAK = 1,
|
||||
VIF_IRQ_STALL = 2
|
||||
};
|
||||
|
||||
//
|
||||
// Bitfield Structure
|
||||
//
|
||||
|
|
|
@ -28,7 +28,8 @@ __fi void vif0FLUSH()
|
|||
if(vif0Regs.stat.VEW == true)
|
||||
{
|
||||
vif0.waitforvu = true;
|
||||
vif0.vifstalled = true;
|
||||
vif0.vifstalled.enabled = true;
|
||||
vif0.vifstalled.value = VIF_TIMING_BREAK;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -55,8 +56,8 @@ bool _VIF0chain()
|
|||
VIF_LOG("VIF0chain size=%d, madr=%lx, tadr=%lx",
|
||||
vif0ch.qwc, vif0ch.madr, vif0ch.tadr);
|
||||
|
||||
if (vif0.vifstalled)
|
||||
return VIF0transfer(pMem + vif0.irqoffset, vif0ch.qwc * 4 - vif0.irqoffset);
|
||||
if (vif0.irqoffset.enabled)
|
||||
return VIF0transfer(pMem + vif0.irqoffset.value, vif0ch.qwc * 4 - vif0.irqoffset.value);
|
||||
else
|
||||
return VIF0transfer(pMem, vif0ch.qwc * 4);
|
||||
}
|
||||
|
@ -101,21 +102,22 @@ __fi void vif0SetupTransfer()
|
|||
|
||||
VIF_LOG("\tVIF0 SrcChain TTE=1, data = 0x%08x.%08x", masked_tag._u32[3], masked_tag._u32[2]);
|
||||
|
||||
if (vif0.vifstalled)
|
||||
if (vif0.irqoffset.enabled)
|
||||
{
|
||||
ret = VIF0transfer((u32*)&masked_tag + vif0.irqoffset, 4 - vif0.irqoffset, true); //Transfer Tag on stall
|
||||
ret = VIF0transfer((u32*)&masked_tag + vif0.irqoffset.value, 4 - vif0.irqoffset.value, true); //Transfer Tag on stall
|
||||
//ret = VIF0transfer((u32*)ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset); //Transfer Tag on stall
|
||||
}
|
||||
else
|
||||
{
|
||||
//Some games (like killzone) do Tags mid unpack, the nops will just write blank data
|
||||
//to the VU's, which breaks stuff, this is where the 128bit packet will fail, so we ignore the first 2 words
|
||||
vif0.irqoffset = 2;
|
||||
vif0.irqoffset.value = 2;
|
||||
vif0.irqoffset.enabled = true;
|
||||
ret = VIF0transfer((u32*)&masked_tag + 2, 2, true); //Transfer Tag
|
||||
//ret = VIF0transfer((u32*)ptag + 2, 2); //Transfer Tag
|
||||
}
|
||||
|
||||
if (!ret && vif0.irqoffset)
|
||||
if (!ret && vif0.irqoffset.enabled)
|
||||
{
|
||||
vif0.inprogress = 0; //Better clear this so it has to do it again (Jak 1)
|
||||
return; //IRQ set by VIFTransfer
|
||||
|
@ -123,7 +125,8 @@ __fi void vif0SetupTransfer()
|
|||
}
|
||||
}
|
||||
|
||||
vif0.irqoffset = 0;
|
||||
vif0.irqoffset.value = 0;
|
||||
vif0.irqoffset.enabled = false;
|
||||
vif0.done |= hwDmacSrcChainWithStack(vif0ch, ptag->ID);
|
||||
|
||||
if(vif0ch.qwc > 0) vif0.inprogress = 1;
|
||||
|
@ -153,12 +156,13 @@ __fi void vif0VUFinish()
|
|||
return;
|
||||
}
|
||||
vif0Regs.stat.VEW = false;
|
||||
VIF_LOG("VU0 finished");
|
||||
if(vif0.waitforvu == true)
|
||||
{
|
||||
vif0.waitforvu = false;
|
||||
ExecuteVU(0);
|
||||
//Make sure VIF0 isnt already scheduled to spin.
|
||||
if(!(cpuRegs.interrupt & 0x1))
|
||||
if(!(cpuRegs.interrupt & 0x1) && vif0ch.chcr.STR == true)
|
||||
vif0Interrupt();
|
||||
}
|
||||
//DevCon.Warning("VU0 state cleared");
|
||||
|
@ -200,6 +204,9 @@ __fi void vif0Interrupt()
|
|||
//CPU_INT(DMAC_VIF0, 16);
|
||||
return;
|
||||
}
|
||||
|
||||
vif0.vifstalled.enabled = false;
|
||||
|
||||
//Must go after the Stall, incase it's still in progress, GTC africa likes to see it still transferring.
|
||||
if (vif0.cmd)
|
||||
{
|
||||
|
@ -233,9 +240,9 @@ __fi void vif0Interrupt()
|
|||
return;
|
||||
}
|
||||
|
||||
if (vif0.vifstalled && vif0.irq)
|
||||
if (vif0.vifstalled.enabled && vif0.done)
|
||||
{
|
||||
DevCon.WriteLn("VIF0 looping on stall\n");
|
||||
DevCon.WriteLn("VIF0 looping on stall at end\n");
|
||||
CPU_INT(DMAC_VIF0, 0);
|
||||
return; //Dont want to end if vif is stalled.
|
||||
}
|
||||
|
@ -246,6 +253,8 @@ __fi void vif0Interrupt()
|
|||
|
||||
vif0ch.chcr.STR = false;
|
||||
vif0Regs.stat.FQC = min((u16)0x8, vif0ch.qwc);
|
||||
vif0.vifstalled.enabled = false;
|
||||
vif0.irqoffset.enabled = false;
|
||||
g_vif0Cycles = 0;
|
||||
hwDmacIrq(DMAC_VIF0);
|
||||
vif0Regs.stat.FQC = 0;
|
||||
|
@ -260,16 +269,18 @@ void dmaVIF0()
|
|||
vif0ch.tadr, vif0ch.asr0, vif0ch.asr1);
|
||||
|
||||
g_vif0Cycles = 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;*/
|
||||
|
||||
|
||||
if ((vif0ch.chcr.MOD == NORMAL_MODE) || vif0ch.qwc > 0) // Normal Mode
|
||||
{
|
||||
vif0.dmamode = VIF_NORMAL_TO_MEM_MODE;
|
||||
|
||||
if(vif0.irqoffset.enabled == true && vif0.done == false)
|
||||
{
|
||||
if(vif0ch.chcr.MOD == NORMAL_MODE)DevCon.Warning("Warning! VIF0 starting a new Normal transfer with vif offset set (Possible force stop?)");
|
||||
else if(vif0ch.qwc == 0) DevCon.Warning("Warning! VIF0 starting a new Chain transfer with vif offset set (Possible force stop?)");
|
||||
}
|
||||
|
||||
vif0.done = false;
|
||||
|
||||
if(vif0ch.chcr.MOD == CHAIN_MODE && vif0ch.qwc > 0)
|
||||
|
|
|
@ -28,7 +28,8 @@ __fi void vif1FLUSH()
|
|||
if(vif1Regs.stat.VEW == true)
|
||||
{
|
||||
vif1.waitforvu = true;
|
||||
vif1.vifstalled = true;
|
||||
vif1.vifstalled.enabled = true;
|
||||
vif1.vifstalled.value = VIF_TIMING_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +101,8 @@ bool _VIF1chain()
|
|||
if (vif1ch.qwc == 0)
|
||||
{
|
||||
vif1.inprogress &= ~1;
|
||||
vif1.irqoffset = 0;
|
||||
vif1.irqoffset.value = 0;
|
||||
vif1.irqoffset.enabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -124,8 +126,8 @@ bool _VIF1chain()
|
|||
VIF_LOG("VIF1chain size=%d, madr=%lx, tadr=%lx",
|
||||
vif1ch.qwc, vif1ch.madr, vif1ch.tadr);
|
||||
|
||||
if (vif1.vifstalled)
|
||||
return VIF1transfer(pMem + vif1.irqoffset, vif1ch.qwc * 4 - vif1.irqoffset, false);
|
||||
if (vif1.irqoffset.enabled)
|
||||
return VIF1transfer(pMem + vif1.irqoffset.value, vif1ch.qwc * 4 - vif1.irqoffset.value, false);
|
||||
else
|
||||
return VIF1transfer(pMem, vif1ch.qwc * 4, false);
|
||||
}
|
||||
|
@ -174,27 +176,29 @@ __fi void vif1SetupTransfer()
|
|||
|
||||
VIF_LOG("\tVIF1 SrcChain TTE=1, data = 0x%08x.%08x", masked_tag._u32[3], masked_tag._u32[2]);
|
||||
|
||||
if (vif1.vifstalled)
|
||||
if (vif1.irqoffset.enabled)
|
||||
{
|
||||
ret = VIF1transfer((u32*)&masked_tag + vif1.irqoffset, 4 - vif1.irqoffset, true); //Transfer Tag on stall
|
||||
ret = VIF1transfer((u32*)&masked_tag + vif1.irqoffset.value, 4 - vif1.irqoffset.value, true); //Transfer Tag on stall
|
||||
//ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset); //Transfer Tag on stall
|
||||
}
|
||||
else
|
||||
{
|
||||
//Some games (like killzone) do Tags mid unpack, the nops will just write blank data
|
||||
//to the VU's, which breaks stuff, this is where the 128bit packet will fail, so we ignore the first 2 words
|
||||
vif1.irqoffset = 2;
|
||||
vif1.irqoffset.value = 2;
|
||||
vif1.irqoffset.enabled = true;
|
||||
ret = VIF1transfer((u32*)&masked_tag + 2, 2, true); //Transfer Tag
|
||||
//ret = VIF1transfer((u32*)ptag + 2, 2); //Transfer Tag
|
||||
}
|
||||
|
||||
if (!ret && vif1.irqoffset)
|
||||
if (!ret && vif1.irqoffset.enabled)
|
||||
{
|
||||
vif1.inprogress &= ~1; //Better clear this so it has to do it again (Jak 1)
|
||||
return; //IRQ set by VIFTransfer
|
||||
}
|
||||
}
|
||||
vif1.irqoffset = 0;
|
||||
vif1.irqoffset.value = 0;
|
||||
vif1.irqoffset.enabled = false;
|
||||
|
||||
vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID);
|
||||
|
||||
|
@ -225,6 +229,7 @@ __fi void vif1VUFinish()
|
|||
}
|
||||
|
||||
vif1Regs.stat.VEW = false;
|
||||
VIF_LOG("VU1 finished");
|
||||
if(vif1.waitforvu == true)
|
||||
{
|
||||
vif1.waitforvu = false;
|
||||
|
@ -303,6 +308,8 @@ __fi void vif1Interrupt()
|
|||
}
|
||||
}
|
||||
|
||||
vif1.vifstalled.enabled = false;
|
||||
|
||||
//Mirroring change to VIF0
|
||||
if (vif1.cmd)
|
||||
{
|
||||
|
@ -342,9 +349,9 @@ __fi void vif1Interrupt()
|
|||
return;
|
||||
}
|
||||
|
||||
if (vif1.vifstalled && vif1.irq)
|
||||
if (vif1.vifstalled.enabled && vif1.done)
|
||||
{
|
||||
DevCon.WriteLn("VIF1 looping on stall\n");
|
||||
DevCon.WriteLn("VIF1 looping on stall at end\n");
|
||||
CPU_INT(DMAC_VIF1, 0);
|
||||
return; //Dont want to end if vif is stalled.
|
||||
}
|
||||
|
@ -362,7 +369,8 @@ __fi void vif1Interrupt()
|
|||
if (vif1ch.chcr.DIR) vif1Regs.stat.FQC = min(vif1ch.qwc, (u16)16);
|
||||
|
||||
vif1ch.chcr.STR = false;
|
||||
vif1.vifstalled = false;
|
||||
vif1.vifstalled.enabled = false;
|
||||
vif1.irqoffset.enabled = false;
|
||||
g_vif1Cycles = 0;
|
||||
DMA_LOG("VIF1 DMA End");
|
||||
hwDmacIrq(DMAC_VIF1);
|
||||
|
@ -376,12 +384,6 @@ void dmaVIF1()
|
|||
vif1ch.chcr._u32, vif1ch.madr, vif1ch.qwc,
|
||||
vif1ch.tadr, vif1ch.asr0, vif1ch.asr1);
|
||||
|
||||
// vif1.done = 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_vif1Cycles = 0;
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
|
@ -419,6 +421,7 @@ void dmaVIF1()
|
|||
else
|
||||
vif1.dmamode = VIF_NORMAL_TO_MEM_MODE;
|
||||
|
||||
if(vif1.irqoffset.enabled == true && vif1.done == false) DevCon.Warning("Warning! VIF1 starting a Normal transfer with vif offset set (Possible force stop?)");
|
||||
vif1.done = true;
|
||||
}
|
||||
|
||||
|
@ -426,6 +429,7 @@ void dmaVIF1()
|
|||
}
|
||||
else
|
||||
{
|
||||
if(vif1.irqoffset.enabled == true && vif1.done == false) DevCon.Warning("Warning! VIF1 starting a new Chain transfer with vif offset set (Possible force stop?)");
|
||||
vif1.dmamode = VIF_CHAIN_MODE;
|
||||
vif1.done = false;
|
||||
vif1.inprogress &= ~0x1;
|
||||
|
|
|
@ -72,14 +72,14 @@ static __fi bool mfifoVIF1rbTransfer()
|
|||
src = (u32*)PSM(vif1ch.madr);
|
||||
if (src == NULL) return false;
|
||||
|
||||
if (vif1.vifstalled)
|
||||
ret = VIF1transfer(src + vif1.irqoffset, s1 - vif1.irqoffset);
|
||||
if (vif1.irqoffset.enabled)
|
||||
ret = VIF1transfer(src + vif1.irqoffset.value, s1 - vif1.irqoffset.value);
|
||||
else
|
||||
ret = VIF1transfer(src, s1);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
if(vif1.irqoffset != 0) DevCon.Warning("VIF1 MFIFO Offest != 0! vifoffset=%x", vif1.irqoffset);
|
||||
if(vif1.irqoffset.value != 0) DevCon.Warning("VIF1 MFIFO Offest != 0! vifoffset=%x", vif1.irqoffset.value);
|
||||
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
|
||||
vif1ch.madr = maddr;
|
||||
|
||||
|
@ -97,8 +97,8 @@ static __fi bool mfifoVIF1rbTransfer()
|
|||
src = (u32*)PSM(vif1ch.madr);
|
||||
if (src == NULL) return false;
|
||||
|
||||
if (vif1.vifstalled)
|
||||
ret = VIF1transfer(src + vif1.irqoffset, mfifoqwc * 4 - vif1.irqoffset);
|
||||
if (vif1.irqoffset.enabled)
|
||||
ret = VIF1transfer(src + vif1.irqoffset.value, mfifoqwc * 4 - vif1.irqoffset.value);
|
||||
else
|
||||
ret = VIF1transfer(src, mfifoqwc << 2);
|
||||
|
||||
|
@ -138,8 +138,8 @@ static __fi void mfifo_VIF1chain()
|
|||
|
||||
if (pMem == NULL) return;
|
||||
|
||||
if (vif1.vifstalled)
|
||||
VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch.qwc * 4 - vif1.irqoffset);
|
||||
if (vif1.irqoffset.enabled)
|
||||
VIF1transfer((u32*)pMem + vif1.irqoffset.value, vif1ch.qwc * 4 - vif1.irqoffset.value);
|
||||
else
|
||||
VIF1transfer((u32*)pMem, vif1ch.qwc << 2);
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ void mfifoVIF1transfer(int qwc)
|
|||
if (qwc > 0)
|
||||
{
|
||||
//vifqwc += qwc;
|
||||
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vif1ch.chcr._u32, vif1.vifstalled, vif1.done);
|
||||
SPR_LOG("Added %x qw to mfifo,Vif CHCR %x Stalled %x done %x", qwc, vif1ch.chcr._u32, vif1.vifstalled.enabled, vif1.done);
|
||||
if (vif1.inprogress & 0x10)
|
||||
{
|
||||
if(vif1ch.chcr.STR == true && !(cpuRegs.interrupt & (1<<DMAC_MFIFO_VIF)))
|
||||
|
@ -187,28 +187,30 @@ void mfifoVIF1transfer(int qwc)
|
|||
|
||||
VIF_LOG("\tVIF1 SrcChain TTE=1, data = 0x%08x.%08x", masked_tag._u32[3], masked_tag._u32[2]);
|
||||
|
||||
if (vif1.vifstalled)
|
||||
if (vif1.irqoffset.enabled)
|
||||
{
|
||||
ret = VIF1transfer((u32*)&masked_tag + vif1.irqoffset, 4 - vif1.irqoffset, true); //Transfer Tag on stall
|
||||
ret = VIF1transfer((u32*)&masked_tag + vif1.irqoffset.value, 4 - vif1.irqoffset.value, true); //Transfer Tag on stall
|
||||
//ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset); //Transfer Tag on stall
|
||||
}
|
||||
else
|
||||
{
|
||||
vif1.irqoffset = 2;
|
||||
vif1.irqoffset.value = 2;
|
||||
vif1.irqoffset.enabled = true;
|
||||
ret = VIF1transfer((u32*)&masked_tag + 2, 2, true); //Transfer Tag
|
||||
//ret = VIF1transfer((u32*)ptag + 2, 2); //Transfer Tag
|
||||
}
|
||||
|
||||
if (!ret && vif1.irqoffset)
|
||||
if (!ret && vif1.irqoffset.enabled)
|
||||
{
|
||||
vif1.inprogress &= ~1;
|
||||
return; //IRQ set by VIFTransfer
|
||||
|
||||
} //else vif1.vifstalled = false;
|
||||
} //else vif1.vifstalled.enabled = false;
|
||||
g_vif1Cycles += 2;
|
||||
}
|
||||
|
||||
vif1.irqoffset = 0;
|
||||
vif1.irqoffset.value = 0;
|
||||
vif1.irqoffset.enabled = false;
|
||||
|
||||
vif1ch.unsafeTransfer(ptag);
|
||||
|
||||
|
@ -305,6 +307,8 @@ void vifMFIFOInterrupt()
|
|||
if(!(vif1.done && vif1ch.qwc == 0))return;
|
||||
}
|
||||
|
||||
vif1.vifstalled.enabled = false;
|
||||
|
||||
if (vif1.done == false || vif1ch.qwc) {
|
||||
switch(vif1.inprogress & 1) {
|
||||
case 0: //Set up transfer
|
||||
|
@ -330,7 +334,8 @@ void vifMFIFOInterrupt()
|
|||
return;
|
||||
}
|
||||
|
||||
vif1.vifstalled = false;
|
||||
vif1.vifstalled.enabled = false;
|
||||
vif1.irqoffset.enabled = false;
|
||||
vif1.done = 1;
|
||||
g_vif1Cycles = 0;
|
||||
vif1Regs.stat.FQC = min((u16)0x10, vif1ch.qwc);
|
||||
|
|
|
@ -44,7 +44,7 @@ static __fi void vuExecMicro(int idx, u32 addr) {
|
|||
int startcycles = 0;
|
||||
//vifFlush(idx);
|
||||
|
||||
//if(vifX.vifstalled == true) return;
|
||||
//if(vifX.vifstalled.enabled == true) return;
|
||||
|
||||
if (vifRegs.itops > (idx ? 0x3ffu : 0xffu)) {
|
||||
Console.WriteLn("VIF%d ITOP overrun! %x", idx, vifRegs.itops);
|
||||
|
@ -76,12 +76,14 @@ static __fi void vuExecMicro(int idx, u32 addr) {
|
|||
if (!idx) vu0ExecMicro(addr);
|
||||
else vu1ExecMicro(addr);
|
||||
|
||||
///NOTE: Shadowman 2 has SPS with this, uncommenting the correct code fixes it
|
||||
if (!idx) { startcycles = ((VU0.cycle-startcycles) + ( vif0ch.qwc - (vif0.vifpacketsize >> 2) )); CPU_INT(VIF_VU0_FINISH, 1/*startcycles * BIAS*/); }
|
||||
else { startcycles = ((VU1.cycle-startcycles) + ( vif1ch.qwc - (vif1.vifpacketsize >> 2) )); CPU_INT(VIF_VU1_FINISH, 1/*startcycles * BIAS*/); }
|
||||
|
||||
|
||||
//DevCon.Warning("Ran VU%x, VU0 Cycles %x, VU1 Cycles %x, start %x cycle %x", idx, g_vu0Cycles, g_vu1Cycles, startcycles, VU1.cycle);
|
||||
GetVifX.vifstalled = true;
|
||||
GetVifX.vifstalled.enabled = true;
|
||||
GetVifX.vifstalled.value = VIF_TIMING_BREAK;
|
||||
}
|
||||
|
||||
void ExecuteVU(int idx)
|
||||
|
@ -135,7 +137,8 @@ template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDire
|
|||
if (size != ret) { // Stall if gif didn't process all the data (path2 queued)
|
||||
GUNIT_WARN("Vif %s: Stall! [size=%d][ret=%d]", name, size, ret);
|
||||
//gifUnit.PrintInfo();
|
||||
vif1.vifstalled = true;
|
||||
vif1.vifstalled.enabled = true;
|
||||
vif1.vifstalled.value = VIF_TIMING_BREAK;
|
||||
vif1Regs.stat.VGW = true;
|
||||
return 0;
|
||||
}
|
||||
|
@ -168,7 +171,8 @@ vifOp(vifCode_Flush) {
|
|||
GUNIT_WARN("Vif Flush: Stall!");
|
||||
//gifUnit.PrintInfo();
|
||||
vif1Regs.stat.VGW = true;
|
||||
vifX.vifstalled = true;
|
||||
vifX.vifstalled.enabled = true;
|
||||
vifX.vifstalled.value = VIF_TIMING_BREAK;
|
||||
return 0;
|
||||
}
|
||||
else vifX.cmd = 0;
|
||||
|
@ -197,14 +201,7 @@ vifOp(vifCode_FlushA) {
|
|||
//p3.state= GIF_PATH_IDLE; // Does any game need this anymore?
|
||||
DevCon.Warning("Vif FlushA - path3 has no more data, but didn't EOP");
|
||||
}
|
||||
/*else { // Path 3 hasn't finished its current gs packet
|
||||
if (gifUnit.stat.APATH != 3 && gifUnit.Path3Masked()) {
|
||||
gifUnit.stat.APATH = 3; // Hack: Force path 3 to finish (persona 3 needs this)
|
||||
//DevCon.Warning("Vif FlushA - Forcing path3 to finish current packet");
|
||||
}
|
||||
gifInterrupt(); // Feed path3 some gif dma data
|
||||
gifUnit.Execute(); // Execute path3 in-case gifInterrupt() didn't...
|
||||
}*/
|
||||
|
||||
if (p3.state != GIF_PATH_IDLE) {
|
||||
doStall = true; // If path3 still isn't finished...
|
||||
}
|
||||
|
@ -213,7 +210,8 @@ vifOp(vifCode_FlushA) {
|
|||
}
|
||||
if (doStall) {
|
||||
vif1Regs.stat.VGW = true;
|
||||
vifX.vifstalled = true;
|
||||
vifX.vifstalled.enabled = true;
|
||||
vifX.vifstalled.value = VIF_TIMING_BREAK;
|
||||
return 0;
|
||||
}
|
||||
else vifX.cmd = 0;
|
||||
|
@ -274,7 +272,7 @@ vifOp(vifCode_MPG) {
|
|||
vifX.tag.addr = (u16)(vifXRegs.code << 3) & (idx ? 0x3fff : 0xfff);
|
||||
vifX.tag.size = vifNum ? (vifNum*2) : 512;
|
||||
vifFlush(idx);
|
||||
if(vifX.vifstalled == true) return 0;
|
||||
if(vifX.vifstalled.enabled == true) return 0;
|
||||
else
|
||||
{
|
||||
vifX.pass = 1;
|
||||
|
@ -331,7 +329,8 @@ vifOp(vifCode_MSCALF) {
|
|||
if (u32 a = gifUnit.checkPaths(1,1,0)) {
|
||||
GUNIT_WARN("Vif MSCALF: Stall! [%d,%d]", !!(a&1), !!(a&2));
|
||||
vif1Regs.stat.VGW = true;
|
||||
vifX.vifstalled = true;
|
||||
vifX.vifstalled.enabled = true;
|
||||
vifX.vifstalled.value = VIF_TIMING_BREAK;
|
||||
}
|
||||
if(vifX.waitforvu == false)
|
||||
{
|
||||
|
@ -396,7 +395,8 @@ vifOp(vifCode_Null) {
|
|||
if (!(vifXRegs.err.ME1)) { // Ignore vifcode and tag mismatch error
|
||||
Console.WriteLn("Vif%d: Unknown VifCmd! [%x]", idx, vifX.cmd);
|
||||
vifXRegs.stat.ER1 = true;
|
||||
vifX.vifstalled = true;
|
||||
vifX.vifstalled.enabled = true;
|
||||
vifX.vifstalled.value = VIF_IRQ_STALL;
|
||||
//vifX.irq++;
|
||||
}
|
||||
vifX.cmd = 0;
|
||||
|
|
|
@ -54,6 +54,11 @@ union tTRXREG {
|
|||
};
|
||||
};
|
||||
|
||||
struct tVIF_CTRL {
|
||||
bool enabled;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
// NOTE, if debugging vif stalls, use sega classics, spyro, gt4, and taito
|
||||
struct vifStruct {
|
||||
__aligned16 u128 MaskRow;
|
||||
|
@ -71,7 +76,7 @@ struct vifStruct {
|
|||
int irq;
|
||||
|
||||
bool done;
|
||||
bool vifstalled;
|
||||
tVIF_CTRL vifstalled;
|
||||
bool stallontag;
|
||||
bool waitforvu;
|
||||
|
||||
|
@ -81,7 +86,7 @@ struct vifStruct {
|
|||
tTRXREG TRXREG;
|
||||
u32 GSLastDownloadSize;
|
||||
|
||||
u8 irqoffset; // 32bit offset where next vif code is
|
||||
tVIF_CTRL irqoffset; // 32bit offset where next vif code is
|
||||
u32 vifpacketsize;
|
||||
u8 inprogress;
|
||||
u8 dmamode;
|
||||
|
|
|
@ -32,8 +32,8 @@ _vifT void vifTransferLoop(u32* &data) {
|
|||
|
||||
vifXRegs.stat.VPS |= VPS_TRANSFERRING;
|
||||
vifXRegs.stat.ER1 = false;
|
||||
|
||||
while (pSize > 0 && !vifX.vifstalled) {
|
||||
if(!idx)VIF_LOG("Starting VIF0 loop, pSize = %x, stalled = %x", pSize, vifX.vifstalled.enabled );
|
||||
while (pSize > 0 && !vifX.vifstalled.enabled) {
|
||||
|
||||
if(!vifX.cmd) { // Get new VifCode
|
||||
|
||||
|
@ -66,11 +66,8 @@ _vifT static __fi bool vifTransfer(u32 *data, int size, bool TTE) {
|
|||
vifStruct& vifX = GetVifX;
|
||||
|
||||
// irqoffset necessary to add up the right qws, or else will spin (spiderman)
|
||||
int transferred = vifX.irqoffset;
|
||||
|
||||
vifX.irqoffset = 0;
|
||||
vifX.vifstalled = false;
|
||||
vifX.stallontag = false;
|
||||
int transferred = vifX.irqoffset.enabled ? vifX.irqoffset.value : 0;
|
||||
|
||||
vifX.vifpacketsize = size;
|
||||
vifTransferLoop<idx>(data);
|
||||
|
||||
|
@ -81,15 +78,16 @@ _vifT static __fi bool vifTransfer(u32 *data, int size, bool TTE) {
|
|||
if (!idx) g_vif0Cycles += max(1, (int)((transferred * BIAS) >> 2));
|
||||
else g_vif1Cycles += max(1, (int)((transferred * BIAS) >> 2));
|
||||
|
||||
vifX.irqoffset = transferred % 4; // cannot lose the offset
|
||||
|
||||
vifX.irqoffset.value = transferred % 4; // cannot lose the offset
|
||||
|
||||
if (vifX.irq && vifX.cmd == 0) {
|
||||
//DevCon.WriteLn("Vif IRQ!");
|
||||
if(((vifXRegs.code >> 24) & 0x7f) != 0x7) {
|
||||
vifXRegs.stat.VIS = true; // Note: commenting this out fixes WALL-E?
|
||||
}
|
||||
//Always needs to be set to return to the correct offset if there is data left.
|
||||
vifX.vifstalled = true;
|
||||
vifX.vifstalled.enabled = true;
|
||||
vifX.vifstalled.value = VIF_IRQ_STALL;
|
||||
}
|
||||
|
||||
if (!TTE) // *WARNING* - Tags CAN have interrupts! so lets just ignore the dma modifying stuffs (GT4)
|
||||
|
@ -100,13 +98,22 @@ _vifT static __fi bool vifTransfer(u32 *data, int size, bool TTE) {
|
|||
|
||||
if (vifXch.chcr.STR) hwDmacSrcTadrInc(vifXch);
|
||||
|
||||
if(!vifXch.qwc) {
|
||||
if(!vifXch.qwc)
|
||||
vifX.inprogress &= ~0x1;
|
||||
vifX.vifstalled = false;
|
||||
}
|
||||
else if(vifX.irqoffset.value != 0)
|
||||
vifX.irqoffset.enabled = true;
|
||||
else
|
||||
vifX.irqoffset.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(vifX.irqoffset.value > 1)
|
||||
vifX.irqoffset.enabled = true;
|
||||
else
|
||||
vifX.irqoffset.enabled = false;
|
||||
}
|
||||
|
||||
return !vifX.vifstalled;
|
||||
return !vifX.vifstalled.enabled;
|
||||
}
|
||||
|
||||
// When TTE is set to 1, MADR and QWC are not updated as part of the transfer.
|
||||
|
|
Loading…
Reference in New Issue