diff --git a/pcsx2/Dmac.h b/pcsx2/Dmac.h index 9915c057a1..944427241e 100644 --- a/pcsx2/Dmac.h +++ b/pcsx2/Dmac.h @@ -627,6 +627,47 @@ static __forceinline bool inScratchpad(u32 addr) return ((addr >=0x70000000) && (addr <= 0x70003fff)); } +// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits) +static __forceinline tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write) +{ + // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); } + + + //Probably dont need these. + if (DMA_TAG(addr).SPR) return (tDMA_TAG*)&psS[addr & 0x3ff0]; + + // Need to check the physical address as well as just the "SPR" flag, as VTLB doesn't seem to handle it.--refraction + if (inScratchpad(addr)) + { + //Console.Warning("Writing to the scratchpad without the SPR flag set!"); + return (tDMA_TAG*)&psS[addr & 0x3ff0]; + } + + // FIXME: Why??? DMA uses physical addresses + + + if ((addr & 0x7ffffff0) >= 0x20000000) + { + Console.Error( "*PCSX2*: DMA error: %8.8x", addr); + return NULL; + } + + addr &= 0x1ffffff0; + + if (addr >= 0x11004000 && addr < 0x11010000) + { + //Access for VU Memory + return (tDMA_TAG*)vtlb_GetPhyPtr(addr & 0x1FFFFFF0); + } + + if (addr > Ps2MemSize::Base) + { + return (tDMA_TAG*)(write ? psMHW : psMHR); + } + + return (tDMA_TAG*)&psM[addr]; +} + // Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits) static __forceinline tDMA_TAG *dmaGetAddr(u32 addr, bool write) { @@ -642,14 +683,16 @@ static __forceinline tDMA_TAG *dmaGetAddr(u32 addr, bool write) } // FIXME: Why??? DMA uses physical addresses - addr &= 0x3ffffff0; - - if (addr >= 0x20000000) + + + if ((addr & 0x7ffffff0) >= 0x20000000) { Console.Error( "*PCSX2*: DMA error: %8.8x", addr); return NULL; } + addr &= 0x1ffffff0; + if (addr > Ps2MemSize::Base) { return (tDMA_TAG*)(write ? psMHW : psMHR); diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index d54feeaf58..2d8ea0bca4 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -75,10 +75,6 @@ __forceinline void gsInterrupt() return; } - // Champions: Return to Arms prints this a lot. - if((gif->chcr.MOD == CHAIN_MODE) && ((gif->chcr.TAG >> 12) & 0x7) != 0x0 && ((gif->chcr.TAG >> 12) & 0x7) != 0x7 && !((gif->chcr.TAG >> 12) & 0x8)) - DevCon.Warning("GIF Ending when refe or end not set! CHCR = %x", gif->chcr._u32); - gspath3done = false; gscycles = 0; gif->chcr.STR = false; @@ -358,6 +354,7 @@ void dmaGIF() //Halflife sets a QWC amount in chain mode, no tadr set. if (gif->qwc > 0) gspath3done = true; + if(gif->chcr.MOD == CHAIN_MODE && gif->qwc > 0) DevCon.Warning("GIF QWC on Chain CHCR = %x", gif->chcr); GIFdma(); } diff --git a/pcsx2/SPR.cpp b/pcsx2/SPR.cpp index 781ebe1ab5..4d7ebda3be 100644 --- a/pcsx2/SPR.cpp +++ b/pcsx2/SPR.cpp @@ -52,7 +52,7 @@ int _SPR0chain() tDMA_TAG *pMem; if (spr0->qwc == 0) return 0; - pMem = dmaGetAddr(spr0->madr, true); + pMem = SPRdmaGetAddr(spr0->madr, true); if (pMem == NULL) return -1; switch (dmacRegs->ctrl.MFD) @@ -106,7 +106,7 @@ void _SPR0interleave() { spr0->qwc = std::min(tqwc, qwc); qwc -= spr0->qwc; - pMem = dmaGetAddr(spr0->madr, true); + pMem = SPRdmaGetAddr(spr0->madr, true); switch (dmacRegs->ctrl.MFD) { @@ -252,9 +252,7 @@ void SPRFROMinterrupt() } if (!spr0finished) return; - if((spr0->chcr.MOD == CHAIN_MODE) && ((spr0->chcr.TAG >> 12) & 0x7) != 0x0 && ((spr0->chcr.TAG >> 12) & 0x7) != 0x7 && !((spr0->chcr.TAG >> 12) & 0x8)) - DevCon.Warning("SPR0 Ending when refe or end not set! CHCR = %x", spr0->chcr._u32); - + spr0->chcr.STR = false; hwDmacIrq(DMAC_FROM_SPR); } @@ -271,6 +269,7 @@ void dmaSPR0() // fromSPR CPU_INT(DMAC_FROM_SPR, /*ptag[0].QWC / BIAS*/ 4 ); return; } + if(spr0->chcr.MOD == CHAIN_MODE && spr0->qwc > 0) DevCon.Warning("SPR0 QWC on Chain CHCR = %x", spr0->chcr); // COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values // It merely assumes that the last one has finished then starts another one (broke with the DMA fix) // This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction) @@ -290,7 +289,7 @@ int _SPR1chain() if (spr1->qwc == 0) return 0; - pMem = dmaGetAddr(spr1->madr, false); + pMem = SPRdmaGetAddr(spr1->madr, false); if (pMem == NULL) return -1; SPR1transfer((u32*)pMem, spr1->qwc << 2); @@ -320,7 +319,7 @@ void _SPR1interleave() { spr1->qwc = std::min(tqwc, qwc); qwc -= spr1->qwc; - pMem = dmaGetAddr(spr1->madr, false); + pMem = SPRdmaGetAddr(spr1->madr, false); memcpy_fast(&psSu8(spr1->sadr), (u8*)pMem, spr1->qwc << 4); spr1->sadr += spr1->qwc * 16; spr1->madr += (sqwc + spr1->qwc) * 16; @@ -356,7 +355,7 @@ void _dmaSPR1() // toSPR work function } // Chain Mode - ptag = dmaGetAddr(spr1->tadr, false); //Set memory pointer to TADR + ptag = SPRdmaGetAddr(spr1->tadr, false); //Set memory pointer to TADR if (!spr1->transfer("SPR1 Tag", ptag)) { @@ -390,7 +389,7 @@ void _dmaSPR1() // toSPR work function spr1finished = done; if (!done) { - ptag = dmaGetAddr(spr1->tadr, false); //Set memory pointer to TADR + ptag = SPRdmaGetAddr(spr1->tadr, false); //Set memory pointer to TADR CPU_INT(DMAC_TO_SPR, /*(ptag[0].QWC / BIAS)*/ 4 );// the lower 16 bits of the tag / BIAS); } break; @@ -414,10 +413,11 @@ void dmaSPR1() // toSPR if ((spr1->chcr.MOD == CHAIN_MODE) && (spr1->qwc == 0)) { tDMA_TAG *ptag; - ptag = dmaGetAddr(spr1->tadr, false); //Set memory pointer to TADR + ptag = SPRdmaGetAddr(spr1->tadr, false); //Set memory pointer to TADR CPU_INT(DMAC_TO_SPR, /*ptag[0].QWC / BIAS*/ 4 ); return; } + if(spr1->chcr.MOD == CHAIN_MODE && spr1->qwc > 0) DevCon.Warning("SPR1 QWC on Chain CHCR = %x", spr1->chcr); // COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values // It merely assumes that the last one has finished then starts another one (broke with the DMA fix) // This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction) @@ -429,9 +429,6 @@ void SPRTOinterrupt() _dmaSPR1(); if (!spr1finished) return; - if((spr1->chcr.MOD == CHAIN_MODE) && ((spr1->chcr.TAG >> 12) & 0x7) != 0x0 && ((spr1->chcr.TAG >> 12) & 0x7) != 0x7 && !((spr1->chcr.TAG >> 12) & 0x8)) - DevCon.Warning("SPR1 Ending when refe or end not set! CHCR = %x", spr1->chcr._u32); - spr1->chcr.STR = false; hwDmacIrq(DMAC_TO_SPR); } diff --git a/pcsx2/Sif0.cpp b/pcsx2/Sif0.cpp index 26468688c6..c5abe2fddd 100644 --- a/pcsx2/Sif0.cpp +++ b/pcsx2/Sif0.cpp @@ -151,9 +151,7 @@ static __forceinline void EndEE() SIF_LOG("SIF0 EE: cycles = 0"); sif0.ee.cycles = 1; } - if((sif0dma->chcr.MOD == CHAIN_MODE) && ((sif0dma->chcr.TAG >> 12) & 0x7) != 0x0 && ((sif0dma->chcr.TAG >> 12) & 0x7) != 0x7 && !((sif0dma->chcr.TAG >> 12) & 0x8)) - DevCon.Warning("SIF0 Ending when refe or end not set! CHCR = %x", sif0dma->chcr._u32); - + CPU_INT(DMAC_SIF0, sif0.ee.cycles*BIAS); } @@ -314,6 +312,7 @@ __forceinline void dmaSIF0() SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos"); } + if(sif0dma->chcr.MOD == CHAIN_MODE && sif0dma->qwc > 0) DevCon.Warning("SIF0 QWC on Chain CHCR = %x", sif0dma->chcr); psHu32(SBUS_F240) |= 0x2000; sif0.ee.busy = true; diff --git a/pcsx2/Sif1.cpp b/pcsx2/Sif1.cpp index 25fc1b9e55..5418121319 100644 --- a/pcsx2/Sif1.cpp +++ b/pcsx2/Sif1.cpp @@ -175,9 +175,7 @@ static __forceinline void EndEE() sif1.ee.cycles = 1; } - if((sif1dma->chcr.MOD == CHAIN_MODE) && ((sif1dma->chcr.TAG >> 12) & 0x7) != 0x0 && ((sif1dma->chcr.TAG >> 12) & 0x7) != 0x7 && !((sif1dma->chcr.TAG >> 12) & 0x8)) - DevCon.Warning("SIF0 Ending when refe or end not set! CHCR = %x", sif1dma->chcr._u32); - + CPU_INT(DMAC_SIF1, min((int)(sif1.ee.cycles*BIAS), 384)); } @@ -311,6 +309,8 @@ __forceinline void dmaSIF1() SIF_LOG("warning, sif1.fifoReadPos != sif1.fifoWritePos"); } + if(sif1dma->chcr.MOD == CHAIN_MODE && sif1dma->qwc > 0) DevCon.Warning("SIF1 QWC on Chain CHCR = %x", sif1dma->chcr); + psHu32(SBUS_F240) |= 0x4000; sif1.ee.busy = true; diff --git a/pcsx2/Vif0_Dma.cpp b/pcsx2/Vif0_Dma.cpp index 4f5671896f..180703a957 100644 --- a/pcsx2/Vif0_Dma.cpp +++ b/pcsx2/Vif0_Dma.cpp @@ -182,9 +182,6 @@ __forceinline void vif0Interrupt() if (vif0.cmd != 0) Console.WriteLn("vif0.cmd still set %x tag size %x", vif0.cmd, vif0.tag.size); #endif - /*if(vif0.dmamode == VIF_CHAIN_MODE && ((vif0ch->chcr.TAG >> 12) & 0x7) != 0x0 && ((vif0ch->chcr.TAG >> 12) & 0x7) != 0x7 && !((vif0ch->chcr.TAG >> 12) & 0x8)) - DevCon.Warning("VIF0 Ending when refe or end not set! CHCR = %x", vif0ch->chcr._u32);*/ - vif0Regs->stat.VPS = VPS_IDLE; //Vif goes idle as the stall happened between commands; vif0ch->chcr.STR = false; g_vifCycles = 0; @@ -205,6 +202,7 @@ void dmaVIF0() if ((vif0ch->chcr.MOD == NORMAL_MODE) || vif0ch->qwc > 0) // Normal Mode { vif0.dmamode = VIF_NORMAL_TO_MEM_MODE; + if(vif0ch->chcr.MOD == CHAIN_MODE && vif0ch->qwc > 0) DevCon.Warning("VIF0 QWC on Chain CHCR = %x", vif0ch->chcr); } else { diff --git a/pcsx2/Vif1_Dma.cpp b/pcsx2/Vif1_Dma.cpp index 03f0aa7120..4131dabe3b 100644 --- a/pcsx2/Vif1_Dma.cpp +++ b/pcsx2/Vif1_Dma.cpp @@ -302,13 +302,6 @@ __forceinline void vif1Interrupt() g_vifCycles = 0; hwDmacIrq(DMAC_VIF1); - /*if(vif1.dmamode == VIF_CHAIN_MODE && ((vif1ch->chcr.TAG >> 12) & 0x7) != 0x0 && ((vif1ch->chcr.TAG >> 12) & 0x7) != 0x7 && !((vif1ch->chcr.TAG >> 12) & 0x8)) - DevCon.Warning("VIF1 Ending when refe or end not set! CHCR = %x", vif1ch->chcr._u32);*/ - //Im not totally sure why Path3 Masking makes it want to see stuff in the fifo - //Games effected by setting, Fatal Frame, KH2, Shox, Crash N Burn, GT3/4 possibly - //Im guessing due to the full gs fifo before the reverse? (Refraction) - //Note also this is only the condition for reverse fifo mode, normal direction clears it as normal - //if (!vif1Regs->mskpath3 || vif1ch->chcr.DIR) vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16); } void dmaVIF1() @@ -339,6 +332,8 @@ void dmaVIF1() vif1.dmamode = VIF_NORMAL_FROM_MEM_MODE; else vif1.dmamode = VIF_NORMAL_TO_MEM_MODE; + + if(vif1ch->chcr.MOD == CHAIN_MODE && vif1ch->qwc > 0) DevCon.Warning("VIF1 QWC on Chain CHCR = %x", vif1ch->chcr); } else { diff --git a/pcsx2/Vif1_MFIFO.cpp b/pcsx2/Vif1_MFIFO.cpp index 56cbebbac9..1a9e7adef4 100644 --- a/pcsx2/Vif1_MFIFO.cpp +++ b/pcsx2/Vif1_MFIFO.cpp @@ -297,9 +297,6 @@ void vifMFIFOInterrupt() hwDmacIrq(DMAC_MFIFO_EMPTY); }*/ - if(((vif1ch->chcr.TAG >> 12) & 0x7) != 0x0 && ((vif1ch->chcr.TAG >> 12) & 0x7) != 0x7) - DevCon.Warning("VIF1 MFIFO Ending when refe or end not set! CHCR = %x", vif1ch->chcr._u32); - vif1.done = 1; g_vifCycles = 0; vif1ch->chcr.STR = false;