diff --git a/pcsx2/Sif.cpp b/pcsx2/Sif.cpp index 6da6f154ba..dc6d7bf194 100644 --- a/pcsx2/Sif.cpp +++ b/pcsx2/Sif.cpp @@ -20,8 +20,7 @@ #include "IopCommon.h" #include "Sif.h" -_sif sif0, sif1; - +extern _sif sif0, sif1; bool eesifbusy[2] = { false, false }; extern bool iopsifbusy[2]; diff --git a/pcsx2/Sif.h b/pcsx2/Sif.h index cfbde7c392..7154ae0201 100644 --- a/pcsx2/Sif.h +++ b/pcsx2/Sif.h @@ -69,6 +69,13 @@ struct sifFifo } SIF_LOG(" SIF - %d = %d (pos=%d)", words, size, readPos); } + void clear() + { + memzero(data); + readPos = 0; + writePos = 0; + size = 0; + } }; struct _sif @@ -80,10 +87,8 @@ struct _sif s32 counter; struct sifData data; }; -extern _sif sif0, sif1; -extern bool eesifbusy[2]; -extern bool iopsifbusy[2]; +extern bool eesifbusy[2], iopsifbusy[2]; extern void sifInit(); diff --git a/pcsx2/Sif0.cpp b/pcsx2/Sif0.cpp index 324736ba5e..4e9e8966b3 100644 --- a/pcsx2/Sif0.cpp +++ b/pcsx2/Sif0.cpp @@ -20,7 +20,23 @@ #include "IopCommon.h" #include "Sif.h" -static __forceinline bool SifEERead(int &cycles) +_sif sif0; + +static bool done = false; +static int cycles = 0, psxCycles = 0; + +static __forceinline void Sif0Init() +{ + done = false; + cycles = 0; + psxCycles = 0; + memzero(sif0); + //sif0.end = 0; + //sif0.data.data = 0; +} + +// Write from Fifo to EE. +static __forceinline bool SifEERead() { const int readSize = min((s32)sif0dma->qwc, sif0.fifo.size >> 2); //if (readSize <= 0) @@ -54,7 +70,8 @@ static __forceinline bool SifEERead(int &cycles) return true; } -static __forceinline bool SifIOPWrite(int &psxCycles) +// Write IOP to Fifo. +static __forceinline bool SifIOPWrite() { // There's some data ready to transfer into the fifo.. const int writeSize = min(sif0.counter, sif0.fifo.free()); @@ -76,6 +93,7 @@ static __forceinline bool SifIOPWrite(int &psxCycles) return true; } +// Read Fifo into an ee tag, transfer it to sif0dma, and process it. static __forceinline bool SIFEEReadTag() { static __aligned16 u32 tag[4]; @@ -116,14 +134,17 @@ static __forceinline bool SIFEEReadTag() return true; } +// Read Fifo into an ee tag, and transfer it to hw_dma(9). And presumably process it. static __forceinline bool SIFIOPWriteTag() { - // Process DMA tag at HW_DMA9_TADR + // 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.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. hw_dma(9).madr = sif0.data.data & 0xFFFFFF; sif0.counter = sif0.data.words & 0xFFFFFF; @@ -132,19 +153,17 @@ static __forceinline bool SIFIOPWriteTag() return true; } -static __forceinline void SIF0EEend(int &cycles) +// Stop transferring ee, and signal an interrupt. +static __forceinline void SIF0EEend() { - // Stop & signal interrupts on EE - sif0.end = 0; eesifbusy[0] = false; if (cycles == 0) DevCon.Warning("EESIF0cycles = 0"); // No transfer happened else CPU_INT(DMAC_SIF0, cycles*BIAS); // Hence no Interrupt } -static __forceinline void SIF0IOPend(int &psxCycles) +// Stop transferring iop, and signal an interrupt. +static __forceinline void SIF0IOPend() { - // Stop & signal interrupts on IOP - sif0.data.data = 0; iopsifbusy[0] = false; // iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords) @@ -154,7 +173,8 @@ static __forceinline void SIF0IOPend(int &psxCycles) else PSX_INT(IopEvt_SIF0, psxCycles); // Hence no Interrupt } -static __forceinline void SIF0EEDma(int &cycles, bool &done) +// Handle the EE transfer. +static __forceinline void SIF0EEDma() { #ifdef PCSX2_DEVBUILD if (dmacRegs->ctrl.STS == STS_SIF0) @@ -168,7 +188,7 @@ static __forceinline void SIF0EEDma(int &cycles, bool &done) if ((sif0dma->chcr.MOD == NORMAL_MODE) || sif0.end) { done = true; - SIF0EEend(cycles); + SIF0EEend(); } else if (sif0.fifo.size >= 4) // Read a tag { @@ -179,19 +199,20 @@ static __forceinline void SIF0EEDma(int &cycles, bool &done) if (sif0dma->qwc > 0) // If we're reading something continue to do so { - SifEERead(cycles); + SifEERead(); } } +// Handle the IOP transfer. // Note: Test any changes in this function against Grandia III. -static __forceinline void SIF0IOPDma(int &psxCycles, bool &done) +static __forceinline void SIF0IOPDma() { if (sif0.counter <= 0) // If there's no more to transfer { if (sif0_tag.IRQ || (sif0_tag.ID & 4)) { done = true; - SIF0IOPend(psxCycles); + SIF0IOPend(); } else // Chain mode { @@ -201,22 +222,28 @@ static __forceinline void SIF0IOPDma(int &psxCycles, bool &done) } else { - SifIOPWrite(psxCycles); + SifIOPWrite(); } } +static __forceinline void Sif0End() +{ +} + +// Transfer IOP to EE, putting data in the fifo as an intermediate step. __forceinline void SIF0Dma() { - bool done = false; - int cycles = 0, psxCycles = 0; - SIF_LOG("SIF0 DMA start..."); + Sif0Init(); do { - if (iopsifbusy[0]) SIF0IOPDma(psxCycles, done); - if (eesifbusy[0]) SIF0EEDma(cycles, done); + if (iopsifbusy[0]) SIF0IOPDma(); + if (eesifbusy[0]) SIF0EEDma(); } while (!done); + + SIF_LOG("SIF0 DMA end..."); + Sif0End(); } __forceinline void sif0Interrupt() diff --git a/pcsx2/Sif1.cpp b/pcsx2/Sif1.cpp index a41e9f1e11..16db72b46d 100644 --- a/pcsx2/Sif1.cpp +++ b/pcsx2/Sif1.cpp @@ -20,7 +20,23 @@ #include "IopCommon.h" #include "Sif.h" -static __forceinline bool SifEEWrite(int &cycles) +_sif sif1; + +static bool done = false; +static int cycles = 0, psxCycles = 0; + +static __forceinline void Sif1Init() +{ + done = false; + cycles = 0; + psxCycles = 0; + memzero(sif1); + //sif1.end = 0; + //sif1.data.data = 0; +} + +// Write from the EE to Fifo. +static __forceinline bool SifEEWrite() { // There's some data ready to transfer into the fifo.. @@ -50,7 +66,8 @@ static __forceinline bool SifEEWrite(int &cycles) return true; } -static __forceinline bool SifIOPRead(int &psxCycles) +// Read from the fifo and write to IOP +static __forceinline bool SifIOPRead() { // If we're reading something, continue to do so. const int readSize = min (sif1.counter, sif1.fifo.size); @@ -72,6 +89,7 @@ static __forceinline bool SifIOPRead(int &psxCycles) return true; } +// Get a tag and process it. static __forceinline bool SIFEEWriteTag() { // Chain mode @@ -138,6 +156,7 @@ static __forceinline bool SIFEEWriteTag() return true; } +// Write fifo to data, and put it in IOP. static __forceinline bool SIFIOPReadTag() { // Read a tag. @@ -151,10 +170,9 @@ static __forceinline bool SIFIOPReadTag() return true; } -static __forceinline void SIF1EEend(int &cycles) +// Stop processing EE, and signal an interrupt. +static __forceinline void SIF1EEend() { - // Stop & signal interrupts on EE - sif1.end = 0; eesifbusy[1] = false; // Voodoocycles : Okami wants around 100 cycles when booting up @@ -164,10 +182,9 @@ static __forceinline void SIF1EEend(int &cycles) else CPU_INT(DMAC_SIF1, min((int)(cycles*BIAS), 384)); // Hence no Interrupt (fixes Eternal Poison reboot when selecting new game) } -static __forceinline void SIF1IOPend(int &psxCycles) +// Stop processing IOP, and signal an interrupt. +static __forceinline void SIF1IOPend() { - // Stop & signal interrupts on IOP - sif1.data.data = 0; iopsifbusy[1] = false; //Fixme ( voodoocycles ): @@ -178,7 +195,8 @@ static __forceinline void SIF1IOPend(int &psxCycles) else PSX_INT(IopEvt_SIF1, min((psxCycles * 26), 1024)); // Hence no Interrupt } -static __forceinline void SIF1EEDma(int &cycles, bool &done) +// Handle the EE transfer. +static __forceinline void SIF1EEDma() { #ifdef PCSX2_DEVBUILD if (dmacRegs->ctrl.STD == STD_SIF1) @@ -194,7 +212,7 @@ static __forceinline void SIF1EEDma(int &cycles, bool &done) if ((sif1dma->chcr.MOD == NORMAL_MODE) || sif1.end) { done = true; - SIF1EEend(cycles); + SIF1EEend(); } else { @@ -204,15 +222,16 @@ static __forceinline void SIF1EEDma(int &cycles, bool &done) } else { - SifEEWrite(cycles); + SifEEWrite(); } } -static __forceinline void SIF1IOPDma(int &psxCycles, bool &done) +// Handle the IOP transfer. +static __forceinline void SIF1IOPDma() { if (sif1.counter > 0) { - SifIOPRead(psxCycles); + SifIOPRead(); } if (sif1.counter <= 0) @@ -220,7 +239,7 @@ static __forceinline void SIF1IOPDma(int &psxCycles, bool &done) if (sif1_tag.IRQ || (sif1_tag.ID & 4)) { done = true; - SIF1IOPend(psxCycles); + SIF1IOPend(); } else if (sif1.fifo.size >= 4) { @@ -231,17 +250,25 @@ static __forceinline void SIF1IOPDma(int &psxCycles, bool &done) } } +static __forceinline void Sif1End() +{ +} + +// Transfer EE to IOP, putting data in the fifo as an intermediate step. __forceinline void SIF1Dma() { - bool done = false; - int cycles = 0, psxCycles = 0; - + SIF_LOG("SIF1 DMA start..."); + Sif1Init(); + do { - if (eesifbusy[1]) SIF1EEDma(cycles, done); - if (iopsifbusy[1]) SIF1IOPDma(psxCycles, done); + if (eesifbusy[1]) SIF1EEDma(); + if (iopsifbusy[1]) SIF1IOPDma(); } while (!done); + + SIF_LOG("SIF0 DMA end..."); + Sif1End(); } __forceinline void sif1Interrupt() @@ -256,6 +283,8 @@ __forceinline void EEsif1Interrupt() sif1dma->chcr.STR = false; } +// Do almost exactly the same thing as psxDma10 in IopDma.cpp. +// Main difference is this checks for iop, where psxDma10 checks for ee. __forceinline void dmaSIF1() { SIF_LOG(wxString(L"dmaSIF1" + sif1dma->cmqt_to_str()).To8BitData());