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
This commit is contained in:
Jake.Stine 2008-12-08 07:57:04 +00:00 committed by Gregory Hainaut
parent 7b2868c47b
commit 479795370e
4 changed files with 34 additions and 29 deletions

View File

@ -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;
}

View File

@ -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++;

View File

@ -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<<n) )
// SysPrintf( "***** IOP > 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)

View File

@ -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
}