mirror of https://github.com/PCSX2/pcsx2.git
Improved my previous fix, Psychonaughts exhibited behaviour sudo mentioned (data not being grabbed from VU) so added a seperate SPR handler.
Removed an old check which is useless now and added a new replacement one. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2890 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
e99837abaf
commit
662d589217
49
pcsx2/Dmac.h
49
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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue