diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index 5f531da3e9..7fb313a331 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -25,6 +25,7 @@ #include "Counters.h" #include "VifDma.h" +#include "Tags.h" using std::min; @@ -43,8 +44,7 @@ static int gifstate = GIF_STATE_READY; //static u64 s_gstag = 0; // used for querying the last tag -// This should be a bool, as should the return value of hwDmacSrcChainWithStack. -// Next time I feel like breaking the save state, it will be. --arcum42 +// This should be a bool. Next time I feel like breaking the save state, it will be. --arcum42 static int gspath3done = 0; static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0; @@ -491,31 +491,31 @@ void mfifoGIFtransfer(int qwc) gifqwc--; switch (id) { - case 0: // Refe - Transfer Packet According to ADDR field + case TAG_REFE: // Refe - Transfer Packet According to ADDR field gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); gifstate = GIF_STATE_DONE; //End Transfer break; - case 1: // CNT - Transfer QWC following the tag. + case TAG_CNT: // CNT - Transfer QWC following the tag. gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW after Tag gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data gifstate = GIF_STATE_READY; break; - case 2: // Next - Transfer QWC following tag. TADR = ADDR + case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR temp = gif->madr; //Temporarily Store ADDR gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW following the tag gif->tadr = temp; //Copy temporarily stored ADDR to Tag gifstate = GIF_STATE_READY; break; - case 3: // Ref - Transfer QWC from ADDR field - case 4: // Refs - Transfer QWC from ADDR field (Stall Control) + case TAG_REF: // Ref - Transfer QWC from ADDR field + case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control) gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag gifstate = GIF_STATE_READY; break; - case 7: // End - Transfer QWC following the tag + case TAG_END: // End - Transfer QWC following the tag gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to data following the tag gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data gifstate = GIF_STATE_DONE; //End Transfer diff --git a/pcsx2/Hw.cpp b/pcsx2/Hw.cpp index 7d3f740e8e..fc3e1ccdd1 100644 --- a/pcsx2/Hw.cpp +++ b/pcsx2/Hw.cpp @@ -32,6 +32,7 @@ #include "VifDma.h" #include "SPR.h" #include "Sif.h" +#include "Tags.h" using namespace R5900; @@ -150,27 +151,27 @@ bool hwMFIFOWrite(u32 addr, u8 *data, u32 size) { bool hwDmacSrcChainWithStack(DMACh *dma, int id) { switch (id) { - case 0: // Refe - Transfer Packet According to ADDR field + case TAG_REFE: // Refe - Transfer Packet According to ADDR field return true; //End Transfer - case 1: // CNT - Transfer QWC following the tag. + case TAG_CNT: // CNT - Transfer QWC following the tag. dma->madr = dma->tadr + 16; //Set MADR to QW after Tag dma->tadr = dma->madr + (dma->qwc << 4); //Set TADR to QW following the data return false; - case 2: // Next - Transfer QWC following tag. TADR = ADDR + case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR { u32 temp = dma->madr; //Temporarily Store ADDR dma->madr = dma->tadr + 16; //Set MADR to QW following the tag dma->tadr = temp; //Copy temporarily stored ADDR to Tag return false; } - case 3: // Ref - Transfer QWC from ADDR field - case 4: // Refs - Transfer QWC from ADDR field (Stall Control) + case TAG_REF: // Ref - Transfer QWC from ADDR field + case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control) dma->tadr += 16; //Set TADR to next tag return false; - case 5: // Call - Transfer QWC following the tag, save succeeding tag + case TAG_CALL: // Call - Transfer QWC following the tag, save succeeding tag { u32 temp = dma->madr; //Temporarily Store ADDR @@ -191,7 +192,7 @@ bool hwDmacSrcChainWithStack(DMACh *dma, int id) { return false; } - case 6: // Ret - Transfer QWC following the tag, load next tag + case TAG_RET: // Ret - Transfer QWC following the tag, load next tag dma->madr = dma->tadr + 16; //Set MADR to data following the tag if ((dma->chcr & 0x30) == 0x20) { //If ASR1 is NOT equal to 0 (Contains address) @@ -211,7 +212,7 @@ bool hwDmacSrcChainWithStack(DMACh *dma, int id) { } return false; - case 7: // End - Transfer QWC following the tag + case TAG_END: // End - Transfer QWC following the tag dma->madr = dma->tadr + 16; //Set MADR to data following the tag //Dont Increment tadr, breaks Soul Calibur II and III return true; //End Transfer @@ -224,26 +225,26 @@ bool hwDmacSrcChain(DMACh *dma, int id) { u32 temp; switch (id) { - case 0: // Refe - Transfer Packet According to ADDR field + case TAG_REFE: // Refe - Transfer Packet According to ADDR field return true; //End Transfer - case 1: // CNT - Transfer QWC following the tag. + case TAG_CNT: // CNT - Transfer QWC following the tag. dma->madr = dma->tadr + 16; //Set MADR to QW after Tag dma->tadr = dma->madr + (dma->qwc << 4); //Set TADR to QW following the data return false; - case 2: // Next - Transfer QWC following tag. TADR = ADDR + case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR temp = dma->madr; //Temporarily Store ADDR dma->madr = dma->tadr + 16; //Set MADR to QW following the tag dma->tadr = temp; //Copy temporarily stored ADDR to Tag return false; - case 3: // Ref - Transfer QWC from ADDR field - case 4: // Refs - Transfer QWC from ADDR field (Stall Control) + case TAG_REF: // Ref - Transfer QWC from ADDR field + case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control) dma->tadr += 16; //Set TADR to next tag return false; - case 7: // End - Transfer QWC following the tag + case TAG_END: // End - Transfer QWC following the tag dma->madr = dma->tadr + 16; //Set MADR to data following the tag //Dont Increment tadr, breaks Soul Calibur II and III return true; //End Transfer diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index 4adf2495f2..91d57e28ef 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -26,6 +26,7 @@ #include "coroutine.h" #include "Vif.h" +#include "Tags.h" using namespace std; // for min / max @@ -1392,15 +1393,18 @@ static __forceinline bool IPU1chain(u32* &pMem, int &totalqwc) return false; } +// Remind me to give this a better name. --arcum42 static __forceinline bool IncreaseTadr(u32 tag) { - switch (tag & 0x70000000) + u32 id = (tag >> 28) & 0x7; + + switch (id) { - case 0x00000000: + case TAG_REFE: // refe ipu1dma->tadr += 16; return true; - case 0x70000000: + case TAG_END: // end ipu1dma->tadr = ipu1dma->madr; return true; } @@ -1409,6 +1413,48 @@ static __forceinline bool IncreaseTadr(u32 tag) extern void gsInterrupt(); +static __forceinline bool ipuDmacSrcChain(DMACh *tag, u32 *ptag) +{ + u32 id = (ptag[0] >> 28) & 0x7; + + switch (id) + { + case TAG_REFE: // refe + // do not change tadr + tag->madr = ptag[1]; + return true; + break; + + case TAG_CNT: // cnt + tag->madr = tag->tadr + 16; + // Set the taddr to the next tag + tag->tadr += 16 + (tag->qwc << 4); + break; + + case TAG_NEXT: // next + tag->madr = tag->tadr + 16; + tag->tadr = ptag[1]; + break; + + case TAG_REF: // ref + tag->madr = ptag[1]; + tag->tadr += 16; + break; + + case TAG_END: // end + // do not change tadr + tag->madr = tag->tadr + 16; + return true; + break; + + default: + Console::Error("IPU ERROR: different transfer mode!, Please report to PCSX2 Team"); + break; + } + + return false; +} + int IPU1dma() { u32 *ptag, *pMem; @@ -1421,7 +1467,7 @@ int IPU1dma() if (!(ipu1dma->chcr & 0x100) || (cpuRegs.interrupt & (1 << DMAC_TO_IPU))) return 0; assert(!(g_nDMATransfer & IPU_DMA_TIE1)); - + //We need to make sure GIF has flushed before sending IPU data, it seems to REALLY screw FFX videos while(gif->chcr & 0x100 && vif1Regs->mskpath3 == 0) { @@ -1509,41 +1555,8 @@ int IPU1dma() ipu1dma->chcr = (ipu1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15 ipu1dma->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag - - switch (ptag[0] & 0x70000000) - { - case 0x00000000: // refe - // do not change tadr - ipu1dma->madr = ptag[1]; - done = TRUE; - break; - - case 0x10000000: // cnt - ipu1dma->madr = ipu1dma->tadr + 16; - // Set the taddr to the next tag - ipu1dma->tadr += 16 + (ipu1dma->qwc << 4); - break; - - case 0x20000000: // next - ipu1dma->madr = ipu1dma->tadr + 16; - ipu1dma->tadr = ptag[1]; - break; - - case 0x30000000: // ref - ipu1dma->madr = ptag[1]; - ipu1dma->tadr += 16; - break; - - case 0x70000000: // end - // do not change tadr - ipu1dma->madr = ipu1dma->tadr + 16; - done = TRUE; - break; - - default: - Console::Error("IPU ERROR: different transfer mode!, Please report to PCSX2 Team"); - break; - } + + done = ipuDmacSrcChain(ipu1dma, ptag); 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); @@ -1555,7 +1568,7 @@ int IPU1dma() if (ipu1dma->qwc == 0) { - //if ((ipu1dma->chcr & 0x80) && (ptag[0] & 0x80000000)) //Check TIE bit of CHCR and IRQ bit of tag + //Check TIE bit of CHCR and IRQ bit of tag if (g_nDMATransfer & IPU_DMA_DOTIE1) { Console::WriteLn("IPU1 TIE"); diff --git a/pcsx2/Sif.cpp b/pcsx2/Sif.cpp index d6b9469d9d..703cadc327 100644 --- a/pcsx2/Sif.cpp +++ b/pcsx2/Sif.cpp @@ -22,6 +22,7 @@ #include "IopCommon.h" #include "Sifcmd.h" +#include "Tags.h" using namespace std; @@ -305,33 +306,33 @@ __forceinline void SIF1Dma() switch (id) { - case 0: // refe + case TAG_REFE: // refe SIF_LOG(" REFE %08X", ptag[1]); sif1.end = 1; sif1dma->madr = ptag[1]; sif1dma->tadr += 16; break; - case 1: // cnt + case TAG_CNT: // cnt SIF_LOG(" CNT"); sif1dma->madr = sif1dma->tadr + 16; sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4); break; - case 2: // next + case TAG_NEXT: // next SIF_LOG(" NEXT %08X", ptag[1]); sif1dma->madr = sif1dma->tadr + 16; sif1dma->tadr = ptag[1]; break; - case 3: // ref - case 4: // refs + case TAG_REF: // ref + case TAG_REFS: // refs SIF_LOG(" REF %08X", ptag[1]); sif1dma->madr = ptag[1]; sif1dma->tadr += 16; break; - case 7: // end + case TAG_END: // end SIF_LOG(" END"); sif1.end = 1; sif1dma->madr = sif1dma->tadr + 16; diff --git a/pcsx2/Tags.h b/pcsx2/Tags.h index 5be98ea2fa..1cbb86f359 100644 --- a/pcsx2/Tags.h +++ b/pcsx2/Tags.h @@ -78,19 +78,12 @@ namespace ChainTags // Untested static __forceinline pce_values PCE(u32 *tag) { - u8 temp = 0; - if (tag[0] & (1 << 22)) temp |= (1 << 0); - if (tag[0] & (1 << 23)) temp |= (1 << 1); - return (pce_values)temp; + return (pce_values)((tag[0] >> 22) & 0x3); } - static __forceinline tag_id Id(u32* &tag) + static __forceinline tag_id Id(u32* tag) { - u8 temp = 0; - if (tag[0] & (1 << 28)) temp |= (1 << 0); - if (tag[0] & (1 << 29)) temp |= (1 << 1); - if (tag[0] & (1 << 30)) temp |= (1 << 2); - return (tag_id)temp; + return (tag_id)((tag[0] >> 28) & 0x7); } static __forceinline bool IRQ(u32 *tag) diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index 714560e814..3f38cc471a 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -24,6 +24,7 @@ #include "VUmicro.h" #include "Vif.h" #include "VifDma.h" +#include "Tags.h" VIFregisters *vifRegs; u32* vifRow = NULL; @@ -479,18 +480,18 @@ void mfifoVIF1transfer(int qwc) switch (id) { - case 0: // Refe - Transfer Packet According to ADDR field + case TAG_REFE: // Refe - Transfer Packet According to ADDR field vif1ch->tadr = psHu32(DMAC_RBOR) + ((vif1ch->tadr + 16) & psHu32(DMAC_RBSR)); vif1.done = true; //End Transfer break; - case 1: // CNT - Transfer QWC following the tag. + case TAG_CNT: // CNT - Transfer QWC following the tag. vif1ch->madr = psHu32(DMAC_RBOR) + ((vif1ch->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW after Tag vif1ch->tadr = psHu32(DMAC_RBOR) + ((vif1ch->madr + (vif1ch->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data vif1.done = false; break; - case 2: // Next - Transfer QWC following tag. TADR = ADDR + case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR { int temp = vif1ch->madr; //Temporarily Store ADDR vif1ch->madr = psHu32(DMAC_RBOR) + ((vif1ch->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW following the tag @@ -500,13 +501,13 @@ void mfifoVIF1transfer(int qwc) break; } - case 3: // Ref - Transfer QWC from ADDR field - case 4: // Refs - Transfer QWC from ADDR field (Stall Control) + case TAG_REF: // Ref - Transfer QWC from ADDR field + case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control) vif1ch->tadr = psHu32(DMAC_RBOR) + ((vif1ch->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag vif1.done = false; break; - case 7: // End - Transfer QWC following the tag + case TAG_END: // End - Transfer QWC following the tag vif1ch->madr = psHu32(DMAC_RBOR) + ((vif1ch->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to data following the tag vif1ch->tadr = psHu32(DMAC_RBOR) + ((vif1ch->madr + (vif1ch->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data vif1.done = true; //End Transfer