mirror of https://github.com/PCSX2/pcsx2.git
VIF MFIFO:
- Proper fix for FF7 DoC. - Changed the handlng of .inprogress to be cleared/set with ANDs and ORs (could probably change this to a structure later), it could have interfered with MFIFO functionality. -Un-bool'd a function in MFIFO which really didnt need to be bool'd, causing pointless passing around of data. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3632 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
e97c68e832
commit
81dc6726d0
|
@ -149,7 +149,7 @@ bool _VIF1chain()
|
|||
|
||||
if (vif1ch->qwc == 0)
|
||||
{
|
||||
vif1.inprogress = 0;
|
||||
vif1.inprogress &= ~1;
|
||||
vif1.irqoffset = 0;
|
||||
return true;
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ bool _VIF1chain()
|
|||
if (vif1.dmamode == VIF_NORMAL_TO_MEM_MODE)
|
||||
{
|
||||
vif1TransferToMemory();
|
||||
vif1.inprogress = 0;
|
||||
vif1.inprogress &= ~1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ __fi void vif1SetupTransfer()
|
|||
{
|
||||
case VIF_NORMAL_TO_MEM_MODE:
|
||||
case VIF_NORMAL_FROM_MEM_MODE:
|
||||
vif1.inprogress = 1;
|
||||
vif1.inprogress |= 1;
|
||||
vif1.done = true;
|
||||
g_vifCycles = 2;
|
||||
break;
|
||||
|
@ -217,7 +217,7 @@ __fi void vif1SetupTransfer()
|
|||
}
|
||||
|
||||
|
||||
vif1.inprogress = 0;
|
||||
vif1.inprogress &= ~1;
|
||||
|
||||
if (vif1c.chcr.TTE)
|
||||
{
|
||||
|
@ -234,7 +234,7 @@ __fi void vif1SetupTransfer()
|
|||
|
||||
if (!ret && vif1.irqoffset < 2)
|
||||
{
|
||||
vif1.inprogress = 0; //Better clear this so it has to do it again (Jak 1)
|
||||
vif1.inprogress &= ~1; //Better clear this so it has to do it again (Jak 1)
|
||||
return; //IRQ set by VIFTransfer
|
||||
|
||||
} //else vif1.vifstalled = false;
|
||||
|
@ -243,7 +243,7 @@ __fi void vif1SetupTransfer()
|
|||
|
||||
vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID);
|
||||
|
||||
if(vif1c.qwc > 0) vif1.inprogress = 1;
|
||||
if(vif1c.qwc > 0) vif1.inprogress |= 1;
|
||||
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (vif1c.chcr.TIE && ptag->IRQ)
|
||||
|
|
|
@ -93,22 +93,22 @@ static __fi bool mfifoVIF1rbTransfer()
|
|||
return ret;
|
||||
}
|
||||
|
||||
static __fi bool mfifo_VIF1chain()
|
||||
static __fi void mfifo_VIF1chain()
|
||||
{
|
||||
bool ret;
|
||||
|
||||
/* Is QWC = 0? if so there is nothing to transfer */
|
||||
if ((vif1ch->qwc == 0))
|
||||
{
|
||||
vif1.inprogress &= ~1;
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (vif1ch->madr >= dmacRegs->rbor.ADDR &&
|
||||
vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
|
||||
{
|
||||
//Need to exit on mfifo locations, if the madr is matching the madr of spr, we dont have any data left :(
|
||||
|
||||
u16 startqwc = vif1ch->qwc;
|
||||
ret = mfifoVIF1rbTransfer();
|
||||
mfifoVIF1rbTransfer();
|
||||
vifqwc -= startqwc - vif1ch->qwc;
|
||||
|
||||
}
|
||||
|
@ -117,14 +117,15 @@ static __fi bool mfifo_VIF1chain()
|
|||
tDMA_TAG *pMem = dmaGetAddr(vif1ch->madr, !vif1ch->chcr.DIR);
|
||||
SPR_LOG("Non-MFIFO Location");
|
||||
|
||||
if (pMem == NULL) return false;
|
||||
//No need to exit on non-mfifo as it is indirect anyway, so it can be transferring this while spr refills the mfifo
|
||||
|
||||
if (pMem == NULL) return;
|
||||
|
||||
if (vif1.vifstalled)
|
||||
ret = VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset);
|
||||
VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset);
|
||||
else
|
||||
ret = VIF1transfer((u32*)pMem, vif1ch->qwc << 2);
|
||||
VIF1transfer((u32*)pMem, vif1ch->qwc << 2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -141,13 +142,7 @@ void mfifoVIF1transfer(int qwc)
|
|||
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr._u32, vif1.vifstalled, vif1.done);
|
||||
if (vif1.inprogress & 0x10)
|
||||
{
|
||||
if (vif1ch->madr >= dmacRegs->rbor.ADDR && vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
|
||||
CPU_INT(DMAC_MFIFO_VIF, 1);
|
||||
else
|
||||
{
|
||||
// Minor hack. Please ask before removal (rama) (FF7 Dirge of Cerberus)
|
||||
CPU_INT(DMAC_MFIFO_VIF, min( 386, (int)(vif1ch->qwc * BIAS) ) );
|
||||
}
|
||||
if(vif1ch->chcr.STR == true)CPU_INT(DMAC_MFIFO_VIF, 4);
|
||||
|
||||
vif1Regs->stat.FQC = 0x10; // FQC=16
|
||||
}
|
||||
|
@ -227,9 +222,11 @@ void mfifoVIF1transfer(int qwc)
|
|||
VIF_LOG("dmaIrq Set");
|
||||
vif1.done = true;
|
||||
}
|
||||
|
||||
vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
|
||||
vif1.inprogress |= 1;
|
||||
}
|
||||
vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
|
||||
vif1.inprogress |= 1;
|
||||
|
||||
|
||||
SPR_LOG("mfifoVIF1transfer end %x madr %x, tadr %x vifqwc %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr, vifqwc);
|
||||
}
|
||||
|
@ -288,39 +285,40 @@ void vifMFIFOInterrupt()
|
|||
{
|
||||
// Console.WriteLn("Empty 1");
|
||||
vifqwc = 0;
|
||||
vif1.inprogress |= 0x10;
|
||||
vif1Regs->stat.FQC = 0;
|
||||
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
||||
if((vif1.inprogress & 0x10) == 0)
|
||||
{
|
||||
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
||||
vif1.inprogress |= 0x10;
|
||||
}
|
||||
vif1Regs->stat.FQC = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
mfifoVIF1transfer(0);
|
||||
if ((vif1ch->madr >= dmacRegs->rbor.ADDR) && (vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK)))
|
||||
CPU_INT(DMAC_MFIFO_VIF, 1);
|
||||
else
|
||||
{
|
||||
// Minor hack. Please ask before removal (rama) (FF7 Dirge of Cerberus)
|
||||
CPU_INT(DMAC_MFIFO_VIF, min( 386, (int)(vif1ch->qwc * BIAS) ) );
|
||||
}
|
||||
|
||||
CPU_INT(DMAC_MFIFO_VIF, 4);
|
||||
return;
|
||||
|
||||
case 1: //Transfer data
|
||||
mfifo_VIF1chain();
|
||||
CPU_INT(DMAC_MFIFO_VIF, 1);
|
||||
//Sanity check! making sure we always have non-zero values
|
||||
CPU_INT(DMAC_MFIFO_VIF, (g_vifCycles == 0 ? 4 : g_vifCycles) );
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*if (vifqwc <= 0)
|
||||
{
|
||||
//Console.WriteLn("Empty 2");
|
||||
//vif1.inprogress |= 0x10;
|
||||
vif1Regs->stat.FQC = 0; // FQC=0
|
||||
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
||||
}*/
|
||||
|
||||
//FF7 Dirge of Cerberus seems to like the mfifo to tell it when it's empty, even if it's ending.
|
||||
//Doesn't seem to care about the vif1 dma interrupting (possibly disabled the interrupt?)
|
||||
if (vif1ch->tadr == spr0->madr)
|
||||
{
|
||||
vifqwc = 0;
|
||||
if((vif1.inprogress & 0x10) == 0)
|
||||
{
|
||||
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
||||
vif1.inprogress |= 0x10;
|
||||
}
|
||||
}
|
||||
vif1.vifstalled = false;
|
||||
vif1.done = 1;
|
||||
g_vifCycles = 0;
|
||||
|
|
Loading…
Reference in New Issue