Skip to content

Commit

Permalink
VIF: If Force break + Reset requested, Reset gets priority
Browse files Browse the repository at this point in the history
Fixes #5275
  • Loading branch information
refractionpcsx2 committed Jan 7, 2022
1 parent b9da7c6 commit 3951e15
Showing 1 changed file with 76 additions and 77 deletions.
153 changes: 76 additions & 77 deletions pcsx2/Vif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,40 +74,8 @@ void SaveStateBase::vif1Freeze()
__fi void vif0FBRST(u32 value)
{
VIF_LOG("VIF0_FBRST write32 0x%8.8x", value);

if (value & 0x1) // Reset Vif.
{
//Console.WriteLn("Vif0 Reset %x", vif0Regs.stat._u32);
u128 SaveCol;
u128 SaveRow;

// if(vif0ch.chcr.STR) DevCon.Warning("FBRST While Vif0 active");
//Must Preserve Row/Col registers! (Downhill Domination for testing)
SaveCol._u64[0] = vif0.MaskCol._u64[0];
SaveCol._u64[1] = vif0.MaskCol._u64[1];
SaveRow._u64[0] = vif0.MaskRow._u64[0];
SaveRow._u64[1] = vif0.MaskRow._u64[1];
memzero(vif0);
vif0.MaskCol._u64[0] = SaveCol._u64[0];
vif0.MaskCol._u64[1] = SaveCol._u64[1];
vif0.MaskRow._u64[0] = SaveRow._u64[0];
vif0.MaskRow._u64[1] = SaveRow._u64[1];
vif0ch.qwc = 0; //?
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
psHu64(VIF0_FIFO) = 0;
psHu64(VIF0_FIFO + 8) = 0;
vif0.vifstalled.enabled = false;
vif0.irqoffset.enabled = false;
vif0.inprogress = 0;
vif0.cmd = 0;
vif0.done = true;
vif0ch.chcr.STR = false;
vif0Regs.err.reset();
vif0Regs.stat.clear_flags(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0
}

/* Fixme: Forcebreaks are pretty unknown for operation, presumption is it just stops it what its doing
usually accompanied by a reset, but if we find a broken game which falls here, we need to see it! (Refraction) */
usually accompanied by a reset, but if we find a broken game which falls here, we need to see it! (Refraction) */
if (value & 0x2) // Forcebreak Vif,
{
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
Expand Down Expand Up @@ -145,42 +113,45 @@ __fi void vif0FBRST(u32 value)
CPU_INT(DMAC_VIF0, 0); // Gets the timing right - Flatout
}
}
}

