mirror of https://github.com/PCSX2/pcsx2.git
Fix for Eternal Poison video (really this time :P)
There is a current issue with IPU causing videos to cut short, going to need to spend some time checking this git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2863 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
6382f6811b
commit
d4d4d78c39
|
@ -62,9 +62,10 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value )
|
||||||
tDMA_CHCR chcr(value);
|
tDMA_CHCR chcr(value);
|
||||||
|
|
||||||
//It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
|
//It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
|
||||||
|
|
||||||
if (chcr.STR && reg->chcr.STR && dmacRegs->ctrl.DMAE) {
|
if (chcr.STR && reg->chcr.STR && dmacRegs->ctrl.DMAE) {
|
||||||
if((reg->chcr._u32 & 0xff) == (chcr._u32 & 0xff) && psHu8(DMAC_ENABLER+2) == 0) //Tried to start another DMA in the same mode
|
if((reg->chcr._u32 & 0xff) == (chcr._u32 & 0xff) && psHu8(DMAC_ENABLER+2) == 0) //Tried to start another DMA in the same mode
|
||||||
DevCon.Warning(L"DMAExec32 Attempt to run DMA while one is already active in %s(%x)", ChcrName(mem), mem);
|
DevCon.Warning(L"DMAExec16 Attempt to run DMA while one is already active in %s(%x)", ChcrName(mem), mem);
|
||||||
else //Just trying to change mode without stopping the DMA, so we dont care really :P
|
else //Just trying to change mode without stopping the DMA, so we dont care really :P
|
||||||
{
|
{
|
||||||
HW_LOG("Attempted to change modes while DMA active, ignoring");
|
HW_LOG("Attempted to change modes while DMA active, ignoring");
|
||||||
|
@ -76,6 +77,19 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//This should be more correct, but the FFX video does some WIERD stuff and tries to stop and restart the IPU without suspending
|
||||||
|
/*if (reg->chcr.STR) {
|
||||||
|
if(psHu8(DMAC_ENABLER+2) == 0) // DMA Not in suspend mode
|
||||||
|
{
|
||||||
|
DevCon.Warning(L"DMAExec16 Attempt to alter DMA While not Suspended %s(%x) Current Val %x New Val %x", ChcrName(mem), mem, reg->chcr._u32, value);
|
||||||
|
// When DMA is active only STR field is writable, so we just
|
||||||
|
// call the dma transfer function w/o modifying CHCR contents...
|
||||||
|
//func();
|
||||||
|
Registers::Thaw();
|
||||||
|
return; // Test with Gust games and fatal frame
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
// Note: pad is the padding right above qwc, so we're testing whether qwc
|
// Note: pad is the padding right above qwc, so we're testing whether qwc
|
||||||
// has overflowed into pad.
|
// has overflowed into pad.
|
||||||
// Note2: May be only needed for IPU which has this handling in IPU.cpp now. (Fixes GS transfers)
|
// Note2: May be only needed for IPU which has this handling in IPU.cpp now. (Fixes GS transfers)
|
||||||
|
@ -117,6 +131,19 @@ static void DmaExec( void (*func)(), u32 mem, u32 value )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//This should be more correct, but the FFX video does some WIERD stuff and tries to stop and restart the IPU without suspending
|
||||||
|
/*if (reg->chcr.STR) {
|
||||||
|
if(psHu8(DMAC_ENABLER+2) == 0) // DMA Not in suspend mode
|
||||||
|
{
|
||||||
|
DevCon.Warning(L"DMAExec32 Attempt to alter DMA While not Suspended %s(%x) Current Val %x New Val %x", ChcrName(mem), mem, reg->chcr._u32, value);
|
||||||
|
// When DMA is active only STR field is writable, so we just
|
||||||
|
// call the dma transfer function w/o modifying CHCR contents...
|
||||||
|
//func();
|
||||||
|
Registers::Thaw();
|
||||||
|
return; // Test with Gust games and fatal frame
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
// Note: pad is the padding right above qwc, so we're testing whether qwc
|
// Note: pad is the padding right above qwc, so we're testing whether qwc
|
||||||
// has overflowed into pad.
|
// has overflowed into pad.
|
||||||
// Note2: May be only needed for IPU which has this handling in IPU.cpp now. (Fixes GS transfers)
|
// Note2: May be only needed for IPU which has this handling in IPU.cpp now. (Fixes GS transfers)
|
||||||
|
|
|
@ -1251,42 +1251,40 @@ static __forceinline void ipuDmacSrcChain()
|
||||||
{
|
{
|
||||||
case 0x0: // refe
|
case 0x0: // refe
|
||||||
//if(IPU1Status.InProgress == false) ipu1dma->tadr += 16;
|
//if(IPU1Status.InProgress == false) ipu1dma->tadr += 16;
|
||||||
if(ipu1dma->qwc == 0) IPU1Status.DMAFinished = true;
|
if(ipu1dma->qwc == 0 && IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = true;
|
||||||
break;
|
break;
|
||||||
case 0x1: // cnt
|
case 0x1: // cnt
|
||||||
// Set the taddr to the next tag
|
// Set the taddr to the next tag
|
||||||
ipu1dma->tadr = ipu1dma->madr;
|
ipu1dma->tadr = ipu1dma->madr;
|
||||||
if(ipu1dma->qwc == 0) IPU1Status.DMAFinished = false;
|
if(ipu1dma->qwc == 0 && IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x2: // next
|
case 0x2: // next
|
||||||
ipu1dma->tadr = IPU1Status.NextMem;
|
ipu1dma->tadr = IPU1Status.NextMem;
|
||||||
if(ipu1dma->qwc == 0) IPU1Status.DMAFinished = false;
|
if(ipu1dma->qwc == 0 && IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3: // ref
|
case 0x3: // ref
|
||||||
//if(IPU1Status.InProgress == false)ipu1dma->tadr += 16;
|
//if(IPU1Status.InProgress == false)ipu1dma->tadr += 16;
|
||||||
if(ipu1dma->qwc == 0) IPU1Status.DMAFinished = false;
|
if(ipu1dma->qwc == 0 && IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x7: // end
|
case 0x7: // end
|
||||||
ipu1dma->tadr = ipu1dma->madr;
|
ipu1dma->tadr = ipu1dma->madr;
|
||||||
if(ipu1dma->qwc == 0) IPU1Status.DMAFinished = true;
|
if(ipu1dma->qwc == 0 && IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static __forceinline bool WaitGSPaths()
|
static __forceinline bool WaitGSPaths()
|
||||||
{
|
{
|
||||||
if (dmacRegs->ctrl.STD != STD_GIF || (gif->madr + (gif->qwc * 16)) < dmacRegs->stadr.ADDR)
|
if(GSTransferStatus.PTH3 < STOPPED_MODE)
|
||||||
{
|
{
|
||||||
if(gif->chcr.STR && (vif1Regs->mskpath3 == 0) && GSTransferStatus.PTH3 != STOPPED_MODE)
|
//GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr._u32, gif->tadr, gif->madr, gif->qwc);
|
||||||
{
|
|
||||||
GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr._u32, gif->tadr, gif->madr, gif->qwc);
|
|
||||||
//DevCon.WriteLn("Waiting for GIF");
|
//DevCon.WriteLn("Waiting for GIF");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(GSTransferStatus.PTH2 != STOPPED_MODE)
|
if(GSTransferStatus.PTH2 != STOPPED_MODE)
|
||||||
{
|
{
|
||||||
//DevCon.WriteLn("Waiting for VIF");
|
//DevCon.WriteLn("Waiting for VIF");
|
||||||
|
@ -1344,7 +1342,7 @@ static __forceinline int IPU1chain() {
|
||||||
// if (GSTransferStatus._u32 != 0x2a)
|
// if (GSTransferStatus._u32 != 0x2a)
|
||||||
// {
|
// {
|
||||||
// if(GSTransferStatus.PTH3 != STOPPED_MODE && vif1Regs->mskpath3) return true;
|
// if(GSTransferStatus.PTH3 != STOPPED_MODE && vif1Regs->mskpath3) return true;
|
||||||
// DMA_LOG("Waiting for GS transfers to finish %x", GSTransferStatus._u32);
|
// IPU_LOG("Waiting for GS transfers to finish %x", GSTransferStatus._u32);
|
||||||
// IPU_INT_TO(4);
|
// IPU_INT_TO(4);
|
||||||
// return false;
|
// return false;
|
||||||
// }
|
// }
|
||||||
|
@ -1364,7 +1362,7 @@ int IPU1dma()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DMA_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", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma->tadr);
|
||||||
|
|
||||||
switch(IPU1Status.DMAMode)
|
switch(IPU1Status.DMAMode)
|
||||||
{
|
{
|
||||||
|
@ -1375,7 +1373,7 @@ int IPU1dma()
|
||||||
IPU_INT_TO(4); //Give it a short wait.
|
IPU_INT_TO(4); //Give it a short wait.
|
||||||
return totalqwc;
|
return totalqwc;
|
||||||
}
|
}
|
||||||
DMA_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", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress);
|
||||||
if(IPU1Status.InProgress == true) totalqwc += IPU1chain();
|
if(IPU1Status.InProgress == true) totalqwc += IPU1chain();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1389,7 +1387,7 @@ int IPU1dma()
|
||||||
IPU_INT_TO(4); //Give it a short wait.
|
IPU_INT_TO(4); //Give it a short wait.
|
||||||
return totalqwc;
|
return totalqwc;
|
||||||
}
|
}
|
||||||
DMA_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", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress);
|
||||||
totalqwc += IPU1chain();
|
totalqwc += IPU1chain();
|
||||||
//Set the TADR forward
|
//Set the TADR forward
|
||||||
ipuDmacSrcChain();
|
ipuDmacSrcChain();
|
||||||
|
@ -1425,13 +1423,13 @@ int IPU1dma()
|
||||||
//ipu1dma->tadr += 16;
|
//ipu1dma->tadr += 16;
|
||||||
ipu1dma->tadr += 16;
|
ipu1dma->tadr += 16;
|
||||||
ipu1dma->madr = ptag[1];
|
ipu1dma->madr = ptag[1];
|
||||||
DMA_LOG("Tag should end on %x", ipu1dma->tadr);
|
IPU_LOG("Tag should end on %x", ipu1dma->tadr);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1: // cnt
|
case 0x1: // cnt
|
||||||
ipu1dma->madr = ipu1dma->tadr + 16;
|
ipu1dma->madr = ipu1dma->tadr + 16;
|
||||||
DMA_LOG("Tag should end on %x", ipu1dma->madr + ipu1dma->qwc * 16);
|
IPU_LOG("Tag should end on %x", ipu1dma->madr + ipu1dma->qwc * 16);
|
||||||
//ipu1dma->tadr = ipu1dma->madr + (ipu1dma->qwc * 16);
|
//ipu1dma->tadr = ipu1dma->madr + (ipu1dma->qwc * 16);
|
||||||
// Set the taddr to the next tag
|
// Set the taddr to the next tag
|
||||||
//IPU1Status.DMAFinished = false;
|
//IPU1Status.DMAFinished = false;
|
||||||
|
@ -1440,14 +1438,14 @@ int IPU1dma()
|
||||||
case 0x2: // next
|
case 0x2: // next
|
||||||
ipu1dma->madr = ipu1dma->tadr + 16;
|
ipu1dma->madr = ipu1dma->tadr + 16;
|
||||||
IPU1Status.NextMem = ptag[1];
|
IPU1Status.NextMem = ptag[1];
|
||||||
DMA_LOG("Tag should end on %x", IPU1Status.NextMem);
|
IPU_LOG("Tag should end on %x", IPU1Status.NextMem);
|
||||||
//IPU1Status.DMAFinished = false;
|
//IPU1Status.DMAFinished = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3: // ref
|
case 0x3: // ref
|
||||||
ipu1dma->madr = ptag[1];
|
ipu1dma->madr = ptag[1];
|
||||||
ipu1dma->tadr += 16;
|
ipu1dma->tadr += 16;
|
||||||
DMA_LOG("Tag should end on %x", ipu1dma->tadr);
|
IPU_LOG("Tag should end on %x", ipu1dma->tadr);
|
||||||
//IPU1Status.DMAFinished = false;
|
//IPU1Status.DMAFinished = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1455,7 +1453,7 @@ int IPU1dma()
|
||||||
// do not change tadr
|
// do not change tadr
|
||||||
ipu1dma->madr = ipu1dma->tadr + 16;
|
ipu1dma->madr = ipu1dma->tadr + 16;
|
||||||
ipu1dma->tadr += 16;
|
ipu1dma->tadr += 16;
|
||||||
DMA_LOG("Tag should end on %x", ipu1dma->madr + ipu1dma->qwc * 16);
|
IPU_LOG("Tag should end on %x", ipu1dma->madr + ipu1dma->qwc * 16);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1466,10 +1464,10 @@ int IPU1dma()
|
||||||
|
|
||||||
//if(ipu1dma->qwc == 0) Console.Warning("Blank QWC!");
|
//if(ipu1dma->qwc == 0) Console.Warning("Blank QWC!");
|
||||||
if(ipu1dma->qwc > 0) IPU1Status.InProgress = true;
|
if(ipu1dma->qwc > 0) IPU1Status.InProgress = true;
|
||||||
DMA_LOG("dmaIPU1 dmaChain %8.8x_%8.8x size=%d, addr=%lx, fifosize=%x",
|
IPU_LOG("dmaIPU1 dmaChain %8.8x_%8.8x size=%d, addr=%lx, fifosize=%x",
|
||||||
ptag[1], ptag[0], ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC);
|
ptag[1], ptag[0], ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC);
|
||||||
|
|
||||||
if ((ipu1dma->chcr._u32 & 0x80) && ptag[0] & 0x80000000) //Tag Interrupt is set, so schedule the end/interrupt
|
if (ipu1dma->chcr.TIE && (ptag[0] & 0x80000000)) //Tag Interrupt is set, so schedule the end/interrupt
|
||||||
IPU1Status.DMAFinished = true;
|
IPU1Status.DMAFinished = true;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1478,7 +1476,7 @@ int IPU1dma()
|
||||||
IPU_INT_TO(4); //Give it a short wait.
|
IPU_INT_TO(4); //Give it a short wait.
|
||||||
return totalqwc;
|
return totalqwc;
|
||||||
}
|
}
|
||||||
DMA_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", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress);
|
||||||
totalqwc += IPU1chain();
|
totalqwc += IPU1chain();
|
||||||
//Set the TADR forward
|
//Set the TADR forward
|
||||||
ipuDmacSrcChain();
|
ipuDmacSrcChain();
|
||||||
|
@ -1567,10 +1565,10 @@ __forceinline void dmaIPU0() // fromIPU
|
||||||
|
|
||||||
__forceinline void dmaIPU1() // toIPU
|
__forceinline void dmaIPU1() // toIPU
|
||||||
{
|
{
|
||||||
|
IPU_LOG("IPU1DMAStart QWC %x, MADR %x, CHCR %x, TADR %x", ipu1dma->qwc, ipu1dma->madr, ipu1dma->chcr._u32, ipu1dma->tadr);
|
||||||
if(ipu1dma->chcr.MOD == 1) //Chain Mode
|
if(ipu1dma->chcr.MOD == 1) //Chain Mode
|
||||||
{
|
{
|
||||||
DMA_LOG("Setting up IPU1 Chain mode");
|
IPU_LOG("Setting up IPU1 Chain mode");
|
||||||
if(ipu1dma->qwc == 0)
|
if(ipu1dma->qwc == 0)
|
||||||
{
|
{
|
||||||
IPU1Status.InProgress = false;
|
IPU1Status.InProgress = false;
|
||||||
|
@ -1603,7 +1601,7 @@ __forceinline void dmaIPU1() // toIPU
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DMA_LOG("Setting up IPU1 Normal mode");
|
IPU_LOG("Setting up IPU1 Normal mode");
|
||||||
IPU1Status.InProgress = true;
|
IPU1Status.InProgress = true;
|
||||||
IPU1Status.DMAFinished = true;
|
IPU1Status.DMAFinished = true;
|
||||||
IPU1Status.DMAMode = DMA_MODE_NORMAL;
|
IPU1Status.DMAMode = DMA_MODE_NORMAL;
|
||||||
|
@ -1628,6 +1626,7 @@ void ipu0Interrupt()
|
||||||
if (g_nDMATransfer.GIFSTALL)
|
if (g_nDMATransfer.GIFSTALL)
|
||||||
{
|
{
|
||||||
// gif
|
// gif
|
||||||
|
Console.Warning("IPU GIF Stall");
|
||||||
g_nDMATransfer.GIFSTALL = false;
|
g_nDMATransfer.GIFSTALL = false;
|
||||||
//if (gif->chcr.STR) GIFdma();
|
//if (gif->chcr.STR) GIFdma();
|
||||||
}
|
}
|
||||||
|
@ -1635,6 +1634,7 @@ void ipu0Interrupt()
|
||||||
if (g_nDMATransfer.VIFSTALL)
|
if (g_nDMATransfer.VIFSTALL)
|
||||||
{
|
{
|
||||||
// vif
|
// vif
|
||||||
|
Console.Warning("IPU VIF Stall");
|
||||||
g_nDMATransfer.VIFSTALL = false;
|
g_nDMATransfer.VIFSTALL = false;
|
||||||
if (vif1ch->chcr.STR) dmaVIF1();
|
if (vif1ch->chcr.STR) dmaVIF1();
|
||||||
}
|
}
|
||||||
|
@ -1642,6 +1642,7 @@ void ipu0Interrupt()
|
||||||
if (g_nDMATransfer.SIFSTALL)
|
if (g_nDMATransfer.SIFSTALL)
|
||||||
{
|
{
|
||||||
// sif
|
// sif
|
||||||
|
Console.Warning("IPU SIF Stall");
|
||||||
g_nDMATransfer.SIFSTALL = false;
|
g_nDMATransfer.SIFSTALL = false;
|
||||||
|
|
||||||
// Not totally sure whether this needs to be done or not, so I'm
|
// Not totally sure whether this needs to be done or not, so I'm
|
||||||
|
@ -1660,7 +1661,7 @@ void ipu0Interrupt()
|
||||||
|
|
||||||
IPU_FORCEINLINE void ipu1Interrupt()
|
IPU_FORCEINLINE void ipu1Interrupt()
|
||||||
{
|
{
|
||||||
DMA_LOG("ipu1Interrupt %x:", cpuRegs.cycle);
|
IPU_LOG("ipu1Interrupt %x:", cpuRegs.cycle);
|
||||||
|
|
||||||
if(IPU1Status.DMAFinished == false || IPU1Status.InProgress == true) //Sanity Check
|
if(IPU1Status.DMAFinished == false || IPU1Status.InProgress == true) //Sanity Check
|
||||||
{
|
{
|
||||||
|
@ -1670,9 +1671,6 @@ IPU_FORCEINLINE void ipu1Interrupt()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Console.Warning("Whoops");
|
|
||||||
|
|
||||||
|
|
||||||
ipu1dma->chcr.STR = false;
|
ipu1dma->chcr.STR = false;
|
||||||
hwDmacIrq(DMAC_TO_IPU);
|
hwDmacIrq(DMAC_TO_IPU);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue