Revised Ipu1Chain, and tweaked Ipu1Dma.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1329 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
arcum42 2009-06-05 04:59:13 +00:00
parent a134dd6110
commit c668c7c351
1 changed files with 67 additions and 82 deletions

View File

@ -1373,7 +1373,7 @@ int FIFOto_write(u32* pMem, int size)
return firsttrans;
}
static __forceinline s32 IPU1chain(u32* &pMem, int &totalqwc)
static __forceinline bool IPU1chain(u32* &pMem, int &totalqwc)
{
if (ipu1dma->qwc > 0)
{
@ -1384,7 +1384,7 @@ static __forceinline s32 IPU1chain(u32* &pMem, int &totalqwc)
if (pMem == NULL)
{
Console::Error("ipu1dma NULL!");
return totalqwc;
return true;
}
qwc = FIFOto_write(pMem, qwc);
@ -1395,11 +1395,25 @@ static __forceinline s32 IPU1chain(u32* &pMem, int &totalqwc)
if (ipu1dma->qwc > 0)
{
g_nDMATransfer |= IPU_DMA_ACTV1;
return totalqwc;
return true;
}
}
return false;
}
return -1;
static __forceinline bool IncreaseTadr(u32 tag)
{
switch (tag & 0x70000000)
{
case 0x00000000:
ipu1dma->tadr += 16;
return true;
case 0x70000000:
ipu1dma->tadr = ipu1dma->madr;
return true;
}
return false;
}
extern void gsInterrupt();
@ -1427,8 +1441,7 @@ int IPU1dma()
// in kh, qwc == 0 when dma_actv1 is set
if ((g_nDMATransfer & IPU_DMA_ACTV1) && ipu1dma->qwc > 0)
{
int temp = IPU1chain(pMem, totalqwc);
if (temp != -1) return temp;
if (IPU1chain(pMem, totalqwc)) return totalqwc;
//Check TIE bit of CHCR and IRQ bit of tag
if ((ipu1dma->chcr & 0x80) && (g_nDMATransfer & IPU_DMA_DOTIE1))
@ -1441,7 +1454,7 @@ int IPU1dma()
return totalqwc;
}
if ((ipu1dma->chcr&0xc) == 0)
if (!(ipu1dma->chcr & 0xc))
{
IPU_INT_TO(totalqwc * BIAS);
return totalqwc;
@ -1454,15 +1467,7 @@ int IPU1dma()
{
ptag = (u32*)dmaGetAddr(ipu1dma->tadr);
switch (tag&0x70000000)
{
case 0x00000000:
ipu1dma->tadr += 16;
break;
case 0x70000000:
ipu1dma->tadr = ipu1dma->madr;
break;
}
IncreaseTadr(tag);
ipu1dma->chcr = (ipu1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000);
IPU_LOG("IPU dmaIrq Set");
@ -1471,15 +1476,8 @@ int IPU1dma()
return totalqwc;
}
switch (tag&0x70000000)
if (IncreaseTadr(tag))
{
case 0x00000000:
ipu1dma->tadr += 16;
IPU_INT_TO((1 + totalqwc)*BIAS);
return totalqwc;
case 0x70000000:
ipu1dma->tadr = ipu1dma->madr;
IPU_INT_TO((1 + totalqwc)*BIAS);
return totalqwc;
}
@ -1488,34 +1486,31 @@ int IPU1dma()
g_nDMATransfer &= ~(IPU_DMA_ACTV1 | IPU_DMA_DOTIE1);
}
if ((ipu1dma->chcr & 0xc) == 0 && ipu1dma->qwc == 0) // Normal Mode
if (((ipu1dma->chcr & 0xc) == 0) && (ipu1dma->qwc == 0)) // Normal Mode
{
//Console::WriteLn("ipu1 normal empty qwc?");
return totalqwc;
}
// Transfer Dn_QWC from Dn_MADR to GIF
if ((ipu1dma->chcr & 0xc) == 0 || ipu1dma->qwc > 0) // Normal Mode
if (ipu1dma->qwc > 0)
{
IPU_LOG("dmaIPU1 Normal size=%d, addr=%lx, fifosize=%x",
ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC);
int temp = IPU1chain(pMem, totalqwc);
if (temp != -1) return temp;
if (!IPU1chain(pMem, totalqwc)) IPU_INT_TO((ipu1cycles + totalqwc) * BIAS);
IPU_INT_TO((ipu1cycles + totalqwc)*BIAS);
return totalqwc;
}
else
{
// Chain Mode
// Chain Mode & ipu1dma->qwc is 0
ptag = (u32*)dmaGetAddr(ipu1dma->tadr); //Set memory pointer to TADR
if (ptag == NULL) //Is ptag empty?
{
Console::Error("IPU1 BUSERR");
ipu1dma->chcr = (ipu1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
psHu32(DMAC_STAT) |= 1 << 15; //If yes, set BEIS (BUSERR) in DMAC_STAT register
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register
return totalqwc;
}
@ -1567,50 +1562,40 @@ int IPU1dma()
else
g_nDMATransfer &= ~IPU_DMA_DOTIE1;
//Britney Dance beat does a blank NEXT tag, for some odd reason the fix doesnt work if after IPU1Chain O_o
if ((ipu1dma->qwc == 0) && (!done) && !(g_nDMATransfer & IPU_DMA_DOTIE1)) IPU1dma();
int temp = IPU1chain(pMem, totalqwc);
if (temp != -1) return temp;
if ((ipu1dma->chcr & 0x80) && (ptag[0]&0x80000000) && ipu1dma->qwc == 0) //Check TIE bit of CHCR and IRQ bit of tag
if (ipu1dma->qwc == 0)
{
//if ((ipu1dma->chcr & 0x80) && (ptag[0] & 0x80000000)) //Check TIE bit of CHCR and IRQ bit of tag
if (g_nDMATransfer & IPU_DMA_DOTIE1)
{
Console::WriteLn("IPU1 TIE");
if (IPU1chain(pMem, totalqwc)) return totalqwc;
if (done)
{
ptag = (u32*)dmaGetAddr(ipu1dma->tadr);
switch (ptag[0]&0x70000000)
{
case 0x00000000:
ipu1dma->tadr += 16;
break;
case 0x70000000:
ipu1dma->tadr = ipu1dma->madr;
break;
}
IncreaseTadr(ptag[0]);
ipu1dma->chcr = (ipu1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000);
}
IPU_INT_TO(ipu1cycles + totalqwc*BIAS);
IPU_INT_TO(ipu1cycles + totalqwc * BIAS); // Should it be (ipu1cycles + totalqwc) * BIAS?
g_nDMATransfer |= IPU_DMA_TIE1;
return totalqwc;
}
if (ipu1dma->qwc == 0)
else
{
switch (ptag[0]&0x70000000)
{
case 0x00000000:
ipu1dma->tadr += 16;
break;
case 0x70000000:
ipu1dma->tadr = ipu1dma->madr;
break;
//Britney Dance beat does a blank NEXT tag, for some odd reason the fix doesnt work if after IPU1Chain O_o
if (!done) IPU1dma();
if (IPU1chain(pMem, totalqwc)) return totalqwc;
}
IncreaseTadr(ptag[0]);
}
else
{
if (IPU1chain(pMem, totalqwc)) return totalqwc;
}
}