mirror of https://github.com/PCSX2/pcsx2.git
-Fixed Metal Saga video (which i seemed to have broken with voodoo!! maybe i should see the lady in the voodoo shop, last time i did that she told me i had to fight a fearsome pirate...) ahem, sorry.
-Fixed a Bitstream bug which was annoying me. -Modified a silly long if check with multiple bit shifts, should be a tiny bit quicker. -Various other IPU changes git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2926 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
aae53a9707
commit
35498e329f
|
@ -37,19 +37,11 @@
|
||||||
// IPU Inline'd IRQs : Calls the IPU interrupt handlers directly instead of
|
// IPU Inline'd IRQs : Calls the IPU interrupt handlers directly instead of
|
||||||
// feeding them through the EE's branch test. (see IPU.h for details)
|
// feeding them through the EE's branch test. (see IPU.h for details)
|
||||||
|
|
||||||
#ifdef IPU_INLINE_IRQS
|
|
||||||
# define IPU_INT_TO( cycles ) ipu1Interrupt()
|
|
||||||
# define IPU_INT_FROM( cycles ) ipu0Interrupt()
|
|
||||||
# define IPU_FORCEINLINE
|
|
||||||
#else
|
|
||||||
# define IPU_INT_TO( cycles ) if(!(cpuRegs.interrupt & (1<<4))) CPU_INT( DMAC_TO_IPU, cycles )
|
|
||||||
# define IPU_INT_FROM( cycles ) CPU_INT( DMAC_FROM_IPU, cycles )
|
|
||||||
# define IPU_FORCEINLINE __forceinline
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static tIPU_DMA g_nDMATransfer(0);
|
static tIPU_DMA g_nDMATransfer(0);
|
||||||
static tIPU_cmd ipu_cmd;
|
static tIPU_cmd ipu_cmd;
|
||||||
static IPUStatus IPU1Status;
|
|
||||||
|
|
||||||
// FIXME - g_nIPU0Data and Pointer are not saved in the savestate, which breaks savestates for some
|
// FIXME - g_nIPU0Data and Pointer are not saved in the savestate, which breaks savestates for some
|
||||||
// FMVs at random (if they get saved during the half frame of a 30fps rate). The fix is complicated
|
// FMVs at random (if they get saved during the half frame of a 30fps rate). The fix is complicated
|
||||||
|
@ -799,7 +791,7 @@ void IPUCMD_WRITE(u32 val)
|
||||||
// have to resort to the thread
|
// have to resort to the thread
|
||||||
ipu_cmd.current = val >> 28;
|
ipu_cmd.current = val >> 28;
|
||||||
ipuRegs->ctrl.BUSY = 1;
|
ipuRegs->ctrl.BUSY = 1;
|
||||||
if(ipu1dma->qwc == 0 && ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPUWorker()
|
void IPUWorker()
|
||||||
|
@ -811,7 +803,7 @@ void IPUWorker()
|
||||||
case SCE_IPU_VDEC:
|
case SCE_IPU_VDEC:
|
||||||
if (!ipuVDEC(ipuRegs->cmd.DATA))
|
if (!ipuVDEC(ipuRegs->cmd.DATA))
|
||||||
{
|
{
|
||||||
if(ipu1dma->qwc == 0 && ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ipuRegs->cmd.BUSY = 0;
|
ipuRegs->cmd.BUSY = 0;
|
||||||
|
@ -821,7 +813,7 @@ void IPUWorker()
|
||||||
case SCE_IPU_FDEC:
|
case SCE_IPU_FDEC:
|
||||||
if (!ipuFDEC(ipuRegs->cmd.DATA))
|
if (!ipuFDEC(ipuRegs->cmd.DATA))
|
||||||
{
|
{
|
||||||
if(ipu1dma->qwc == 0 && ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ipuRegs->cmd.BUSY = 0;
|
ipuRegs->cmd.BUSY = 0;
|
||||||
|
@ -831,7 +823,7 @@ void IPUWorker()
|
||||||
case SCE_IPU_SETIQ:
|
case SCE_IPU_SETIQ:
|
||||||
if (!ipuSETIQ(ipuRegs->cmd.DATA))
|
if (!ipuSETIQ(ipuRegs->cmd.DATA))
|
||||||
{
|
{
|
||||||
if(ipu1dma->qwc == 0 && ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -839,7 +831,7 @@ void IPUWorker()
|
||||||
case SCE_IPU_SETVQ:
|
case SCE_IPU_SETVQ:
|
||||||
if (!ipuSETVQ(ipuRegs->cmd.DATA))
|
if (!ipuSETVQ(ipuRegs->cmd.DATA))
|
||||||
{
|
{
|
||||||
if(ipu1dma->qwc == 0 && ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -847,7 +839,7 @@ void IPUWorker()
|
||||||
case SCE_IPU_CSC:
|
case SCE_IPU_CSC:
|
||||||
if (!ipuCSC(ipuRegs->cmd.DATA))
|
if (!ipuCSC(ipuRegs->cmd.DATA))
|
||||||
{
|
{
|
||||||
if(ipu1dma->qwc == 0&& ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM();
|
if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM();
|
||||||
|
@ -856,7 +848,7 @@ void IPUWorker()
|
||||||
case SCE_IPU_PACK:
|
case SCE_IPU_PACK:
|
||||||
if (!ipuPACK(ipuRegs->cmd.DATA))
|
if (!ipuPACK(ipuRegs->cmd.DATA))
|
||||||
{
|
{
|
||||||
if(ipu1dma->qwc == 0 && ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -865,7 +857,7 @@ void IPUWorker()
|
||||||
so_call(s_routine);
|
so_call(s_routine);
|
||||||
if (!s_RoutineDone)
|
if (!s_RoutineDone)
|
||||||
{
|
{
|
||||||
if(ipu1dma->qwc == 0 && ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,7 +876,7 @@ void IPUWorker()
|
||||||
so_call(s_routine);
|
so_call(s_routine);
|
||||||
if (!s_RoutineDone)
|
if (!s_RoutineDone)
|
||||||
{
|
{
|
||||||
if(ipu1dma->qwc == 0 && ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -957,7 +949,8 @@ u16 __fastcall FillInternalBuffer(u32 * pointer, u32 advance, u32 size)
|
||||||
inc_readbits();
|
inc_readbits();
|
||||||
g_BP.FP = 1;
|
g_BP.FP = 1;
|
||||||
}
|
}
|
||||||
else if ((g_BP.FP < 2) && (*(int*)pointer + size) >= 128)
|
|
||||||
|
if ((g_BP.FP < 2) && (*(int*)pointer + size) >= 128)
|
||||||
{
|
{
|
||||||
if (ipu_fifo.in.read(next_readbits())) g_BP.FP += 1;
|
if (ipu_fifo.in.read(next_readbits())) g_BP.FP += 1;
|
||||||
}
|
}
|
||||||
|
@ -1337,15 +1330,6 @@ static __forceinline int IPU1chain() {
|
||||||
IPU1Status.InProgress = false;
|
IPU1Status.InProgress = false;
|
||||||
} //If we still have data the commands should pull this across when need be.
|
} //If we still have data the commands should pull this across when need be.
|
||||||
|
|
||||||
|
|
||||||
if(totalqwc > 0 || ipu1dma->qwc == 0)
|
|
||||||
{
|
|
||||||
IPU_INT_TO(totalqwc * BIAS);
|
|
||||||
if(ipuRegs->ctrl.BUSY && g_BP.IFC) IPUWorker();
|
|
||||||
}
|
|
||||||
else IPU_INT_TO(1024);
|
|
||||||
|
|
||||||
|
|
||||||
return totalqwc;
|
return totalqwc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1495,6 +1479,18 @@ int IPU1dma()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Do this here to prevent double settings on Chain DMA's
|
||||||
|
if(totalqwc > 0 || ipu1dma->qwc == 0)
|
||||||
|
{
|
||||||
|
IPU_INT_TO(totalqwc * BIAS);
|
||||||
|
if(ipuRegs->ctrl.BUSY && g_BP.IFC) IPUWorker();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IPU_LOG("Here");
|
||||||
|
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", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma->tadr);
|
||||||
return totalqwc;
|
return totalqwc;
|
||||||
}
|
}
|
||||||
|
@ -1599,7 +1595,7 @@ __forceinline void dmaIPU1() // toIPU
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //Attempting to continue a previous chain
|
{ //Attempting to continue a previous chain
|
||||||
DevCon.Warning("Resuming DMA TAG %x", (ipu1dma->chcr.TAG >> 12));
|
IPU_LOG("Resuming DMA TAG %x", (ipu1dma->chcr.TAG >> 12));
|
||||||
//We MUST check the CHCR for the tag it last knew, it can be manipulated!
|
//We MUST check the CHCR for the tag it last knew, it can be manipulated!
|
||||||
IPU1Status.ChainMode = (ipu1dma->chcr.TAG >> 12) & 0x7;
|
IPU1Status.ChainMode = (ipu1dma->chcr.TAG >> 12) & 0x7;
|
||||||
IPU1Status.InProgress = true;
|
IPU1Status.InProgress = true;
|
||||||
|
|
|
@ -43,6 +43,16 @@
|
||||||
#define ipumsk( src ) ( (src) & 0xff )
|
#define ipumsk( src ) ( (src) & 0xff )
|
||||||
#define ipucase( src ) case ipumsk(src)
|
#define ipucase( src ) case ipumsk(src)
|
||||||
|
|
||||||
|
#ifdef IPU_INLINE_IRQS
|
||||||
|
# define IPU_INT_TO( cycles ) ipu1Interrupt()
|
||||||
|
# define IPU_INT_FROM( cycles ) ipu0Interrupt()
|
||||||
|
# define IPU_FORCEINLINE
|
||||||
|
#else
|
||||||
|
# define IPU_INT_TO( cycles ) if(!(cpuRegs.interrupt & (1<<4))) CPU_INT( DMAC_TO_IPU, cycles )
|
||||||
|
# define IPU_INT_FROM( cycles ) CPU_INT( DMAC_FROM_IPU, cycles )
|
||||||
|
# define IPU_FORCEINLINE __forceinline
|
||||||
|
#endif
|
||||||
|
|
||||||
struct IPUStatus {
|
struct IPUStatus {
|
||||||
bool InProgress;
|
bool InProgress;
|
||||||
u8 DMAMode;
|
u8 DMAMode;
|
||||||
|
@ -55,6 +65,8 @@ struct IPUStatus {
|
||||||
u32 NextMem;
|
u32 NextMem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static IPUStatus IPU1Status;
|
||||||
|
|
||||||
#define DMA_MODE_NORMAL 0
|
#define DMA_MODE_NORMAL 0
|
||||||
#define DMA_MODE_CHAIN 1
|
#define DMA_MODE_CHAIN 1
|
||||||
|
|
||||||
|
|
|
@ -114,16 +114,16 @@ int IPU_Fifo_Output::write(const u32 *value, int size)
|
||||||
int IPU_Fifo_Input::read(void *value)
|
int IPU_Fifo_Input::read(void *value)
|
||||||
{
|
{
|
||||||
// wait until enough data
|
// wait until enough data
|
||||||
if (g_BP.IFC == 0)
|
if (g_BP.IFC < 8)
|
||||||
{
|
{
|
||||||
// IPU FIFO is empty and DMA is waiting so lets tell the DMA we are ready to put data in the FIFO
|
// IPU FIFO is empty and DMA is waiting so lets tell the DMA we are ready to put data in the FIFO
|
||||||
if(cpuRegs.interrupt & (1<<4) && cpuRegs.eCycle[4] == 1024)
|
if(cpuRegs.eCycle[4] == 0x9999)
|
||||||
{
|
{
|
||||||
//DevCon.Warning("Setting ECycle");
|
//DevCon.Warning("Setting ECycle");
|
||||||
cpuRegs.eCycle[4] = 4;
|
CPU_INT( DMAC_TO_IPU, 4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (IPU1dma() == 0)*/ return 0;
|
if (g_BP.IFC == 0) return 0;
|
||||||
pxAssert(g_BP.IFC > 0);
|
pxAssert(g_BP.IFC > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -285,7 +285,7 @@ static __forceinline void TESTINT( u8 n, void (*callback)() )
|
||||||
|
|
||||||
static __forceinline void _cpuTestInterrupts()
|
static __forceinline void _cpuTestInterrupts()
|
||||||
{
|
{
|
||||||
if (!dmacRegs->ctrl.DMAE || psHu16(DMAC_ENABLER + 2))
|
if (!dmacRegs->ctrl.DMAE || psHu8(DMAC_ENABLER+2) == 1)
|
||||||
{
|
{
|
||||||
//Console.Write("DMAC Disabled or suspended");
|
//Console.Write("DMAC Disabled or suspended");
|
||||||
return;
|
return;
|
||||||
|
@ -302,7 +302,7 @@ static __forceinline void _cpuTestInterrupts()
|
||||||
// The following ints are rarely called. Encasing them in a conditional
|
// The following ints are rarely called. Encasing them in a conditional
|
||||||
// as follows helps speed up most games.
|
// as follows helps speed up most games.
|
||||||
|
|
||||||
if( cpuRegs.interrupt & ( 1 | (3 << 3) | (3<<8) | (3<<10)) )
|
if( cpuRegs.interrupt & 0xF19 ) // Bits 0 3 4 8 9 10 11 ( 111100011001 )
|
||||||
{
|
{
|
||||||
TESTINT(0, vif0Interrupt);
|
TESTINT(0, vif0Interrupt);
|
||||||
#ifndef IPU_INLINE_IRQS
|
#ifndef IPU_INLINE_IRQS
|
||||||
|
|
Loading…
Reference in New Issue