From 3aabc1adbf52cd18c303c9fdc956033a31ccd27a Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 24 Sep 2016 12:45:38 +0200 Subject: [PATCH 1/8] spu2x work 1 --- pcsx2/Sio.h | 10 +- plugins/spu2-x/src/Dma.cpp | 22 +- plugins/spu2-x/src/Global.h | 2 + plugins/spu2-x/src/Mixer.cpp | 37 +- plugins/spu2-x/src/ReadInput.cpp | 1 + .../spu2-x/src/Windows/RealtimeDebugger.cpp | 7 - plugins/spu2-x/src/defs.h | 27 + plugins/spu2-x/src/spu2sys.cpp | 527 +++++++++++++----- 8 files changed, 455 insertions(+), 178 deletions(-) diff --git a/pcsx2/Sio.h b/pcsx2/Sio.h index 6153f9bc55..00ffbd38b5 100644 --- a/pcsx2/Sio.h +++ b/pcsx2/Sio.h @@ -17,7 +17,7 @@ // Let's enable this to free the IOP event handler of some considerable load. // Games are highly unlikely to need timed IRQ's for PAD and MemoryCard handling anyway (rama). -#define SIO_INLINE_IRQS +//#define SIO_INLINE_IRQS #include "MemoryCardFile.h" @@ -30,8 +30,8 @@ struct _mcd u32 transferAddr; // Transfer address u8 FLAG; // for PSX; - - u8 port; // port + + u8 port; // port u8 slot; // and slot for this memcard // Auto Eject @@ -55,13 +55,13 @@ struct _mcd } // Read from memorycard to dest - void Read(u8 *dest, int size) + void Read(u8 *dest, int size) { SysPlugins.McdRead(port, slot, dest, transferAddr, size); } // Write to memorycard from src - void Write(u8 *src, int size) + void Write(u8 *src, int size) { SysPlugins.McdSave(port, slot, src,transferAddr, size); } diff --git a/plugins/spu2-x/src/Dma.cpp b/plugins/spu2-x/src/Dma.cpp index 766816c5f1..4b5c82407d 100644 --- a/plugins/spu2-x/src/Dma.cpp +++ b/plugins/spu2-x/src/Dma.cpp @@ -214,7 +214,10 @@ void V_Core::PlainDMAWrite(u16 *pMem, u32 size) else DMA7LogWrite(pMem,size<<1); - TSA &= 0xfffff; + if (psxmode) + TSA &= 0x7ffff; + else + TSA &= 0xfffff; u32 buff1end = TSA + size; u32 buff2end=0; @@ -235,14 +238,11 @@ void V_Core::PlainDMAWrite(u16 *pMem, u32 size) cacheLine++; } while ( cacheLine != &cacheEnd ); - //ConLog( "* SPU2-X: Cache Clear Range! TSA=0x%x, TDA=0x%x (low8=0x%x, high8=0x%x, len=0x%x)\n", - // TSA, buff1end, flagTSA, flagTDA, clearLen ); - - // First Branch needs cleared: // It starts at TSA and goes to buff1end. const u32 buff1size = (buff1end-TSA); + ConLog("* SPU2-X: DMA exec! TSA = %x buff1size*2 = %x\n", TSA, buff1size*2); memcpy( GetMemPtr( TSA ), pMem, buff1size*2 ); u32 TDA; @@ -261,7 +261,8 @@ void V_Core::PlainDMAWrite(u16 *pMem, u32 size) // 0x2800? Hard to know for sure (almost no games depend on this) memcpy( GetMemPtr( 0 ), &pMem[buff1size], buff2end*2 ); - TDA = (buff2end+1) & 0xfffff; + if (psxmode) TDA = (buff2end + 1) & 0x7ffff; + else TDA = (buff2end+1) & 0xfffff; // Flag interrupt? If IRQA occurs between start and dest, flag it. // Important: Test both core IRQ settings for either DMA! @@ -297,7 +298,8 @@ void V_Core::PlainDMAWrite(u16 *pMem, u32 size) // Buffer doesn't wrap/overflow! // Just set the TDA and check for an IRQ... - TDA = (buff1end + 1) & 0xfffff; + if (psxmode) TDA = (buff1end + 1) & 0x7ffff; + else TDA = (buff1end + 1) & 0xfffff; // Flag interrupt? If IRQA occurs between start and dest, flag it. // Important: Test both core IRQ settings for either DMA! @@ -402,6 +404,7 @@ void V_Core::DoDMAwrite(u16* pMem, u32 size) if(size<2) { //if(dma7callback) dma7callback(); + ConLog("* SPU2-X: Warning DMA Transfer of 0 bytes? size is %x\n", size); Regs.STATX &= ~0x80; //Regs.ATTR |= 0x30; DMAICounter=1; @@ -422,11 +425,12 @@ void V_Core::DoDMAwrite(u16* pMem, u32 size) } } - TSA &= 0xfffff; + if (psxmode) TSA &= 0x7ffff; + else TSA &= 0xfffff; bool adma_enable = ((AutoDMACtrl&(Index+1))==(Index+1)); - if(adma_enable) + if(adma_enable && !psxmode) // no adma in psx mode { TSA&=0x1fff; StartADMAWrite(pMem,size); diff --git a/plugins/spu2-x/src/Global.h b/plugins/spu2-x/src/Global.h index b8eda4d429..e79d2b520d 100644 --- a/plugins/spu2-x/src/Global.h +++ b/plugins/spu2-x/src/Global.h @@ -20,6 +20,8 @@ #define NOMINMAX +extern bool psxmode; + struct StereoOut16; struct StereoOut32; struct StereoOutFloat; diff --git a/plugins/spu2-x/src/Mixer.cpp b/plugins/spu2-x/src/Mixer.cpp index 4ddb8f3beb..414da0ba53 100644 --- a/plugins/spu2-x/src/Mixer.cpp +++ b/plugins/spu2-x/src/Mixer.cpp @@ -128,7 +128,8 @@ static void __forceinline IncrementNextA(V_Core& thiscore, uint voiceidx) } vc.NextA++; - vc.NextA&=0xFFFFF; + if (psxmode) vc.NextA &= 0x7FFFF; + else vc.NextA&=0xFFFFF; } // decoded pcm data, used to cache the decoded data so that it needn't be decoded @@ -588,9 +589,10 @@ static __forceinline StereoOut32 MixVoice( uint coreidx, uint voiceidx ) // Write-back of raw voice data (post ADSR applied) - if (voiceidx==1) spu2M_WriteFast( ( (0==coreidx) ? 0x400 : 0xc00 ) + OutPos, vc.OutX ); - else if (voiceidx==3) spu2M_WriteFast( ( (0==coreidx) ? 0x600 : 0xe00 ) + OutPos, vc.OutX ); - + if (!psxmode) { // i'm not sure if this is correct for psxmode. it doesn't seem to hurt to have it off so i assume it is bad. + if (voiceidx == 1) spu2M_WriteFast(((0 == coreidx) ? 0x400 : 0xc00) + OutPos, vc.OutX); + else if (voiceidx == 3) spu2M_WriteFast(((0 == coreidx) ? 0x600 : 0xe00) + OutPos, vc.OutX); + } return ApplyVolume( StereoOut32( Value, Value ), vc.Volume ); } else @@ -609,9 +611,10 @@ static __forceinline StereoOut32 MixVoice( uint coreidx, uint voiceidx ) } // Write-back of raw voice data (some zeros since the voice is "dead") - if (voiceidx==1) spu2M_WriteFast( ( (0==coreidx) ? 0x400 : 0xc00 ) + OutPos, 0 ); - else if (voiceidx==3) spu2M_WriteFast( ( (0==coreidx) ? 0x600 : 0xe00 ) + OutPos, 0 ); - + if (!psxmode) { // i'm not sure if this is correct for psxmode. it doesn't seem to hurt to have it off so i assume it is bad. + if (voiceidx == 1) spu2M_WriteFast(((0 == coreidx) ? 0x400 : 0xc00) + OutPos, 0); + else if (voiceidx == 3) spu2M_WriteFast(((0 == coreidx) ? 0x600 : 0xe00) + OutPos, 0); + } return StereoOut32( 0, 0 ); } } @@ -642,11 +645,13 @@ StereoOut32 V_Core::Mix( const VoiceMixSet& inVoices, const StereoOut32& Input, // Saturate final result to standard 16 bit range. const VoiceMixSet Voices( clamp_mix( inVoices.Dry ), clamp_mix( inVoices.Wet ) ); - // Write Mixed results To Output Area - spu2M_WriteFast( ( (0==Index) ? 0x1000 : 0x1800 ) + OutPos, Voices.Dry.Left ); - spu2M_WriteFast( ( (0==Index) ? 0x1200 : 0x1A00 ) + OutPos, Voices.Dry.Right ); - spu2M_WriteFast( ( (0==Index) ? 0x1400 : 0x1C00 ) + OutPos, Voices.Wet.Left ); - spu2M_WriteFast( ( (0==Index) ? 0x1600 : 0x1E00 ) + OutPos, Voices.Wet.Right ); + if (!psxmode) { + // Write Mixed results To Output Area + spu2M_WriteFast(((0 == Index) ? 0x1000 : 0x1800) + OutPos, Voices.Dry.Left); + spu2M_WriteFast(((0 == Index) ? 0x1200 : 0x1A00) + OutPos, Voices.Dry.Right); + spu2M_WriteFast(((0 == Index) ? 0x1400 : 0x1C00) + OutPos, Voices.Wet.Left); + spu2M_WriteFast(((0 == Index) ? 0x1600 : 0x1E00) + OutPos, Voices.Wet.Right); + } // Write mixed results to logfile (if enabled) @@ -833,10 +838,12 @@ void Mix() Ext = clamp_mix( ApplyVolume( Ext, Cores[0].MasterVol ) ); } - // Commit Core 0 output to ram before mixing Core 1: + if (!psxmode) { + // Commit Core 0 output to ram before mixing Core 1: + spu2M_WriteFast(0x800 + OutPos, Ext.Left); + spu2M_WriteFast(0xA00 + OutPos, Ext.Right); + } - spu2M_WriteFast( 0x800 + OutPos, Ext.Left ); - spu2M_WriteFast( 0xA00 + OutPos, Ext.Right ); WaveDump::WriteCore( 0, CoreSrc_External, Ext ); Ext = ApplyVolume( Ext, Cores[1].ExtVol ); diff --git a/plugins/spu2-x/src/ReadInput.cpp b/plugins/spu2-x/src/ReadInput.cpp index 9326a97004..78a3b81a21 100644 --- a/plugins/spu2-x/src/ReadInput.cpp +++ b/plugins/spu2-x/src/ReadInput.cpp @@ -31,6 +31,7 @@ // StereoOut32 V_Core::ReadInput_HiFi() { + if (psxmode)ConLog("ReadInput_HiFi!!!!!\n"); InputPosRead &= ~1; // //#ifdef PCM24_S1_INTERLEAVE diff --git a/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp b/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp index d1bf7aceda..64be714416 100644 --- a/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp +++ b/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp @@ -164,13 +164,6 @@ void UpdateDebugDialog() TextOut(hdc,IX+4,IY+32,t,6); vcd.displayPeak = 0; - - if(vcd.lastSetStartA != vc.StartA) - { - printf(" *** Warning! Core %d Voice %d: StartA should be %06x, and is %06x.\n", - c,v,vcd.lastSetStartA,vc.StartA); - vcd.lastSetStartA = vc.StartA; - } } // top now: 400 diff --git a/plugins/spu2-x/src/defs.h b/plugins/spu2-x/src/defs.h index 0306b6c478..be28eec75d 100644 --- a/plugins/spu2-x/src/defs.h +++ b/plugins/spu2-x/src/defs.h @@ -28,6 +28,7 @@ extern s16* GetMemPtr(u32 addr); extern s16 spu2M_Read( u32 addr ); +extern s16 spu2M_ReadPSX(u32 addr); extern void spu2M_Write( u32 addr, s16 value ); extern void spu2M_Write( u32 addr, u16 value ); @@ -154,6 +155,10 @@ struct V_Voice s32 Prev1; s32 Prev2; + // psx caches + u16 psxPitch; + u16 psxLoopStartA; + u16 psxStartA; // Pitch Modulated by previous voice bool Modulated; // Source (Wave/Noise) @@ -441,6 +446,15 @@ struct V_Core u32 KeyOn; // not the KON register (though maybe it is) + // psxmode caches + u16 psxIRQA; + u16 psxTSA; + u16 psxSPUCNT; + u16 psxSoundDataTransferControl; + u16 psxSPUSTAT; + u16 psxReverbStartA; + + StereoOut32 downbuf[8]; StereoOut32 upbuf[8]; int dbpos, ubpos; @@ -505,12 +519,25 @@ struct V_Core return ret; } + __forceinline u16 DmaReadPSX() + { + const u16 ret = (u16)spu2M_ReadPSX(TSA); + ++TSA; TSA &= 0x7ffff; + return ret; + } + __forceinline void DmaWrite(u16 value) { spu2M_Write( TSA, value ); ++TSA; TSA &= 0xfffff; } + __forceinline void DmaWritePSX(u16 value) + { + spu2M_Write(TSA, value); + ++TSA; TSA &= 0x7ffff; + } + void LogAutoDMA( FILE* fp ); s32 NewDmaRead(u32* data, u32 bytesLeft, u32* bytesProcessed); diff --git a/plugins/spu2-x/src/spu2sys.cpp b/plugins/spu2-x/src/spu2sys.cpp index db12e90124..c52478c7eb 100644 --- a/plugins/spu2-x/src/spu2sys.cpp +++ b/plugins/spu2-x/src/spu2sys.cpp @@ -42,6 +42,8 @@ int PlayMode; bool has_to_call_irq=false; +bool psxmode = false; + void SetIrqCall(int core) { // reset by an irq disable/enable cycle, behaviour found by @@ -67,6 +69,11 @@ __forceinline s16 spu2M_Read( u32 addr ) return *GetMemPtr( addr & 0xfffff ); } +__forceinline s16 spu2M_ReadPSX(u32 addr) +{ + return *GetMemPtr(addr & 0x7ffff); +} + // writes a signed value to the SPU2 ram // Invalidates the ADPCM cache in the process. __forceinline void spu2M_Write( u32 addr, s16 value ) @@ -116,6 +123,7 @@ void V_Core::Init( int index ) { ConLog( "* SPU2-X: Init SPU2 core %d \n", index ); memset( this, 0, sizeof(V_Core) ); + psxmode = false; const int c = Index = index; @@ -191,32 +199,32 @@ void V_Core::AnalyzeReverbPreset() { ConLog("Reverb Parameter Update for Core %d:\n", Index); ConLog("----------------------------------------------------------\n"); - + ConLog(" IN_COEF_L, IN_COEF_R 0x%08x, 0x%08x\n", Revb.IN_COEF_L, Revb.IN_COEF_R); ConLog(" FB_SRC_A, FB_SRC_B 0x%08x, 0x%08x\n", Revb.FB_SRC_A, Revb.FB_SRC_B); ConLog(" FB_ALPHA, FB_X 0x%08x, 0x%08x\n", Revb.FB_ALPHA, Revb.FB_X); - + ConLog(" ACC_COEF_A 0x%08x\n", Revb.ACC_COEF_A); ConLog(" ACC_COEF_B 0x%08x\n", Revb.ACC_COEF_B); ConLog(" ACC_COEF_C 0x%08x\n", Revb.ACC_COEF_C); ConLog(" ACC_COEF_D 0x%08x\n", Revb.ACC_COEF_D); - + ConLog(" ACC_SRC_A0, ACC_SRC_A1 0x%08x, 0x%08x\n", Revb.ACC_SRC_A0, Revb.ACC_SRC_A1); ConLog(" ACC_SRC_B0, ACC_SRC_B1 0x%08x, 0x%08x\n", Revb.ACC_SRC_B0, Revb.ACC_SRC_B1); ConLog(" ACC_SRC_C0, ACC_SRC_C1 0x%08x, 0x%08x\n", Revb.ACC_SRC_C0, Revb.ACC_SRC_C1); ConLog(" ACC_SRC_D0, ACC_SRC_D1 0x%08x, 0x%08x\n", Revb.ACC_SRC_D0, Revb.ACC_SRC_D1); - + ConLog(" IIR_SRC_A0, IIR_SRC_A1 0x%08x, 0x%08x\n", Revb.IIR_SRC_A0, Revb.IIR_SRC_A1); ConLog(" IIR_SRC_B0, IIR_SRC_B1 0x%08x, 0x%08x\n", Revb.IIR_SRC_B0, Revb.IIR_SRC_B1); ConLog(" IIR_DEST_A0, IIR_DEST_A1 0x%08x, 0x%08x\n", Revb.IIR_DEST_A0, Revb.IIR_DEST_A1); - ConLog(" IIR_DEST_B0, IIR_DEST_B1 0x%08x, 0x%08x\n", Revb.IIR_DEST_B0, Revb.IIR_DEST_B1); + ConLog(" IIR_DEST_B0, IIR_DEST_B1 0x%08x, 0x%08x\n", Revb.IIR_DEST_B0, Revb.IIR_DEST_B1); ConLog(" IIR_ALPHA, IIR_COEF 0x%08x, 0x%08x\n", Revb.IIR_ALPHA, Revb.IIR_COEF); ConLog(" MIX_DEST_A0 0x%08x\n", Revb.MIX_DEST_A0); ConLog(" MIX_DEST_A1 0x%08x\n", Revb.MIX_DEST_A1); ConLog(" MIX_DEST_B0 0x%08x\n", Revb.MIX_DEST_B0); ConLog(" MIX_DEST_B1 0x%08x\n", Revb.MIX_DEST_B1); - + ConLog(" EffectsBufferSize 0x%x\n", EffectsBufferSize); ConLog("----------------------------------------------------------\n"); } @@ -226,7 +234,7 @@ s32 V_Core::EffectsBufferIndexer( s32 offset ) const // that it *4's all addresses before upping them to the SPU2 -- so our buffers are // already x4'd. It doesn't really make sense that we should x4 them again, and this // seems to work. (feedback-free in bios and DDS) --air - + u32 pos = EffectsStartA + offset; // Need to use modulus here, because games can and will drop the buffer size @@ -261,12 +269,12 @@ void V_Core::UpdateEffectsBufferSize() //printf("Rvb Area change: ESA = %x, EEA = %x, Size(dec) = %d, Size(hex) = %x FxEnable = %d\n", EffectsStartA, EffectsEndA, newbufsize * 2, newbufsize * 2, FxEnable); if( (newbufsize*2) > 0x20000 ) // max 128kb per core - { + { //printf("too big, returning\n"); //return; } if (newbufsize == EffectsBufferSize && EffectsStartA == EffectsBufferStart) return; - + RevBuffers.NeedsUpdated = false; EffectsBufferSize = newbufsize; EffectsBufferStart = EffectsStartA; @@ -274,7 +282,7 @@ void V_Core::UpdateEffectsBufferSize() if( EffectsBufferSize <= 0 ) return; //AnalyzeReverbPreset(); - + // Rebuild buffer indexers. RevBuffers.ACC_SRC_A0 = EffectsBufferIndexer( Revb.ACC_SRC_A0 ); RevBuffers.ACC_SRC_A1 = EffectsBufferIndexer( Revb.ACC_SRC_A1 ); @@ -401,6 +409,7 @@ __forceinline void TimeUpdate(u32 cClocks) Cores[0].DMAICounter-=TickInterval; if(Cores[0].DMAICounter<=0) { + ConLog("counter set and callback!\n"); Cores[0].MADR=Cores[0].TADR; Cores[0].DMAICounter=0; if(dma4callback) dma4callback(); @@ -489,6 +498,27 @@ void V_VolumeSlide::RegSet( u16 src ) Value = GetVol32( src ); } +// Ah the joys of endian-specific code! :D +static __forceinline void SetHiWord(u32& src, u16 value) +{ + ((u16*)&src)[1] = value; +} + +static __forceinline void SetLoWord(u32& src, u16 value) +{ + ((u16*)&src)[0] = value; +} + +static __forceinline u16 GetHiWord(u32& src) +{ + return ((u16*)&src)[1]; +} + +static __forceinline u16 GetLoWord(u32& src) +{ + return ((u16*)&src)[0]; +} + void V_Core::WriteRegPS1( u32 mem, u16 value ) { pxAssume( Index == 0 ); // Valid on Core 0 only! @@ -501,32 +531,89 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) //voice values u8 voice = ((reg-0x1c00)>>4); u8 vval = reg&0xf; + switch(vval) { case 0x0: //VOLL (Volume L) - Voices[voice].Volume.Left.Mode = 0; - Voices[voice].Volume.Left.RegSet( value << 1 ); - Voices[voice].Volume.Left.Reg_VOL = value; - break; + { + V_VolumeSlide& thisvol = Voices[voice].Volume.Left; + thisvol.Reg_VOL = value; + if (value & 0x8000) // +Lin/-Lin/+Exp/-Exp + { + thisvol.Mode = (value & 0xF000) >> 12; + thisvol.Increment = (value & 0x7F); + // We're not sure slides work 100% + if (IsDevBuild) ConLog("* SPU2: Voice uses Slides in Mode = %x, Increment = %x\n", thisvol.Mode, thisvol.Increment); + } + else + { + // Constant Volume mode (no slides or envelopes) + // Volumes range from 0x3fff to 0x7fff, with 0x4000 serving as + // the "sign" bit, so a simple bitwise extension will do the trick: + + thisvol.RegSet(value << 1); + thisvol.Mode = 0; + thisvol.Increment = 0; + } + //ConLog("voice %x VOLL write: %x\n", voice, value); + break; + } case 0x2: //VOLR (Volume R) - Voices[voice].Volume.Right.Mode = 0; - Voices[voice].Volume.Right.RegSet( value << 1 ); - Voices[voice].Volume.Right.Reg_VOL = value; - break; + { + V_VolumeSlide& thisvol = Voices[voice].Volume.Right; + thisvol.Reg_VOL = value; - case 0x4: Voices[voice].Pitch = value; break; - case 0x6: Voices[voice].StartA = (u32)value << 8; break; + if (value & 0x8000) // +Lin/-Lin/+Exp/-Exp + { + thisvol.Mode = (value & 0xF000) >> 12; + thisvol.Increment = (value & 0x7F); + // We're not sure slides work 100% + if (IsDevBuild) ConLog("* SPU2: Voice uses Slides in Mode = %x, Increment = %x\n", thisvol.Mode, thisvol.Increment); + } + else + { + // Constant Volume mode (no slides or envelopes) + // Volumes range from 0x3fff to 0x7fff, with 0x4000 serving as + // the "sign" bit, so a simple bitwise extension will do the trick: + + thisvol.RegSet(value << 1); + thisvol.Mode = 0; + thisvol.Increment = 0; + } + //ConLog("voice %x VOLR write: %x\n", voice, value); + break; + } + case 0x4: + if (value > 0x3fff) ConLog("* SPU2: Pitch setting too big: 0x%x\n", value); + Voices[voice].Pitch = value & 0x3fff; + //ConLog("voice %x Pitch write: %x\n", voice, Voices[voice].Pitch); + break; + case 0x6: + Voices[voice].StartA = value * 8; + Voices[voice].psxStartA = value; + //ConLog("voice %x StartA write: %x\n", voice, Voices[voice].StartA); + break; case 0x8: // ADSR1 (Envelope) Voices[voice].ADSR.regADSR1 = value; + //ConLog("voice %x regADSR1 write: %x\n", voice, Voices[voice].ADSR.regADSR1); break; case 0xa: // ADSR2 (Envelope) Voices[voice].ADSR.regADSR2 = value; + //ConLog("voice %x regADSR2 write: %x\n", voice, Voices[voice].ADSR.regADSR2); + break; + case 0xc: // Voice 0..23 ADSR Current Volume + // not commonly set by games + Voices[voice].ADSR.Value = (value << 16) | value; + //ConLog("voice %x ADSR.Value write: %x\n", voice, Voices[voice].ADSR.Value); + break; + case 0xe: + Voices[voice].LoopStartA = value * 8; + Voices[voice].psxLoopStartA = value; + //ConLog("voice %x LoopStartA write: %x\n", voice, Voices[voice].LoopStartA); break; - - case 0xe: Voices[voice].LoopStartA = (u32)value << 8; break; jNO_DEFAULT; } @@ -553,85 +640,193 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) break; case 0x1d88:// Voice ON (0-15) - SPU2_FastWrite(REG_S_KON,value); + StartVoices(0, (u32)value); break; case 0x1d8a:// Voice ON (16-23) - SPU2_FastWrite(REG_S_KON+2,value); + StartVoices(0, ((u32)value) << 16); break; case 0x1d8c:// Voice OFF (0-15) - SPU2_FastWrite(REG_S_KOFF,value); + StopVoices(0, (u32)value); break; case 0x1d8e:// Voice OFF (16-23) - SPU2_FastWrite(REG_S_KOFF+2,value); + StopVoices(0, ((u32)value) << 16); break; case 0x1d90:// Channel FM (pitch lfo) mode (0-15) - SPU2_FastWrite(REG_S_PMON,value); + Regs.PMON = value & 0xFFFF; + for (int vc = 1; vc<16; ++vc) + Voices[vc].Modulated = (value >> vc) & 1; + if (value != 0) ConLog("spu2x warning: wants to set Pitch Modulation reg1 to %x \n", value); break; case 0x1d92:// Channel FM (pitch lfo) mode (16-23) - SPU2_FastWrite(REG_S_PMON+2,value); + Regs.PMON = value << 16; + for (int vc = 0; vc<8; ++vc) + Voices[vc + 16].Modulated = (value >> vc) & 1; break; case 0x1d94:// Channel Noise mode (0-15) - SPU2_FastWrite(REG_S_NON,value); + SetLoWord(Regs.NON, value); + for (int vc = 0; vc<16; ++vc) + Voices[vc].Noise = (value >> vc) & 1; + if (value != 0) ConLog("spu2x warning: wants to set Channel Noise mode reg1 to %x\n", value); break; case 0x1d96:// Channel Noise mode (16-23) - SPU2_FastWrite(REG_S_NON+2,value); + SetHiWord(Regs.NON, value); + for (int vc = 0; vc<8; ++vc) + Voices[vc + 16].Noise = (value >> vc) & 1; + //ConLog("spu2x warning: wants to set Channel Noise mode reg2 to %x (ignored)\n", value); break; - case 0x1d98:// Channel Reverb mode (0-15) - SPU2_FastWrite(REG_S_VMIXEL,value); - SPU2_FastWrite(REG_S_VMIXER,value); + case 0x1d98:// 1F801D98h - Voice 0..23 Reverb mode aka Echo On (EON) (R/W) + //Regs.VMIXEL = value & 0xFFFF; + //ConLog("spu2x warning: setting reverb mode reg1 to %x \n", Regs.VMIXEL); break; - case 0x1d9a:// Channel Reverb mode (16-23) - SPU2_FastWrite(REG_S_VMIXEL+2,value); - SPU2_FastWrite(REG_S_VMIXER+2,value); + case 0x1d9a:// 1F801D98h + 2 - Voice 0..23 Reverb mode aka Echo On (EON) (R/W) + //Regs.VMIXEL = value << 16; + //ConLog("spu2x warning: setting reverb mode reg2 to %x \n", Regs.VMIXEL); break; - case 0x1d9c:// Channel Reverb mode (0-15) - SPU2_FastWrite(REG_S_VMIXL,value); - SPU2_FastWrite(REG_S_VMIXR,value); + // this was wrong? // edit: appears so! + //case 0x1d9c:// Channel Reverb mode (0-15) + // SPU2_FastWrite(REG_S_VMIXL,value); + // SPU2_FastWrite(REG_S_VMIXR,value); + //break; + + //case 0x1d9e:// Channel Reverb mode (16-23) + // SPU2_FastWrite(REG_S_VMIXL+2,value); + // SPU2_FastWrite(REG_S_VMIXR+2,value); + //break; + case 0x1d9c: // Voice 0..15 ON/OFF (status) (ENDX) (R) // writeable but hw overrides it shortly after + Regs.ENDX &= 0xff0000; + ConLog("spu2x warning: wants to set ENDX reg1 to %x \n", value); break; - case 0x1d9e:// Channel Reverb mode (16-23) - SPU2_FastWrite(REG_S_VMIXL+2,value); - SPU2_FastWrite(REG_S_VMIXR+2,value); + case 0x1d9e:// // Voice 15..23 ON/OFF (status) (ENDX) (R) // writeable but hw overrides it shortly after + Regs.ENDX &= 0xffff; + ConLog("spu2x warning: wants to set ENDX reg2 to %x \n", value); break; case 0x1da2:// Reverb work area start { - u32 val = (u32)value << 8; - - SPU2_FastWrite(REG_A_ESA, val&0xFFFF); - SPU2_FastWrite(REG_A_ESA+2,val>>16); + EffectsStartA = value * 8; + EffectsEndA = 0x7FFFF; // fixed EndA in psx mode + psxReverbStartA = value; + Cores[0].RevBuffers.NeedsUpdated = true; } break; case 0x1da4: - IRQA = (u32)value<<8; + IRQA = value * 8; + psxIRQA = value; + ConLog("SPU2-X Setting IRQA to %x value was %x \n", IRQA, value); break; case 0x1da6: - TSA = (u32)value<<8; + TSA = value * 8; + psxTSA = value; + ConLog("SPU2-X Setting TSA to %x value was %x \n", TSA, value); + break; + + case 0x1da8: // Spu Write to Memory + ConLog("SPU direct DMA Write. Current TSA = %x\n", TSA); + if (Cores[0].IRQEnable && (Cores[0].IRQA <= Cores[0].TSA)) + { + SetIrqCall(0); + _irqcallback(); + } + DmaWritePSX(value); + show = false; break; case 0x1daa: - SPU2_FastWrite(REG_C_ATTR,value); + { + psxSPUCNT = value; + ConLog("SPU Control register write with %x\n", value); + bool irqe = Cores[0].IRQEnable; + int bit0 = Cores[0].AttrBit0; + bool fxenable = Cores[0].FxEnable; + u8 oldDmaMode = Cores[0].DmaMode; + + Cores[0].AttrBit0 = (value >> 0) & 0x01; //1 bit + Cores[0].DMABits = (value >> 1) & 0x07; //3 bits + Cores[0].DmaMode = (value >> 4) & 0x03; //2 bit (not necessary, we get the direction from the iop) + Cores[0].IRQEnable = (value >> 6) & 0x01; //1 bit + Cores[0].FxEnable = (value >> 7) & 0x01; //1 bit + Cores[0].NoiseClk = (value >> 8) & 0x3f; //6 bits + //thiscore.Mute =(value>>14) & 0x01; //1 bit + Cores[0].Mute = 0; + //thiscore.CoreEnabled=(value>>15) & 0x01; //1 bit + // no clue + if (value >> 15) + Cores[0].Regs.STATX = 0; + Cores[0].Regs.ATTR = value & 0x7fff; + + if (fxenable && !Cores[0].FxEnable) + { + Cores[0].ReverbX = 0; + Cores[0].RevBuffers.NeedsUpdated = true; + } + + if (oldDmaMode != Cores[0].DmaMode) + { + // FIXME... maybe: if this mode was cleared in the middle of a DMA, should we interrupt it? + ConLog("* SPU2-X: DMA mode changed. oldDmaMode = %x , newDmaMode = %x \n", oldDmaMode,Cores[0].DmaMode); + Cores[0].Regs.STATX &= ~0x400; // ready to transfer + } + + if (value & 0x000E) + { + if (MsgToConsole()) ConLog("* SPU2-X: Core 0 ATTR unknown bits SET! value=%x\n", value); + } + + if (Cores[0].AttrBit0 != bit0) + { + if (MsgToConsole()) ConLog("* SPU2-X: ATTR bit 0 set to %d\n", Cores[0].AttrBit0); + } + if (Cores[0].IRQEnable != irqe) + { + ConLog("* SPU2-X: write reg psx Core%d IRQ %s at cycle %d. Current IRQA = %x Current TSA = %x\n", + 0, ((Cores[0].IRQEnable==0)?"disabled":"enabled"), Cycles, Cores[0].IRQA, Cores[0].TSA); + + if (!Cores[0].IRQEnable) + Spdif.Info &= ~(4 << Cores[0].Index); + } + } break; - case 0x1dae: - SPU2_FastWrite(REG_P_STATX,value); - break; + case 0x1dac: // 1F801DACh - Sound RAM Data Transfer Control (should be 0004h) + ConLog("SPU Sound RAM Data Transfer Control (should be 0004h) : value = %x \n", value); + psxSoundDataTransferControl = value; + break; + + case 0x1dae: // 1F801DAEh - SPU Status Register (SPUSTAT) (R) + // The SPUSTAT register should be treated read-only (writing is possible in so far that the written + // value can be read-back for a short moment, however, thereafter the hardware is overwriting that value). + //Regs.STATX = value; + break; + + case 0x1DB0: // 1F801DB0h 4 CD Volume Left/Right + break; // cd left? + case 0x1DB2: + break;// cd right? + case 0x1DB4: // 1F801DB4h 4 Extern Volume Left / Right + break; // Extern left? + case 0x1DB6: + break; // Extern right? + case 0x1DB8: // 1F801DB8h 4 Current Main Volume Left/Right + break; // Current left? + case 0x1DBA: + break; // Current right? + case 0x1DBC: // 1F801DBCh 4 Unknown? (R/W) + break; + case 0x1DBE: + break; - case 0x1da8:// Spu Write to Memory - DmaWrite(value); - show=false; - break; } if(show) FileLog("[%10d] (!) SPU write mem %08x value %04x\n",Cycles,mem,value); @@ -641,6 +836,7 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) u16 V_Core::ReadRegPS1(u32 mem) { + //ConLog("ReadRegPS1 from %x on core %d\n", mem, Index); pxAssume( Index == 0 ); // Valid on Core 0 only! bool show=true; @@ -655,24 +851,40 @@ u16 V_Core::ReadRegPS1(u32 mem) u8 vval = reg&0xf; switch(vval) { - case 0: //VOLL (Volume L) + case 0x0: //VOLL (Volume L) //value=Voices[voice].VolumeL.Mode; //value=Voices[voice].VolumeL.Value; value = Voices[voice].Volume.Left.Reg_VOL; - break; + break; - case 1: //VOLR (Volume R) + case 0x2: //VOLR (Volume R) //value=Voices[voice].VolumeR.Mode; //value=Voices[voice].VolumeR.Value; value = Voices[voice].Volume.Right.Reg_VOL; - break; + break; - case 2: value = Voices[voice].Pitch; break; - case 3: value = Voices[voice].StartA; break; - case 4: value = Voices[voice].ADSR.regADSR1; break; - case 5: value = Voices[voice].ADSR.regADSR2; break; - case 6: value = Voices[voice].ADSR.Value >> 16; break; - case 7: value = Voices[voice].LoopStartA; break; + case 0x4: + value = Voices[voice].Pitch; + //ConLog("voice %d read pitch result = %x\n", voice, value); + break; + case 0x6: + value = Voices[voice].psxStartA; + //ConLog("voice %d read StartA result = %x\n", voice, value); + break; + case 0x8: + value = Voices[voice].ADSR.regADSR1; + break; + case 0xa: + value = Voices[voice].ADSR.regADSR2; + break; + case 0xc: // Voice 0..23 ADSR Current Volume + value = Voices[voice].ADSR.Value >> 16; // no clue + //if (value != 0) ConLog("voice %d read ADSR.Value result = %x\n", voice, value); + break; + case 0xe: + value = Voices[voice].psxLoopStartA; + //ConLog("voice %d read LoopStartA result = %x\n", voice, value); + break; jNO_DEFAULT; } @@ -684,75 +896,58 @@ u16 V_Core::ReadRegPS1(u32 mem) case 0x1d84: value = FxVol.Left >> 16; break; case 0x1d86: value = FxVol.Right >> 16; break; - case 0x1d88: value = 0; break; + case 0x1d88: value = 0; break; // Voice 0..23 Key ON(Start Attack / Decay / Sustain) (W) case 0x1d8a: value = 0; break; - case 0x1d8c: value = 0; break; + case 0x1d8c: value = 0; break; // Voice 0..23 Key OFF (Start Release) (W) case 0x1d8e: value = 0; break; - case 0x1d90: value = Regs.PMON&0xFFFF; break; + case 0x1d90: value = Regs.PMON&0xFFFF; break; // Voice 0..23 Channel FM(pitch lfo) mode(R / W) case 0x1d92: value = Regs.PMON>>16; break; - case 0x1d94: value = Regs.NON&0xFFFF; break; + case 0x1d94: value = Regs.NON&0xFFFF; break; // Voice 0..23 Channel Noise mode (R/W) case 0x1d96: value = Regs.NON>>16; break; - case 0x1d98: value = Regs.VMIXEL&0xFFFF; break; + case 0x1d98: value = Regs.VMIXEL&0xFFFF; break; // Voice 0..23 Channel Reverb mode (R/W) case 0x1d9a: value = Regs.VMIXEL>>16; break; - case 0x1d9c: value = Regs.VMIXL&0xFFFF; break; - case 0x1d9e: value = Regs.VMIXL>>16; break; + /*case 0x1d9c: value = Regs.VMIXL&0xFFFF; break;*/ // this is wrong? + /*case 0x1d9e: value = Regs.VMIXL >> 16; break;*/ + case 0x1d9c: value = Regs.ENDX & 0xFFFF; break;// Voice 0..23 Channel ON / OFF(status) (R) (ENDX) + case 0x1d9e: value = Regs.ENDX >> 16; case 0x1da2: -#if 0 - // This smells of old hack - if( value != EffectsStartA>>3 ) - { - value = EffectsStartA>>3; - UpdateEffectsBufferSize(); - ReverbX = 0; - } -#else - value = EffectsStartA >> 3; -#endif - break; - case 0x1da4: value = IRQA>>3; break; - case 0x1da6: value = TSA>>3; break; - - case 0x1daa: - value = SPU2read(REG_C_ATTR); + value = psxReverbStartA; break; - case 0x1dae: - value = 0; //SPU2read(REG_P_STATX)<<3; + case 0x1da4: + value = psxIRQA; + ConLog("SPU2-X IRQA read: 0x1da4 = %x , (IRQA = %x)\n", value, IRQA); + break; + case 0x1da6: + value = psxTSA; + ConLog("SPU2-X TSA read: 0x1da6 = %x , (TSA = %x)\n", value, TSA); break; case 0x1da8: value = DmaRead(); show=false; break; + case 0x1daa: + //value = psxSPUCNT; + value = Cores[0].Regs.ATTR; + ConLog("SPU2-X ps1 reg psxSPUCNT read return value: %x\n", value); + break; + case 0x1dac: // 1F801DACh - Sound RAM Data Transfer Control (should be 0004h) + value = psxSoundDataTransferControl; + break; + case 0x1dae: + value = Regs.STATX; + //value = Cores[0].Regs.STATX; + ConLog("SPU2-X ps1 reg REG_P_STATX read return value: %x\n", value); + break; } if(show) FileLog("[%10d] (!) SPU read mem %08x value %04x\n",Cycles,mem,value); return value; } -// Ah the joys of endian-specific code! :D -static __forceinline void SetHiWord( u32& src, u16 value ) -{ - ((u16*)&src)[1] = value; -} - -static __forceinline void SetLoWord( u32& src, u16 value ) -{ - ((u16*)&src)[0] = value; -} - -static __forceinline u16 GetHiWord( u32& src ) -{ - return ((u16*)&src)[1]; -} - -static __forceinline u16 GetLoWord( u32& src ) -{ - return ((u16*)&src)[0]; -} - template< int CoreIdx, int VoiceIdx, int param > static void __fastcall RegWrite_VoiceParams( u16 value ) { @@ -871,7 +1066,7 @@ static void __fastcall RegWrite_Core( u16 value ) const int omem = cAddr; const int core = CoreIdx; V_Core& thiscore = Cores[core]; - + //ConLog("RegWrite_Core #%d addr: %x value %x \n", core, omem, value); switch(omem) { case REG__1AC: @@ -899,35 +1094,36 @@ static void __fastcall RegWrite_Core( u16 value ) case REG_C_ATTR: { - bool irqe = thiscore.IRQEnable; - int bit0 = thiscore.AttrBit0; - bool fxenable = thiscore.FxEnable; - u8 oldDmaMode = thiscore.DmaMode; - - thiscore.AttrBit0 =(value>> 0) & 0x01; //1 bit - thiscore.DMABits =(value>> 1) & 0x07; //3 bits - thiscore.DmaMode =(value>> 4) & 0x03; //2 bit (not necessary, we get the direction from the iop) - thiscore.IRQEnable =(value>> 6) & 0x01; //1 bit - thiscore.FxEnable =(value>> 7) & 0x01; //1 bit - thiscore.NoiseClk =(value>> 8) & 0x3f; //6 bits + bool irqe = thiscore.IRQEnable; + int bit0 = thiscore.AttrBit0; + bool fxenable = thiscore.FxEnable; + u8 oldDmaMode = thiscore.DmaMode; + + thiscore.AttrBit0 = (value >> 0) & 0x01; //1 bit + thiscore.DMABits = (value >> 1) & 0x07; //3 bits + thiscore.DmaMode = (value >> 4) & 0x03; //2 bit (not necessary, we get the direction from the iop) + thiscore.IRQEnable = (value >> 6) & 0x01; //1 bit + thiscore.FxEnable = (value >> 7) & 0x01; //1 bit + thiscore.NoiseClk = (value >> 8) & 0x3f; //6 bits //thiscore.Mute =(value>>14) & 0x01; //1 bit - thiscore.Mute =0; + thiscore.Mute = 0; //thiscore.CoreEnabled=(value>>15) & 0x01; //1 bit // no clue - if (value>>15) + if (value >> 15) thiscore.Regs.STATX = 0; - thiscore.Regs.ATTR =value&0x7fff; + thiscore.Regs.ATTR = value & 0x7fff; - if (fxenable && !thiscore.FxEnable - && (thiscore.EffectsStartA != thiscore.ExtEffectsStartA - || thiscore.EffectsEndA != thiscore.ExtEffectsEndA)) - { - thiscore.EffectsStartA = thiscore.ExtEffectsStartA; - thiscore.EffectsEndA = thiscore.ExtEffectsEndA; - thiscore.ReverbX = 0; - thiscore.RevBuffers.NeedsUpdated = true; + if (!psxmode) { + if (fxenable && !thiscore.FxEnable + && (thiscore.EffectsStartA != thiscore.ExtEffectsStartA + || thiscore.EffectsEndA != thiscore.ExtEffectsEndA)) + { + thiscore.EffectsStartA = thiscore.ExtEffectsStartA; + thiscore.EffectsEndA = thiscore.ExtEffectsEndA; + thiscore.ReverbX = 0; + thiscore.RevBuffers.NeedsUpdated = true; + } } - if(oldDmaMode != thiscore.DmaMode) { // FIXME... maybe: if this mode was cleared in the middle of a DMA, should we interrupt it? @@ -947,7 +1143,7 @@ static void __fastcall RegWrite_Core( u16 value ) { //ConLog("* SPU2-X: Core%d IRQ %s at cycle %d. Current IRQA = %x Current EffectA = %x\n", // core, ((thiscore.IRQEnable==0)?"disabled":"enabled"), Cycles, thiscore.IRQA, thiscore.EffectsStartA); - + if(!thiscore.IRQEnable) Spdif.Info &= ~(4 << thiscore.Index); } @@ -990,8 +1186,8 @@ static void __fastcall RegWrite_Core( u16 value ) SetLoWord( thiscore.Regs.reg_out, value ); \ if( result == thiscore.Regs.reg_out ) break; \ \ - const uint start_bit = (hiword) ? 16 : 0; \ - const uint end_bit = (hiword) ? 24 : 16; \ + const uint start_bit = hiword ? 16 : 0; \ + const uint end_bit = hiword ? 24 : 16; \ for (uint vc=start_bit, vx=1; vc, RegWrite_Core + RegWrite_Core, RegWrite_Core #define ReverbPair( core, mem ) \ - RegWrite_Reverb, RegWrite_Core + RegWrite_Reverb, RegWrite_Core #define REGRAW(addr) RegWrite_Raw From 08b6edae801499d9704469934abddfebdf7c493f Mon Sep 17 00:00:00 2001 From: Robert Neumann Date: Sat, 1 Oct 2016 10:28:48 +0200 Subject: [PATCH 2/8] psxmode: further spu2x work --- plugins/spu2-x/src/Dma.cpp | 22 +++++++++------------- plugins/spu2-x/src/spu2sys.cpp | 24 ++++++------------------ 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/plugins/spu2-x/src/Dma.cpp b/plugins/spu2-x/src/Dma.cpp index 4b5c82407d..766816c5f1 100644 --- a/plugins/spu2-x/src/Dma.cpp +++ b/plugins/spu2-x/src/Dma.cpp @@ -214,10 +214,7 @@ void V_Core::PlainDMAWrite(u16 *pMem, u32 size) else DMA7LogWrite(pMem,size<<1); - if (psxmode) - TSA &= 0x7ffff; - else - TSA &= 0xfffff; + TSA &= 0xfffff; u32 buff1end = TSA + size; u32 buff2end=0; @@ -238,11 +235,14 @@ void V_Core::PlainDMAWrite(u16 *pMem, u32 size) cacheLine++; } while ( cacheLine != &cacheEnd ); + //ConLog( "* SPU2-X: Cache Clear Range! TSA=0x%x, TDA=0x%x (low8=0x%x, high8=0x%x, len=0x%x)\n", + // TSA, buff1end, flagTSA, flagTDA, clearLen ); + + // First Branch needs cleared: // It starts at TSA and goes to buff1end. const u32 buff1size = (buff1end-TSA); - ConLog("* SPU2-X: DMA exec! TSA = %x buff1size*2 = %x\n", TSA, buff1size*2); memcpy( GetMemPtr( TSA ), pMem, buff1size*2 ); u32 TDA; @@ -261,8 +261,7 @@ void V_Core::PlainDMAWrite(u16 *pMem, u32 size) // 0x2800? Hard to know for sure (almost no games depend on this) memcpy( GetMemPtr( 0 ), &pMem[buff1size], buff2end*2 ); - if (psxmode) TDA = (buff2end + 1) & 0x7ffff; - else TDA = (buff2end+1) & 0xfffff; + TDA = (buff2end+1) & 0xfffff; // Flag interrupt? If IRQA occurs between start and dest, flag it. // Important: Test both core IRQ settings for either DMA! @@ -298,8 +297,7 @@ void V_Core::PlainDMAWrite(u16 *pMem, u32 size) // Buffer doesn't wrap/overflow! // Just set the TDA and check for an IRQ... - if (psxmode) TDA = (buff1end + 1) & 0x7ffff; - else TDA = (buff1end + 1) & 0xfffff; + TDA = (buff1end + 1) & 0xfffff; // Flag interrupt? If IRQA occurs between start and dest, flag it. // Important: Test both core IRQ settings for either DMA! @@ -404,7 +402,6 @@ void V_Core::DoDMAwrite(u16* pMem, u32 size) if(size<2) { //if(dma7callback) dma7callback(); - ConLog("* SPU2-X: Warning DMA Transfer of 0 bytes? size is %x\n", size); Regs.STATX &= ~0x80; //Regs.ATTR |= 0x30; DMAICounter=1; @@ -425,12 +422,11 @@ void V_Core::DoDMAwrite(u16* pMem, u32 size) } } - if (psxmode) TSA &= 0x7ffff; - else TSA &= 0xfffff; + TSA &= 0xfffff; bool adma_enable = ((AutoDMACtrl&(Index+1))==(Index+1)); - if(adma_enable && !psxmode) // no adma in psx mode + if(adma_enable) { TSA&=0x1fff; StartADMAWrite(pMem,size); diff --git a/plugins/spu2-x/src/spu2sys.cpp b/plugins/spu2-x/src/spu2sys.cpp index c52478c7eb..8a410cd10c 100644 --- a/plugins/spu2-x/src/spu2sys.cpp +++ b/plugins/spu2-x/src/spu2sys.cpp @@ -556,7 +556,7 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) thisvol.Mode = 0; thisvol.Increment = 0; } - //ConLog("voice %x VOLL write: %x\n", voice, value); + ConLog("voice %x VOLL write: %x\n", voice, value); break; } case 0x2: //VOLR (Volume R) @@ -581,7 +581,7 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) thisvol.Mode = 0; thisvol.Increment = 0; } - //ConLog("voice %x VOLR write: %x\n", voice, value); + ConLog("voice %x VOLR write: %x\n", voice, value); break; } case 0x4: @@ -607,7 +607,7 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) case 0xc: // Voice 0..23 ADSR Current Volume // not commonly set by games Voices[voice].ADSR.Value = (value << 16) | value; - //ConLog("voice %x ADSR.Value write: %x\n", voice, Voices[voice].ADSR.Value); + ConLog("voice %x ADSR.Value write: %x\n", voice, Voices[voice].ADSR.Value); break; case 0xe: Voices[voice].LoopStartA = value * 8; @@ -723,13 +723,13 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) case 0x1da4: IRQA = value * 8; psxIRQA = value; - ConLog("SPU2-X Setting IRQA to %x value was %x \n", IRQA, value); + ConLog("SPU2-X Setting IRQA to %x \n", IRQA); break; case 0x1da6: TSA = value * 8; psxTSA = value; - ConLog("SPU2-X Setting TSA to %x value was %x \n", TSA, value); + ConLog("SPU2-X Setting TSA to %x \n", TSA); break; case 0x1da8: // Spu Write to Memory @@ -740,6 +740,7 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) _irqcallback(); } DmaWritePSX(value); + //DmaWrite(value); show = false; break; @@ -1337,19 +1338,6 @@ static void __fastcall RegWrite_Core( u16 value ) Cores[1].ReverbX = 0; Cores[1].RevBuffers.NeedsUpdated = true; Cores[1].Mute = 1; // silence core1 in psxmode - //for (uint v = 0; v < 24; ++v) - //{ - // Cores[0].Voices[v].Volume = V_VolumeSlideLR(0, 0); // V_VolumeSlideLR::Max; - // Cores[0].Voices[v].SCurrent = 28; - - // Cores[0].Voices[v].ADSR.Value = 0; - // Cores[0].Voices[v].ADSR.Phase = 0; - // Cores[0].Voices[v].Pitch = 0x1000; - // Cores[0].Voices[v].NextA = 0x1001; - // Cores[0].Voices[v].StartA = 0x1000; - // Cores[0].Voices[v].LoopStartA = 0x1000; - // Cores[0].Voices[v].Modulated = 0; - //} for (uint v = 0; v < 24; ++v) { Cores[1].Voices[v].Volume = V_VolumeSlideLR(0, 0); // V_VolumeSlideLR::Max; From 1ec70f1df35ccdd12a43bea20dac85c243d21f3a Mon Sep 17 00:00:00 2001 From: Robert Neumann Date: Sun, 9 Oct 2016 00:11:50 +0200 Subject: [PATCH 3/8] psxmode: Spu2x now working correctly. Kudos to pseudonym. Took him 30 minutes to fix this! --- plugins/spu2-x/src/Mixer.cpp | 35 +++--- plugins/spu2-x/src/defs.h | 22 ---- plugins/spu2-x/src/spu2sys.cpp | 203 ++++++++++++++------------------- 3 files changed, 101 insertions(+), 159 deletions(-) diff --git a/plugins/spu2-x/src/Mixer.cpp b/plugins/spu2-x/src/Mixer.cpp index 414da0ba53..b4c96cfb38 100644 --- a/plugins/spu2-x/src/Mixer.cpp +++ b/plugins/spu2-x/src/Mixer.cpp @@ -128,8 +128,7 @@ static void __forceinline IncrementNextA(V_Core& thiscore, uint voiceidx) } vc.NextA++; - if (psxmode) vc.NextA &= 0x7FFFF; - else vc.NextA&=0xFFFFF; + vc.NextA&=0xFFFFF; } // decoded pcm data, used to cache the decoded data so that it needn't be decoded @@ -589,10 +588,8 @@ static __forceinline StereoOut32 MixVoice( uint coreidx, uint voiceidx ) // Write-back of raw voice data (post ADSR applied) - if (!psxmode) { // i'm not sure if this is correct for psxmode. it doesn't seem to hurt to have it off so i assume it is bad. - if (voiceidx == 1) spu2M_WriteFast(((0 == coreidx) ? 0x400 : 0xc00) + OutPos, vc.OutX); - else if (voiceidx == 3) spu2M_WriteFast(((0 == coreidx) ? 0x600 : 0xe00) + OutPos, vc.OutX); - } + if (voiceidx == 1) spu2M_WriteFast(((0 == coreidx) ? 0x400 : 0xc00) + OutPos, vc.OutX); + else if (voiceidx == 3) spu2M_WriteFast(((0 == coreidx) ? 0x600 : 0xe00) + OutPos, vc.OutX); return ApplyVolume( StereoOut32( Value, Value ), vc.Volume ); } else @@ -611,10 +608,8 @@ static __forceinline StereoOut32 MixVoice( uint coreidx, uint voiceidx ) } // Write-back of raw voice data (some zeros since the voice is "dead") - if (!psxmode) { // i'm not sure if this is correct for psxmode. it doesn't seem to hurt to have it off so i assume it is bad. - if (voiceidx == 1) spu2M_WriteFast(((0 == coreidx) ? 0x400 : 0xc00) + OutPos, 0); - else if (voiceidx == 3) spu2M_WriteFast(((0 == coreidx) ? 0x600 : 0xe00) + OutPos, 0); - } + if (voiceidx == 1) spu2M_WriteFast(((0 == coreidx) ? 0x400 : 0xc00) + OutPos, 0); + else if (voiceidx == 3) spu2M_WriteFast(((0 == coreidx) ? 0x600 : 0xe00) + OutPos, 0); return StereoOut32( 0, 0 ); } } @@ -645,13 +640,11 @@ StereoOut32 V_Core::Mix( const VoiceMixSet& inVoices, const StereoOut32& Input, // Saturate final result to standard 16 bit range. const VoiceMixSet Voices( clamp_mix( inVoices.Dry ), clamp_mix( inVoices.Wet ) ); - if (!psxmode) { - // Write Mixed results To Output Area - spu2M_WriteFast(((0 == Index) ? 0x1000 : 0x1800) + OutPos, Voices.Dry.Left); - spu2M_WriteFast(((0 == Index) ? 0x1200 : 0x1A00) + OutPos, Voices.Dry.Right); - spu2M_WriteFast(((0 == Index) ? 0x1400 : 0x1C00) + OutPos, Voices.Wet.Left); - spu2M_WriteFast(((0 == Index) ? 0x1600 : 0x1E00) + OutPos, Voices.Wet.Right); - } + // Write Mixed results To Output Area + spu2M_WriteFast(((0 == Index) ? 0x1000 : 0x1800) + OutPos, Voices.Dry.Left); + spu2M_WriteFast(((0 == Index) ? 0x1200 : 0x1A00) + OutPos, Voices.Dry.Right); + spu2M_WriteFast(((0 == Index) ? 0x1400 : 0x1C00) + OutPos, Voices.Wet.Left); + spu2M_WriteFast(((0 == Index) ? 0x1600 : 0x1E00) + OutPos, Voices.Wet.Right); // Write mixed results to logfile (if enabled) @@ -838,11 +831,9 @@ void Mix() Ext = clamp_mix( ApplyVolume( Ext, Cores[0].MasterVol ) ); } - if (!psxmode) { - // Commit Core 0 output to ram before mixing Core 1: - spu2M_WriteFast(0x800 + OutPos, Ext.Left); - spu2M_WriteFast(0xA00 + OutPos, Ext.Right); - } + // Commit Core 0 output to ram before mixing Core 1: + spu2M_WriteFast(0x800 + OutPos, Ext.Left); + spu2M_WriteFast(0xA00 + OutPos, Ext.Right); WaveDump::WriteCore( 0, CoreSrc_External, Ext ); diff --git a/plugins/spu2-x/src/defs.h b/plugins/spu2-x/src/defs.h index be28eec75d..2056686151 100644 --- a/plugins/spu2-x/src/defs.h +++ b/plugins/spu2-x/src/defs.h @@ -28,7 +28,6 @@ extern s16* GetMemPtr(u32 addr); extern s16 spu2M_Read( u32 addr ); -extern s16 spu2M_ReadPSX(u32 addr); extern void spu2M_Write( u32 addr, s16 value ); extern void spu2M_Write( u32 addr, u16 value ); @@ -155,10 +154,6 @@ struct V_Voice s32 Prev1; s32 Prev2; - // psx caches - u16 psxPitch; - u16 psxLoopStartA; - u16 psxStartA; // Pitch Modulated by previous voice bool Modulated; // Source (Wave/Noise) @@ -447,12 +442,8 @@ struct V_Core u32 KeyOn; // not the KON register (though maybe it is) // psxmode caches - u16 psxIRQA; - u16 psxTSA; - u16 psxSPUCNT; u16 psxSoundDataTransferControl; u16 psxSPUSTAT; - u16 psxReverbStartA; StereoOut32 downbuf[8]; @@ -519,25 +510,12 @@ struct V_Core return ret; } - __forceinline u16 DmaReadPSX() - { - const u16 ret = (u16)spu2M_ReadPSX(TSA); - ++TSA; TSA &= 0x7ffff; - return ret; - } - __forceinline void DmaWrite(u16 value) { spu2M_Write( TSA, value ); ++TSA; TSA &= 0xfffff; } - __forceinline void DmaWritePSX(u16 value) - { - spu2M_Write(TSA, value); - ++TSA; TSA &= 0x7ffff; - } - void LogAutoDMA( FILE* fp ); s32 NewDmaRead(u32* data, u32 bytesLeft, u32* bytesProcessed); diff --git a/plugins/spu2-x/src/spu2sys.cpp b/plugins/spu2-x/src/spu2sys.cpp index 8a410cd10c..9bf76ce866 100644 --- a/plugins/spu2-x/src/spu2sys.cpp +++ b/plugins/spu2-x/src/spu2sys.cpp @@ -44,6 +44,7 @@ bool has_to_call_irq=false; bool psxmode = false; +#define PSXUNLIKELYHACKS 1 void SetIrqCall(int core) { // reset by an irq disable/enable cycle, behaviour found by @@ -69,11 +70,6 @@ __forceinline s16 spu2M_Read( u32 addr ) return *GetMemPtr( addr & 0xfffff ); } -__forceinline s16 spu2M_ReadPSX(u32 addr) -{ - return *GetMemPtr(addr & 0x7ffff); -} - // writes a signed value to the SPU2 ram // Invalidates the ADPCM cache in the process. __forceinline void spu2M_Write( u32 addr, s16 value ) @@ -409,7 +405,7 @@ __forceinline void TimeUpdate(u32 cClocks) Cores[0].DMAICounter-=TickInterval; if(Cores[0].DMAICounter<=0) { - ConLog("counter set and callback!\n"); + //ConLog("counter set and callback!\n"); Cores[0].MADR=Cores[0].TADR; Cores[0].DMAICounter=0; if(dma4callback) dma4callback(); @@ -519,6 +515,17 @@ static __forceinline u16 GetLoWord(u32& src) return ((u16*)&src)[0]; } +static u32 map_spu1to2(u32 addr) +{ + return addr * 4 + (addr >= 0x100 ? 0xc0000 : 0); +} + +static u32 map_spu2to1(u32 addr) +{ + // if (addr >= 0x800 && addr < 0x80000) oh dear + return (addr - (addr >= 0xc0000 ? 0xc0000 : 0)) / 4; +} + void V_Core::WriteRegPS1( u32 mem, u16 value ) { pxAssume( Index == 0 ); // Valid on Core 0 only! @@ -535,33 +542,9 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) switch(vval) { case 0x0: //VOLL (Volume L) - { - V_VolumeSlide& thisvol = Voices[voice].Volume.Left; - thisvol.Reg_VOL = value; - - if (value & 0x8000) // +Lin/-Lin/+Exp/-Exp - { - thisvol.Mode = (value & 0xF000) >> 12; - thisvol.Increment = (value & 0x7F); - // We're not sure slides work 100% - if (IsDevBuild) ConLog("* SPU2: Voice uses Slides in Mode = %x, Increment = %x\n", thisvol.Mode, thisvol.Increment); - } - else - { - // Constant Volume mode (no slides or envelopes) - // Volumes range from 0x3fff to 0x7fff, with 0x4000 serving as - // the "sign" bit, so a simple bitwise extension will do the trick: - - thisvol.RegSet(value << 1); - thisvol.Mode = 0; - thisvol.Increment = 0; - } - ConLog("voice %x VOLL write: %x\n", voice, value); - break; - } case 0x2: //VOLR (Volume R) { - V_VolumeSlide& thisvol = Voices[voice].Volume.Right; + V_VolumeSlide& thisvol = vval == 0 ? Voices[voice].Volume.Left : Voices[voice].Volume.Right; thisvol.Reg_VOL = value; if (value & 0x8000) // +Lin/-Lin/+Exp/-Exp @@ -581,7 +564,7 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) thisvol.Mode = 0; thisvol.Increment = 0; } - ConLog("voice %x VOLR write: %x\n", voice, value); + //ConLog("voice %x VOL%c write: %x\n", voice, vval == 0 ? 'L' : 'R', value); break; } case 0x4: @@ -590,8 +573,7 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) //ConLog("voice %x Pitch write: %x\n", voice, Voices[voice].Pitch); break; case 0x6: - Voices[voice].StartA = value * 8; - Voices[voice].psxStartA = value; + Voices[voice].StartA = map_spu1to2(value); //ConLog("voice %x StartA write: %x\n", voice, Voices[voice].StartA); break; @@ -606,12 +588,11 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) break; case 0xc: // Voice 0..23 ADSR Current Volume // not commonly set by games - Voices[voice].ADSR.Value = (value << 16) | value; + Voices[voice].ADSR.Value = value * 0x10001U; ConLog("voice %x ADSR.Value write: %x\n", voice, Voices[voice].ADSR.Value); break; case 0xe: - Voices[voice].LoopStartA = value * 8; - Voices[voice].psxLoopStartA = value; + Voices[voice].LoopStartA = map_spu1to2(value); //ConLog("voice %x LoopStartA write: %x\n", voice, Voices[voice].LoopStartA); break; @@ -713,89 +694,87 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) case 0x1da2:// Reverb work area start { - EffectsStartA = value * 8; - EffectsEndA = 0x7FFFF; // fixed EndA in psx mode - psxReverbStartA = value; + EffectsStartA = map_spu1to2(value); + EffectsEndA = 0xFFFFF; // fixed EndA in psx mode Cores[0].RevBuffers.NeedsUpdated = true; } break; case 0x1da4: - IRQA = value * 8; - psxIRQA = value; - ConLog("SPU2-X Setting IRQA to %x \n", IRQA); + IRQA = map_spu1to2(value); + //ConLog("SPU2-X Setting IRQA to %x \n", IRQA); break; case 0x1da6: - TSA = value * 8; - psxTSA = value; - ConLog("SPU2-X Setting TSA to %x \n", TSA); + TSA = map_spu1to2(value); + //ConLog("SPU2-X Setting TSA to %x \n", TSA); break; case 0x1da8: // Spu Write to Memory - ConLog("SPU direct DMA Write. Current TSA = %x\n", TSA); + //ConLog("SPU direct DMA Write. Current TSA = %x\n", TSA); if (Cores[0].IRQEnable && (Cores[0].IRQA <= Cores[0].TSA)) { SetIrqCall(0); _irqcallback(); } - DmaWritePSX(value); - //DmaWrite(value); + DmaWrite(value); show = false; break; case 0x1daa: { - psxSPUCNT = value; - ConLog("SPU Control register write with %x\n", value); - bool irqe = Cores[0].IRQEnable; - int bit0 = Cores[0].AttrBit0; - bool fxenable = Cores[0].FxEnable; - u8 oldDmaMode = Cores[0].DmaMode; + V_Core& thiscore = Cores[0]; + bool irqe = thiscore.IRQEnable; + int bit0 = thiscore.AttrBit0; + bool fxenable = thiscore.FxEnable; + u8 oldDmaMode = thiscore.DmaMode; - Cores[0].AttrBit0 = (value >> 0) & 0x01; //1 bit - Cores[0].DMABits = (value >> 1) & 0x07; //3 bits - Cores[0].DmaMode = (value >> 4) & 0x03; //2 bit (not necessary, we get the direction from the iop) - Cores[0].IRQEnable = (value >> 6) & 0x01; //1 bit - Cores[0].FxEnable = (value >> 7) & 0x01; //1 bit - Cores[0].NoiseClk = (value >> 8) & 0x3f; //6 bits + thiscore.AttrBit0 = (value >> 0) & 0x01; //1 bit + thiscore.DMABits = (value >> 1) & 0x07; //3 bits + thiscore.DmaMode = (value >> 4) & 0x03; //2 bit (not necessary, we get the direction from the iop) + thiscore.IRQEnable = (value >> 6) & 0x01; //1 bit + thiscore.FxEnable = (value >> 7) & 0x01; //1 bit + thiscore.NoiseClk = (value >> 8) & 0x3f; //6 bits //thiscore.Mute =(value>>14) & 0x01; //1 bit - Cores[0].Mute = 0; + thiscore.Mute = 0; //thiscore.CoreEnabled=(value>>15) & 0x01; //1 bit // no clue if (value >> 15) - Cores[0].Regs.STATX = 0; - Cores[0].Regs.ATTR = value & 0x7fff; + thiscore.Regs.STATX = 0; + thiscore.Regs.ATTR = value & 0x7fff; - if (fxenable && !Cores[0].FxEnable) + if (fxenable && !thiscore.FxEnable + && (thiscore.EffectsStartA != thiscore.ExtEffectsStartA + || thiscore.EffectsEndA != thiscore.ExtEffectsEndA)) { - Cores[0].ReverbX = 0; - Cores[0].RevBuffers.NeedsUpdated = true; + thiscore.EffectsStartA = thiscore.ExtEffectsStartA; + thiscore.EffectsEndA = thiscore.ExtEffectsEndA; + thiscore.ReverbX = 0; + thiscore.RevBuffers.NeedsUpdated = true; } - if (oldDmaMode != Cores[0].DmaMode) + if (oldDmaMode != thiscore.DmaMode) { // FIXME... maybe: if this mode was cleared in the middle of a DMA, should we interrupt it? - ConLog("* SPU2-X: DMA mode changed. oldDmaMode = %x , newDmaMode = %x \n", oldDmaMode,Cores[0].DmaMode); - Cores[0].Regs.STATX &= ~0x400; // ready to transfer + thiscore.Regs.STATX &= ~0x400; // ready to transfer } if (value & 0x000E) { - if (MsgToConsole()) ConLog("* SPU2-X: Core 0 ATTR unknown bits SET! value=%x\n", value); + if (MsgToConsole()) ConLog("* SPU2-X: Core 0 ATTR unknown bits SET! value=%04x\n", value); } - if (Cores[0].AttrBit0 != bit0) + if (thiscore.AttrBit0 != bit0) { - if (MsgToConsole()) ConLog("* SPU2-X: ATTR bit 0 set to %d\n", Cores[0].AttrBit0); + if (MsgToConsole()) ConLog("* SPU2-X: ATTR bit 0 set to %d\n", thiscore.AttrBit0); } - if (Cores[0].IRQEnable != irqe) + if (thiscore.IRQEnable != irqe) { - ConLog("* SPU2-X: write reg psx Core%d IRQ %s at cycle %d. Current IRQA = %x Current TSA = %x\n", - 0, ((Cores[0].IRQEnable==0)?"disabled":"enabled"), Cycles, Cores[0].IRQA, Cores[0].TSA); + //ConLog("* SPU2-X: Core%d IRQ %s at cycle %d. Current IRQA = %x Current EffectA = %x\n", + // core, ((thiscore.IRQEnable==0)?"disabled":"enabled"), Cycles, thiscore.IRQA, thiscore.EffectsStartA); - if (!Cores[0].IRQEnable) - Spdif.Info &= ~(4 << Cores[0].Index); + if (!thiscore.IRQEnable) + Spdif.Info &= ~(4 << thiscore.Index); } } break; @@ -869,7 +848,7 @@ u16 V_Core::ReadRegPS1(u32 mem) //ConLog("voice %d read pitch result = %x\n", voice, value); break; case 0x6: - value = Voices[voice].psxStartA; + value = map_spu2to1(Voices[voice].StartA); //ConLog("voice %d read StartA result = %x\n", voice, value); break; case 0x8: @@ -883,7 +862,7 @@ u16 V_Core::ReadRegPS1(u32 mem) //if (value != 0) ConLog("voice %d read ADSR.Value result = %x\n", voice, value); break; case 0xe: - value = Voices[voice].psxLoopStartA; + value = map_spu2to1(Voices[voice].LoopStartA); //ConLog("voice %d read LoopStartA result = %x\n", voice, value); break; @@ -916,32 +895,30 @@ u16 V_Core::ReadRegPS1(u32 mem) case 0x1d9e: value = Regs.ENDX >> 16; case 0x1da2: - value = psxReverbStartA; + value = map_spu2to1(EffectsStartA); break; case 0x1da4: - value = psxIRQA; - ConLog("SPU2-X IRQA read: 0x1da4 = %x , (IRQA = %x)\n", value, IRQA); + value = map_spu2to1(IRQA); + //ConLog("SPU2-X IRQA read: 0x1da4 = %x , (IRQA = %x)\n", value, IRQA); break; case 0x1da6: - value = psxTSA; - ConLog("SPU2-X TSA read: 0x1da6 = %x , (TSA = %x)\n", value, TSA); + value = map_spu2to1(TSA); + //ConLog("SPU2-X TSA read: 0x1da6 = %x , (TSA = %x)\n", value, TSA); break; case 0x1da8: value = DmaRead(); show=false; break; case 0x1daa: - //value = psxSPUCNT; value = Cores[0].Regs.ATTR; - ConLog("SPU2-X ps1 reg psxSPUCNT read return value: %x\n", value); + //ConLog("SPU2-X ps1 reg psxSPUCNT read return value: %x\n", value); break; case 0x1dac: // 1F801DACh - Sound RAM Data Transfer Control (should be 0004h) value = psxSoundDataTransferControl; break; case 0x1dae: - value = Regs.STATX; - //value = Cores[0].Regs.STATX; - ConLog("SPU2-X ps1 reg REG_P_STATX read return value: %x\n", value); + value = Cores[0].Regs.STATX; + //ConLog("SPU2-X ps1 reg REG_P_STATX read return value: %x\n", value); break; } @@ -1114,16 +1091,14 @@ static void __fastcall RegWrite_Core( u16 value ) thiscore.Regs.STATX = 0; thiscore.Regs.ATTR = value & 0x7fff; - if (!psxmode) { - if (fxenable && !thiscore.FxEnable - && (thiscore.EffectsStartA != thiscore.ExtEffectsStartA - || thiscore.EffectsEndA != thiscore.ExtEffectsEndA)) - { - thiscore.EffectsStartA = thiscore.ExtEffectsStartA; - thiscore.EffectsEndA = thiscore.ExtEffectsEndA; - thiscore.ReverbX = 0; - thiscore.RevBuffers.NeedsUpdated = true; - } + if (fxenable && !thiscore.FxEnable + && (thiscore.EffectsStartA != thiscore.ExtEffectsStartA + || thiscore.EffectsEndA != thiscore.ExtEffectsEndA)) + { + thiscore.EffectsStartA = thiscore.ExtEffectsStartA; + thiscore.EffectsEndA = thiscore.ExtEffectsEndA; + thiscore.ReverbX = 0; + thiscore.RevBuffers.NeedsUpdated = true; } if(oldDmaMode != thiscore.DmaMode) { @@ -1320,24 +1295,22 @@ static void __fastcall RegWrite_Core( u16 value ) case REG_S_ADMAS: if ( MsgToConsole() ) ConLog("* SPU2-X: Core %d AutoDMAControl set to %d (at cycle %d)\n",core,value, Cycles); + + if (psxmode) ConLog("* SPU2-X: Writing to REG_S_ADMAS while in PSX mode! value: %x",value); // hack for ps1driver which writes -1 (and never turns the adma off after psxlogo). // adma isn't available in psx mode either - if (value == 32767) { + if (value == 32767 && PSXUNLIKELYHACKS) { psxmode = true; - //memset(spu2regs, 0, 0x010000); - memset(_spu2mem, 0, 0x200000); - Cores[0].EffectsStartA = 0x7FFF8; - Cores[0].EffectsEndA = 0x7FFFF; - Cores[0].ReverbX = 0; - Cores[0].RevBuffers.NeedsUpdated = true; - Cores[1].EffectsStartA = 0xFFFF8; // park core1 effect area in high mem - Cores[1].EffectsEndA = 0xFFFFF; + //memset(_spu2mem, 0, 0x200000); Cores[1].FxEnable = 0; - Cores[1].ExtEffectsStartA = 0xFFFF8; // park core1 ext effect area in high mem - Cores[1].ExtEffectsStartA = 0xFFFFF; + Cores[1].EffectsStartA = 0x7FFF8; // park core1 effect area in inaccessible mem + Cores[1].EffectsEndA = 0x7FFFF; + Cores[1].ExtEffectsStartA = 0x7FFF8; // park core1 ext effect area in high mem + Cores[1].ExtEffectsStartA = 0x7FFFF; Cores[1].ReverbX = 0; Cores[1].RevBuffers.NeedsUpdated = true; - Cores[1].Mute = 1; // silence core1 in psxmode + Cores[0].ReverbX = 0; + Cores[0].RevBuffers.NeedsUpdated = true; for (uint v = 0; v < 24; ++v) { Cores[1].Voices[v].Volume = V_VolumeSlideLR(0, 0); // V_VolumeSlideLR::Max; @@ -1346,9 +1319,9 @@ static void __fastcall RegWrite_Core( u16 value ) Cores[1].Voices[v].ADSR.Value = 0; Cores[1].Voices[v].ADSR.Phase = 0; Cores[1].Voices[v].Pitch = 0x0; - Cores[1].Voices[v].NextA = 0xBFFFF; - Cores[1].Voices[v].StartA = 0xBFFFF; - Cores[1].Voices[v].LoopStartA = 0xBFFFF; + Cores[1].Voices[v].NextA = 0x6FFFF; + Cores[1].Voices[v].StartA = 0x6FFFF; + Cores[1].Voices[v].LoopStartA = 0x6FFFF; Cores[1].Voices[v].Modulated = 0; } return; From ee0513741551f99458902112e8829c58016e318a Mon Sep 17 00:00:00 2001 From: Robert Neumann Date: Sun, 9 Oct 2016 10:49:35 +0200 Subject: [PATCH 4/8] psxmode: Spu2x: add reverb register handling, fix a problem with the address translation, re-enable "VMIXEL" writing (which should just be named Echo/Effect ON or EON really) --- plugins/spu2-x/src/spu2sys.cpp | 48 +++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/plugins/spu2-x/src/spu2sys.cpp b/plugins/spu2-x/src/spu2sys.cpp index 9bf76ce866..a96429f925 100644 --- a/plugins/spu2-x/src/spu2sys.cpp +++ b/plugins/spu2-x/src/spu2sys.cpp @@ -262,7 +262,6 @@ void V_Core::UpdateFeedbackBuffersB() void V_Core::UpdateEffectsBufferSize() { const s32 newbufsize = EffectsEndA - EffectsStartA + 1; - //printf("Rvb Area change: ESA = %x, EEA = %x, Size(dec) = %d, Size(hex) = %x FxEnable = %d\n", EffectsStartA, EffectsEndA, newbufsize * 2, newbufsize * 2, FxEnable); if( (newbufsize*2) > 0x20000 ) // max 128kb per core { @@ -271,13 +270,16 @@ void V_Core::UpdateEffectsBufferSize() } if (newbufsize == EffectsBufferSize && EffectsStartA == EffectsBufferStart) return; + //printf("Rvb Area change: ESA = %x, EEA = %x, Size(dec) = %d, Size(hex) = %x FxEnable = %d\n", EffectsStartA, EffectsEndA, newbufsize * 2, newbufsize * 2, FxEnable); + RevBuffers.NeedsUpdated = false; EffectsBufferSize = newbufsize; EffectsBufferStart = EffectsStartA; if( EffectsBufferSize <= 0 ) return; - //AnalyzeReverbPreset(); + // debug: shows reverb parameters in console + if(MsgToConsole()) AnalyzeReverbPreset(); // Rebuild buffer indexers. RevBuffers.ACC_SRC_A0 = EffectsBufferIndexer( Revb.ACC_SRC_A0 ); @@ -517,12 +519,12 @@ static __forceinline u16 GetLoWord(u32& src) static u32 map_spu1to2(u32 addr) { - return addr * 4 + (addr >= 0x100 ? 0xc0000 : 0); + return addr * 4 + (addr >= 0x200 ? 0xc0000 : 0); } static u32 map_spu2to1(u32 addr) { - // if (addr >= 0x800 && addr < 0x80000) oh dear + // if (addr >= 0x800 && addr < 0xc0000) oh dear return (addr - (addr >= 0xc0000 ? 0xc0000 : 0)) / 4; } @@ -663,12 +665,12 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) break; case 0x1d98:// 1F801D98h - Voice 0..23 Reverb mode aka Echo On (EON) (R/W) - //Regs.VMIXEL = value & 0xFFFF; + Regs.VMIXEL = value & 0xFFFF; //ConLog("spu2x warning: setting reverb mode reg1 to %x \n", Regs.VMIXEL); break; case 0x1d9a:// 1F801D98h + 2 - Voice 0..23 Reverb mode aka Echo On (EON) (R/W) - //Regs.VMIXEL = value << 16; + Regs.VMIXEL = value << 16; //ConLog("spu2x warning: setting reverb mode reg2 to %x \n", Regs.VMIXEL); break; @@ -751,6 +753,7 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) thiscore.EffectsEndA = thiscore.ExtEffectsEndA; thiscore.ReverbX = 0; thiscore.RevBuffers.NeedsUpdated = true; + ConLog("fx toggle!\n"); } if (oldDmaMode != thiscore.DmaMode) @@ -807,6 +810,39 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) case 0x1DBE: break; + case 0x1DC0: Revb.FB_SRC_A = value; break; + case 0x1DC2: Revb.FB_SRC_B = value; break; + case 0x1DC4: Revb.IIR_ALPHA = value; break; + case 0x1DC6: Revb.ACC_COEF_A = value; break; + case 0x1DC8: Revb.ACC_COEF_B = value; break; + case 0x1DCA: Revb.ACC_COEF_C = value; break; + case 0x1DCC: Revb.ACC_COEF_D = value; break; + case 0x1DCE: Revb.IIR_COEF = value; break; + case 0x1DD0: Revb.FB_ALPHA = value; break; + case 0x1DD2: Revb.FB_X = value; break; + case 0x1DD4: Revb.IIR_DEST_A0 = value; break; + case 0x1DD6: Revb.IIR_DEST_A1 = value; break; + case 0x1DD8: Revb.ACC_SRC_A0 = value; break; + case 0x1DDA: Revb.ACC_SRC_A1 = value; break; + case 0x1DDC: Revb.ACC_SRC_B0 = value; break; + case 0x1DDE: Revb.ACC_SRC_B1 = value; break; + case 0x1DE0: Revb.IIR_SRC_A0 = value; break; + case 0x1DE2: Revb.IIR_SRC_A1 = value; break; + case 0x1DE4: Revb.IIR_DEST_B0 = value; break; + case 0x1DE6: Revb.IIR_DEST_B1 = value; break; + case 0x1DE8: Revb.ACC_SRC_C0 = value; break; + case 0x1DEA: Revb.ACC_SRC_C1 = value; break; + case 0x1DEC: Revb.ACC_SRC_D0 = value; break; + case 0x1DEE: Revb.ACC_SRC_D1 = value; break; + case 0x1DF0: Revb.IIR_SRC_B1 = value; break; + case 0x1DF2: Revb.IIR_SRC_B0 = value; break; + case 0x1DF4: Revb.MIX_DEST_A0 = value; break; + case 0x1DF6: Revb.MIX_DEST_A1 = value; break; + case 0x1DF8: Revb.MIX_DEST_B0 = value; break; + case 0x1DFA: Revb.MIX_DEST_B1 = value; break; + case 0x1DFC: Revb.IN_COEF_L = value; break; + case 0x1DFE: Revb.IN_COEF_R = value; break; + } if(show) FileLog("[%10d] (!) SPU write mem %08x value %04x\n",Cycles,mem,value); From 19a8ed8b25ce9cd93a80591aae6676488dca240a Mon Sep 17 00:00:00 2001 From: Robert Neumann Date: Sun, 9 Oct 2016 14:52:40 +0200 Subject: [PATCH 5/8] psxmode: Spu2x: more native SPU2 reghandlers. first "working" reverb! (everything before was just random data) --- plugins/spu2-x/src/spu2sys.cpp | 155 +++++++++++---------------------- 1 file changed, 50 insertions(+), 105 deletions(-) diff --git a/plugins/spu2-x/src/spu2sys.cpp b/plugins/spu2-x/src/spu2sys.cpp index a96429f925..248047256a 100644 --- a/plugins/spu2-x/src/spu2sys.cpp +++ b/plugins/spu2-x/src/spu2sys.cpp @@ -268,7 +268,9 @@ void V_Core::UpdateEffectsBufferSize() //printf("too big, returning\n"); //return; } - if (newbufsize == EffectsBufferSize && EffectsStartA == EffectsBufferStart) return; + + // bad optimization? + //if (newbufsize == EffectsBufferSize && EffectsStartA == EffectsBufferStart) return; //printf("Rvb Area change: ESA = %x, EEA = %x, Size(dec) = %d, Size(hex) = %x FxEnable = %d\n", EffectsStartA, EffectsEndA, newbufsize * 2, newbufsize * 2, FxEnable); @@ -623,54 +625,51 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) break; case 0x1d88:// Voice ON (0-15) - StartVoices(0, (u32)value); + SPU2_FastWrite(REG_S_KON, value); break; case 0x1d8a:// Voice ON (16-23) - StartVoices(0, ((u32)value) << 16); + SPU2_FastWrite(REG_S_KON + 2, value); break; case 0x1d8c:// Voice OFF (0-15) - StopVoices(0, (u32)value); + SPU2_FastWrite(REG_S_KOFF, value); break; case 0x1d8e:// Voice OFF (16-23) - StopVoices(0, ((u32)value) << 16); + SPU2_FastWrite(REG_S_KOFF + 2, value); break; case 0x1d90:// Channel FM (pitch lfo) mode (0-15) - Regs.PMON = value & 0xFFFF; - for (int vc = 1; vc<16; ++vc) - Voices[vc].Modulated = (value >> vc) & 1; - if (value != 0) ConLog("spu2x warning: wants to set Pitch Modulation reg1 to %x \n", value); + SPU2_FastWrite(REG_S_PMON, value); + if (value!=0)ConLog("spu2x warning: wants to set Pitch Modulation reg1 to %x \n", value); break; case 0x1d92:// Channel FM (pitch lfo) mode (16-23) - Regs.PMON = value << 16; - for (int vc = 0; vc<8; ++vc) - Voices[vc + 16].Modulated = (value >> vc) & 1; + SPU2_FastWrite(REG_S_PMON + 2, value); + if (value != 0)ConLog("spu2x warning: wants to set Pitch Modulation reg2 to %x \n", value); break; case 0x1d94:// Channel Noise mode (0-15) - SetLoWord(Regs.NON, value); - for (int vc = 0; vc<16; ++vc) - Voices[vc].Noise = (value >> vc) & 1; + SPU2_FastWrite(REG_S_NON, value); if (value != 0) ConLog("spu2x warning: wants to set Channel Noise mode reg1 to %x\n", value); break; case 0x1d96:// Channel Noise mode (16-23) - SetHiWord(Regs.NON, value); - for (int vc = 0; vc<8; ++vc) - Voices[vc + 16].Noise = (value >> vc) & 1; - //ConLog("spu2x warning: wants to set Channel Noise mode reg2 to %x (ignored)\n", value); + SPU2_FastWrite(REG_S_NON + 2, value); + if (value != 0) ConLog("spu2x warning: wants to set Channel Noise mode reg2 to %x\n", value); break; case 0x1d98:// 1F801D98h - Voice 0..23 Reverb mode aka Echo On (EON) (R/W) - Regs.VMIXEL = value & 0xFFFF; + //Regs.VMIXEL = value & 0xFFFF; + SPU2_FastWrite(REG_S_VMIXEL, value); + SPU2_FastWrite(REG_S_VMIXER, value); //ConLog("spu2x warning: setting reverb mode reg1 to %x \n", Regs.VMIXEL); break; case 0x1d9a:// 1F801D98h + 2 - Voice 0..23 Reverb mode aka Echo On (EON) (R/W) - Regs.VMIXEL = value << 16; + //Regs.VMIXEL = value << 16; + SPU2_FastWrite(REG_S_VMIXEL + 2, value); + SPU2_FastWrite(REG_S_VMIXER + 2, value); //ConLog("spu2x warning: setting reverb mode reg2 to %x \n", Regs.VMIXEL); break; @@ -685,20 +684,21 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) // SPU2_FastWrite(REG_S_VMIXR+2,value); //break; case 0x1d9c: // Voice 0..15 ON/OFF (status) (ENDX) (R) // writeable but hw overrides it shortly after - Regs.ENDX &= 0xff0000; + //Regs.ENDX &= 0xff0000; ConLog("spu2x warning: wants to set ENDX reg1 to %x \n", value); break; case 0x1d9e:// // Voice 15..23 ON/OFF (status) (ENDX) (R) // writeable but hw overrides it shortly after - Regs.ENDX &= 0xffff; + //Regs.ENDX &= 0xffff; ConLog("spu2x warning: wants to set ENDX reg2 to %x \n", value); break; case 0x1da2:// Reverb work area start { EffectsStartA = map_spu1to2(value); - EffectsEndA = 0xFFFFF; // fixed EndA in psx mode + //EffectsEndA = 0xFFFFF; // fixed EndA in psx mode Cores[0].RevBuffers.NeedsUpdated = true; + ReverbX = 0; } break; @@ -724,74 +724,19 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) break; case 0x1daa: - { - V_Core& thiscore = Cores[0]; - bool irqe = thiscore.IRQEnable; - int bit0 = thiscore.AttrBit0; - bool fxenable = thiscore.FxEnable; - u8 oldDmaMode = thiscore.DmaMode; - - thiscore.AttrBit0 = (value >> 0) & 0x01; //1 bit - thiscore.DMABits = (value >> 1) & 0x07; //3 bits - thiscore.DmaMode = (value >> 4) & 0x03; //2 bit (not necessary, we get the direction from the iop) - thiscore.IRQEnable = (value >> 6) & 0x01; //1 bit - thiscore.FxEnable = (value >> 7) & 0x01; //1 bit - thiscore.NoiseClk = (value >> 8) & 0x3f; //6 bits - //thiscore.Mute =(value>>14) & 0x01; //1 bit - thiscore.Mute = 0; - //thiscore.CoreEnabled=(value>>15) & 0x01; //1 bit - // no clue - if (value >> 15) - thiscore.Regs.STATX = 0; - thiscore.Regs.ATTR = value & 0x7fff; - - if (fxenable && !thiscore.FxEnable - && (thiscore.EffectsStartA != thiscore.ExtEffectsStartA - || thiscore.EffectsEndA != thiscore.ExtEffectsEndA)) - { - thiscore.EffectsStartA = thiscore.ExtEffectsStartA; - thiscore.EffectsEndA = thiscore.ExtEffectsEndA; - thiscore.ReverbX = 0; - thiscore.RevBuffers.NeedsUpdated = true; - ConLog("fx toggle!\n"); - } - - if (oldDmaMode != thiscore.DmaMode) - { - // FIXME... maybe: if this mode was cleared in the middle of a DMA, should we interrupt it? - thiscore.Regs.STATX &= ~0x400; // ready to transfer - } - - if (value & 0x000E) - { - if (MsgToConsole()) ConLog("* SPU2-X: Core 0 ATTR unknown bits SET! value=%04x\n", value); - } - - if (thiscore.AttrBit0 != bit0) - { - if (MsgToConsole()) ConLog("* SPU2-X: ATTR bit 0 set to %d\n", thiscore.AttrBit0); - } - if (thiscore.IRQEnable != irqe) - { - //ConLog("* SPU2-X: Core%d IRQ %s at cycle %d. Current IRQA = %x Current EffectA = %x\n", - // core, ((thiscore.IRQEnable==0)?"disabled":"enabled"), Cycles, thiscore.IRQA, thiscore.EffectsStartA); - - if (!thiscore.IRQEnable) - Spdif.Info &= ~(4 << thiscore.Index); - } - } + SPU2_FastWrite(REG_C_ATTR, value); break; case 0x1dac: // 1F801DACh - Sound RAM Data Transfer Control (should be 0004h) - ConLog("SPU Sound RAM Data Transfer Control (should be 0004h) : value = %x \n", value); + ConLog("SPU Sound RAM Data Transfer Control (should be 4) : value = %x \n", value); psxSoundDataTransferControl = value; - break; + break; case 0x1dae: // 1F801DAEh - SPU Status Register (SPUSTAT) (R) // The SPUSTAT register should be treated read-only (writing is possible in so far that the written // value can be read-back for a short moment, however, thereafter the hardware is overwriting that value). //Regs.STATX = value; - break; + break; case 0x1DB0: // 1F801DB0h 4 CD Volume Left/Right break; // cd left? @@ -810,8 +755,8 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) case 0x1DBE: break; - case 0x1DC0: Revb.FB_SRC_A = value; break; - case 0x1DC2: Revb.FB_SRC_B = value; break; + case 0x1DC0: Revb.FB_SRC_A = value * 4; break; + case 0x1DC2: Revb.FB_SRC_B = value * 4; break; case 0x1DC4: Revb.IIR_ALPHA = value; break; case 0x1DC6: Revb.ACC_COEF_A = value; break; case 0x1DC8: Revb.ACC_COEF_B = value; break; @@ -820,26 +765,26 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) case 0x1DCE: Revb.IIR_COEF = value; break; case 0x1DD0: Revb.FB_ALPHA = value; break; case 0x1DD2: Revb.FB_X = value; break; - case 0x1DD4: Revb.IIR_DEST_A0 = value; break; - case 0x1DD6: Revb.IIR_DEST_A1 = value; break; - case 0x1DD8: Revb.ACC_SRC_A0 = value; break; - case 0x1DDA: Revb.ACC_SRC_A1 = value; break; - case 0x1DDC: Revb.ACC_SRC_B0 = value; break; - case 0x1DDE: Revb.ACC_SRC_B1 = value; break; - case 0x1DE0: Revb.IIR_SRC_A0 = value; break; - case 0x1DE2: Revb.IIR_SRC_A1 = value; break; - case 0x1DE4: Revb.IIR_DEST_B0 = value; break; - case 0x1DE6: Revb.IIR_DEST_B1 = value; break; - case 0x1DE8: Revb.ACC_SRC_C0 = value; break; - case 0x1DEA: Revb.ACC_SRC_C1 = value; break; - case 0x1DEC: Revb.ACC_SRC_D0 = value; break; - case 0x1DEE: Revb.ACC_SRC_D1 = value; break; - case 0x1DF0: Revb.IIR_SRC_B1 = value; break; - case 0x1DF2: Revb.IIR_SRC_B0 = value; break; - case 0x1DF4: Revb.MIX_DEST_A0 = value; break; - case 0x1DF6: Revb.MIX_DEST_A1 = value; break; - case 0x1DF8: Revb.MIX_DEST_B0 = value; break; - case 0x1DFA: Revb.MIX_DEST_B1 = value; break; + case 0x1DD4: Revb.IIR_DEST_A0 = value * 4; break; + case 0x1DD6: Revb.IIR_DEST_A1 = value * 4; break; + case 0x1DD8: Revb.ACC_SRC_A0 = value * 4; break; + case 0x1DDA: Revb.ACC_SRC_A1 = value * 4; break; + case 0x1DDC: Revb.ACC_SRC_B0 = value * 4; break; + case 0x1DDE: Revb.ACC_SRC_B1 = value * 4; break; + case 0x1DE0: Revb.IIR_SRC_A0 = value * 4; break; + case 0x1DE2: Revb.IIR_SRC_A1 = value * 4; break; + case 0x1DE4: Revb.IIR_DEST_B0 = value * 4; break; + case 0x1DE6: Revb.IIR_DEST_B1 = value * 4; break; + case 0x1DE8: Revb.ACC_SRC_C0 = value * 4; break; + case 0x1DEA: Revb.ACC_SRC_C1 = value * 4; break; + case 0x1DEC: Revb.ACC_SRC_D0 = value * 4; break; + case 0x1DEE: Revb.ACC_SRC_D1 = value * 4; break; + case 0x1DF0: Revb.IIR_SRC_B0 = value * 4; break; // IIR_SRC_B0 and IIR_SRC_B1 supposedly swapped on SPU2 + case 0x1DF2: Revb.IIR_SRC_B1 = value * 4; break; // but I don't believe it! (games in psxmode sound better unswapped) + case 0x1DF4: Revb.MIX_DEST_A0 = value * 4; break; + case 0x1DF6: Revb.MIX_DEST_A1 = value * 4; break; + case 0x1DF8: Revb.MIX_DEST_B0 = value * 4; break; + case 0x1DFA: Revb.MIX_DEST_B1 = value * 4; break; case 0x1DFC: Revb.IN_COEF_L = value; break; case 0x1DFE: Revb.IN_COEF_R = value; break; From 95fe77a5949206ad42da63b7532e56150a4121ae Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 9 Oct 2016 16:15:19 +0200 Subject: [PATCH 6/8] bad merge fix --- pcsx2/Sio.h | 2 +- plugins/spu2-x/src/spu2sys.cpp | 53 +++++++++++++++++----------------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/pcsx2/Sio.h b/pcsx2/Sio.h index 00ffbd38b5..2f31026eca 100644 --- a/pcsx2/Sio.h +++ b/pcsx2/Sio.h @@ -17,7 +17,7 @@ // Let's enable this to free the IOP event handler of some considerable load. // Games are highly unlikely to need timed IRQ's for PAD and MemoryCard handling anyway (rama). -//#define SIO_INLINE_IRQS +#define SIO_INLINE_IRQS #include "MemoryCardFile.h" diff --git a/plugins/spu2-x/src/spu2sys.cpp b/plugins/spu2-x/src/spu2sys.cpp index 248047256a..243bf38995 100644 --- a/plugins/spu2-x/src/spu2sys.cpp +++ b/plugins/spu2-x/src/spu2sys.cpp @@ -498,27 +498,6 @@ void V_VolumeSlide::RegSet( u16 src ) Value = GetVol32( src ); } -// Ah the joys of endian-specific code! :D -static __forceinline void SetHiWord(u32& src, u16 value) -{ - ((u16*)&src)[1] = value; -} - -static __forceinline void SetLoWord(u32& src, u16 value) -{ - ((u16*)&src)[0] = value; -} - -static __forceinline u16 GetHiWord(u32& src) -{ - return ((u16*)&src)[1]; -} - -static __forceinline u16 GetLoWord(u32& src) -{ - return ((u16*)&src)[0]; -} - static u32 map_spu1to2(u32 addr) { return addr * 4 + (addr >= 0x200 ? 0xc0000 : 0); @@ -797,7 +776,6 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) u16 V_Core::ReadRegPS1(u32 mem) { - //ConLog("ReadRegPS1 from %x on core %d\n", mem, Index); pxAssume( Index == 0 ); // Valid on Core 0 only! bool show=true; @@ -907,6 +885,27 @@ u16 V_Core::ReadRegPS1(u32 mem) return value; } +// Ah the joys of endian-specific code! :D +static __forceinline void SetHiWord(u32& src, u16 value) +{ + ((u16*)&src)[1] = value; +} + +static __forceinline void SetLoWord(u32& src, u16 value) +{ + ((u16*)&src)[0] = value; +} + +static __forceinline u16 GetHiWord(u32& src) +{ + return ((u16*)&src)[1]; +} + +static __forceinline u16 GetLoWord(u32& src) +{ + return ((u16*)&src)[0]; +} + template< int CoreIdx, int VoiceIdx, int param > static void __fastcall RegWrite_VoiceParams( u16 value ) { @@ -1025,7 +1024,7 @@ static void __fastcall RegWrite_Core( u16 value ) const int omem = cAddr; const int core = CoreIdx; V_Core& thiscore = Cores[core]; - //ConLog("RegWrite_Core #%d addr: %x value %x \n", core, omem, value); + switch(omem) { case REG__1AC: @@ -1143,8 +1142,8 @@ static void __fastcall RegWrite_Core( u16 value ) SetLoWord( thiscore.Regs.reg_out, value ); \ if( result == thiscore.Regs.reg_out ) break; \ \ - const uint start_bit = hiword ? 16 : 0; \ - const uint end_bit = hiword ? 24 : 16; \ + const uint start_bit = (hiword) ? 16 : 0; \ + const uint end_bit = (hiword) ? 24 : 16; \ for (uint vc=start_bit, vx=1; vc, RegWrite_Core + RegWrite_Core, RegWrite_Core #define ReverbPair( core, mem ) \ - RegWrite_Reverb, RegWrite_Core + RegWrite_Reverb, RegWrite_Core #define REGRAW(addr) RegWrite_Raw From 3bc847a9f08ec02890412448df4f2612695edcbc Mon Sep 17 00:00:00 2001 From: Robert Neumann Date: Sun, 9 Oct 2016 16:21:48 +0200 Subject: [PATCH 7/8] bad merge fix 2 --- pcsx2/Sio.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pcsx2/Sio.h b/pcsx2/Sio.h index 2f31026eca..6153f9bc55 100644 --- a/pcsx2/Sio.h +++ b/pcsx2/Sio.h @@ -30,8 +30,8 @@ struct _mcd u32 transferAddr; // Transfer address u8 FLAG; // for PSX; - - u8 port; // port + + u8 port; // port u8 slot; // and slot for this memcard // Auto Eject @@ -55,13 +55,13 @@ struct _mcd } // Read from memorycard to dest - void Read(u8 *dest, int size) + void Read(u8 *dest, int size) { SysPlugins.McdRead(port, slot, dest, transferAddr, size); } // Write to memorycard from src - void Write(u8 *src, int size) + void Write(u8 *src, int size) { SysPlugins.McdSave(port, slot, src,transferAddr, size); } From 36631f2270c979850a27024b2e0b80c53e5874f2 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 9 Oct 2016 19:02:13 +0200 Subject: [PATCH 8/8] remove a useless define cosmetics more cosmetics some more cosmetics? sure! whitespaces whiterspaces --- plugins/spu2-x/src/Mixer.cpp | 18 +++---- plugins/spu2-x/src/defs.h | 1 - plugins/spu2-x/src/spu2sys.cpp | 88 +++++++++++++++++----------------- 3 files changed, 53 insertions(+), 54 deletions(-) diff --git a/plugins/spu2-x/src/Mixer.cpp b/plugins/spu2-x/src/Mixer.cpp index b4c96cfb38..84affe3197 100644 --- a/plugins/spu2-x/src/Mixer.cpp +++ b/plugins/spu2-x/src/Mixer.cpp @@ -588,8 +588,9 @@ static __forceinline StereoOut32 MixVoice( uint coreidx, uint voiceidx ) // Write-back of raw voice data (post ADSR applied) - if (voiceidx == 1) spu2M_WriteFast(((0 == coreidx) ? 0x400 : 0xc00) + OutPos, vc.OutX); - else if (voiceidx == 3) spu2M_WriteFast(((0 == coreidx) ? 0x600 : 0xe00) + OutPos, vc.OutX); + if (voiceidx==1) spu2M_WriteFast( ( (0==coreidx) ? 0x400 : 0xc00 ) + OutPos, vc.OutX ); + else if (voiceidx==3) spu2M_WriteFast( ( (0==coreidx) ? 0x600 : 0xe00 ) + OutPos, vc.OutX ); + return ApplyVolume( StereoOut32( Value, Value ), vc.Volume ); } else @@ -608,8 +609,9 @@ static __forceinline StereoOut32 MixVoice( uint coreidx, uint voiceidx ) } // Write-back of raw voice data (some zeros since the voice is "dead") - if (voiceidx == 1) spu2M_WriteFast(((0 == coreidx) ? 0x400 : 0xc00) + OutPos, 0); - else if (voiceidx == 3) spu2M_WriteFast(((0 == coreidx) ? 0x600 : 0xe00) + OutPos, 0); + if (voiceidx==1) spu2M_WriteFast( ( (0==coreidx) ? 0x400 : 0xc00 ) + OutPos, 0 ); + else if (voiceidx==3) spu2M_WriteFast( ( (0==coreidx) ? 0x600 : 0xe00 ) + OutPos, 0 ); + return StereoOut32( 0, 0 ); } } @@ -641,10 +643,10 @@ StereoOut32 V_Core::Mix( const VoiceMixSet& inVoices, const StereoOut32& Input, const VoiceMixSet Voices( clamp_mix( inVoices.Dry ), clamp_mix( inVoices.Wet ) ); // Write Mixed results To Output Area - spu2M_WriteFast(((0 == Index) ? 0x1000 : 0x1800) + OutPos, Voices.Dry.Left); - spu2M_WriteFast(((0 == Index) ? 0x1200 : 0x1A00) + OutPos, Voices.Dry.Right); - spu2M_WriteFast(((0 == Index) ? 0x1400 : 0x1C00) + OutPos, Voices.Wet.Left); - spu2M_WriteFast(((0 == Index) ? 0x1600 : 0x1E00) + OutPos, Voices.Wet.Right); + spu2M_WriteFast( ( (0==Index) ? 0x1000 : 0x1800 ) + OutPos, Voices.Dry.Left ); + spu2M_WriteFast( ( (0==Index) ? 0x1200 : 0x1A00 ) + OutPos, Voices.Dry.Right ); + spu2M_WriteFast( ( (0==Index) ? 0x1400 : 0x1C00 ) + OutPos, Voices.Wet.Left ); + spu2M_WriteFast( ( (0==Index) ? 0x1600 : 0x1E00 ) + OutPos, Voices.Wet.Right ); // Write mixed results to logfile (if enabled) diff --git a/plugins/spu2-x/src/defs.h b/plugins/spu2-x/src/defs.h index 2056686151..96996b2840 100644 --- a/plugins/spu2-x/src/defs.h +++ b/plugins/spu2-x/src/defs.h @@ -445,7 +445,6 @@ struct V_Core u16 psxSoundDataTransferControl; u16 psxSPUSTAT; - StereoOut32 downbuf[8]; StereoOut32 upbuf[8]; int dbpos, ubpos; diff --git a/plugins/spu2-x/src/spu2sys.cpp b/plugins/spu2-x/src/spu2sys.cpp index 243bf38995..895ed4372b 100644 --- a/plugins/spu2-x/src/spu2sys.cpp +++ b/plugins/spu2-x/src/spu2sys.cpp @@ -44,7 +44,6 @@ bool has_to_call_irq=false; bool psxmode = false; -#define PSXUNLIKELYHACKS 1 void SetIrqCall(int core) { // reset by an irq disable/enable cycle, behaviour found by @@ -195,32 +194,32 @@ void V_Core::AnalyzeReverbPreset() { ConLog("Reverb Parameter Update for Core %d:\n", Index); ConLog("----------------------------------------------------------\n"); - + ConLog(" IN_COEF_L, IN_COEF_R 0x%08x, 0x%08x\n", Revb.IN_COEF_L, Revb.IN_COEF_R); ConLog(" FB_SRC_A, FB_SRC_B 0x%08x, 0x%08x\n", Revb.FB_SRC_A, Revb.FB_SRC_B); ConLog(" FB_ALPHA, FB_X 0x%08x, 0x%08x\n", Revb.FB_ALPHA, Revb.FB_X); - + ConLog(" ACC_COEF_A 0x%08x\n", Revb.ACC_COEF_A); ConLog(" ACC_COEF_B 0x%08x\n", Revb.ACC_COEF_B); ConLog(" ACC_COEF_C 0x%08x\n", Revb.ACC_COEF_C); ConLog(" ACC_COEF_D 0x%08x\n", Revb.ACC_COEF_D); - + ConLog(" ACC_SRC_A0, ACC_SRC_A1 0x%08x, 0x%08x\n", Revb.ACC_SRC_A0, Revb.ACC_SRC_A1); ConLog(" ACC_SRC_B0, ACC_SRC_B1 0x%08x, 0x%08x\n", Revb.ACC_SRC_B0, Revb.ACC_SRC_B1); ConLog(" ACC_SRC_C0, ACC_SRC_C1 0x%08x, 0x%08x\n", Revb.ACC_SRC_C0, Revb.ACC_SRC_C1); ConLog(" ACC_SRC_D0, ACC_SRC_D1 0x%08x, 0x%08x\n", Revb.ACC_SRC_D0, Revb.ACC_SRC_D1); - + ConLog(" IIR_SRC_A0, IIR_SRC_A1 0x%08x, 0x%08x\n", Revb.IIR_SRC_A0, Revb.IIR_SRC_A1); ConLog(" IIR_SRC_B0, IIR_SRC_B1 0x%08x, 0x%08x\n", Revb.IIR_SRC_B0, Revb.IIR_SRC_B1); ConLog(" IIR_DEST_A0, IIR_DEST_A1 0x%08x, 0x%08x\n", Revb.IIR_DEST_A0, Revb.IIR_DEST_A1); - ConLog(" IIR_DEST_B0, IIR_DEST_B1 0x%08x, 0x%08x\n", Revb.IIR_DEST_B0, Revb.IIR_DEST_B1); + ConLog(" IIR_DEST_B0, IIR_DEST_B1 0x%08x, 0x%08x\n", Revb.IIR_DEST_B0, Revb.IIR_DEST_B1); ConLog(" IIR_ALPHA, IIR_COEF 0x%08x, 0x%08x\n", Revb.IIR_ALPHA, Revb.IIR_COEF); ConLog(" MIX_DEST_A0 0x%08x\n", Revb.MIX_DEST_A0); ConLog(" MIX_DEST_A1 0x%08x\n", Revb.MIX_DEST_A1); ConLog(" MIX_DEST_B0 0x%08x\n", Revb.MIX_DEST_B0); ConLog(" MIX_DEST_B1 0x%08x\n", Revb.MIX_DEST_B1); - + ConLog(" EffectsBufferSize 0x%x\n", EffectsBufferSize); ConLog("----------------------------------------------------------\n"); } @@ -230,7 +229,7 @@ s32 V_Core::EffectsBufferIndexer( s32 offset ) const // that it *4's all addresses before upping them to the SPU2 -- so our buffers are // already x4'd. It doesn't really make sense that we should x4 them again, and this // seems to work. (feedback-free in bios and DDS) --air - + u32 pos = EffectsStartA + offset; // Need to use modulus here, because games can and will drop the buffer size @@ -264,7 +263,7 @@ void V_Core::UpdateEffectsBufferSize() const s32 newbufsize = EffectsEndA - EffectsStartA + 1; if( (newbufsize*2) > 0x20000 ) // max 128kb per core - { + { //printf("too big, returning\n"); //return; } @@ -521,7 +520,6 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) //voice values u8 voice = ((reg-0x1c00)>>4); u8 vval = reg&0xf; - switch(vval) { case 0x0: //VOLL (Volume L) @@ -604,51 +602,51 @@ void V_Core::WriteRegPS1( u32 mem, u16 value ) break; case 0x1d88:// Voice ON (0-15) - SPU2_FastWrite(REG_S_KON, value); + SPU2_FastWrite(REG_S_KON,value); break; case 0x1d8a:// Voice ON (16-23) - SPU2_FastWrite(REG_S_KON + 2, value); + SPU2_FastWrite(REG_S_KON+2,value); break; case 0x1d8c:// Voice OFF (0-15) - SPU2_FastWrite(REG_S_KOFF, value); + SPU2_FastWrite(REG_S_KOFF,value); break; case 0x1d8e:// Voice OFF (16-23) - SPU2_FastWrite(REG_S_KOFF + 2, value); + SPU2_FastWrite(REG_S_KOFF+2,value); break; case 0x1d90:// Channel FM (pitch lfo) mode (0-15) - SPU2_FastWrite(REG_S_PMON, value); + SPU2_FastWrite(REG_S_PMON,value); if (value!=0)ConLog("spu2x warning: wants to set Pitch Modulation reg1 to %x \n", value); break; case 0x1d92:// Channel FM (pitch lfo) mode (16-23) - SPU2_FastWrite(REG_S_PMON + 2, value); + SPU2_FastWrite(REG_S_PMON+2,value); if (value != 0)ConLog("spu2x warning: wants to set Pitch Modulation reg2 to %x \n", value); break; case 0x1d94:// Channel Noise mode (0-15) - SPU2_FastWrite(REG_S_NON, value); + SPU2_FastWrite(REG_S_NON,value); if (value != 0) ConLog("spu2x warning: wants to set Channel Noise mode reg1 to %x\n", value); break; case 0x1d96:// Channel Noise mode (16-23) - SPU2_FastWrite(REG_S_NON + 2, value); + SPU2_FastWrite(REG_S_NON+2,value); if (value != 0) ConLog("spu2x warning: wants to set Channel Noise mode reg2 to %x\n", value); break; case 0x1d98:// 1F801D98h - Voice 0..23 Reverb mode aka Echo On (EON) (R/W) //Regs.VMIXEL = value & 0xFFFF; - SPU2_FastWrite(REG_S_VMIXEL, value); - SPU2_FastWrite(REG_S_VMIXER, value); + SPU2_FastWrite(REG_S_VMIXEL,value); + SPU2_FastWrite(REG_S_VMIXER,value); //ConLog("spu2x warning: setting reverb mode reg1 to %x \n", Regs.VMIXEL); break; case 0x1d9a:// 1F801D98h + 2 - Voice 0..23 Reverb mode aka Echo On (EON) (R/W) //Regs.VMIXEL = value << 16; - SPU2_FastWrite(REG_S_VMIXEL + 2, value); - SPU2_FastWrite(REG_S_VMIXER + 2, value); + SPU2_FastWrite(REG_S_VMIXEL+2,value); + SPU2_FastWrite(REG_S_VMIXER+2,value); //ConLog("spu2x warning: setting reverb mode reg2 to %x \n", Regs.VMIXEL); break; @@ -886,22 +884,22 @@ u16 V_Core::ReadRegPS1(u32 mem) } // Ah the joys of endian-specific code! :D -static __forceinline void SetHiWord(u32& src, u16 value) +static __forceinline void SetHiWord( u32& src, u16 value ) { ((u16*)&src)[1] = value; } -static __forceinline void SetLoWord(u32& src, u16 value) +static __forceinline void SetLoWord( u32& src, u16 value ) { ((u16*)&src)[0] = value; } -static __forceinline u16 GetHiWord(u32& src) +static __forceinline u16 GetHiWord( u32& src ) { return ((u16*)&src)[1]; } -static __forceinline u16 GetLoWord(u32& src) +static __forceinline u16 GetLoWord( u32& src ) { return ((u16*)&src)[0]; } @@ -1024,7 +1022,7 @@ static void __fastcall RegWrite_Core( u16 value ) const int omem = cAddr; const int core = CoreIdx; V_Core& thiscore = Cores[core]; - + switch(omem) { case REG__1AC: @@ -1052,34 +1050,35 @@ static void __fastcall RegWrite_Core( u16 value ) case REG_C_ATTR: { - bool irqe = thiscore.IRQEnable; - int bit0 = thiscore.AttrBit0; - bool fxenable = thiscore.FxEnable; - u8 oldDmaMode = thiscore.DmaMode; - - thiscore.AttrBit0 = (value >> 0) & 0x01; //1 bit - thiscore.DMABits = (value >> 1) & 0x07; //3 bits - thiscore.DmaMode = (value >> 4) & 0x03; //2 bit (not necessary, we get the direction from the iop) - thiscore.IRQEnable = (value >> 6) & 0x01; //1 bit - thiscore.FxEnable = (value >> 7) & 0x01; //1 bit - thiscore.NoiseClk = (value >> 8) & 0x3f; //6 bits + bool irqe = thiscore.IRQEnable; + int bit0 = thiscore.AttrBit0; + bool fxenable = thiscore.FxEnable; + u8 oldDmaMode = thiscore.DmaMode; + + thiscore.AttrBit0 =(value>> 0) & 0x01; //1 bit + thiscore.DMABits =(value>> 1) & 0x07; //3 bits + thiscore.DmaMode =(value>> 4) & 0x03; //2 bit (not necessary, we get the direction from the iop) + thiscore.IRQEnable =(value>> 6) & 0x01; //1 bit + thiscore.FxEnable =(value>> 7) & 0x01; //1 bit + thiscore.NoiseClk =(value>> 8) & 0x3f; //6 bits //thiscore.Mute =(value>>14) & 0x01; //1 bit - thiscore.Mute = 0; + thiscore.Mute =0; //thiscore.CoreEnabled=(value>>15) & 0x01; //1 bit // no clue - if (value >> 15) + if (value>>15) thiscore.Regs.STATX = 0; - thiscore.Regs.ATTR = value & 0x7fff; + thiscore.Regs.ATTR =value&0x7fff; if (fxenable && !thiscore.FxEnable && (thiscore.EffectsStartA != thiscore.ExtEffectsStartA - || thiscore.EffectsEndA != thiscore.ExtEffectsEndA)) + || thiscore.EffectsEndA != thiscore.ExtEffectsEndA)) { thiscore.EffectsStartA = thiscore.ExtEffectsStartA; thiscore.EffectsEndA = thiscore.ExtEffectsEndA; thiscore.ReverbX = 0; thiscore.RevBuffers.NeedsUpdated = true; } + if(oldDmaMode != thiscore.DmaMode) { // FIXME... maybe: if this mode was cleared in the middle of a DMA, should we interrupt it? @@ -1099,7 +1098,7 @@ static void __fastcall RegWrite_Core( u16 value ) { //ConLog("* SPU2-X: Core%d IRQ %s at cycle %d. Current IRQA = %x Current EffectA = %x\n", // core, ((thiscore.IRQEnable==0)?"disabled":"enabled"), Cycles, thiscore.IRQA, thiscore.EffectsStartA); - + if(!thiscore.IRQEnable) Spdif.Info &= ~(4 << thiscore.Index); } @@ -1224,7 +1223,6 @@ static void __fastcall RegWrite_Core( u16 value ) case REG_S_ENDX: thiscore.Regs.ENDX &= 0xff0000; - break; case (REG_S_ENDX + 2): @@ -1279,7 +1277,7 @@ static void __fastcall RegWrite_Core( u16 value ) if (psxmode) ConLog("* SPU2-X: Writing to REG_S_ADMAS while in PSX mode! value: %x",value); // hack for ps1driver which writes -1 (and never turns the adma off after psxlogo). // adma isn't available in psx mode either - if (value == 32767 && PSXUNLIKELYHACKS) { + if (value == 32767) { psxmode = true; //memset(_spu2mem, 0, 0x200000); Cores[1].FxEnable = 0;