From 61f7a4ddabb4e205ca3efd1016e6988e44d71583 Mon Sep 17 00:00:00 2001 From: sudonim1 Date: Fri, 25 Jun 2010 01:49:26 +0000 Subject: [PATCH] SPU2-X: Double IRQ prevention found on real hardware. Only affects developers who didn't read the SDK documentation properly, like me. Nothing fixed as far as we know. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3294 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/spu2-x/src/Dma.cpp | 33 +++++++++++---------------------- plugins/spu2-x/src/Mixer.cpp | 6 ++---- plugins/spu2-x/src/Reverb.cpp | 3 +-- plugins/spu2-x/src/defs.h | 2 +- plugins/spu2-x/src/spu2sys.cpp | 10 +++++++--- 5 files changed, 22 insertions(+), 32 deletions(-) diff --git a/plugins/spu2-x/src/Dma.cpp b/plugins/spu2-x/src/Dma.cpp index d84817d7fb..6154f1f376 100644 --- a/plugins/spu2-x/src/Dma.cpp +++ b/plugins/spu2-x/src/Dma.cpp @@ -275,15 +275,13 @@ void V_Core::PlainDMAWrite(u16 *pMem, u32 size) if ((Cores[i].IRQEnable && (Cores[i].IRQA >= TSA)) || (Cores[i].IRQA < TDA)) { ConLog("DMAwrite Core %d: IRQ Called (IRQ passed). IRQA = %x Cycles = %d\n", i, Cores[i].IRQA, Cycles ); - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } #else if ((IRQEnable && (IRQA >= TSA)) || (IRQA < TDA)) { - Spdif.Info |= 4 << Index; - SetIrqCall(); + SetIrqCall(Index); } #endif } @@ -305,15 +303,13 @@ void V_Core::PlainDMAWrite(u16 *pMem, u32 size) if( Cores[i].IRQEnable && (Cores[i].IRQA >= TSA) && (Cores[i].IRQA < TDA) ) { ConLog("DMAwrite Core %d: IRQ Called (IRQ passed). IRQA = %x Cycles = %d\n", i, Cores[i].IRQA, Cycles ); - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } #else if( IRQEnable && (IRQA >= TSA) && (IRQA < TDA) ) { - Spdif.Info |= 4 << Index; - SetIrqCall(); + SetIrqCall(Index); } #endif } @@ -360,8 +356,7 @@ void V_Core::DoDMAread(u16* pMem, u32 size) { if ((Cores[i].IRQEnable && (Cores[i].IRQA >= TSA)) || (Cores[i].IRQA < TDA)) { - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } } @@ -379,8 +374,7 @@ void V_Core::DoDMAread(u16* pMem, u32 size) { if( Cores[i].IRQEnable && (Cores[i].IRQA >= TSA) && (Cores[i].IRQA < TDA) ) { - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } } @@ -475,8 +469,7 @@ s32 V_Core::NewDmaRead(u32* data, u32 bytesLeft, u32* bytesProcessed) { if( Cores[i].IRQEnable && (Cores[i].IRQA >= TSA) || (Cores[i].IRQA < TDA) ) { - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } } @@ -494,8 +487,7 @@ s32 V_Core::NewDmaRead(u32* data, u32 bytesLeft, u32* bytesProcessed) { if( Cores[i].IRQEnable && (Cores[i].IRQA >= TSA) && (Cores[i].IRQA < TDA) ) { - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } } @@ -569,8 +561,7 @@ s32 V_Core::NewDmaWrite(u32* data, u32 bytesLeft, u32* bytesProcessed) { if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) ) { - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } } @@ -590,8 +581,7 @@ s32 V_Core::NewDmaWrite(u32* data, u32 bytesLeft, u32* bytesProcessed) { if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) ) { - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } @@ -609,8 +599,7 @@ s32 V_Core::NewDmaWrite(u32* data, u32 bytesLeft, u32* bytesProcessed) { if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) ) { - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } diff --git a/plugins/spu2-x/src/Mixer.cpp b/plugins/spu2-x/src/Mixer.cpp index 56712c493c..a575efff17 100644 --- a/plugins/spu2-x/src/Mixer.cpp +++ b/plugins/spu2-x/src/Mixer.cpp @@ -116,8 +116,7 @@ static void __forceinline IncrementNextA(V_Core& thiscore, uint voiceidx) if( IsDevBuild ) ConLog(" * SPU2 Core %d: IRQ Called (IRQA (%05X) passed; voice %d).\n", i, Cores[i].IRQA, thiscore.Index * 24 + voiceidx); - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } @@ -509,8 +508,7 @@ static __forceinline void spu2M_WriteFast( u32 addr, s16 value ) if( Cores[i].IRQEnable && Cores[i].IRQA == addr ) { //printf("Core %d special write IRQ Called (IRQ passed). IRQA = %x\n",i,addr); - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } // throw an assertion if the memory range is invalid: diff --git a/plugins/spu2-x/src/Reverb.cpp b/plugins/spu2-x/src/Reverb.cpp index 1d741dd62d..8044ba7a0c 100644 --- a/plugins/spu2-x/src/Reverb.cpp +++ b/plugins/spu2-x/src/Reverb.cpp @@ -154,8 +154,7 @@ StereoOut32 V_Core::DoReverb( const StereoOut32& Input ) (Cores[i].IRQA == mix_dest_b0) || (Cores[i].IRQA == mix_dest_b1) ) { //printf("Core %d IRQ Called (Reverb). IRQA = %x\n",i,addr); - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } } diff --git a/plugins/spu2-x/src/defs.h b/plugins/spu2-x/src/defs.h index 48fa5c18f7..0324f1f974 100644 --- a/plugins/spu2-x/src/defs.h +++ b/plugins/spu2-x/src/defs.h @@ -528,7 +528,7 @@ extern s16* spu2regs; extern s16* _spu2mem; extern int PlayMode; -extern void SetIrqCall(); +extern void SetIrqCall(int core); extern void StartVoices(int core, u32 value); extern void StopVoices(int core, u32 value); extern void InitADSR(); diff --git a/plugins/spu2-x/src/spu2sys.cpp b/plugins/spu2-x/src/spu2sys.cpp index 0ac7b3f5f7..7b6c54569b 100644 --- a/plugins/spu2-x/src/spu2sys.cpp +++ b/plugins/spu2-x/src/spu2sys.cpp @@ -42,8 +42,13 @@ int PlayMode; bool has_to_call_irq=false; -void SetIrqCall() +void SetIrqCall(int core) { + // reset by an irq disable/enable cycle, behaviour found by + // test programs that bizarrely only fired one interrupt + if (Spdif.Info & 4 << core) + return; + Spdif.Info |= 4 << core; has_to_call_irq=true; } @@ -856,8 +861,7 @@ static void __fastcall RegWrite_Core( u16 value ) { if(Cores[i].IRQEnable && (Cores[i].IRQA == thiscore.TSA)) { - Spdif.Info |= 4 << i; - SetIrqCall(); + SetIrqCall(i); } } thiscore.DmaWrite( value );