From 46079853f9392a9f03dad279831392656da2dfcb Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Mon, 25 Jan 2010 07:42:45 +0000 Subject: [PATCH] Unified vif0 and vif1's write32 functions... git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2518 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/HwWrite.cpp | 4 +- pcsx2/Vif.cpp | 249 +++++++++++++++++++++++++++++++++++++++++ pcsx2/Vif.h | 5 + pcsx2/Vif0_Dma.cpp | 111 ------------------ pcsx2/Vif1_Dma.cpp | 166 --------------------------- pcsx2/Vif_Commands.cpp | 7 +- 6 files changed, 259 insertions(+), 283 deletions(-) diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index 30907ff6e8..6399578945 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -121,9 +121,7 @@ tDMAC_QUEUE QueuedDMA(0); void hwWrite8(u32 mem, u8 value) { - if ((mem >= VIF0_STAT) && (mem < VIF0_FIFO)) - { - DevCon.WriteLn("vif write8!"); // Is this ever called? + if ((mem >= VIF0_STAT) && (mem < VIF0_FIFO)) { u32 bytemod = mem & 0x3; u32 bitpos = 8 * bytemod; u32 oldval = ~(0xff << bitpos) & psHu32(mem); diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index 49c48aefda..e9757b282a 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -17,6 +17,8 @@ #include "Common.h" #include "Vif.h" #include "Vif_Dma.h" +#include "GS.h" +#include "Gif.h" void vif0Init() { initNewVif(0); } void vif1Init() { initNewVif(1); } @@ -82,3 +84,250 @@ void SaveStateBase::vif1Freeze() Freeze(g_vif1HasMask3); // 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); } diff --git a/pcsx2/Vif.h b/pcsx2/Vif.h index ac0203705c..ddcb2defa5 100644 --- a/pcsx2/Vif.h +++ b/pcsx2/Vif.h @@ -217,6 +217,11 @@ extern VIFregisters *vifRegs; #define vif0Regs (&vif0RegsRef) #define vif1Regs (&vif1RegsRef) +#define _vifT template +#define vifX (idx ? vif1 : vif0) +#define vifXRegs (idx ? (vif1Regs) : (vif0Regs)) +#define _f __forceinline + extern void dmaVIF0(); extern void dmaVIF1(); extern void mfifoVIF1transfer(int qwc); diff --git a/pcsx2/Vif0_Dma.cpp b/pcsx2/Vif0_Dma.cpp index 3076d22554..43a19a5b87 100644 --- a/pcsx2/Vif0_Dma.cpp +++ b/pcsx2/Vif0_Dma.cpp @@ -333,114 +333,3 @@ void dmaVIF0() vif0.done = false; 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 */ -} diff --git a/pcsx2/Vif1_Dma.cpp b/pcsx2/Vif1_Dma.cpp index ff4d338394..935c91d184 100644 --- a/pcsx2/Vif1_Dma.cpp +++ b/pcsx2/Vif1_Dma.cpp @@ -519,169 +519,3 @@ void dmaVIF1() vif1.done = false; 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 */ -} diff --git a/pcsx2/Vif_Commands.cpp b/pcsx2/Vif_Commands.cpp index 853cd5261f..c091a3af85 100644 --- a/pcsx2/Vif_Commands.cpp +++ b/pcsx2/Vif_Commands.cpp @@ -21,14 +21,15 @@ #include "newVif.h" #include "VUmicro.h" -#define _vifT template -#define vifX (idx ? vif1 : vif0) -#define vifXRegs (idx ? (vif1Regs) : (vif0Regs)) #define vif1Only() { if (!idx) { vifCMD_Null(); return; } } #define vif1Only_() { if (!idx) { return vifTrans_Null(NULL); } } _vifT void vifCMD_Null(); +//------------------------------------------------------------------ +// Vif0/Vif1 Misc Functions +//------------------------------------------------------------------ + _f void vifFlush(int idx) { if (!idx) vif0FLUSH(); else vif1FLUSH();