mirror of https://github.com/PCSX2/pcsx2.git
GIF:
-Implemented GIF_MODE Masking fixed the All Star Pro Wrestling series slowness/hanging. DMA: -Standardize the IPU and SIF dma's to use the standard chain handling in hw.c, fixed up some DMA resuming stuff in the forementioned units, VIF, GIF and SPR. -Added some warnings for DMA stall control which isn't implemented, hopefully somebody will find a game that does it so we can add/test it :) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5915 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
e24f3585d4
commit
35b5e6a923
|
@ -547,6 +547,11 @@ static DMACh& vif1ch = (DMACh&)eeHw[0x9000];
|
|||
static DMACh& gifch = (DMACh&)eeHw[0xA000];
|
||||
static DMACh& spr0ch = (DMACh&)eeHw[0xD000];
|
||||
static DMACh& spr1ch = (DMACh&)eeHw[0xD400];
|
||||
static DMACh& ipu0ch = (DMACh&)eeHw[0xb000];
|
||||
static DMACh& ipu1ch = (DMACh&)eeHw[0xb400];
|
||||
static DMACh& sif0ch = (DMACh&)eeHw[0xc000];
|
||||
static DMACh& sif1ch = (DMACh&)eeHw[0xc400];
|
||||
static DMACh& sif2dma = (DMACh&)eeHw[0xc800];
|
||||
|
||||
extern void throwBusError(const char *s);
|
||||
extern void setDmacStat(u32 num);
|
||||
|
|
|
@ -229,7 +229,7 @@ void GIFdma()
|
|||
if (dmacRegs.ctrl.STD == STD_GIF)
|
||||
{
|
||||
// there are still bugs, need to also check if gifch.madr +16*qwc >= stadr, if not, stall
|
||||
if (!gspath3done && ((gifch.madr + (gifch.qwc * 16)) > dmacRegs.stadr.ADDR) && (ptag->ID == TAG_REFS))
|
||||
if ((ptag->ID == TAG_REFS) && ((gifch.madr + (gifch.qwc * 16)) > dmacRegs.stadr.ADDR))
|
||||
{
|
||||
// stalled.
|
||||
// We really need to test this. Pay attention to prevcycles, as it used to trigger GIFchains in the code above. (rama)
|
||||
|
@ -246,6 +246,10 @@ void GIFdma()
|
|||
|
||||
checkTieBit(ptag);
|
||||
}
|
||||
else if (dmacRegs.ctrl.STD == STD_GIF && gifch.chcr.MOD == NORMAL_MODE)
|
||||
{
|
||||
Console.WriteLn("GIF DMA Stall in Normal mode not implemented - Report which game to PCSX2 Team");
|
||||
}
|
||||
|
||||
clearFIFOstuff(true);
|
||||
gifRegs.stat.FQC = min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
|
||||
|
@ -296,7 +300,7 @@ void dmaGIF()
|
|||
|
||||
if(gifch.chcr.MOD == CHAIN_MODE && gifch.qwc > 0) {
|
||||
//DevCon.Warning(L"GIF QWC on Chain " + gifch.chcr.desc());
|
||||
if ((gifch.chcr.tag().ID == TAG_REFE) || (gifch.chcr.tag().ID == TAG_END)) {
|
||||
if ((gifch.chcr.tag().ID == TAG_REFE) || (gifch.chcr.tag().ID == TAG_END) || (gifch.chcr.tag().IRQ && gifch.chcr.TIE)) {
|
||||
gspath3done = true;
|
||||
}
|
||||
}
|
||||
|
@ -456,7 +460,10 @@ void mfifoGIFtransfer(int qwc)
|
|||
ptag[1]._u32, ptag[0]._u32, gifch.qwc, ptag->ID, gifch.madr, gifch.tadr, gifqwc, spr0ch.madr);
|
||||
|
||||
gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID);
|
||||
|
||||
if (dmacRegs.ctrl.STD == STD_GIF && (ptag->ID == TAG_REFS))
|
||||
{
|
||||
Console.WriteLn("GIF MFIFO DMA Stall not implemented - Report which game to PCSX2 Team");
|
||||
}
|
||||
mfifoGifMaskMem(ptag->ID);
|
||||
|
||||
if(gspath3done == true) gifstate = GIF_STATE_DONE;
|
||||
|
|
|
@ -308,11 +308,15 @@ if this doesnt happen, which was the reasoning for the hacked up SPR timing we h
|
|||
-Refraction
|
||||
******************************/
|
||||
|
||||
void hwDmacSrcTadrInc(DMACh& dma)
|
||||
inline void hwDmacSrcTadrInc(DMACh& dma)
|
||||
{
|
||||
//Don't touch it if in normal/interleave mode.
|
||||
if (dma.chcr.STR == 0) return;
|
||||
if (dma.chcr.MOD != 1) return;
|
||||
|
||||
u16 tagid = (dma.chcr.TAG >> 12) & 0x7;
|
||||
|
||||
if(tagid == TAG_CNT)
|
||||
if (tagid == TAG_CNT)
|
||||
{
|
||||
dma.tadr = dma.madr;
|
||||
}
|
||||
|
|
|
@ -102,8 +102,16 @@ void __fastcall _hwWrite32( u32 mem, u32 value )
|
|||
|
||||
icase(GIF_MODE)
|
||||
{
|
||||
// need to set GIF_MODE (hamster ball)
|
||||
gifRegs.mode.write(value);
|
||||
|
||||
//Need to kickstart the GIF if the M3R mask comes off
|
||||
if (gifRegs.stat.M3R == 1 && gifRegs.mode.M3R == 0 && gifch.chcr.STR)
|
||||
{
|
||||
DevCon.Warning("GIF Mode cancelling P3 Disable");
|
||||
CPU_INT(DMAC_GIF, 8);
|
||||
}
|
||||
|
||||
|
||||
gifRegs.stat.M3R = gifRegs.mode.M3R;
|
||||
gifRegs.stat.IMT = gifRegs.mode.IMT;
|
||||
return;
|
||||
|
|
|
@ -61,7 +61,7 @@ void tIPU_cmd::clear()
|
|||
|
||||
__fi void IPUProcessInterrupt()
|
||||
{
|
||||
if (ipuRegs.ctrl.BUSY) // && (g_BP.FP || g_BP.IFC || (ipu1dma.chcr.STR && ipu1dma.qwc > 0)))
|
||||
if (ipuRegs.ctrl.BUSY) // && (g_BP.FP || g_BP.IFC || (ipu1ch.chcr.STR && ipu1ch.qwc > 0)))
|
||||
IPUWorker();
|
||||
}
|
||||
|
||||
|
@ -873,7 +873,7 @@ __fi void IPUCMD_WRITE(u32 val)
|
|||
|
||||
case SCE_IPU_FDEC:
|
||||
IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, CHCR 0x%x",
|
||||
val & 0x3f, g_BP.IFC, g_BP.BP, ipu1dma.chcr._u32);
|
||||
val & 0x3f, g_BP.IFC, g_BP.BP, ipu1ch.chcr._u32);
|
||||
|
||||
g_BP.Advance(val & 0x3F);
|
||||
ipuRegs.SetDataBusy();
|
||||
|
@ -898,7 +898,7 @@ __fi void IPUCMD_WRITE(u32 val)
|
|||
|
||||
ipuRegs.ctrl.BUSY = 1;
|
||||
|
||||
//if(!ipu1dma.chcr.STR) hwIntcIrq(INTC_IPU);
|
||||
//if(!ipu1ch.chcr.STR) hwIntcIrq(INTC_IPU);
|
||||
}
|
||||
|
||||
__noinline void IPUWorker()
|
||||
|
@ -922,7 +922,7 @@ __noinline void IPUWorker()
|
|||
// CHECK!: IPU0dma remains when IDEC is done, so we need to clear it
|
||||
// Check Mana Khemia 1 "off campus" to trigger a GUST IDEC messup.
|
||||
// This hackfixes it :/
|
||||
//if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt();
|
||||
//if (ipu0ch.qwc > 0 && ipu0ch.chcr.STR) ipu0Interrupt();
|
||||
break;
|
||||
|
||||
case SCE_IPU_BDEC:
|
||||
|
|
|
@ -47,28 +47,28 @@ static __fi void ipuDmacSrcChain()
|
|||
switch (IPU1Status.ChainMode)
|
||||
{
|
||||
case TAG_REFE: // refe
|
||||
//if(IPU1Status.InProgress == false) ipu1dma.tadr += 16;
|
||||
//if(IPU1Status.InProgress == false) ipu1ch.tadr += 16;
|
||||
IPU1Status.DMAFinished = true;
|
||||
break;
|
||||
case TAG_CNT: // cnt
|
||||
// Set the taddr to the next tag
|
||||
ipu1dma.tadr = ipu1dma.madr;
|
||||
ipu1ch.tadr = ipu1ch.madr;
|
||||
//if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false;
|
||||
break;
|
||||
|
||||
case TAG_NEXT: // next
|
||||
ipu1dma.tadr = IPU1Status.NextMem;
|
||||
ipu1ch.tadr = IPU1Status.NextMem;
|
||||
//if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false;
|
||||
break;
|
||||
|
||||
case TAG_REF: // ref
|
||||
//if(IPU1Status.InProgress == false)ipu1dma.tadr += 16;
|
||||
//if(IPU1Status.InProgress == false)ipu1ch.tadr += 16;
|
||||
//if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false;
|
||||
break;
|
||||
|
||||
case TAG_END: // end
|
||||
//ipu1dma.tadr = ipu1dma.madr;
|
||||
IPU1Status.DMAFinished = true;
|
||||
//ipu1ch.tadr = ipu1ch.madr;
|
||||
//IPU1Status.DMAFinished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -77,12 +77,12 @@ static __fi int IPU1chain() {
|
|||
|
||||
int totalqwc = 0;
|
||||
|
||||
if (ipu1dma.qwc > 0 && IPU1Status.InProgress == true)
|
||||
if (ipu1ch.qwc > 0 && IPU1Status.InProgress == true)
|
||||
{
|
||||
int qwc = ipu1dma.qwc;
|
||||
int qwc = ipu1ch.qwc;
|
||||
u32 *pMem;
|
||||
|
||||
pMem = (u32*)dmaGetAddr(ipu1dma.madr, false);
|
||||
pMem = (u32*)dmaGetAddr(ipu1ch.madr, false);
|
||||
|
||||
if (pMem == NULL)
|
||||
{
|
||||
|
@ -92,15 +92,16 @@ static __fi int IPU1chain() {
|
|||
|
||||
//Write our data to the fifo
|
||||
qwc = ipu_fifo.in.write(pMem, qwc);
|
||||
ipu1dma.madr += qwc << 4;
|
||||
ipu1dma.qwc -= qwc;
|
||||
ipu1ch.madr += qwc << 4;
|
||||
ipu1ch.qwc -= qwc;
|
||||
totalqwc += qwc;
|
||||
}
|
||||
|
||||
//Update TADR etc
|
||||
if(IPU1Status.DMAMode == DMA_MODE_CHAIN) ipuDmacSrcChain();
|
||||
|
||||
if( ipu1dma.qwc == 0)
|
||||
hwDmacSrcTadrInc(ipu1ch);
|
||||
|
||||
if( ipu1ch.qwc == 0)
|
||||
IPU1Status.InProgress = false;
|
||||
|
||||
return totalqwc;
|
||||
|
@ -113,22 +114,22 @@ int IPU1dma()
|
|||
|
||||
//We need to make sure GIF has flushed before sending IPU data, it seems to REALLY screw FFX videos
|
||||
|
||||
if(ipu1dma.chcr.STR == false || IPU1Status.DMAMode == 2)
|
||||
if(ipu1ch.chcr.STR == false || IPU1Status.DMAMode == 2)
|
||||
{
|
||||
//We MUST stop the IPU from trying to fill the FIFO with more data if the DMA has been suspended
|
||||
//if we don't, we risk causing the data to go out of sync with the fifo and we end up losing some!
|
||||
//This is true for Dragons Quest 8 and probably others which suspend the DMA.
|
||||
DevCon.Warning("IPU1 running when IPU1 DMA disabled! CHCR %x QWC %x", ipu1dma.chcr._u32, ipu1dma.qwc);
|
||||
DevCon.Warning("IPU1 running when IPU1 DMA disabled! CHCR %x QWC %x", ipu1ch.chcr._u32, ipu1ch.qwc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IPU_LOG("IPU1 DMA Called QWC %x Finished %d In Progress %d tadr %x", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma.tadr);
|
||||
IPU_LOG("IPU1 DMA Called QWC %x Finished %d In Progress %d tadr %x", ipu1ch.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1ch.tadr);
|
||||
|
||||
switch(IPU1Status.DMAMode)
|
||||
{
|
||||
case DMA_MODE_NORMAL:
|
||||
{
|
||||
IPU_LOG("Processing Normal QWC left %x Finished %d In Progress %d", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress);
|
||||
IPU_LOG("Processing Normal QWC left %x Finished %d In Progress %d", ipu1ch.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress);
|
||||
if(IPU1Status.InProgress == true) totalqwc += IPU1chain();
|
||||
}
|
||||
break;
|
||||
|
@ -137,82 +138,37 @@ int IPU1dma()
|
|||
{
|
||||
if(IPU1Status.InProgress == true) //No transfer is ready to go so we need to set one up
|
||||
{
|
||||
IPU_LOG("Processing Chain QWC left %x Finished %d In Progress %d", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress);
|
||||
IPU_LOG("Processing Chain QWC left %x Finished %d In Progress %d", ipu1ch.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress);
|
||||
totalqwc += IPU1chain();
|
||||
//Set the TADR forward
|
||||
}
|
||||
|
||||
|
||||
if(IPU1Status.InProgress == false && IPU1Status.DMAFinished == false) //No transfer is ready to go so we need to set one up
|
||||
{
|
||||
tDMA_TAG* ptag = dmaGetAddr(ipu1dma.tadr, false); //Set memory pointer to TADR
|
||||
tDMA_TAG* ptag = dmaGetAddr(ipu1ch.tadr, false); //Set memory pointer to TADR
|
||||
|
||||
if (!ipu1dma.transfer("IPU1", ptag))
|
||||
if (!ipu1ch.transfer("IPU1", ptag))
|
||||
{
|
||||
return totalqwc;
|
||||
}
|
||||
ipu1ch.madr = ptag[1]._u32;
|
||||
|
||||
ipu1cycles += 1; // Add 1 cycles from the QW read for the tag
|
||||
IPU1Status.ChainMode = ptag->ID;
|
||||
|
||||
if(ipu1dma.chcr.TTE) DevCon.Warning("TTE?");
|
||||
if(ipu1ch.chcr.TTE) DevCon.Warning("TTE?");
|
||||
|
||||
switch (IPU1Status.ChainMode)
|
||||
{
|
||||
case TAG_REFE: // refe
|
||||
// do not change tadr
|
||||
//ipu1dma.tadr += 16;
|
||||
ipu1dma.tadr += 16;
|
||||
ipu1dma.madr = ptag[1]._u32;
|
||||
IPU_LOG("Tag should end on %x", ipu1dma.tadr);
|
||||
IPU1Status.DMAFinished = hwDmacSrcChain(ipu1ch, ptag->ID);
|
||||
|
||||
break;
|
||||
|
||||
case TAG_CNT: // cnt
|
||||
ipu1dma.tadr += 16;
|
||||
ipu1dma.madr = ipu1dma.tadr;
|
||||
IPU_LOG("Tag should end on %x", ipu1dma.madr + ipu1dma.qwc * 16);
|
||||
//ipu1dma.tadr = ipu1dma.madr + (ipu1dma.qwc * 16);
|
||||
// Set the taddr to the next tag
|
||||
//IPU1Status.DMAFinished = false;
|
||||
break;
|
||||
|
||||
case TAG_NEXT: // next
|
||||
ipu1dma.madr = ipu1dma.tadr + 16;
|
||||
IPU1Status.NextMem = ptag[1]._u32;
|
||||
IPU_LOG("Tag should end on %x", IPU1Status.NextMem);
|
||||
//IPU1Status.DMAFinished = false;
|
||||
break;
|
||||
|
||||
case TAG_REF: // ref
|
||||
ipu1dma.madr = ptag[1]._u32;
|
||||
ipu1dma.tadr += 16;
|
||||
IPU_LOG("Tag should end on %x", ipu1dma.tadr);
|
||||
//IPU1Status.DMAFinished = false;
|
||||
break;
|
||||
|
||||
case TAG_END: // end
|
||||
// do not change tadr
|
||||
ipu1dma.madr = ipu1dma.tadr + 16;
|
||||
//ipu1dma.tadr += 16;
|
||||
IPU_LOG("Tag should end on %x", ipu1dma.madr + ipu1dma.qwc * 16);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
DevCon.Error("IPU ERROR: different transfer mode!, Please report to PCSX2 Team");
|
||||
break;
|
||||
}
|
||||
|
||||
//if(ipu1dma.qwc == 0) Console.Warning("Blank QWC!");
|
||||
if(ipu1dma.qwc > 0) IPU1Status.InProgress = true;
|
||||
if(ipu1ch.qwc > 0) IPU1Status.InProgress = true;
|
||||
IPU_LOG("dmaIPU1 dmaChain %8.8x_%8.8x size=%d, addr=%lx, fifosize=%x",
|
||||
ptag[1]._u32, ptag[0]._u32, ipu1dma.qwc, ipu1dma.madr, 8 - g_BP.IFC);
|
||||
ptag[1]._u32, ptag[0]._u32, ipu1ch.qwc, ipu1ch.madr, 8 - g_BP.IFC);
|
||||
|
||||
if (ipu1dma.chcr.TIE && ptag->IRQ) //Tag Interrupt is set, so schedule the end/interrupt
|
||||
if (ipu1ch.chcr.TIE && ptag->IRQ) //Tag Interrupt is set, so schedule the end/interrupt
|
||||
IPU1Status.DMAFinished = true;
|
||||
|
||||
IPU_LOG("Processing Start Chain QWC left %x Finished %d In Progress %d", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress);
|
||||
IPU_LOG("Processing Start Chain QWC left %x Finished %d In Progress %d", ipu1ch.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress);
|
||||
totalqwc += IPU1chain();
|
||||
//Set the TADR forward
|
||||
}
|
||||
|
@ -222,7 +178,7 @@ int IPU1dma()
|
|||
}
|
||||
|
||||
//Do this here to prevent double settings on Chain DMA's
|
||||
if(totalqwc > 0 || ipu1dma.qwc == 0)
|
||||
if(totalqwc > 0 || ipu1ch.qwc == 0)
|
||||
{
|
||||
IPU_INT_TO(totalqwc * BIAS);
|
||||
IPUProcessInterrupt();
|
||||
|
@ -232,7 +188,7 @@ int IPU1dma()
|
|||
cpuRegs.eCycle[4] = 0x9999;//IPU_INT_TO(2048);
|
||||
}
|
||||
|
||||
IPU_LOG("Completed Call IPU1 DMA QWC Remaining %x Finished %d In Progress %d tadr %x", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma.tadr);
|
||||
IPU_LOG("Completed Call IPU1 DMA QWC Remaining %x Finished %d In Progress %d tadr %x", ipu1ch.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1ch.tadr);
|
||||
return totalqwc;
|
||||
}
|
||||
|
||||
|
@ -248,46 +204,45 @@ void IPU0dma()
|
|||
int readsize;
|
||||
tDMA_TAG* pMem;
|
||||
|
||||
if ((!(ipu0dma.chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma.qwc == 0))
|
||||
if ((!(ipu0ch.chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0ch.qwc == 0))
|
||||
{
|
||||
DevCon.Warning("How??");
|
||||
return;
|
||||
}
|
||||
|
||||
pxAssert(!(ipu0dma.chcr.TTE));
|
||||
pxAssert(!(ipu0ch.chcr.TTE));
|
||||
|
||||
IPU_LOG("dmaIPU0 chcr = %lx, madr = %lx, qwc = %lx",
|
||||
ipu0dma.chcr._u32, ipu0dma.madr, ipu0dma.qwc);
|
||||
ipu0ch.chcr._u32, ipu0ch.madr, ipu0ch.qwc);
|
||||
|
||||
pxAssert(ipu0dma.chcr.MOD == NORMAL_MODE);
|
||||
pxAssert(ipu0ch.chcr.MOD == NORMAL_MODE);
|
||||
|
||||
pMem = dmaGetAddr(ipu0dma.madr, true);
|
||||
pMem = dmaGetAddr(ipu0ch.madr, true);
|
||||
|
||||
readsize = min(ipu0dma.qwc, (u16)ipuRegs.ctrl.OFC);
|
||||
readsize = min(ipu0ch.qwc, (u16)ipuRegs.ctrl.OFC);
|
||||
ipu_fifo.out.read(pMem, readsize);
|
||||
|
||||
ipu0dma.madr += readsize << 4;
|
||||
ipu0dma.qwc -= readsize; // note: qwc is u16
|
||||
ipu0ch.madr += readsize << 4;
|
||||
ipu0ch.qwc -= readsize; // note: qwc is u16
|
||||
|
||||
|
||||
if (ipu0dma.qwc == 0)
|
||||
{
|
||||
if (dmacRegs.ctrl.STS == STS_fromIPU) // STS == fromIPU
|
||||
{
|
||||
dmacRegs.stadr.ADDR = ipu0dma.madr;
|
||||
dmacRegs.stadr.ADDR = ipu0ch.madr;
|
||||
switch (dmacRegs.ctrl.STD)
|
||||
{
|
||||
case NO_STD:
|
||||
break;
|
||||
case STD_GIF: // GIF
|
||||
DevCon.Warning("GIFSTALL");
|
||||
//DevCon.Warning("GIFSTALL");
|
||||
g_nDMATransfer.GIFSTALL = true;
|
||||
break;
|
||||
case STD_VIF1: // VIF
|
||||
DevCon.Warning("VIFSTALL");
|
||||
//DevCon.Warning("VIFSTALL");
|
||||
g_nDMATransfer.VIFSTALL = true;
|
||||
break;
|
||||
case STD_SIF1:
|
||||
DevCon.Warning("SIFSTALL");
|
||||
// DevCon.Warning("SIFSTALL");
|
||||
g_nDMATransfer.SIFSTALL = true;
|
||||
break;
|
||||
}
|
||||
|
@ -296,7 +251,7 @@ void IPU0dma()
|
|||
//This was IPU_INT_FROM(readsize*BIAS );
|
||||
//This broke vids in Digital Devil Saga
|
||||
//Note that interrupting based on totalsize is just guessing..
|
||||
}
|
||||
|
||||
IPU_INT_FROM( readsize * BIAS );
|
||||
if(ipuRegs.ctrl.IFC > 0) IPUProcessInterrupt();
|
||||
|
||||
|
@ -305,17 +260,17 @@ void IPU0dma()
|
|||
|
||||
__fi void dmaIPU0() // fromIPU
|
||||
{
|
||||
if (ipu0dma.pad != 0)
|
||||
if (ipu0ch.pad != 0)
|
||||
{
|
||||
// Note: pad is the padding right above qwc, so we're testing whether qwc
|
||||
// has overflowed into pad.
|
||||
DevCon.Warning(L"IPU0dma's upper 16 bits set to %x", ipu0dma.pad);
|
||||
ipu0dma.qwc = ipu0dma.pad = 0;
|
||||
DevCon.Warning(L"IPU0dma's upper 16 bits set to %x", ipu0ch.pad);
|
||||
ipu0ch.qwc = ipu0ch.pad = 0;
|
||||
//If we are going to clear down IPU0, we should end it too. Going to test this scenario on the PS2 mind - Refraction
|
||||
ipu0dma.chcr.STR = false;
|
||||
ipu0ch.chcr.STR = false;
|
||||
hwDmacIrq(DMAC_FROM_IPU);
|
||||
}
|
||||
|
||||
//if (dmacRegs.ctrl.STS == STS_fromIPU) DevCon.Warning("DMA Stall enabled on IPU0");
|
||||
IPU_INT_FROM( 64 );
|
||||
|
||||
|
||||
|
@ -324,35 +279,42 @@ __fi void dmaIPU0() // fromIPU
|
|||
|
||||
__fi void dmaIPU1() // toIPU
|
||||
{
|
||||
IPU_LOG("IPU1DMAStart QWC %x, MADR %x, CHCR %x, TADR %x", ipu1dma.qwc, ipu1dma.madr, ipu1dma.chcr._u32, ipu1dma.tadr);
|
||||
IPU_LOG("IPU1DMAStart QWC %x, MADR %x, CHCR %x, TADR %x", ipu1ch.qwc, ipu1ch.madr, ipu1ch.chcr._u32, ipu1ch.tadr);
|
||||
|
||||
if (ipu1dma.pad != 0)
|
||||
if (ipu1ch.pad != 0)
|
||||
{
|
||||
// Note: pad is the padding right above qwc, so we're testing whether qwc
|
||||
// has overflowed into pad.
|
||||
DevCon.Warning(L"IPU1dma's upper 16 bits set to %x\n", ipu1dma.pad);
|
||||
ipu1dma.qwc = ipu1dma.pad = 0;
|
||||
DevCon.Warning(L"IPU1dma's upper 16 bits set to %x\n", ipu1ch.pad);
|
||||
ipu1ch.qwc = ipu1ch.pad = 0;
|
||||
// If we are going to clear down IPU1, we should end it too.
|
||||
// Going to test this scenario on the PS2 mind - Refraction
|
||||
ipu1dma.chcr.STR = false;
|
||||
ipu1ch.chcr.STR = false;
|
||||
hwDmacIrq(DMAC_TO_IPU);
|
||||
}
|
||||
|
||||
if (ipu1dma.chcr.MOD == CHAIN_MODE) //Chain Mode
|
||||
if (ipu1ch.chcr.MOD == CHAIN_MODE) //Chain Mode
|
||||
{
|
||||
IPU_LOG("Setting up IPU1 Chain mode");
|
||||
if(ipu1dma.qwc == 0)
|
||||
if(ipu1ch.qwc == 0)
|
||||
{
|
||||
IPU1Status.InProgress = false;
|
||||
IPU1Status.DMAFinished = false;
|
||||
}
|
||||
else
|
||||
{ //Attempting to continue a previous chain
|
||||
IPU_LOG("Resuming DMA TAG %x", (ipu1dma.chcr.TAG >> 12));
|
||||
IPU_LOG("Resuming DMA TAG %x", (ipu1ch.chcr.TAG >> 12));
|
||||
//We MUST check the CHCR for the tag it last knew, it can be manipulated!
|
||||
IPU1Status.ChainMode = (ipu1dma.chcr.TAG >> 12) & 0x7;
|
||||
IPU1Status.ChainMode = (ipu1ch.chcr.TAG >> 12) & 0x7;
|
||||
IPU1Status.InProgress = true;
|
||||
IPU1Status.DMAFinished = ((ipu1dma.chcr.TAG >> 15) && ipu1dma.chcr.TIE) ? true : false;
|
||||
if ((ipu1ch.chcr.tag().ID == TAG_REFE) || (ipu1ch.chcr.tag().ID == TAG_END) || (ipu1ch.chcr.tag().IRQ && ipu1ch.chcr.TIE))
|
||||
{
|
||||
IPU1Status.DMAFinished = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPU1Status.DMAFinished = false;
|
||||
}
|
||||
}
|
||||
|
||||
IPU1Status.DMAMode = DMA_MODE_CHAIN;
|
||||
|
@ -360,9 +322,9 @@ __fi void dmaIPU1() // toIPU
|
|||
}
|
||||
else //Normal Mode
|
||||
{
|
||||
if(ipu1dma.qwc == 0)
|
||||
if(ipu1ch.qwc == 0)
|
||||
{
|
||||
ipu1dma.chcr.STR = false;
|
||||
ipu1ch.chcr.STR = false;
|
||||
// Hack to force stop IPU
|
||||
ipuRegs.cmd.BUSY = 0;
|
||||
ipuRegs.ctrl.BUSY = 0;
|
||||
|
@ -388,7 +350,7 @@ void ipu0Interrupt()
|
|||
{
|
||||
IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle);
|
||||
|
||||
if(ipu0dma.qwc > 0)
|
||||
if(ipu0ch.qwc > 0)
|
||||
{
|
||||
IPU0dma();
|
||||
return;
|
||||
|
@ -402,7 +364,7 @@ void ipu0Interrupt()
|
|||
if (g_nDMATransfer.GIFSTALL)
|
||||
{
|
||||
// gif
|
||||
DevCon.Warning("IPU GIF Stall");
|
||||
//DevCon.Warning("IPU GIF Stall");
|
||||
g_nDMATransfer.GIFSTALL = false;
|
||||
//if (gif->chcr.STR) GIFdma();
|
||||
}
|
||||
|
@ -410,7 +372,7 @@ void ipu0Interrupt()
|
|||
if (g_nDMATransfer.VIFSTALL)
|
||||
{
|
||||
// vif
|
||||
DevCon.Warning("IPU VIF Stall");
|
||||
//DevCon.Warning("IPU VIF Stall");
|
||||
g_nDMATransfer.VIFSTALL = false;
|
||||
//if (vif1ch.chcr.STR) dmaVIF1();
|
||||
}
|
||||
|
@ -418,12 +380,12 @@ void ipu0Interrupt()
|
|||
if (g_nDMATransfer.SIFSTALL)
|
||||
{
|
||||
// sif
|
||||
DevCon.Warning("IPU SIF Stall");
|
||||
//DevCon.Warning("IPU SIF Stall");
|
||||
g_nDMATransfer.SIFSTALL = false;
|
||||
|
||||
// Not totally sure whether this needs to be done or not, so I'm
|
||||
// leaving it commented out for the moment.
|
||||
//if (sif1dma.chcr.STR) SIF1Dma();
|
||||
//if (sif1ch.chcr.STR) SIF1Dma();
|
||||
}
|
||||
|
||||
if (g_nDMATransfer.TIE0)
|
||||
|
@ -431,7 +393,7 @@ void ipu0Interrupt()
|
|||
g_nDMATransfer.TIE0 = false;
|
||||
}
|
||||
|
||||
ipu0dma.chcr.STR = false;
|
||||
ipu0ch.chcr.STR = false;
|
||||
hwDmacIrq(DMAC_FROM_IPU);
|
||||
DMA_LOG("IPU0 DMA End");
|
||||
}
|
||||
|
@ -447,7 +409,7 @@ IPU_FORCEINLINE void ipu1Interrupt()
|
|||
}
|
||||
|
||||
DMA_LOG("IPU1 DMA End");
|
||||
ipu1dma.chcr.STR = false;
|
||||
ipu1ch.chcr.STR = false;
|
||||
IPU1Status.DMAMode = 2;
|
||||
hwDmacIrq(DMAC_TO_IPU);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
|
||||
#include "IPU.h"
|
||||
|
||||
static DMACh& ipu0dma = (DMACh&)eeHw[0xb000];
|
||||
static DMACh& ipu1dma = (DMACh&)eeHw[0xb400];
|
||||
|
||||
|
||||
struct IPUStatus {
|
||||
bool InProgress;
|
||||
|
|
|
@ -120,7 +120,7 @@ int _SPR0chain()
|
|||
__fi void SPR0chain()
|
||||
{
|
||||
int cycles = 0;
|
||||
cycles = _SPR0chain() * BIAS;
|
||||
cycles = _SPR0chain() / BIAS;
|
||||
CPU_INT(DMAC_FROM_SPR, cycles);
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,7 @@ void _SPR0interleave()
|
|||
SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
|
||||
spr0ch.qwc, tqwc, sqwc, spr0ch.madr, spr0ch.sadr);
|
||||
|
||||
CPU_INT(DMAC_FROM_SPR, qwc * BIAS);
|
||||
CPU_INT(DMAC_FROM_SPR, qwc / BIAS);
|
||||
|
||||
while (qwc > 0)
|
||||
{
|
||||
|
@ -178,6 +178,10 @@ static __fi void _dmaSPR0()
|
|||
{
|
||||
case NORMAL_MODE:
|
||||
{
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR) // STS == fromSPR
|
||||
{
|
||||
Console.WriteLn("SPR stall control Normal not implemented");
|
||||
}
|
||||
SPR0chain();
|
||||
spr0finished = true;
|
||||
return;
|
||||
|
@ -239,6 +243,10 @@ static __fi void _dmaSPR0()
|
|||
//case INTERLEAVE_MODE:
|
||||
default:
|
||||
{
|
||||
if (dmacRegs.ctrl.STS == STS_fromSPR) // STS == fromSPR
|
||||
{
|
||||
Console.WriteLn("SPR stall control interleave not implemented");
|
||||
}
|
||||
_SPR0interleave();
|
||||
spr0finished = true;
|
||||
break;
|
||||
|
@ -352,7 +360,7 @@ __fi void SPR1chain()
|
|||
int cycles = 0;
|
||||
if(!CHECK_IPUWAITHACK)
|
||||
{
|
||||
cycles = _SPR1chain() * BIAS;
|
||||
cycles = _SPR1chain() / BIAS;
|
||||
CPU_INT(DMAC_TO_SPR, cycles);
|
||||
}
|
||||
else
|
||||
|
@ -372,7 +380,7 @@ void _SPR1interleave()
|
|||
if (tqwc == 0) tqwc = qwc;
|
||||
SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
|
||||
spr1ch.qwc, tqwc, sqwc, spr1ch.madr, spr1ch.sadr);
|
||||
CPU_INT(DMAC_TO_SPR, qwc * BIAS);
|
||||
CPU_INT(DMAC_TO_SPR, qwc / BIAS);
|
||||
while (qwc > 0)
|
||||
{
|
||||
spr1ch.qwc = std::min(tqwc, qwc);
|
||||
|
@ -432,7 +440,7 @@ void _dmaSPR1() // toSPR work function
|
|||
SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx taddr=%lx saddr=%lx",
|
||||
ptag[1]._u32, ptag[0]._u32, spr1ch.qwc, ptag->ID, spr1ch.madr, spr1ch.tadr, spr1ch.sadr);
|
||||
|
||||
done = (hwDmacSrcChain(spr1ch, ptag->ID));
|
||||
done = hwDmacSrcChain(spr1ch, ptag->ID);
|
||||
SPR1chain(); //Transfers the data set by the switch
|
||||
|
||||
if (spr1ch.chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
|
@ -468,7 +476,7 @@ void dmaSPR1() // toSPR
|
|||
if(spr1ch.chcr.MOD == CHAIN_MODE && spr1ch.qwc > 0)
|
||||
{
|
||||
//DevCon.Warning(L"SPR1 QWC on Chain " + spr1ch.chcr.desc());
|
||||
if ((spr1ch.chcr.tag().ID == TAG_END) || (spr1ch.chcr.tag().ID == TAG_REFE))
|
||||
if ((spr1ch.chcr.tag().ID == TAG_END) || (spr1ch.chcr.tag().ID == TAG_REFE) || (spr1ch.chcr.tag().IRQ && spr1ch.chcr.TIE))
|
||||
{
|
||||
spr1finished = true;
|
||||
}
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
|
||||
static const int FIFO_SIF_W = 128;
|
||||
|
||||
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
|
||||
|
|
|
@ -35,14 +35,14 @@ static __fi void Sif0Init()
|
|||
// Write from Fifo to EE.
|
||||
static __fi bool WriteFifoToEE()
|
||||
{
|
||||
const int readSize = min((s32)sif0dma.qwc, sif0.fifo.size >> 2);
|
||||
const int readSize = min((s32)sif0ch.qwc, sif0.fifo.size >> 2);
|
||||
|
||||
tDMA_TAG *ptag;
|
||||
|
||||
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma.madr);
|
||||
SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma.qwc << 2);
|
||||
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0ch.madr);
|
||||
SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0ch.qwc << 2);
|
||||
|
||||
ptag = sif0dma.getAddr(sif0dma.madr, DMAC_SIF0, true);
|
||||
ptag = sif0ch.getAddr(sif0ch.madr, DMAC_SIF0, true);
|
||||
if (ptag == NULL)
|
||||
{
|
||||
DevCon.Warning("Write Fifo to EE: ptag == NULL");
|
||||
|
@ -52,11 +52,11 @@ static __fi bool WriteFifoToEE()
|
|||
sif0.fifo.read((u32*)ptag, readSize << 2);
|
||||
|
||||
// Clearing handled by vtlb memory protection and manual blocks.
|
||||
//Cpu->Clear(sif0dma.madr, readSize*4);
|
||||
//Cpu->Clear(sif0ch.madr, readSize*4);
|
||||
|
||||
sif0dma.madr += readSize << 4;
|
||||
sif0ch.madr += readSize << 4;
|
||||
sif0.ee.cycles += readSize; // fixme : BIAS is factored in above
|
||||
sif0dma.qwc -= readSize;
|
||||
sif0ch.qwc -= readSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ static __fi bool WriteIOPtoFifo()
|
|||
return true;
|
||||
}
|
||||
|
||||
// Read Fifo into an ee tag, transfer it to sif0dma, and process it.
|
||||
// Read Fifo into an ee tag, transfer it to sif0ch, and process it.
|
||||
static __fi bool ProcessEETag()
|
||||
{
|
||||
static __aligned16 u32 tag[4];
|
||||
|
@ -88,13 +88,13 @@ static __fi bool ProcessEETag()
|
|||
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(&ptag);
|
||||
sif0dma.madr = tag[1];
|
||||
sif0ch.unsafeTransfer(&ptag);
|
||||
sif0ch.madr = tag[1];
|
||||
|
||||
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]);
|
||||
sif0ch.madr, sif0ch.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);
|
||||
|
||||
if (sif0dma.chcr.TIE && ptag.IRQ)
|
||||
if (sif0ch.chcr.TIE && ptag.IRQ)
|
||||
{
|
||||
//Console.WriteLn("SIF0 TIE");
|
||||
sif0.ee.end = true;
|
||||
|
@ -106,7 +106,7 @@ static __fi bool ProcessEETag()
|
|||
|
||||
case TAG_CNTS:
|
||||
if (dmacRegs.ctrl.STS == STS_SIF0)
|
||||
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
|
||||
dmacRegs.stadr.ADDR = sif0ch.madr + (sif0ch.qwc * 16);
|
||||
break;
|
||||
|
||||
case TAG_END:
|
||||
|
@ -180,7 +180,7 @@ static __fi void EndIOP()
|
|||
// Handle the EE transfer.
|
||||
static __fi void HandleEETransfer()
|
||||
{
|
||||
if(sif0dma.chcr.STR == false)
|
||||
if(sif0ch.chcr.STR == false)
|
||||
{
|
||||
//DevCon.Warning("Replacement for irq prevention hack EE SIF0");
|
||||
sif0.ee.end = false;
|
||||
|
@ -190,20 +190,20 @@ static __fi void HandleEETransfer()
|
|||
|
||||
if (dmacRegs.ctrl.STS == STS_SIF0)
|
||||
{
|
||||
DevCon.Warning("SIF0 stall control");
|
||||
DevCon.Warning("SIF0 stall control not properly implemented");
|
||||
}
|
||||
|
||||
/*if (sif0dma.qwc == 0)
|
||||
if (sif0dma.chcr.MOD == NORMAL_MODE)
|
||||
/*if (sif0ch.qwc == 0)
|
||||
if (sif0ch.chcr.MOD == NORMAL_MODE)
|
||||
if (!sif0.ee.end){
|
||||
DevCon.Warning("sif0 irq prevented");
|
||||
done = true;
|
||||
return;
|
||||
}*/
|
||||
|
||||
if (sif0dma.qwc <= 0)
|
||||
if (sif0ch.qwc <= 0)
|
||||
{
|
||||
if ((sif0dma.chcr.MOD == NORMAL_MODE) || sif0.ee.end)
|
||||
if ((sif0ch.chcr.MOD == NORMAL_MODE) || sif0.ee.end)
|
||||
{
|
||||
// Stop transferring ee, and signal an interrupt.
|
||||
done = true;
|
||||
|
@ -211,13 +211,13 @@ static __fi void HandleEETransfer()
|
|||
}
|
||||
else if (sif0.fifo.size >= 4) // Read a tag
|
||||
{
|
||||
// Read Fifo into an ee tag, transfer it to sif0dma
|
||||
// Read Fifo into an ee tag, transfer it to sif0ch
|
||||
// and process it.
|
||||
ProcessEETag();
|
||||
}
|
||||
}
|
||||
|
||||
if (sif0dma.qwc > 0) // If we're writing something, continue to do so.
|
||||
if (sif0ch.qwc > 0) // If we're writing something, continue to do so.
|
||||
{
|
||||
// Write from Fifo to EE.
|
||||
if (sif0.fifo.size > 0)
|
||||
|
@ -312,7 +312,7 @@ __fi void SIF0Dma()
|
|||
}
|
||||
if (sif0.ee.busy)
|
||||
{
|
||||
if(sif0.fifo.size >= 4 || (sif0.ee.end == true && sif0dma.qwc == 0))
|
||||
if(sif0.fifo.size >= 4 || (sif0.ee.end == true && sif0ch.qwc == 0))
|
||||
{
|
||||
BusyCheck++;
|
||||
HandleEETransfer();
|
||||
|
@ -332,19 +332,19 @@ __fi void sif0Interrupt()
|
|||
__fi void EEsif0Interrupt()
|
||||
{
|
||||
hwDmacIrq(DMAC_SIF0);
|
||||
sif0dma.chcr.STR = false;
|
||||
sif0ch.chcr.STR = false;
|
||||
}
|
||||
|
||||
__fi void dmaSIF0()
|
||||
{
|
||||
SIF_LOG(wxString(L"dmaSIF0" + sif0dma.cmqt_to_str()).To8BitData());
|
||||
SIF_LOG(wxString(L"dmaSIF0" + sif0ch.cmqt_to_str()).To8BitData());
|
||||
|
||||
if (sif0.fifo.readPos != sif0.fifo.writePos)
|
||||
{
|
||||
SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos");
|
||||
}
|
||||
|
||||
//if(sif0dma.chcr.MOD == CHAIN_MODE && sif0dma.qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0dma.chcr.desc());
|
||||
//if(sif0ch.chcr.MOD == CHAIN_MODE && sif0ch.qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0ch.chcr.desc());
|
||||
psHu32(SBUS_F240) |= 0x2000;
|
||||
sif0.ee.busy = true;
|
||||
|
||||
|
|
|
@ -38,11 +38,11 @@ static __fi 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.sif_free() >> 2);
|
||||
const int writeSize = min((s32)sif1ch.qwc, sif1.fifo.sif_free() >> 2);
|
||||
|
||||
tDMA_TAG *ptag;
|
||||
|
||||
ptag = sif1dma.getAddr(sif1dma.madr, DMAC_SIF1, false);
|
||||
ptag = sif1ch.getAddr(sif1ch.madr, DMAC_SIF1, false);
|
||||
if (ptag == NULL)
|
||||
{
|
||||
DevCon.Warning("Write EE to Fifo: ptag == NULL");
|
||||
|
@ -51,10 +51,10 @@ static __fi bool WriteEEtoFifo()
|
|||
|
||||
sif1.fifo.write((u32*)ptag, writeSize << 2);
|
||||
|
||||
sif1dma.madr += writeSize << 4;
|
||||
hwDmacSrcTadrInc(sif1dma);
|
||||
sif1ch.madr += writeSize << 4;
|
||||
hwDmacSrcTadrInc(sif1ch);
|
||||
sif1.ee.cycles += writeSize; // fixme : BIAS is factored in above
|
||||
sif1dma.qwc -= writeSize;
|
||||
sif1ch.qwc -= writeSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -85,61 +85,31 @@ static __fi bool ProcessEETag()
|
|||
tDMA_TAG *ptag;
|
||||
SIF_LOG("Sif1: ProcessEETag");
|
||||
|
||||
// Process DMA tag at sif1dma.tadr
|
||||
ptag = sif1dma.DMAtransfer(sif1dma.tadr, DMAC_SIF1);
|
||||
// Process DMA tag at sif1ch.tadr
|
||||
ptag = sif1ch.DMAtransfer(sif1ch.tadr, DMAC_SIF1);
|
||||
if (ptag == NULL)
|
||||
{
|
||||
Console.WriteLn("Sif1 ProcessEETag: ptag = NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sif1dma.chcr.TTE)
|
||||
if (sif1ch.chcr.TTE)
|
||||
{
|
||||
Console.WriteLn("SIF1 TTE");
|
||||
sif1.fifo.write((u32*)ptag + 2, 2);
|
||||
}
|
||||
|
||||
if (sif1dma.chcr.TIE && ptag->IRQ)
|
||||
if (sif1ch.chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
Console.WriteLn("SIF1 TIE");
|
||||
sif1.ee.end = true;
|
||||
}
|
||||
|
||||
SIF_LOG(wxString(ptag->tag_to_str()).To8BitData());
|
||||
switch (ptag->ID)
|
||||
{
|
||||
case TAG_REFE:
|
||||
sif1.ee.end = true;
|
||||
sif1dma.madr = ptag[1]._u32;
|
||||
sif1dma.tadr += 16;
|
||||
break;
|
||||
sif1ch.madr = ptag[1]._u32;
|
||||
|
||||
case TAG_CNT:
|
||||
sif1dma.tadr += 16;
|
||||
sif1dma.madr = sif1dma.tadr;
|
||||
break;
|
||||
sif1.ee.end = hwDmacSrcChain(sif1ch, ptag->ID);
|
||||
|
||||
case TAG_NEXT:
|
||||
sif1dma.madr = sif1dma.tadr + 16;
|
||||
sif1dma.tadr = ptag[1]._u32;
|
||||
break;
|
||||
|
||||
case TAG_REF:
|
||||
case TAG_REFS:
|
||||
if(ptag->ID == TAG_REFS && dmacRegs.ctrl.STD == STD_SIF1) DevCon.Warning("SIF1 Drain Stall Control not implemented");
|
||||
sif1dma.madr = ptag[1]._u32;
|
||||
sif1dma.tadr += 16;
|
||||
break;
|
||||
|
||||
case TAG_END:
|
||||
sif1.ee.end = true;
|
||||
sif1dma.madr = sif1dma.tadr + 16;
|
||||
//sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
|
||||
break;
|
||||
|
||||
default:
|
||||
Console.WriteLn("Bad addr1 source chain");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -205,7 +175,7 @@ static __fi void EndIOP()
|
|||
// Handle the EE transfer.
|
||||
static __fi void HandleEETransfer()
|
||||
{
|
||||
if(sif1dma.chcr.STR == false)
|
||||
if(sif1ch.chcr.STR == false)
|
||||
{
|
||||
//DevCon.Warning("Replacement for irq prevention hack EE SIF1");
|
||||
sif1.ee.end = false;
|
||||
|
@ -214,22 +184,22 @@ static __fi void HandleEETransfer()
|
|||
}
|
||||
if (dmacRegs.ctrl.STD == STD_SIF1)
|
||||
{
|
||||
DevCon.Warning("SIF1 stall control"); // STD == fromSIF1
|
||||
DevCon.Warning("SIF1 stall control Not Implemented"); // STD == fromSIF1
|
||||
}
|
||||
|
||||
/*if (sif1dma.qwc == 0)
|
||||
if (sif1dma.chcr.MOD == NORMAL_MODE)
|
||||
/*if (sif1ch.qwc == 0)
|
||||
if (sif1ch.chcr.MOD == NORMAL_MODE)
|
||||
if (!sif1.ee.end){
|
||||
DevCon.Warning("sif1 irq prevented CHCR %x QWC %x", sif1dma.chcr, sif1dma.qwc);
|
||||
DevCon.Warning("sif1 irq prevented CHCR %x QWC %x", sif1ch.chcr, sif1ch.qwc);
|
||||
done = true;
|
||||
return;
|
||||
}*/
|
||||
|
||||
// If there's no more to transfer.
|
||||
if (sif1dma.qwc <= 0)
|
||||
if (sif1ch.qwc <= 0)
|
||||
{
|
||||
// If NORMAL mode or end of CHAIN then stop DMA.
|
||||
if ((sif1dma.chcr.MOD == NORMAL_MODE) || sif1.ee.end)
|
||||
if ((sif1ch.chcr.MOD == NORMAL_MODE) || sif1.ee.end)
|
||||
{
|
||||
done = true;
|
||||
EndEE();
|
||||
|
@ -297,7 +267,7 @@ __fi void SIF1Dma()
|
|||
|
||||
if (sif1.ee.busy)
|
||||
{
|
||||
if(sif1.fifo.sif_free() > 0 || (sif1.ee.end == true && sif1dma.qwc == 0))
|
||||
if(sif1.fifo.sif_free() > 0 || (sif1.ee.end == true && sif1ch.qwc == 0))
|
||||
{
|
||||
BusyCheck++;
|
||||
HandleEETransfer();
|
||||
|
@ -327,25 +297,24 @@ __fi void sif1Interrupt()
|
|||
__fi void EEsif1Interrupt()
|
||||
{
|
||||
hwDmacIrq(DMAC_SIF1);
|
||||
sif1dma.chcr.STR = false;
|
||||
sif1ch.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.
|
||||
__fi void dmaSIF1()
|
||||
{
|
||||
SIF_LOG(wxString(L"dmaSIF1" + sif1dma.cmqt_to_str()).To8BitData());
|
||||
SIF_LOG(wxString(L"dmaSIF1" + sif1ch.cmqt_to_str()).To8BitData());
|
||||
|
||||
if (sif1.fifo.readPos != sif1.fifo.writePos)
|
||||
{
|
||||
SIF_LOG("warning, sif1.fifoReadPos != sif1.fifoWritePos");
|
||||
}
|
||||
|
||||
//if(sif1dma.chcr.MOD == CHAIN_MODE && sif1dma.qwc > 0) DevCon.Warning(L"SIF1 QWC on Chain CHCR " + sif1dma.chcr.desc());
|
||||
|
||||
psHu32(SBUS_F240) |= 0x4000;
|
||||
sif1.ee.busy = true;
|
||||
|
||||
|
||||
// Okay, this here is needed currently (r3644).
|
||||
// FFX battles in the thunder plains map die otherwise, Phantasy Star 4 as well
|
||||
// These 2 games could be made playable again by increasing the time the EE or the IOP run,
|
||||
|
@ -358,6 +327,14 @@ __fi void dmaSIF1()
|
|||
// Legend of Legaia doesn't throw a warning either :)
|
||||
sif1.ee.end = false;
|
||||
|
||||
if (sif1ch.chcr.MOD == CHAIN_MODE && sif1ch.qwc > 0)
|
||||
{
|
||||
if ((sif1ch.chcr.tag().ID == TAG_REFE) || (sif1ch.chcr.tag().ID == TAG_END) || (sif1ch.chcr.tag().IRQ && vif1ch.chcr.TIE))
|
||||
{
|
||||
sif1.ee.end = true;
|
||||
}
|
||||
}
|
||||
|
||||
SIF1Dma();
|
||||
|
||||
}
|
||||
|
|
|
@ -66,80 +66,69 @@ __fi void vif0SetupTransfer()
|
|||
{
|
||||
tDMA_TAG *ptag;
|
||||
|
||||
switch (vif0.dmamode)
|
||||
ptag = dmaGetAddr(vif0ch.tadr, false); //Set memory pointer to TADR
|
||||
|
||||
if (!(vif0ch.transfer("vif0 Tag", ptag))) return;
|
||||
|
||||
vif0ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
g_vif0Cycles += 1; // Add 1 g_vifCycles from the QW read for the tag
|
||||
|
||||
// Transfer dma tag if tte is set
|
||||
|
||||
VIF_LOG("vif0 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx",
|
||||
ptag[1]._u32, ptag[0]._u32, vif0ch.qwc, ptag->ID, vif0ch.madr, vif0ch.tadr);
|
||||
|
||||
vif0.inprogress = 0;
|
||||
|
||||
if (vif0ch.chcr.TTE)
|
||||
{
|
||||
case VIF_NORMAL_TO_MEM_MODE:
|
||||
vif0.inprogress = 1;
|
||||
vif0.done = true;
|
||||
g_vif0Cycles = 2;
|
||||
break;
|
||||
// Transfer dma tag if tte is set
|
||||
|
||||
case VIF_CHAIN_MODE:
|
||||
ptag = dmaGetAddr(vif0ch.tadr, false); //Set memory pointer to TADR
|
||||
bool ret;
|
||||
|
||||
if (!(vif0ch.transfer("vif0 Tag", ptag))) return;
|
||||
static __aligned16 u128 masked_tag;
|
||||
|
||||
vif0ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
g_vif0Cycles += 1; // Add 1 g_vifCycles from the QW read for the tag
|
||||
masked_tag._u64[0] = 0;
|
||||
masked_tag._u64[1] = *((u64*)ptag + 1);
|
||||
|
||||
// Transfer dma tag if tte is set
|
||||
VIF_LOG("\tVIF0 SrcChain TTE=1, data = 0x%08x.%08x", masked_tag._u32[3], masked_tag._u32[2]);
|
||||
|
||||
VIF_LOG("vif0 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx",
|
||||
ptag[1]._u32, ptag[0]._u32, vif0ch.qwc, ptag->ID, vif0ch.madr, vif0ch.tadr);
|
||||
if (vif0.irqoffset.enabled)
|
||||
{
|
||||
ret = VIF0transfer((u32*)&masked_tag + vif0.irqoffset.value, 4 - vif0.irqoffset.value, true); //Transfer Tag on stall
|
||||
//ret = VIF0transfer((u32*)ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset); //Transfer Tag on stall
|
||||
}
|
||||
else
|
||||
{
|
||||
//Some games (like killzone) do Tags mid unpack, the nops will just write blank data
|
||||
//to the VU's, which breaks stuff, this is where the 128bit packet will fail, so we ignore the first 2 words
|
||||
vif0.irqoffset.value = 2;
|
||||
vif0.irqoffset.enabled = true;
|
||||
ret = VIF0transfer((u32*)&masked_tag + 2, 2, true); //Transfer Tag
|
||||
//ret = VIF0transfer((u32*)ptag + 2, 2); //Transfer Tag
|
||||
}
|
||||
|
||||
vif0.inprogress = 0;
|
||||
if (!ret && vif0.irqoffset.enabled)
|
||||
{
|
||||
vif0.inprogress = 0; //Better clear this so it has to do it again (Jak 1)
|
||||
return; //IRQ set by VIFTransfer
|
||||
|
||||
if (vif0ch.chcr.TTE)
|
||||
{
|
||||
// Transfer dma tag if tte is set
|
||||
}
|
||||
}
|
||||
|
||||
bool ret;
|
||||
vif0.irqoffset.value = 0;
|
||||
vif0.irqoffset.enabled = false;
|
||||
vif0.done |= hwDmacSrcChainWithStack(vif0ch, ptag->ID);
|
||||
|
||||
static __aligned16 u128 masked_tag;
|
||||
if(vif0ch.qwc > 0) vif0.inprogress = 1;
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (vif0ch.chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
VIF_LOG("dmaIrq Set");
|
||||
|
||||
masked_tag._u64[0] = 0;
|
||||
masked_tag._u64[1] = *((u64*)ptag + 1);
|
||||
|
||||
VIF_LOG("\tVIF0 SrcChain TTE=1, data = 0x%08x.%08x", masked_tag._u32[3], masked_tag._u32[2]);
|
||||
|
||||
if (vif0.irqoffset.enabled)
|
||||
{
|
||||
ret = VIF0transfer((u32*)&masked_tag + vif0.irqoffset.value, 4 - vif0.irqoffset.value, true); //Transfer Tag on stall
|
||||
//ret = VIF0transfer((u32*)ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset); //Transfer Tag on stall
|
||||
}
|
||||
else
|
||||
{
|
||||
//Some games (like killzone) do Tags mid unpack, the nops will just write blank data
|
||||
//to the VU's, which breaks stuff, this is where the 128bit packet will fail, so we ignore the first 2 words
|
||||
vif0.irqoffset.value = 2;
|
||||
vif0.irqoffset.enabled = true;
|
||||
ret = VIF0transfer((u32*)&masked_tag + 2, 2, true); //Transfer Tag
|
||||
//ret = VIF0transfer((u32*)ptag + 2, 2); //Transfer Tag
|
||||
}
|
||||
|
||||
if (!ret && vif0.irqoffset.enabled)
|
||||
{
|
||||
vif0.inprogress = 0; //Better clear this so it has to do it again (Jak 1)
|
||||
return; //IRQ set by VIFTransfer
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
vif0.irqoffset.value = 0;
|
||||
vif0.irqoffset.enabled = false;
|
||||
vif0.done |= hwDmacSrcChainWithStack(vif0ch, ptag->ID);
|
||||
|
||||
if(vif0ch.qwc > 0) vif0.inprogress = 1;
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (vif0ch.chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
VIF_LOG("dmaIrq Set");
|
||||
|
||||
//End Transfer
|
||||
vif0.done = true;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
//End Transfer
|
||||
vif0.done = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +243,7 @@ __fi void vif0Interrupt()
|
|||
return; //Dont want to end if vif is stalled.
|
||||
}
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if (vif0ch.qwc > 0) Console.WriteLn("vif0 Ending with %x QWC left");
|
||||
if (vif0ch.qwc > 0) Console.WriteLn("vif0 Ending with %x QWC left", vif0ch.qwc);
|
||||
if (vif0.cmd != 0) Console.WriteLn("vif0.cmd still set %x tag size %x", vif0.cmd, vif0.tag.size);
|
||||
#endif
|
||||
|
||||
|
@ -278,34 +267,37 @@ void dmaVIF0()
|
|||
|
||||
g_vif0Cycles = 0;
|
||||
|
||||
|
||||
if ((vif0ch.chcr.MOD == NORMAL_MODE) || vif0ch.qwc > 0) // Normal Mode
|
||||
if (vif0ch.qwc > 0) // Normal Mode
|
||||
{
|
||||
vif0.dmamode = VIF_NORMAL_TO_MEM_MODE;
|
||||
if (vif0ch.chcr.MOD == CHAIN_MODE)
|
||||
{
|
||||
vif0.dmamode = VIF_CHAIN_MODE;
|
||||
|
||||
if(vif0.irqoffset.enabled == true && vif0.done == false)
|
||||
if ((vif0ch.chcr.tag().ID == TAG_REFE) || (vif0ch.chcr.tag().ID == TAG_END) || (vif0ch.chcr.tag().IRQ && vif0ch.chcr.TIE))
|
||||
{
|
||||
if(vif0ch.chcr.MOD == NORMAL_MODE)DevCon.Warning("Warning! VIF0 starting a new Normal transfer with vif offset set (Possible force stop?)");
|
||||
else if(vif0ch.qwc == 0) DevCon.Warning("Warning! VIF0 starting a new Chain transfer with vif offset set (Possible force stop?)");
|
||||
vif0.done = true;
|
||||
}
|
||||
|
||||
vif0.done = false;
|
||||
|
||||
if(vif0ch.chcr.MOD == CHAIN_MODE && vif0ch.qwc > 0)
|
||||
else
|
||||
{
|
||||
vif0.dmamode = VIF_CHAIN_MODE;
|
||||
DevCon.Warning(L"VIF0 QWC on Chain CHCR " + vif0ch.chcr.desc());
|
||||
|
||||
if ((vif0ch.chcr.tag().ID == TAG_REFE) || (vif0ch.chcr.tag().ID == TAG_END))
|
||||
{
|
||||
vif0.done = true;
|
||||
}
|
||||
vif0.done = false;
|
||||
}
|
||||
}
|
||||
else //Assume Normal mode.
|
||||
{
|
||||
vif0.dmamode = VIF_NORMAL_FROM_MEM_MODE;
|
||||
|
||||
if (vif0.irqoffset.enabled == true && vif0.done == false) DevCon.Warning("Warning! VIF0 starting a Normal transfer with vif offset set (Possible force stop?)");
|
||||
vif0.done = true;
|
||||
}
|
||||
|
||||
vif0.inprogress |= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vif0.irqoffset.enabled == true && vif0.done == false) DevCon.Warning("Warning! VIF0 starting a new Chain transfer with vif offset set (Possible force stop?)");
|
||||
vif0.dmamode = VIF_CHAIN_MODE;
|
||||
vif0.done = false;
|
||||
vif0.inprogress &= ~0x1;
|
||||
}
|
||||
|
||||
vif0Regs.stat.FQC = min((u16)0x8, vif0ch.qwc);
|
||||
|
|
|
@ -136,84 +136,81 @@ __fi void vif1SetupTransfer()
|
|||
{
|
||||
tDMA_TAG *ptag;
|
||||
|
||||
switch (vif1.dmamode)
|
||||
ptag = dmaGetAddr(vif1ch.tadr, false); //Set memory pointer to TADR
|
||||
|
||||
if (!(vif1ch.transfer("Vif1 Tag", ptag))) return;
|
||||
|
||||
vif1ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
g_vif1Cycles += 1; // Add 1 g_vifCycles from the QW read for the tag
|
||||
vif1.inprogress &= ~1;
|
||||
|
||||
VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx",
|
||||
ptag[1]._u32, ptag[0]._u32, vif1ch.qwc, ptag->ID, vif1ch.madr, vif1ch.tadr);
|
||||
|
||||
if (!vif1.done && ((dmacRegs.ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1
|
||||
{
|
||||
case VIF_CHAIN_MODE:
|
||||
ptag = dmaGetAddr(vif1ch.tadr, false); //Set memory pointer to TADR
|
||||
|
||||
if (!(vif1ch.transfer("Vif1 Tag", ptag))) return;
|
||||
|
||||
vif1ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR
|
||||
g_vif1Cycles += 1; // Add 1 g_vifCycles from the QW read for the tag
|
||||
|
||||
VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx",
|
||||
ptag[1]._u32, ptag[0]._u32, vif1ch.qwc, ptag->ID, vif1ch.madr, vif1ch.tadr);
|
||||
|
||||
if (!vif1.done && ((dmacRegs.ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1
|
||||
{
|
||||
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
|
||||
if ((vif1ch.madr + vif1ch.qwc * 16) >= dmacRegs.stadr.ADDR)
|
||||
{
|
||||
// stalled
|
||||
hwDmacIrq(DMAC_STALL_SIS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
|
||||
if ((vif1ch.madr + vif1ch.qwc * 16) >= dmacRegs.stadr.ADDR)
|
||||
{
|
||||
//DevCon.Warning("VIF1 DMA Stall");
|
||||
// stalled
|
||||
hwDmacIrq(DMAC_STALL_SIS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vif1.inprogress &= ~1;
|
||||
|
||||
if (vif1ch.chcr.TTE)
|
||||
{
|
||||
// Transfer dma tag if tte is set
|
||||
|
||||
bool ret;
|
||||
if (vif1ch.chcr.TTE)
|
||||
{
|
||||
// Transfer dma tag if tte is set
|
||||
|
||||
static __aligned16 u128 masked_tag;
|
||||
bool ret;
|
||||
|
||||
masked_tag._u64[0] = 0;
|
||||
masked_tag._u64[1] = *((u64*)ptag + 1);
|
||||
static __aligned16 u128 masked_tag;
|
||||
|
||||
VIF_LOG("\tVIF1 SrcChain TTE=1, data = 0x%08x.%08x", masked_tag._u32[3], masked_tag._u32[2]);
|
||||
masked_tag._u64[0] = 0;
|
||||
masked_tag._u64[1] = *((u64*)ptag + 1);
|
||||
|
||||
if (vif1.irqoffset.enabled)
|
||||
{
|
||||
ret = VIF1transfer((u32*)&masked_tag + vif1.irqoffset.value, 4 - vif1.irqoffset.value, true); //Transfer Tag on stall
|
||||
//ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset); //Transfer Tag on stall
|
||||
}
|
||||
else
|
||||
{
|
||||
//Some games (like killzone) do Tags mid unpack, the nops will just write blank data
|
||||
//to the VU's, which breaks stuff, this is where the 128bit packet will fail, so we ignore the first 2 words
|
||||
vif1.irqoffset.value = 2;
|
||||
vif1.irqoffset.enabled = true;
|
||||
ret = VIF1transfer((u32*)&masked_tag + 2, 2, true); //Transfer Tag
|
||||
//ret = VIF1transfer((u32*)ptag + 2, 2); //Transfer Tag
|
||||
}
|
||||
VIF_LOG("\tVIF1 SrcChain TTE=1, data = 0x%08x.%08x", masked_tag._u32[3], masked_tag._u32[2]);
|
||||
|
||||
if (!ret && vif1.irqoffset.enabled)
|
||||
{
|
||||
vif1.inprogress &= ~1; //Better clear this so it has to do it again (Jak 1)
|
||||
return; //IRQ set by VIFTransfer
|
||||
}
|
||||
}
|
||||
vif1.irqoffset.value = 0;
|
||||
vif1.irqoffset.enabled = false;
|
||||
if (vif1.irqoffset.enabled)
|
||||
{
|
||||
ret = VIF1transfer((u32*)&masked_tag + vif1.irqoffset.value, 4 - vif1.irqoffset.value, true); //Transfer Tag on stall
|
||||
//ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset); //Transfer Tag on stall
|
||||
}
|
||||
else
|
||||
{
|
||||
//Some games (like killzone) do Tags mid unpack, the nops will just write blank data
|
||||
//to the VU's, which breaks stuff, this is where the 128bit packet will fail, so we ignore the first 2 words
|
||||
vif1.irqoffset.value = 2;
|
||||
vif1.irqoffset.enabled = true;
|
||||
ret = VIF1transfer((u32*)&masked_tag + 2, 2, true); //Transfer Tag
|
||||
//ret = VIF1transfer((u32*)ptag + 2, 2); //Transfer Tag
|
||||
}
|
||||
|
||||
vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID);
|
||||
if (!ret && vif1.irqoffset.enabled)
|
||||
{
|
||||
vif1.inprogress &= ~1; //Better clear this so it has to do it again (Jak 1)
|
||||
return; //IRQ set by VIFTransfer
|
||||
}
|
||||
}
|
||||
vif1.irqoffset.value = 0;
|
||||
vif1.irqoffset.enabled = false;
|
||||
|
||||
if(vif1ch.qwc > 0) vif1.inprogress |= 1;
|
||||
vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID);
|
||||
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (vif1ch.chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
VIF_LOG("dmaIrq Set");
|
||||
if(vif1ch.qwc > 0) vif1.inprogress |= 1;
|
||||
|
||||
//End Transfer
|
||||
vif1.done = true;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (vif1ch.chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
VIF_LOG("dmaIrq Set");
|
||||
|
||||
//End Transfer
|
||||
vif1.done = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -433,7 +430,7 @@ void dmaVIF1()
|
|||
vif1.dmamode = VIF_CHAIN_MODE;
|
||||
//DevCon.Warning(L"VIF1 QWC on Chain CHCR " + vif1ch.chcr.desc());
|
||||
|
||||
if ((vif1ch.chcr.tag().ID == TAG_REFE) || (vif1ch.chcr.tag().ID == TAG_END))
|
||||
if ((vif1ch.chcr.tag().ID == TAG_REFE) || (vif1ch.chcr.tag().ID == TAG_END) || (vif1ch.chcr.tag().IRQ && vif1ch.chcr.TIE))
|
||||
{
|
||||
vif1.done = true;
|
||||
}
|
||||
|
@ -445,9 +442,9 @@ void dmaVIF1()
|
|||
else //Assume normal mode for reverse FIFO and Normal.
|
||||
{
|
||||
if (dmacRegs.ctrl.STD == STD_VIF1)
|
||||
Console.WriteLn("DMA Stall Control on VIF1 normal");
|
||||
Console.WriteLn("DMA Stall Control on VIF1 normal not implemented - Report which game to PCSX2 Team");
|
||||
|
||||
if (vif1ch.chcr.DIR) // to Memory
|
||||
if (vif1ch.chcr.DIR) // from Memory
|
||||
vif1.dmamode = VIF_NORMAL_FROM_MEM_MODE;
|
||||
else
|
||||
vif1.dmamode = VIF_NORMAL_TO_MEM_MODE;
|
||||
|
|
|
@ -202,6 +202,11 @@ void mfifoVIF1transfer(int qwc)
|
|||
vif1ch.tadr = qwctag(vif1ch.tadr);
|
||||
ptag = dmaGetAddr(vif1ch.tadr, false);
|
||||
|
||||
if (dmacRegs.ctrl.STD == STD_VIF1 && (ptag->ID == TAG_REFS))
|
||||
{
|
||||
Console.WriteLn("VIF MFIFO DMA Stall not implemented - Report which game to PCSX2 Team");
|
||||
}
|
||||
|
||||
if (vif1ch.chcr.TTE)
|
||||
{
|
||||
bool ret;
|
||||
|
|
|
@ -93,7 +93,7 @@ _vifT static __fi bool vifTransfer(u32 *data, int size, bool TTE) {
|
|||
vifXch.madr +=(transferred << 4);
|
||||
vifXch.qwc -= transferred;
|
||||
|
||||
if (vifXch.chcr.STR) hwDmacSrcTadrInc(vifXch);
|
||||
hwDmacSrcTadrInc(vifXch);
|
||||
|
||||
vifX.irqoffset.enabled = false;
|
||||
|
||||
|
|
|
@ -33,14 +33,14 @@ s32 PrepareEERead()
|
|||
"\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)));
|
||||
sif0dma.madr = tag[1];
|
||||
sif0ch.unsafeTransfer(((tDMA_TAG*)(tag)));
|
||||
sif0ch.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]);
|
||||
sif0ch.madr, sif0ch.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);
|
||||
|
||||
if (sif0dma.chcr.TIE && ptag.IRQ)
|
||||
if (sif0ch.chcr.TIE && ptag.IRQ)
|
||||
{
|
||||
//Console.WriteLn("SIF0 TIE");
|
||||
sif0.ee.end = true;
|
||||
|
@ -51,12 +51,12 @@ s32 PrepareEERead()
|
|||
case TAG_REFE:
|
||||
sif0.ee.end = true;
|
||||
if (dmacRegs.ctrl.STS != NO_STS)
|
||||
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
|
||||
dmacRegs.stadr.ADDR = sif0ch.madr + (sif0ch.qwc * 16);
|
||||
break;
|
||||
|
||||
case TAG_REFS:
|
||||
if (dmacRegs.ctrl.STS != NO_STS)
|
||||
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
|
||||
dmacRegs.stadr.ADDR = sif0ch.madr + (sif0ch.qwc * 16);
|
||||
break;
|
||||
|
||||
case TAG_END:
|
||||
|
@ -91,7 +91,7 @@ s32 DoSifRead(u32 iopAvailable)
|
|||
|
||||
SIF_LOG("Write IOP to EE: +++++++++++ %lX of %lX", transferSizeWords, sif0.iop.counter);
|
||||
|
||||
tDMA_TAG *ptag = sif0dma.getAddr(sif0dma.madr, DMAC_SIF0, true);
|
||||
tDMA_TAG *ptag = sif0ch.getAddr(sif0ch.madr, DMAC_SIF0, true);
|
||||
if (ptag == NULL)
|
||||
{
|
||||
DevCon.Warning("Write IOP to EE: ptag == NULL");
|
||||
|
@ -101,11 +101,11 @@ s32 DoSifRead(u32 iopAvailable)
|
|||
memcpy((u32*)ptag, (u32*)iopPhysMem(hw_dma9.madr), transferSizeBytes);
|
||||
|
||||
// Clearing handled by vtlb memory protection and manual blocks.
|
||||
//Cpu->Clear(sif0dma.madr, readSize*4);
|
||||
//Cpu->Clear(sif0ch.madr, readSize*4);
|
||||
|
||||
sif0dma.madr += transferSizeBytes;
|
||||
sif0ch.madr += transferSizeBytes;
|
||||
sif0.ee.cycles += transferSizeQWords * 2;
|
||||
sif0dma.qwc -= transferSizeQWords;
|
||||
sif0ch.qwc -= transferSizeQWords;
|
||||
|
||||
return transferSizeBytes;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue