From 479795370e24087eb7c16b67efa7237ae79615b4 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Mon, 8 Dec 2008 07:57:04 +0000 Subject: [PATCH] Bugfix: SIO's DMA-Out cycle timing was way off the mark, and sometimes caused games to "lose" some SIO-related interrupts. git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@401 a6443dda-0b58-4228-96e9-037be469359c --- pcsx2/CDVD.c | 3 ++- pcsx2/PsxSio2.c | 9 +++------ pcsx2/R3000A.c | 37 +++++++++++++++++++++++-------------- pcsx2/VU1micro.c | 14 ++++++-------- 4 files changed, 34 insertions(+), 29 deletions(-) diff --git a/pcsx2/CDVD.c b/pcsx2/CDVD.c index d52e472fa8..68314273a9 100644 --- a/pcsx2/CDVD.c +++ b/pcsx2/CDVD.c @@ -890,6 +890,8 @@ int cdvdReadSector() { __forceinline void cdvdReadInterrupt() { //SysPrintf("cdvdReadInterrupt %x %x %x %x %x\n", cpuRegs.interrupt, cdvd.Readed, cdvd.Reading, cdvd.nSectors, (HW_DMA3_BCR_H16 * HW_DMA3_BCR_L16) *4); + psxRegs.interrupt &= ~(1<<19); + cdvd.Ready = 0x00; if (cdvd.Readed == 0) { cdvd.RetryCntP = 0; @@ -932,7 +934,6 @@ __forceinline void cdvdReadInterrupt() { HW_DMA3_CHCR &= ~0x01000000; psxDmaInterrupt(3); cdvd.Ready = 0x4e; - psxRegs.interrupt&= ~(1 << 19); return; } diff --git a/pcsx2/PsxSio2.c b/pcsx2/PsxSio2.c index 9528343f8b..c71dc15e30 100644 --- a/pcsx2/PsxSio2.c +++ b/pcsx2/PsxSio2.c @@ -228,7 +228,6 @@ void psxDma11(u32 madr, u32 bcr, u32 chcr) { return; } } - } HW_DMA11_MADR = madr; @@ -243,16 +242,14 @@ void psxDMA11Interrupt() } void psxDma12(u32 madr, u32 bcr, u32 chcr) { - int size = bcr; - PSXDMA_LOG("*** DMA 12 - SIO2 out *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - + int size = ((bcr >> 16) * (bcr & 0xFFFF)) * 4; + PSXDMA_LOG("*** DMA 12 - SIO2 out *** %lx addr = %lx size = %lx\n", chcr, madr, size); if (chcr != 0x41000200) return; sio2.recvIndex = 0; // Set To start; saqib - bcr = ((bcr >> 16) * (bcr & 0xFFFF)) * 4; // 8 bits - + bcr = size; while (bcr > 0) { PSXMu8(madr) = sio2_fifoOut(); bcr--; madr++; diff --git a/pcsx2/R3000A.c b/pcsx2/R3000A.c index 9902f8c73a..cfb612a323 100644 --- a/pcsx2/R3000A.c +++ b/pcsx2/R3000A.c @@ -100,14 +100,14 @@ void psxException(u32 code, u32 bd) { psxRegs.CP0.n.Cause &= ~0x7f; psxRegs.CP0.n.Cause |= code; -#ifdef PSXCPU_LOG - if (bd) { PSXCPU_LOG("bd set\n"); } -#endif // Set the EPC & PC - if (bd) { + if (bd) + { + PSXCPU_LOG("bd set\n"); psxRegs.CP0.n.Cause|= 0x80000000; psxRegs.CP0.n.EPC = (psxRegs.pc - 4); - } else + } + else psxRegs.CP0.n.EPC = (psxRegs.pc); if (psxRegs.CP0.n.Status & 0x400000) @@ -128,21 +128,22 @@ void psxException(u32 code, u32 bd) { u32 call = psxRegs.GPR.n.t1 & 0xff; switch (psxRegs.pc & 0x1fffff) { case 0xa0: -#ifdef PSXBIOS_LOG - if (call != 0x28 && call != 0xe) { - PSXBIOS_LOG("Bios call a0: %s (%x) %x,%x,%x,%x\n", biosA0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); } -#endif + + if (call != 0x28 && call != 0xe) + PSXBIOS_LOG("Bios call a0: %s (%x) %x,%x,%x,%x\n", biosA0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); + if (biosA0[call]) biosA0[call](); break; + case 0xb0: -#ifdef PSXBIOS_LOG - if (call != 0x17 && call != 0xb) { - PSXBIOS_LOG("Bios call b0: %s (%x) %x,%x,%x,%x\n", biosB0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); } -#endif + if (call != 0x17 && call != 0xb) + PSXBIOS_LOG("Bios call b0: %s (%x) %x,%x,%x,%x\n", biosB0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); + if (biosB0[call]) biosB0[call](); break; + case 0xc0: PSXBIOS_LOG("Bios call c0: %s (%x) %x,%x,%x,%x\n", biosC0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); @@ -181,6 +182,14 @@ __forceinline int psxTestCycle( u32 startCycle, s32 delta ) __forceinline void PSX_INT( int 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 + // code to help trap those sort of things. + + // Exception: IRQ16 - SIO - it drops ints like crazy when handling PAD stuff. + //if( /*n!=16 &&*/ psxRegs.interrupt & (1< Twice-thrown int on IRQ %d\n", n ); + psxRegs.interrupt |= 1 << n; psxRegs.sCycle[n] = psxRegs.cycle; @@ -214,7 +223,7 @@ static __forceinline void _psxTestInterrupts() { PSX_TESTINT(9, sif0Interrupt, 1); // SIF0 PSX_TESTINT(10, sif1Interrupt, 1); // SIF1 - PSX_TESTINT(16, sioInterrupt, 0); + //PSX_TESTINT(16, sioInterrupt, 0); PSX_TESTINT(19, cdvdReadInterrupt, 1); // Profile-guided Optimization (sorta) diff --git a/pcsx2/VU1micro.c b/pcsx2/VU1micro.c index a11ada5aed..37eb1c7283 100644 --- a/pcsx2/VU1micro.c +++ b/pcsx2/VU1micro.c @@ -200,9 +200,7 @@ void _vu1Exec(VURegs* VU) { int discard=0; if(VU1.VI[REG_TPC].UL >= VU1.maxmicro){ -#ifdef CPU_LOG - SysPrintf("VU1 memory overflow!!: %x\n", VU->VI[REG_TPC].UL); -#endif + CPU_LOG("VU1 memory overflow!!: %x\n", VU->VI[REG_TPC].UL); VU0.VI[REG_VPU_STAT].UL&= ~0x100; VU->cycle++; return; @@ -326,11 +324,11 @@ void vu1Exec(VURegs* VU) { } VU->cycle++; #ifdef CPU_LOG - if (VU->VI[0].UL != 0) SysPrintf("VI[0] != 0!!!!\n"); - if (VU->VF[0].f.x != 0.0f) SysPrintf("VF[0].x != 0.0!!!!\n"); - if (VU->VF[0].f.y != 0.0f) SysPrintf("VF[0].y != 0.0!!!!\n"); - if (VU->VF[0].f.z != 0.0f) SysPrintf("VF[0].z != 0.0!!!!\n"); - if (VU->VF[0].f.w != 1.0f) SysPrintf("VF[0].w != 1.0!!!!\n"); + if (VU->VI[0].UL != 0) CPU_LOG("VI[0] != 0!!!!\n"); + if (VU->VF[0].f.x != 0.0f) CPU_LOG("VF[0].x != 0.0!!!!\n"); + if (VU->VF[0].f.y != 0.0f) CPU_LOG("VF[0].y != 0.0!!!!\n"); + if (VU->VF[0].f.z != 0.0f) CPU_LOG("VF[0].z != 0.0!!!!\n"); + if (VU->VF[0].f.w != 1.0f) CPU_LOG("VF[0].w != 1.0!!!!\n"); #endif }