__fi void vif1FBRST(u32 value)
{
VIF_LOG("VIF1_FBRST write32 0x%8.8x", value);

if (FBRST(value).RST) // Reset Vif.
if (value & 0x1) // Reset Vif.
{
//Console.WriteLn("Vif0 Reset %x", vif0Regs.stat._u32);
u128 SaveCol;
u128 SaveRow;
//if(vif1ch.chcr.STR) DevCon.Warning("FBRST While Vif1 active");
//Must Preserve Row/Col registers! (Downhill Domination for testing) - Really shouldnt be part of the vifstruct.
SaveCol._u64[0] = vif1.MaskCol._u64[0];
SaveCol._u64[1] = vif1.MaskCol._u64[1];
SaveRow._u64[0] = vif1.MaskRow._u64[0];
SaveRow._u64[1] = vif1.MaskRow._u64[1];
u8 mfifo_empty = vif1.inprogress & 0x10;
memzero(vif1);
vif1.MaskCol._u64[0] = SaveCol._u64[0];
vif1.MaskCol._u64[1] = SaveCol._u64[1];
vif1.MaskRow._u64[0] = SaveRow._u64[0];
vif1.MaskRow._u64[1] = SaveRow._u64[1];


GUNIT_WARN(Color_Red, "VIF FBRST Reset MSK = %x", vif1Regs.mskpath3);
vif1Regs.mskpath3 = false;
gifRegs.stat.M3P = 0;
vif1Regs.err.reset();
vif1.inprogress = mfifo_empty;
vif1.cmd = 0;
vif1.vifstalled.enabled = false;
vif1Regs.stat._u32 = 0;
// if(vif0ch.chcr.STR) DevCon.Warning("FBRST While Vif0 active");
//Must Preserve Row/Col registers! (Downhill Domination for testing)
SaveCol._u64[0] = vif0.MaskCol._u64[0];
SaveCol._u64[1] = vif0.MaskCol._u64[1];
SaveRow._u64[0] = vif0.MaskRow._u64[0];
SaveRow._u64[1] = vif0.MaskRow._u64[1];
memzero(vif0);
vif0.MaskCol._u64[0] = SaveCol._u64[0];
vif0.MaskCol._u64[1] = SaveCol._u64[1];
vif0.MaskRow._u64[0] = SaveRow._u64[0];
vif0.MaskRow._u64[1] = SaveRow._u64[1];
vif0ch.qwc = 0; //?
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
psHu64(VIF0_FIFO) = 0;
psHu64(VIF0_FIFO + 8) = 0;
vif0.vifstalled.enabled = false;
vif0.irqoffset.enabled = false;
vif0.inprogress = 0;
vif0.cmd = 0;
vif0.done = true;
vif0ch.chcr.STR = false;
vif0Regs.err.reset();
vif0Regs.stat.clear_flags(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0
}
}

__fi void vif1FBRST(u32 value)
{
VIF_LOG("VIF1_FBRST write32 0x%8.8x", value);

/* Fixme: Forcebreaks are pretty unknown for operation, presumption is it just stops it what its doing
usually accompanied by a reset, but if we find a broken game which falls here, we need to see it! (Refraction) */
usually accompanied by a reset, but if we find a broken game which falls here, we need to see it! (Refraction) */

if (FBRST(value).FBK) // Forcebreak Vif.
{
Expand All @@ -196,7 +167,7 @@ __fi void vif1FBRST(u32 value)
if (FBRST(value).STP) // Stop Vif.
{
// Not completely sure about this, can't remember what game used this, but 'draining' the VIF helped it, instead of
// just stoppin the VIF (linuz).
// just stoppin the VIF (linuz).
vif1Regs.stat.VSS = true;
vif1Regs.stat.VPS = VPS_IDLE;
vif1.vifstalled.enabled = VifStallEnable(vif1ch);
Expand All @@ -207,7 +178,7 @@ __fi void vif1FBRST(u32 value)
{
bool cancel = false;
//DevCon.Warning("Cancel stall. Stat = %x", vif1Regs.stat._u32);
/* Cancel stall, first check if there is a stall to cancel, and then clear VIF1_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */
// Cancel stall, first check if there is a stall to cancel, and then clear VIF1_STAT VSS|VFS|VIS|INT|ER0|ER1 bits
if (vif1Regs.stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{
cancel = true;
Expand All @@ -222,25 +193,53 @@ __fi void vif1FBRST(u32 value)
// loop necessary for spiderman
switch (dmacRegs.ctrl.MFD)
{
case MFD_VIF1:
//Console.WriteLn("MFIFO Stall");
//MFIFO active and not empty
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 && !vif1Regs.stat.test(VIF1_STAT_FDR))
CPU_INT(DMAC_VIF1, 0);
break;
case MFD_VIF1:
//Console.WriteLn("MFIFO Stall");
//MFIFO active and not empty
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 && !vif1Regs.stat.test(VIF1_STAT_FDR))
CPU_INT(DMAC_VIF1, 0);
break;
}

//vif1ch.chcr.STR = true;
}
}

if (FBRST(value).RST) // Reset Vif.
{
u128 SaveCol;
u128 SaveRow;
//if(vif1ch.chcr.STR) DevCon.Warning("FBRST While Vif1 active");
//Must Preserve Row/Col registers! (Downhill Domination for testing) - Really shouldnt be part of the vifstruct.
SaveCol._u64[0] = vif1.MaskCol._u64[0];
SaveCol._u64[1] = vif1.MaskCol._u64[1];
SaveRow._u64[0] = vif1.MaskRow._u64[0];
SaveRow._u64[1] = vif1.MaskRow._u64[1];
u8 mfifo_empty = vif1.inprogress & 0x10;
memzero(vif1);
vif1.MaskCol._u64[0] = SaveCol._u64[0];
vif1.MaskCol._u64[1] = SaveCol._u64[1];
vif1.MaskRow._u64[0] = SaveRow._u64[0];
vif1.MaskRow._u64[1] = SaveRow._u64[1];


GUNIT_WARN(Color_Red, "VIF FBRST Reset MSK = %x", vif1Regs.mskpath3);
vif1Regs.mskpath3 = false;
gifRegs.stat.M3P = 0;
vif1Regs.err.reset();
vif1.inprogress = mfifo_empty;
vif1.cmd = 0;
vif1.vifstalled.enabled = false;
vif1Regs.stat._u32 = 0;
}
}

__fi void vif1STAT(u32 value)
Expand Down

0 comments on commit 3951e15

Please sign in to comment.