mirror of https://github.com/PCSX2/pcsx2.git
A continuation of what I was doing in r2305.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2309 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
5ff94743c1
commit
1b42c82faf
|
@ -99,8 +99,11 @@ union tDMA_TAG {
|
|||
tDMA_TAG(u32 val) { _u32 = val; }
|
||||
u16 upper() { return (_u32 >> 16); }
|
||||
u16 lower() { return (u16)_u32; }
|
||||
void reset() { _u32 = 0; }
|
||||
};
|
||||
|
||||
#define DMA_TAG(value) ((tDMA_TAG)(value))
|
||||
|
||||
union tDMA_CHCR {
|
||||
struct {
|
||||
u32 DIR : 1; // Direction: 0 - to memory, 1 - from memory. VIF1 & SIF2 only.
|
||||
|
|
|
@ -50,10 +50,10 @@ static void TestClearVUs(u32 madr, u32 size)
|
|||
|
||||
int _SPR0chain()
|
||||
{
|
||||
u32 *pMem;
|
||||
tDMA_TAG *pMem;
|
||||
|
||||
if (spr0->qwc == 0) return 0;
|
||||
pMem = (u32*)dmaGetAddr(spr0->madr);
|
||||
pMem = (tDMA_TAG*)dmaGetAddr(spr0->madr);
|
||||
if (pMem == NULL) return -1;
|
||||
|
||||
switch (dmacRegs->ctrl.MFD)
|
||||
|
@ -97,7 +97,7 @@ void _SPR0interleave()
|
|||
int qwc = spr0->qwc;
|
||||
int sqwc = dmacRegs->sqwc.SQWC;
|
||||
int tqwc = dmacRegs->sqwc.TQWC;
|
||||
u32 *pMem;
|
||||
tDMA_TAG *pMem;
|
||||
|
||||
if (tqwc == 0) tqwc = qwc;
|
||||
//Console.WriteLn("dmaSPR0 interleave");
|
||||
|
@ -108,7 +108,7 @@ void _SPR0interleave()
|
|||
{
|
||||
spr0->qwc = std::min(tqwc, qwc);
|
||||
qwc -= spr0->qwc;
|
||||
pMem = (u32*)dmaGetAddr(spr0->madr);
|
||||
pMem = (tDMA_TAG*)dmaGetAddr(spr0->madr);
|
||||
|
||||
switch (dmacRegs->ctrl.MFD)
|
||||
{
|
||||
|
@ -151,8 +151,7 @@ static __forceinline void _dmaSPR0()
|
|||
}
|
||||
case CHAIN_MODE:
|
||||
{
|
||||
u32 *ptag;
|
||||
int id;
|
||||
tDMA_TAG *ptag;
|
||||
bool done = FALSE;
|
||||
|
||||
if (spr0->qwc > 0)
|
||||
|
@ -162,23 +161,22 @@ static __forceinline void _dmaSPR0()
|
|||
return;
|
||||
}
|
||||
// Destination Chain Mode
|
||||
ptag = &psSu32(spr0->sadr);
|
||||
ptag = (tDMA_TAG*)&psSu32(spr0->sadr);
|
||||
spr0->sadr += 16;
|
||||
|
||||
Tag::UnsafeTransfer(spr0, ptag);
|
||||
id = Tag::Id(ptag);
|
||||
spr0->unsafeTransfer(ptag);
|
||||
|
||||
spr0->madr = ptag[1]; //MADR = ADDR field
|
||||
spr0->madr = ptag[1].ADDR; //MADR = ADDR field
|
||||
|
||||
SPR_LOG("spr0 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
|
||||
ptag[1], ptag[0], spr0->qwc, id, spr0->madr, spr0->sadr);
|
||||
ptag[1]._u32, ptag[0]._u32, spr0->qwc, ptag->ID, spr0->madr, spr0->sadr);
|
||||
|
||||
if (dmacRegs->ctrl.STS == STS_fromSPR) // STS == fromSPR
|
||||
{
|
||||
Console.WriteLn("SPR stall control");
|
||||
}
|
||||
|
||||
switch (id)
|
||||
switch (ptag->ID)
|
||||
{
|
||||
case TAG_CNTS: // CNTS - Transfer QWC following the tag (Stall Control)
|
||||
if (dmacRegs->ctrl.STS == STS_fromSPR) dmacRegs->stadr.ADDR = spr0->madr + (spr0->qwc * 16); //Copy MADR to DMAC_STADR stall addr register
|
||||
|
@ -194,7 +192,8 @@ static __forceinline void _dmaSPR0()
|
|||
}
|
||||
|
||||
SPR0chain();
|
||||
if (spr0->chcr.TIE && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
|
||||
if (spr0->chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
{
|
||||
//Console.WriteLn("SPR0 TIE");
|
||||
done = true;
|
||||
|
@ -204,12 +203,12 @@ static __forceinline void _dmaSPR0()
|
|||
|
||||
if (!done)
|
||||
{
|
||||
ptag = &psSu32(spr0->sadr); //Set memory pointer to SADR
|
||||
CPU_INT(8, ((u16)ptag[0]) / BIAS); // the lower 16bits of the tag / BIAS);
|
||||
ptag = (tDMA_TAG*)&psSu32(spr0->sadr); //Set memory pointer to SADR
|
||||
CPU_INT(8, ptag[0].QWC / BIAS); // the lower 16bits of the tag / BIAS);
|
||||
return;
|
||||
}
|
||||
SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
|
||||
ptag[1], ptag[0], spr0->qwc, id, spr0->madr);
|
||||
ptag[1]._u32, ptag[0]._u32, spr0->qwc, ptag->ID, spr0->madr);
|
||||
break;
|
||||
}
|
||||
//case INTERLEAVE_MODE:
|
||||
|
@ -265,9 +264,9 @@ void dmaSPR0() // fromSPR
|
|||
|
||||
if ((spr0->chcr.MOD == CHAIN_MODE) && spr0->qwc == 0)
|
||||
{
|
||||
u32 *ptag;
|
||||
ptag = &psSu32(spr0->sadr); //Set memory pointer to SADR
|
||||
CPU_INT(8, (ptag[0] & 0xffff) / BIAS);
|
||||
tDMA_TAG *ptag;
|
||||
ptag = (tDMA_TAG*)&psSu32(spr0->sadr); //Set memory pointer to SADR
|
||||
CPU_INT(8, ptag[0].QWC / BIAS);
|
||||
return;
|
||||
}
|
||||
// COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values
|
||||
|
@ -285,14 +284,14 @@ __forceinline static void SPR1transfer(u32 *data, int size)
|
|||
|
||||
int _SPR1chain()
|
||||
{
|
||||
u32 *pMem;
|
||||
tDMA_TAG *pMem;
|
||||
|
||||
if (spr1->qwc == 0) return 0;
|
||||
|
||||
pMem = (u32*)dmaGetAddr(spr1->madr);
|
||||
pMem = (tDMA_TAG*)dmaGetAddr(spr1->madr);
|
||||
if (pMem == NULL) return -1;
|
||||
|
||||
SPR1transfer(pMem, spr1->qwc << 2);
|
||||
SPR1transfer((u32*)pMem, spr1->qwc << 2);
|
||||
spr1->madr += spr1->qwc << 4;
|
||||
|
||||
return (spr1->qwc) * BIAS;
|
||||
|
@ -309,7 +308,7 @@ void _SPR1interleave()
|
|||
int qwc = spr1->qwc;
|
||||
int sqwc = dmacRegs->sqwc.SQWC;
|
||||
int tqwc = dmacRegs->sqwc.TQWC;
|
||||
u32 *pMem;
|
||||
tDMA_TAG *pMem;
|
||||
|
||||
if (tqwc == 0) tqwc = qwc;
|
||||
SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
|
||||
|
@ -319,7 +318,7 @@ void _SPR1interleave()
|
|||
{
|
||||
spr1->qwc = std::min(tqwc, qwc);
|
||||
qwc -= spr1->qwc;
|
||||
pMem = (u32*)dmaGetAddr(spr1->madr);
|
||||
pMem = (tDMA_TAG*)dmaGetAddr(spr1->madr);
|
||||
memcpy_fast(&psSu8(spr1->sadr), (u8*)pMem, spr1->qwc << 4);
|
||||
spr1->sadr += spr1->qwc * 16;
|
||||
spr1->madr += (sqwc + spr1->qwc) * 16;
|
||||
|
@ -343,8 +342,7 @@ void _dmaSPR1() // toSPR work function
|
|||
}
|
||||
case CHAIN_MODE:
|
||||
{
|
||||
u32 *ptag;
|
||||
int id;
|
||||
tDMA_TAG *ptag;
|
||||
bool done = false;
|
||||
|
||||
if (spr1->qwc > 0)
|
||||
|
@ -356,31 +354,30 @@ void _dmaSPR1() // toSPR work function
|
|||
}
|
||||
// Chain Mode
|
||||
|
||||
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||
ptag = (tDMA_TAG*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||
|
||||
if (!(Tag::Transfer("SPR1 Tag", spr1, ptag)))
|
||||
if (!spr1->transfer("SPR1 Tag", ptag))
|
||||
{
|
||||
done = true;
|
||||
spr1finished = done;
|
||||
}
|
||||
|
||||
id = Tag::Id(ptag);
|
||||
spr1->madr = ptag[1]; //MADR = ADDR field
|
||||
spr1->madr = ptag[1].ADDR; //MADR = ADDR field
|
||||
|
||||
// Transfer dma tag if tte is set
|
||||
if (spr1->chcr.TTE)
|
||||
{
|
||||
SPR_LOG("SPR TTE: %x_%x\n", ptag[3], ptag[2]);
|
||||
SPR1transfer(ptag, 4); //Transfer Tag
|
||||
SPR_LOG("SPR TTE: %x_%x\n", ptag[3]._u32, ptag[2]._u32);
|
||||
SPR1transfer((u32*)ptag, 4); //Transfer Tag
|
||||
}
|
||||
|
||||
SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx",
|
||||
ptag[1], ptag[0], spr1->qwc, id, spr1->madr);
|
||||
ptag[1]._u32, ptag[0]._u32, spr1->qwc, ptag->ID, spr1->madr);
|
||||
|
||||
done = (hwDmacSrcChain(spr1, id) == 1);
|
||||
done = (hwDmacSrcChain(spr1, ptag->ID) == 1);
|
||||
SPR1chain(); //Transfers the data set by the switch
|
||||
|
||||
if (spr1->chcr.TIE && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (spr1->chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
{
|
||||
SPR_LOG("dmaIrq Set");
|
||||
|
||||
|
@ -391,8 +388,8 @@ void _dmaSPR1() // toSPR work function
|
|||
spr1finished = done;
|
||||
if (!done)
|
||||
{
|
||||
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||
CPU_INT(9, (((u16)ptag[0]) / BIAS));// the lower 16 bits of the tag / BIAS);
|
||||
ptag = (tDMA_TAG*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||
CPU_INT(9, (ptag[0].QWC / BIAS));// the lower 16 bits of the tag / BIAS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -414,9 +411,9 @@ void dmaSPR1() // toSPR
|
|||
|
||||
if ((spr1->chcr.MOD == CHAIN_MODE) && (spr1->qwc == 0))
|
||||
{
|
||||
u32 *ptag;
|
||||
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||
CPU_INT(9, (ptag[0] & 0xffff) / BIAS);
|
||||
tDMA_TAG *ptag;
|
||||
ptag = (tDMA_TAG*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||
CPU_INT(9, ptag[0].QWC / BIAS);
|
||||
return;
|
||||
}
|
||||
// COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values
|
||||
|
|
|
@ -95,7 +95,7 @@ static __forceinline void SIF1read(u32 *to, int words)
|
|||
|
||||
__forceinline void SIF0Dma()
|
||||
{
|
||||
u32 *ptag;
|
||||
tDMA_TAG *ptag;
|
||||
bool done = false;
|
||||
int cycles = 0, psxCycles = 0;
|
||||
|
||||
|
@ -114,7 +114,7 @@ __forceinline void SIF0Dma()
|
|||
// if (sif0.sifData.data & 0xC0000000)
|
||||
// which checks if the tag type is refe or end, or if the irq flag is set.
|
||||
// If the tag is refe or end, sif0.end gets set, so I'm replacing it with something easier to read: --arcum42
|
||||
if (/*(sif0dma->chcr.MOD == NORMAL_MODE) ||*/ sif0.end || Tag::IRQ(sif0.sifData.data))
|
||||
if (/*(sif0dma->chcr.MOD == NORMAL_MODE) ||*/ sif0.end || DMA_TAG(sif0.sifData.data).IRQ)
|
||||
{
|
||||
SIF_LOG(" IOP SIF Stopped");
|
||||
|
||||
|
@ -144,7 +144,7 @@ __forceinline void SIF0Dma()
|
|||
|
||||
SIF_LOG(" SIF0 Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", HW_DMA9_MADR, HW_DMA9_TADR, sif0.counter, sif0.sifData.words, sif0.sifData.data);
|
||||
|
||||
u32 tagId = Tag::Id(sif0.sifData.data);
|
||||
u32 tagId = DMA_TAG(sif0.sifData.data).ID;
|
||||
if ((tagId == TAG_REFE) || (tagId == TAG_END))
|
||||
SIF_LOG(" END");
|
||||
else
|
||||
|
@ -180,7 +180,7 @@ __forceinline void SIF0Dma()
|
|||
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr);
|
||||
SIF_LOG("----------- %lX of %lX", readSize << 2, size << 2);
|
||||
|
||||
ptag = _dmaGetAddr(sif0dma, sif0dma->madr, DMAC_SIF0);
|
||||
ptag = (tDMA_TAG*)_dmaGetAddr(sif0dma, sif0dma->madr, DMAC_SIF0);
|
||||
if (ptag == NULL) return;
|
||||
|
||||
SIF0read((u32*)ptag, readSize << 2);
|
||||
|
@ -214,12 +214,12 @@ __forceinline void SIF0Dma()
|
|||
SIF0read((u32*)&tag[0], 4); // Tag
|
||||
SIF_LOG(" EE SIF read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]);
|
||||
|
||||
Tag::UnsafeTransfer(sif0dma,&tag[0]);
|
||||
sif0dma->madr = tag[1];
|
||||
sif0dma->unsafeTransfer(((tDMA_TAG*)(tag)));
|
||||
sif0dma->madr = DMA_TAG(tag[1]).ADDR;
|
||||
|
||||
SIF_LOG(" EE SIF dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", sif0dma->madr, sif0dma->qwc, (tag[0] >> 28)&3, (tag[0] >> 31)&1, tag[1], tag[0]);
|
||||
|
||||
switch (Tag::Id(tag[0]))
|
||||
switch (DMA_TAG(tag[0]).ID)
|
||||
{
|
||||
case TAG_REFE:
|
||||
sif0.end = 1;
|
||||
|
@ -248,7 +248,7 @@ __forceinline void SIF0Dma()
|
|||
|
||||
__forceinline void SIF1Dma()
|
||||
{
|
||||
u32 *ptag;
|
||||
tDMA_TAG *ptag;
|
||||
bool done = FALSE;
|
||||
int cycles = 0, psxCycles = 0;
|
||||
do
|
||||
|
@ -276,30 +276,30 @@ __forceinline void SIF1Dma()
|
|||
{
|
||||
// Process DMA tag at sif1dma->tadr
|
||||
done = false;
|
||||
ptag = _dmaGetAddr(sif1dma, sif1dma->tadr, DMAC_SIF1);
|
||||
ptag = (tDMA_TAG*)_dmaGetAddr(sif1dma, sif1dma->tadr, DMAC_SIF1);
|
||||
if (ptag == NULL) return;
|
||||
|
||||
Tag::UnsafeTransfer(sif1dma, ptag);
|
||||
sif1dma->unsafeTransfer(ptag);
|
||||
|
||||
if (sif1dma->chcr.TTE)
|
||||
{
|
||||
Console.WriteLn("SIF1 TTE");
|
||||
SIF1write(ptag + 2, 2);
|
||||
SIF1write((u32*)ptag + 2, 2);
|
||||
}
|
||||
|
||||
if ((sif1dma->chcr.TIE) && (Tag::IRQ(ptag)))
|
||||
if (sif1dma->chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
Console.WriteLn("SIF1 TIE");
|
||||
sif1.end = 1;
|
||||
}
|
||||
//sif1.chain = 1;
|
||||
|
||||
switch (Tag::Id(ptag))
|
||||
switch (ptag->ID)
|
||||
{
|
||||
case TAG_REFE: // refe
|
||||
SIF_LOG(" REFE %08X", ptag[1]);
|
||||
SIF_LOG(" REFE %08X", ptag[1]._u32);
|
||||
sif1.end = 1;
|
||||
sif1dma->madr = ptag[1];
|
||||
sif1dma->madr = ptag[1].ADDR;
|
||||
sif1dma->tadr += 16;
|
||||
break;
|
||||
|
||||
|
@ -310,15 +310,15 @@ __forceinline void SIF1Dma()
|
|||
break;
|
||||
|
||||
case TAG_NEXT: // next
|
||||
SIF_LOG(" NEXT %08X", ptag[1]);
|
||||
SIF_LOG(" NEXT %08X", ptag[1]._u32);
|
||||
sif1dma->madr = sif1dma->tadr + 16;
|
||||
sif1dma->tadr = ptag[1];
|
||||
sif1dma->tadr = ptag[1].ADDR;
|
||||
break;
|
||||
|
||||
case TAG_REF: // ref
|
||||
case TAG_REFS: // refs
|
||||
SIF_LOG(" REF %08X", ptag[1]);
|
||||
sif1dma->madr = ptag[1];
|
||||
SIF_LOG(" REF %08X", ptag[1]._u32);
|
||||
sif1dma->madr = ptag[1].ADDR;
|
||||
sif1dma->tadr += 16;
|
||||
break;
|
||||
|
||||
|
@ -337,15 +337,15 @@ __forceinline void SIF1Dma()
|
|||
else // There's some data ready to transfer into the fifo..
|
||||
{
|
||||
int qwTransfer = sif1dma->qwc;
|
||||
u32 *data;
|
||||
tDMA_TAG *data;
|
||||
|
||||
data = _dmaGetAddr(sif1dma, sif1dma->madr, DMAC_SIF1);
|
||||
data = (tDMA_TAG*)_dmaGetAddr(sif1dma, sif1dma->madr, DMAC_SIF1);
|
||||
if (data == NULL) return;
|
||||
|
||||
if (qwTransfer > (FIFO_SIF1_W - sif1.fifoSize) / 4) // Copy part of sif1dma into FIFO
|
||||
qwTransfer = (FIFO_SIF1_W - sif1.fifoSize) / 4;
|
||||
|
||||
SIF1write(data, qwTransfer << 2);
|
||||
SIF1write((u32*)data, qwTransfer << 2);
|
||||
|
||||
sif1dma->madr += qwTransfer << 4;
|
||||
cycles += qwTransfer; // fixme : BIAS is factored in above
|
||||
|
@ -395,7 +395,7 @@ __forceinline void SIF1Dma()
|
|||
{
|
||||
struct sifData d;
|
||||
SIF1read((u32*)&d, 4);
|
||||
SIF_LOG(" IOP SIF dest chain tag madr:%08X wc:%04X id:%X irq:%d", d.data & 0xffffff, d.words, (d.data >> 28)&7, (d.data >> 31)&1);
|
||||
SIF_LOG(" IOP SIF dest chain tag madr:%08X wc:%04X id:%X irq:%d", d.data & 0xffffff, d.words, DMA_TAG(d.data).ID, DMA_TAG(d.data).IRQ);
|
||||
HW_DMA10_MADR = d.data & 0xffffff;
|
||||
sif1.counter = d.words;
|
||||
sif1.tagMode = (d.data >> 24) & 0xFF;
|
||||
|
|
|
@ -484,15 +484,15 @@ static __forceinline bool mfifo_VIF1chain()
|
|||
}
|
||||
else
|
||||
{
|
||||
u32 *pMem = (u32*)dmaGetAddr(vif1ch->madr);
|
||||
tDMA_TAG *pMem = (tDMA_TAG*)dmaGetAddr(vif1ch->madr);
|
||||
SPR_LOG("Non-MFIFO Location");
|
||||
|
||||
if (pMem == NULL) return false;
|
||||
|
||||
if (vif1.vifstalled)
|
||||
ret = VIF1transfer(pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset, false);
|
||||
ret = VIF1transfer((u32*)pMem + vif1.irqoffset, vif1ch->qwc * 4 - vif1.irqoffset, false);
|
||||
else
|
||||
ret = VIF1transfer(pMem, vif1ch->qwc << 2, false);
|
||||
ret = VIF1transfer((u32*)pMem, vif1ch->qwc << 2, false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -504,8 +504,7 @@ static u32 qwctag(u32 mask)
|
|||
|
||||
void mfifoVIF1transfer(int qwc)
|
||||
{
|
||||
u32 *ptag;
|
||||
int id;
|
||||
tDMA_TAG *ptag;
|
||||
|
||||
g_vifCycles = 0;
|
||||
|
||||
|
@ -529,16 +528,16 @@ void mfifoVIF1transfer(int qwc)
|
|||
|
||||
if (vif1ch->qwc == 0 && vifqwc > 0)
|
||||
{
|
||||
ptag = (u32*)dmaGetAddr(vif1ch->tadr);
|
||||
ptag = (tDMA_TAG*)dmaGetAddr(vif1ch->tadr);
|
||||
|
||||
if (vif1ch->chcr.TTE)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
if (vif1.stallontag)
|
||||
ret = VIF1transfer(ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, true); //Transfer Tag on Stall
|
||||
ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, true); //Transfer Tag on Stall
|
||||
else
|
||||
ret = VIF1transfer(ptag + 2, 2, true); //Transfer Tag
|
||||
ret = VIF1transfer((u32*)ptag + 2, 2, true); //Transfer Tag
|
||||
|
||||
if (!(ret))
|
||||
{
|
||||
|
@ -548,16 +547,15 @@ void mfifoVIF1transfer(int qwc)
|
|||
}
|
||||
}
|
||||
|
||||
Tag::UnsafeTransfer(vif1ch, ptag);
|
||||
vif1ch->unsafeTransfer(ptag);
|
||||
|
||||
vif1ch->madr = ptag[1];
|
||||
id =Tag::Id(ptag);
|
||||
vif1ch->madr = ptag[1].ADDR;
|
||||
vifqwc--;
|
||||
|
||||
SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x",
|
||||
ptag[1], ptag[0], vif1ch->qwc, id, vif1ch->madr, vif1ch->tadr, vifqwc, spr0->madr);
|
||||
ptag[1]._u32, ptag[0]._u32, vif1ch->qwc, ptag->ID, vif1ch->madr, vif1ch->tadr, vifqwc, spr0->madr);
|
||||
|
||||
switch (id)
|
||||
switch (ptag->ID)
|
||||
{
|
||||
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
||||
vif1ch->tadr = qwctag(vif1ch->tadr + 16);
|
||||
|
@ -593,7 +591,7 @@ void mfifoVIF1transfer(int qwc)
|
|||
break;
|
||||
}
|
||||
|
||||
if ((vif1ch->chcr.TIE) && (Tag::IRQ(ptag)))
|
||||
if (vif1ch->chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
VIF_LOG("dmaIrq Set");
|
||||
vif1.done = true;
|
||||
|
|
|
@ -113,6 +113,8 @@ union tVIF_STAT {
|
|||
wxString desc() { return wxsFormat(L"Stat: 0x%x", _u32); }
|
||||
};
|
||||
|
||||
#define VIF_STAT(value) ((tVIF_STAT)(value))
|
||||
|
||||
union tVIF_FBRST {
|
||||
struct {
|
||||
u32 RST : 1; // Resets Vif(0/1) when written.
|
||||
|
@ -132,6 +134,8 @@ union tVIF_FBRST {
|
|||
wxString desc() { return wxsFormat(L"Fbrst: 0x%x", _u32); }
|
||||
};
|
||||
|
||||
#define FBRST(value) ((tVIF_FBRST)(value))
|
||||
|
||||
union tVIF_ERR {
|
||||
struct {
|
||||
u32 MII : 1; // Masks Stat INT.
|
||||
|
|
|
@ -30,7 +30,6 @@ extern int (__fastcall *Vif0TransTLB[128])(u32 *data);
|
|||
extern void (*Vif0CMDTLB[75])();
|
||||
|
||||
vifStruct vif0;
|
||||
u32 *vif0ptag;
|
||||
|
||||
__forceinline void vif0FLUSH()
|
||||
{
|
||||
|
@ -499,18 +498,17 @@ bool _VIF0chain()
|
|||
|
||||
bool _chainVIF0()
|
||||
{
|
||||
int id;
|
||||
tDMA_TAG *ptag;
|
||||
|
||||
vif0ptag = (u32*)dmaGetAddr(vif0ch->tadr); //Set memory pointer to TADR
|
||||
ptag = (tDMA_TAG*)dmaGetAddr(vif0ch->tadr); //Set memory pointer to TADR
|
||||
|
||||
if (!(Tag::Transfer("Vif0 Tag", vif0ch, vif0ptag))) return false;
|
||||
if (!(vif0ch->transfer("Vif0 Tag", ptag))) return false;
|
||||
|
||||
vif0ch->madr = vif0ptag[1]; // MADR = ADDR field
|
||||
id = Tag::Id(vif0ptag); // ID for DmaChain copied from bit 28 of the tag
|
||||
g_vifCycles += 1; // Increase the QW read for the tag
|
||||
vif0ch->madr = ptag[1].ADDR; // MADR = ADDR field
|
||||
g_vifCycles += 1; // Increase the QW read for the tag
|
||||
|
||||
VIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx",
|
||||
vif0ptag[1], vif0ptag[0], vif0ch->qwc, id, vif0ch->madr, vif0ch->tadr);
|
||||
ptag[1]._u32, ptag[0]._u32, vif0ch->qwc, ptag->ID, vif0ch->madr, vif0ch->tadr);
|
||||
|
||||
// Transfer dma tag if tte is set
|
||||
if (vif0ch->chcr.TTE)
|
||||
|
@ -518,21 +516,21 @@ bool _chainVIF0()
|
|||
bool ret;
|
||||
|
||||
if (vif0.vifstalled)
|
||||
ret = VIF0transfer(vif0ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset, true); //Transfer Tag on stall
|
||||
ret = VIF0transfer((u32*)ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset, true); //Transfer Tag on stall
|
||||
else
|
||||
ret = VIF0transfer(vif0ptag + 2, 2, true); //Transfer Tag
|
||||
ret = VIF0transfer((u32*)ptag + 2, 2, true); //Transfer Tag
|
||||
|
||||
if (!(ret)) return false; //IRQ set by VIFTransfer
|
||||
}
|
||||
|
||||
vif0.done |= hwDmacSrcChainWithStack(vif0ch, id);
|
||||
vif0.done |= hwDmacSrcChainWithStack(vif0ch, ptag->ID);
|
||||
|
||||
VIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx",
|
||||
vif0ptag[1], vif0ptag[0], vif0ch->qwc, id, vif0ch->madr, vif0ch->tadr);
|
||||
ptag[1]._u32, ptag[0]._u32, vif0ch->qwc, ptag->ID, vif0ch->madr, vif0ch->tadr);
|
||||
|
||||
_VIF0chain(); //Transfers the data set by the switch
|
||||
|
||||
if (vif0ch->chcr.TIE && Tag::IRQ(vif0ptag)) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (vif0ch->chcr.TIE && ptag->IRQ) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
{
|
||||
VIF_LOG("dmaIrq Set\n");
|
||||
vif0.done = true; //End Transfer
|
||||
|
|
|
@ -33,7 +33,6 @@ extern int (__fastcall *Vif1TransTLB[128])(u32 *data);
|
|||
|
||||
Path3Modes Path3progress = STOPPED_MODE;
|
||||
vifStruct vif1;
|
||||
static u32 *vif1ptag;
|
||||
|
||||
static __aligned16 u32 splittransfer[4];
|
||||
static u32 splitptr = 0;
|
||||
|
@ -365,7 +364,6 @@ static int __fastcall Vif1TransUnpack(u32 *data)
|
|||
XMMRegisters::Thaw();
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -793,6 +791,8 @@ bool _chainVIF1()
|
|||
|
||||
__forceinline void vif1SetupTransfer()
|
||||
{
|
||||
tDMA_TAG *ptag;
|
||||
|
||||
switch (vif1.dmamode)
|
||||
{
|
||||
case VIF_NORMAL_TO_MEM_MODE:
|
||||
|
@ -803,22 +803,19 @@ __forceinline void vif1SetupTransfer()
|
|||
break;
|
||||
|
||||
case VIF_CHAIN_MODE:
|
||||
int id;
|
||||
ptag = (tDMA_TAG*)dmaGetAddr(vif1ch->tadr); //Set memory pointer to TADR
|
||||
|
||||
vif1ptag = (u32*)dmaGetAddr(vif1ch->tadr); //Set memory pointer to TADR
|
||||
if (!(vif1ch->transfer("Vif1 Tag", ptag))) return;
|
||||
|
||||
if (!(Tag::Transfer("Vif1 Tag", vif1ch, vif1ptag))) return;
|
||||
|
||||
vif1ch->madr = vif1ptag[1]; //MADR = ADDR field
|
||||
vif1ch->madr = ptag[1].ADDR; //MADR = ADDR field
|
||||
g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag
|
||||
id = Tag::Id(vif1ptag); //ID for DmaChain copied from bit 28 of the tag
|
||||
|
||||
// Transfer dma tag if tte is set
|
||||
|
||||
VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n",
|
||||
vif1ptag[1], vif1ptag[0], vif1ch->qwc, id, vif1ch->madr, vif1ch->tadr);
|
||||
ptag[1]._u32, ptag[0]._u32, vif1ch->qwc, ptag->ID, vif1ch->madr, vif1ch->tadr);
|
||||
|
||||
if (!vif1.done && ((dmacRegs->ctrl.STD == STD_VIF1) && (id == 4))) // STD == VIF1
|
||||
if (!vif1.done && ((dmacRegs->ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1
|
||||
{
|
||||
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
|
||||
if ((vif1ch->madr + vif1ch->qwc * 16) >= dmacRegs->stadr.ADDR)
|
||||
|
@ -836,9 +833,9 @@ __forceinline void vif1SetupTransfer()
|
|||
bool ret;
|
||||
|
||||
if (vif1.vifstalled)
|
||||
ret = VIF1transfer(vif1ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, true); //Transfer Tag on stall
|
||||
ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, true); //Transfer Tag on stall
|
||||
else
|
||||
ret = VIF1transfer(vif1ptag + 2, 2, true); //Transfer Tag
|
||||
ret = VIF1transfer((u32*)ptag + 2, 2, true); //Transfer Tag
|
||||
|
||||
if ((ret == false) && vif1.irqoffset < 2)
|
||||
{
|
||||
|
@ -848,10 +845,10 @@ __forceinline void vif1SetupTransfer()
|
|||
}
|
||||
|
||||
vif1.irqoffset = 0;
|
||||
vif1.done |= hwDmacSrcChainWithStack(vif1ch, id);
|
||||
vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID);
|
||||
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (vif1ch->chcr.TIE && (Tag::IRQ(vif1ptag)))
|
||||
if (vif1ch->chcr.TIE && ptag->IRQ)
|
||||
{
|
||||
VIF_LOG("dmaIrq Set");
|
||||
|
||||
|
@ -997,7 +994,7 @@ void dmaVIF1()
|
|||
if (vif1.dmamode != VIF_NORMAL_FROM_MEM_MODE)
|
||||
vif1Regs->stat.FQC = 0x10;
|
||||
else
|
||||
vif1Regs->stat.set_flags(min((u16)16, vif1ch->qwc) << 24);
|
||||
vif1Regs->stat.FQC = min((u16)0x10, vif1ch->qwc);
|
||||
|
||||
// Chain Mode
|
||||
vif1.done = false;
|
||||
|
@ -1019,7 +1016,7 @@ void vif1Write32(u32 mem, u32 value)
|
|||
case VIF1_FBRST: // FBRST
|
||||
VIF_LOG("VIF1_FBRST write32 0x%8.8x", value);
|
||||
|
||||
if (value & 0x1) // Reset Vif.
|
||||
if (FBRST(value).RST) // Reset Vif.
|
||||
{
|
||||
memzero(vif1);
|
||||
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
||||
|
@ -1037,10 +1034,11 @@ void vif1Write32(u32 mem, u32 value)
|
|||
|
||||
vif1Regs->err.reset();
|
||||
vif1.inprogress = 0;
|
||||
vif1Regs->stat.clear_flags(VIF1_STAT_FQC | VIF1_STAT_FDR | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS); // FQC=0
|
||||
vif1Regs->stat.FQC = 0;
|
||||
vif1Regs->stat.clear_flags(VIF1_STAT_FDR | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS);
|
||||
}
|
||||
|
||||
if (value & 0x2) // Forcebreak Vif.
|
||||
if (FBRST(value).FBK) // Forcebreak Vif.
|
||||
{
|
||||
/* I guess we should stop the VIF dma here, but not 100% sure (linuz) */
|
||||
vif1Regs->stat.VFS = true;
|
||||
|
@ -1050,7 +1048,7 @@ void vif1Write32(u32 mem, u32 value)
|
|||
Console.WriteLn("vif1 force break");
|
||||
}
|
||||
|
||||
if (value & 0x4) // Stop Vif.
|
||||
if (FBRST(value).STP) // Stop Vif.
|
||||
{
|
||||
// Not completely sure about this, can't remember what game used this, but 'draining' the VIF helped it, instead of
|
||||
// just stoppin the VIF (linuz).
|
||||
|
@ -1060,7 +1058,7 @@ void vif1Write32(u32 mem, u32 value)
|
|||
vif1.vifstalled = true;
|
||||
}
|
||||
|
||||
if (value & 0x8) // Cancel Vif Stall.
|
||||
if (FBRST(value).STC) // Cancel Vif Stall.
|
||||
{
|
||||
bool cancel = false;
|
||||
|
||||
|
@ -1122,14 +1120,14 @@ void vif1Write32(u32 mem, u32 value)
|
|||
}
|
||||
#endif
|
||||
|
||||
vif1Regs->stat.FDR = !!(value & VIF1_STAT_FDR);
|
||||
//vif1Regs->stat._u32 = (vif1Regs->stat._u32 & ~VIF1_STAT_FDR) | (value & VIF1_STAT_FDR);
|
||||
if (vif1Regs->stat.FDR)
|
||||
vif1Regs->stat.FDR = VIF_STAT(value).FDR;
|
||||
|
||||
if (vif1Regs->stat.FDR) // Vif transferring to memory.
|
||||
{
|
||||
// Hack but it checks this is true before transfer? (fatal frame)
|
||||
vif1Regs->stat.FQC = 0x1;
|
||||
}
|
||||
else
|
||||
else // Memory transferring to Vif.
|
||||
{
|
||||
vif1ch->qwc = 0;
|
||||
vif1.vifstalled = false;
|
||||
|
|
Loading…
Reference in New Issue