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
This commit is contained in:
sudonim1 2010-06-25 01:49:26 +00:00
parent c18b61f585
commit 61f7a4ddab
5 changed files with 22 additions and 32 deletions

View File

@ -275,15 +275,13 @@ void V_Core::PlainDMAWrite(u16 *pMem, u32 size)
if ((Cores[i].IRQEnable && (Cores[i].IRQA >= TSA)) || (Cores[i].IRQA < TDA)) 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 ); ConLog("DMAwrite Core %d: IRQ Called (IRQ passed). IRQA = %x Cycles = %d\n", i, Cores[i].IRQA, Cycles );
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }
#else #else
if ((IRQEnable && (IRQA >= TSA)) || (IRQA < TDA)) if ((IRQEnable && (IRQA >= TSA)) || (IRQA < TDA))
{ {
Spdif.Info |= 4 << Index; SetIrqCall(Index);
SetIrqCall();
} }
#endif #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) ) 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 ); ConLog("DMAwrite Core %d: IRQ Called (IRQ passed). IRQA = %x Cycles = %d\n", i, Cores[i].IRQA, Cycles );
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }
#else #else
if( IRQEnable && (IRQA >= TSA) && (IRQA < TDA) ) if( IRQEnable && (IRQA >= TSA) && (IRQA < TDA) )
{ {
Spdif.Info |= 4 << Index; SetIrqCall(Index);
SetIrqCall();
} }
#endif #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)) if ((Cores[i].IRQEnable && (Cores[i].IRQA >= TSA)) || (Cores[i].IRQA < TDA))
{ {
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }
} }
@ -379,8 +374,7 @@ void V_Core::DoDMAread(u16* pMem, u32 size)
{ {
if( Cores[i].IRQEnable && (Cores[i].IRQA >= TSA) && (Cores[i].IRQA < TDA) ) if( Cores[i].IRQEnable && (Cores[i].IRQA >= TSA) && (Cores[i].IRQA < TDA) )
{ {
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }
} }
@ -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) ) if( Cores[i].IRQEnable && (Cores[i].IRQA >= TSA) || (Cores[i].IRQA < TDA) )
{ {
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }
} }
@ -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) ) if( Cores[i].IRQEnable && (Cores[i].IRQA >= TSA) && (Cores[i].IRQA < TDA) )
{ {
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }
} }
@ -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) ) if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) )
{ {
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }
} }
@ -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) ) if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) )
{ {
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }
@ -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) ) if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) )
{ {
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }

View File

@ -116,8 +116,7 @@ static void __forceinline IncrementNextA(V_Core& thiscore, uint voiceidx)
if( IsDevBuild ) if( IsDevBuild )
ConLog(" * SPU2 Core %d: IRQ Called (IRQA (%05X) passed; voice %d).\n", i, Cores[i].IRQA, thiscore.Index * 24 + voiceidx); 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(i);
SetIrqCall();
} }
} }
@ -509,8 +508,7 @@ static __forceinline void spu2M_WriteFast( u32 addr, s16 value )
if( Cores[i].IRQEnable && Cores[i].IRQA == addr ) if( Cores[i].IRQEnable && Cores[i].IRQA == addr )
{ {
//printf("Core %d special write IRQ Called (IRQ passed). IRQA = %x\n",i,addr); //printf("Core %d special write IRQ Called (IRQ passed). IRQA = %x\n",i,addr);
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }
// throw an assertion if the memory range is invalid: // throw an assertion if the memory range is invalid:

View File

@ -154,8 +154,7 @@ StereoOut32 V_Core::DoReverb( const StereoOut32& Input )
(Cores[i].IRQA == mix_dest_b0) || (Cores[i].IRQA == mix_dest_b1) ) (Cores[i].IRQA == mix_dest_b0) || (Cores[i].IRQA == mix_dest_b1) )
{ {
//printf("Core %d IRQ Called (Reverb). IRQA = %x\n",i,addr); //printf("Core %d IRQ Called (Reverb). IRQA = %x\n",i,addr);
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }
} }

View File

@ -528,7 +528,7 @@ extern s16* spu2regs;
extern s16* _spu2mem; extern s16* _spu2mem;
extern int PlayMode; extern int PlayMode;
extern void SetIrqCall(); extern void SetIrqCall(int core);
extern void StartVoices(int core, u32 value); extern void StartVoices(int core, u32 value);
extern void StopVoices(int core, u32 value); extern void StopVoices(int core, u32 value);
extern void InitADSR(); extern void InitADSR();

View File

@ -42,8 +42,13 @@ int PlayMode;
bool has_to_call_irq=false; 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; 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)) if(Cores[i].IRQEnable && (Cores[i].IRQA == thiscore.TSA))
{ {
Spdif.Info |= 4 << i; SetIrqCall(i);
SetIrqCall();
} }
} }
thiscore.DmaWrite( value ); thiscore.DmaWrite( value );