From cf4719019de5ad29c7b3212a51471991631343a5 Mon Sep 17 00:00:00 2001 From: arcum42 Date: Mon, 19 Oct 2009 11:45:37 +0000 Subject: [PATCH] A few changes to Sif, SPR, and Gif I've had sitting around. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2037 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/Gif.cpp | 72 ++++++++++++++++++++++++++------------------- pcsx2/IopHw.h | 13 +++++++- pcsx2/SPR.cpp | 54 ++++++++++++++++------------------ pcsx2/SaveState.cpp | 2 +- pcsx2/Sif.cpp | 18 +++++------- 5 files changed, 89 insertions(+), 70 deletions(-) diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index b6de30396d..721a7c27ac 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -30,15 +30,13 @@ using std::min; // A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished). // Should be a gifstate_t rather then int, but I don't feel like possibly interfering with savestates right now. static int gifstate = GIF_STATE_READY; +static bool gifempty = false; -//static u64 s_gstag = 0; // used for querying the last tag - -// This should be a bool. Next time I feel like breaking the save state, it will be. --arcum42 static bool gspath3done = false; static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0; static u32 gifqwc = 0; -bool gifmfifoirq = false; +static bool gifmfifoirq = false; static __forceinline void clearFIFOstuff(bool full) { @@ -60,8 +58,9 @@ __forceinline void gsInterrupt() return; } - if ((vif1.cmd & 0x7f) == 0x51) + if ((vif1.cmd & 0x7f) == 0x51) // DIRECTHL { + // Not waiting for the end of the Gif transfer. if (Path3progress != IMAGE_MODE) vif1Regs->stat.VGW = 0; } @@ -141,7 +140,7 @@ static __forceinline void GIFchain() static __forceinline bool checkTieBit(u32* &ptag) { - if (gif->chcr.TIE && (Tag::IRQ(ptag))) //Check TIE bit of CHCR and IRQ bit of tag + if (gif->chcr.TIE && (Tag::IRQ(ptag))) { GIF_LOG("dmaIrq Set"); gspath3done = true; @@ -151,28 +150,30 @@ static __forceinline bool checkTieBit(u32* &ptag) return false; } -static __forceinline bool ReadTag(u32* &ptag, u32 &id) +static __forceinline u32* ReadTag(u32 &id) { - ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + u32* ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + + if (!(Tag::Transfer("Gif", gif, ptag))) return NULL; - if (!(Tag::Transfer("Gif", gif, ptag))) return false; gif->madr = ptag[1]; //MADR = ADDR field - id = Tag::Id(ptag); //ID for DmaChain copied from bit 28 of the tag + id = Tag::Id(ptag); gscycles += 2; // Add 1 cycles from the QW read for the tag gspath3done = hwDmacSrcChainWithStack(gif, id); - return true; + return ptag; } -static __forceinline void ReadTag2(u32* &ptag) +static __forceinline u32* ReadTag2() { - ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR + u32* ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR Tag::UnsafeTransfer(gif, ptag); gif->madr = ptag[1]; gspath3done = hwDmacSrcChainWithStack(gif, Tag::Id(ptag)); + return ptag; } void GIFdma() @@ -209,6 +210,7 @@ void GIFdma() //Path2 gets priority in intermittent mode if ((gifRegs->stat.P1Q || (vif1.cmd & 0x7f) == 0x50) && gifRegs->mode.IMT && (Path3progress == IMAGE_MODE)) { + // We are in image mode doing DIRECTHL, Path 1 is in queue, and in intermittant mode. GIF_LOG("Waiting VU %x, PATH2 %x, GIFMODE %x Progress %x", gifRegs->stat.P1Q, (vif1.cmd & 0x7f), gifRegs->mode._u32, Path3progress); CPU_INT(2, 16); return; @@ -220,7 +222,8 @@ void GIFdma() { if ((gif->chcr.MOD == CHAIN_MODE) && gif->chcr.STR) { - if (!ReadTag(ptag, id)) return; + ptag = ReadTag(id); + 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); //Check TIE bit of CHCR and IRQ bit of tag @@ -257,7 +260,8 @@ void GIFdma() if ((gif->chcr.MOD == CHAIN_MODE) && (!gspath3done)) // Chain Mode { - if (!ReadTag(ptag, id)) return; + ptag = ReadTag(id); + 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); if (dmacRegs->ctrl.STD == STD_GIF) @@ -312,7 +316,7 @@ void dmaGIF() gspath3done = false; // For some reason this doesn't clear? So when the system starts the thread, we will clear it :) gifRegs->stat.P3Q = 1; - gifRegs->stat.FQC |= 0x10;// FQC=31, hack ;) ( 31? 16! arcum42) [used to be 0xE00; // OPH=1 | APATH=3] + gifRegs->stat.FQC |= 0x10; // hack ;) clearFIFOstuff(true); @@ -325,9 +329,7 @@ void dmaGIF() if ((gif->qwc == 0) && (gif->chcr.MOD != NORMAL_MODE)) { - u32 *ptag; - - ReadTag2(ptag); + 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); checkTieBit(ptag); @@ -401,10 +403,12 @@ static __forceinline int mfifoGIFchain() } else { - int mfifoqwc = gif->qwc; + int mfifoqwc; + u32 *pMem = (u32*)dmaGetAddr(gif->madr); if (pMem == NULL) return -1; - mfifoqwc = WRITERING_DMA(pMem, mfifoqwc); + + mfifoqwc = WRITERING_DMA(pMem, gif->qwc); mfifocycles += (mfifoqwc) * 2; /* guessing */ } @@ -420,7 +424,6 @@ void mfifoGIFtransfer(int qwc) { u32 *ptag; int id; - u32 temp = 0; mfifocycles = 0; gifmfifoirq = false; @@ -428,8 +431,11 @@ void mfifoGIFtransfer(int qwc) if(qwc > 0 ) { gifqwc += qwc; - if (gifstate != GIF_STATE_EMPTY) return; + + if (!(gifstate & GIF_STATE_EMPTY)) return; + // if (gifempty == false) return; gifstate &= ~GIF_STATE_EMPTY; + gifempty = false; } GIF_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr); @@ -440,13 +446,14 @@ void mfifoGIFtransfer(int qwc) { //if( gifqwc > 1 ) DevCon.WriteLn("gif mfifo tadr==madr but qwc = %d", gifqwc); hwDmacIrq(DMAC_MFIFO_EMPTY); - gifstate |= GIF_STATE_EMPTY; + gifstate |= GIF_STATE_EMPTY; + gifempty = true; return; } gif->tadr = qwctag(gif->tadr); + ptag = (u32*)dmaGetAddr(gif->tadr); - Tag::UnsafeTransfer(gif, ptag); gif->madr = ptag[1]; @@ -472,11 +479,13 @@ void mfifoGIFtransfer(int qwc) break; case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR - temp = gif->madr; //Temporarily Store ADDR + { + u32 temp = gif->madr; //Temporarily Store ADDR gif->madr = qwctag(gif->tadr + 16); //Set MADR to QW following the tag gif->tadr = temp; //Copy temporarily stored ADDR to Tag gifstate = GIF_STATE_READY; break; + } case TAG_REF: // Ref - Transfer QWC from ADDR field case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control) @@ -507,7 +516,7 @@ void mfifoGIFtransfer(int qwc) } FreezeRegs(0); - if ((gif->qwc == 0) && (gifstate == GIF_STATE_DONE)) gifstate = GIF_STATE_STALL; + if ((gif->qwc == 0) && (gifstate & GIF_STATE_DONE)) gifstate = GIF_STATE_STALL; CPU_INT(11,mfifocycles); SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr); @@ -515,6 +524,7 @@ void mfifoGIFtransfer(int qwc) void gifMFIFOInterrupt() { + Console.WriteLn("gifMFIFOInterrupt"); mfifocycles = 0; if (Path3progress == STOPPED_MODE) @@ -543,13 +553,15 @@ void gifMFIFOInterrupt() return; } - if (gifstate != GIF_STATE_STALL) + if (!(gifstate & GIF_STATE_STALL)) { if (gifqwc <= 0) { //Console.WriteLn("Empty"); hwDmacIrq(DMAC_MFIFO_EMPTY); gifstate |= GIF_STATE_EMPTY; + gifempty = true; + gifRegs->stat.IMT = 0; return; } @@ -558,7 +570,7 @@ void gifMFIFOInterrupt() } #ifdef PCSX2_DEVBUILD - if (gifstate == GIF_STATE_READY || gif->qwc > 0) + if ((gifstate & GIF_STATE_READY) || (gif->qwc > 0)) { Console.Error("gifMFIFO Panic > Shouldn't go here!"); return; @@ -587,6 +599,6 @@ void SaveStateBase::gifFreeze() Freeze( gifqwc ); Freeze( gspath3done ); Freeze( gscycles ); - + //Freeze(gifempty); // Note: mfifocycles is not a persistent var, so no need to save it here. } diff --git a/pcsx2/IopHw.h b/pcsx2/IopHw.h index 784e3d0e31..ef95fde6e5 100644 --- a/pcsx2/IopHw.h +++ b/pcsx2/IopHw.h @@ -134,10 +134,21 @@ enum DMAChcrAddresses enum DMATadrAddresses { + HWx_DMA0_TADR = 0x1f80108c, + HWx_DMA1_TADR = 0x1f80109c, HWx_DMA2_TADR = 0x1f8010ac, + HWx_DMA3_TADR = 0x1f8010bc, HWx_DMA4_TADR = 0x1f8010cc, - HWx_DMA9_TADR = 0x1f80152c + HWx_DMA5_TADR = 0x1f8010dc, + HWx_DMA6_TADR = 0x1f8010ec, + HWx_DMA7_TADR = 0x1f80150c, + HWx_DMA8_TADR = 0x1f80151c, + HWx_DMA9_TADR = 0x1f80152c, + HWx_DMA10_TADR = 0x1f80153c, + HWx_DMA11_TADR = 0x1f80154c, + HWx_DMA12_TADR = 0x1f80155c }; + /* Registers for the IOP Counters */ enum IOPCountRegs { diff --git a/pcsx2/SPR.cpp b/pcsx2/SPR.cpp index 1cac26802d..50bdb03805 100644 --- a/pcsx2/SPR.cpp +++ b/pcsx2/SPR.cpp @@ -66,14 +66,14 @@ int _SPR0chain() else mfifotransferred += spr0->qwc; - hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); + hwMFIFOWrite(spr0->madr, &psSu8(spr0->sadr), spr0->qwc << 4); spr0->madr += spr0->qwc << 4; spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK); break; case NO_MFD: case MFD_RESERVED: - memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); + memcpy_fast((u8*)pMem, &psSu8(spr0->sadr), spr0->qwc << 4); // clear VU mem also! TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes) @@ -97,7 +97,7 @@ void _SPR0interleave() { int qwc = spr0->qwc; int sqwc = dmacRegs->sqwc.SQWC; - int tqwc = dmacRegs->sqwc.TQWC; + int tqwc = dmacRegs->sqwc.TQWC; u32 *pMem; if (tqwc == 0) tqwc = qwc; @@ -115,7 +115,7 @@ void _SPR0interleave() { case MFD_VIF1: case MFD_GIF: - hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); + hwMFIFOWrite(spr0->madr, &psSu8(spr0->sadr), spr0->qwc << 4); mfifotransferred += spr0->qwc; break; @@ -123,7 +123,7 @@ void _SPR0interleave() case MFD_RESERVED: // clear VU mem also! TestClearVUs(spr0->madr, spr0->qwc << 2); - memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); + memcpy_fast((u8*)pMem, &psSu8(spr0->sadr), spr0->qwc << 4); break; } spr0->sadr += spr0->qwc * 16; @@ -163,7 +163,7 @@ static __forceinline void _dmaSPR0() return; } // Destination Chain Mode - ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; + ptag = &psSu32(spr0->sadr); spr0->sadr += 16; Tag::UnsafeTransfer(spr0, ptag); @@ -186,25 +186,26 @@ static __forceinline void _dmaSPR0() break; case TAG_CNT: // CNT - Transfer QWC following the tag. - done = FALSE; + done = false; break; case TAG_END: // End - Transfer QWC following the tag - done = TRUE; + done = true; break; } + SPR0chain(); if (spr0->chcr.TIE && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag { //Console.WriteLn("SPR0 TIE"); - done = TRUE; + done = true; } spr0finished = done; if (!done) { - ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR + ptag = &psSu32(spr0->sadr); //Set memory pointer to SADR CPU_INT(8, ((u16)ptag[0]) / BIAS); // the lower 16bits of the tag / BIAS); return; } @@ -227,8 +228,18 @@ void SPRFROMinterrupt() if(mfifotransferred != 0) { - switch (dmacRegs->ctrl.MFD) + switch (dmacRegs->ctrl.MFD) { + case MFD_VIF1: // Most common case. + { + if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("VIF MFIFO Write outside MFIFO area"); + spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK); + //Console.WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr); + mfifoVIF1transfer(mfifotransferred); + mfifotransferred = 0; + if (vif1ch->chcr.STR) return; + break; + } case MFD_GIF: { if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("GIF MFIFO Write outside MFIFO area"); @@ -239,16 +250,6 @@ void SPRFROMinterrupt() if (gif->chcr.STR) return; break; } - case MFD_VIF1: - { - if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console.WriteLn("VIF MFIFO Write outside MFIFO area"); - spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK); - //Console.WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr); - mfifoVIF1transfer(mfifotransferred); - mfifotransferred = 0; - if (vif1ch->chcr.STR) return; - break; - } default: break; } @@ -258,7 +259,6 @@ void SPRFROMinterrupt() hwDmacIrq(DMAC_FROM_SPR); } - void dmaSPR0() // fromSPR { SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx", @@ -267,7 +267,7 @@ void dmaSPR0() // fromSPR if ((spr0->chcr.MOD == CHAIN_MODE) && spr0->qwc == 0) { u32 *ptag; - ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR + ptag = &psSu32(spr0->sadr); //Set memory pointer to SADR CPU_INT(8, (ptag[0] & 0xffff) / BIAS); return; } @@ -279,7 +279,7 @@ void dmaSPR0() // fromSPR __forceinline static void SPR1transfer(u32 *data, int size) { - memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)data, size << 2); + memcpy_fast(&psSu8(spr1->sadr), (u8*)data, size << 2); spr1->sadr += size << 2; } @@ -305,7 +305,6 @@ __forceinline void SPR1chain() spr1->qwc = 0; } - void _SPR1interleave() { int qwc = spr1->qwc; @@ -322,7 +321,7 @@ void _SPR1interleave() spr1->qwc = std::min(tqwc, qwc); qwc -= spr1->qwc; pMem = (u32*)dmaGetAddr(spr1->madr); - memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)pMem, spr1->qwc << 4); + memcpy_fast(&psSu8(spr1->sadr), (u8*)pMem, spr1->qwc << 4); spr1->sadr += spr1->qwc * 16; spr1->madr += (sqwc + spr1->qwc) * 16; } @@ -405,11 +404,10 @@ void _dmaSPR1() // toSPR work function break; } } - } + void dmaSPR1() // toSPR { - SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n" " tadr = 0x%x, sadr = 0x%x", spr1->chcr._u32, spr1->madr, spr1->qwc, diff --git a/pcsx2/SaveState.cpp b/pcsx2/SaveState.cpp index dd6d4c7554..08bb0b9979 100644 --- a/pcsx2/SaveState.cpp +++ b/pcsx2/SaveState.cpp @@ -365,7 +365,7 @@ void memSavingState::FreezeMem( void* data, int size ) void memSavingState::FreezeAll() { - // 90% of all savestates fit in under 45 megs (and require more than 43 megs, so migght as well...) + // 90% of all savestates fit in under 45 megs (and require more than 43 megs, so might as well...) m_memory.ChunkSize = ReallocThreshold; m_memory.MakeRoomFor( MemoryBaseAllocSize ); diff --git a/pcsx2/Sif.cpp b/pcsx2/Sif.cpp index 69a0a4c9f3..4eaf8a5976 100644 --- a/pcsx2/Sif.cpp +++ b/pcsx2/Sif.cpp @@ -201,8 +201,8 @@ __forceinline void SIF0Dma() else SIF_LOG(" EE SIF interrupt"); - eesifbusy[0] = false; CPU_INT(5, cycles*BIAS); + eesifbusy[0] = false; done = true; } else if (sif0.fifoSize >= 4) // Read a tag @@ -216,7 +216,7 @@ __forceinline void SIF0Dma() sif0dma->madr = tag[1]; SIF_LOG(" EE SIF dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", sif0dma->madr, sif0dma->qwc, (tag[0] >> 28)&3, (tag[0] >> 31)&1, tag[1], tag[0]); - + switch (Tag::Id(tag[0])) { case TAG_REFE: @@ -277,9 +277,7 @@ __forceinline void SIF1Dma() ptag = _dmaGetAddr(sif1dma, sif1dma->tadr, DMAC_SIF1); if (ptag == NULL) return; - - sif1dma->chcr._u32 = (sif1dma->chcr._u32 & 0xFFFF) | ((*ptag) & 0xFFFF0000); // Copy the tag - sif1dma->qwc = (u16)ptag[0]; + Tag::UnsafeTransfer(sif1dma, ptag); if (sif1dma->chcr.TTE) { @@ -287,6 +285,11 @@ __forceinline void SIF1Dma() SIF1write(ptag + 2, 2); } + if ((sif1dma->chcr.TIE) && (Tag::IRQ(ptag))) + { + Console.WriteLn("SIF1 TIE"); + sif1.end = 1; + } //sif1.chain = 1; switch (Tag::Id(ptag)) @@ -327,11 +330,6 @@ __forceinline void SIF1Dma() default: Console.WriteLn("Bad addr1 source chain"); } - if ((sif1dma->chcr.TIE) && (Tag::IRQ(ptag))) - { - Console.WriteLn("SIF1 TIE"); - sif1.end = 1; - } } } else // There's some data ready to transfer into the fifo..