diff --git a/pcsx2/Sif.h b/pcsx2/Sif.h index 7154ae0201..3e978f1395 100644 --- a/pcsx2/Sif.h +++ b/pcsx2/Sif.h @@ -80,14 +80,32 @@ struct sifFifo struct _sif { - sifFifo fifo; + sifFifo fifo; // Used in both. s32 chain; // Not used. - s32 end; + s32 end; // Only used for EE. s32 tagMode; // No longer used. - s32 counter; - struct sifData data; + s32 counter; // Used to keep track of how much is left in IOP. + struct sifData data; // Only used in IOP. }; +/*struct _sif +{ + sifFifo fifo; // Used in both. + struct ee + { + bool end; // Only used for EE. + bool busy; + } + struct iop + { + bool end; + bool busy; + + s32 counter; // Used to keep track of how much is left in IOP. + struct sifData data; // Only used in IOP. + } +};*/ + extern bool eesifbusy[2], iopsifbusy[2]; extern void sifInit(); diff --git a/pcsx2/Sif0.cpp b/pcsx2/Sif0.cpp index b3692f1f2c..2ef59fd6b1 100644 --- a/pcsx2/Sif0.cpp +++ b/pcsx2/Sif0.cpp @@ -44,12 +44,12 @@ static __forceinline bool WriteFifoToEE() tDMA_TAG *ptag; //SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr); - SIF_LOG("----------- %lX of %lX", readSize << 2, sif0dma->qwc << 2); + SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma->qwc << 2); ptag = sif0dma->getAddr(sif0dma->madr, DMAC_SIF0); if (ptag == NULL) { - DevCon.Warning("WriteFifoToEE: ptag == NULL"); + DevCon.Warning("Write Fifo to EE: ptag == NULL"); return false; } @@ -64,7 +64,7 @@ static __forceinline bool WriteFifoToEE() //} //else //{ - //DevCon.Warning("WriteFifoToEE: readSize is 0"); + //DevCon.Warning("Write Fifo to EE: readSize is 0"); // return false; //} return true; @@ -78,12 +78,12 @@ static __forceinline bool WriteIOPtoFifo() //if (writeSize <= 0) //{ - //DevCon.Warning("WriteIOPtoFifo: writeSize is 0"); + //DevCon.Warning("Write IOP to Fifo: writeSize is 0"); // return false; //} //else //{ - SIF_LOG("+++++++++++ %lX of %lX", writeSize, sif0.counter); + SIF_LOG("Write IOP to Fifo: +++++++++++ %lX of %lX", writeSize, sif0.counter); sif0.fifo.write((u32*)iopPhysMem(hw_dma(9).madr), writeSize); hw_dma(9).madr += writeSize << 2; @@ -99,13 +99,13 @@ static __forceinline bool ProcessEETag() static __aligned16 u32 tag[4]; sif0.fifo.read((u32*)&tag[0], 4); // Tag - SIF_LOG(" EE SIF read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]); + SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]); sif0dma->unsafeTransfer(((tDMA_TAG*)(tag))); sif0dma->madr = tag[1]; tDMA_TAG ptag(tag[0]); - SIF_LOG(" EE SIF dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", + SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", sif0dma->madr, sif0dma->qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]); if (sif0dma->chcr.TIE && ptag.IRQ) @@ -148,7 +148,7 @@ static __forceinline bool ProcessIOPTag() hw_dma(9).madr = sif0.data.data & 0xFFFFFF; sif0.counter = sif0.data.words & 0xFFFFFF; - SIF_LOG(" SIF0 Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", HW_DMA9_MADR, HW_DMA9_TADR, sif0.counter, sif0.data.words, sif0.data.data); + SIF_LOG("SIF0 IOP Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", HW_DMA9_MADR, HW_DMA9_TADR, sif0.counter, sif0.data.words, sif0.data.data); return true; } @@ -156,20 +156,22 @@ static __forceinline bool ProcessIOPTag() // Stop transferring ee, and signal an interrupt. static __forceinline void EndEE() { + SIF_LOG("Sif0: End EE"); eesifbusy[0] = false; - if (cycles == 0) DevCon.Warning("EESIF0cycles = 0"); // No transfer happened + if (cycles == 0) DevCon.Warning("SIF0 EE: cycles = 0"); // No transfer happened else CPU_INT(DMAC_SIF0, cycles*BIAS); // Hence no Interrupt } // Stop transferring iop, and signal an interrupt. static __forceinline void EndIOP() { + SIF_LOG("Sif0: End IOP"); iopsifbusy[0] = false; // 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); - if (psxCycles == 0) DevCon.Warning("IOPSIF0cycles = 0"); // No transfer happened + if (psxCycles == 0) DevCon.Warning("SIF0 IOP: cycles = 0"); // No transfer happened else PSX_INT(IopEvt_SIF0, psxCycles); // Hence no Interrupt } @@ -195,7 +197,6 @@ static __forceinline void HandleEETransfer() { // Read Fifo into an ee tag, transfer it to sif0dma // and process it. - done = false; ProcessEETag(); } } @@ -209,6 +210,33 @@ static __forceinline void HandleEETransfer() // Handle the IOP transfer. // Note: Test any changes in this function against Grandia III. +// What currently happens is this: +// SIF0 DMA start... +// SIF + 4 = 4 (pos=4) +// SIF0 IOP Tag: madr=19870, tadr=179cc, counter=8 (00000008_80019870) +// SIF - 4 = 0 (pos=4) +// SIF0 EE read tag: 90000002 935c0 0 0 +// SIF0 EE dest chain tag madr:000935C0 qwc:0002 id:1 irq:1(000935C0_90000002) +// Write Fifo to EE: ----------- 0 of 8 +// SIF - 0 = 0 (pos=4) +// Write IOP to Fifo: +++++++++++ 8 of 8 +// SIF + 8 = 8 (pos=12) +// Write Fifo to EE: ----------- 8 of 8 +// SIF - 8 = 0 (pos=12) +// Sif0: End IOP +// Sif0: End EE +// SIF0 DMA end... + +// What happens if (sif0.counter > 0) is handled first is this + +// SIF0 DMA start... +// ... +// SIF + 8 = 8 (pos=12) +// Sif0: End IOP +// Write Fifo to EE: ----------- 8 of 8 +// SIF - 8 = 0 (pos=12) +// SIF0 DMA end... + static __forceinline void HandleIOPTransfer() { if (sif0.counter <= 0) // If there's no more to transfer @@ -223,7 +251,6 @@ static __forceinline void HandleIOPTransfer() { // Read Fifo into an iop tag, and transfer it to hw_dma(9). // And presumably process it. - done = false; ProcessIOPTag(); } } @@ -248,7 +275,7 @@ __forceinline void SIF0Dma() { if (iopsifbusy[0]) HandleIOPTransfer(); if (eesifbusy[0]) HandleEETransfer(); - } while (!done); + } while (!done); // Substituting (iopsifbusy[0] || eesifbusy[0]) breaks things. SIF_LOG("SIF0 DMA end..."); Sif0End(); diff --git a/pcsx2/Sif1.cpp b/pcsx2/Sif1.cpp index 094b874bf6..39373d15bd 100644 --- a/pcsx2/Sif1.cpp +++ b/pcsx2/Sif1.cpp @@ -39,7 +39,8 @@ static __forceinline void Sif1Init() static __forceinline bool WriteEEtoFifo() { // There's some data ready to transfer into the fifo.. - + + SIF_LOG("Sif 1: Write EE to Fifo"); const int writeSize = min((s32)sif1dma->qwc, sif1.fifo.free() >> 2); //if (writeSize <= 0) //{ @@ -53,7 +54,7 @@ static __forceinline bool WriteEEtoFifo() ptag = sif1dma->getAddr(sif1dma->madr, DMAC_SIF1); if (ptag == NULL) { - DevCon.Warning("WriteEEtoFifo: ptag == NULL"); + DevCon.Warning("Write EE to Fifo: ptag == NULL"); return false; } @@ -70,6 +71,8 @@ static __forceinline bool WriteEEtoFifo() 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); //if (readSize <= 0) //{ @@ -78,12 +81,12 @@ static __forceinline bool WriteFifoToIOP() //} //else //{ - SIF_LOG(" IOP SIF doing transfer %04X to %08X", readSize, HW_DMA10_MADR); + SIF_LOG("Sif 1 IOP doing transfer %04X to %08X", readSize, HW_DMA10_MADR); 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 / 16 + psxCycles += readSize >> 2; // fixme: should be >> 4 sif1.counter -= readSize; //} return true; @@ -94,12 +97,13 @@ static __forceinline bool ProcessEETag() { // Chain mode tDMA_TAG *ptag; + SIF_LOG("Sif1: ProcessEETag"); // Process DMA tag at sif1dma->tadr ptag = sif1dma->DMAtransfer(sif1dma->tadr, DMAC_SIF1); if (ptag == NULL) { - Console.WriteLn("ProcessEETag: ptag = NULL"); + Console.WriteLn("Sif1 ProcessEETag: ptag = NULL"); return false; } @@ -161,7 +165,7 @@ static __forceinline bool SIFIOPReadTag() { // Read a tag. sif1.fifo.read((u32*)&sif1.data, 4); - SIF_LOG(" IOP SIF dest chain tag madr:%08X wc:%04X id:%X irq:%d", + SIF_LOG("SIF 1 IOP: dest chain tag madr:%08X wc:%04X id:%X irq:%d", sif1.data.data & 0xffffff, sif1.data.words, DMA_TAG(sif1.data.data).ID, DMA_TAG(sif1.data.data).IRQ); @@ -174,25 +178,43 @@ static __forceinline bool SIFIOPReadTag() static __forceinline void EndEE() { eesifbusy[1] = 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) DevCon.Warning("SIF1 EE: cycles = 0"); // No transfer happened - else CPU_INT(DMAC_SIF1, min((int)(cycles*BIAS), 384)); // Hence no Interrupt (fixes Eternal Poison reboot when selecting new game) + if (cycles == 0) + { + // No transfer happened + DevCon.Warning("SIF1 EE: cycles = 0"); + } + else + { + // Hence no Interrupt (fixes Eternal Poison reboot when selecting new game) + CPU_INT(DMAC_SIF1, min((int)(cycles*BIAS), 384)); + } } // Stop processing IOP, and signal an interrupt. static __forceinline void EndIOP() { iopsifbusy[1] = 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) DevCon.Warning("SIF1 IOP: cycles = 0"); // No transfer happened - else PSX_INT(IopEvt_SIF1, min((psxCycles * 26), 1024)); // Hence no Interrupt + if (psxCycles == 0) + { + // No transfer happened + DevCon.Warning("SIF1 IOP: cycles = 0"); + } + else + { + // Hence no Interrupt + PSX_INT(IopEvt_SIF1, min((psxCycles * 26), 1024)); + } } // Handle the EE transfer. @@ -264,10 +286,9 @@ __forceinline void SIF1Dma() { if (eesifbusy[1]) HandleEETransfer(); if (iopsifbusy[1]) HandleIOPTransfer(); - } while (!done); - SIF_LOG("SIF0 DMA end..."); + SIF_LOG("SIF1 DMA end..."); Sif1End(); }