mirror of https://github.com/PCSX2/pcsx2.git
IPU: Set DMA to only transfer on request (or reset)
This commit is contained in:
parent
1695124472
commit
d775a9364b
|
@ -296,7 +296,7 @@ void ipuSoftReset()
|
|||
ipu_cmd.clear();
|
||||
ipuRegs.cmd.BUSY = 0;
|
||||
ipuRegs.cmd.DATA = 0; // required for Enthusia - Professional Racing after fix, or will freeze at start of next video.
|
||||
|
||||
IPU1Status.DataRequested = true;
|
||||
memzero(g_BP);
|
||||
hwIntcIrq(INTC_IPU); // required for FightBox
|
||||
}
|
||||
|
@ -363,14 +363,12 @@ __fi bool ipuWrite64(u32 mem, u64 value)
|
|||
|
||||
static void ipuBCLR(u32 val)
|
||||
{
|
||||
// The Input FIFO shouldn't be cleared when the DMA is running, however if it is the DMA should drain
|
||||
// as it is constantly fighting it....
|
||||
while(ipu1ch.chcr.STR)
|
||||
{
|
||||
ipu_fifo.in.clear();
|
||||
if (ipu1ch.chcr.STR && g_BP.IFC < 8 && IPU1Status.DataRequested)
|
||||
ipu1Interrupt();
|
||||
}
|
||||
|
||||
|
||||
if(!ipu1ch.chcr.STR)
|
||||
psHu32(DMAC_STAT) &= ~(1 << DMAC_TO_IPU);
|
||||
|
||||
ipu_fifo.in.clear();
|
||||
|
||||
memzero(g_BP);
|
||||
|
@ -878,6 +876,12 @@ __fi void IPUCMD_WRITE(u32 val)
|
|||
ipuBCLR(val);
|
||||
hwIntcIrq(INTC_IPU); //DMAC_TO_IPU
|
||||
ipuRegs.ctrl.BUSY = 0;
|
||||
|
||||
IPU1Status.DataRequested = true;
|
||||
if (ipu1ch.chcr.STR && cpuRegs.eCycle[4] == 0x9999)
|
||||
{
|
||||
CPU_INT(DMAC_TO_IPU, 32);
|
||||
}
|
||||
return;
|
||||
|
||||
case SCE_IPU_SETTH:
|
||||
|
@ -1005,10 +1009,4 @@ __noinline void IPUWorker()
|
|||
ipuRegs.ctrl.BUSY = 0;
|
||||
//ipu_cmd.current = 0xffffffff;
|
||||
hwIntcIrq(INTC_IPU);
|
||||
|
||||
// Fill the FIFO ready for the next command
|
||||
if (ipu1ch.chcr.STR && cpuRegs.eCycle[4] == 0x9999)
|
||||
{
|
||||
CPU_INT(DMAC_TO_IPU, 32);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "IPU_Fifo.h"
|
||||
#include "IPUdma.h"
|
||||
|
||||
#define ipumsk( src ) ( (src) & 0xff )
|
||||
#define ipucase( src ) case ipumsk(src)
|
||||
|
|
|
@ -85,11 +85,12 @@ int IPU_Fifo_Input::write(u32* pMem, int size)
|
|||
int IPU_Fifo_Input::read(void *value)
|
||||
{
|
||||
// wait until enough data to ensure proper streaming.
|
||||
if (g_BP.IFC < 3)
|
||||
if (g_BP.IFC <= 1)
|
||||
{
|
||||
// IPU FIFO is empty and DMA is waiting so lets tell the DMA we are ready to put data in the FIFO
|
||||
if(cpuRegs.eCycle[4] == 0x9999)
|
||||
{
|
||||
IPU1Status.DataRequested = true;
|
||||
CPU_INT( DMAC_TO_IPU, 32 );
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "IPU/IPUdma.h"
|
||||
#include "mpeg2lib/Mpeg.h"
|
||||
|
||||
static IPUStatus IPU1Status;
|
||||
IPUStatus IPU1Status;
|
||||
static tIPU_DMA g_nDMATransfer;
|
||||
|
||||
void ipuDmaReset()
|
||||
|
@ -119,6 +119,13 @@ int IPU1dma()
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (IPU1Status.DataRequested == false)
|
||||
{
|
||||
cpuRegs.eCycle[4] = 0x9999;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
|
@ -174,16 +181,27 @@ int IPU1dma()
|
|||
}
|
||||
|
||||
//Do this here to prevent double settings on Chain DMA's
|
||||
if(totalqwc > 0 || ipu1ch.qwc == 0)
|
||||
if(totalqwc == 0 || (IPU1Status.DMAFinished && !IPU1Status.InProgress))
|
||||
{
|
||||
IPU_INT_TO(totalqwc * BIAS);
|
||||
IPUProcessInterrupt();
|
||||
totalqwc = std::min(4, totalqwc);
|
||||
IPU_INT_TO(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuRegs.eCycle[4] = 0x9999;//IPU_INT_TO(2048);
|
||||
|
||||
if (g_BP.IFC == 8)
|
||||
{
|
||||
IPU1Status.DataRequested = false;
|
||||
cpuRegs.eCycle[4] = 0x9999;//IPU_INT_TO(2048);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPU_INT_TO(totalqwc*BIAS);
|
||||
}
|
||||
}
|
||||
|
||||
IPUProcessInterrupt();
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -296,7 +314,10 @@ __fi void dmaIPU1() // toIPU
|
|||
}
|
||||
|
||||
IPU1Status.DMAMode = DMA_MODE_CHAIN;
|
||||
IPU1dma();
|
||||
if(ipuRegs.ctrl.BUSY || IPU1Status.DataRequested)
|
||||
IPU1dma();
|
||||
else
|
||||
cpuRegs.eCycle[4] = 0x9999;
|
||||
}
|
||||
else //Normal Mode
|
||||
{
|
||||
|
@ -304,7 +325,10 @@ __fi void dmaIPU1() // toIPU
|
|||
IPU1Status.InProgress = true;
|
||||
IPU1Status.DMAFinished = true;
|
||||
IPU1Status.DMAMode = DMA_MODE_NORMAL;
|
||||
IPU1dma();
|
||||
if (ipuRegs.ctrl.BUSY || IPU1Status.DataRequested)
|
||||
IPU1dma();
|
||||
else
|
||||
cpuRegs.eCycle[4] = 0x9999;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ struct IPUStatus {
|
|||
bool stalled;
|
||||
u8 ChainMode;
|
||||
u32 NextMem;
|
||||
bool DataRequested;
|
||||
};
|
||||
|
||||
#define DMA_MODE_NORMAL 0
|
||||
|
@ -91,3 +92,4 @@ extern void IPU0dma();
|
|||
extern int IPU1dma();
|
||||
|
||||
extern void ipuDmaReset();
|
||||
extern IPUStatus IPU1Status;
|
||||
|
|
Loading…
Reference in New Issue