diff --git a/common/include/Pcsx2Types.h b/common/include/Pcsx2Types.h index 11c316ac51..d1a42bd190 100644 --- a/common/include/Pcsx2Types.h +++ b/common/include/Pcsx2Types.h @@ -161,7 +161,7 @@ union u128 bool operator!=( const u128& right ) const { - return (lo != right.lo) && (hi != right.hi); + return (lo != right.lo) || (hi != right.hi); } // In order for the following ToString() and WriteTo methods to be available, you must @@ -206,7 +206,7 @@ struct s128 bool operator!=( const s128& right ) const { - return (lo != right.lo) && (hi != right.hi); + return (lo != right.lo) || (hi != right.hi); } }; diff --git a/pcsx2/Dmac.h b/pcsx2/Dmac.h index b68737b79d..d22145677f 100644 --- a/pcsx2/Dmac.h +++ b/pcsx2/Dmac.h @@ -92,6 +92,8 @@ union tDMA_TAG { }; u32 _u32; + tDMA_TAG() {} + tDMA_TAG(u32 val) { _u32 = val; } u16 upper() const { return (_u32 >> 16); } u16 lower() const { return (u16)_u32; } diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index 5e19cd9124..d39c1d242b 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -206,7 +206,7 @@ __fi u32 ipuRead32(u32 mem) if (!ipuRegs.ctrl.BUSY) IPU_LOG("read32: IPU_CTRL=0x%08X", ipuRegs.ctrl._u32); - return ipuRegs.ctrl._u32; + return ipuRegs.ctrl._u32; } ipucase(IPU_BP): // IPU_BP @@ -218,7 +218,7 @@ __fi u32 ipuRead32(u32 mem) ipuRegs.ipubp |= g_BP.FP << 16; IPU_LOG("read32: IPU_BP=0x%08X", ipuRegs.ipubp); - return ipuRegs.ipubp; + return ipuRegs.ipubp; } default: @@ -448,6 +448,14 @@ static bool __fastcall ipuVDEC(u32 val) jNO_DEFAULT } + // HACK ATTACK! This code OR's the MPEG decoder's bitstream position into the upper + // 16 bits of DATA; which really doesn't make sense since (a) we already rewound the bits + // back into the IPU internal buffer above, and (b) the IPU doesn't have an MPEG internal + // 32-bit decoder buffer of its own anyway. Furthermore, setting the upper 16 bits to + // any value other than zero appears to work fine. When set to zero, however, FMVs run + // very choppy (basically only decoding/updating every 30th frame or so). So yeah, + // someone with knowledge on the subject please feel free to explain this one. :) --air + ipuRegs.cmd.DATA &= 0xFFFF; ipuRegs.cmd.DATA |= 0x10000; @@ -466,6 +474,7 @@ static bool __fastcall ipuVDEC(u32 val) IPU_LOG("VDEC command data 0x%x(0x%x). Skip 0x%X bits/Table=%d (%s), pct %d", ipuRegs.cmd.DATA, ipuRegs.cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ? ((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs.ctrl.PCT); + return true; jNO_DEFAULT @@ -488,8 +497,6 @@ static __fi bool ipuFDEC(u32 val) static bool ipuSETIQ(u32 val) { - int i; - if ((val >> 27) & 1) { u8 (&niq)[64] = decoder.niq; @@ -500,7 +507,7 @@ static bool ipuSETIQ(u32 val) } IPU_LOG("Read non-intra quantization matrix from FIFO."); - for (i = 0; i < 8; i++) + for (uint i = 0; i < 8; i++) { IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X", niq[i * 8 + 0], niq[i * 8 + 1], niq[i * 8 + 2], niq[i * 8 + 3], @@ -517,7 +524,7 @@ static bool ipuSETIQ(u32 val) } IPU_LOG("Read intra quantization matrix from FIFO."); - for (i = 0; i < 8; i++) + for (uint i = 0; i < 8; i++) { IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X", iq[i * 8 + 0], iq[i * 8 + 1], iq[i * 8 + 2], iq[i *8 + 3], @@ -539,7 +546,7 @@ static bool ipuSETVQ(u32 val) "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n" "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n" "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n" - "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d", + "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d", vqclut[0] >> 10, (vqclut[0] >> 5) & 0x1F, vqclut[0] & 0x1F, vqclut[1] >> 10, (vqclut[1] >> 5) & 0x1F, vqclut[1] & 0x1F, vqclut[2] >> 10, (vqclut[2] >> 5) & 0x1F, vqclut[2] & 0x1F, diff --git a/pcsx2/IopDma.cpp b/pcsx2/IopDma.cpp index 0225d886be..5df826c1d3 100644 --- a/pcsx2/IopDma.cpp +++ b/pcsx2/IopDma.cpp @@ -195,14 +195,8 @@ 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); sif0.iop.busy = true; - psHu32(SBUS_F240) |= 0x2000; - /*if (sif0.ee.busy) - {*/ - SIF0Dma(); - psHu32(SBUS_F240) &= ~0x20; - psHu32(SBUS_F240) &= ~0x2000; - //} + SIF0Dma(); } void psxDma10(u32 madr, u32 bcr, u32 chcr) @@ -210,15 +204,8 @@ void psxDma10(u32 madr, u32 bcr, u32 chcr) SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx", chcr, madr, bcr); sif1.iop.busy = true; - psHu32(SBUS_F240) |= 0x4000; - /*if (sif1.ee.busy) - {*/ - SIF1Dma(); - psHu32(SBUS_F240) &= ~0x40; - psHu32(SBUS_F240) &= ~0x100; - psHu32(SBUS_F240) &= ~0x4000; - //} + SIF1Dma(); } /* psxDma11 & psxDma 12 are in IopSio2.cpp, along with the appropriate interrupt functions. */ diff --git a/pcsx2/Sif.h b/pcsx2/Sif.h index 9d276a4a78..cfed819387 100644 --- a/pcsx2/Sif.h +++ b/pcsx2/Sif.h @@ -22,13 +22,17 @@ static DMACh& sif0dma = (DMACh&)eeHw[0xc000]; static DMACh& sif1dma = (DMACh&)eeHw[0xc400]; static DMACh& sif2dma = (DMACh&)eeHw[0xc800]; - +// Despite its name, this is actually the IOP's DMAtag, which itself also contains +// the EE's DMAtag in its upper 64 bits. Note that only the lower 24 bits of 'data' is +// the IOP's chain transfer address (loaded into MADR). Bits 30 and 31 are transfer stop +// bits of some sort. struct sifData { s32 data; s32 words; - s32 count; // I think this is unused. - s32 addr; // This too. + + tDMA_TAG tag_lo; // EE DMA tag + tDMA_TAG tag_hi; // EE DMA tag }; struct sifFifo @@ -100,6 +104,7 @@ struct sif_ee s32 cycles; }; + struct sif_iop { bool end; @@ -110,6 +115,7 @@ struct sif_iop 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. diff --git a/pcsx2/Sif0.cpp b/pcsx2/Sif0.cpp index 29ecc0ea90..d3d865cb20 100644 --- a/pcsx2/Sif0.cpp +++ b/pcsx2/Sif0.cpp @@ -69,8 +69,8 @@ static __fi bool WriteIOPtoFifo() 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; + sif0.fifo.write((u32*)iopPhysMem(hw_dma9.madr), writeSize); + hw_dma9.madr += writeSize << 2; // iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords). sif0.iop.cycles += (writeSize >> 2)/* * BIAS*/; // fixme : should be >> 4 @@ -83,13 +83,13 @@ static __fi bool WriteIOPtoFifo() static __fi bool ProcessEETag() { static __aligned16 u32 tag[4]; + tDMA_TAG& ptag(*(tDMA_TAG*)tag); sif0.fifo.read((u32*)&tag[0], 4); // Tag SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]); - sif0dma.unsafeTransfer(((tDMA_TAG*)(tag))); + sif0dma.unsafeTransfer(&ptag); sif0dma.madr = tag[1]; - tDMA_TAG ptag(tag[0]); 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]); @@ -102,16 +102,12 @@ static __fi bool ProcessEETag() switch (ptag.ID) { - case TAG_REFE: - sif0.ee.end = true; - if (dmacRegs.ctrl.STS != NO_STS) - dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16); - break; + case TAG_CNT: break; - case TAG_REFS: + case TAG_CNTS: if (dmacRegs.ctrl.STS != NO_STS) dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16); - break; + break; case TAG_END: sif0.ee.end = true; @@ -120,22 +116,29 @@ static __fi bool ProcessEETag() return true; } -// Read Fifo into an iop tag, and transfer it to hw_dma(9). And presumably process it. +// Read Fifo into an iop tag, and transfer it to hw_dma9. And presumably process it. static __fi bool ProcessIOPTag() { - // Process DMA tag at hw_dma(9).tadr - sif0.iop.data = *(sifData *)iopPhysMem(hw_dma(9).tadr); + // Process DMA tag at hw_dma9.tadr + sif0.iop.data = *(sifData *)iopPhysMem(hw_dma9.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; + // send the EE's side of the DMAtag. The tag is only 64 bits, with the upper 64 bits + // ignored by the EE. - // We're only copying the first 24 bits. - hw_dma(9).madr = sif0data & 0xFFFFFF; + sif0.fifo.write((u32*)iopPhysMem(hw_dma9.tadr + 8), 2); + sif0.fifo.writePos = (sif0.fifo.writePos + 2) & (FIFO_SIF_W - 1); // iggy on the upper 64. + sif0.fifo.size += 2; + + hw_dma9.tadr += 16; ///hw_dma9.madr + 16 + sif0.sifData.words << 2; + + // We're only copying the first 24 bits. Bits 30 and 31 (checked below) are Stop/IRQ bits. + hw_dma9.madr = sif0data & 0xFFFFFF; sif0.iop.counter = sif0words; + // IOP tags have an IRQ bit and an End of Transfer bit: 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); + SIF_LOG("SIF0 IOP Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", hw_dma9.madr, hw_dma9.tadr, sif0.iop.counter, sif0words, sif0data); return true; } @@ -265,7 +268,7 @@ static __fi void HandleIOPTransfer() } else { - // Read Fifo into an iop tag, and transfer it to hw_dma(9). + // Read Fifo into an iop tag, and transfer it to hw_dma9. // And presumably process it. ProcessIOPTag(); } @@ -282,6 +285,9 @@ static __fi void HandleIOPTransfer() static __fi void Sif0End() { + psHu32(SBUS_F240) &= ~0x20; + psHu32(SBUS_F240) &= ~0x2000; + SIF_LOG("SIF0 DMA end..."); } @@ -351,8 +357,5 @@ __fi void dmaSIF0() { //hwIntcIrq(INTC_SBUS); // not sure, so let's not SIF0Dma(); - // Do we really want to mess with the SIF flags like that? Nah. - //psHu32(SBUS_F240) &= ~0x20; - //psHu32(SBUS_F240) &= ~0x2000; } } diff --git a/pcsx2/Sif1.cpp b/pcsx2/Sif1.cpp index 58bb072af0..67fb0148e5 100644 --- a/pcsx2/Sif1.cpp +++ b/pcsx2/Sif1.cpp @@ -68,9 +68,9 @@ static __fi bool WriteFifoToIOP() 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; + sif1.fifo.read((u32*)iopPhysMem(hw_dma10.madr), readSize); + psxCpu->Clear(hw_dma10.madr, readSize); + hw_dma10.madr += readSize << 2; sif1.iop.cycles += readSize >> 2; // fixme: should be >> 4 sif1.iop.counter -= readSize; @@ -151,7 +151,7 @@ static __fi bool SIFIOPReadTag() sif1data & 0xffffff, sif1words, sif1tag.ID, sif1tag.IRQ); // Only use the first 24 bits. - hw_dma(10).madr = sif1data & 0xffffff; + hw_dma10.madr = sif1data & 0xffffff; sif1.iop.counter = sif1words; if (sif1tag.IRQ || (sif1tag.ID & 4)) sif1.iop.end = true; @@ -276,6 +276,9 @@ static __fi void HandleIOPTransfer() static __fi void Sif1End() { + psHu32(SBUS_F240) &= ~0x40; + psHu32(SBUS_F240) &= ~0x4000; + SIF_LOG("SIF1 DMA end..."); } @@ -349,9 +352,5 @@ __fi void dmaSIF1() if (sif1.iop.busy) { SIF1Dma(); - // Do we really want to mess with the SIF flags like that? Nah. - //psHu32(SBUS_F240) &= ~0x40; - //psHu32(SBUS_F240) &= ~0x100; - //psHu32(SBUS_F240) &= ~0x4000; } } diff --git a/pcsx2/windows/VCprojects/IopSif.cpp b/pcsx2/windows/VCprojects/IopSif.cpp index 5085bd4cbe..7e693f3d87 100644 --- a/pcsx2/windows/VCprojects/IopSif.cpp +++ b/pcsx2/windows/VCprojects/IopSif.cpp @@ -17,20 +17,20 @@ s32 PrepareEERead() { static __aligned16 u32 tag[4]; - // Process DMA tag at hw_dma(9).tadr - sif0.iop.data = *(sifData *)iopPhysMem(hw_dma(9).tadr); + // Process DMA tag at hw_dma9.tadr + sif0.iop.data = *(sifData *)iopPhysMem(hw_dma9.tadr); sif0.iop.data.words = (sif0.iop.data.words + 3) & 0xfffffffc; // Round up to nearest 4. - memcpy(tag, (u32*)iopPhysMem(hw_dma(9).tadr + 8), 16); + memcpy(tag, (u32*)iopPhysMem(hw_dma9.tadr + 8), 16); - hw_dma(9).tadr += 16; ///hw_dma(9).madr + 16 + sif0.sifData.words << 2; + hw_dma9.tadr += 16; ///hw_dma9.madr + 16 + sif0.sifData.words << 2; // We're only copying the first 24 bits. - hw_dma(9).madr = sif0data & 0xFFFFFF; + hw_dma9.madr = sif0data & 0xFFFFFF; sif0.iop.counter = sif0words; if (sif0tag.IRQ || (sif0tag.ID & 4)) sif0.iop.end = true; SIF_LOG("SIF0 IOP to EE Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)" - "\n\tread tag: %x %x %x %x", hw_dma(9).madr, hw_dma(9).tadr, sif0.iop.counter, sif0words, sif0data, + "\n\tread tag: %x %x %x %x", hw_dma9.madr, hw_dma9.tadr, sif0.iop.counter, sif0words, sif0data, tag[0], tag[1], tag[2], tag[3]); sif0dma.unsafeTransfer(((tDMA_TAG*)(tag))); @@ -98,7 +98,7 @@ s32 DoSifRead(u32 iopAvailable) return false; } - memcpy((u32*)ptag, (u32*)iopPhysMem(hw_dma(9).madr), transferSizeBytes); + memcpy((u32*)ptag, (u32*)iopPhysMem(hw_dma9.madr), transferSizeBytes); // Clearing handled by vtlb memory protection and manual blocks. //Cpu->Clear(sif0dma.madr, readSize*4);