diff --git a/pcsx2/COP0.cpp b/pcsx2/COP0.cpp index 500f2eeaf9..ea94cf3f7e 100644 --- a/pcsx2/COP0.cpp +++ b/pcsx2/COP0.cpp @@ -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;*/ } } } diff --git a/pcsx2/Counters.cpp b/pcsx2/Counters.cpp index d8af6b3f80..3825b41d59 100644 --- a/pcsx2/Counters.cpp +++ b/pcsx2/Counters.cpp @@ -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); diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index 53789055bc..abb171d06e 100644 --- a/pcsx2/GS.cpp +++ b/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 } diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index 43659dc34a..16155c09e7 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -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; diff --git a/pcsx2/MTGS.cpp b/pcsx2/MTGS.cpp index 8b8c949302..dfebe33b8f 100644 --- a/pcsx2/MTGS.cpp +++ b/pcsx2/MTGS.cpp @@ -137,23 +137,30 @@ static void RegHandlerSIGNAL(const u32* data) GSSIGLBLID->SIGID = (GSSIGLBLID->SIGID&~data[1])|(data[0]&data[1]); - if ((CSRw & 0x1)) + 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)) + 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) diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index 76f466303c..f61b024b75 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -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; } diff --git a/pcsx2/Vif.h b/pcsx2/Vif.h index 2f84369b5a..64335c4dde 100644 --- a/pcsx2/Vif.h +++ b/pcsx2/Vif.h @@ -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; } diff --git a/pcsx2/VifDma.cpp b/pcsx2/VifDma.cpp index de78c47275..fcbe73b6bf 100644 --- a/pcsx2/VifDma.cpp +++ b/pcsx2/VifDma.cpp @@ -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); diff --git a/pcsx2/VifDma.h b/pcsx2/VifDma.h index 56c08d7d6f..3a5d85000b 100644 --- a/pcsx2/VifDma.h +++ b/pcsx2/VifDma.h @@ -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);