Converted VifDma.cpp over to using Tags.h. Worked some more on straightening out Tags.h.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1638 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
arcum42 2009-08-16 20:03:55 +00:00
parent de2d3603a0
commit adb9c06dba
4 changed files with 181 additions and 179 deletions

View File

@ -1398,9 +1398,7 @@ static __forceinline bool IPU1chain(int &totalqwc)
// Remind me to give this a better name. --arcum42
static __forceinline bool IncreaseTadr(u32 tag)
{
u32 id = (tag >> 28) & 0x7;
switch (id)
switch (Tag::Id(tag))
{
case TAG_REFE: // refe
ipu1dma->tadr += 16;
@ -1417,9 +1415,7 @@ extern void gsInterrupt();
static __forceinline bool ipuDmacSrcChain(DMACh *tag, u32 *ptag)
{
u32 id = (ptag[0] >> 28) & 0x7;
switch (id)
switch (Tag::Id(ptag))
{
case TAG_REFE: // refe
// do not change tadr
@ -1507,13 +1503,13 @@ int IPU1dma()
// Chain mode.
u32 tag = ipu1dma->chcr; // upper bits describe current tag
if (CHCR::TIE(ipu1dma) && ChainTags::IRQ(tag))
if (CHCR::TIE(ipu1dma) && Tag::IRQ(tag))
{
ptag = (u32*)dmaGetAddr(ipu1dma->tadr);
IncreaseTadr(tag);
UpperTagTransfer(ipu1dma, ptag);
Tag::UpperTransfer(ipu1dma, ptag);
IPU_LOG("IPU dmaIrq Set");
IPU_INT_TO(totalqwc * BIAS);
@ -1554,7 +1550,7 @@ int IPU1dma()
ptag = (u32*)dmaGetAddr(ipu1dma->tadr); //Set memory pointer to TADR
// Transfer the tag.
if (!(TransferTag("IPU1", ipu1dma, ptag))) return totalqwc;
if (!(Tag::Transfer("IPU1", ipu1dma, ptag))) return totalqwc;
ipu1cycles += 1; // Add 1 cycles from the QW read for the tag
@ -1564,7 +1560,7 @@ int IPU1dma()
ptag[1], ptag[0], ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC);
if (CHCR::TIE(ipu1dma) && ChainTags::IRQ(ptag))
if (CHCR::TIE(ipu1dma) && Tag::IRQ(ptag))
g_nDMATransfer |= IPU_DMA_DOTIE1;
else
g_nDMATransfer &= ~IPU_DMA_DOTIE1;
@ -1585,7 +1581,7 @@ int IPU1dma()
IncreaseTadr(ptag[0]);
// Transfer the last of ptag into chcr.
UpperTagTransfer(ipu1dma, ptag);
Tag::UpperTransfer(ipu1dma, ptag);
}
IPU_INT_TO(ipu1cycles + totalqwc * BIAS); // Should it be (ipu1cycles + totalqwc) * BIAS?

View File

@ -20,48 +20,7 @@
// I kept seeing the same code over and over with different structure names
// and the same members, and figured it'd be a good spot to use templates...
enum TransferMode
{
NORMAL_MODE = 0,
CHAIN_MODE,
INTERLEAVE_MODE,
UNDEFINED_MODE
};
template <class T>
static __forceinline void UpperTagTransfer(T tag, u32* ptag)
{
// Transfer upper part of tag to CHCR bits 31-15
tag->chcr = (tag->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000);
}
template <class T>
static __forceinline void LowerTagTransfer(T tag, u32* ptag)
{
//QWC set to lower 16bits of the tag
tag->qwc = (u16)ptag[0];
}
// Transfer a tag.
template <class T>
static __forceinline bool TransferTag(const char *s, T tag, u32* ptag)
{
if (ptag == NULL) // Is ptag empty?
{
Console::Error("%s BUSERR", params s);
UpperTagTransfer(tag, ptag);
// Set BEIS (BUSERR) in DMAC_STAT register
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS;
return false;
}
else
{
UpperTagTransfer(tag, ptag);
LowerTagTransfer(tag, ptag);
return true;
}
}
// Actually, looks like I didn't need templates after all... :)
enum pce_values
{
@ -97,8 +56,73 @@ enum chcr_flags
CHCR_STR = 0x100 // Start. 0 while stopping DMA, 1 while it's running.
};
namespace ChainTags
enum TransferMode
{
NORMAL_MODE = 0,
CHAIN_MODE,
INTERLEAVE_MODE,
UNDEFINED_MODE
};
namespace Tag
{
// Transfer functions,
static __forceinline void UpperTransfer(DMACh *tag, u32* ptag)
{
// Transfer upper part of tag to CHCR bits 31-15
tag->chcr = (tag->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000);
}
static __forceinline void LowerTransfer(DMACh *tag, u32* ptag)
{
//QWC set to lower 16bits of the tag
tag->qwc = (u16)ptag[0];
}
static __forceinline bool Transfer(const char *s, DMACh *tag, u32* ptag)
{
if (ptag == NULL) // Is ptag empty?
{
Console::Error("%s BUSERR", params s);
UpperTransfer(tag, ptag);
// Set BEIS (BUSERR) in DMAC_STAT register
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS;
return false;
}
else
{
UpperTransfer(tag, ptag);
LowerTransfer(tag, ptag);
return true;
}
}
/*// Not sure if I'll need this one.
static __forceinline bool SafeTransfer(const char *s, DMACh *tag, u32* ptag)
{
if (ptag == NULL) // Is ptag empty?
{
Console::Error("%s BUSERR", params s);
// Set BEIS (BUSERR) in DMAC_STAT register
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS;
return false;
}
else
{
UpperTransfer(tag, ptag);
LowerTransfer(tag, ptag);
return true;
}
}*/
static __forceinline void UnsafeTransfer(DMACh *tag, u32* ptag)
{
UpperTransfer(tag, ptag);
LowerTransfer(tag, ptag);
}
// Untested
static __forceinline u16 QWC(u32 *tag)
{
@ -116,6 +140,11 @@ namespace ChainTags
return (tag_id)((tag[0] >> 28) & 0x7);
}
static __forceinline tag_id Id(u32 tag)
{
return (tag_id)((tag >> 28) & 0x7);
}
static __forceinline bool IRQ(u32 *tag)
{
return !!(tag[0] & 0x8000000);
@ -130,58 +159,34 @@ namespace ChainTags
namespace CHCR
{
// Query the flags in the channel control register.
template <class T>
static __forceinline bool STR(T tag) { return !!(tag->chcr & CHCR_STR); }
template <class T>
static __forceinline bool TIE(T tag) { return !!(tag->chcr & CHCR_TIE); }
template <class T>
static __forceinline bool TTE(T tag) { return !!(tag->chcr & CHCR_TTE); }
template <class T>
static __forceinline u8 DIR(T tag) { return (tag->chcr & CHCR_DIR); }
template <class T>
static __forceinline TransferMode MOD(T tag)
static __forceinline bool STR(DMACh *tag) { return !!(tag->chcr & CHCR_STR); }
static __forceinline bool TIE(DMACh *tag) { return !!(tag->chcr & CHCR_TIE); }
static __forceinline bool TTE(DMACh *tag) { return !!(tag->chcr & CHCR_TTE); }
static __forceinline u8 DIR(DMACh *tag) { return !!(tag->chcr & CHCR_DIR); }
static __forceinline TransferMode MOD(DMACh *tag)
{
return (TransferMode)((tag->chcr & CHCR_MOD) >> 2);
}
template <class T>
static __forceinline u8 ASP(T tag)
static __forceinline u8 ASP(DMACh *tag)
{
return (TransferMode)((tag->chcr & CHCR_ASP) >> 2);
}
// Clear the individual flags.
template <class T>
static __forceinline void clearSTR(T tag) { tag->chcr &= ~CHCR_STR; }
template <class T>
static __forceinline void clearTIE(T tag) { tag->chcr &= ~CHCR_TIE; }
template <class T>
static __forceinline void clearTTE(T tag) { tag->chcr &= ~CHCR_TTE; }
template <class T>
static __forceinline void clearDIR(T tag) { tag->chcr &= ~CHCR_DIR; }
static __forceinline void clearSTR(/*T*/DMACh *tag) { tag->chcr &= ~CHCR_STR; }
static __forceinline void clearTIE(DMACh *tag) { tag->chcr &= ~CHCR_TIE; }
static __forceinline void clearTTE(DMACh *tag) { tag->chcr &= ~CHCR_TTE; }
static __forceinline void clearDIR(DMACh *tag) { tag->chcr &= ~CHCR_DIR; }
// Set them.
template <class T>
static __forceinline void setSTR(T tag) { tag->chcr |= CHCR_STR; }
static __forceinline void setSTR(DMACh *tag) { tag->chcr |= CHCR_STR; }
static __forceinline void setTIE(DMACh *tag) { tag->chcr |= CHCR_TIE; }
static __forceinline void setTTE(DMACh *tag) { tag->chcr |= CHCR_TTE; }
static __forceinline void setDIR(DMACh *tag) { tag->chcr |= CHCR_DIR; }
template <class T>
static __forceinline void setTIE(T tag) { tag->chcr |= CHCR_TIE; }
template <class T>
static __forceinline void setTTE(T tag) { tag->chcr |= CHCR_TTE; }
template <class T>
static __forceinline void setDIR(T tag) { tag->chcr |= CHCR_DIR; }
template <class T>
static __forceinline void setMOD(T tag, TransferMode mode)
static __forceinline void setMOD(DMACh *tag, TransferMode mode)
{
if (mode & (1 << 0))
tag->chcr |= CHCR_MOD1;
@ -194,8 +199,7 @@ namespace CHCR
tag->chcr &= CHCR_MOD2;
}
template <class T>
static __forceinline void setASP(T tag, u8 num)
static __forceinline void setASP(DMACh *tag, u8 num)
{
if (num & (1 << 0))
tag->chcr |= CHCR_ASP1;
@ -209,8 +213,7 @@ namespace CHCR
}
// Print information about a chcr tag.
template <class T>
static __forceinline void Print(const char* s, T tag)
static __forceinline void Print(const char* s, DMACh *tag)
{
u8 num_addr = ASP(tag);
TransferMode mode = MOD(tag);
@ -232,4 +235,18 @@ namespace CHCR
if (STR(tag)) Console::Write(" (DMA started)."); else Console::Write(" (DMA stopped).");
Console::WriteLn("");
}
}
}
namespace QWC
{
static __forceinline bool Empty(DMACh *tag)
{
return (tag->qwc == 0);
}
static __forceinline void Clear(DMACh *tag)
{
tag->qwc == 0;
}
}

View File

@ -23,6 +23,7 @@
#include "VUmicro.h"
#include "GS.h"
#include "VifDma.h"
#include "Tags.h"
#include <xmmintrin.h>
#include <emmintrin.h>
@ -425,23 +426,19 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int
{
vif->tag.addr += (((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + ((4 - ft->qsize) + unpacksize)) * 4;
dest += ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + (4 - ft->qsize) + unpacksize;
if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
}
else
{
vif->tag.addr += ((4 - ft->qsize) + unpacksize) * 4;
dest += (4 - ft->qsize) + unpacksize;
if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
}
if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
cdata += unpacksize * ft->dsize;
vif->cl = 0;
VIFUNPACK_LOG("Aligning packet done size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr);
@ -451,12 +448,14 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int
else
{
vif->tag.addr += ((4 - ft->qsize) + unpacksize) * 4;
dest += (4 - ft->qsize) + unpacksize;
if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
dest += (4 - ft->qsize) + unpacksize;
if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
cdata += unpacksize * ft->dsize;
VIFUNPACK_LOG("Aligning packet done size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr);
}
@ -468,7 +467,7 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int
if (vifRegs->cycle.cl >= vifRegs->cycle.wl) // skipping write
{
if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
@ -498,7 +497,9 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int
dest += 4;
vif->tag.addr += 16;
}
if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
// Hurrah for the 4th occurrance of this piece of code in this function...
if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
@ -629,7 +630,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
((memlimit + (vifRegs->cycle.cl - vifRegs->cycle.wl) * 16) == tempsize) ||
(tempsize == memlimit)))
{
//Its a red herring! so ignore it! SSE unpacks will be much quicker
//It's a red herring, so ignore it! SSE unpacks will be much quicker.
tempsize = 0;
}
else
@ -985,6 +986,7 @@ static int __fastcall Vif0TransNull(u32 *data) // Shouldnt go here
vif0.cmd = 0;
return 0;
}
static int __fastcall Vif0TransSTMask(u32 *data) // STMASK
{
SetNewMask(g_vif0Masks, g_vif0HasMask3, data[0], vif0Regs->mask);
@ -1372,30 +1374,24 @@ int _chainVIF0()
int id, ret;
vif0ptag = (u32*)dmaGetAddr(vif0ch->tadr); //Set memory pointer to TADR
if (vif0ptag == NULL) //Is vif0ptag empty?
{
Console::Error("Vif0 Tag BUSERR");
vif0ch->chcr = (vif0ch->chcr & 0xFFFF) | ((*vif0ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register
return -1; //Return -1 as an error has occurred
}
id = (vif0ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
vif0ch->qwc = (u16)vif0ptag[0]; //QWC set to lower 16bits of the tag
vif0ch->madr = vif0ptag[1]; //MADR = ADDR field
g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag
if (!(Tag::Transfer("Vif0 Tag", vif0ch, vif0ptag))) return -1;
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
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);
vif0ch->chcr = (vif0ch->chcr & 0xFFFF) | ((*vif0ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
// Transfer dma tag if tte is set
if (vif0ch->chcr & 0x40)
if (CHCR::TTE(vif0ch))
{
if (vif0.vifstalled)
ret = VIF0transfer(vif0ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset, 1); //Transfer Tag on stall
else
ret = VIF0transfer(vif0ptag + 2, 2, 1); //Transfer Tag
if (ret == -1) return -1; //There has been an error
if (ret == -2) return -2; //IRQ set by VIFTransfer
}
@ -1407,7 +1403,7 @@ int _chainVIF0()
ret = _VIF0chain(); //Transfers the data set by the switch
if ((vif0ch->chcr & 0x80) && (vif0ptag[0] >> 31)) //Check TIE bit of CHCR and IRQ bit of tag
if (CHCR::TIE(vif0ch) && Tag::IRQ(vif0ptag)) //Check TIE bit of CHCR and IRQ bit of tag
{
VIF_LOG("dmaIrq Set\n");
@ -1446,9 +1442,9 @@ void vif0Interrupt()
}
}
if ((vif0ch->chcr & 0x100) == 0) Console::WriteLn("Vif0 running when CHCR = %x", params vif0ch->chcr);
if (!CHCR::STR(vif0ch)) Console::WriteLn("Vif0 running when CHCR = %x", params vif0ch->chcr);
if ((vif0ch->chcr & 0x4) && (!vif0.done) && (!vif0.vifstalled))
if ((CHCR::MOD(vif0ch) == CHAIN_MODE) && (!vif0.done) && (!vif0.vifstalled))
{
if (!(psHu32(DMAC_CTRL) & 0x1))
@ -1469,7 +1465,7 @@ void vif0Interrupt()
if (vif0ch->qwc > 0) Console::WriteLn("VIF0 Ending with QWC left");
if (vif0.cmd != 0) Console::WriteLn("vif0.cmd still set %x", params vif0.cmd);
vif0ch->chcr &= ~0x100;
CHCR::clearSTR(vif0ch);
hwDmacIrq(DMAC_VIF0);
vif0Regs->stat &= ~0xF000000; // FQC=0
}
@ -1658,7 +1654,7 @@ void vif0Reset()
memzero_obj(*vif0Regs);
SetNewMask(g_vif0Masks, g_vif0HasMask3, 0, 0xffffffff);
psHu64(VIF0_FIFO) = 0;
psHu64(0x10004008) = 0; // VIF0_FIFO + 8
psHu64(VIF0_FIFO + 8) = 0;
vif0Regs->stat &= ~VIF0_STAT_VPS;
vif0.done = true;
vif0Regs->stat &= ~0xF000000; // FQC=0
@ -1866,7 +1862,7 @@ static int __fastcall Vif1TransDirectHL(u32 *data)
if ((vif1.cmd & 0x7f) == 0x51)
{
if (gif->chcr & 0x100 && (!vif1Regs->mskpath3 && (Path3progress == IMAGE_MODE))) //PATH3 is in image mode, so wait for end of transfer
if (CHCR::STR(gif) && (!vif1Regs->mskpath3 && (Path3progress == IMAGE_MODE))) //PATH3 is in image mode, so wait for end of transfer
{
vif1Regs->stat |= VIF1_STAT_VGW;
return 0;
@ -1961,8 +1957,7 @@ static int __fastcall Vif1TransUnpack(u32 *data)
if (vif1.vifpacketsize < vif1.tag.size)
{
int ret = vif1.tag.size;
/* size is less that the total size, transfer is
'in pieces' */
/* size is less that the total size, transfer is 'in pieces' */
if(vif1Regs->offset != 0 || vif1.cl != 0)
{
vif1.tag.size -= vif1.vifpacketsize - VIFalign(data, &vif1.tag, vif1.vifpacketsize, VIF1dmanum);
@ -2073,7 +2068,7 @@ void Vif1MskPath3() // MSKPATH3
}
static void Vif1CMDMskPath3() // MSKPATH3
{
if(vif1ch->chcr & 0x100)
if (CHCR::STR(vif1ch))
{
schedulepath3msk = 0x10 | ((vif1Regs->code >> 15) & 0x1);
vif1.vifstalled = true;
@ -2101,7 +2096,7 @@ static void Vif1CMDFlush() // FLUSH/E/A
if ((vif1.cmd & 0x7f) == 0x13)
{
// Gif is already transferring so wait for it.
if (((Path3progress != STOPPED_MODE) || !vif1Regs->mskpath3) && gif->chcr & 0x100)
if (((Path3progress != STOPPED_MODE) || !vif1Regs->mskpath3) && CHCR::STR(gif))
{
vif1Regs->stat |= VIF1_STAT_VGW;
CPU_INT(2, 4);
@ -2236,7 +2231,9 @@ int VIF1transfer(u32 *data, int size, int istag)
ret = Vif1TransTLB[vif1.cmd](data);
data += ret;
vif1.vifpacketsize -= ret;
if (vif1.cmd == 0) vif1Regs->stat &= ~VIF1_STAT_VPS_T; //We are once again waiting for a new vifcode as the command has cleared
//We are once again waiting for a new vifcode as the command has cleared
if (vif1.cmd == 0) vif1Regs->stat &= ~VIF1_STAT_VPS_T;
continue;
}
@ -2303,8 +2300,7 @@ int VIF1transfer(u32 *data, int size, int istag)
if (((vif1Regs->code >> 24) & 0x7f) != 0x7) vif1Regs->stat |= VIF1_STAT_VIS; // Note: commenting this out fixes WALL-E
if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1))
vif1.inprogress &= ~0x1;
if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1)) vif1.inprogress &= ~0x1;
// spiderman doesn't break on qw boundaries
if (istag) return -2;
@ -2334,8 +2330,7 @@ int VIF1transfer(u32 *data, int size, int istag)
}
if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1))
vif1.inprogress &= ~0x1;
if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1)) vif1.inprogress &= ~0x1;
return vif1.vifstalled ? -2 : 0;
}
@ -2406,7 +2401,7 @@ int _VIF1chain()
return 0;
}
if (vif1.dmamode == VIF_NORMAL_MEM_MODE)
if (vif1.dmamode == VIF_NORMAL_FROM_MEM_MODE)
{
vif1TransferFromMemory();
vif1.inprogress = 0;
@ -2435,40 +2430,31 @@ int _VIF1chain()
bool _chainVIF1()
{
return vif1.done;//Return Done
return vif1.done; // Return Done
}
__forceinline void vif1SetupTransfer()
{
switch (vif1.dmamode)
{
case VIF_NORMAL_MODE: //Normal
case VIF_NORMAL_MEM_MODE: //Normal (From memory)
case VIF_NORMAL_TO_MEM_MODE: // Normal
case VIF_NORMAL_FROM_MEM_MODE: // Normal (From memory)
vif1.inprogress = 1;
vif1.done = true;
g_vifCycles = 2;
break;
case VIF_CHAIN_MODE: //Chain
case VIF_CHAIN_MODE: // Chain
int id;
int ret;
vif1ptag = (u32*)dmaGetAddr(vif1ch->tadr); //Set memory pointer to TADR
if (vif1ptag == NULL) //Is vif0ptag empty?
{
Console::Error("Vif1 Tag BUSERR");
vif1ch->chcr = (vif1ch->chcr & 0xFFFF) | ((*vif1ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register
return; //Return -1 as an error has occurred
}
id = (vif1ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
vif1ch->qwc = (u16)vif1ptag[0]; //QWC set to lower 16bits of the tag
if (!(Tag::Transfer("Vif1 Tag", vif1ch, vif1ptag))) return;
vif1ch->madr = vif1ptag[1]; //MADR = ADDR field
vif1ch->chcr = (vif1ch->chcr & 0xFFFF) | ((*vif1ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
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
@ -2488,7 +2474,7 @@ __forceinline void vif1SetupTransfer()
vif1.inprogress = 1;
if (vif1ch->chcr & 0x40)
if (CHCR::TTE(vif1ch))
{
if (vif1.vifstalled)
@ -2506,12 +2492,13 @@ __forceinline void vif1SetupTransfer()
vif1.irqoffset = 0;
vif1.done |= hwDmacSrcChainWithStack(vif1ch, id);
if ((vif1ch->chcr & 0x80) && (vif1ptag[0] >> 31)) //Check TIE bit of CHCR and IRQ bit of tag
//Check TIE bit of CHCR and IRQ bit of tag
if ((CHCR::TIE(vif1ch)) && (Tag::IRQ(vif1ptag)))
{
VIF_LOG("dmaIrq Set");
vif1.done = true;
return; //End Transfer
return; //End Transfer
}
break;
}
@ -2527,7 +2514,7 @@ __forceinline void vif1Interrupt()
if((vif1Regs->stat & VIF1_STAT_VGW))
{
if(gif->chcr & 0x100)
if (CHCR::STR(gif))
{
CPU_INT(1, gif->qwc * BIAS);
return;
@ -2536,7 +2523,7 @@ __forceinline void vif1Interrupt()
}
if ((vif1ch->chcr & 0x100) == 0) Console::WriteLn("Vif1 running when CHCR == %x", params vif1ch->chcr);
if (!(CHCR::STR(vif1ch))) Console::WriteLn("Vif1 running when CHCR == %x", params vif1ch->chcr);
if (vif1.irq && vif1.tag.size == 0)
{
@ -2601,7 +2588,7 @@ __forceinline void vif1Interrupt()
//Games effected by setting, Fatal Frame, KH2, Shox, Crash N Burn, GT3/4 possibly
//Im guessing due to the full gs fifo before the reverse? (Refraction)
//Note also this is only the condition for reverse fifo mode, normal direction clears it as normal
if(!vif1Regs->mskpath3 || (vif1ch->chcr & 0x1))vif1Regs->stat &= ~0x1F000000; // FQC=0
if (!vif1Regs->mskpath3 || (CHCR::DIR(vif1ch))) vif1Regs->stat &= ~0x1F000000; // FQC=0
}
void dmaVIF1()
@ -2617,7 +2604,7 @@ void dmaVIF1()
if (((psHu32(DMAC_CTRL) & 0xC) == 0x8)) // VIF MFIFO
{
//Console::WriteLn("VIFMFIFO\n");
if (!(vif1ch->chcr & 0x4)) Console::WriteLn("MFIFO mode != Chain! %x", params vif1ch->chcr);
if (CHCR::MOD(vif1ch) != CHAIN_MODE) Console::WriteLn("MFIFO mode != Chain! %x", params vif1ch->chcr);
vifMFIFOInterrupt();
return;
}
@ -2629,23 +2616,23 @@ void dmaVIF1()
}
#endif
if (!(vif1ch->chcr & 0x4) || vif1ch->qwc > 0) // Normal Mode
if ((CHCR::MOD(vif1ch) == NORMAL_MODE) || vif1ch->qwc > 0) // Normal Mode
{
if ((psHu32(DMAC_CTRL) & 0xC0) == 0x40)
Console::WriteLn("DMA Stall Control on VIF1 normal");
if ((vif1ch->chcr & 0x1)) // to Memory
vif1.dmamode = VIF_NORMAL_MODE;
if ((CHCR::DIR(vif1ch))) // to Memory
vif1.dmamode = VIF_NORMAL_TO_MEM_MODE;
else
vif1.dmamode = VIF_NORMAL_MEM_MODE;
vif1.dmamode = VIF_NORMAL_FROM_MEM_MODE;
}
else
{
vif1.dmamode = VIF_CHAIN_MODE;
}
if(vif1.dmamode != VIF_NORMAL_MEM_MODE)
if (vif1.dmamode != VIF_NORMAL_FROM_MEM_MODE)
vif1Regs->stat |= 0x10000000; // FQC=16
else
vif1Regs->stat |= min((u16)16, vif1ch->qwc) << 24; // FQC=16
@ -2677,14 +2664,16 @@ void vif1Write32(u32 mem, u32 value)
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
vif1ch->qwc = 0; //?
psHu64(VIF1_FIFO) = 0;
psHu64(0x10005008) = 0; // VIF1_FIFO + 8
psHu64(VIF1_FIFO + 8) = 0;
vif1.done = true;
if(vif1Regs->mskpath3)
{
vif1Regs->mskpath3 = 0;
psHu32(GIF_STAT) &= ~0x2;
if(gif->chcr & 0x100) CPU_INT(2, 4);
if (CHCR::STR(gif)) CPU_INT(2, 4);
}
vif1Regs->err = 0;
vif1.inprogress = 0;
vif1Regs->stat &= ~(0x1F800000 | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS); // FQC=0
@ -2741,7 +2730,7 @@ void vif1Write32(u32 mem, u32 value)
// Gets the timing right - Flatout
CPU_INT(1, vif1ch->qwc * BIAS);
}
vif1ch->chcr |= 0x100;
CHCR::setSTR(vif1ch);
}
}
}

View File

@ -20,8 +20,8 @@
enum VifModes
{
VIF_NORMAL_MODE = 0,
VIF_NORMAL_MEM_MODE = 1,
VIF_NORMAL_TO_MEM_MODE = 0,
VIF_NORMAL_FROM_MEM_MODE = 1,
VIF_CHAIN_MODE = 2
};