mirror of https://github.com/PCSX2/pcsx2.git
Unified vif0 and vif1's write32 functions...
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2518 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
5fa30179a8
commit
46079853f9
|
@ -121,9 +121,7 @@ tDMAC_QUEUE QueuedDMA(0);
|
||||||
|
|
||||||
void hwWrite8(u32 mem, u8 value)
|
void hwWrite8(u32 mem, u8 value)
|
||||||
{
|
{
|
||||||
if ((mem >= VIF0_STAT) && (mem < VIF0_FIFO))
|
if ((mem >= VIF0_STAT) && (mem < VIF0_FIFO)) {
|
||||||
{
|
|
||||||
DevCon.WriteLn("vif write8!"); // Is this ever called?
|
|
||||||
u32 bytemod = mem & 0x3;
|
u32 bytemod = mem & 0x3;
|
||||||
u32 bitpos = 8 * bytemod;
|
u32 bitpos = 8 * bytemod;
|
||||||
u32 oldval = ~(0xff << bitpos) & psHu32(mem);
|
u32 oldval = ~(0xff << bitpos) & psHu32(mem);
|
||||||
|
|
249
pcsx2/Vif.cpp
249
pcsx2/Vif.cpp
|
@ -17,6 +17,8 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Vif.h"
|
#include "Vif.h"
|
||||||
#include "Vif_Dma.h"
|
#include "Vif_Dma.h"
|
||||||
|
#include "GS.h"
|
||||||
|
#include "Gif.h"
|
||||||
|
|
||||||
void vif0Init() { initNewVif(0); }
|
void vif0Init() { initNewVif(0); }
|
||||||
void vif1Init() { initNewVif(1); }
|
void vif1Init() { initNewVif(1); }
|
||||||
|
@ -82,3 +84,250 @@ void SaveStateBase::vif1Freeze()
|
||||||
Freeze(g_vif1HasMask3); // Not Used Anymore
|
Freeze(g_vif1HasMask3); // Not Used Anymore
|
||||||
Freeze(g_vif1Masks); // Not Used Anymore
|
Freeze(g_vif1Masks); // Not Used Anymore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// Vif0/Vif1 Write32
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
extern bool _chainVIF0();
|
||||||
|
extern bool _VIF0chain();
|
||||||
|
|
||||||
|
_f 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);
|
||||||
|
|
||||||
|
memzero(vif0);
|
||||||
|
vif0ch->qwc = 0; //?
|
||||||
|
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
|
||||||
|
psHu64(VIF0_FIFO) = 0;
|
||||||
|
psHu64(VIF0_FIFO + 8) = 0;
|
||||||
|
vif0.done = true;
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value & 0x2) // Forcebreak Vif,
|
||||||
|
{
|
||||||
|
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
|
||||||
|
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
|
||||||
|
vif0Regs->stat.VFS = true;
|
||||||
|
vif0Regs->stat.VPS = VPS_IDLE;
|
||||||
|
vif0.vifstalled = true;
|
||||||
|
Console.WriteLn("vif0 force break");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value & 0x4) // 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).
|
||||||
|
vif0Regs->stat.VSS = true;
|
||||||
|
vif0Regs->stat.VPS = VPS_IDLE;
|
||||||
|
vif0.vifstalled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value & 0x8) // Cancel Vif Stall.
|
||||||
|
{
|
||||||
|
bool cancel = false;
|
||||||
|
|
||||||
|
/* Cancel stall, first check if there is a stall to cancel, and then clear VIF0_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */
|
||||||
|
if (vif0Regs->stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
|
||||||
|
cancel = true;
|
||||||
|
|
||||||
|
vif0Regs->stat.clear_flags(VIF0_STAT_VSS | VIF0_STAT_VFS | VIF0_STAT_VIS |
|
||||||
|
VIF0_STAT_INT | VIF0_STAT_ER0 | VIF0_STAT_ER1);
|
||||||
|
if (cancel)
|
||||||
|
{
|
||||||
|
if (vif0.vifstalled)
|
||||||
|
{
|
||||||
|
g_vifCycles = 0;
|
||||||
|
|
||||||
|
// loop necessary for spiderman
|
||||||
|
if (vif0.stallontag)
|
||||||
|
_chainVIF0();
|
||||||
|
else
|
||||||
|
_VIF0chain();
|
||||||
|
|
||||||
|
vif0ch->chcr.STR = true;
|
||||||
|
CPU_INT(0, g_vifCycles); // Gets the timing right - Flatout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_f void vif1FBRST(u32 value) {
|
||||||
|
VIF_LOG("VIF1_FBRST write32 0x%8.8x", value);
|
||||||
|
|
||||||
|
if (FBRST(value).RST) // Reset Vif.
|
||||||
|
{
|
||||||
|
memzero(vif1);
|
||||||
|
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||||
|
vif1ch->qwc = 0; //?
|
||||||
|
psHu64(VIF1_FIFO) = 0;
|
||||||
|
psHu64(VIF1_FIFO + 8) = 0;
|
||||||
|
vif1.done = true;
|
||||||
|
|
||||||
|
if(vif1Regs->mskpath3)
|
||||||
|
{
|
||||||
|
vif1Regs->mskpath3 = 0;
|
||||||
|
gifRegs->stat.IMT = false;
|
||||||
|
if (gif->chcr.STR) CPU_INT(2, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
vif1Regs->err.reset();
|
||||||
|
vif1.inprogress = 0;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FBRST(value).FBK) // Forcebreak Vif.
|
||||||
|
{
|
||||||
|
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
|
||||||
|
vif1Regs->stat.VFS = true;
|
||||||
|
vif1Regs->stat.VPS = VPS_IDLE;
|
||||||
|
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||||
|
vif1.vifstalled = true;
|
||||||
|
Console.WriteLn("vif1 force break");
|
||||||
|
}
|
||||||
|
|
||||||
|
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).
|
||||||
|
vif1Regs->stat.VSS = true;
|
||||||
|
vif1Regs->stat.VPS = VPS_IDLE;
|
||||||
|
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||||
|
vif1.vifstalled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FBRST(value).STC) // Cancel Vif Stall.
|
||||||
|
{
|
||||||
|
bool cancel = false;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
vif1Regs->stat.clear_flags(VIF1_STAT_VSS | VIF1_STAT_VFS | VIF1_STAT_VIS |
|
||||||
|
VIF1_STAT_INT | VIF1_STAT_ER0 | VIF1_STAT_ER1);
|
||||||
|
|
||||||
|
if (cancel)
|
||||||
|
{
|
||||||
|
if (vif1.vifstalled)
|
||||||
|
{
|
||||||
|
g_vifCycles = 0;
|
||||||
|
// loop necessary for spiderman
|
||||||
|
switch(dmacRegs->ctrl.MFD)
|
||||||
|
{
|
||||||
|
case MFD_VIF1:
|
||||||
|
//Console.WriteLn("MFIFO Stall");
|
||||||
|
CPU_INT(10, vif1ch->qwc * BIAS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NO_MFD:
|
||||||
|
case MFD_RESERVED:
|
||||||
|
case MFD_GIF: // Wonder if this should be with VIF?
|
||||||
|
// Gets the timing right - Flatout
|
||||||
|
CPU_INT(1, vif1ch->qwc * BIAS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
vif1ch->chcr.STR = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_f void vif1STAT(u32 value) {
|
||||||
|
VIF_LOG("VIF1_STAT write32 0x%8.8x", value);
|
||||||
|
|
||||||
|
/* Only FDR bit is writable, so mask the rest */
|
||||||
|
if ((vif1Regs->stat.FDR) ^ ((tVIF_STAT&)value).FDR) {
|
||||||
|
// different so can't be stalled
|
||||||
|
if (vif1Regs->stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) {
|
||||||
|
DevCon.WriteLn("changing dir when vif1 fifo stalled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vif1Regs->stat.FDR = VIF_STAT(value).FDR;
|
||||||
|
|
||||||
|
if (vif1Regs->stat.FDR) // Vif transferring to memory.
|
||||||
|
{
|
||||||
|
// Hack but it checks this is true before transfer? (fatal frame)
|
||||||
|
vif1Regs->stat.FQC = 0x1;
|
||||||
|
}
|
||||||
|
else // Memory transferring to Vif.
|
||||||
|
{
|
||||||
|
vif1ch->qwc = 0;
|
||||||
|
vif1.vifstalled = false;
|
||||||
|
vif1.done = true;
|
||||||
|
vif1Regs->stat.FQC = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define caseVif(x) (idx ? VIF1_##x : VIF0_##x)
|
||||||
|
|
||||||
|
_vifT void vifWrite32(u32 mem, u32 value) {
|
||||||
|
switch (mem) {
|
||||||
|
case caseVif(MARK):
|
||||||
|
VIF_LOG("VIF%d_MARK write32 0x%8.8x", idx, value);
|
||||||
|
vifXRegs->stat.MRK = false;
|
||||||
|
vifXRegs->mark = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case caseVif(FBRST):
|
||||||
|
if (!idx) vif0FBRST(value);
|
||||||
|
else vif1FBRST(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case caseVif(ERR):
|
||||||
|
VIF_LOG("VIF%d_ERR write32 0x%8.8x", idx, value);
|
||||||
|
vifXRegs->err.write(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case caseVif(STAT):
|
||||||
|
if (idx) { // Only Vif1 does this stuff?
|
||||||
|
vif1STAT(value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Console.WriteLn("Unknown Vif%d write to %x", idx, mem);
|
||||||
|
psHu32(mem) = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case caseVif(MODE):
|
||||||
|
vifXRegs->mode = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case caseVif(R0):
|
||||||
|
case caseVif(R1):
|
||||||
|
case caseVif(R2):
|
||||||
|
case caseVif(R3):
|
||||||
|
if (!idx) g_vifmask.Row0[ (mem>>4)&3 ] = value;
|
||||||
|
else g_vifmask.Row1[ (mem>>4)&3 ] = value;
|
||||||
|
((u32*)&vifXRegs->r0) [((mem>>4)&3)*4] = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case caseVif(C0):
|
||||||
|
case caseVif(C1):
|
||||||
|
case caseVif(C2):
|
||||||
|
case caseVif(C3):
|
||||||
|
if (!idx) g_vifmask.Col0[ (mem>>4)&3 ] = value;
|
||||||
|
else g_vifmask.Col1[ (mem>>4)&3 ] = value;
|
||||||
|
((u32*)&vifXRegs->c0) [((mem>>4)&3)*4] = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Console.WriteLn("Unknown Vif%d write to %x", idx, mem);
|
||||||
|
psHu32(mem) = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Other registers are read-only so do nothing for them */
|
||||||
|
}
|
||||||
|
|
||||||
|
void vif0Write32(u32 mem, u32 value) { vifWrite32<0>(mem, value); }
|
||||||
|
void vif1Write32(u32 mem, u32 value) { vifWrite32<1>(mem, value); }
|
||||||
|
|
|
@ -217,6 +217,11 @@ extern VIFregisters *vifRegs;
|
||||||
#define vif0Regs (&vif0RegsRef)
|
#define vif0Regs (&vif0RegsRef)
|
||||||
#define vif1Regs (&vif1RegsRef)
|
#define vif1Regs (&vif1RegsRef)
|
||||||
|
|
||||||
|
#define _vifT template <int idx>
|
||||||
|
#define vifX (idx ? vif1 : vif0)
|
||||||
|
#define vifXRegs (idx ? (vif1Regs) : (vif0Regs))
|
||||||
|
#define _f __forceinline
|
||||||
|
|
||||||
extern void dmaVIF0();
|
extern void dmaVIF0();
|
||||||
extern void dmaVIF1();
|
extern void dmaVIF1();
|
||||||
extern void mfifoVIF1transfer(int qwc);
|
extern void mfifoVIF1transfer(int qwc);
|
||||||
|
|
|
@ -333,114 +333,3 @@ void dmaVIF0()
|
||||||
vif0.done = false;
|
vif0.done = false;
|
||||||
CPU_INT(0, 0);
|
CPU_INT(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vif0Write32(u32 mem, u32 value)
|
|
||||||
{
|
|
||||||
switch (mem)
|
|
||||||
{
|
|
||||||
case VIF0_MARK:
|
|
||||||
VIF_LOG("VIF0_MARK write32 0x%8.8x", value);
|
|
||||||
|
|
||||||
/* Clear mark flag in VIF0_STAT and set mark with 'value' */
|
|
||||||
vif0Regs->stat.MRK = false;
|
|
||||||
vif0Regs->mark = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIF0_FBRST:
|
|
||||||
VIF_LOG("VIF0_FBRST write32 0x%8.8x", value);
|
|
||||||
|
|
||||||
if (value & 0x1) // Reset Vif.
|
|
||||||
{
|
|
||||||
//Console.WriteLn("Vif0 Reset %x", vif0Regs->stat._u32);
|
|
||||||
|
|
||||||
memzero(vif0);
|
|
||||||
vif0ch->qwc = 0; //?
|
|
||||||
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
|
|
||||||
psHu64(VIF0_FIFO) = 0;
|
|
||||||
psHu64(VIF0_FIFO + 8) = 0;
|
|
||||||
vif0.done = true;
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value & 0x2) // Forcebreak Vif,
|
|
||||||
{
|
|
||||||
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
|
|
||||||
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
|
|
||||||
vif0Regs->stat.VFS = true;
|
|
||||||
vif0Regs->stat.VPS = VPS_IDLE;
|
|
||||||
vif0.vifstalled = true;
|
|
||||||
Console.WriteLn("vif0 force break");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value & 0x4) // 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).
|
|
||||||
vif0Regs->stat.VSS = true;
|
|
||||||
vif0Regs->stat.VPS = VPS_IDLE;
|
|
||||||
vif0.vifstalled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value & 0x8) // Cancel Vif Stall.
|
|
||||||
{
|
|
||||||
bool cancel = false;
|
|
||||||
|
|
||||||
/* Cancel stall, first check if there is a stall to cancel, and then clear VIF0_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */
|
|
||||||
if (vif0Regs->stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
|
|
||||||
cancel = true;
|
|
||||||
|
|
||||||
vif0Regs->stat.clear_flags(VIF0_STAT_VSS | VIF0_STAT_VFS | VIF0_STAT_VIS |
|
|
||||||
VIF0_STAT_INT | VIF0_STAT_ER0 | VIF0_STAT_ER1);
|
|
||||||
if (cancel)
|
|
||||||
{
|
|
||||||
if (vif0.vifstalled)
|
|
||||||
{
|
|
||||||
g_vifCycles = 0;
|
|
||||||
|
|
||||||
// loop necessary for spiderman
|
|
||||||
if (vif0.stallontag)
|
|
||||||
_chainVIF0();
|
|
||||||
else
|
|
||||||
_VIF0chain();
|
|
||||||
|
|
||||||
vif0ch->chcr.STR = true;
|
|
||||||
CPU_INT(0, g_vifCycles); // Gets the timing right - Flatout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIF0_ERR:
|
|
||||||
// ERR
|
|
||||||
VIF_LOG("VIF0_ERR write32 0x%8.8x", value);
|
|
||||||
|
|
||||||
/* Set VIF0_ERR with 'value' */
|
|
||||||
vif0Regs->err.write(value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIF0_R0:
|
|
||||||
case VIF0_R1:
|
|
||||||
case VIF0_R2:
|
|
||||||
case VIF0_R3:
|
|
||||||
pxAssume((mem&0xf) == 0);
|
|
||||||
g_vifmask.Row0 [ (mem>>4)&3 ] = value;
|
|
||||||
((u32*)&vif0Regs->r0)[((mem>>4)&3)*4] = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIF0_C0:
|
|
||||||
case VIF0_C1:
|
|
||||||
case VIF0_C2:
|
|
||||||
case VIF0_C3:
|
|
||||||
pxAssume((mem&0xf) == 0);
|
|
||||||
g_vifmask.Col0 [ (mem>>4)&3 ] = value;
|
|
||||||
((u32*)&vif0Regs->c0)[((mem>>4)&3)*4] = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Console.WriteLn("Unknown Vif0 write to %x", mem);
|
|
||||||
psHu32(mem) = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Other registers are read-only so do nothing for them */
|
|
||||||
}
|
|
||||||
|
|
|
@ -519,169 +519,3 @@ void dmaVIF1()
|
||||||
vif1.done = false;
|
vif1.done = false;
|
||||||
vif1Interrupt();
|
vif1Interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vif1Write32(u32 mem, u32 value)
|
|
||||||
{
|
|
||||||
switch (mem)
|
|
||||||
{
|
|
||||||
case VIF1_MARK:
|
|
||||||
VIF_LOG("VIF1_MARK write32 0x%8.8x", value);
|
|
||||||
|
|
||||||
/* Clear mark flag in VIF1_STAT and set mark with 'value' */
|
|
||||||
vif1Regs->stat.MRK = false;
|
|
||||||
vif1Regs->mark = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIF1_FBRST: // FBRST
|
|
||||||
VIF_LOG("VIF1_FBRST write32 0x%8.8x", value);
|
|
||||||
|
|
||||||
if (FBRST(value).RST) // Reset Vif.
|
|
||||||
{
|
|
||||||
memzero(vif1);
|
|
||||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
|
||||||
vif1ch->qwc = 0; //?
|
|
||||||
psHu64(VIF1_FIFO) = 0;
|
|
||||||
psHu64(VIF1_FIFO + 8) = 0;
|
|
||||||
vif1.done = true;
|
|
||||||
|
|
||||||
if(vif1Regs->mskpath3)
|
|
||||||
{
|
|
||||||
vif1Regs->mskpath3 = 0;
|
|
||||||
gifRegs->stat.IMT = false;
|
|
||||||
if (gif->chcr.STR) CPU_INT(2, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
vif1Regs->err.reset();
|
|
||||||
vif1.inprogress = 0;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FBRST(value).FBK) // Forcebreak Vif.
|
|
||||||
{
|
|
||||||
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
|
|
||||||
vif1Regs->stat.VFS = true;
|
|
||||||
vif1Regs->stat.VPS = VPS_IDLE;
|
|
||||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
|
||||||
vif1.vifstalled = true;
|
|
||||||
Console.WriteLn("vif1 force break");
|
|
||||||
}
|
|
||||||
|
|
||||||
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).
|
|
||||||
vif1Regs->stat.VSS = true;
|
|
||||||
vif1Regs->stat.VPS = VPS_IDLE;
|
|
||||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
|
||||||
vif1.vifstalled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FBRST(value).STC) // Cancel Vif Stall.
|
|
||||||
{
|
|
||||||
bool cancel = false;
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
vif1Regs->stat.clear_flags(VIF1_STAT_VSS | VIF1_STAT_VFS | VIF1_STAT_VIS |
|
|
||||||
VIF1_STAT_INT | VIF1_STAT_ER0 | VIF1_STAT_ER1);
|
|
||||||
|
|
||||||
if (cancel)
|
|
||||||
{
|
|
||||||
if (vif1.vifstalled)
|
|
||||||
{
|
|
||||||
g_vifCycles = 0;
|
|
||||||
// loop necessary for spiderman
|
|
||||||
switch(dmacRegs->ctrl.MFD)
|
|
||||||
{
|
|
||||||
case MFD_VIF1:
|
|
||||||
//Console.WriteLn("MFIFO Stall");
|
|
||||||
CPU_INT(10, vif1ch->qwc * BIAS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NO_MFD:
|
|
||||||
case MFD_RESERVED:
|
|
||||||
case MFD_GIF: // Wonder if this should be with VIF?
|
|
||||||
// Gets the timing right - Flatout
|
|
||||||
CPU_INT(1, vif1ch->qwc * BIAS);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
vif1ch->chcr.STR = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIF1_ERR: // ERR
|
|
||||||
VIF_LOG("VIF1_ERR write32 0x%8.8x", value);
|
|
||||||
|
|
||||||
/* Set VIF1_ERR with 'value' */
|
|
||||||
vif1Regs->err.write(value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIF1_STAT: // STAT
|
|
||||||
VIF_LOG("VIF1_STAT write32 0x%8.8x", value);
|
|
||||||
|
|
||||||
#ifdef PCSX2_DEVBUILD
|
|
||||||
/* Only FDR bit is writable, so mask the rest */
|
|
||||||
if ((vif1Regs->stat.FDR) ^ ((tVIF_STAT&)value).FDR)
|
|
||||||
{
|
|
||||||
// different so can't be stalled
|
|
||||||
if (vif1Regs->stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
|
|
||||||
{
|
|
||||||
DevCon.WriteLn("changing dir when vif1 fifo stalled");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vif1Regs->stat.FDR = VIF_STAT(value).FDR;
|
|
||||||
|
|
||||||
if (vif1Regs->stat.FDR) // Vif transferring to memory.
|
|
||||||
{
|
|
||||||
// Hack but it checks this is true before transfer? (fatal frame)
|
|
||||||
vif1Regs->stat.FQC = 0x1;
|
|
||||||
}
|
|
||||||
else // Memory transferring to Vif.
|
|
||||||
{
|
|
||||||
vif1ch->qwc = 0;
|
|
||||||
vif1.vifstalled = false;
|
|
||||||
vif1.done = true;
|
|
||||||
vif1Regs->stat.FQC = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIF1_MODE:
|
|
||||||
vif1Regs->mode = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIF1_R0:
|
|
||||||
case VIF1_R1:
|
|
||||||
case VIF1_R2:
|
|
||||||
case VIF1_R3:
|
|
||||||
pxAssume((mem&0xf) == 0);
|
|
||||||
g_vifmask.Row1 [ (mem>>4)&3 ] = value;
|
|
||||||
((u32*)&vif1Regs->r0)[((mem>>4)&3)*4] = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIF1_C0:
|
|
||||||
case VIF1_C1:
|
|
||||||
case VIF1_C2:
|
|
||||||
case VIF1_C3:
|
|
||||||
pxAssume((mem&0xf) == 0);
|
|
||||||
g_vifmask.Col1 [ (mem>>4)&3 ] = value;
|
|
||||||
((u32*)&vif1Regs->c0)[((mem>>4)&3)*4] = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Console.WriteLn("Unknown Vif1 write to %x", mem);
|
|
||||||
psHu32(mem) = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Other registers are read-only so do nothing for them */
|
|
||||||
}
|
|
||||||
|
|
|
@ -21,14 +21,15 @@
|
||||||
#include "newVif.h"
|
#include "newVif.h"
|
||||||
#include "VUmicro.h"
|
#include "VUmicro.h"
|
||||||
|
|
||||||
#define _vifT template <int idx>
|
|
||||||
#define vifX (idx ? vif1 : vif0)
|
|
||||||
#define vifXRegs (idx ? (vif1Regs) : (vif0Regs))
|
|
||||||
#define vif1Only() { if (!idx) { vifCMD_Null<idx>(); return; } }
|
#define vif1Only() { if (!idx) { vifCMD_Null<idx>(); return; } }
|
||||||
#define vif1Only_() { if (!idx) { return vifTrans_Null<idx>(NULL); } }
|
#define vif1Only_() { if (!idx) { return vifTrans_Null<idx>(NULL); } }
|
||||||
|
|
||||||
_vifT void vifCMD_Null();
|
_vifT void vifCMD_Null();
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// Vif0/Vif1 Misc Functions
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
_f void vifFlush(int idx) {
|
_f void vifFlush(int idx) {
|
||||||
if (!idx) vif0FLUSH();
|
if (!idx) vif0FLUSH();
|
||||||
else vif1FLUSH();
|
else vif1FLUSH();
|
||||||
|
|
Loading…
Reference in New Issue