-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:
refraction 2010-04-29 00:10:15 +00:00
parent aae53a9707
commit 35498e329f
4 changed files with 44 additions and 36 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);
} }

View File

@ -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