mirror of
https://github.com/libretro/pcsx2.git
synced 2024-12-23 02:08:27 +00:00
Various changes, mainly Gif related cleanup. Fixed SafeArray.h to work with Linux again while I'm at it...
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1432 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
95db132180
commit
7f00193900
@ -440,11 +440,6 @@ int CPCOND0() {
|
||||
|
||||
//#define CPCOND0 1
|
||||
|
||||
/*#define BC0(cond) \
|
||||
if (CPCOND0() cond) { \
|
||||
intDoBranch(_BranchTarget_); \
|
||||
}*/
|
||||
|
||||
void BC0F() {
|
||||
if (CPCOND0() == 0) intDoBranch(_BranchTarget_);
|
||||
COP0_LOG( "COP0 > BC0F" );
|
||||
@ -454,11 +449,6 @@ void BC0T() {
|
||||
if (CPCOND0() == 1) intDoBranch(_BranchTarget_);
|
||||
COP0_LOG( "COP0 > BC0T" );
|
||||
}
|
||||
|
||||
/*#define BC0L(cond) \
|
||||
if (CPCOND0() cond) { \
|
||||
intDoBranch(_BranchTarget_); \
|
||||
} else cpuRegs.pc+= 4;*/
|
||||
|
||||
void BC0FL() {
|
||||
if (CPCOND0() == 0)
|
||||
|
@ -277,7 +277,7 @@ extern mtgsThreadObject* mtgsThread;
|
||||
|
||||
void mtgsWaitGS();
|
||||
bool mtgsOpen();
|
||||
void mtgsRingBufSimplePacket( s32 command, u32 data0, u32 data1, u32 data2 );
|
||||
//void mtgsRingBufSimplePacket( s32 command, u32 data0, u32 data1, u32 data2 );
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Generalized GS Functions and Stuff
|
||||
|
385
pcsx2/Gif.cpp
385
pcsx2/Gif.cpp
@ -38,6 +38,7 @@ enum gifstate_t
|
||||
};
|
||||
|
||||
// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished).
|
||||
// Should be a gifstate_t rather then int, but I don't feel like possibly interfering with savestates right now.
|
||||
static int gifstate = GIF_STATE_READY;
|
||||
|
||||
static u64 s_gstag = 0; // used for querying the last tag
|
||||
@ -48,25 +49,39 @@ static int gspath3done = 0;
|
||||
|
||||
static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0;
|
||||
static u32 gifqwc = 0;
|
||||
bool gifmfifoirq = FALSE;
|
||||
bool gifmfifoirq = false;
|
||||
|
||||
__forceinline void gsInterrupt() {
|
||||
static __forceinline void clearFIFOstuff(bool full)
|
||||
{
|
||||
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||
|
||||
if (full)
|
||||
GSCSRr |= 0x8000; //FIFO full
|
||||
else
|
||||
GSCSRr |= 0x4000; //FIFO empty
|
||||
}
|
||||
|
||||
__forceinline void gsInterrupt()
|
||||
{
|
||||
GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle);
|
||||
|
||||
if((gif->chcr & 0x100) == 0){
|
||||
if ((gif->chcr & 0x100) == 0)
|
||||
{
|
||||
//Console::WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", params gif->chcr, gif->qwc, done);
|
||||
return;
|
||||
}
|
||||
|
||||
if((vif1.cmd & 0x7f) == 0x51)
|
||||
if ((vif1.cmd & 0x7f) == 0x51)
|
||||
{
|
||||
if(Path3progress != 0)vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||
if (Path3progress != IMAGE_MODE) vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||
}
|
||||
|
||||
if(Path3progress == 2) psHu32(GIF_STAT)&= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0
|
||||
if (Path3progress == STOPPED_MODE) psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0
|
||||
|
||||
if (gif->qwc > 0 || gspath3done == 0) {
|
||||
if (!(psHu32(DMAC_CTRL) & 0x1)) {
|
||||
if ((gif->qwc > 0) || (gspath3done == 0))
|
||||
{
|
||||
if (!(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
Console::Notice("gs dma masked, re-scheduling...");
|
||||
// re-raise the int shortly in the future
|
||||
CPU_INT( 2, 64 );
|
||||
@ -77,16 +92,16 @@ __forceinline void gsInterrupt() {
|
||||
return;
|
||||
}
|
||||
|
||||
vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||
gspath3done = 0;
|
||||
gscycles = 0;
|
||||
gif->chcr &= ~0x100;
|
||||
vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||
|
||||
psHu32(GIF_STAT)&= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0
|
||||
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||
GSCSRr |= 0x4000; //FIFO empty
|
||||
psHu32(GIF_STAT) &= ~GIF_STAT_P3Q;
|
||||
//psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
|
||||
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
|
||||
psHu32(GIF_STAT) &= ~0x1F000000; // QFC=0
|
||||
|
||||
clearFIFOstuff(false);
|
||||
hwDmacIrq(DMAC_GIF);
|
||||
GIF_LOG("GIF DMA end");
|
||||
|
||||
@ -96,7 +111,6 @@ static u32 WRITERING_DMA(u32 *pMem, u32 qwc)
|
||||
{
|
||||
psHu32(GIF_STAT) |= GIF_STAT_APATH3 | GIF_STAT_OPH;
|
||||
|
||||
|
||||
if( mtgsThread != NULL )
|
||||
{
|
||||
int sizetoread = qwc;
|
||||
@ -126,13 +140,15 @@ static u32 WRITERING_DMA(u32 *pMem, u32 qwc)
|
||||
}
|
||||
}
|
||||
|
||||
int _GIFchain() {
|
||||
|
||||
u32 qwc = /*((psHu32(GIF_MODE) & 0x4) || vif1Regs->mskpath3) ? min(8, (int)gif->qwc) :*/ min( gifsplit, (int)gif->qwc );
|
||||
int _GIFchain()
|
||||
{
|
||||
//u32 qwc = ((psHu32(GIF_MODE) & 0x4) || vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : min( gifsplit, (int)gif->qwc );
|
||||
u32 qwc = min( gifsplit, (int)gif->qwc );
|
||||
u32 *pMem;
|
||||
|
||||
pMem = (u32*)dmaGetAddr(gif->madr);
|
||||
if (pMem == NULL) {
|
||||
if (pMem == NULL)
|
||||
{
|
||||
// reset path3, fixes dark cloud 2
|
||||
gsGIFSoftReset(4);
|
||||
|
||||
@ -142,11 +158,8 @@ int _GIFchain() {
|
||||
Console::Notice( "Hackfix - NULL GIFchain" );
|
||||
return -1;
|
||||
}
|
||||
qwc = WRITERING_DMA(pMem, qwc);
|
||||
|
||||
/*gif->madr+= qwc*16;
|
||||
gif->qwc -= qwc;*/
|
||||
return (qwc);
|
||||
return (WRITERING_DMA(pMem, qwc));
|
||||
}
|
||||
|
||||
static __forceinline void GIFchain()
|
||||
@ -156,17 +169,47 @@ static __forceinline void GIFchain()
|
||||
FreezeRegs(0);
|
||||
}
|
||||
|
||||
static __forceinline void dmaGIFend()
|
||||
static __forceinline bool checkTieBit(u32* &ptag)
|
||||
{
|
||||
CPU_INT(2, 16);
|
||||
if ((gif->chcr & 0x80) && (ptag[0] >> 31)) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
{
|
||||
GIF_LOG("dmaIrq Set");
|
||||
gspath3done = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// These could probably be consolidated into one function,
|
||||
// but I wasn't absolutely sure if there was a good reason
|
||||
// not to do the gif->qwc != 0 check. --arcum42
|
||||
static __forceinline void GIFdmaEnd()
|
||||
static __forceinline bool ReadTag(u32* &ptag, u32 &id)
|
||||
{
|
||||
CPU_INT(2, gscycles * BIAS);
|
||||
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
|
||||
|
||||
if (ptag == NULL) //Is ptag empty?
|
||||
{
|
||||
//If yes, set BEIS (BUSERR) in DMAC_STAT register
|
||||
psHu32(DMAC_STAT)|= DMAC_STAT_BEIS;
|
||||
return false;
|
||||
}
|
||||
gscycles+=2; // Add 1 cycles from the QW read for the tag
|
||||
gif->chcr = ( gif->chcr & 0xFFFF ) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
|
||||
|
||||
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
|
||||
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||
gif->madr = ptag[1]; //MADR = ADDR field
|
||||
|
||||
gspath3done = hwDmacSrcChainWithStack(gif, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
static __forceinline void ReadTag2(u32* &ptag)
|
||||
{
|
||||
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
|
||||
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
|
||||
gif->madr = ptag[1];
|
||||
|
||||
gspath3done = hwDmacSrcChainWithStack(gif, (ptag[0] >> 28) & 0x7);
|
||||
}
|
||||
|
||||
void GIFdma()
|
||||
@ -174,200 +217,167 @@ void GIFdma()
|
||||
u32 *ptag;
|
||||
u32 id;
|
||||
|
||||
gscycles= prevcycles ? prevcycles: 0;
|
||||
gscycles = prevcycles;
|
||||
|
||||
if ((psHu32(GIF_CTRL) & 8)) { // temporarily stop
|
||||
if ((psHu32(GIF_CTRL) & 8)) // temporarily stop
|
||||
{
|
||||
Console::WriteLn("Gif dma temp paused?");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80 && prevcycles != 0) { // STD == GIF
|
||||
if (((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && (prevcycles != 0)) // STD == GIF
|
||||
{
|
||||
Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", params (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3, gif->madr, psHu32(DMAC_STADR));
|
||||
|
||||
if( gif->madr + (gif->qwc * 16) > psHu32(DMAC_STADR) ) {
|
||||
if ((gif->madr + (gif->qwc * 16)) > psHu32(DMAC_STADR))
|
||||
{
|
||||
CPU_INT(2, gscycles);
|
||||
gscycles = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
prevcycles = 0;
|
||||
gif->qwc = 0;
|
||||
}
|
||||
|
||||
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||
GSCSRr |= 0x8000; //FIFO full
|
||||
psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [ used to be 0xE00; // OPH=1 | APATH=3]
|
||||
|
||||
if(((psHu32(GIF_STAT) & 0x100) || (vif1.cmd & 0x7f) == 0x50) && (psHu32(GIF_MODE) & 0x4) && Path3progress == 0) //Path2 gets priority in intermittent mode
|
||||
clearFIFOstuff(true);
|
||||
psHu32(GIF_STAT) |= 0x10000000; // FQC=31, hack ;) [ used to be 0xE00; // OPH=1 | APATH=3]
|
||||
|
||||
//Path2 gets priority in intermittent mode
|
||||
if (((psHu32(GIF_STAT) & 0x100) || (vif1.cmd & 0x7f) == 0x50) && (psHu32(GIF_MODE) & 0x4) && (Path3progress == IMAGE_MODE))
|
||||
{
|
||||
GIF_LOG("Waiting VU %x, PATH2 %x, GIFMODE %x Progress %x", psHu32(GIF_STAT) & 0x100, (vif1.cmd & 0x7f), psHu32(GIF_MODE), Path3progress);
|
||||
dmaGIFend();
|
||||
CPU_INT(2, 16);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1)) {
|
||||
if(gif->qwc == 0) {
|
||||
if((gif->chcr & 0x10c) == 0x104) {
|
||||
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
|
||||
|
||||
if (ptag == NULL) { //Is ptag empty?
|
||||
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register
|
||||
return;
|
||||
}
|
||||
gscycles += 2;
|
||||
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
|
||||
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
|
||||
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||
gif->madr = ptag[1]; //MADR = ADDR field
|
||||
gspath3done = hwDmacSrcChainWithStack(gif, id);
|
||||
if (vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))
|
||||
{
|
||||
if (gif->qwc == 0)
|
||||
{
|
||||
if ((gif->chcr & 0x10c) == 0x104)
|
||||
{
|
||||
if (!ReadTag(ptag, id)) return;
|
||||
GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr);
|
||||
|
||||
if ((gif->chcr & 0x80) && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag
|
||||
GIF_LOG("PATH3 MSK dmaIrq Set");
|
||||
Console::WriteLn("GIF TIE");
|
||||
gspath3done |= 1;
|
||||
}
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (checkTieBit(ptag)) GIF_LOG("PATH3 MSK dmaIrq Set");
|
||||
}
|
||||
}
|
||||
|
||||
if(Path3progress == 2 /*|| (vif1Regs->stat |= VIF1_STAT_VGW) == 0*/)
|
||||
if (Path3progress == STOPPED_MODE) /*|| (vif1Regs->stat |= VIF1_STAT_VGW) == 0*/
|
||||
{
|
||||
vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||
if(gif->qwc == 0)dmaGIFend();
|
||||
if (gif->qwc == 0) CPU_INT(2, 16);
|
||||
return;
|
||||
}
|
||||
|
||||
GIFchain();
|
||||
GIFdmaEnd();
|
||||
CPU_INT(2, gscycles * BIAS);
|
||||
return;
|
||||
}
|
||||
|
||||
// Transfer Dn_QWC from Dn_MADR to GIF
|
||||
if ((gif->chcr & 0xc) == 0 || gif->qwc > 0) { // Normal Mode
|
||||
if (((gif->chcr & 0xc) == 0) || (gif->qwc > 0)) // Normal Mode
|
||||
{
|
||||
|
||||
if ((((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && ((gif->chcr & 0xc) == 0))) {
|
||||
if (((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && ((gif->chcr & 0xc) == 0))
|
||||
{
|
||||
Console::WriteLn("DMA Stall Control on GIF normal");
|
||||
}
|
||||
|
||||
GIFchain(); //Transfers the data set by the switch
|
||||
|
||||
GIFdmaEnd();
|
||||
CPU_INT(2, gscycles * BIAS);
|
||||
return;
|
||||
}
|
||||
if ((gif->chcr & 0xc) == 0x4 && gspath3done == 0)
|
||||
if (((gif->chcr & 0xc) == 0x4) && (gspath3done == 0)) // Chain Mode
|
||||
{
|
||||
// Chain Mode
|
||||
//while ((gspath3done == 0) && (gif->qwc == 0)) { //Loop if the transfers aren't intermittent
|
||||
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
|
||||
if (ptag == NULL) { //Is ptag empty?
|
||||
psHu32(DMAC_STAT)|= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register
|
||||
if (!ReadTag(ptag, id)) return;
|
||||
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr);
|
||||
|
||||
if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80) // STD == GIF
|
||||
{
|
||||
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
|
||||
if (!gspath3done && ((gif->madr + (gif->qwc * 16)) > psHu32(DMAC_STADR)) && (id == 4))
|
||||
{
|
||||
// stalled
|
||||
Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", params (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR));
|
||||
prevcycles = gscycles;
|
||||
gif->tadr -= 16;
|
||||
hwDmacIrq(DMAC_13);
|
||||
CPU_INT(2, gscycles);
|
||||
gscycles = 0;
|
||||
return;
|
||||
}
|
||||
gscycles+=2; // Add 1 cycles from the QW read for the tag
|
||||
|
||||
// We used to transfer dma tags if tte is set here
|
||||
|
||||
gif->chcr = ( gif->chcr & 0xFFFF ) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
|
||||
|
||||
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
|
||||
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||
gif->madr = ptag[1]; //MADR = ADDR field
|
||||
}
|
||||
|
||||
gspath3done = hwDmacSrcChainWithStack(gif, id);
|
||||
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr);
|
||||
|
||||
if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80) { // STD == GIF
|
||||
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
|
||||
if(!gspath3done && ((gif->madr + (gif->qwc * 16)) > psHu32(DMAC_STADR)) && (id == 4)) {
|
||||
// stalled
|
||||
Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", params (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR));
|
||||
prevcycles = gscycles;
|
||||
gif->tadr -= 16;
|
||||
hwDmacIrq(13);
|
||||
CPU_INT(2, gscycles);
|
||||
gscycles = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//GIFchain(); //Transfers the data set by the switch
|
||||
|
||||
if ((gif->chcr & 0x80) && (ptag[0] >> 31)) { //Check TIE bit of CHCR and IRQ bit of tag
|
||||
GIF_LOG("dmaIrq Set");
|
||||
gspath3done = 1;
|
||||
}
|
||||
//}
|
||||
checkTieBit(ptag);
|
||||
}
|
||||
|
||||
prevcycles = 0;
|
||||
if (gspath3done == 0 && gif->qwc == 0)
|
||||
|
||||
if ((gspath3done == 0) && (gif->qwc == 0))
|
||||
{
|
||||
|
||||
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
|
||||
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
|
||||
gif->madr = ptag[1];
|
||||
|
||||
gspath3done = hwDmacSrcChainWithStack(gif, (ptag[0] >> 28) & 0x7);
|
||||
if ((gif->chcr & 0x80) && (ptag[0] >> 31)) { //Check TIE bit of CHCR and IRQ bit of tag
|
||||
GIF_LOG("dmaIrq Set");
|
||||
gspath3done = 1;
|
||||
}
|
||||
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, (ptag[0] >> 28) & 0x7, gif->madr);
|
||||
GIFdmaEnd();
|
||||
return;
|
||||
|
||||
} else GIFdmaEnd();
|
||||
gscycles = 0;
|
||||
|
||||
checkTieBit(ptag);
|
||||
|
||||
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, (ptag[0] >> 28) & 0x7, gif->madr);
|
||||
CPU_INT(2, gscycles * BIAS);
|
||||
}
|
||||
else
|
||||
{
|
||||
CPU_INT(2, gscycles * BIAS);
|
||||
gscycles = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void dmaGIF() {
|
||||
void dmaGIF()
|
||||
{
|
||||
//We used to add wait time for the buffer to fill here, fixing some timing problems in path 3 masking
|
||||
//It takes the time of 24 QW for the BUS to become ready - The Punisher And Streetball
|
||||
GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1);
|
||||
|
||||
Path3progress = 2;
|
||||
gspath3done = 0; // For some reason this doesnt clear? So when the system starts the thread, we will clear it :)
|
||||
Path3progress = STOPPED_MODE;
|
||||
gspath3done = 0; // For some reason this doesn't clear? So when the system starts the thread, we will clear it :)
|
||||
psHu32(GIF_STAT) |= GIF_STAT_P3Q;
|
||||
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||
GSCSRr |= 0x8000; //FIFO full
|
||||
psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [used to be 0xE00; // OPH=1 | APATH=3]
|
||||
psHu32(GIF_STAT) |= 0x10000000; // FQC=31, hack ;) [used to be 0xE00; // OPH=1 | APATH=3]
|
||||
clearFIFOstuff(true);
|
||||
|
||||
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO
|
||||
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) // GIF MFIFO
|
||||
{
|
||||
//Console::WriteLn("GIF MFIFO");
|
||||
gifMFIFOInterrupt();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((gif->qwc == 0) && ((gif->chcr & 0xc) != 0)){
|
||||
if ((gif->qwc == 0) && ((gif->chcr & 0xc) != 0))
|
||||
{
|
||||
u32 *ptag;
|
||||
ptag = (u32*)dmaGetAddr(gif->tadr);
|
||||
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
|
||||
gif->madr = ptag[1];
|
||||
|
||||
|
||||
ReadTag2(ptag);
|
||||
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, (ptag[0] >> 28), gif->madr);
|
||||
|
||||
|
||||
gspath3done = hwDmacSrcChainWithStack(gif, (ptag[0] >> 28) & 0x7);
|
||||
if ((gif->chcr & 0x80) && (ptag[0] >> 31)) { //Check TIE bit of CHCR and IRQ bit of tag
|
||||
GIF_LOG("dmaIrq Set");
|
||||
gspath3done = 1;
|
||||
}
|
||||
|
||||
checkTieBit(ptag);
|
||||
GIFdma();
|
||||
//gif->qwc = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//Halflife sets a QWC amount in chain mode, no tadr set.
|
||||
if(gif->qwc > 0) gspath3done = 1;
|
||||
if (gif->qwc > 0) gspath3done = 1;
|
||||
|
||||
GIFdma();
|
||||
}
|
||||
|
||||
// called from only one location, so forceinline it:
|
||||
static __forceinline int mfifoGIFrbTransfer() {
|
||||
static __forceinline int mfifoGIFrbTransfer()
|
||||
{
|
||||
u32 mfifoqwc = min(gifqwc, (u32)gif->qwc);
|
||||
u32 *src;
|
||||
|
||||
@ -384,15 +394,19 @@ static __forceinline int mfifoGIFrbTransfer() {
|
||||
if (src == NULL) return -1;
|
||||
s1 = WRITERING_DMA(src, s1);
|
||||
|
||||
if(s1 == (mfifoqwc - s2))
|
||||
if (s1 == (mfifoqwc - s2))
|
||||
{
|
||||
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
|
||||
src = (u32*)PSM(psHu32(DMAC_RBOR));
|
||||
if (src == NULL) return -1;
|
||||
s2 = WRITERING_DMA(src, s2);
|
||||
} else s2 = 0;
|
||||
mfifoqwc = s1 + s2;
|
||||
}
|
||||
else
|
||||
{
|
||||
s2 = 0;
|
||||
}
|
||||
|
||||
mfifoqwc = s1 + s2;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -406,21 +420,18 @@ static __forceinline int mfifoGIFrbTransfer() {
|
||||
}
|
||||
|
||||
gifqwc -= mfifoqwc;
|
||||
//gif->qwc -= mfifoqwc;
|
||||
//gif->madr += mfifoqwc*16;
|
||||
//mfifocycles += (mfifoqwc) * 2; /* guessing */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// called from only one location, so forceinline it:
|
||||
static __forceinline int mfifoGIFchain() {
|
||||
static __forceinline int mfifoGIFchain()
|
||||
{
|
||||
/* Is QWC = 0? if so there is nothing to transfer */
|
||||
|
||||
if (gif->qwc == 0) return 0;
|
||||
|
||||
if (gif->madr >= psHu32(DMAC_RBOR) &&
|
||||
gif->madr <= (psHu32(DMAC_RBOR)+psHu32(DMAC_RBSR)))
|
||||
gif->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)))
|
||||
{
|
||||
if (mfifoGIFrbTransfer() == -1) return -1;
|
||||
}
|
||||
@ -431,23 +442,23 @@ static __forceinline int mfifoGIFchain() {
|
||||
if (pMem == NULL) return -1;
|
||||
|
||||
mfifoqwc = WRITERING_DMA(pMem, mfifoqwc);
|
||||
//gif->madr += mfifoqwc*16;
|
||||
//gif->qwc -= mfifoqwc;
|
||||
mfifocycles += (mfifoqwc) * 2; /* guessing */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mfifoGIFtransfer(int qwc) {
|
||||
void mfifoGIFtransfer(int qwc)
|
||||
{
|
||||
u32 *ptag;
|
||||
int id;
|
||||
u32 temp = 0;
|
||||
mfifocycles = 0;
|
||||
|
||||
gifmfifoirq = FALSE;
|
||||
gifmfifoirq = false;
|
||||
|
||||
if(qwc > 0 ) {
|
||||
if(qwc > 0 )
|
||||
{
|
||||
gifqwc += qwc;
|
||||
if (gifstate != GIF_STATE_EMPTY) return;
|
||||
gifstate &= ~GIF_STATE_EMPTY;
|
||||
@ -455,13 +466,16 @@ void mfifoGIFtransfer(int qwc) {
|
||||
|
||||
GIF_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr);
|
||||
|
||||
if (gif->qwc == 0) {
|
||||
if (gif->tadr == spr0->madr) {
|
||||
if (gif->qwc == 0)
|
||||
{
|
||||
if (gif->tadr == spr0->madr)
|
||||
{
|
||||
//if( gifqwc > 1 ) DevCon::WriteLn("gif mfifo tadr==madr but qwc = %d", params gifqwc);
|
||||
hwDmacIrq(14);
|
||||
hwDmacIrq(DMAC_14);
|
||||
gifstate |= GIF_STATE_EMPTY;
|
||||
return;
|
||||
}
|
||||
|
||||
gif->tadr = psHu32(DMAC_RBOR) + (gif->tadr & psHu32(DMAC_RBSR));
|
||||
ptag = (u32*)dmaGetAddr(gif->tadr);
|
||||
|
||||
@ -475,7 +489,8 @@ void mfifoGIFtransfer(int qwc) {
|
||||
ptag[1], ptag[0], gif->qwc, id, gif->madr, gif->tadr, gifqwc, spr0->madr);
|
||||
|
||||
gifqwc--;
|
||||
switch (id) {
|
||||
switch (id)
|
||||
{
|
||||
case 0: // Refe - Transfer Packet According to ADDR field
|
||||
gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR));
|
||||
gifstate = GIF_STATE_DONE; //End Transfer
|
||||
@ -507,7 +522,8 @@ void mfifoGIFtransfer(int qwc) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((gif->chcr & 0x80) && (ptag[0] >> 31)) {
|
||||
if ((gif->chcr & 0x80) && (ptag[0] >> 31))
|
||||
{
|
||||
SPR_LOG("dmaIrq Set");
|
||||
gifstate = GIF_STATE_DONE;
|
||||
gifmfifoirq = TRUE;
|
||||
@ -515,16 +531,15 @@ void mfifoGIFtransfer(int qwc) {
|
||||
}
|
||||
|
||||
FreezeRegs(1);
|
||||
|
||||
if (mfifoGIFchain() == -1) {
|
||||
Console::WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", params
|
||||
gif->qwc, gif->madr, gif->tadr);
|
||||
gifstate = GIF_STATE_STALL;
|
||||
}
|
||||
|
||||
if (mfifoGIFchain() == -1)
|
||||
{
|
||||
Console::WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", params
|
||||
gif->qwc, gif->madr, gif->tadr);
|
||||
gifstate = GIF_STATE_STALL;
|
||||
}
|
||||
FreezeRegs(0);
|
||||
|
||||
if(gif->qwc == 0 && gifstate == GIF_STATE_DONE) gifstate = GIF_STATE_STALL;
|
||||
if ((gif->qwc == 0) && (gifstate == GIF_STATE_DONE)) gifstate = GIF_STATE_STALL;
|
||||
CPU_INT(11,mfifocycles);
|
||||
|
||||
SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr);
|
||||
@ -533,40 +548,45 @@ void mfifoGIFtransfer(int qwc) {
|
||||
void gifMFIFOInterrupt()
|
||||
{
|
||||
mfifocycles = 0;
|
||||
if(Path3progress == 2) psHu32(GIF_STAT)&= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0
|
||||
if (Path3progress == STOPPED_MODE) psHu32(GIF_STAT)&= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0
|
||||
|
||||
if((spr0->chcr & 0x100) && spr0->qwc == 0)
|
||||
if ((spr0->chcr & 0x100) && (spr0->qwc == 0))
|
||||
{
|
||||
spr0->chcr &= ~0x100;
|
||||
hwDmacIrq(DMAC_FROM_SPR);
|
||||
}
|
||||
|
||||
if (!(gif->chcr & 0x100)) {
|
||||
if (!(gif->chcr & 0x100))
|
||||
{
|
||||
Console::WriteLn("WTF GIFMFIFO");
|
||||
cpuRegs.interrupt &= ~(1 << 11);
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
if(((psHu32(GIF_STAT) & 0x100) || (vif1.cmd & 0x7f) == 0x50) && (psHu32(GIF_MODE) & 0x4) && Path3progress == 0) //Path2 gets priority in intermittent mode
|
||||
if (((psHu32(GIF_STAT) & 0x100) || (vif1.cmd & 0x7f) == 0x50) && (psHu32(GIF_MODE) & 0x4) && Path3progress == IMAGE_MODE) //Path2 gets priority in intermittent mode
|
||||
{
|
||||
//GIF_LOG("Waiting VU %x, PATH2 %x, GIFMODE %x Progress %x", psHu32(GIF_STAT) & 0x100, (vif1.cmd & 0x7f), psHu32(GIF_MODE), Path3progress);
|
||||
CPU_INT(11,mfifocycles);
|
||||
return;
|
||||
}
|
||||
|
||||
if(gifstate != GIF_STATE_STALL) {
|
||||
if(gifqwc <= 0) {
|
||||
if (gifstate != GIF_STATE_STALL)
|
||||
{
|
||||
if (gifqwc <= 0)
|
||||
{
|
||||
//Console::WriteLn("Empty");
|
||||
gifstate |= GIF_STATE_EMPTY;
|
||||
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
|
||||
hwDmacIrq(14);
|
||||
hwDmacIrq(DMAC_14);
|
||||
return;
|
||||
}
|
||||
mfifoGIFtransfer(0);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if(gifstate == GIF_STATE_READY || gif->qwc > 0) {
|
||||
if (gifstate == GIF_STATE_READY || gif->qwc > 0)
|
||||
{
|
||||
Console::Error("gifMFIFO Panic > Shouldn't go here!");
|
||||
return;
|
||||
}
|
||||
@ -576,15 +596,16 @@ void gifMFIFOInterrupt()
|
||||
|
||||
gspath3done = 0;
|
||||
gscycles = 0;
|
||||
psHu32(GIF_STAT)&= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0
|
||||
|
||||
psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0
|
||||
psHu32(GIF_STAT) &= ~GIF_STAT_P3Q;
|
||||
gifstate = GIF_STATE_READY;
|
||||
gif->chcr &= ~0x100;
|
||||
vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||
hwDmacIrq(DMAC_GIF);
|
||||
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||
GSCSRr |= 0x4000; //FIFO empty
|
||||
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
|
||||
|
||||
vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||
gif->chcr &= ~0x100;
|
||||
gifstate = GIF_STATE_READY;
|
||||
hwDmacIrq(DMAC_GIF);
|
||||
clearFIFOstuff(false);
|
||||
}
|
||||
|
||||
void SaveState::gifFreeze()
|
||||
|
14
pcsx2/Hw.cpp
14
pcsx2/Hw.cpp
@ -90,7 +90,7 @@ __forceinline void intcInterrupt()
|
||||
cpuException(0x400, cpuRegs.branch);
|
||||
}
|
||||
|
||||
__forceinline void dmacInterrupt()
|
||||
__forceinline void dmacInterrupt()
|
||||
{
|
||||
if ((cpuRegs.CP0.n.Status.val & 0x10807) != 0x10801) return;
|
||||
|
||||
@ -116,7 +116,7 @@ void hwDmacIrq(int n) {
|
||||
}
|
||||
|
||||
/* Write 'size' bytes to memory address 'addr' from 'data'. */
|
||||
int hwMFIFOWrite(u32 addr, u8 *data, u32 size) {
|
||||
bool hwMFIFOWrite(u32 addr, u8 *data, u32 size) {
|
||||
u32 msize = psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16;
|
||||
u8 *dst;
|
||||
|
||||
@ -129,22 +129,22 @@ int hwMFIFOWrite(u32 addr, u8 *data, u32 size) {
|
||||
|
||||
/* it does, so first copy 's1' bytes from 'data' to 'addr' */
|
||||
dst = (u8*)PSM(addr);
|
||||
if (dst == NULL) return -1;
|
||||
if (dst == NULL) return false;
|
||||
memcpy_fast(dst, data, s1);
|
||||
|
||||
/* and second copy 's2' bytes from '&data[s1]' to 'maddr' */
|
||||
dst = (u8*)PSM(psHu32(DMAC_RBOR));
|
||||
if (dst == NULL) return -1;
|
||||
if (dst == NULL) return false;
|
||||
memcpy_fast(dst, &data[s1], s2);
|
||||
}
|
||||
else {
|
||||
/* it doesn't, so just copy 'size' bytes from 'data' to 'addr' */
|
||||
dst = (u8*)PSM(addr);
|
||||
if (dst == NULL) return -1;
|
||||
if (dst == NULL) return false;
|
||||
memcpy_fast(dst, data, size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -206,7 +206,7 @@ bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
||||
dma->asr0 = 0; //Clear ASR0
|
||||
} else { //Else if ASR1 and ASR0 are empty
|
||||
//dma->tadr += 16; //Clear tag address - Kills Klonoa 2
|
||||
return 1; //End Transfer
|
||||
return true; //End Transfer
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -306,6 +306,8 @@ enum DMACIrqs
|
||||
DMAC_SIF2,
|
||||
DMAC_FROM_SPR,
|
||||
DMAC_TO_SPR,
|
||||
DMAC_13 = 13, // Stall?
|
||||
DMAC_14 = 14, // Transfer?
|
||||
DMAC_ERROR = 15,
|
||||
};
|
||||
|
||||
@ -519,8 +521,8 @@ extern void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval);
|
||||
void hwIntcIrq(int n);
|
||||
void hwDmacIrq(int n);
|
||||
|
||||
int hwMFIFORead(u32 addr, u8 *data, u32 size);
|
||||
int hwMFIFOWrite(u32 addr, u8 *data, u32 size);
|
||||
//bool hwMFIFORead(u32 addr, u8 *data, u32 size);
|
||||
bool hwMFIFOWrite(u32 addr, u8 *data, u32 size);
|
||||
|
||||
bool hwDmacSrcChainWithStack(DMACh *dma, int id);
|
||||
bool hwDmacSrcChain(DMACh *dma, int id);
|
||||
|
@ -224,8 +224,8 @@ void mtgsThreadObject::Start()
|
||||
|
||||
m_post_InitDone.Wait();
|
||||
|
||||
if( m_returncode != 0 ) // means the thread failed to init the GS plugin
|
||||
throw Exception::PluginFailure( "GS", "The GS plugin failed to open/initialize." );
|
||||
// means the thread failed to init the GS plugin
|
||||
if ( m_returncode != 0 ) throw Exception::PluginFailure( "GS", "The GS plugin failed to open/initialize." );
|
||||
}
|
||||
|
||||
mtgsThreadObject::~mtgsThreadObject()
|
||||
@ -282,21 +282,23 @@ __forceinline int mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
|
||||
|
||||
while(size > 0)
|
||||
{
|
||||
if(path.tag.nloop == 0)
|
||||
if (path.tag.nloop == 0)
|
||||
{
|
||||
path.SetTag( pMem );
|
||||
|
||||
pMem += sizeof(GIFTAG);
|
||||
--size;
|
||||
|
||||
if(pathidx == 2)
|
||||
if (pathidx == 2)
|
||||
{
|
||||
if(path.tag.flg != GIF_FLG_IMAGE)Path3progress = 1; //Other mode
|
||||
else Path3progress = 0; //IMAGE mode
|
||||
if (path.tag.flg != GIF_FLG_IMAGE)
|
||||
Path3progress = TRANSFER_MODE; //Other mode (but not stopped, I guess?)
|
||||
else
|
||||
Path3progress = IMAGE_MODE; //IMAGE mode
|
||||
//if(pathidx == 2) GIF_LOG("Set Giftag NLoop %d EOP %x Mode %d Path3msk %x Path3progress %x ", path.tag.nloop, path.tag.eop, path.tag.flg, vif1Regs->mskpath3, Path3progress);
|
||||
}
|
||||
|
||||
if( pathidx == 0 )
|
||||
if (pathidx == 0)
|
||||
{
|
||||
// int transize = 0;
|
||||
// hack: if too much data for VU1, just ignore.
|
||||
@ -324,7 +326,8 @@ __forceinline int mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
|
||||
return ++size;
|
||||
}
|
||||
}
|
||||
}else
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: size > 0 => do {} while(size > 0); should be faster than while(size > 0) {}
|
||||
|
||||
@ -453,7 +456,7 @@ __forceinline int mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
|
||||
//params path.tag.nloop, path.tag.eop, path.tag.flg, path.tag.nreg, Path3progress, vif1Regs->stat & VIF1_STAT_VGW);
|
||||
if(path.tag.eop)
|
||||
{
|
||||
Path3progress = 2;
|
||||
Path3progress = STOPPED_MODE;
|
||||
//GIF_LOG("Set progress NLoop %d EOP %x Mode %d Path3msk %x Path3progress %x ", path.tag.nloop, path.tag.eop, path.tag.flg, vif1Regs->mskpath3, Path3progress);
|
||||
}
|
||||
|
||||
@ -1134,7 +1137,7 @@ void mtgsThreadObject::Freeze( SaveState& state )
|
||||
|
||||
// this function is needed because of recompiled calls from iGS.cpp
|
||||
// (currently used in GCC only)
|
||||
void mtgsRingBufSimplePacket( s32 command, u32 data0, u32 data1, u32 data2 )
|
||||
{
|
||||
mtgsThread->SendSimplePacket( (GS_RINGTYPE)command, data0, data1, data2 );
|
||||
}
|
||||
//void mtgsRingBufSimplePacket( s32 command, u32 data0, u32 data1, u32 data2 )
|
||||
//{
|
||||
// mtgsThread->SendSimplePacket( (GS_RINGTYPE)command, data0, data1, data2 );
|
||||
//}
|
||||
|
@ -164,7 +164,7 @@ __forceinline int psxTestCycle( u32 startCycle, s32 delta )
|
||||
__forceinline void PSX_INT( IopEventId n, s32 ecycle )
|
||||
{
|
||||
// Generally speaking games shouldn't throw ints that haven't been cleared yet.
|
||||
// It's usually indicative os something amiss in our emulation, so uncomment this
|
||||
// It's usually indicative of something amiss in our emulation, so uncomment this
|
||||
// code to help trap those sort of things.
|
||||
|
||||
// Exception: IRQ16 - SIO - it drops ints like crazy when handling PAD stuff.
|
||||
|
@ -420,9 +420,9 @@ class SafeAlignedArray : public SafeArray<T>
|
||||
protected:
|
||||
T* _virtual_realloc( int newsize )
|
||||
{
|
||||
return (T*)( ( m_ptr == NULL ) ?
|
||||
return (T*)( ( this->m_ptr == NULL ) ?
|
||||
_aligned_malloc( newsize * sizeof(T), Alignment ) :
|
||||
_aligned_realloc( m_ptr, newsize * sizeof(T), Alignment )
|
||||
_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment )
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -582,7 +582,7 @@ void vifMFIFOInterrupt()
|
||||
vifqwc = 0;
|
||||
vif1.inprogress |= 0x10;
|
||||
vif1Regs->stat &= ~0x1F000000; // FQC=0
|
||||
hwDmacIrq(14);
|
||||
hwDmacIrq(DMAC_14);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -606,7 +606,7 @@ void vifMFIFOInterrupt()
|
||||
//Console::WriteLn("Empty 2");
|
||||
//vif1.inprogress |= 0x10;
|
||||
vif1Regs->stat &= ~0x1F000000; // FQC=0
|
||||
hwDmacIrq(14);
|
||||
hwDmacIrq(DMAC_14);
|
||||
}*/
|
||||
|
||||
//On a TIE break we do not clear the MFIFO (Art of Fighting)
|
||||
|
@ -58,7 +58,7 @@ static const unsigned int VIF0dmanum = 0;
|
||||
static const unsigned int VIF1dmanum = 1;
|
||||
|
||||
int g_vifCycles = 0;
|
||||
int Path3progress = 2; //0 = Image Mode (DirectHL), 1 = transferring, 2 = Stopped at End of Packet
|
||||
Path3Modes Path3progress = STOPPED_MODE;
|
||||
|
||||
u32 splittransfer[4];
|
||||
u32 splitptr = 0;
|
||||
@ -1873,9 +1873,9 @@ static int __fastcall Vif1TransDirectHL(u32 *data)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if((vif1.cmd & 0x7f) == 0x51)
|
||||
if ((vif1.cmd & 0x7f) == 0x51)
|
||||
{
|
||||
if(gif->chcr & 0x100 && (!vif1Regs->mskpath3 && Path3progress == 0)) //PATH3 is in image mode, so wait for end of transfer
|
||||
if (gif->chcr & 0x100 && (!vif1Regs->mskpath3 && (Path3progress == IMAGE_MODE))) //PATH3 is in image mode, so wait for end of transfer
|
||||
{
|
||||
vif1Regs->stat |= VIF1_STAT_VGW;
|
||||
return 0;
|
||||
@ -2072,7 +2072,8 @@ void Vif1MskPath3() // MSKPATH3
|
||||
}
|
||||
else
|
||||
{
|
||||
Path3progress = 1; //Let the Gif know it can transfer again (making sure any vif stall isnt unset prematurely)
|
||||
//Let the Gif know it can transfer again (making sure any vif stall isnt unset prematurely)
|
||||
Path3progress = TRANSFER_MODE;
|
||||
psHu32(GIF_STAT) &= ~0x2;
|
||||
CPU_INT(2, 4);
|
||||
}
|
||||
@ -2106,9 +2107,10 @@ static void Vif1CMDFlush() // FLUSH/E/A
|
||||
{
|
||||
vif1FLUSH();
|
||||
|
||||
if((vif1.cmd & 0x7f) == 0x13)
|
||||
if ((vif1.cmd & 0x7f) == 0x13)
|
||||
{
|
||||
if((Path3progress != 2 || !vif1Regs->mskpath3) && gif->chcr & 0x100) // Gif is already transferring so wait for it.
|
||||
// Gif is already transferring so wait for it.
|
||||
if (((Path3progress != STOPPED_MODE) || !vif1Regs->mskpath3) && gif->chcr & 0x100)
|
||||
{
|
||||
vif1Regs->stat |= VIF1_STAT_VGW;
|
||||
CPU_INT(2, 4);
|
||||
@ -2488,7 +2490,7 @@ __forceinline void vif1SetupTransfer()
|
||||
if ((vif1ch->madr + vif1ch->qwc * 16) >= psHu32(DMAC_STADR))
|
||||
{
|
||||
// stalled
|
||||
hwDmacIrq(13);
|
||||
hwDmacIrq(DMAC_13);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,13 @@ enum VifModes
|
||||
VIF_CHAIN_MODE = 2
|
||||
};
|
||||
|
||||
enum Path3Modes //0 = Image Mode (DirectHL), 1 = transferring, 2 = Stopped at End of Packet
|
||||
{
|
||||
IMAGE_MODE = 0,
|
||||
TRANSFER_MODE = 1,
|
||||
STOPPED_MODE = 2
|
||||
};
|
||||
|
||||
struct vifCode {
|
||||
u32 addr;
|
||||
u32 size;
|
||||
@ -54,7 +61,7 @@ struct vifStruct {
|
||||
};
|
||||
|
||||
extern vifStruct vif0, vif1;
|
||||
extern int Path3progress;
|
||||
extern Path3Modes Path3progress;
|
||||
extern u8 schedulepath3msk;
|
||||
|
||||
void __fastcall UNPACK_S_32( u32 *dest, u32 *data, int size );
|
||||
|
Loading…
Reference in New Issue
Block a user