From e86d7fba0e47bfcf9fe5010adab36424a89991b3 Mon Sep 17 00:00:00 2001 From: arcum42 Date: Fri, 5 Feb 2010 12:41:25 +0000 Subject: [PATCH] Sif: Implemented a new _sif structure, and made the code use it. Added some temporary code to try to keep the savestate backward compatible. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2563 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/IopDma.cpp | 8 ++--- pcsx2/Sif.cpp | 41 +++++++++++++++++++------- pcsx2/Sif.h | 23 ++++++++++----- pcsx2/Sif0.cpp | 77 +++++++++++++++++++++++------------------------- pcsx2/Sif1.cpp | 77 ++++++++++++++++++++++-------------------------- 5 files changed, 122 insertions(+), 104 deletions(-) diff --git a/pcsx2/IopDma.cpp b/pcsx2/IopDma.cpp index 443f6fc0d1..9312d58827 100644 --- a/pcsx2/IopDma.cpp +++ b/pcsx2/IopDma.cpp @@ -169,10 +169,10 @@ void psxDma9(u32 madr, u32 bcr, u32 chcr) { SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx", chcr, madr, bcr, HW_DMA9_TADR); - iopsifbusy[0] = true; + sif0.iop.busy = true; psHu32(SBUS_F240) |= 0x2000; - if (eesifbusy[0]) + if (sif0.ee.busy) { SIF0Dma(); psHu32(SBUS_F240) &= ~0x20; @@ -184,10 +184,10 @@ void psxDma10(u32 madr, u32 bcr, u32 chcr) { SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx", chcr, madr, bcr); - iopsifbusy[1] = true; + sif1.iop.busy = true; psHu32(SBUS_F240) |= 0x4000; - if (eesifbusy[1]) + if (sif1.ee.busy) { XMMRegisters::Freeze(); SIF1Dma(); diff --git a/pcsx2/Sif.cpp b/pcsx2/Sif.cpp index 48d460143c..3c52ea4040 100644 --- a/pcsx2/Sif.cpp +++ b/pcsx2/Sif.cpp @@ -20,16 +20,10 @@ #include "IopCommon.h" #include "Sif.h" -extern _sif sif0, sif1; -bool eesifbusy[2] = { false, false }; -bool iopsifbusy[2] = { false, false }; - void sifInit() { memzero(sif0); memzero(sif1); - memzero(eesifbusy); - memzero(iopsifbusy); } __forceinline void dmaSIF2() @@ -46,9 +40,34 @@ void SaveStateBase::sifFreeze() { FreezeTag("SIFdma"); - Freeze(sif0); - Freeze(sif1); - - Freeze(eesifbusy); - Freeze(iopsifbusy); + // Nasty backwards compatability stuff. + old_sif_structure old_sif0, old_sif1; + bool ee_busy[2], iop_busy[2]; + + old_sif0.fifo = sif0.fifo; + old_sif1.fifo = sif1.fifo; + + ee_busy[0] = sif0.ee.busy; + ee_busy[1] = sif1.ee.busy; + iop_busy[0] = sif0.iop.busy; + iop_busy[1] = sif1.iop.busy; + + old_sif0.end = (sif0.ee.end) ? 1 : 0; + old_sif1.end = (sif1.iop.end) ? 1 : 0; + + old_sif0.counter = sif0.iop.counter; + old_sif1.counter = sif1.iop.counter; + + old_sif0.data = sif0.iop.data; + old_sif1.data = sif1.iop.data; + + Freeze(old_sif0); + Freeze(old_sif1); + Freeze(ee_busy); + Freeze(iop_busy); + + // When we break save state, switch to just freezing sif0 & sif1. + +// Freeze(sif0); +// Freeze(sif1); } diff --git a/pcsx2/Sif.h b/pcsx2/Sif.h index b5cfc89cc9..b4e9d47a9f 100644 --- a/pcsx2/Sif.h +++ b/pcsx2/Sif.h @@ -83,7 +83,7 @@ struct sifFifo } }; -struct _sif +struct old_sif_structure { sifFifo fifo; // Used in both. s32 chain; // Not used. @@ -93,17 +93,20 @@ struct _sif struct sifData data; // Only used in IOP. }; -/* struct sif_ee { bool end; // Only used for EE. bool busy; + + s32 cycles; }; struct sif_iop { bool end; bool busy; - + + s32 cycles; + s32 counter; // Used to keep track of how much is left in IOP. struct sifData data; // Only used in IOP. }; @@ -112,9 +115,9 @@ struct _sif sifFifo fifo; // Used in both. sif_ee ee; sif_iop iop; -};*/ +}; -extern bool eesifbusy[2], iopsifbusy[2]; +extern _sif sif0, sif1; extern void sifInit(); @@ -131,7 +134,13 @@ extern void EEsif1Interrupt(); extern void sif0Interrupt(); extern void sif1Interrupt(); -#define sif0tag DMA_TAG(sif0.data.data) -#define sif1tag DMA_TAG(sif1.data.data) +#define sif0data sif0.iop.data.data +#define sif1data sif1.iop.data.data + +#define sif0words sif0.iop.data.words +#define sif1words sif1.iop.data.words + +#define sif0tag DMA_TAG(sif0data) +#define sif1tag DMA_TAG(sif1data) #endif /* __SIF_H__ */ diff --git a/pcsx2/Sif0.cpp b/pcsx2/Sif0.cpp index 3f308512ad..278f02d560 100644 --- a/pcsx2/Sif0.cpp +++ b/pcsx2/Sif0.cpp @@ -23,17 +23,12 @@ _sif sif0; static bool done = false; -static int cycles = 0, psxCycles = 0; static __forceinline void Sif0Init() { done = false; - cycles = 0; - psxCycles = 0; - //if (sif0.end == 1) SIF_LOG("Starting with sif0.end set."); - //memzero(sif0); - //sif0.end = 0; - //sif0.data.data = 0; + sif0.ee.cycles = 0; + sif0.iop.cycles = 0; } // Write from Fifo to EE. @@ -60,7 +55,7 @@ static __forceinline bool WriteFifoToEE() //Cpu->Clear(sif0dma->madr, readSize*4); sif0dma->madr += readSize << 4; - cycles += readSize; // fixme : BIAS is factored in above + sif0.ee.cycles += readSize; // fixme : BIAS is factored in above sif0dma->qwc -= readSize; //} //else @@ -75,7 +70,7 @@ static __forceinline bool WriteFifoToEE() static __forceinline bool WriteIOPtoFifo() { // There's some data ready to transfer into the fifo.. - const int writeSize = min(sif0.counter, sif0.fifo.free()); + const int writeSize = min(sif0.iop.counter, sif0.fifo.free()); //if (writeSize <= 0) //{ @@ -84,14 +79,14 @@ static __forceinline bool WriteIOPtoFifo() //} //else //{ - SIF_LOG("Write IOP to Fifo: +++++++++++ %lX of %lX", writeSize, sif0.counter); + SIF_LOG("Write IOP to Fifo: +++++++++++ %lX of %lX", writeSize, sif0.iop.counter); sif0.fifo.write((u32*)iopPhysMem(hw_dma(9).madr), writeSize); hw_dma(9).madr += writeSize << 2; // iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords). - psxCycles += (writeSize >> 2) * BIAS; // fixme : should be >> 4 - sif0.counter -= writeSize; + sif0.iop.cycles += (writeSize >> 2) * BIAS; // fixme : should be >> 4 + sif0.iop.counter -= writeSize; //} return true; } @@ -114,13 +109,13 @@ static __forceinline bool ProcessEETag() if (sif0dma->chcr.TIE && ptag.IRQ) { //Console.WriteLn("SIF0 TIE"); - sif0.end = 1; + sif0.ee.end = true; } switch (ptag.ID) { case TAG_REFE: - sif0.end = 1; + sif0.ee.end = true; if (dmacRegs->ctrl.STS != NO_STS) dmacRegs->stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16); break; @@ -131,7 +126,7 @@ static __forceinline bool ProcessEETag() break; case TAG_END: - sif0.end = 1; + sif0.ee.end = true; break; } return true; @@ -141,22 +136,23 @@ static __forceinline bool ProcessEETag() static __forceinline bool ProcessIOPTag() { // Process DMA tag at hw_dma(9).tadr - sif0.data = *(sifData *)iopPhysMem(hw_dma(9).tadr); - sif0.data.words = (sif0.data.words + 3) & 0xfffffffc; // Round up to nearest 4. + sif0.iop.data = *(sifData *)iopPhysMem(hw_dma(9).tadr); + sif0.iop.data.words = (sif0.iop.data.words + 3) & 0xfffffffc; // Round up to nearest 4. sif0.fifo.write((u32*)iopPhysMem(hw_dma(9).tadr + 8), 4); hw_dma(9).tadr += 16; ///hw_dma(9).madr + 16 + sif0.sifData.words << 2; // Looks like we are only copying the first 24 bits. #ifdef CHOP_OFF_DATA - hw_dma(9).madr = sif0.data.data & 0xFFFFFF; + hw_dma(9).madr = sif0data & 0xFFFFFF; #else - hw_dma(9).madr = sif0.data.data; + hw_dma(9).madr = sif0data; #endif - sif0.counter = sif0.data.words; - //if (sif0.data.words != ( sif0.data.words & 0xFFFFFF)) DevCon.WriteLn("sif0.data.words more then 24 bit."); + sif0.iop.counter = sif0words; + //if (sif0words != ( sif0words & 0xFFFFFF)) DevCon.WriteLn("sif0words more then 24 bit."); - SIF_LOG("SIF0 IOP Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", hw_dma(9).madr, hw_dma(9).tadr, sif0.counter, sif0.data.words, sif0.data.data); + if (sif0tag.IRQ || (sif0tag.ID & 4)) sif0.iop.end = true; + SIF_LOG("SIF0 IOP Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", hw_dma(9).madr, hw_dma(9).tadr, sif0.iop.counter, sif0words, sif0data); return true; } @@ -164,9 +160,9 @@ static __forceinline bool ProcessIOPTag() static __forceinline void EndEE() { SIF_LOG("Sif0: End EE"); - sif0.end = 0; - eesifbusy[0] = false; - if (cycles == 0) + sif0.ee.end = false; + sif0.ee.busy = false; + if (sif0.ee.cycles == 0) { // No transfer happened, DevCon.Warning("SIF0 EE: cycles = 0"); @@ -174,7 +170,7 @@ static __forceinline void EndEE() else { // hence no Interrupt. - CPU_INT(DMAC_SIF0, cycles*BIAS); + CPU_INT(DMAC_SIF0, sif0.ee.cycles*BIAS); } } @@ -182,10 +178,11 @@ static __forceinline void EndEE() static __forceinline void EndIOP() { SIF_LOG("Sif0: End IOP"); - sif0.data.data = 0; - iopsifbusy[0] = false; + sif0data = 0; + sif0.iop.end = false; + sif0.iop.busy = false; - if (psxCycles == 0) + if (sif0.iop.cycles == 0) { // No transfer happened, DevCon.Warning("SIF0 IOP: cycles = 0"); @@ -195,8 +192,8 @@ static __forceinline void EndIOP() // hence no Interrupt. // iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords) // So when we're all done, the equation looks like thus: - //PSX_INT(IopEvt_SIF0, ( ( psxCycles*BIAS ) / 4 ) / 8); - PSX_INT(IopEvt_SIF0, psxCycles); + //PSX_INT(IopEvt_SIF0, ( ( sif0.iop.cycles*BIAS ) / 4 ) / 8); + PSX_INT(IopEvt_SIF0, sif0.iop.cycles); } } @@ -212,7 +209,7 @@ static __forceinline void HandleEETransfer() if (sif0dma->qwc <= 0) { - if ((sif0dma->chcr.MOD == NORMAL_MODE) || sif0.end) + if ((sif0dma->chcr.MOD == NORMAL_MODE) || sif0.ee.end) { // Stop transferring ee, and signal an interrupt. done = true; @@ -252,7 +249,7 @@ static __forceinline void HandleEETransfer() // Sif0: End EE // SIF0 DMA end... -// What happens if (sif0.counter > 0) is handled first is this +// What happens if (sif0.iop.counter > 0) is handled first is this // SIF0 DMA start... // ... @@ -264,9 +261,9 @@ static __forceinline void HandleEETransfer() static __forceinline void HandleIOPTransfer() { - if (sif0.counter <= 0) // If there's no more to transfer + if (sif0.iop.counter <= 0) // If there's no more to transfer { - if (sif0tag.IRQ || (sif0tag.ID & 4)) + if (sif0.iop.end) { // Stop transferring iop, and signal an interrupt. done = true; @@ -298,9 +295,9 @@ __forceinline void SIF0Dma() do { - if (iopsifbusy[0]) HandleIOPTransfer(); - if (eesifbusy[0]) HandleEETransfer(); - } while (!done); // Substituting (iopsifbusy[0] || eesifbusy[0]) breaks things. + if (sif0.iop.busy) HandleIOPTransfer(); + if (sif0.ee.busy) HandleEETransfer(); + } while (!done); // Substituting (sif0.ee.busy || sif0.iop.busy) breaks things. SIF_LOG("SIF0 DMA end..."); Sif0End(); @@ -328,9 +325,9 @@ __forceinline void dmaSIF0() } psHu32(SBUS_F240) |= 0x2000; - eesifbusy[0] = true; + sif0.ee.busy = true; - if (iopsifbusy[0]) + if (sif0.iop.busy) { XMMRegisters::Freeze(); hwIntcIrq(INTC_SBUS); diff --git a/pcsx2/Sif1.cpp b/pcsx2/Sif1.cpp index efbf863fd2..a64e158cf4 100644 --- a/pcsx2/Sif1.cpp +++ b/pcsx2/Sif1.cpp @@ -23,17 +23,12 @@ _sif sif1; static bool done = false; -static int cycles = 0, psxCycles = 0; static __forceinline void Sif1Init() { done = false; - cycles = 0; - psxCycles = 0; - //if (sif1.end == 1) SIF_LOG("Starting with sif1.end set."); - //memzero(sif1); - //sif1.end = 0; - //sif1.data.data = 0; + sif1.ee.cycles = 0; + sif1.iop.cycles = 0; } // Write from the EE to Fifo. @@ -62,7 +57,7 @@ static __forceinline bool WriteEEtoFifo() sif1.fifo.write((u32*)ptag, writeSize << 2); sif1dma->madr += writeSize << 4; - cycles += writeSize; // fixme : BIAS is factored in above + sif1.ee.cycles += writeSize; // fixme : BIAS is factored in above sif1dma->qwc -= writeSize; //} return true; @@ -74,7 +69,7 @@ static __forceinline bool WriteFifoToIOP() // If we're reading something, continue to do so. SIF_LOG("Sif1: Write Fifo to IOP"); - const int readSize = min (sif1.counter, sif1.fifo.size); + const int readSize = min (sif1.iop.counter, sif1.fifo.size); //if (readSize <= 0) //{ //DevCon.Warning("WriteFifoToIOP: readSize is 0"); @@ -87,8 +82,8 @@ static __forceinline bool WriteFifoToIOP() sif1.fifo.read((u32*)iopPhysMem(hw_dma(10).madr), readSize); psxCpu->Clear(hw_dma(10).madr, readSize); hw_dma(10).madr += readSize << 2; - psxCycles += readSize >> 2; // fixme: should be >> 4 - sif1.counter -= readSize; + sif1.iop.cycles += readSize >> 2; // fixme: should be >> 4 + sif1.iop.counter -= readSize; //} return true; } @@ -117,40 +112,36 @@ static __forceinline bool ProcessEETag() if (sif1dma->chcr.TIE && ptag->IRQ) { Console.WriteLn("SIF1 TIE"); - sif1.end = 1; + sif1.ee.end = true; } + SIF_LOG(wxString(ptag->tag_to_str()).To8BitData()); switch (ptag->ID) { case TAG_REFE: - SIF_LOG(" REFE %08X", ptag[1]._u32); - sif1.end = 1; + sif1.ee.end = true; sif1dma->madr = ptag[1]._u32; sif1dma->tadr += 16; break; case TAG_CNT: - SIF_LOG(" CNT"); sif1dma->madr = sif1dma->tadr + 16; sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4); break; case TAG_NEXT: - SIF_LOG(" NEXT %08X", ptag[1]._u32); sif1dma->madr = sif1dma->tadr + 16; sif1dma->tadr = ptag[1]._u32; break; case TAG_REF: case TAG_REFS: - SIF_LOG(" REF %08X", ptag[1]._u32); sif1dma->madr = ptag[1]._u32; sif1dma->tadr += 16; break; case TAG_END: - SIF_LOG(" END"); - sif1.end = 1; + sif1.ee.end = true; sif1dma->madr = sif1dma->tadr + 16; sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4); break; @@ -165,33 +156,34 @@ static __forceinline bool ProcessEETag() static __forceinline bool SIFIOPReadTag() { // Read a tag. - sif1.fifo.read((u32*)&sif1.data, 4); - //sif1.data.words = (sif1.data.words + 3) & 0xfffffffc; // Round up to nearest 4. + sif1.fifo.read((u32*)&sif1.iop.data, 4); + //sif1words = (sif1words + 3) & 0xfffffffc; // Round up to nearest 4. SIF_LOG("SIF 1 IOP: dest chain tag madr:%08X wc:%04X id:%X irq:%d", - sif1.data.data & 0xffffff, sif1.data.words, sif1tag.ID, sif1tag.IRQ); + sif1data & 0xffffff, sif1words, sif1tag.ID, sif1tag.IRQ); #ifdef CHOP_OFF_DATA - hw_dma(10).madr = sif1.data.data & 0xffffff; + hw_dma(10).madr = sif1data & 0xffffff; #else - hw_dma(10).madr = sif1.data.data; + hw_dma(10).madr = sif1data; #endif - sif1.counter = sif1.data.words; - //if (sif1.data.words != ( sif1.data.words & 0xFFFFFF)) DevCon.WriteLn("sif1.data.words more then 24 bit."); + sif1.iop.counter = sif1words; + //if (sif1words != ( sif1words & 0xFFFFFF)) DevCon.WriteLn("sif1words more then 24 bit."); + if (sif1tag.IRQ || (sif1tag.ID & 4)) sif1.iop.end = true; return true; } // Stop processing EE, and signal an interrupt. static __forceinline void EndEE() { - sif1.end = 0; - eesifbusy[1] = false; + sif1.ee.end = false; + sif1.ee.busy = false; SIF_LOG("Sif 1: End EE"); // Voodoocycles : Okami wants around 100 cycles when booting up // Other games reach like 50k cycles here, but the EE will long have given up by then and just retry. // (Cause of double interrupts on the EE) - if (cycles == 0) + if (sif1.ee.cycles == 0) { // No transfer happened DevCon.Warning("SIF1 EE: cycles = 0"); @@ -199,22 +191,23 @@ static __forceinline void EndEE() else { // Hence no Interrupt (fixes Eternal Poison reboot when selecting new game) - CPU_INT(DMAC_SIF1, min((int)(cycles*BIAS), 384)); + CPU_INT(DMAC_SIF1, min((int)(sif1.ee.cycles*BIAS), 384)); } } // Stop processing IOP, and signal an interrupt. static __forceinline void EndIOP() { - sif1.data.data = 0; - iopsifbusy[1] = false; + sif1data = 0; + sif1.iop.end = false; + sif1.iop.busy = false; SIF_LOG("Sif 1: End IOP"); //Fixme ( voodoocycles ): //The *24 are needed for ecco the dolphin (CDVD hangs) and silver surfer (Pad not detected) //Greater than *35 break rebooting when trying to play Tekken5 arcade history //Total cycles over 1024 makes SIF too slow to keep up the sound stream in so3... - if (psxCycles == 0) + if (sif1.iop.cycles == 0) { // No transfer happened DevCon.Warning("SIF1 IOP: cycles = 0"); @@ -223,7 +216,7 @@ static __forceinline void EndIOP() { // Hence no Interrupt // iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords) - PSX_INT(IopEvt_SIF1, min((psxCycles * 26), 1024)); + PSX_INT(IopEvt_SIF1, min((sif1.iop.cycles * 26), 1024)); } } @@ -241,7 +234,7 @@ static __forceinline void HandleEETransfer() if (sif1dma->qwc <= 0) { // If NORMAL mode or end of CHAIN then stop DMA. - if ((sif1dma->chcr.MOD == NORMAL_MODE) || sif1.end) + if ((sif1dma->chcr.MOD == NORMAL_MODE) || sif1.ee.end) { done = true; EndEE(); @@ -261,14 +254,14 @@ static __forceinline void HandleEETransfer() // Handle the IOP transfer. static __forceinline void HandleIOPTransfer() { - if (sif1.counter > 0) + if (sif1.iop.counter > 0) { WriteFifoToIOP(); } - if (sif1.counter <= 0) + if (sif1.iop.counter <= 0) { - if (sif1tag.IRQ || (sif1tag.ID & 4)) + if (sif1.iop.end) { done = true; EndIOP(); @@ -294,8 +287,8 @@ __forceinline void SIF1Dma() do { - if (eesifbusy[1]) HandleEETransfer(); - if (iopsifbusy[1]) HandleIOPTransfer(); + if (sif1.ee.busy) HandleEETransfer(); + if (sif1.iop.busy) HandleIOPTransfer(); } while (!done); SIF_LOG("SIF1 DMA end..."); @@ -326,9 +319,9 @@ __forceinline void dmaSIF1() } psHu32(SBUS_F240) |= 0x4000; - eesifbusy[1] = true; + sif1.ee.busy = true; - if (iopsifbusy[1]) + if (sif1.iop.busy) { XMMRegisters::Freeze(); SIF1Dma();