diff --git a/pcsx2/Dmac.h b/pcsx2/Dmac.h index 9eca759fd6..7bc6e97054 100644 --- a/pcsx2/Dmac.h +++ b/pcsx2/Dmac.h @@ -121,9 +121,13 @@ union tDMA_CHCR { void set_flags(u32 flags) { _u32 |= flags; } void clear_flags(u32 flags) { _u32 &= ~flags; } void reset() { _u32 = 0; } + u16 upper() { return (_u32 >> 16); } + u16 lower() { return (u16)_u32; } wxString desc() { return wxsFormat(L"Chcr: 0x%x", _u32); } }; +#define CHCR(value) ((tDMA_CHCR)(value)) + union tDMA_SADR { struct { u32 ADDR : 14; @@ -303,6 +307,31 @@ enum DMAInter MEISintr = 0x40004000 }; +union tDMAC_QUEUE +{ + struct + { + u16 VIF0 : 1; + u16 VIF1 : 1; + u16 GIF : 1; + u16 IPU0 : 1; + u16 IPU1 : 1; + u16 SIF0 : 1; + u16 SIF1 : 1; + u16 SIF2 : 1; + u16 SPR0 : 1; + u16 SPR1 : 1; + u16 SIS : 1; + u16 MEIS : 1; + u16 BEIS : 1; + }; + u16 _u16; + + tDMAC_QUEUE(u16 val) { _u16 = val; } + void reset() { _u16 = 0; } + bool empty() { return (_u16 == 0); } +}; + union tDMAC_CTRL { struct { u32 DMAE : 1; // 0/1 - disables/enables all DMAs diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index d78904827c..598818c34a 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -91,7 +91,6 @@ __forceinline void gsInterrupt() clearFIFOstuff(false); hwDmacIrq(DMAC_GIF); GIF_LOG("GIF DMA end"); - } static u32 WRITERING_DMA(u32 *pMem, u32 qwc) @@ -108,12 +107,17 @@ static u32 WRITERING_DMA(u32 *pMem, u32 qwc) return size; } +static u32 WRITERING_DMA(tDMA_TAG *pMem, u32 qwc) +{ + return WRITERING_DMA((u32*)pMem, qwc); +} + int _GIFchain() { u32 qwc = min( gifsplit, (int)gif->qwc ); - u32 *pMem; + tDMA_TAG *pMem; - pMem = (u32*)dmaGetAddr(gif->madr); + pMem = (tDMA_TAG*)dmaGetAddr(gif->madr); if (pMem == NULL) { // reset path3, fixes dark cloud 2 @@ -136,9 +140,9 @@ static __forceinline void GIFchain() Registers::Thaw(); } -static __forceinline bool checkTieBit(u32* &ptag) +static __forceinline bool checkTieBit(tDMA_TAG* &ptag) { - if (gif->chcr.TIE && (Tag::IRQ(ptag))) + if (gif->chcr.TIE && ptag->IRQ) { GIF_LOG("dmaIrq Set"); gspath3done = true; @@ -148,36 +152,33 @@ static __forceinline bool checkTieBit(u32* &ptag) return false; } -static __forceinline u32* ReadTag(u32 &id) +static __forceinline tDMA_TAG* ReadTag() { - u32* ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + tDMA_TAG* ptag = (tDMA_TAG*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR - if (!(Tag::Transfer("Gif", gif, ptag))) return NULL; + if (!(gif->transfer("Gif", ptag))) return NULL; - gif->madr = ptag[1]; //MADR = ADDR field - - id = Tag::Id(ptag); + gif->madr = ptag[1].ADDR; //MADR = ADDR field gscycles += 2; // Add 1 cycles from the QW read for the tag - gspath3done = hwDmacSrcChainWithStack(gif, id); + gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID); return ptag; } -static __forceinline u32* ReadTag2() +static __forceinline tDMA_TAG* ReadTag2() { - u32* ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + tDMA_TAG* ptag = (tDMA_TAG*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR - Tag::UnsafeTransfer(gif, ptag); - gif->madr = ptag[1]; + gif->unsafeTransfer(ptag); + gif->madr = ptag[1].ADDR; - gspath3done = hwDmacSrcChainWithStack(gif, Tag::Id(ptag)); + gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID); return ptag; } void GIFdma() { - u32 *ptag; - u32 id; + tDMA_TAG *ptag; gscycles = prevcycles; @@ -220,9 +221,9 @@ void GIFdma() { if ((gif->chcr.MOD == CHAIN_MODE) && gif->chcr.STR) { - ptag = ReadTag(id); + ptag = ReadTag(); if (ptag == NULL) return; - GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr); + GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr); //Check TIE bit of CHCR and IRQ bit of tag if (checkTieBit(ptag)) GIF_LOG("PATH3 MSK dmaIrq Set"); @@ -258,14 +259,14 @@ void GIFdma() if ((gif->chcr.MOD == CHAIN_MODE) && (!gspath3done)) // Chain Mode { - ptag = ReadTag(id); + ptag = ReadTag(); if (ptag == NULL) return; - GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr); + GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr); if (dmacRegs->ctrl.STD == STD_GIF) { // there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall - if (!gspath3done && ((gif->madr + (gif->qwc * 16)) > dmacRegs->stadr.ADDR) && (id == 4)) + if (!gspath3done && ((gif->madr + (gif->qwc * 16)) > dmacRegs->stadr.ADDR) && (ptag->ID == TAG_REFS)) { // stalled Console.WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR)); @@ -285,16 +286,15 @@ void GIFdma() if ((!gspath3done) && (gif->qwc == 0)) { - ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + ptag = (tDMA_TAG*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + gif->unsafeTransfer(ptag); + gif->madr = ptag[1].ADDR; - Tag::UnsafeTransfer(gif, ptag); - gif->madr = ptag[1]; - - gspath3done = hwDmacSrcChainWithStack(gif, Tag::Id(ptag)); + gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID); checkTieBit(ptag); - GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, (ptag[0] >> 28) & 0x7, gif->madr); + GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr); CPU_INT(2, gscycles * BIAS); } else @@ -327,8 +327,8 @@ void dmaGIF() if ((gif->qwc == 0) && (gif->chcr.MOD != NORMAL_MODE)) { - u32* ptag = ReadTag2(); - GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, (ptag[0] >> 28), gif->madr); + tDMA_TAG* ptag = ReadTag2(); + GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr); checkTieBit(ptag); GIFdma(); @@ -342,7 +342,7 @@ void dmaGIF() } // called from only one location, so forceinline it: -static __forceinline int mfifoGIFrbTransfer() +static __forceinline bool mfifoGIFrbTransfer() { u32 mfifoqwc = min(gifqwc, (u32)gif->qwc); u32 *src; @@ -357,14 +357,14 @@ static __forceinline int mfifoGIFrbTransfer() /* it does (wrap around), so first copy 's1' bytes from 'addr' to 'data' */ src = (u32*)PSM(gif->madr); - if (src == NULL) return -1; + if (src == NULL) return false; s1 = WRITERING_DMA(src, s1); if (s1 == (mfifoqwc - s2)) { /* and second copy 's2' bytes from 'maddr' to '&data[s1]' */ src = (u32*)PSM(dmacRegs->rbor.ADDR); - if (src == NULL) return -1; + if (src == NULL) return false; s2 = WRITERING_DMA(src, s2); } else @@ -378,39 +378,39 @@ static __forceinline int mfifoGIFrbTransfer() { /* it doesn't, so just transfer 'qwc*16' words from 'gif->madr' to GS */ src = (u32*)PSM(gif->madr); - if (src == NULL) return -1; + if (src == NULL) return false; mfifoqwc = WRITERING_DMA(src, mfifoqwc); gif->madr = dmacRegs->rbor.ADDR + (gif->madr & dmacRegs->rbsr.RMSK); } gifqwc -= mfifoqwc; - return 0; + return true; } // called from only one location, so forceinline it: -static __forceinline int mfifoGIFchain() +static __forceinline bool mfifoGIFchain() { /* Is QWC = 0? if so there is nothing to transfer */ - if (gif->qwc == 0) return 0; + if (gif->qwc == 0) return true; if (gif->madr >= dmacRegs->rbor.ADDR && gif->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK)) { - if (mfifoGIFrbTransfer() == -1) return -1; + if (!mfifoGIFrbTransfer()) return false; } else { int mfifoqwc; - u32 *pMem = (u32*)dmaGetAddr(gif->madr); - if (pMem == NULL) return -1; + tDMA_TAG *pMem = (tDMA_TAG*)dmaGetAddr(gif->madr); + if (pMem == NULL) return false; mfifoqwc = WRITERING_DMA(pMem, gif->qwc); mfifocycles += (mfifoqwc) * 2; /* guessing */ } - return 0; + return true; } static u32 qwctag(u32 mask) @@ -420,8 +420,7 @@ static u32 qwctag(u32 mask) void mfifoGIFtransfer(int qwc) { - u32 *ptag; - int id; + tDMA_TAG *ptag; mfifocycles = 0; gifmfifoirq = false; @@ -451,19 +450,18 @@ void mfifoGIFtransfer(int qwc) gif->tadr = qwctag(gif->tadr); - ptag = (u32*)dmaGetAddr(gif->tadr); - Tag::UnsafeTransfer(gif, ptag); - - gif->madr = ptag[1]; - id =Tag::Id(ptag); + ptag = (tDMA_TAG*)dmaGetAddr(gif->tadr); + gif->unsafeTransfer(ptag); + gif->madr = ptag[1].ADDR; + mfifocycles += 2; GIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x", - ptag[1], ptag[0], gif->qwc, id, gif->madr, gif->tadr, gifqwc, spr0->madr); + ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr, gif->tadr, gifqwc, spr0->madr); gifqwc--; - switch (id) + switch (ptag->ID) { case TAG_REFE: // Refe - Transfer Packet According to ADDR field gif->tadr = qwctag(gif->tadr + 16); @@ -498,7 +496,7 @@ void mfifoGIFtransfer(int qwc) break; } - if ((gif->chcr.TIE) && (Tag::IRQ(ptag))) + if ((gif->chcr.TIE) && (ptag->IRQ)) { SPR_LOG("dmaIrq Set"); gifstate = GIF_STATE_DONE; @@ -507,7 +505,7 @@ void mfifoGIFtransfer(int qwc) } Registers::Freeze(); - if (mfifoGIFchain() == -1) + if (!mfifoGIFchain()) { Console.WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", gif->qwc, gif->madr, gif->tadr); gifstate = GIF_STATE_STALL; diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index 027346d7b7..ded0f207d1 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -55,7 +55,7 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value ) u32 qwcRegister = mem | 0x20; //It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC - if ((value & 0x100) && ((psHu32(mem) & 0x100) == 0x100) && dmacRegs->ctrl.DMAE) + if ((CHCR(value).STR) && (psH_Chcr(mem).STR) && dmacRegs->ctrl.DMAE) { DevCon.Warning( "DMAExec16 Attempt to run DMA while one is already active mem = %x", mem); } @@ -64,12 +64,11 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value ) if ((psHu32(qwcRegister) >> 16) != 0) { DMA_LOG("DMA QWC (%x) upper 16bits set to %x\n", - qwcRegister, - psHu32(qwcRegister) >> 16); + qwcRegister, psHu32(qwcRegister) >> 16); psHu32(qwcRegister) = 0; } - psHu16(mem) = (u16)value; + psHu16(mem) = CHCR(value).lower(); if ((psHu16(mem) & 0x100) && dmacRegs->ctrl.DMAE) { //Console.WriteLn("16bit DMA Start"); @@ -82,7 +81,7 @@ static void DmaExec( void (*func)(), u32 mem, u32 value ) u32 qwcRegister = mem | 0x20; //It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC - if ((value & 0x100) && ((psHu32(mem) & 0x100) == 0x100) && dmacRegs->ctrl.DMAE) + if ((CHCR(value).STR) && (psH_Chcr(mem).STR) && dmacRegs->ctrl.DMAE) { DevCon.Warning( "DMAExec32 Attempt to run DMA while one is already active mem = %x", mem ); @@ -95,28 +94,26 @@ static void DmaExec( void (*func)(), u32 mem, u32 value ) if ((psHu32(qwcRegister) >> 16) != 0) { DevCon.Warning("DMA QWC (%x) upper 16bits set to %x\n", - qwcRegister, - psHu32(qwcRegister) >> 16); + qwcRegister, psHu32(qwcRegister) >> 16); psHu32(qwcRegister) = 0; } - - /* Keep the old tag if in chain mode and hw doesn't set it*/ - if (((value & 0xc) == 0x4) && ((value & 0xffff0000) == 0)) - psHu32(mem) = (psHu32(mem) & 0xffff0000) | (u16)value; + + /* Keep the old tag if in chain mode and hw doesn't set it*/ + if ((CHCR(value).MOD == CHAIN_MODE) && (CHCR(value).TAG == 0)) + psHu32(mem) = (psH_Chcr(mem).TAG << 16) | CHCR(value).lower(); else /* Else (including Normal mode etc) write whatever the hardware sends*/ - psHu32(mem) = (u32)value; - - if ((psHu32(mem) & 0x100) && dmacRegs->ctrl.DMAE) + psHu32(mem) = value; + + if (psH_Chcr(mem).STR && dmacRegs->ctrl.DMAE) func(); } - ///////////////////////////////////////////////////////////////////////// // Hardware WRITE 8 bit char sio_buffer[1024]; int sio_count; -u16 QueuedDMA = 0; +tDMAC_QUEUE QueuedDMA(0); void hwWrite8(u32 mem, u8 value) { @@ -189,7 +186,7 @@ void hwWrite8(u32 mem, u8 value) if ((value & 0x1) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("8 bit VIF0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x1; + QueuedDMA.VIF0 = true; } DmaExec8(dmaVIF0, mem, value); break; @@ -199,7 +196,7 @@ void hwWrite8(u32 mem, u8 value) if ((value & 0x1) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("8 bit VIF1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x2; + QueuedDMA.VIF1 = true; } if(value & 0x1) vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO DmaExec8(dmaVIF1, mem, value); @@ -210,7 +207,7 @@ void hwWrite8(u32 mem, u8 value) if ((value & 0x1) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("8 bit GIF DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x4; + QueuedDMA.GIF = true; } DmaExec8(dmaGIF, mem, value); break; @@ -220,7 +217,7 @@ void hwWrite8(u32 mem, u8 value) if ((value & 0x1) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("8 bit IPU0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x8; + QueuedDMA.IPU0 = true; } DmaExec8(dmaIPU0, mem, value); break; @@ -230,7 +227,7 @@ void hwWrite8(u32 mem, u8 value) if ((value & 0x1) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("8 bit IPU1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x10; + QueuedDMA.IPU1 = true; } DmaExec8(dmaIPU1, mem, value); break; @@ -241,7 +238,7 @@ void hwWrite8(u32 mem, u8 value) if ((value & 0x1) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("8 bit SIF0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x20; + QueuedDMA.SIF0 = true; } DmaExec8(dmaSIF0, mem, value); break; @@ -251,7 +248,7 @@ void hwWrite8(u32 mem, u8 value) if ((value & 0x1) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("8 bit SIF1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x40; + QueuedDMA.SIF1 = true; } DmaExec8(dmaSIF1, mem, value); break; @@ -261,7 +258,7 @@ void hwWrite8(u32 mem, u8 value) if ((value & 0x1) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("8 bit SIF2 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x80; + QueuedDMA.SIF2 |= true; } DmaExec8(dmaSIF2, mem, value); break; @@ -271,7 +268,7 @@ void hwWrite8(u32 mem, u8 value) if ((value & 0x1) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("8 bit SPR0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x100; + QueuedDMA.SPR0 = true; } DmaExec8(dmaSPR0, mem, value); break; @@ -281,7 +278,7 @@ void hwWrite8(u32 mem, u8 value) if ((value & 0x1) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("8 bit SPR1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x200; + QueuedDMA .SPR1 = true; } DmaExec8(dmaSPR1, mem, value); break; @@ -366,7 +363,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) if ((value & 0x100) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit VIF0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x1; + QueuedDMA.VIF0 = true; } DmaExec16(dmaVIF0, mem, value); break; @@ -376,9 +373,10 @@ __forceinline void hwWrite16(u32 mem, u16 value) if ((value & 0x100) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit VIF1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x2; + QueuedDMA.VIF1 = true; } - if(value & 0x100) vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO + + if (value & 0x100) vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO DmaExec16(dmaVIF1, mem, value); break; @@ -420,7 +418,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) if ((value & 0x100) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit GIF DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x4; + QueuedDMA.GIF = true; } DmaExec16(dmaGIF, mem, value); break; @@ -462,7 +460,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) if ((value & 0x100) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit IPU0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x8; + QueuedDMA.IPU0 = true; } DmaExec16(dmaIPU0, mem, value); break; @@ -494,7 +492,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) if ((value & 0x100) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit IPU1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x10; + QueuedDMA.IPU1 = true; } DmaExec16(dmaIPU1, mem, value); break; @@ -526,7 +524,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) if ((value & 0x100) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit SIF0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x20; + QueuedDMA.SIF0 = true; } DmaExec16(dmaSIF0, mem, value); break; @@ -540,7 +538,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) if ((value & 0x100) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit SIF1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x40; + QueuedDMA.SIF1 = true; } DmaExec16(dmaSIF1, mem, value); break; @@ -572,7 +570,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) if ((value & 0x100) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit SIF2 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x80; + QueuedDMA.SIF2 = true; } DmaExec16(dmaSIF2, mem, value); break; @@ -586,7 +584,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) if ((value & 0x100) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit SPR0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x100; + QueuedDMA.SPR0 = true; } DmaExec16(dmaSPR0, mem, value); break; @@ -596,7 +594,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) if ((value & 0x100) && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit SPR1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x200; + QueuedDMA.SPR1 = true; } DmaExec16(dmaSPR1, mem, value); break; @@ -751,10 +749,10 @@ void __fastcall hwWrite32_page_0B( u32 mem, u32 value ) { case D3_CHCR: // dma3 - fromIPU DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("32 bit IPU0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x8; + QueuedDMA.IPU0 = true; } DmaExec(dmaIPU0, mem, value); return; @@ -768,10 +766,10 @@ void __fastcall hwWrite32_page_0B( u32 mem, u32 value ) case D4_CHCR: // dma4 - toIPU DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("32 bit IPU1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x10; + QueuedDMA.IPU1 = true; } DmaExec(dmaIPU1, mem, value); return; @@ -788,16 +786,16 @@ void __fastcall hwWrite32_page_0B( u32 mem, u32 value ) void __fastcall StartQueuedDMA() { - if(QueuedDMA & 0x001) { QueuedDMA &= ~0x001; dmaVIF0(); } - if(QueuedDMA & 0x002) { QueuedDMA &= ~0x002; dmaVIF1(); } - if(QueuedDMA & 0x004) { QueuedDMA &= ~0x004; dmaGIF(); } - if(QueuedDMA & 0x008) { QueuedDMA &= ~0x008; dmaIPU0(); } - if(QueuedDMA & 0x010) { QueuedDMA &= ~0x010; dmaIPU1(); } - if(QueuedDMA & 0x020) { QueuedDMA &= ~0x020; dmaSIF0(); } - if(QueuedDMA & 0x040) { QueuedDMA &= ~0x040; dmaSIF1(); } - if(QueuedDMA & 0x080) { QueuedDMA &= ~0x080; dmaSIF2(); } - if(QueuedDMA & 0x100) { QueuedDMA &= ~0x100; dmaSPR0(); } - if(QueuedDMA & 0x200) { QueuedDMA &= ~0x200; dmaSPR1(); } + if (QueuedDMA.VIF0) { QueuedDMA.VIF0 = false; dmaVIF0(); } + if (QueuedDMA.VIF1) { QueuedDMA.VIF1 = false; dmaVIF1(); } + if (QueuedDMA.GIF ) { QueuedDMA.GIF = false; dmaGIF(); } + if (QueuedDMA.IPU0) { QueuedDMA.IPU0 = false; dmaIPU0(); } + if (QueuedDMA.IPU1) { QueuedDMA.IPU1 = false; dmaIPU1(); } + if (QueuedDMA.SIF0) { QueuedDMA.SIF0 = false; dmaSIF0(); } + if (QueuedDMA.SIF1) { QueuedDMA.SIF1 = false; dmaSIF1(); } + if (QueuedDMA.SIF2) { QueuedDMA.SIF2 = false; dmaSIF2(); } + if (QueuedDMA.SPR0) { QueuedDMA.SPR0 = false; dmaSPR0(); } + if (QueuedDMA.SPR1) { QueuedDMA.SPR1 = false; dmaSPR1(); } } void __fastcall hwWrite32_page_0E( u32 mem, u32 value ) @@ -814,7 +812,7 @@ void __fastcall hwWrite32_page_0E( u32 mem, u32 value ) //Check for DMAS that were started while the DMAC was disabled if (((oldvalue & 0x1) == 0) && ((value & 0x1) == 1)) { - if (QueuedDMA != 0) StartQueuedDMA(); + if (!QueuedDMA.empty()) StartQueuedDMA(); } break; } @@ -919,10 +917,10 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value ) case D0_CHCR: // dma0 - vif0 DMA_LOG("VIF0dma EXECUTE, value=0x%x", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("32 bit VIF0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x1; + QueuedDMA.VIF0 = true; } DmaExec(dmaVIF0, mem, value); @@ -932,17 +930,21 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value ) case D1_CHCR: // dma1 - vif1 - chcr DMA_LOG("VIF1dma EXECUTE, value=0x%x", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("32 bit VIF1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x2; + QueuedDMA.VIF1 = true; } - if (value & 0x100) + if (CHCR(value).STR) { vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO - } else cpuRegs.interrupt &= ~(1<<10) | ~(1<<1); //Tekken tag seems to stop vif and start it again in normal, so we will cancel the mfifo loop - + } + else + { + cpuRegs.interrupt &= ~(1<<10) | ~(1<<1); //Tekken tag seems to stop vif and start it again in normal, so we will cancel the mfifo loop + } + DmaExec(dmaVIF1, mem, value); return; @@ -956,10 +958,10 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value ) //------------------------------------------------------------------ case D2_CHCR: // dma2 - gif DMA_LOG("GIFdma EXECUTE, value=0x%x", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("32 bit GIF DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x4; + QueuedDMA.GIF = true; } DmaExec(dmaGIF, mem, value); return; @@ -975,20 +977,20 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value ) case D5_CHCR: // dma5 - sif0 DMA_LOG("SIF0dma EXECUTE, value=0x%x", value); //if (value == 0) psxSu32(0x30) = 0x40000; - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("32 bit SIF0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x20; + QueuedDMA.SIF0 = true; } DmaExec(dmaSIF0, mem, value); return; //------------------------------------------------------------------ case D6_CHCR: // dma6 - sif1 DMA_LOG("SIF1dma EXECUTE, value=0x%x", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("32 bit SIF1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x40; + QueuedDMA.SIF1 = true; } DmaExec(dmaSIF1, mem, value); return; @@ -1000,30 +1002,30 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value ) //------------------------------------------------------------------ case D7_CHCR: // dma7 - sif2 DMA_LOG("SIF2dma EXECUTE, value=0x%x", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("32 bit SIF2 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x80; + QueuedDMA.SIF2 = true; } DmaExec(dmaSIF2, mem, value); return; //------------------------------------------------------------------ case D8_CHCR: // dma8 - fromSPR DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("32 bit SPR0 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x100; + QueuedDMA.SPR0 = true; } DmaExec(dmaSPR0, mem, value); return; //------------------------------------------------------------------ case SPR1_CHCR: // dma9 - toSPR DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("32 bit SPR1 DMA Start while DMAC Disabled\n"); - QueuedDMA |= 0x200; + QueuedDMA.SPR1 = true; } DmaExec(dmaSPR1, mem, value); return; @@ -1120,7 +1122,7 @@ void __fastcall hwWrite64_page_0E( u32 mem, const mem64_t* srcval ) if (((oldvalue & 0x1) == 0) && ((value & 0x1) == 1)) { - if (QueuedDMA != 0) StartQueuedDMA(); + if (!QueuedDMA.empty()) StartQueuedDMA(); } break; } diff --git a/pcsx2/Memory.h b/pcsx2/Memory.h index 42d5422443..7a7b1e4426 100644 --- a/pcsx2/Memory.h +++ b/pcsx2/Memory.h @@ -119,6 +119,7 @@ extern u8 *psS; //0.015 mb, scratch pad #define psSu32(mem) (*(u32*)&PS2MEM_SCRATCH[(mem) & 0x3fff]) #define psSu64(mem) (*(u64*)&PS2MEM_SCRATCH[(mem) & 0x3fff]) +#define psH_Chcr(mem) (*(tDMA_CHCR*)&PS2MEM_HW[(mem) & 0xffff]) extern void memAlloc(); extern void memReset(); // clears PS2 ram and loads the bios. Throws Exception::FileNotFound on error. extern void memShutdown();