mirror of https://github.com/PCSX2/pcsx2.git
COP0.cpp: Updated the commented out Perf counter code to work on the newer builds, also removed the line which stopped them updating at all if the interrupt wasnt on.
Others: Fixed a couple of unpack bugs, tried to tackle an MFIFO bug with Tekken Tag. Also re-jiggled a few bits on my recent changed, please negative if it breaks anything. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1400 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
d15db78baf
commit
0f30bf62b5
|
@ -217,15 +217,15 @@ void COP0_DiagnosticPCCR()
|
|||
if( cpuRegs.PERF.n.pccr.b.Event1 >= 7 && cpuRegs.PERF.n.pccr.b.Event1 <= 10 )
|
||||
Console::Notice( "PERF/PCR1 Unsupported Update Event Mode = 0x%x", params cpuRegs.PERF.n.pccr.b.Event1 );
|
||||
}
|
||||
|
||||
extern int branch;
|
||||
__forceinline void COP0_UpdatePCCR()
|
||||
{
|
||||
if( cpuRegs.CP0.n.Status.b.ERL || !cpuRegs.PERF.n.pccr.b.CTE ) return;
|
||||
//if( cpuRegs.CP0.n.Status.b.ERL || !cpuRegs.PERF.n.pccr.b.CTE ) return;
|
||||
|
||||
// TODO : Implement memory mode checks here (kernel/super/user)
|
||||
// For now we just assume user mode.
|
||||
|
||||
if( cpuRegs.PERF.n.pccr.b.U0 )
|
||||
if( cpuRegs.PERF.n.pccr.val & 0xf )
|
||||
{
|
||||
// ----------------------------------
|
||||
// Update Performance Counter 0
|
||||
|
@ -243,24 +243,25 @@ __forceinline void COP0_UpdatePCCR()
|
|||
|
||||
//prev ^= (1UL<<31); // XOR is fun!
|
||||
//if( (prev & cpuRegs.PERF.n.pcr0) & (1UL<<31) )
|
||||
if( cpuRegs.PERF.n.pcr0 & 0x80000000 )
|
||||
if( (cpuRegs.PERF.n.pcr0 & 0x80000000) && (cpuRegs.CP0.n.Status.b.ERL == 1) && cpuRegs.PERF.n.pccr.b.CTE)
|
||||
{
|
||||
// TODO: Vector to the appropriate exception here.
|
||||
// This code *should* be correct, but is untested (and other parts of the emu are
|
||||
// not prepared to handle proper Level 2 exception vectors yet)
|
||||
|
||||
/*if( delay_slot )
|
||||
//branch == 1 is probably not the best way to check for the delay slot, but it beats nothing! (Refraction)
|
||||
/* if( branch == 1 )
|
||||
{
|
||||
cpuRegs.CP0.ErrorEPC = cpuRegs.pc - 4;
|
||||
cpuRegs.CP0.Cause.BD2 = 1;
|
||||
cpuRegs.CP0.n.ErrorEPC = cpuRegs.pc - 4;
|
||||
cpuRegs.CP0.n.Cause |= 0x40000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuRegs.CP0.ErrorEPC = cpuRegs.pc;
|
||||
cpuRegs.CP0.Cause.BD2 = 0;
|
||||
cpuRegs.CP0.n.ErrorEPC = cpuRegs.pc;
|
||||
cpuRegs.CP0.n.Cause &= ~0x40000000;
|
||||
}
|
||||
|
||||
if( cpuRegs.CP0.Status.DEV )
|
||||
if( cpuRegs.CP0.n.Status.b.DEV )
|
||||
{
|
||||
// Bootstrap vector
|
||||
cpuRegs.pc = 0xbfc00280;
|
||||
|
@ -269,8 +270,8 @@ __forceinline void COP0_UpdatePCCR()
|
|||
{
|
||||
cpuRegs.pc = 0x80000080;
|
||||
}
|
||||
cpuRegs.CP0.Status.ERL = 1;
|
||||
cpuRegs.CP0.Cause.EXC2 = 2;*/
|
||||
cpuRegs.CP0.n.Status.b.ERL = 1;
|
||||
cpuRegs.CP0.n.Cause |= 0x20000;*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -289,9 +290,36 @@ __forceinline void COP0_UpdatePCCR()
|
|||
cpuRegs.PERF.n.pcr1 += incr;
|
||||
s_iLastPERFCycle[1] = cpuRegs.cycle;
|
||||
|
||||
if( cpuRegs.PERF.n.pcr1 & 0x80000000 )
|
||||
if( (cpuRegs.PERF.n.pcr1 & 0x80000000) && (cpuRegs.CP0.n.Status.b.ERL == 1) && cpuRegs.PERF.n.pccr.b.CTE)
|
||||
{
|
||||
// See PCR0 comments for notes on exceptions
|
||||
// TODO: Vector to the appropriate exception here.
|
||||
// This code *should* be correct, but is untested (and other parts of the emu are
|
||||
// not prepared to handle proper Level 2 exception vectors yet)
|
||||
|
||||
//branch == 1 is probably not the best way to check for the delay slot, but it beats nothing! (Refraction)
|
||||
|
||||
/*if( branch == 1 )
|
||||
{
|
||||
cpuRegs.CP0.n.ErrorEPC = cpuRegs.pc - 4;
|
||||
cpuRegs.CP0.n.Cause |= 0x40000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuRegs.CP0.n.ErrorEPC = cpuRegs.pc;
|
||||
cpuRegs.CP0.n.Cause &= ~0x40000000;
|
||||
}
|
||||
|
||||
if( cpuRegs.CP0.n.Status.b.DEV )
|
||||
{
|
||||
// Bootstrap vector
|
||||
cpuRegs.pc = 0xbfc00280;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuRegs.pc = 0x80000080;
|
||||
}
|
||||
cpuRegs.CP0.n.Status.b.ERL = 1;
|
||||
cpuRegs.CP0.n.Cause |= 0x20000;*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -336,8 +336,16 @@ static __forceinline void VSyncStart(u32 sCycle)
|
|||
EECNT_LOG( "///////// EE COUNTER VSYNC START \\\\\\\\\\\\\\\\\\\\ (frame: %d)", iFrame );
|
||||
vSyncDebugStuff( iFrame ); // EE Profiling and Debug code
|
||||
|
||||
if ((CSRw & 0x8)) GSCSRr|= 0x8;
|
||||
if (!(GSIMR&0x800)) gsIrq();
|
||||
if ((CSRw & 0x8))
|
||||
{
|
||||
GSCSRr|= 0x8;
|
||||
|
||||
if (!(GSIMR&0x800))
|
||||
{
|
||||
gsIrq();
|
||||
}
|
||||
CSRw &= ~0x8; //Disable the interrupt from triggering twice
|
||||
}
|
||||
|
||||
hwIntcIrq(INTC_VBLANK_S);
|
||||
psxVBlankStart();
|
||||
|
@ -404,8 +412,16 @@ __forceinline void rcntUpdate_hScanline()
|
|||
hsyncCounter.Mode = MODE_HRENDER;
|
||||
}
|
||||
else { //HBLANK END / HRENDER Begin
|
||||
if (CSRw & 0x4) GSCSRr |= 4; // signal
|
||||
if (!(GSIMR&0x400)) gsIrq();
|
||||
if (CSRw & 0x4)
|
||||
{
|
||||
GSCSRr |= 4; // signal
|
||||
|
||||
if (!(GSIMR&0x400))
|
||||
{
|
||||
gsIrq();
|
||||
}
|
||||
CSRw &= ~0x4; //Disable the interrupt from triggering twice
|
||||
}
|
||||
if (gates) rcntEndGate(false, hsyncCounter.sCycle);
|
||||
if (psxhblankgate) psxCheckEndGate16(0);
|
||||
|
||||
|
|
30
pcsx2/GS.cpp
30
pcsx2/GS.cpp
|
@ -290,14 +290,7 @@ void gsGIFReset()
|
|||
|
||||
void gsCSRwrite(u32 value)
|
||||
{
|
||||
CSRw |= value & ~0x60;
|
||||
|
||||
if( mtgsThread != NULL )
|
||||
mtgsThread->SendSimplePacket( GS_RINGTYPE_WRITECSR, CSRw, 0, 0 );
|
||||
else
|
||||
GSwriteCSR(CSRw);
|
||||
|
||||
GSCSRr = ((GSCSRr&~value)&0x1f)|(GSCSRr&~0x1f);
|
||||
|
||||
// Our emulated GS has no FIFO...
|
||||
/*if( value & 0x100 ) { // FLUSH
|
||||
|
@ -317,17 +310,36 @@ void gsCSRwrite(u32 value)
|
|||
GSreset();
|
||||
}
|
||||
|
||||
CSRw = 0x1f;
|
||||
CSRw |= 0x1f;
|
||||
GSCSRr = 0x551B4000; // Set the FINISH bit to 1 - GS is always at a finish state as we don't have a FIFO(saqib)
|
||||
GSIMR = 0x7F00; //This is bits 14-8 thats all that should be 1
|
||||
}
|
||||
else if( value & 0x100 ) // FLUSH
|
||||
{
|
||||
//Console::WriteLn("GS_CSR FLUSH GS fifo: %x (CSRr=%x)", params value, GSCSRr);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSRw |= value & 0x1f;
|
||||
|
||||
if( mtgsThread != NULL )
|
||||
mtgsThread->SendSimplePacket( GS_RINGTYPE_WRITECSR, CSRw, 0, 0 );
|
||||
else
|
||||
GSwriteCSR(CSRw);
|
||||
|
||||
GSCSRr = ((GSCSRr&~value)&0x1f)|(GSCSRr&~0x1f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void IMRwrite(u32 value)
|
||||
{
|
||||
GSIMR = (value & 0x1f00)|0x6000;
|
||||
|
||||
if((GSCSRr & 0x1f) & (~(GSIMR >> 8) & 0x1f)) gsIrq();
|
||||
if((GSCSRr & 0x1f) & (~(GSIMR >> 8) & 0x1f))
|
||||
{
|
||||
gsIrq();
|
||||
}
|
||||
// don't update mtgs mem
|
||||
}
|
||||
|
||||
|
|
|
@ -949,7 +949,7 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
|
|||
if (value & 0x100)
|
||||
{
|
||||
vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO
|
||||
}
|
||||
} else cpuRegs.interrupt &= ~(1<<10) | ~(1<<1); //Tekken tag seems to stop vif and start it again in normal, so we will cancel the mfifo loop
|
||||
|
||||
DmaExec(dmaVIF1, mem, value);
|
||||
return;
|
||||
|
|
|
@ -138,22 +138,29 @@ static void RegHandlerSIGNAL(const u32* data)
|
|||
GSSIGLBLID->SIGID = (GSSIGLBLID->SIGID&~data[1])|(data[0]&data[1]);
|
||||
|
||||
if ((CSRw & 0x1))
|
||||
{
|
||||
GSCSRr |= 1; // signal
|
||||
|
||||
if (!(GSIMR&0x100) )
|
||||
gsIrq();
|
||||
if (!(GSIMR&0x100) )
|
||||
{
|
||||
gsIrq();
|
||||
}
|
||||
CSRw &= ~0x1; //Disable the interrupt from triggering twice
|
||||
}
|
||||
}
|
||||
|
||||
static void RegHandlerFINISH(const u32* data)
|
||||
{
|
||||
MTGS_LOG("MTGS FINISH data %x_%x CSRw %x\n",data[0], data[1], CSRw);
|
||||
DevCon::Notice("MTGS FINISH data %x_%x CSRw %x\n", params data[0], data[1], CSRw);
|
||||
|
||||
if ((CSRw & 0x2))
|
||||
{
|
||||
GSCSRr |= 2; // finish
|
||||
|
||||
if (!(GSIMR&0x200) )
|
||||
gsIrq();
|
||||
|
||||
if (!(GSIMR&0x200) )
|
||||
gsIrq();
|
||||
CSRw &= ~0x2; //Disable the interrupt from triggering twice
|
||||
}
|
||||
}
|
||||
|
||||
static void RegHandlerLABEL(const u32* data)
|
||||
|
|
|
@ -533,6 +533,8 @@ void vifMFIFOInterrupt()
|
|||
{
|
||||
g_vifCycles = 0;
|
||||
|
||||
if(schedulepath3msk) Vif1MskPath3();
|
||||
|
||||
if((vif1Regs->stat & VIF1_STAT_VGW))
|
||||
{
|
||||
if(gif->chcr & 0x100)
|
||||
|
@ -596,14 +598,6 @@ void vifMFIFOInterrupt()
|
|||
CPU_INT(10, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(vif1.inprogress & 0x1)) mfifoVIF1transfer(0);
|
||||
|
||||
if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)))
|
||||
CPU_INT(10, 0);
|
||||
else
|
||||
CPU_INT(10, vif1ch->qwc * BIAS);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,16 +92,16 @@ static __forceinline u32 setVifRowRegs(u32 reg, u32 data)
|
|||
switch (reg)
|
||||
{
|
||||
case 0:
|
||||
vifRegs->r0 += data;
|
||||
vifRegs->r0 = data;
|
||||
break;
|
||||
case 1:
|
||||
vifRegs->r1 += data;
|
||||
vifRegs->r1 = data;
|
||||
break;
|
||||
case 2:
|
||||
vifRegs->r2 += data;
|
||||
vifRegs->r2 = data;
|
||||
break;
|
||||
case 3:
|
||||
vifRegs->r3 += data;
|
||||
vifRegs->r3 = data;
|
||||
break;
|
||||
jNO_DEFAULT;
|
||||
}
|
||||
|
|
|
@ -328,6 +328,10 @@ static void ProcessMemSkip(int size, unsigned int unpackType, const unsigned int
|
|||
VIFUNPACK_LOG("addr aligned to %x", vif->tag.addr);
|
||||
vif->tag.addr = (vif->tag.addr & ~0xf) + (vifRegs->offset * 4);
|
||||
}
|
||||
if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
|
||||
{
|
||||
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -634,14 +638,16 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
|
|||
}
|
||||
else
|
||||
{
|
||||
//DevCon::Notice("VIF%x Unpack ending %x > %x", params VIFdmanum, tempsize, VIFdmanum ? 0x4000 : 0x1000);
|
||||
DevCon::Notice("VIF%x Unpack ending %x > %x", params VIFdmanum, tempsize, VIFdmanum ? 0x4000 : 0x1000);
|
||||
tempsize = size;
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tempsize = 0;
|
||||
tempsize = 0; //Commenting out this then
|
||||
//tempsize = size; // -\_uncommenting these Two enables non-SSE unpacks
|
||||
//size = 0; // -/
|
||||
}
|
||||
|
||||
if (size >= ft->gsize)
|
||||
|
@ -745,6 +751,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
|
|||
{
|
||||
int incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4;
|
||||
size = 0;
|
||||
int addrstart = v->addr;
|
||||
if((tempsize >> 2) != vif->tag.size) DevCon::Notice("split when size != tagsize");
|
||||
|
||||
VIFUNPACK_LOG("sorting tempsize :p, size %d, vifnum %d, addr %x", tempsize, vifRegs->num, vif->tag.addr);
|
||||
|
@ -753,6 +760,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
|
|||
{
|
||||
if(v->addr >= memlimit)
|
||||
{
|
||||
DevCon::Notice("Mem limit ovf");
|
||||
v->addr &= (memlimit - 1);
|
||||
dest = (u32*)(VU->Mem + v->addr);
|
||||
}
|
||||
|
@ -789,6 +797,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
|
|||
v->addr &= (memlimit - 1);
|
||||
dest = (u32*)(VU->Mem + v->addr);
|
||||
}
|
||||
v->addr = addrstart;
|
||||
if(tempsize > 0) size = tempsize;
|
||||
|
||||
}
|
||||
|
@ -2057,7 +2066,7 @@ static void Vif1CMDSTMod() // STMOD
|
|||
|
||||
u8 schedulepath3msk = 0;
|
||||
|
||||
static void Vif1MskPath3() // MSKPATH3
|
||||
void Vif1MskPath3() // MSKPATH3
|
||||
{
|
||||
vif1Regs->mskpath3 = schedulepath3msk & 0x1;
|
||||
//Console::WriteLn("VIF MSKPATH3 %x", params vif1Regs->mskpath3);
|
||||
|
|
|
@ -55,6 +55,7 @@ struct vifStruct {
|
|||
|
||||
extern vifStruct vif0, vif1;
|
||||
extern int Path3progress;
|
||||
extern u8 schedulepath3msk;
|
||||
|
||||
void __fastcall UNPACK_S_32( u32 *dest, u32 *data, int size );
|
||||
|
||||
|
@ -95,6 +96,7 @@ void vif0Init();
|
|||
void vif1Init();
|
||||
extern void vif0Interrupt();
|
||||
extern void vif1Interrupt();
|
||||
extern void Vif1MskPath3();
|
||||
|
||||
void vif0Write32(u32 mem, u32 value);
|
||||
void vif1Write32(u32 mem, u32 value);
|
||||
|
|
Loading…
Reference in New Issue