mirror of https://github.com/PCSX2/pcsx2.git
Path3 Masking mystery solved, Simpsons (Issue 24) GT4 (Issue 211), tenchu and many many other path3 masking games should be fixed. This will only work on MTGS.
Also semi-removed my gifsplit thing to resolve the tekken 5 menus Issue 209 Note: GT4 is still missing its logo, this is down to a really bizzare timing issue i cant pinpoint. Removed redundant path3hack git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1257 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
bd9886b332
commit
44378b31f7
|
@ -571,7 +571,6 @@ int loadElfFile(const char *filename)
|
|||
}
|
||||
|
||||
#include "VU.h"
|
||||
extern bool path3hack;
|
||||
int g_VUGameFixes = 0;
|
||||
|
||||
// fixme - this should be moved to patches or eliminated
|
||||
|
@ -584,9 +583,5 @@ void LoadGameSpecificSettings()
|
|||
case 0xb99379b7: // erementar gerad (discolored chars)
|
||||
g_VUGameFixes |= VUFIX_XGKICKDELAY2; // Tested - still needed - arcum42
|
||||
break;
|
||||
//case 0xa08c4057: //Sprint Cars (SLUS)
|
||||
//case 0x8b0725d5: //Flinstones Bedrock Racing (SLES)
|
||||
//path3hack = TRUE; // We can move this to patch files right now
|
||||
//break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -243,8 +243,6 @@ void gsReset()
|
|||
|
||||
memzero_obj(g_RealGSMem);
|
||||
|
||||
Path3transfer = FALSE;
|
||||
|
||||
GSCSRr = 0x551B400F; // Set the FINISH bit to 1 for now
|
||||
GSIMR = 0x7f00;
|
||||
psHu32(GIF_STAT) = 0;
|
||||
|
|
117
pcsx2/Gif.cpp
117
pcsx2/Gif.cpp
|
@ -28,7 +28,7 @@
|
|||
|
||||
using std::min;
|
||||
|
||||
#define gifsplit 64
|
||||
#define gifsplit 0x10000
|
||||
enum gifstate_t
|
||||
{
|
||||
GIF_STATE_READY = 0,
|
||||
|
@ -57,6 +57,9 @@ __forceinline void gsInterrupt() {
|
|||
//Console::WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", params gif->chcr, gif->qwc, done);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Path3progress == 2) vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||
|
||||
if (gif->qwc > 0 || gspath3done == 0) {
|
||||
if (!(psHu32(DMAC_CTRL) & 0x1)) {
|
||||
Console::Notice("gs dma masked, re-scheduling...");
|
||||
|
@ -66,19 +69,11 @@ __forceinline void gsInterrupt() {
|
|||
}
|
||||
|
||||
GIFdma();
|
||||
#ifdef GSPATH3FIX
|
||||
// re-raise the IRQ as part of the mysterious Path3fix.
|
||||
// fixme - this hack *should* have the gs_irq raised from the VIF, I think. It would be
|
||||
// more efficient and more correct. (air)
|
||||
/*if (!(vif1Regs->mskpath3 && (vif1ch->chcr & 0x100)) || (psHu32(GIF_MODE) & 0x1))
|
||||
CPU_INT( 2, 64 );*/
|
||||
#endif
|
||||
if(gspath3done == 0 || gif->qwc > 0) return;
|
||||
return;
|
||||
}
|
||||
|
||||
gspath3done = 0;
|
||||
gscycles = 0;
|
||||
Path3transfer = FALSE;
|
||||
gif->chcr &= ~0x100;
|
||||
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||
GSCSRr |= 0x4000; //FIFO empty
|
||||
|
@ -89,12 +84,10 @@ __forceinline void gsInterrupt() {
|
|||
|
||||
}
|
||||
|
||||
static void WRITERING_DMA(u32 *pMem, u32 qwc)
|
||||
static u32 WRITERING_DMA(u32 *pMem, u32 qwc)
|
||||
{
|
||||
psHu32(GIF_STAT) |= 0xE00;
|
||||
|
||||
// Path3 transfer will be set to false by the GIFtag handler.
|
||||
Path3transfer = TRUE;
|
||||
|
||||
if( mtgsThread != NULL )
|
||||
{
|
||||
|
@ -114,15 +107,14 @@ static void WRITERING_DMA(u32 *pMem, u32 qwc)
|
|||
memcpy_aligned(pgsmem, pMem, sizetoread<<4);
|
||||
|
||||
mtgsThread->SendDataPacket();
|
||||
return sizetoread;
|
||||
}
|
||||
else
|
||||
{
|
||||
GSGIFTRANSFER3(pMem, qwc);
|
||||
if (GSgetLastTag != NULL)
|
||||
{
|
||||
GSgetLastTag(&s_gstag);
|
||||
if (s_gstag == 1) Path3transfer = FALSE; /* fixes SRS and others */
|
||||
}
|
||||
gif->madr+= qwc*16;
|
||||
gif->qwc -= qwc;
|
||||
return qwc;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,11 +137,11 @@ int _GIFchain() {
|
|||
Console::Notice( "Hackfix - NULL GIFchain" );
|
||||
return -1;
|
||||
}
|
||||
WRITERING_DMA(pMem, qwc);
|
||||
qwc = WRITERING_DMA(pMem, qwc);
|
||||
|
||||
gif->madr+= qwc*16;
|
||||
gif->qwc -= qwc;
|
||||
return (qwc)*2;
|
||||
/*gif->madr+= qwc*16;
|
||||
gif->qwc -= qwc;*/
|
||||
return (qwc);
|
||||
}
|
||||
|
||||
static __forceinline void GIFchain()
|
||||
|
@ -161,10 +153,7 @@ static __forceinline void GIFchain()
|
|||
|
||||
static __forceinline void dmaGIFend()
|
||||
{
|
||||
if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0)
|
||||
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
|
||||
else
|
||||
CPU_INT(2, min( gifsplit, (int)gif->qwc ) /** BIAS*/);
|
||||
CPU_INT(2, 2);
|
||||
}
|
||||
|
||||
// These could probably be consolidated into one function,
|
||||
|
@ -172,10 +161,10 @@ static __forceinline void dmaGIFend()
|
|||
// not to do the gif->qwc != 0 check. --arcum42
|
||||
static __forceinline void GIFdmaEnd()
|
||||
{
|
||||
if (psHu32(GIF_MODE) & 0x4)
|
||||
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
|
||||
else
|
||||
CPU_INT(2, min( gifsplit, (int)gif->qwc ) /** BIAS*/);
|
||||
//if (psHu32(GIF_MODE) & 0x4)
|
||||
CPU_INT(2, gscycles * BIAS);
|
||||
/*else
|
||||
CPU_INT(2, min( gifsplit, (int)gif->qwc ) * BIAS);*/
|
||||
}
|
||||
|
||||
void GIFdma()
|
||||
|
@ -183,7 +172,7 @@ void GIFdma()
|
|||
u32 *ptag;
|
||||
u32 id;
|
||||
|
||||
gscycles= prevcycles ? prevcycles: gscycles;
|
||||
gscycles= prevcycles ? prevcycles: 0;
|
||||
|
||||
if ((psHu32(GIF_CTRL) & 8)) { // temporarily stop
|
||||
Console::WriteLn("Gif dma temp paused?");
|
||||
|
@ -219,6 +208,13 @@ void GIFdma()
|
|||
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
|
||||
{
|
||||
//GIF_LOG("Waiting VU %x, PATH2 %x, GIFMODE %x Progress %x", psHu32(GIF_STAT) & 0x100, (vif1.cmd & 0x7f), psHu32(GIF_MODE), Path3progress);
|
||||
dmaGIFend();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef GSPATH3FIX
|
||||
if (vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1)) {
|
||||
if(gif->qwc == 0) {
|
||||
|
@ -245,26 +241,24 @@ void GIFdma()
|
|||
}
|
||||
}
|
||||
|
||||
GIFchain();
|
||||
|
||||
if((gif->qwc == 0) && ((gspath3done == 1) || (gif->chcr & 0xc) == 0)){
|
||||
gspath3done = 0;
|
||||
gif->chcr &= ~0x100;
|
||||
GSCSRr &= ~0xC000;
|
||||
GSCSRr |= 0x4000;
|
||||
Path3transfer = FALSE;
|
||||
psHu32(GIF_STAT)&= ~0x1F000E00; // OPH=0 | APATH=0 | QFC=0
|
||||
hwDmacIrq(DMAC_GIF);
|
||||
if(Path3progress == 2/* && gif->qwc != 0*/)
|
||||
{
|
||||
dmaGIFend();
|
||||
return;
|
||||
}
|
||||
//Dont unfreeze xmm regs here, Masked PATH3 can only be called by VIF, which is already handling it.
|
||||
|
||||
GIFchain();
|
||||
GIFdmaEnd();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// Transfer Dn_QWC from Dn_MADR to GIF
|
||||
if ((gif->chcr & 0xc) == 0 || gif->qwc > 0) { // Normal Mode
|
||||
|
||||
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
|
||||
|
||||
if (((gif->qwc == 0) && (gif->chcr & 0xc) == 0))
|
||||
|
@ -273,7 +267,6 @@ void GIFdma()
|
|||
{
|
||||
GIFdmaEnd();
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
if ((gif->chcr & 0xc) == 0x4 && gspath3done == 0)
|
||||
|
@ -322,23 +315,23 @@ void GIFdma()
|
|||
|
||||
prevcycles = 0;
|
||||
if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) {
|
||||
if (gspath3done == 0 || gif->qwc > 0)
|
||||
{
|
||||
if (gif->qwc != 0)
|
||||
{
|
||||
GIFdmaEnd();
|
||||
}
|
||||
else
|
||||
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;
|
||||
}
|
||||
GIFdmaEnd();
|
||||
gif->qwc = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} else GIFdmaEnd();
|
||||
gscycles = 0;
|
||||
}
|
||||
}
|
||||
|
@ -358,23 +351,33 @@ void dmaGIF() {
|
|||
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||
GSCSRr |= 0x8000; //FIFO full
|
||||
psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [used to be 0xE00; // OPH=1 | APATH=3]
|
||||
Path3progress = 2;
|
||||
|
||||
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];
|
||||
|
||||
//gspath3done = hwDmacSrcChainWithStack(gif, (ptag[0] >> 28) & 0x7);
|
||||
GIFdmaEnd();
|
||||
gif->qwc = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
GIFdma();
|
||||
//gif->qwc = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//Halflife sets a QWC amount in chain mode, no tadr set.
|
||||
if((gif->qwc > 0) && ((gif->chcr & 0x4) == 0x4)) gspath3done = 1;
|
||||
|
||||
dmaGIFend();
|
||||
GIFdma();
|
||||
}
|
||||
|
||||
// called from only one location, so forceinline it:
|
||||
|
|
|
@ -287,9 +287,11 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
|
|||
pMem += sizeof(GIFTAG);
|
||||
--size;
|
||||
|
||||
if(pathidx == 2 && path.tag.eop)
|
||||
if(pathidx == 2)
|
||||
{
|
||||
Path3transfer = FALSE;
|
||||
if(path.tag.flg != GIF_FLG_IMAGE)Path3progress = 1; //Other mode
|
||||
else Path3progress = 0; //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 )
|
||||
|
@ -305,11 +307,11 @@ __forceinline u32 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) {}
|
||||
|
||||
//if(pathidx == 2) GIF_LOG("PATH3 NLoop %d EOP %x Mode %d Path3msk %x Path3progress %x ", path.tag.nloop, path.tag.eop, path.tag.flg, vif1Regs->mskpath3, Path3progress);
|
||||
switch(path.tag.flg)
|
||||
{
|
||||
case GIF_FLG_PACKED:
|
||||
|
@ -372,10 +374,11 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
|
|||
}
|
||||
}
|
||||
|
||||
if(pathidx == 0)
|
||||
if(pathidx == 0 || pathidx == 2)
|
||||
{
|
||||
if(path.tag.eop && path.tag.nloop == 0)
|
||||
{
|
||||
//if(pathidx == 2) GIF_LOG("BREAK PATH3 NLoop %d EOP %x Mode %d Path3msk %x Path3progress %x ", path.tag.nloop, path.tag.eop, path.tag.flg, vif1Regs->mskpath3, Path3progress);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -392,6 +395,23 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
|
|||
// along the way (often means curreg was in a bad state or something)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(pathidx == 2)
|
||||
{
|
||||
if(path.tag.nloop == 0 )
|
||||
{
|
||||
//DevCon::Notice("Finishing Giftag NLoop %d EOP %x Mode %d nregs %d Path3progress %d Vifstat VGW %x",
|
||||
//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;
|
||||
//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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef PCSX2_GSRING_SAMPLING_STATS
|
||||
__asm
|
||||
{
|
||||
|
@ -838,6 +858,11 @@ int mtgsThreadObject::PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 s
|
|||
// enough room for size - retval:
|
||||
int retval = _gifTransferDummy( pathidx, srcdata, size );
|
||||
|
||||
if(pathidx == 2)
|
||||
{
|
||||
gif->madr += (size - retval) * 16;
|
||||
gif->qwc -= size - retval;
|
||||
}
|
||||
size = size - retval;
|
||||
m_packet_size = size;
|
||||
size++; // takes into account our command qword.
|
||||
|
|
|
@ -57,7 +57,6 @@ PatchTextTable commands[] =
|
|||
// X - EE rounding mode (default is NEAR)
|
||||
// Y - VU rounding mode (default is CHOP)
|
||||
{ "zerogs", 6, patchFunc_zerogs }, // zerogs=hex
|
||||
{ "path3hack", 7, patchFunc_path3hack },
|
||||
{ "vunanmode",8, patchFunc_vunanmode },
|
||||
{ "ffxhack",9, patchFunc_ffxhack},
|
||||
{ "xkickdelay",10, patchFunc_xkickdelay},
|
||||
|
@ -674,11 +673,6 @@ void patchFunc_vunanmode( char * cmd, char * param )
|
|||
// Doesn't do anything anymore
|
||||
}
|
||||
|
||||
void patchFunc_path3hack( char * cmd, char * param )
|
||||
{
|
||||
path3hack = TRUE;
|
||||
}
|
||||
|
||||
void patchFunc_roundmode( char * cmd, char * param )
|
||||
{
|
||||
int index;
|
||||
|
|
|
@ -82,7 +82,6 @@ void patchFunc_comment( char * text1, char * text2 );
|
|||
void patchFunc_gametitle( char * text1, char * text2 );
|
||||
void patchFunc_patch( char * text1, char * text2 );
|
||||
void patchFunc_fastmemory( char * text1, char * text2 );
|
||||
void patchFunc_path3hack( char * text1, char * text2 );
|
||||
void patchFunc_roundmode( char * text1, char * text2 );
|
||||
void patchFunc_zerogs( char * text1, char * text2 );
|
||||
void patchFunc_vunanmode( char * text1, char * text2 );
|
||||
|
@ -109,7 +108,6 @@ int AddPatch(int Mode, int Place, int Address, int Size, u64 data);
|
|||
|
||||
extern void SetFastMemory(int); // iR5900LoadStore.c
|
||||
|
||||
extern bool path3hack;
|
||||
//extern int g_VUGameFixes;
|
||||
extern int g_ZeroGSOptions;
|
||||
extern u32 g_sseMXCSR;
|
||||
|
|
|
@ -58,8 +58,7 @@ static const unsigned int VIF0dmanum = 0;
|
|||
static const unsigned int VIF1dmanum = 1;
|
||||
|
||||
int g_vifCycles = 0;
|
||||
bool path3hack = false;
|
||||
bool Path3transfer = false;
|
||||
int Path3progress = 2; //0 = Image Mode (DirectHL), 1 = transferring, 2 = Stopped at End of Packet
|
||||
|
||||
u32 splittransfer[4];
|
||||
u32 splitptr = 0;
|
||||
|
@ -1891,6 +1890,7 @@ static int __fastcall Vif1TransDirectHL(u32 *data)
|
|||
}
|
||||
else
|
||||
{
|
||||
psHu32(GIF_STAT) &= ~0x80;
|
||||
ret = vif1.tag.size;
|
||||
vif1.tag.size = 0;
|
||||
vif1.cmd = 0;
|
||||
|
@ -2019,22 +2019,11 @@ static void Vif1CMDMskPath3() // MSKPATH3
|
|||
#ifdef GSPATH3FIX
|
||||
if ((vif1Regs->code >> 15) & 0x1)
|
||||
{
|
||||
|
||||
while ((gif->chcr & 0x100)) //Can be done 2 different ways, depends on the game/company
|
||||
{
|
||||
if (!path3hack && !Path3transfer && (gif->qwc == 0)) break;
|
||||
|
||||
gsInterrupt();
|
||||
|
||||
if (path3hack && (gif->qwc == 0)) break; //add games not working with it to elfheader.c to enable this instead
|
||||
|
||||
}
|
||||
psHu32(GIF_STAT) |= 0x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// fixme: This is the *only* reason 'transferred' is global. Otherwise it'd be local to Vif1Transfer.
|
||||
if (gif->chcr & 0x100) CPU_INT(2, (transferred >> 2) * BIAS); // Restart Path3 on its own, time it right!
|
||||
Path3progress = 1; //Let the Gif know it can transfer again (making sure any vif stall isnt unset prematurely)
|
||||
psHu32(GIF_STAT) &= ~0x2;
|
||||
}
|
||||
#else
|
||||
|
@ -2068,10 +2057,9 @@ static void Vif1CMDFlush() // FLUSH/E/A
|
|||
|
||||
if((vif1.cmd & 0x7f) == 0x13)
|
||||
{
|
||||
while ((gif->chcr & 0x100))
|
||||
if(Path3progress != 2 && gif->chcr & 0x100) // Gif is already transferring so wait for it.
|
||||
{
|
||||
if (!Path3transfer && gif->qwc == 0) break;
|
||||
gsInterrupt();
|
||||
vif1Regs->stat |= VIF1_STAT_VGW;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2123,13 +2111,16 @@ static void Vif1CMDDirectHL() // DIRECT/HL
|
|||
vif1.tag.size = vifImm << 2;
|
||||
|
||||
|
||||
if((gif->chcr & 0x100) && (vif1.cmd & 0x7f) == 0x51)
|
||||
if((vif1.cmd & 0x7f) == 0x51)
|
||||
{
|
||||
//if(vif1Regs->mskpath3)CPU_INT(2, vif1ch->qwc - (vif1.vifpacketsize >> 2) * BIAS);
|
||||
//DirectHL flushes the lot
|
||||
if(gif->chcr & 0x100 && Path3progress == 0) //PATH3 is in image mode, so wait for end of transfer
|
||||
{
|
||||
//DevCon::Notice("DirectHL gif chcr %x gif qwc %x mskpth3 %x", params gif->chcr, gif->qwc, vif1Regs->mskpath3);
|
||||
vif1Regs->stat |= VIF1_STAT_VGW;
|
||||
}
|
||||
|
||||
}
|
||||
psHu32(GIF_STAT) |= 0x80;
|
||||
|
||||
}
|
||||
static void Vif1CMDNull() // invalid opcode
|
||||
|
@ -2215,7 +2206,6 @@ int VIF1transfer(u32 *data, int size, int istag)
|
|||
if (vif1.tag.size != 0) DevCon::Error("no vif1 cmd but tag size is left last cmd read %x", params vif1Regs->code);
|
||||
|
||||
if (vif1.irq) break;
|
||||
if(vif1Regs->stat & VIF1_STAT_VGW) break;
|
||||
|
||||
vif1.cmd = (data[0] >> 24);
|
||||
vif1Regs->code = data[0];
|
||||
|
@ -2459,7 +2449,7 @@ __forceinline void vif1SetupTransfer()
|
|||
else
|
||||
ret = VIF1transfer(vif1ptag + 2, 2, 1); //Transfer Tag
|
||||
|
||||
if (ret < 0)
|
||||
if (ret < 0 && vif1.irqoffset < 2)
|
||||
{
|
||||
vif1.inprogress = 0; //Better clear this so it has to do it again (Jak 1)
|
||||
return; //There has been an error or an interrupt
|
||||
|
@ -2485,21 +2475,17 @@ __forceinline void vif1Interrupt()
|
|||
VIF_LOG("vif1Interrupt: %8.8x", cpuRegs.cycle);
|
||||
|
||||
g_vifCycles = 0;
|
||||
if((vif1Regs->stat & VIF1_STAT_VGW) &&
|
||||
(gif->chcr & 0x100))
|
||||
|
||||
if((vif1Regs->stat & VIF1_STAT_VGW))
|
||||
{
|
||||
int delay = 0;
|
||||
|
||||
if ((psHu32(GIF_MODE) & 0x1))
|
||||
delay = min( 8, (int)gif->qwc );
|
||||
else
|
||||
delay = gif->qwc * BIAS;
|
||||
|
||||
//else CPU_INT(2, min( 64, (int)gif->qwc ) * BIAS);
|
||||
CPU_INT(1, delay);
|
||||
if(gif->chcr & 0x100)
|
||||
{
|
||||
CPU_INT(1, 2);
|
||||
return;
|
||||
}
|
||||
vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||
else vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ((vif1ch->chcr & 0x100) == 0) Console::WriteLn("Vif1 running when CHCR == %x", params vif1ch->chcr);
|
||||
|
@ -2539,7 +2525,7 @@ __forceinline void vif1Interrupt()
|
|||
|
||||
if ((vif1.inprogress & 0x1) == 0) vif1SetupTransfer();
|
||||
|
||||
CPU_INT(1, (vif1ch->qwc * BIAS) - (vif1.vifpacketsize >> 1));
|
||||
CPU_INT(1, g_vifCycles);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2606,7 +2592,7 @@ void dmaVIF1()
|
|||
|
||||
// Chain Mode
|
||||
vif1.done = false;
|
||||
CPU_INT(1, 0);
|
||||
vif1Interrupt();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ struct vifStruct {
|
|||
};
|
||||
|
||||
extern vifStruct vif0, vif1;
|
||||
extern bool Path3transfer;
|
||||
extern int Path3progress;
|
||||
|
||||
void __fastcall UNPACK_S_32( u32 *dest, u32 *data, int size );
|
||||
|
||||
|
|
|
@ -4409,7 +4409,7 @@ void recVUMI_XGKICK_(VURegs *VU)
|
|||
CALLFunc((uptr)GSgifTransfer1);
|
||||
#endif
|
||||
}
|
||||
|
||||
psHu32(GIF_STAT) &= ~0x100;
|
||||
s_ScheduleXGKICK = 0;
|
||||
}
|
||||
|
||||
|
@ -4430,6 +4430,8 @@ void recVUMI_XGKICK(VURegs *VU, int info)
|
|||
SHL32ItoR(isreg, 4);
|
||||
AND32ItoR(isreg, 0x3fff);
|
||||
s_XGKICKReg = isreg;
|
||||
psHu32(GIF_STAT) |= 0x100;
|
||||
|
||||
|
||||
if (!SUPERVU_XGKICKDELAY || pc == s_pCurBlock->endpc)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue