mirror of https://github.com/PCSX2/pcsx2.git
SPU2-X: Fixed a huge bug in my last commit that broke most everything except the bios -- Core indexes were set to -1 instead of 0 and 1 (heh). Also a Speedup: Switched to a lookup table for dispatching SPU hardware register writes.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1933 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
3d789c5da3
commit
03972b07de
|
@ -177,8 +177,8 @@ void DoFullDump()
|
|||
" - Rm: %x\n"
|
||||
" - Phase: %x\n"
|
||||
" - Value: %x\n",
|
||||
Cores[c].Voices[v].ADSR.Reg_ADSR1,
|
||||
Cores[c].Voices[v].ADSR.Reg_ADSR2,
|
||||
Cores[c].Voices[v].ADSR.regADSR1,
|
||||
Cores[c].Voices[v].ADSR.regADSR2,
|
||||
Cores[c].Voices[v].ADSR.AttackRate,
|
||||
Cores[c].Voices[v].ADSR.AttackMode,
|
||||
Cores[c].Voices[v].ADSR.DecayRate,
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "PS2E-spu2.h"
|
||||
#include "dma.h"
|
||||
#include "Dialogs.h"
|
||||
#include "RegTable.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include "svnrev.h"
|
||||
|
@ -216,11 +215,7 @@ EXPORT_C_(void) CALLBACK SPU2interruptDMA7()
|
|||
|
||||
EXPORT_C_(s32) SPU2init()
|
||||
{
|
||||
#define MAKESURE(a,b) \
|
||||
/*fprintf(stderr,"%08p: %08p == %08p\n",&(regtable[a>>1]),regtable[a>>1],U16P(b));*/ \
|
||||
assert(regtable[(a)>>1]==U16P(b))
|
||||
|
||||
MAKESURE(0x800,zero);
|
||||
assert( regtable[0x400] == NULL );
|
||||
|
||||
s32 c=0,v=0;
|
||||
ReadSettings();
|
||||
|
@ -271,6 +266,8 @@ EXPORT_C_(s32) SPU2init()
|
|||
|
||||
memset(spu2regs, 0, 0x010000);
|
||||
memset(_spu2mem, 0, 0x200000);
|
||||
Cores[0].Index = 0;
|
||||
Cores[1].Index = 1;
|
||||
Cores[0].Reset();
|
||||
Cores[1].Reset();
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
|
||||
#include "Global.h"
|
||||
#include "RegTable.h"
|
||||
|
||||
const char *ParamNames[8]={"VOLL","VOLR","PITCH","ADSR1","ADSR2","ENVX","VOLXL","VOLXR"};
|
||||
const char *AddressNames[6]={"SSAH","SSAL","LSAH","LSAL","NAXH","NAXL"};
|
||||
|
@ -89,8 +88,8 @@ void SPU2writeLog( const char* action, u32 rmem, u16 value )
|
|||
case SPDIF_OUT:
|
||||
RegLog(2,"SPDIF_OUT",rmem,-1,value);
|
||||
break;
|
||||
case IRQINFO:
|
||||
RegLog(2,"IRQINFO",rmem,-1,value);
|
||||
case SPDIF_IRQINFO:
|
||||
RegLog(2,"SPDIF_IRQINFO",rmem,-1,value);
|
||||
break;
|
||||
case 0x7c4:
|
||||
if(Spdif.Unknown1 != value) ConLog(" * SPU2: SPDIF Unknown Register 1 set to %04x\n",value);
|
||||
|
|
|
@ -16,12 +16,6 @@
|
|||
*/
|
||||
|
||||
#include "Global.h"
|
||||
#include "RegTable.h"
|
||||
|
||||
// This var is used to confirm that our lookup table is "correct"
|
||||
// If the assertion in DllMain fails, it means the table has too too few entries.
|
||||
// (it can't have too many because that would generate a compiler error).
|
||||
const u16 zero = 0;
|
||||
|
||||
#define PCORE(c,p) \
|
||||
U16P(Cores[c].p)
|
||||
|
@ -33,8 +27,8 @@ const u16 zero = 0;
|
|||
PVCP(c,v,Volume.Left.Reg_VOL), \
|
||||
PVCP(c,v,Volume.Right.Reg_VOL), \
|
||||
PVCP(c,v,Pitch), \
|
||||
PVCP(c,v,ADSR.Reg_ADSR1), \
|
||||
PVCP(c,v,ADSR.Reg_ADSR2), \
|
||||
PVCP(c,v,ADSR.regADSR1), \
|
||||
PVCP(c,v,ADSR.regADSR2), \
|
||||
PVCP(c,v,ADSR.Value)+1, \
|
||||
PVCP(c,v,Volume.Left.Value)+1, \
|
||||
PVCP(c,v,Volume.Right.Value)+1
|
||||
|
@ -54,8 +48,7 @@ const u16 zero = 0;
|
|||
PCORE(c,Revb.n)+1, \
|
||||
PCORE(c,Revb.n)
|
||||
|
||||
#pragma pack(1)
|
||||
u16* regtable[0x800] =
|
||||
u16* regtable[0x401] =
|
||||
{
|
||||
// Voice Params: 8 params, 24 voices = 0x180 bytes
|
||||
PVC(0, 0),PVC(0, 1),PVC(0, 2),PVC(0, 3),PVC(0, 4),PVC(0, 5),
|
||||
|
@ -75,22 +68,20 @@ u16* regtable[0x800] =
|
|||
PCORE(0,Regs.VMIXR)+1,
|
||||
PCORE(0,Regs.VMIXER),
|
||||
PCORE(0,Regs.VMIXER)+1,
|
||||
PCORE(0,Regs.MMIX),
|
||||
|
||||
PCORE(0,Regs.MMIX),
|
||||
PCORE(0,Regs.ATTR),
|
||||
|
||||
PCORE(0,IRQA)+1,
|
||||
PCORE(0,IRQA),
|
||||
|
||||
U16P(zero),
|
||||
U16P(zero),
|
||||
U16P(zero),
|
||||
U16P(zero),
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
|
||||
PCORE(0,TSA)+1,
|
||||
PCORE(0,TSA),
|
||||
|
||||
PRAW(0x1ac), PRAW(0x1ae),
|
||||
PRAW(REG__1AC), PRAW(REG__1AE),
|
||||
|
||||
PCORE(0,AutoDMACtrl),
|
||||
|
||||
|
@ -129,7 +120,7 @@ u16* regtable[0x800] =
|
|||
PREVB_REG(0,MIX_DEST_B1),
|
||||
|
||||
PCORE(0,EffectsEndA)+1,
|
||||
U16P(zero),
|
||||
NULL,
|
||||
|
||||
PCORE(0,Regs.ENDX),
|
||||
PCORE(0,Regs.ENDX)+1,
|
||||
|
@ -187,10 +178,8 @@ u16* regtable[0x800] =
|
|||
PCORE(1,IRQA)+1,
|
||||
PCORE(1,IRQA),
|
||||
|
||||
U16P(zero),
|
||||
U16P(zero),
|
||||
U16P(zero),
|
||||
U16P(zero),
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
|
||||
PCORE(1,TSA)+1,
|
||||
PCORE(1,TSA),
|
||||
|
@ -234,7 +223,7 @@ u16* regtable[0x800] =
|
|||
PREVB_REG(1,MIX_DEST_B1),
|
||||
|
||||
PCORE(1,EffectsEndA)+1,
|
||||
U16P(zero),
|
||||
NULL,
|
||||
|
||||
PCORE(1,Regs.ENDX),
|
||||
PCORE(1,Regs.ENDX)+1,
|
||||
|
@ -308,6 +297,5 @@ u16* regtable[0x800] =
|
|||
PRAW(0x7F0),PRAW(0x7F2),PRAW(0x7F4),PRAW(0x7F6),
|
||||
PRAW(0x7F8),PRAW(0x7FA),PRAW(0x7FC),PRAW(0x7FE),
|
||||
|
||||
U16P(zero)
|
||||
NULL
|
||||
};
|
||||
#pragma pack()
|
|
@ -1,32 +0,0 @@
|
|||
//GiGaHeRz's SPU2 Driver
|
||||
//Copyright (c) 2003-2008, David Quintana <gigaherz@gmail.com>
|
||||
//
|
||||
//This library is free software; you can redistribute it and/or
|
||||
//modify it under the terms of the GNU Lesser General Public
|
||||
//License as published by the Free Software Foundation; either
|
||||
//version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
//This library is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
//Lesser General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU Lesser General Public
|
||||
//License along with this library; if not, write to the Free Software
|
||||
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
|
||||
#ifndef _REGTABLE_H_
|
||||
#define _REGTABLE_H_
|
||||
|
||||
#define U16P(x) ( (u16*)&(x) )
|
||||
|
||||
// Returns the hiword of a 32 bit integer.
|
||||
#define U16P_HI(x) ( ((u16*)&(x))+1 )
|
||||
|
||||
// Yay! Global namespace pollution 101!
|
||||
extern const u16 zero;
|
||||
|
||||
extern u16* regtable[0x800];
|
||||
|
||||
#endif
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "Global.h"
|
||||
#include "Dialogs.h"
|
||||
#include "../RegTable.h"
|
||||
|
||||
|
||||
static bool debugDialogOpen=false;
|
||||
|
|
|
@ -990,10 +990,6 @@
|
|||
RelativePath="..\RegTable.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\RegTable.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\spu2freeze.cpp"
|
||||
>
|
||||
|
|
|
@ -99,23 +99,34 @@ public:
|
|||
void DebugDump( FILE* dump, const char* title );
|
||||
};
|
||||
|
||||
|
||||
struct V_ADSR
|
||||
{
|
||||
u16 Reg_ADSR1;
|
||||
u16 Reg_ADSR2;
|
||||
union
|
||||
{
|
||||
u32 reg32;
|
||||
|
||||
struct
|
||||
{
|
||||
u16 regADSR1;
|
||||
u16 regADSR2;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
u32 SustainLevel:4,
|
||||
DecayRate:4,
|
||||
AttackRate:7,
|
||||
AttackMode:1, // 0 for linear (+lin), 1 for pseudo exponential (+exp)
|
||||
|
||||
ReleaseRate:5,
|
||||
ReleaseMode:1, // 0 for linear (-lin), 1 for exponential (-exp)
|
||||
SustainRate:7,
|
||||
SustainMode:3; // 0 = +lin, 1 = -lin, 2 = +exp, 3 = -exp
|
||||
};
|
||||
};
|
||||
|
||||
s32 Value; // Ranges from 0 to 0x7fffffff (signed values are clamped to 0) [Reg_ENVX]
|
||||
u8 Phase;
|
||||
u8 AttackRate; // Ar
|
||||
u8 AttackMode; // Am
|
||||
u8 DecayRate; // Dr
|
||||
u8 SustainLevel; // Sl
|
||||
u8 SustainRate; // Sr
|
||||
u8 SustainMode; // Sm
|
||||
u8 ReleaseRate; // Rr
|
||||
u8 ReleaseMode; // Rm
|
||||
|
||||
u8 Phase; // monitors current phase of ADSR envelope
|
||||
bool Releasing; // Ready To Release, triggered by Voice.Stop();
|
||||
|
||||
public:
|
||||
|
@ -133,10 +144,6 @@ struct V_Voice
|
|||
V_ADSR ADSR;
|
||||
// Pitch (also Reg_PITCH)
|
||||
s16 Pitch;
|
||||
// Pitch Modulated by previous voice
|
||||
s8 Modulated;
|
||||
// Source (Wave/Noise)
|
||||
s8 Noise;
|
||||
// Loop Start address (also Reg_LSAH/L)
|
||||
u32 LoopStartA;
|
||||
// Sound Start address (also Reg_SSAH/L)
|
||||
|
@ -147,15 +154,14 @@ struct V_Voice
|
|||
s32 Prev1;
|
||||
s32 Prev2;
|
||||
|
||||
// Pitch Modulated by previous voice
|
||||
bool Modulated;
|
||||
// Source (Wave/Noise)
|
||||
bool Noise;
|
||||
|
||||
s8 LoopMode;
|
||||
s8 LoopFlags;
|
||||
|
||||
// [Air] : Replaced loop flags read from the ADPCM header with
|
||||
// a single LoopFlags value (above) -- more cache-friendly.
|
||||
//s8 LoopStart;
|
||||
//s8 Loop;
|
||||
//s8 LoopEnd;
|
||||
|
||||
// Sample pointer (19:12 bit fixed point)
|
||||
s32 SP;
|
||||
|
||||
|
@ -303,8 +309,9 @@ struct V_CoreRegs
|
|||
u32 VMIXR;
|
||||
u32 VMIXEL;
|
||||
u32 VMIXER;
|
||||
u16 MMIX;
|
||||
u32 ENDX;
|
||||
|
||||
u16 MMIX;
|
||||
u16 STATX;
|
||||
u16 ATTR;
|
||||
u16 _1AC;
|
||||
|
@ -374,17 +381,18 @@ struct V_Core
|
|||
u32 TSA; // DMA Transfer Start Address
|
||||
u32 TDA; // DMA Transfer Data Address (Internal...)
|
||||
|
||||
s8 IRQEnable; // Interrupt Enable
|
||||
bool IRQEnable; // Interrupt Enable
|
||||
bool FxEnable; // Effect Enable
|
||||
bool Mute; // Mute
|
||||
bool AdmaInProgress;
|
||||
|
||||
s8 DMABits; // DMA related?
|
||||
s8 FxEnable; // Effect Enable
|
||||
s8 NoiseClk; // Noise Clock
|
||||
u16 AutoDMACtrl; // AutoDMA Status
|
||||
s32 DMAICounter; // DMA Interrupt Counter
|
||||
s8 Mute; // Mute
|
||||
u32 InputDataLeft; // Input Buffer
|
||||
u32 InputPos;
|
||||
u32 InputDataProgress;
|
||||
u8 AdmaInProgress;
|
||||
|
||||
V_Reverb Revb; // Reverb Registers
|
||||
V_ReverbBuffers RevBuffers; // buffer pointers for reverb, pre-calculated and pre-clipped.
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
|
||||
// SPDIF interface
|
||||
#define SPDIF_OUT 0x07C0 // SPDIF Out: OFF/'PCM'/Bitstream/Bypass
|
||||
#define IRQINFO 0x07C2
|
||||
#define SPDIF_IRQINFO 0x07C2
|
||||
#define SPDIF_MODE 0x07C6
|
||||
#define SPDIF_MEDIA 0x07C8 // SPDIF Media: 'CD'/DVD
|
||||
#define SPDIF_PROTECT 0x07CC // SPDIF Copy Protection
|
||||
|
@ -180,3 +180,16 @@ Core attributes (SD_C)
|
|||
#define VOICE_ADDR_LSAX 0x4 // Loop point address
|
||||
#define VOICE_ADDR_NAX 0x8 // Waveform data that should be read next
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SPU2-X Register Table LUT
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
#define U16P(x) ( (u16*)&(x) )
|
||||
|
||||
// Returns the hiword of a 32 bit integer.
|
||||
#define U16P_HI(x) ( ((u16*)&(x))+1 )
|
||||
|
||||
extern u16* regtable[0x401];
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
|
||||
#include "Global.h"
|
||||
#include "RegTable.h"
|
||||
#include "dma.h"
|
||||
|
||||
#include "PS2E-spu2.h" // needed until I figure out a nice solution for irqcallback dependencies.
|
||||
|
@ -274,65 +273,6 @@ static const int SanityInterval = 4800;
|
|||
u32 TicksCore = 0;
|
||||
u32 TicksThread = 0;
|
||||
|
||||
PCSX2_ALIGNED16( static u64 g_globalMMXData[8] );
|
||||
|
||||
static __forceinline void SaveMMXRegs()
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
__asm {
|
||||
movntq mmword ptr [g_globalMMXData + 0], mm0
|
||||
movntq mmword ptr [g_globalMMXData + 8], mm1
|
||||
movntq mmword ptr [g_globalMMXData + 16], mm2
|
||||
movntq mmword ptr [g_globalMMXData + 24], mm3
|
||||
movntq mmword ptr [g_globalMMXData + 32], mm4
|
||||
movntq mmword ptr [g_globalMMXData + 40], mm5
|
||||
movntq mmword ptr [g_globalMMXData + 48], mm6
|
||||
movntq mmword ptr [g_globalMMXData + 56], mm7
|
||||
emms
|
||||
}
|
||||
#else
|
||||
__asm__(".intel_syntax\n"
|
||||
"movq [%0+0x00], %%mm0\n"
|
||||
"movq [%0+0x08], %%mm1\n"
|
||||
"movq [%0+0x10], %%mm2\n"
|
||||
"movq [%0+0x18], %%mm3\n"
|
||||
"movq [%0+0x20], %%mm4\n"
|
||||
"movq [%0+0x28], %%mm5\n"
|
||||
"movq [%0+0x30], %%mm6\n"
|
||||
"movq [%0+0x38], %%mm7\n"
|
||||
"emms\n"
|
||||
".att_syntax\n" : : "r"(g_globalMMXData) );
|
||||
#endif
|
||||
}
|
||||
|
||||
static __forceinline void RestoreMMXRegs()
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
__asm {
|
||||
movq mm0, mmword ptr [g_globalMMXData + 0]
|
||||
movq mm1, mmword ptr [g_globalMMXData + 8]
|
||||
movq mm2, mmword ptr [g_globalMMXData + 16]
|
||||
movq mm3, mmword ptr [g_globalMMXData + 24]
|
||||
movq mm4, mmword ptr [g_globalMMXData + 32]
|
||||
movq mm5, mmword ptr [g_globalMMXData + 40]
|
||||
movq mm6, mmword ptr [g_globalMMXData + 48]
|
||||
movq mm7, mmword ptr [g_globalMMXData + 56]
|
||||
emms
|
||||
}
|
||||
#else
|
||||
__asm__(".intel_syntax\n"
|
||||
"movq %%mm0, [%0+0x00]\n"
|
||||
"movq %%mm1, [%0+0x08]\n"
|
||||
"movq %%mm2, [%0+0x10]\n"
|
||||
"movq %%mm3, [%0+0x18]\n"
|
||||
"movq %%mm4, [%0+0x20]\n"
|
||||
"movq %%mm5, [%0+0x28]\n"
|
||||
"movq %%mm6, [%0+0x30]\n"
|
||||
"movq %%mm7, [%0+0x38]\n"
|
||||
"emms\n"
|
||||
".att_syntax\n" : : "r"(g_globalMMXData) );
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline void TimeUpdate(u32 cClocks)
|
||||
{
|
||||
|
@ -423,7 +363,7 @@ __forceinline void TimeUpdate(u32 cClocks)
|
|||
|
||||
static u16 mask = 0xFFFF;
|
||||
|
||||
void UpdateSpdifMode()
|
||||
__forceinline void UpdateSpdifMode()
|
||||
{
|
||||
int OPM=PlayMode;
|
||||
u16 last = 0;
|
||||
|
@ -504,19 +444,11 @@ void V_Core::WriteRegPS1( u32 mem, u16 value )
|
|||
case 3: Voices[voice].StartA = (u32)value<<8; break;
|
||||
|
||||
case 4: // ADSR1 (Envelope)
|
||||
Voices[voice].ADSR.AttackMode = (value & 0x8000)>>15;
|
||||
Voices[voice].ADSR.AttackRate = (value & 0x7F00)>>8;
|
||||
Voices[voice].ADSR.DecayRate = (value & 0xF0)>>4;
|
||||
Voices[voice].ADSR.SustainLevel = (value & 0xF);
|
||||
Voices[voice].ADSR.Reg_ADSR1 = value;
|
||||
Voices[voice].ADSR.regADSR1 = value;
|
||||
break;
|
||||
|
||||
case 5: // ADSR2 (Envelope)
|
||||
Voices[voice].ADSR.SustainMode = (value & 0xE000)>>13;
|
||||
Voices[voice].ADSR.SustainRate = (value & 0x1FC0)>>6;
|
||||
Voices[voice].ADSR.ReleaseMode = (value & 0x20)>>5;
|
||||
Voices[voice].ADSR.ReleaseRate = (value & 0x1F);
|
||||
Voices[voice].ADSR.Reg_ADSR2 = value;
|
||||
Voices[voice].ADSR.regADSR2 = value;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
|
@ -667,8 +599,8 @@ u16 V_Core::ReadRegPS1(u32 mem)
|
|||
|
||||
case 2: value = Voices[voice].Pitch; break;
|
||||
case 3: value = Voices[voice].StartA; break;
|
||||
case 4: value = Voices[voice].ADSR.Reg_ADSR1; break;
|
||||
case 5: value = Voices[voice].ADSR.Reg_ADSR2; 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;
|
||||
|
||||
|
@ -766,19 +698,12 @@ static __forceinline u16 GetLoWord( s32& src )
|
|||
return ((u16*)&src)[0];
|
||||
}
|
||||
|
||||
#ifndef __LINUX__
|
||||
__forceinline
|
||||
#endif
|
||||
void SPU2_FastWrite( u32 rmem, u16 value )
|
||||
template< int CoreIdx, int VoiceIdx, int param >
|
||||
static void __fastcall RegWrite_VoiceParams( u16 value )
|
||||
{
|
||||
u32 vx=0, vc=0, core=0, omem, mem;
|
||||
omem=mem=rmem & 0x7FF; //FFFF;
|
||||
if (mem & 0x400) { omem^=0x400; core=1; }
|
||||
const int core = CoreIdx;
|
||||
const int voice = VoiceIdx;
|
||||
|
||||
if (omem < 0x0180) // Voice Params
|
||||
{
|
||||
const u32 voice = (omem & 0x1F0) >> 4;
|
||||
const u32 param = (omem & 0xF) >> 1;
|
||||
V_Voice& thisvoice = Cores[core].Voices[voice];
|
||||
|
||||
switch (param)
|
||||
|
@ -807,19 +732,18 @@ void SPU2_FastWrite( u32 rmem, u16 value )
|
|||
}
|
||||
break;
|
||||
|
||||
case 2: thisvoice.Pitch=value; break;
|
||||
case 2:
|
||||
thisvoice.Pitch = value;
|
||||
break;
|
||||
|
||||
case 3: // ADSR1 (Envelope)
|
||||
thisvoice.ADSR.AttackMode = (value & 0x8000)>>15;
|
||||
thisvoice.ADSR.AttackRate = (value & 0x7F00)>>8;
|
||||
thisvoice.ADSR.DecayRate = (value & 0xF0)>>4;
|
||||
thisvoice.ADSR.SustainLevel = (value & 0xF);
|
||||
thisvoice.ADSR.Reg_ADSR1 = value; break;
|
||||
thisvoice.ADSR.regADSR1 = value;
|
||||
break;
|
||||
|
||||
case 4: // ADSR2 (Envelope)
|
||||
thisvoice.ADSR.SustainMode = (value & 0xE000)>>13;
|
||||
thisvoice.ADSR.SustainRate = (value & 0x1FC0)>>6;
|
||||
thisvoice.ADSR.ReleaseMode = (value & 0x20)>>5;
|
||||
thisvoice.ADSR.ReleaseRate = (value & 0x1F);
|
||||
thisvoice.ADSR.Reg_ADSR2 = value; break;
|
||||
thisvoice.ADSR.regADSR2 = value;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// [Air] : Mysterious ADSR set code. Too bad none of my games ever use it.
|
||||
// (as usual... )
|
||||
|
@ -833,10 +757,13 @@ void SPU2_FastWrite( u32 rmem, u16 value )
|
|||
jNO_DEFAULT;
|
||||
}
|
||||
}
|
||||
else if ((omem >= 0x01C0) && (omem < 0x02DE))
|
||||
|
||||
template< int CoreIdx, int VoiceIdx, int address >
|
||||
static void __fastcall RegWrite_VoiceAddr( u16 value )
|
||||
{
|
||||
const u32 voice = ((omem-0x01C0) / 12);
|
||||
const u32 address = ((omem-0x01C0) % 12) >> 1;
|
||||
const int core = CoreIdx;
|
||||
const int voice = VoiceIdx;
|
||||
|
||||
V_Voice& thisvoice = Cores[core].Voices[voice];
|
||||
|
||||
switch (address)
|
||||
|
@ -872,26 +799,17 @@ void SPU2_FastWrite( u32 rmem, u16 value )
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if((mem>=0x07C0) && (mem<0x07CE))
|
||||
{
|
||||
*(regtable[mem>>1]) = value;
|
||||
UpdateSpdifMode();
|
||||
}
|
||||
else if( mem >= R_FB_SRC_A && mem < REG_A_EEA )
|
||||
{
|
||||
// Signal to the Reverb code that the effects buffers need to be re-aligned.
|
||||
// This is both simple, efficient, and safe, since we only want to re-align
|
||||
// buffers after both hi and lo words have been written.
|
||||
|
||||
*(regtable[mem>>1]) = value;
|
||||
Cores[core].RevBuffers.NeedsUpdated = true;
|
||||
}
|
||||
else
|
||||
template< int CoreIdx, int cAddr >
|
||||
static void __fastcall RegWrite_Core( u16 value )
|
||||
{
|
||||
const int omem = cAddr;
|
||||
const int core = CoreIdx;
|
||||
V_Core& thiscore = Cores[core];
|
||||
|
||||
switch(omem)
|
||||
{
|
||||
case 0x1ac:
|
||||
case REG__1AC:
|
||||
// ----------------------------------------------------------------------------
|
||||
// 0x1ac / 0x5ac : direct-write to DMA address : special register (undocumented)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -901,8 +819,8 @@ void SPU2_FastWrite( u32 rmem, u16 value )
|
|||
// optimized block copy fashion elsewhere, but some games will write this register
|
||||
// directly, so handle those here:
|
||||
|
||||
// Performance Note: If a game uses this extensively, it *will* be slow. I plan to
|
||||
// fix that using a proper paged LUT someday.
|
||||
// Performance Note: The PS2 Bios uses this extensively right before booting games,
|
||||
// causing massive slowdown if we don't shortcut it here.
|
||||
|
||||
for( int i=0; i<2; i++ )
|
||||
{
|
||||
|
@ -917,7 +835,7 @@ void SPU2_FastWrite( u32 rmem, u16 value )
|
|||
|
||||
case REG_C_ATTR:
|
||||
{
|
||||
int irqe = thiscore.IRQEnable;
|
||||
bool irqe = thiscore.IRQEnable;
|
||||
int bit0 = thiscore.AttrBit0;
|
||||
int bit4 = thiscore.AttrBit4;
|
||||
|
||||
|
@ -969,22 +887,26 @@ void SPU2_FastWrite( u32 rmem, u16 value )
|
|||
break;
|
||||
|
||||
case REG_S_PMON:
|
||||
vx=2; for (vc=1;vc<16;vc++) { thiscore.Voices[vc].Modulated=(s8)((value & vx)/vx); vx<<=1; }
|
||||
for( int vc=1; vc<16; ++vc )
|
||||
thiscore.Voices[vc].Modulated = (value >> vc) & 1;
|
||||
SetLoWord( thiscore.Regs.PMON, value );
|
||||
break;
|
||||
|
||||
case (REG_S_PMON + 2):
|
||||
vx=1; for (vc=16;vc<24;vc++) { thiscore.Voices[vc].Modulated=(s8)((value & vx)/vx); vx<<=1; }
|
||||
for( int vc=0; vc<8; ++vc )
|
||||
thiscore.Voices[vc+16].Modulated = (value >> vc) & 1;
|
||||
SetHiWord( thiscore.Regs.PMON, value );
|
||||
break;
|
||||
|
||||
case REG_S_NON:
|
||||
vx=1; for (vc=0;vc<16;vc++) { thiscore.Voices[vc].Noise=(s8)((value & vx)/vx); vx<<=1; }
|
||||
for( int vc=0; vc<16; ++vc)
|
||||
thiscore.Voices[vc].Noise = (value >> vc) & 1;
|
||||
SetLoWord( thiscore.Regs.NON, value );
|
||||
break;
|
||||
|
||||
case (REG_S_NON + 2):
|
||||
vx=1; for (vc=16;vc<24;vc++) { thiscore.Voices[vc].Noise=(s8)((value & vx)/vx); vx<<=1; }
|
||||
for( int vc=0; vc<8; ++vc )
|
||||
thiscore.Voices[vc+16].Noise = (value >> vc) & 1;
|
||||
SetHiWord( thiscore.Regs.NON, value );
|
||||
break;
|
||||
|
||||
|
@ -1038,12 +960,11 @@ void SPU2_FastWrite( u32 rmem, u16 value )
|
|||
break;
|
||||
|
||||
case REG_P_MMIX:
|
||||
|
||||
{
|
||||
// Each MMIX gate is assigned either 0 or 0xffffffff depending on the status
|
||||
// of the MMIX bits. I use -1 below as a shorthand for 0xffffffff. :)
|
||||
|
||||
vx = value;
|
||||
if (core == 0) vx&=0xFF0;
|
||||
const int vx = value & ((core==0) ? 0xFF0 : 0xFFF);
|
||||
thiscore.WetGate.ExtR = (vx & 0x001) ? -1 : 0;
|
||||
thiscore.WetGate.ExtL = (vx & 0x002) ? -1 : 0;
|
||||
thiscore.DryGate.ExtR = (vx & 0x004) ? -1 : 0;
|
||||
|
@ -1057,6 +978,7 @@ void SPU2_FastWrite( u32 rmem, u16 value )
|
|||
thiscore.DryGate.SndR = (vx & 0x400) ? -1 : 0;
|
||||
thiscore.DryGate.SndL = (vx & 0x800) ? -1 : 0;
|
||||
thiscore.Regs.MMIX = value;
|
||||
}
|
||||
break;
|
||||
|
||||
case (REG_S_KON + 2):
|
||||
|
@ -1108,12 +1030,39 @@ void SPU2_FastWrite( u32 rmem, u16 value )
|
|||
thiscore.ReverbX = 0;
|
||||
break;
|
||||
|
||||
case REG_S_ADMAS:
|
||||
//ConLog(" * SPU2: Core %d AutoDMAControl set to %d (%d)\n",core,value, Cycles);
|
||||
thiscore.AutoDMACtrl=value;
|
||||
|
||||
if(value==0)
|
||||
{
|
||||
thiscore.AdmaInProgress=0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
const int addr = omem | ( (core == 1) ? 0x400 : 0 );
|
||||
*(regtable[addr>>1]) = value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template< int CoreIdx, int addr >
|
||||
static void __fastcall RegWrite_CoreExt( u16 value )
|
||||
{
|
||||
V_Core& thiscore = Cores[CoreIdx];
|
||||
const int core = CoreIdx;
|
||||
|
||||
switch(addr)
|
||||
{
|
||||
// Master Volume Address Write!
|
||||
|
||||
case REG_P_MVOLL:
|
||||
case REG_P_MVOLR:
|
||||
{
|
||||
V_VolumeSlide& thisvol = (omem==REG_P_MVOLL) ? thiscore.MasterVol.Left : thiscore.MasterVol.Right;
|
||||
V_VolumeSlide& thisvol = (addr==REG_P_MVOLL) ? thiscore.MasterVol.Left : thiscore.MasterVol.Right;
|
||||
|
||||
if( value & 0x8000 ) // +Lin/-Lin/+Exp/-Exp
|
||||
{
|
||||
|
@ -1158,21 +1107,310 @@ void SPU2_FastWrite( u32 rmem, u16 value )
|
|||
thiscore.InpVol.Right = GetVol32( value );
|
||||
break;
|
||||
|
||||
case REG_S_ADMAS:
|
||||
//ConLog(" * SPU2: Core %d AutoDMAControl set to %d (%d)\n",core,value, Cycles);
|
||||
thiscore.AutoDMACtrl=value;
|
||||
|
||||
if(value==0)
|
||||
{
|
||||
thiscore.AdmaInProgress=0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
*(regtable[mem>>1]) = value;
|
||||
{
|
||||
const int raddr = addr + ((core==1) ? 0x28 : 0 );
|
||||
*(regtable[raddr>>1]) = value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template< int core, int addr >
|
||||
static void __fastcall RegWrite_Reverb( u16 value )
|
||||
{
|
||||
// Signal to the Reverb code that the effects buffers need to be re-aligned.
|
||||
// This is both simple, efficient, and safe, since we only want to re-align
|
||||
// buffers after both hi and lo words have been written.
|
||||
|
||||
*(regtable[addr>>1]) = value;
|
||||
Cores[core].RevBuffers.NeedsUpdated = true;
|
||||
}
|
||||
|
||||
template< int addr >
|
||||
static void __fastcall RegWrite_SPDIF( u16 value )
|
||||
{
|
||||
*(regtable[addr>>1]) = value;
|
||||
UpdateSpdifMode();
|
||||
}
|
||||
|
||||
template< int addr >
|
||||
static void __fastcall RegWrite_Raw( u16 value )
|
||||
{
|
||||
*(regtable[addr>>1]) = value;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Macros for tbl_reg_writes
|
||||
// --------------------------------------------------------------------------------------
|
||||
#define VoiceParamsSet( core, voice ) \
|
||||
RegWrite_VoiceParams<core,voice,0>, RegWrite_VoiceParams<core,voice,1>, \
|
||||
RegWrite_VoiceParams<core,voice,2>, RegWrite_VoiceParams<core,voice,3>, \
|
||||
RegWrite_VoiceParams<core,voice,4>, RegWrite_VoiceParams<core,voice,5>, \
|
||||
RegWrite_VoiceParams<core,voice,6>, RegWrite_VoiceParams<core,voice,7>
|
||||
|
||||
#define VoiceParamsCore( core ) \
|
||||
VoiceParamsSet(core, 0), VoiceParamsSet(core, 1), VoiceParamsSet(core, 2), VoiceParamsSet(core, 3 ), \
|
||||
VoiceParamsSet(core, 4), VoiceParamsSet(core, 5), VoiceParamsSet(core, 6), VoiceParamsSet(core, 7 ), \
|
||||
VoiceParamsSet(core, 8), VoiceParamsSet(core, 9), VoiceParamsSet(core, 10),VoiceParamsSet(core, 11 ), \
|
||||
VoiceParamsSet(core, 12),VoiceParamsSet(core, 13),VoiceParamsSet(core, 14),VoiceParamsSet(core, 15 ), \
|
||||
VoiceParamsSet(core, 16),VoiceParamsSet(core, 17),VoiceParamsSet(core, 18),VoiceParamsSet(core, 19 ), \
|
||||
VoiceParamsSet(core, 20),VoiceParamsSet(core, 21),VoiceParamsSet(core, 22),VoiceParamsSet(core, 23 )
|
||||
|
||||
#define VoiceAddrSet( core, voice ) \
|
||||
RegWrite_VoiceAddr<core,voice,0>, RegWrite_VoiceAddr<core,voice,1>, \
|
||||
RegWrite_VoiceAddr<core,voice,2>, RegWrite_VoiceAddr<core,voice,3>, \
|
||||
RegWrite_VoiceAddr<core,voice,4>, RegWrite_VoiceAddr<core,voice,5>
|
||||
|
||||
|
||||
#define CoreParamsPair( core, omem ) \
|
||||
RegWrite_Core<core, omem>, RegWrite_Core<core, (omem+2)>
|
||||
|
||||
#define ReverbPair( core, mem ) \
|
||||
RegWrite_Reverb<core, mem>, RegWrite_Core<core, (mem+2)>
|
||||
|
||||
#define REGRAW(addr) RegWrite_Raw<addr>
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// tbl_reg_writes - Register Write Function Invocation LUT
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
typedef void __fastcall RegWriteHandler( u16 value );
|
||||
static RegWriteHandler * const tbl_reg_writes[0x401] =
|
||||
{
|
||||
VoiceParamsCore(0), // 0x000 -> 0x180
|
||||
CoreParamsPair(0,REG_S_PMON),
|
||||
CoreParamsPair(0,REG_S_NON),
|
||||
CoreParamsPair(0,REG_S_VMIXL),
|
||||
CoreParamsPair(0,REG_S_VMIXEL),
|
||||
CoreParamsPair(0,REG_S_VMIXR),
|
||||
CoreParamsPair(0,REG_S_VMIXER),
|
||||
|
||||
RegWrite_Core<0,REG_P_MMIX>,
|
||||
RegWrite_Core<0,REG_C_ATTR>,
|
||||
|
||||
CoreParamsPair(0,REG_A_IRQA),
|
||||
CoreParamsPair(0,REG_S_KON),
|
||||
CoreParamsPair(0,REG_S_KOFF),
|
||||
CoreParamsPair(0,REG_A_TSA),
|
||||
CoreParamsPair(0,REG__1AC),
|
||||
|
||||
RegWrite_Core<0,REG_S_ADMAS>,
|
||||
REGRAW(0x1b2),
|
||||
|
||||
REGRAW(0x1b4), REGRAW(0x1b6),
|
||||
REGRAW(0x1b8), REGRAW(0x1ba),
|
||||
REGRAW(0x1bc), REGRAW(0x1be),
|
||||
|
||||
// 0x1c0!
|
||||
|
||||
VoiceAddrSet(0, 0),VoiceAddrSet(0, 1),VoiceAddrSet(0, 2),VoiceAddrSet(0, 3),VoiceAddrSet(0, 4),VoiceAddrSet(0, 5),
|
||||
VoiceAddrSet(0, 6),VoiceAddrSet(0, 7),VoiceAddrSet(0, 8),VoiceAddrSet(0, 9),VoiceAddrSet(0,10),VoiceAddrSet(0,11),
|
||||
VoiceAddrSet(0,12),VoiceAddrSet(0,13),VoiceAddrSet(0,14),VoiceAddrSet(0,15),VoiceAddrSet(0,16),VoiceAddrSet(0,17),
|
||||
VoiceAddrSet(0,18),VoiceAddrSet(0,19),VoiceAddrSet(0,20),VoiceAddrSet(0,21),VoiceAddrSet(0,22),VoiceAddrSet(0,23),
|
||||
|
||||
CoreParamsPair(0,REG_A_ESA),
|
||||
|
||||
ReverbPair(0,R_FB_SRC_A), // 0x02E4 // Feedback Source A
|
||||
ReverbPair(0,R_FB_SRC_B), // 0x02E8 // Feedback Source B
|
||||
ReverbPair(0,R_IIR_DEST_A0), // 0x02EC
|
||||
ReverbPair(0,R_IIR_DEST_A1), // 0x02F0
|
||||
ReverbPair(0,R_ACC_SRC_A0), // 0x02F4
|
||||
ReverbPair(0,R_ACC_SRC_A1), // 0x02F8
|
||||
ReverbPair(0,R_ACC_SRC_B0), // 0x02FC
|
||||
ReverbPair(0,R_ACC_SRC_B1), // 0x0300
|
||||
ReverbPair(0,R_IIR_SRC_A0), // 0x0304
|
||||
ReverbPair(0,R_IIR_SRC_A1), // 0x0308
|
||||
ReverbPair(0,R_IIR_DEST_B0), // 0x030C
|
||||
ReverbPair(0,R_IIR_DEST_B1), // 0x0310
|
||||
ReverbPair(0,R_ACC_SRC_C0), // 0x0314
|
||||
ReverbPair(0,R_ACC_SRC_C1), // 0x0318
|
||||
ReverbPair(0,R_ACC_SRC_D0), // 0x031C
|
||||
ReverbPair(0,R_ACC_SRC_D1), // 0x0320
|
||||
ReverbPair(0,R_IIR_SRC_B1), // 0x0324
|
||||
ReverbPair(0,R_IIR_SRC_B0), // 0x0328
|
||||
ReverbPair(0,R_MIX_DEST_A0), // 0x032C
|
||||
ReverbPair(0,R_MIX_DEST_A1), // 0x0330
|
||||
ReverbPair(0,R_MIX_DEST_B0), // 0x0334
|
||||
ReverbPair(0,R_MIX_DEST_B1), // 0x0338
|
||||
|
||||
RegWrite_Core<0,REG_A_EEA>, NULL,
|
||||
|
||||
CoreParamsPair(0,REG_S_ENDX), // 0x0340 // End Point passed flag
|
||||
RegWrite_Core<0,REG_P_STATX>, // 0x0344 // Status register?
|
||||
|
||||
//0x346 here
|
||||
REGRAW(0x346),
|
||||
REGRAW(0x348),REGRAW(0x34A),REGRAW(0x34C),REGRAW(0x34E),
|
||||
REGRAW(0x350),REGRAW(0x352),REGRAW(0x354),REGRAW(0x356),
|
||||
REGRAW(0x358),REGRAW(0x35A),REGRAW(0x35C),REGRAW(0x35E),
|
||||
REGRAW(0x360),REGRAW(0x362),REGRAW(0x364),REGRAW(0x366),
|
||||
REGRAW(0x368),REGRAW(0x36A),REGRAW(0x36C),REGRAW(0x36E),
|
||||
REGRAW(0x370),REGRAW(0x372),REGRAW(0x374),REGRAW(0x376),
|
||||
REGRAW(0x378),REGRAW(0x37A),REGRAW(0x37C),REGRAW(0x37E),
|
||||
REGRAW(0x380),REGRAW(0x382),REGRAW(0x384),REGRAW(0x386),
|
||||
REGRAW(0x388),REGRAW(0x38A),REGRAW(0x38C),REGRAW(0x38E),
|
||||
REGRAW(0x390),REGRAW(0x392),REGRAW(0x394),REGRAW(0x396),
|
||||
REGRAW(0x398),REGRAW(0x39A),REGRAW(0x39C),REGRAW(0x39E),
|
||||
REGRAW(0x3A0),REGRAW(0x3A2),REGRAW(0x3A4),REGRAW(0x3A6),
|
||||
REGRAW(0x3A8),REGRAW(0x3AA),REGRAW(0x3AC),REGRAW(0x3AE),
|
||||
REGRAW(0x3B0),REGRAW(0x3B2),REGRAW(0x3B4),REGRAW(0x3B6),
|
||||
REGRAW(0x3B8),REGRAW(0x3BA),REGRAW(0x3BC),REGRAW(0x3BE),
|
||||
REGRAW(0x3C0),REGRAW(0x3C2),REGRAW(0x3C4),REGRAW(0x3C6),
|
||||
REGRAW(0x3C8),REGRAW(0x3CA),REGRAW(0x3CC),REGRAW(0x3CE),
|
||||
REGRAW(0x3D0),REGRAW(0x3D2),REGRAW(0x3D4),REGRAW(0x3D6),
|
||||
REGRAW(0x3D8),REGRAW(0x3DA),REGRAW(0x3DC),REGRAW(0x3DE),
|
||||
REGRAW(0x3E0),REGRAW(0x3E2),REGRAW(0x3E4),REGRAW(0x3E6),
|
||||
REGRAW(0x3E8),REGRAW(0x3EA),REGRAW(0x3EC),REGRAW(0x3EE),
|
||||
REGRAW(0x3F0),REGRAW(0x3F2),REGRAW(0x3F4),REGRAW(0x3F6),
|
||||
REGRAW(0x3F8),REGRAW(0x3FA),REGRAW(0x3FC),REGRAW(0x3FE),
|
||||
|
||||
// AND... we reached 0x400!
|
||||
// Last verse, same as the first:
|
||||
|
||||
VoiceParamsCore(1), // 0x000 -> 0x180
|
||||
CoreParamsPair(1,REG_S_PMON),
|
||||
CoreParamsPair(1,REG_S_NON),
|
||||
CoreParamsPair(1,REG_S_VMIXL),
|
||||
CoreParamsPair(1,REG_S_VMIXEL),
|
||||
CoreParamsPair(1,REG_S_VMIXR),
|
||||
CoreParamsPair(1,REG_S_VMIXER),
|
||||
|
||||
RegWrite_Core<1,REG_P_MMIX>,
|
||||
RegWrite_Core<1,REG_C_ATTR>,
|
||||
|
||||
CoreParamsPair(1,REG_A_IRQA),
|
||||
CoreParamsPair(1,REG_S_KON),
|
||||
CoreParamsPair(1,REG_S_KOFF),
|
||||
CoreParamsPair(1,REG_A_TSA),
|
||||
CoreParamsPair(1,REG__1AC),
|
||||
|
||||
RegWrite_Core<1,REG_S_ADMAS>,
|
||||
REGRAW(0x5b2),
|
||||
|
||||
REGRAW(0x5b4), REGRAW(0x5b6),
|
||||
REGRAW(0x5b8), REGRAW(0x5ba),
|
||||
REGRAW(0x5bc), REGRAW(0x5be),
|
||||
|
||||
// 0x1c0!
|
||||
|
||||
VoiceAddrSet(1, 0),VoiceAddrSet(1, 1),VoiceAddrSet(1, 2),VoiceAddrSet(1, 3),VoiceAddrSet(1, 4),VoiceAddrSet(1, 5),
|
||||
VoiceAddrSet(1, 6),VoiceAddrSet(1, 7),VoiceAddrSet(1, 8),VoiceAddrSet(1, 9),VoiceAddrSet(1,10),VoiceAddrSet(1,11),
|
||||
VoiceAddrSet(1,12),VoiceAddrSet(1,13),VoiceAddrSet(1,14),VoiceAddrSet(1,15),VoiceAddrSet(1,16),VoiceAddrSet(1,17),
|
||||
VoiceAddrSet(1,18),VoiceAddrSet(1,19),VoiceAddrSet(1,20),VoiceAddrSet(1,21),VoiceAddrSet(1,22),VoiceAddrSet(1,23),
|
||||
|
||||
CoreParamsPair(1,REG_A_ESA),
|
||||
|
||||
ReverbPair(1,R_FB_SRC_A), // 0x02E4 // Feedback Source A
|
||||
ReverbPair(1,R_FB_SRC_B), // 0x02E8 // Feedback Source B
|
||||
ReverbPair(1,R_IIR_DEST_A0), // 0x02EC
|
||||
ReverbPair(1,R_IIR_DEST_A1), // 0x02F0
|
||||
ReverbPair(1,R_ACC_SRC_A0), // 0x02F4
|
||||
ReverbPair(1,R_ACC_SRC_A1), // 0x02F8
|
||||
ReverbPair(1,R_ACC_SRC_B0), // 0x02FC
|
||||
ReverbPair(1,R_ACC_SRC_B1), // 0x0300
|
||||
ReverbPair(1,R_IIR_SRC_A0), // 0x0304
|
||||
ReverbPair(1,R_IIR_SRC_A1), // 0x0308
|
||||
ReverbPair(1,R_IIR_DEST_B0), // 0x030C
|
||||
ReverbPair(1,R_IIR_DEST_B1), // 0x0310
|
||||
ReverbPair(1,R_ACC_SRC_C0), // 0x0314
|
||||
ReverbPair(1,R_ACC_SRC_C1), // 0x0318
|
||||
ReverbPair(1,R_ACC_SRC_D0), // 0x031C
|
||||
ReverbPair(1,R_ACC_SRC_D1), // 0x0320
|
||||
ReverbPair(1,R_IIR_SRC_B1), // 0x0324
|
||||
ReverbPair(1,R_IIR_SRC_B0), // 0x0328
|
||||
ReverbPair(1,R_MIX_DEST_A0), // 0x032C
|
||||
ReverbPair(1,R_MIX_DEST_A1), // 0x0330
|
||||
ReverbPair(1,R_MIX_DEST_B0), // 0x0334
|
||||
ReverbPair(1,R_MIX_DEST_B1), // 0x0338
|
||||
|
||||
RegWrite_Core<1,REG_A_EEA>, NULL,
|
||||
|
||||
CoreParamsPair(1,REG_S_ENDX), // 0x0340 // End Point passed flag
|
||||
RegWrite_Core<1,REG_P_STATX>, // 0x0344 // Status register?
|
||||
|
||||
REGRAW(0x746),
|
||||
REGRAW(0x748),REGRAW(0x74A),REGRAW(0x74C),REGRAW(0x74E),
|
||||
REGRAW(0x750),REGRAW(0x752),REGRAW(0x754),REGRAW(0x756),
|
||||
REGRAW(0x758),REGRAW(0x75A),REGRAW(0x75C),REGRAW(0x75E),
|
||||
|
||||
// ------ -------
|
||||
|
||||
RegWrite_CoreExt<0,REG_P_MVOLL>, // 0x0760 // Master Volume Left
|
||||
RegWrite_CoreExt<0,REG_P_MVOLR>, // 0x0762 // Master Volume Right
|
||||
RegWrite_CoreExt<0,REG_P_EVOLL>, // 0x0764 // Effect Volume Left
|
||||
RegWrite_CoreExt<0,REG_P_EVOLR>, // 0x0766 // Effect Volume Right
|
||||
RegWrite_CoreExt<0,REG_P_AVOLL>, // 0x0768 // Core External Input Volume Left (Only Core 1)
|
||||
RegWrite_CoreExt<0,REG_P_AVOLR>, // 0x076A // Core External Input Volume Right (Only Core 1)
|
||||
RegWrite_CoreExt<0,REG_P_BVOLL>, // 0x076C // Sound Data Volume Left
|
||||
RegWrite_CoreExt<0,REG_P_BVOLR>, // 0x076E // Sound Data Volume Right
|
||||
RegWrite_CoreExt<0,REG_P_MVOLXL>, // 0x0770 // Current Master Volume Left
|
||||
RegWrite_CoreExt<0,REG_P_MVOLXR>, // 0x0772 // Current Master Volume Right
|
||||
|
||||
RegWrite_CoreExt<0,R_IIR_ALPHA>, // 0x0774 //IIR alpha (% used)
|
||||
RegWrite_CoreExt<0,R_ACC_COEF_A>, // 0x0776
|
||||
RegWrite_CoreExt<0,R_ACC_COEF_B>, // 0x0778
|
||||
RegWrite_CoreExt<0,R_ACC_COEF_C>, // 0x077A
|
||||
RegWrite_CoreExt<0,R_ACC_COEF_D>, // 0x077C
|
||||
RegWrite_CoreExt<0,R_IIR_COEF>, // 0x077E
|
||||
RegWrite_CoreExt<0,R_FB_ALPHA>, // 0x0780 //feedback alpha (% used)
|
||||
RegWrite_CoreExt<0,R_FB_X>, // 0x0782 //feedback
|
||||
RegWrite_CoreExt<0,R_IN_COEF_L>, // 0x0784
|
||||
RegWrite_CoreExt<0,R_IN_COEF_R>, // 0x0786
|
||||
|
||||
// ------ -------
|
||||
|
||||
RegWrite_CoreExt<1,REG_P_MVOLL>, // 0x0788 // Master Volume Left
|
||||
RegWrite_CoreExt<1,REG_P_MVOLR>, // 0x078A // Master Volume Right
|
||||
RegWrite_CoreExt<1,REG_P_EVOLL>, // 0x0764 // Effect Volume Left
|
||||
RegWrite_CoreExt<1,REG_P_EVOLR>, // 0x0766 // Effect Volume Right
|
||||
RegWrite_CoreExt<1,REG_P_AVOLL>, // 0x0768 // Core External Input Volume Left (Only Core 1)
|
||||
RegWrite_CoreExt<1,REG_P_AVOLR>, // 0x076A // Core External Input Volume Right (Only Core 1)
|
||||
RegWrite_CoreExt<1,REG_P_BVOLL>, // 0x076C // Sound Data Volume Left
|
||||
RegWrite_CoreExt<1,REG_P_BVOLR>, // 0x076E // Sound Data Volume Right
|
||||
RegWrite_CoreExt<1,REG_P_MVOLXL>, // 0x0770 // Current Master Volume Left
|
||||
RegWrite_CoreExt<1,REG_P_MVOLXR>, // 0x0772 // Current Master Volume Right
|
||||
|
||||
RegWrite_CoreExt<1,R_IIR_ALPHA>, // 0x0774 //IIR alpha (% used)
|
||||
RegWrite_CoreExt<1,R_ACC_COEF_A>, // 0x0776
|
||||
RegWrite_CoreExt<1,R_ACC_COEF_B>, // 0x0778
|
||||
RegWrite_CoreExt<1,R_ACC_COEF_C>, // 0x077A
|
||||
RegWrite_CoreExt<1,R_ACC_COEF_D>, // 0x077C
|
||||
RegWrite_CoreExt<1,R_IIR_COEF>, // 0x077E
|
||||
RegWrite_CoreExt<1,R_FB_ALPHA>, // 0x0780 //feedback alpha (% used)
|
||||
RegWrite_CoreExt<1,R_FB_X>, // 0x0782 //feedback
|
||||
RegWrite_CoreExt<1,R_IN_COEF_L>, // 0x0784
|
||||
RegWrite_CoreExt<1,R_IN_COEF_R>, // 0x0786
|
||||
|
||||
REGRAW(0x7B0),REGRAW(0x7B2),REGRAW(0x7B4),REGRAW(0x7B6),
|
||||
REGRAW(0x7B8),REGRAW(0x7BA),REGRAW(0x7BC),REGRAW(0x7BE),
|
||||
|
||||
// SPDIF interface
|
||||
|
||||
RegWrite_SPDIF<SPDIF_OUT>, // 0x07C0 // SPDIF Out: OFF/'PCM'/Bitstream/Bypass
|
||||
RegWrite_SPDIF<SPDIF_IRQINFO>, // 0x07C2
|
||||
REGRAW(0x7C4),
|
||||
RegWrite_SPDIF<SPDIF_MODE>, // 0x07C6
|
||||
RegWrite_SPDIF<SPDIF_MEDIA>, // 0x07C8 // SPDIF Media: 'CD'/DVD
|
||||
REGRAW(0x7CA),
|
||||
RegWrite_SPDIF<SPDIF_PROTECT>, // 0x07CC // SPDIF Copy Protection
|
||||
|
||||
REGRAW(0x7CE),
|
||||
REGRAW(0x7D0),REGRAW(0x7D2),REGRAW(0x7D4),REGRAW(0x7D6),
|
||||
REGRAW(0x7D8),REGRAW(0x7DA),REGRAW(0x7DC),REGRAW(0x7DE),
|
||||
REGRAW(0x7E0),REGRAW(0x7E2),REGRAW(0x7E4),REGRAW(0x7E6),
|
||||
REGRAW(0x7E8),REGRAW(0x7EA),REGRAW(0x7EC),REGRAW(0x7EE),
|
||||
REGRAW(0x7F0),REGRAW(0x7F2),REGRAW(0x7F4),REGRAW(0x7F6),
|
||||
REGRAW(0x7F8),REGRAW(0x7FA),REGRAW(0x7FC),REGRAW(0x7FE),
|
||||
|
||||
NULL // should be at 0x400! (we assert check it on startup)
|
||||
};
|
||||
|
||||
|
||||
__forceinline void SPU2_FastWrite( u32 rmem, u16 value )
|
||||
{
|
||||
tbl_reg_writes[(rmem&0x7ff)/2]( value );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1202,7 +1440,7 @@ void StartVoices(int core, u32 value)
|
|||
*(u8*)GetMemPtr(thisvc.StartA),*(u8 *)GetMemPtr((thisvc.StartA)+1),
|
||||
thisvc.Pitch,
|
||||
thisvc.Volume.Left.Value>>16,thisvc.Volume.Right.Value>>16,
|
||||
thisvc.ADSR.Reg_ADSR1,thisvc.ADSR.Reg_ADSR2);
|
||||
thisvc.ADSR.regADSR1,thisvc.ADSR.regADSR2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue