diff --git a/pcsx2/COP0.cpp b/pcsx2/COP0.cpp index 936380f5be..696cadb12d 100644 --- a/pcsx2/COP0.cpp +++ b/pcsx2/COP0.cpp @@ -433,7 +433,7 @@ void MTC0() } int CPCOND0() { - return (((psHu16(DMAC_STAT) | ~psHu16(DMAC_PCR)) & 0x3ff) == 0x3ff); + return ((dmacRegs->stat.CIS | ~dmacRegs->pcr.CPC) == 0x3ff); } //#define CPCOND0 1 diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index 9f265e8f15..4656747ba9 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -84,7 +84,7 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value ) } psHu16(mem) = (u16)value; - if ((psHu16(mem) & 0x100) && (psHu32(DMAC_CTRL) & 0x1)) + if ((psHu16(mem) & 0x100) && dmacRegs->ctrl.DMAE) { //Console::WriteLn("16bit DMA Start"); func(); diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index 42d4dc0c12..002c3e15b9 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -46,26 +46,15 @@ using namespace std; // for min / max # define IPU_FORCEINLINE __forceinline #endif -#define IPU_DMA_GIFSTALL 1 -#define IPU_DMA_TIE0 2 -#define IPU_DMA_TIE1 4 -#define IPU_DMA_ACTV1 8 -#define IPU_DMA_DOTIE1 16 -#define IPU_DMA_FIREINT0 32 -#define IPU_DMA_FIREINT1 64 -#define IPU_DMA_VIFSTALL 128 - // FIXME - g_nIPU0Data and Pointer are not saved in the savestate, which breaks savestates for some // FMVs at random (if they get saved during the half frame of a 30fps rate). The fix is complicated // since coroutine is such a pita. (air) -static int g_nDMATransfer = 0; int g_nIPU0Data = 0; // data left to transfer u8* g_pIPU0Pointer = NULL; int g_nCmdPos[2] = {0}, g_nCmdIndex = 0; int ipuCurCmd = 0xffffffff; - int FOreadpos = 0, FOwritepos = 0; static int FIreadpos = 0, FIwritepos = 0; PCSX2_ALIGNED16(u32 fifo_input[32]); @@ -158,6 +147,7 @@ int ipuInit() memzero_obj(*ipuRegs); memzero_obj(g_BP); init_g_decoder(); + g_nDMATransfer._u32 = 0; return 0; } @@ -165,7 +155,7 @@ int ipuInit() void ipuReset() { memzero_obj(*ipuRegs); - g_nDMATransfer = 0; + g_nDMATransfer._u32 = 0; } void ipuShutdown() @@ -174,7 +164,7 @@ void ipuShutdown() void ReportIPU() { - Console::WriteLn("g_nDMATransfer = 0x%x.", g_nDMATransfer); + Console::WriteLn("g_nDMATransfer = 0x%x.", g_nDMATransfer._u32); Console::WriteLn("FIreadpos = 0x%x, FIwritepos = 0x%x.", FIreadpos, FIwritepos); Console::WriteLn("fifo_input = 0x%x.", fifo_input); Console::WriteLn("FOreadpos = 0x%x, FOwritepos = 0x%x.", FOreadpos, FOwritepos); @@ -204,7 +194,7 @@ void SaveStateBase::ipuFreeze() // old versions saved the IPU regs, but they're already saved as part of HW! //FreezeMem(ipuRegs, sizeof(IPUregisters)); - Freeze(g_nDMATransfer); + Freeze(g_nDMATransfer._u32); Freeze(FIreadpos); Freeze(FIwritepos); Freeze(fifo_input); @@ -1380,7 +1370,7 @@ static __forceinline bool IPU1chain(int &totalqwc) if (ipu1dma->qwc > 0) { - g_nDMATransfer |= IPU_DMA_ACTV1; + g_nDMATransfer.ACTV1 = 1; return true; } } @@ -1464,24 +1454,26 @@ int IPU1dma() if (!(ipu1dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_TO_IPU))) return 0; - assert(!(g_nDMATransfer & IPU_DMA_TIE1)); + assert(g_nDMATransfer.TIE1 == 0); //We need to make sure GIF has flushed before sending IPU data, it seems to REALLY screw FFX videos flushGIF(); // in kh, qwc == 0 when dma_actv1 is set - if ((g_nDMATransfer & IPU_DMA_ACTV1) && ipu1dma->qwc > 0) + if ((g_nDMATransfer.ACTV1) && ipu1dma->qwc > 0) { if (IPU1chain(totalqwc)) return totalqwc; //Check TIE bit of CHCR and IRQ bit of tag - if (ipu1dma->chcr.TIE && (g_nDMATransfer & IPU_DMA_DOTIE1)) + if (ipu1dma->chcr.TIE && (g_nDMATransfer.DOTIE1)) { Console::WriteLn("IPU1 TIE"); IPU_INT_TO(totalqwc * BIAS); - g_nDMATransfer &= ~(IPU_DMA_ACTV1 | IPU_DMA_DOTIE1); - g_nDMATransfer |= IPU_DMA_TIE1; + g_nDMATransfer.TIE1 = 1; + g_nDMATransfer.DOTIE1 = 0; + g_nDMATransfer.ACTV1 = 0; + return totalqwc; } @@ -1505,7 +1497,7 @@ int IPU1dma() IPU_LOG("IPU dmaIrq Set"); IPU_INT_TO(totalqwc * BIAS); - g_nDMATransfer |= IPU_DMA_TIE1; + g_nDMATransfer.TIE1 = 1; return totalqwc; } @@ -1516,7 +1508,8 @@ int IPU1dma() } } - g_nDMATransfer &= ~(IPU_DMA_ACTV1 | IPU_DMA_DOTIE1); + g_nDMATransfer.DOTIE1 = 0; + g_nDMATransfer.ACTV1 = 0; } // Normal Mode & qwc is finished @@ -1551,16 +1544,12 @@ int IPU1dma() IPU_LOG("dmaIPU1 dmaChain %8.8x_%8.8x size=%d, addr=%lx, fifosize=%x", ptag[1], ptag[0], ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC); - - if (ipu1dma->chcr.TIE && Tag::IRQ(ptag)) - g_nDMATransfer |= IPU_DMA_DOTIE1; - else - g_nDMATransfer &= ~IPU_DMA_DOTIE1; + g_nDMATransfer.DOTIE1 = (ipu1dma->chcr.TIE && Tag::IRQ(ptag)); if (ipu1dma->qwc == 0) { //Check TIE bit of CHCR and IRQ bit of tag - if (g_nDMATransfer & IPU_DMA_DOTIE1) + if (g_nDMATransfer.DOTIE1) { Console::WriteLn("IPU1 TIE"); @@ -1577,7 +1566,7 @@ int IPU1dma() } IPU_INT_TO(ipu1cycles + totalqwc * BIAS); // Should it be (ipu1cycles + totalqwc) * BIAS? - g_nDMATransfer |= IPU_DMA_TIE1; + g_nDMATransfer.TIE1 = 1; return totalqwc; } else @@ -1679,22 +1668,30 @@ int IPU0dma() assert((ipu0dma->chcr._u32 & 0xC) == 0); pMem = (u32*)dmaGetAddr(ipu0dma->madr); + readsize = min(ipu0dma->qwc, (u16)ipuRegs->ctrl.OFC); FIFOfrom_read(pMem, readsize); + ipu0dma->madr += readsize << 4; ipu0dma->qwc -= readsize; // note: qwc is u16 + if (ipu0dma->qwc == 0) { - if ((psHu32(DMAC_CTRL) & 0x30) == 0x30) // STS == fromIPU + if (dmacRegs->ctrl.STS == STS_fromIPU) // STS == fromIPU { - psHu32(DMAC_STADR) = ipu0dma->madr; - switch (psHu32(DMAC_CTRL) & 0xC0) + dmacRegs->stadr.ADDR = ipu0dma->madr; + switch (dmacRegs->ctrl.STD) { - case 0x80: // GIF - g_nDMATransfer |= IPU_DMA_GIFSTALL; + case NO_STD: break; - case 0x40: // VIF - g_nDMATransfer |= IPU_DMA_VIFSTALL; + case STD_GIF: // GIF + g_nDMATransfer.GIFSTALL = 1; + break; + case STD_VIF1: // VIF + g_nDMATransfer.VIFSTALL = 1; + break; + case STD_SIF1: + g_nDMATransfer.SIFSTALL = 1; break; } } @@ -1721,33 +1718,42 @@ void ipu0Interrupt() { IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle); - if (g_nDMATransfer & IPU_DMA_FIREINT0) + if (g_nDMATransfer.FIREINT0) { + g_nDMATransfer.FIREINT0 = 0; hwIntcIrq(INTC_IPU); - g_nDMATransfer &= ~IPU_DMA_FIREINT0; } - if (g_nDMATransfer & IPU_DMA_GIFSTALL) + if (g_nDMATransfer.GIFSTALL) { // gif - g_nDMATransfer &= ~IPU_DMA_GIFSTALL; + g_nDMATransfer.GIFSTALL = 0; if (gif->chcr.STR) GIFdma(); } - if (g_nDMATransfer & IPU_DMA_VIFSTALL) + if (g_nDMATransfer.VIFSTALL) { // vif - g_nDMATransfer &= ~IPU_DMA_VIFSTALL; + g_nDMATransfer.VIFSTALL = 0; if (vif1ch->chcr.STR) dmaVIF1(); } - if (g_nDMATransfer & IPU_DMA_TIE0) + if (g_nDMATransfer.SIFSTALL) { - g_nDMATransfer &= ~IPU_DMA_TIE0; + // sif + g_nDMATransfer.SIFSTALL = 0; + + // Not totally sure whether this needs to be done or not, so I'm + // leaving it commented out for the moment. + //if (sif1dma->chcr.STR) SIF1Dma(); + } + + if (g_nDMATransfer.TIE0) + { + g_nDMATransfer.TIE0 = 0; } ipu0dma->chcr.STR = 0; - hwDmacIrq(DMAC_FROM_IPU); } @@ -1755,14 +1761,14 @@ IPU_FORCEINLINE void ipu1Interrupt() { IPU_LOG("ipu1Interrupt %x:", cpuRegs.cycle); - if (g_nDMATransfer & IPU_DMA_FIREINT1) + if (g_nDMATransfer.FIREINT1) { hwIntcIrq(INTC_IPU); - g_nDMATransfer &= ~IPU_DMA_FIREINT1; + g_nDMATransfer.FIREINT1 = 0; } - if (g_nDMATransfer & IPU_DMA_TIE1) - g_nDMATransfer &= ~IPU_DMA_TIE1; + if (g_nDMATransfer.TIE1) + g_nDMATransfer.TIE1 = 0; else ipu1dma->chcr.STR = 0; diff --git a/pcsx2/IPU/IPU.h b/pcsx2/IPU/IPU.h index 4a06806e69..2d6d478e64 100644 --- a/pcsx2/IPU/IPU.h +++ b/pcsx2/IPU/IPU.h @@ -154,6 +154,25 @@ union tIPU_CMD_CSC } }; +union tIPU_DMA +{ + struct + { + u32 GIFSTALL : 1; + u32 TIE0 :1; + u32 TIE1 : 1; + u32 ACTV1 : 1; + u32 DOTIE1 : 1; + u32 FIREINT0 : 1; + u32 FIREINT1 : 1; + u32 VIFSTALL : 1; + u32 SIFSTALL : 1; + }; + u32 _u32; +}; + +static tIPU_DMA g_nDMATransfer; + enum SCE_IPU { SCE_IPU_BCLR = 0x0 diff --git a/pcsx2/SaveState.h b/pcsx2/SaveState.h index 6eb322d669..31e876f3a6 100644 --- a/pcsx2/SaveState.h +++ b/pcsx2/SaveState.h @@ -27,7 +27,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 = 0x8b410002; +static const u32 g_SaveVersion = 0x8b410003; // 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. :) diff --git a/pcsx2/Tags.h b/pcsx2/Tags.h index 22100263c9..2d35eb566f 100644 --- a/pcsx2/Tags.h +++ b/pcsx2/Tags.h @@ -121,7 +121,7 @@ namespace Tag UpperTransfer(tag, ptag); // Set BEIS (BUSERR) in DMAC_STAT register - psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; + dmacRegs->stat.BEIS = 1; return false; } else @@ -132,25 +132,6 @@ namespace Tag } } - /*// Not sure if I'll need this one. - static __forceinline bool SafeTransfer(const char *s, DMACh *tag, u32* ptag) - { - if (ptag == NULL) // Is ptag empty? - { - Console::Error("%s BUSERR", s); - - // Set BEIS (BUSERR) in DMAC_STAT register - psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; - return false; - } - else - { - UpperTransfer(tag, ptag); - LowerTransfer(tag, ptag); - return true; - } - }*/ - static __forceinline void UnsafeTransfer(DMACh *tag, u32* ptag) { UpperTransfer(tag, ptag); @@ -214,24 +195,3 @@ static __forceinline void PrintCHCR(const char* s, DMACh *tag) Console::WriteLn(""); } -namespace D_CTRL -{ - static __forceinline bool DMAE() { return !!(psHu32(DMAC_CTRL) & CTRL_DMAE); } - static __forceinline bool RELE() { return !!(psHu32(DMAC_CTRL) & CTRL_RELE); } - static __forceinline mfd_type MFD() - { - return (mfd_type)((psHu32(DMAC_CTRL) & CTRL_MFD) >> 2); - } - static __forceinline sts_type STS() - { - return (sts_type)((psHu32(DMAC_CTRL) & CTRL_STS) >> 4); - } - static __forceinline std_type STD() - { - return (std_type)((psHu32(DMAC_CTRL) & CTRL_STD) >> 6); - } - static __forceinline int RCYC() - { - return ((((psHu32(DMAC_CTRL) & CTRL_RCYC) >> 3) + 1) * 8); - } -}