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:
arcum42 2009-12-05 08:01:00 +00:00
parent 5ff94743c1
commit 1b42c82faf
7 changed files with 113 additions and 115 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
ptag = (tDMA_TAG*)dmaGetAddr(vif0ch->tadr); //Set memory pointer to TADR
vif0ptag = (u32*)dmaGetAddr(vif0ch->tadr); //Set memory pointer to TADR
if (!(vif0ch->transfer("Vif0 Tag", ptag))) return false;
if (!(Tag::Transfer("Vif0 Tag", vif0ch, vif0ptag))) 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

View File

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