SPU2ghz: Bugfixed the update of the ENDX flag; fixes Summer Heat Beach Volleyball. Added afxresmw.h to the SPU2ghz project, so that VS Express folks can (hopefully) compile it now, relatively hassle free.

Reverted the Pg icon back to the Official Pcsx2 "2" icon.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@465 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-02-10 03:20:25 +00:00
parent 2247e97f20
commit 68afc71ba8
9 changed files with 376 additions and 632 deletions

View File

@ -8,7 +8,6 @@
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxresmw.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
@ -1350,7 +1349,7 @@ END
2 TEXTINCLUDE
BEGIN
"#include ""afxresmw.h""\r\0"
"#include ""afxresmw.h\0"
END
3 TEXTINCLUDE
@ -1709,14 +1708,3 @@ END
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -7,7 +7,7 @@
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
#include "afxresmw.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
@ -34,14 +34,12 @@ END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
"#include ""afxresmw.h""\r\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
"\r\0"
END
#endif // APSTUDIO_INVOKED

View File

@ -367,6 +367,7 @@
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="3082"
AdditionalIncludeDirectories=""
/>
<Tool
Name="VCPreLinkEventTool"

View File

@ -0,0 +1,23 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2008 Pcsx2 Team
* Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <windows.h>
#include <winuser.h>
#define IDC_STATIC (-1)

View File

@ -403,297 +403,6 @@ EXPORT_C_(u16) SPU2read(u32 rmem)
return ret;
}
static __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
{
u32 vx=0, vc=0, core=0, omem, mem;
omem=mem=rmem & 0x7FF; //FFFF;
if (mem & 0x400) { omem^=0x400; core=1; }
//else if ((omem >= 0x0000) && (omem < 0x0180)) { // Voice Params
if (omem < 0x0180) { // Voice Params
u32 voice=(omem & 0x1F0) >> 4;
u32 param=(omem & 0xF)>>1;
//FileLog("[%10d] SPU2 write mem %08x (Core %d Voice %d Param %s) value %x\n",Cycles,rmem,core,voice,ParamNames[param],value);
switch (param) {
case 0: //VOLL (Volume L)
if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp
Cores[core].Voices[voice].VolumeL.Mode=(value & 0xF000)>>12;
Cores[core].Voices[voice].VolumeL.Increment=(value & 0x3F);
}
else {
Cores[core].Voices[voice].VolumeL.Mode=0;
Cores[core].Voices[voice].VolumeL.Increment=0;
if(value&0x4000)
value=0x3fff - (value&0x3fff);
Cores[core].Voices[voice].VolumeL.Value=value<<1;
}
Cores[core].Voices[voice].VolumeL.Reg_VOL = value; break;
case 1: //VOLR (Volume R)
if (value & 0x8000) {
Cores[core].Voices[voice].VolumeR.Mode=(value & 0xF000)>>12;
Cores[core].Voices[voice].VolumeR.Increment=(value & 0x3F);
}
else {
Cores[core].Voices[voice].VolumeR.Mode=0;
Cores[core].Voices[voice].VolumeR.Increment=0;
Cores[core].Voices[voice].VolumeR.Value=value<<1;
}
Cores[core].Voices[voice].VolumeR.Reg_VOL = value; break;
case 2: Cores[core].Voices[voice].Pitch=value; break;
case 3: // ADSR1 (Envelope)
Cores[core].Voices[voice].ADSR.Am=(value & 0x8000)>>15;
Cores[core].Voices[voice].ADSR.Ar=(value & 0x7F00)>>8;
Cores[core].Voices[voice].ADSR.Dr=(value & 0xF0)>>4;
Cores[core].Voices[voice].ADSR.Sl=(value & 0xF);
Cores[core].Voices[voice].ADSR.Reg_ADSR1 = value; break;
case 4: // ADSR2 (Envelope)
Cores[core].Voices[voice].ADSR.Sm=(value & 0xE000)>>13;
Cores[core].Voices[voice].ADSR.Sr=(value & 0x1FC0)>>6;
Cores[core].Voices[voice].ADSR.Rm=(value & 0x20)>>5;
Cores[core].Voices[voice].ADSR.Rr=(value & 0x1F);
Cores[core].Voices[voice].ADSR.Reg_ADSR2 = value; break;
case 5:
// [Air] : Mysterious volume set code. Too bad none of my games ever use it.
// (as usual... )
Cores[core].Voices[voice].ADSR.Value = value << 15;
ConLog( "* SPU2: Mysterious ADSR Volume Set to 0x%x", value );
break;
case 6: Cores[core].Voices[voice].VolumeL.Value=value; break;
case 7: Cores[core].Voices[voice].VolumeR.Value=value; break;
jNO_DEFAULT;
}
}
else if ((omem >= 0x01C0) && (omem < 0x02DE)) {
u32 voice =((omem-0x01C0) / 12);
u32 address =((omem-0x01C0) % 12)>>1;
//FileLog("[%10d] SPU2 write mem %08x (Core %d Voice %d Address %s) value %x\n",Cycles,rmem,core,voice,AddressNames[address],value);
switch (address) {
case 0: Cores[core].Voices[voice].StartA=((value & 0x0F) << 16) | (Cores[core].Voices[voice].StartA & 0xFFF8);
#ifndef PUBLIC
DebugCores[core].Voices[voice].lastSetStartA = Cores[core].Voices[voice].StartA;
#endif
break;
case 1: Cores[core].Voices[voice].StartA=(Cores[core].Voices[voice].StartA & 0x0F0000) | (value & 0xFFF8);
#ifndef PUBLIC
DebugCores[core].Voices[voice].lastSetStartA = Cores[core].Voices[voice].StartA;
#endif
//if(core==1) printf(" *** StartA for C%dV%02d set to 0x%05x\n",core,voice,Cores[core].Voices[voice].StartA);
break;
case 2: Cores[core].Voices[voice].LoopStartA=((value & 0x0F) << 16) | (Cores[core].Voices[voice].LoopStartA & 0xFFF8);
Cores[core].Voices[voice].LoopMode=3; break;
case 3: Cores[core].Voices[voice].LoopStartA=(Cores[core].Voices[voice].LoopStartA & 0x0F0000) | (value & 0xFFF8);break;
Cores[core].Voices[voice].LoopMode=3; break;
case 4: Cores[core].Voices[voice].NextA=((value & 0x0F) << 16) | (Cores[core].Voices[voice].NextA & 0xFFF8);
//printf(" *** Warning: C%dV%02d NextA MODIFIED EXTERNALLY!\n",core,voice);
break;
case 5: Cores[core].Voices[voice].NextA=(Cores[core].Voices[voice].NextA & 0x0F0000) | (value & 0xFFF8);
//printf(" *** Warning: C%dV%02d NextA MODIFIED EXTERNALLY!\n",core,voice);
break;
}
}
else
switch(omem) {
case REG_C_ATTR:
RegLog(4,"ATTR",rmem,core,value);
{
int irqe=Cores[core].IRQEnable;
int bit0=Cores[core].AttrBit0;
int bit4=Cores[core].AttrBit4;
if(((value>>15)&1)&&(!Cores[core].CoreEnabled)&&(Cores[core].InitDelay==0)) // on init/reset
{
if(hasPtr)
{
Cores[core].InitDelay=1;
Cores[core].Regs.STATX=0;
}
else
{
CoreReset(core);
}
}
Cores[core].AttrBit0 =(value>> 0) & 0x01; //1 bit
Cores[core].DMABits =(value>> 1) & 0x07; //3 bits
Cores[core].AttrBit4 =(value>> 4) & 0x01; //1 bit
Cores[core].AttrBit5 =(value>> 5) & 0x01; //1 bit
Cores[core].IRQEnable =(value>> 6) & 0x01; //1 bit
Cores[core].FxEnable =(value>> 7) & 0x01; //1 bit
Cores[core].NoiseClk =(value>> 8) & 0x3f; //6 bits
//Cores[core].Mute =(value>>14) & 0x01; //1 bit
Cores[core].Mute=0;
Cores[core].CoreEnabled=(value>>15) & 0x01; //1 bit
Cores[core].Regs.ATTR =value&0x7fff;
if(value&0x000E)
{
ConLog(" * SPU2: Core %d ATTR unknown bits SET! value=%04x\n",core,value);
}
if(Cores[core].AttrBit0!=bit0)
{
ConLog(" * SPU2: ATTR bit 0 set to %d\n",Cores[core].AttrBit0);
}
if(Cores[core].IRQEnable!=irqe)
{
ConLog(" * SPU2: IRQ %s\n",((Cores[core].IRQEnable==0)?"disabled":"enabled"));
if(!Cores[core].IRQEnable)
Spdif.Info=0;
}
}
break;
case REG_S_PMON:
RegLog(1,"PMON0",rmem,core,value);
vx=2; for (vc=1;vc<16;vc++) { Cores[core].Voices[vc].Modulated=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.PMON = (Cores[core].Regs.PMON & 0xFFFF0000) | value;
break;
case (REG_S_PMON + 2):
RegLog(1,"PMON1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].Modulated=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.PMON = (Cores[core].Regs.PMON & 0xFFFF) | (value << 16);
break;
case REG_S_NON:
RegLog(1,"NON0",rmem,core,value);
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].Noise=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.NON = (Cores[core].Regs.NON & 0xFFFF0000) | value;
break;
case (REG_S_NON + 2):
RegLog(1,"NON1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].Noise=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.NON = (Cores[core].Regs.NON & 0xFFFF) | (value << 16);
break;
case REG_S_VMIXL:
RegLog(1,"VMIXL0",rmem,core,value);
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].DryL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXL = (Cores[core].Regs.VMIXL & 0xFFFF0000) | value;
case (REG_S_VMIXL + 2):
RegLog(1,"VMIXL1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].DryL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXL = (Cores[core].Regs.VMIXL & 0xFFFF) | (value << 16);
case REG_S_VMIXEL:
RegLog(1,"VMIXEL0",rmem,core,value);
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].WetL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXEL = (Cores[core].Regs.VMIXEL & 0xFFFF0000) | value;
break;
case (REG_S_VMIXEL + 2):
RegLog(1,"VMIXEL1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].WetL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXEL = (Cores[core].Regs.VMIXEL & 0xFFFF) | (value << 16);
break;
case REG_S_VMIXR:
RegLog(1,"VMIXR0",rmem,core,value);
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].DryR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXR = (Cores[core].Regs.VMIXR & 0xFFFF0000) | value;
break;
case (REG_S_VMIXR + 2):
RegLog(1,"VMIXR1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].DryR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXR = (Cores[core].Regs.VMIXR & 0xFFFF) | (value << 16);
break;
case REG_S_VMIXER:
RegLog(1,"VMIXER0",rmem,core,value);
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].WetR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXER = (Cores[core].Regs.VMIXER & 0xFFFF0000) | value;
break;
case (REG_S_VMIXER + 2):
RegLog(1,"VMIXER1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].WetR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXER = (Cores[core].Regs.VMIXER & 0xFFFF) | (value << 16);
break;
case REG_P_MMIX:
RegLog(1,"MMIX",rmem,core,value);
vx=value;
if (core == 0) vx&=0xFF0;
Cores[core].ExtWetR=(vx & 0x001);
Cores[core].ExtWetL=(vx & 0x002)>>1;
Cores[core].ExtDryR=(vx & 0x004)>>2;
Cores[core].ExtDryL=(vx & 0x008)>>3;
Cores[core].InpWetR=(vx & 0x010)>>4;
Cores[core].InpWetL=(vx & 0x020)>>5;
Cores[core].InpDryR=(vx & 0x040)>>6;
Cores[core].InpDryL=(vx & 0x080)>>7;
Cores[core].SndWetR=(vx & 0x100)>>8;
Cores[core].SndWetL=(vx & 0x200)>>9;
Cores[core].SndDryR=(vx & 0x400)>>10;
Cores[core].SndDryL=(vx & 0x800)>>11;
Cores[core].Regs.MMIX = value;
break;
case (REG_S_KON + 2):
RegLog(2,"KON1",rmem,core,value);
StartVoices(core,((u32)value)<<16);
break;
case REG_S_KON:
RegLog(2,"KON0",rmem,core,value);
StartVoices(core,((u32)value));
break;
case (REG_S_KOFF + 2):
RegLog(2,"KOFF1",rmem,core,value);
StopVoices(core,((u32)value)<<16);
break;
case REG_S_KOFF:
RegLog(2,"KOFF0",rmem,core,value);
StopVoices(core,((u32)value));
break;
case REG_S_ENDX:
//ConLog(" * SPU2: Core %d ENDX cleared!\n",core);
RegLog(2,"ENDX0",rmem,core,value);
Cores[core].Regs.ENDX&=0x00FF0000; break;
case (REG_S_ENDX + 2):
//ConLog(" * SPU2: Core %d ENDX cleared!\n",core);
RegLog(2,"ENDX1",rmem,core,value);
Cores[core].Regs.ENDX&=0xFFFF; break;
case REG_P_MVOLL:
RegLog(1,"MVOLL",rmem,core,value);
if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp
Cores[core].MasterL.Mode=(value & 0xE000)/0x2000;
Cores[core].MasterL.Increment=(value & 0x3F) | ((value & 0x800)/0x10);
}
else {
Cores[core].MasterL.Mode=0;
Cores[core].MasterL.Increment=0;
Cores[core].MasterL.Value=value;
}
Cores[core].MasterL.Reg_VOL=value;
break;
case REG_P_MVOLR:
RegLog(1,"MVOLR",rmem,core,value);
if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp
Cores[core].MasterR.Mode=(value & 0xE000)/0x2000;
Cores[core].MasterR.Increment=(value & 0x3F) | ((value & 0x800)/0x10);
}
else {
Cores[core].MasterR.Mode=0;
Cores[core].MasterR.Increment=0;
Cores[core].MasterR.Value=value;
}
Cores[core].MasterR.Reg_VOL=value;
break;
case REG_S_ADMAS:
RegLog(3,"ADMAS",rmem,core,value);
//ConLog(" * SPU2: Core %d AutoDMAControl set to %d (%d)\n",core,value, Cycles);
Cores[core].AutoDMACtrl=value;
if(value==0)
{
Cores[core].AdmaInProgress=0;
}
break;
default:
*(regtable[mem>>1])=value;
break;
}
SPU2writeLog(mem,value);
if ((mem>=0x07C0) && (mem<0x07CE))
{
UpdateSpdifMode();
}
}
EXPORT_C_(void) SPU2write(u32 rmem, u16 value)
{
#ifdef S2R_ENABLE

View File

@ -228,9 +228,10 @@ static void __forceinline __fastcall GetNextDataBuffered( V_Core& thiscore, V_Vo
{
if(vc.LoopFlags & XAFLAG_LOOP_END)
{
if(vc.LoopFlags & XAFLAG_LOOP)
if( vc.LoopFlags & XAFLAG_LOOP )
{
vc.NextA=vc.LoopStartA;
thiscore.Regs.ENDX|=1<<voice;
}
else
{
@ -297,9 +298,6 @@ static void __forceinline __fastcall GetNextDataBuffered( V_Core& thiscore, V_Vo
vc.SCurrent = 0;
if( (vc.LoopFlags & XAFLAG_LOOP_START) && !vc.LoopMode )
vc.LoopStartA = vc.NextA;
// [Air] : Increment will get called below (change made to avoid needless code cache clutter)
//IncrementNextA( thiscore, vc );
}
IncrementNextA( thiscore, vc );

View File

@ -19,7 +19,44 @@
#include "spu2.h"
#include "regtable.h"
u16* regtable[] =
// 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)
#define PVCP(c,v,p) \
PCORE(c,Voices[v].##p)
#define PVC(c,v) \
PVCP(c,v,VolumeL.Reg_VOL), \
PVCP(c,v,VolumeR.Reg_VOL), \
PVCP(c,v,Pitch), \
PVCP(c,v,ADSR.Reg_ADSR1), \
PVCP(c,v,ADSR.Reg_ADSR2), \
PVCP(c,v,ADSR.Value)+1, \
PVCP(c,v,VolumeL.Value), \
PVCP(c,v,VolumeR.Value)
#define PVCA(c,v) \
PVCP(c,v,StartA)+1, \
PVCP(c,v,StartA), \
PVCP(c,v,LoopStartA)+1, \
PVCP(c,v,LoopStartA), \
PVCP(c,v,NextA)+1, \
PVCP(c,v,NextA)
#define PRAW(a) \
((u16*)NULL)
#define PREVB_REG(c,n) \
PCORE(c,Revb.##n)+1, \
PCORE(c,Revb.##n)
#pragma pack(1)
u16* regtable[0x800] =
{
// 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),
@ -274,3 +311,4 @@ u16* regtable[] =
U16P(zero)
};
#pragma pack()

View File

@ -21,40 +21,9 @@
#define U16P(x) ((u16*)&(x))
#define PCORE(c,p) \
U16P(Cores[c].##p)
#define PVCP(c,v,p) \
PCORE(c,Voices[v].##p)
#define PVC(c,v) \
PVCP(c,v,VolumeL.Reg_VOL), \
PVCP(c,v,VolumeR.Reg_VOL), \
PVCP(c,v,Pitch), \
PVCP(c,v,ADSR.Reg_ADSR1), \
PVCP(c,v,ADSR.Reg_ADSR2), \
PVCP(c,v,ADSR.Value)+1, \
PVCP(c,v,VolumeL.Value), \
PVCP(c,v,VolumeR.Value)
#define PVCA(c,v) \
PVCP(c,v,StartA)+1, \
PVCP(c,v,StartA), \
PVCP(c,v,LoopStartA)+1, \
PVCP(c,v,LoopStartA), \
PVCP(c,v,NextA)+1, \
PVCP(c,v,NextA)
#define PRAW(a) \
((u16*)NULL)
#define PREVB_REG(c,n) \
PCORE(c,Revb.##n)+1, \
PCORE(c,Revb.##n)
// Yay! Global namespace pollution 101!
static const u16 zero=0;
extern const u16 zero;
extern u16* regtable[];
extern u16* regtable[0x800];
#endif

View File

@ -744,8 +744,8 @@ void RegWriteLog(u32 core,u16 value);
void SPU2writeLog(u32 rmem, u16 value)
{
#ifndef PUBLIC
u32 vx=0, vc=0, core=0, omem=rmem, mem=rmem&0x7FF;
omem=mem=mem&0x7FF; //FFFF;
u32 vx=0, vc=0, core=0, omem, mem;
omem=mem=rmem & 0x7FF; //FFFF;
if (mem & 0x400) { omem^=0x400; core=1; }
/*
@ -760,7 +760,8 @@ void SPU2writeLog(u32 rmem, u16 value)
FileLog("[%10d] SPU2 write mem %08x (Core %d Voice %d Address %s) value %x\n",Cycles,rmem,core,voice,AddressNames[address],value);
}
*/
if ((mem >= 0x0760) && (mem < 0x07b0)) {
if ((mem >= 0x0760) && (mem < 0x07b0))
{
omem=mem; core=0;
if (mem >= 0x0788) {omem-=0x28; core=1;}
switch(omem) {
@ -817,135 +818,139 @@ void SPU2writeLog(u32 rmem, u16 value)
UpdateSpdifMode();
}
else
switch(omem) {
case REG_C_ATTR:
RegLog(4,"ATTR",rmem,core,value);
break;
case REG_S_PMON:
RegLog(1,"PMON0",rmem,core,value);
break;
case (REG_S_PMON + 2):
RegLog(1,"PMON1",rmem,core,value);
break;
case REG_S_NON:
RegLog(1,"NON0",rmem,core,value);
break;
case (REG_S_NON + 2):
RegLog(1,"NON1",rmem,core,value);
break;
case REG_S_VMIXL:
RegLog(1,"VMIXL0",rmem,core,value);
case (REG_S_VMIXL + 2):
RegLog(1,"VMIXL1",rmem,core,value);
break;
case REG_S_VMIXEL:
RegLog(1,"VMIXEL0",rmem,core,value);
break;
case (REG_S_VMIXEL + 2):
RegLog(1,"VMIXEL1",rmem,core,value);
break;
case REG_S_VMIXR:
RegLog(1,"VMIXR0",rmem,core,value);
break;
case (REG_S_VMIXR + 2):
RegLog(1,"VMIXR1",rmem,core,value);
break;
case REG_S_VMIXER:
RegLog(1,"VMIXER0",rmem,core,value);
break;
case (REG_S_VMIXER + 2):
RegLog(1,"VMIXER1",rmem,core,value);
break;
case REG_P_MMIX:
RegLog(1,"MMIX",rmem,core,value);
break;
case REG_A_IRQA:
RegLog(2,"IRQAH",rmem,core,value);
break;
case (REG_A_IRQA + 2):
RegLog(2,"IRQAL",rmem,core,value);
break;
case (REG_S_KON + 2):
RegLog(2,"KON1",rmem,core,value);
break;
case REG_S_KON:
RegLog(2,"KON0",rmem,core,value);
break;
case (REG_S_KOFF + 2):
RegLog(2,"KOFF1",rmem,core,value);
break;
case REG_S_KOFF:
RegLog(2,"KOFF0",rmem,core,value);
break;
case REG_A_TSA:
RegLog(2,"TSAH",rmem,core,value);
break;
case (REG_A_TSA + 2):
RegLog(2,"TSAL",rmem,core,value);
break;
case REG_S_ENDX:
//ConLog(" * SPU2: Core %d ENDX cleared!\n",core);
RegLog(2,"ENDX0",rmem,core,value);
break;
case (REG_S_ENDX + 2):
//ConLog(" * SPU2: Core %d ENDX cleared!\n",core);
RegLog(2,"ENDX1",rmem,core,value);
break;
case REG_P_MVOLL:
RegLog(1,"MVOLL",rmem,core,value);
break;
case REG_P_MVOLR:
RegLog(1,"MVOLR",rmem,core,value);
break;
case REG_S_ADMAS:
RegLog(3,"ADMAS",rmem,core,value);
ConLog(" * SPU2: Core %d AutoDMAControl set to %d\n",core,value);
break;
case REG_P_STATX:
RegLog(3,"STATX",rmem,core,value);
break;
case REG_A_ESA:
RegLog(1,"ESAH",rmem,core,value);
break;
case (REG_A_ESA + 2):
RegLog(1,"ESAL",rmem,core,value);
break;
case REG_A_EEA:
RegLog(1,"EEAH",rmem,core,value);
break;
{
switch(omem)
{
case REG_C_ATTR:
RegLog(4,"ATTR",rmem,core,value);
break;
case REG_S_PMON:
RegLog(1,"PMON0",rmem,core,value);
break;
case (REG_S_PMON + 2):
RegLog(1,"PMON1",rmem,core,value);
break;
case REG_S_NON:
RegLog(1,"NON0",rmem,core,value);
break;
case (REG_S_NON + 2):
RegLog(1,"NON1",rmem,core,value);
break;
case REG_S_VMIXL:
RegLog(1,"VMIXL0",rmem,core,value);
case (REG_S_VMIXL + 2):
RegLog(1,"VMIXL1",rmem,core,value);
break;
case REG_S_VMIXEL:
RegLog(1,"VMIXEL0",rmem,core,value);
break;
case (REG_S_VMIXEL + 2):
RegLog(1,"VMIXEL1",rmem,core,value);
break;
case REG_S_VMIXR:
RegLog(1,"VMIXR0",rmem,core,value);
break;
case (REG_S_VMIXR + 2):
RegLog(1,"VMIXR1",rmem,core,value);
break;
case REG_S_VMIXER:
RegLog(1,"VMIXER0",rmem,core,value);
break;
case (REG_S_VMIXER + 2):
RegLog(1,"VMIXER1",rmem,core,value);
break;
case REG_P_MMIX:
RegLog(1,"MMIX",rmem,core,value);
break;
case REG_A_IRQA:
RegLog(2,"IRQAH",rmem,core,value);
break;
case (REG_A_IRQA + 2):
RegLog(2,"IRQAL",rmem,core,value);
break;
case (REG_S_KON + 2):
RegLog(2,"KON1",rmem,core,value);
break;
case REG_S_KON:
RegLog(2,"KON0",rmem,core,value);
break;
case (REG_S_KOFF + 2):
RegLog(2,"KOFF1",rmem,core,value);
break;
case REG_S_KOFF:
RegLog(2,"KOFF0",rmem,core,value);
break;
case REG_A_TSA:
RegLog(2,"TSAH",rmem,core,value);
break;
case (REG_A_TSA + 2):
RegLog(2,"TSAL",rmem,core,value);
break;
case REG_S_ENDX:
//ConLog(" * SPU2: Core %d ENDX cleared!\n",core);
RegLog(2,"ENDX0",rmem,core,value);
break;
case (REG_S_ENDX + 2):
//ConLog(" * SPU2: Core %d ENDX cleared!\n",core);
RegLog(2,"ENDX1",rmem,core,value);
break;
case REG_P_MVOLL:
RegLog(1,"MVOLL",rmem,core,value);
break;
case REG_P_MVOLR:
RegLog(1,"MVOLR",rmem,core,value);
break;
case REG_S_ADMAS:
RegLog(3,"ADMAS",rmem,core,value);
ConLog(" * SPU2: Core %d AutoDMAControl set to %d\n",core,value);
break;
case REG_P_STATX:
RegLog(3,"STATX",rmem,core,value);
break;
case REG_A_ESA:
RegLog(1,"ESAH",rmem,core,value);
break;
case (REG_A_ESA + 2):
RegLog(1,"ESAL",rmem,core,value);
break;
case REG_A_EEA:
RegLog(1,"EEAH",rmem,core,value);
break;
#define LOG_REVB_REG(n,t) \
case R_##n: \
RegLog(2,t "H",mem,core,value); \
break; \
case (R_##n + 2): \
RegLog(2,t "L",mem,core,value); \
break;
#define LOG_REVB_REG(n,t) \
case R_##n: \
RegLog(2,t "H",mem,core,value); \
break; \
case (R_##n + 2): \
RegLog(2,t "L",mem,core,value); \
break;
LOG_REVB_REG(FB_SRC_A,"FB_SRC_A")
LOG_REVB_REG(FB_SRC_B,"FB_SRC_B")
LOG_REVB_REG(IIR_SRC_A0,"IIR_SRC_A0")
LOG_REVB_REG(IIR_SRC_A1,"IIR_SRC_A1")
LOG_REVB_REG(IIR_SRC_B1,"IIR_SRC_B1")
LOG_REVB_REG(IIR_SRC_B0,"IIR_SRC_B0")
LOG_REVB_REG(IIR_DEST_A0,"IIR_DEST_A0")
LOG_REVB_REG(IIR_DEST_A1,"IIR_DEST_A1")
LOG_REVB_REG(IIR_DEST_B0,"IIR_DEST_B0")
LOG_REVB_REG(IIR_DEST_B1,"IIR_DEST_B1")
LOG_REVB_REG(ACC_SRC_A0,"ACC_SRC_A0")
LOG_REVB_REG(ACC_SRC_A1,"ACC_SRC_A1")
LOG_REVB_REG(ACC_SRC_B0,"ACC_SRC_B0")
LOG_REVB_REG(ACC_SRC_B1,"ACC_SRC_B1")
LOG_REVB_REG(ACC_SRC_C0,"ACC_SRC_C0")
LOG_REVB_REG(ACC_SRC_C1,"ACC_SRC_C1")
LOG_REVB_REG(ACC_SRC_D0,"ACC_SRC_D0")
LOG_REVB_REG(ACC_SRC_D1,"ACC_SRC_D1")
LOG_REVB_REG(MIX_DEST_A0,"MIX_DEST_A0")
LOG_REVB_REG(MIX_DEST_A1,"MIX_DEST_A1")
LOG_REVB_REG(MIX_DEST_B0,"MIX_DEST_B0")
LOG_REVB_REG(MIX_DEST_B1,"MIX_DEST_B1")
LOG_REVB_REG(FB_SRC_A,"FB_SRC_A")
LOG_REVB_REG(FB_SRC_B,"FB_SRC_B")
LOG_REVB_REG(IIR_SRC_A0,"IIR_SRC_A0")
LOG_REVB_REG(IIR_SRC_A1,"IIR_SRC_A1")
LOG_REVB_REG(IIR_SRC_B1,"IIR_SRC_B1")
LOG_REVB_REG(IIR_SRC_B0,"IIR_SRC_B0")
LOG_REVB_REG(IIR_DEST_A0,"IIR_DEST_A0")
LOG_REVB_REG(IIR_DEST_A1,"IIR_DEST_A1")
LOG_REVB_REG(IIR_DEST_B0,"IIR_DEST_B0")
LOG_REVB_REG(IIR_DEST_B1,"IIR_DEST_B1")
LOG_REVB_REG(ACC_SRC_A0,"ACC_SRC_A0")
LOG_REVB_REG(ACC_SRC_A1,"ACC_SRC_A1")
LOG_REVB_REG(ACC_SRC_B0,"ACC_SRC_B0")
LOG_REVB_REG(ACC_SRC_B1,"ACC_SRC_B1")
LOG_REVB_REG(ACC_SRC_C0,"ACC_SRC_C0")
LOG_REVB_REG(ACC_SRC_C1,"ACC_SRC_C1")
LOG_REVB_REG(ACC_SRC_D0,"ACC_SRC_D0")
LOG_REVB_REG(ACC_SRC_D1,"ACC_SRC_D1")
LOG_REVB_REG(MIX_DEST_A0,"MIX_DEST_A0")
LOG_REVB_REG(MIX_DEST_A1,"MIX_DEST_A1")
LOG_REVB_REG(MIX_DEST_B0,"MIX_DEST_B0")
LOG_REVB_REG(MIX_DEST_B1,"MIX_DEST_B1")
default: RegLog(2,"UNKNOWN",rmem,core,value); spu2Ru16(mem) = value;
default:
RegLog(2,"UNKNOWN",rmem,core,value); spu2Ru16(mem) = value;
}
}
#endif
}
@ -956,31 +961,42 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
omem=mem=rmem & 0x7FF; //FFFF;
if (mem & 0x400) { omem^=0x400; core=1; }
//else if ((omem >= 0x0000) && (omem < 0x0180)) { // Voice Params
if (omem < 0x0180) { // Voice Params
u32 voice=(omem & 0x1F0) >> 4;
u32 param=(omem & 0xF)>>1;
SPU2writeLog(mem,value);
if (omem < 0x0180) // Voice Params
{
const u32 voice = (omem & 0x1F0) >> 4;
const u32 param = (omem & 0xF)>>1;
//FileLog("[%10d] SPU2 write mem %08x (Core %d Voice %d Param %s) value %x\n",Cycles,rmem,core,voice,ParamNames[param],value);
switch (param) {
switch (param)
{
case 0: //VOLL (Volume L)
if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp
if (value & 0x8000) // +Lin/-Lin/+Exp/-Exp
{
Cores[core].Voices[voice].VolumeL.Mode=(value & 0xF000)>>12;
Cores[core].Voices[voice].VolumeL.Increment=(value & 0x3F);
}
else {
else
{
Cores[core].Voices[voice].VolumeL.Mode=0;
Cores[core].Voices[voice].VolumeL.Increment=0;
if(value&0x4000)
value=0x3fff - (value&0x3fff);
Cores[core].Voices[voice].VolumeL.Value=value<<1;
}
Cores[core].Voices[voice].VolumeL.Reg_VOL = value; break;
Cores[core].Voices[voice].VolumeL.Reg_VOL = value;
break;
case 1: //VOLR (Volume R)
if (value & 0x8000) {
if (value & 0x8000)
{
Cores[core].Voices[voice].VolumeR.Mode=(value & 0xF000)>>12;
Cores[core].Voices[voice].VolumeR.Increment=(value & 0x3F);
}
else {
else
{
Cores[core].Voices[voice].VolumeR.Mode=0;
Cores[core].Voices[voice].VolumeR.Increment=0;
Cores[core].Voices[voice].VolumeR.Value=value<<1;
@ -1011,9 +1027,10 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
jNO_DEFAULT;
}
}
else if ((omem >= 0x01C0) && (omem < 0x02DE)) {
u32 voice =((omem-0x01C0) / 12);
u32 address =((omem-0x01C0) % 12)>>1;
else if ((omem >= 0x01C0) && (omem < 0x02DE))
{
const u32 voice =((omem-0x01C0) / 12);
const u32 address =((omem-0x01C0) % 12)>>1;
//FileLog("[%10d] SPU2 write mem %08x (Core %d Voice %d Address %s) value %x\n",Cycles,rmem,core,voice,AddressNames[address],value);
switch (address) {
@ -1041,9 +1058,10 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
}
}
else
switch(omem) {
case REG_C_ATTR:
RegLog(4,"ATTR",rmem,core,value);
{
switch(omem)
{
case REG_C_ATTR:
{
int irqe=Cores[core].IRQEnable;
int bit0=Cores[core].AttrBit0;
@ -1091,150 +1109,152 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
}
}
break;
case REG_S_PMON:
RegLog(1,"PMON0",rmem,core,value);
vx=2; for (vc=1;vc<16;vc++) { Cores[core].Voices[vc].Modulated=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.PMON = (Cores[core].Regs.PMON & 0xFFFF0000) | value;
break;
case (REG_S_PMON + 2):
RegLog(1,"PMON1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].Modulated=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.PMON = (Cores[core].Regs.PMON & 0xFFFF) | (value << 16);
break;
case REG_S_NON:
RegLog(1,"NON0",rmem,core,value);
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].Noise=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.NON = (Cores[core].Regs.NON & 0xFFFF0000) | value;
break;
case (REG_S_NON + 2):
RegLog(1,"NON1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].Noise=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.NON = (Cores[core].Regs.NON & 0xFFFF) | (value << 16);
break;
case REG_S_VMIXL:
RegLog(1,"VMIXL0",rmem,core,value);
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].DryL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXL = (Cores[core].Regs.VMIXL & 0xFFFF0000) | value;
case (REG_S_VMIXL + 2):
RegLog(1,"VMIXL1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].DryL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXL = (Cores[core].Regs.VMIXL & 0xFFFF) | (value << 16);
case REG_S_VMIXEL:
RegLog(1,"VMIXEL0",rmem,core,value);
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].WetL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXEL = (Cores[core].Regs.VMIXEL & 0xFFFF0000) | value;
break;
case (REG_S_VMIXEL + 2):
RegLog(1,"VMIXEL1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].WetL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXEL = (Cores[core].Regs.VMIXEL & 0xFFFF) | (value << 16);
break;
case REG_S_VMIXR:
RegLog(1,"VMIXR0",rmem,core,value);
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].DryR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXR = (Cores[core].Regs.VMIXR & 0xFFFF0000) | value;
break;
case (REG_S_VMIXR + 2):
RegLog(1,"VMIXR1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].DryR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXR = (Cores[core].Regs.VMIXR & 0xFFFF) | (value << 16);
break;
case REG_S_VMIXER:
RegLog(1,"VMIXER0",rmem,core,value);
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].WetR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXER = (Cores[core].Regs.VMIXER & 0xFFFF0000) | value;
break;
case (REG_S_VMIXER + 2):
RegLog(1,"VMIXER1",rmem,core,value);
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].WetR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXER = (Cores[core].Regs.VMIXER & 0xFFFF) | (value << 16);
break;
case REG_P_MMIX:
RegLog(1,"MMIX",rmem,core,value);
vx=value;
if (core == 0) vx&=0xFF0;
Cores[core].ExtWetR=(vx & 0x001);
Cores[core].ExtWetL=(vx & 0x002)>>1;
Cores[core].ExtDryR=(vx & 0x004)>>2;
Cores[core].ExtDryL=(vx & 0x008)>>3;
Cores[core].InpWetR=(vx & 0x010)>>4;
Cores[core].InpWetL=(vx & 0x020)>>5;
Cores[core].InpDryR=(vx & 0x040)>>6;
Cores[core].InpDryL=(vx & 0x080)>>7;
Cores[core].SndWetR=(vx & 0x100)>>8;
Cores[core].SndWetL=(vx & 0x200)>>9;
Cores[core].SndDryR=(vx & 0x400)>>10;
Cores[core].SndDryL=(vx & 0x800)>>11;
Cores[core].Regs.MMIX = value;
break;
case (REG_S_KON + 2):
RegLog(2,"KON1",rmem,core,value);
StartVoices(core,((u32)value)<<16);
break;
case REG_S_KON:
RegLog(2,"KON0",rmem,core,value);
StartVoices(core,((u32)value));
break;
case (REG_S_KOFF + 2):
RegLog(2,"KOFF1",rmem,core,value);
StopVoices(core,((u32)value)<<16);
break;
case REG_S_KOFF:
RegLog(2,"KOFF0",rmem,core,value);
StopVoices(core,((u32)value));
break;
case REG_S_ENDX:
//ConLog(" * SPU2: Core %d ENDX cleared!\n",core);
RegLog(2,"ENDX0",rmem,core,value);
Cores[core].Regs.ENDX&=0x00FF0000; break;
case (REG_S_ENDX + 2):
//ConLog(" * SPU2: Core %d ENDX cleared!\n",core);
RegLog(2,"ENDX1",rmem,core,value);
Cores[core].Regs.ENDX&=0xFFFF; break;
case REG_P_MVOLL:
RegLog(1,"MVOLL",rmem,core,value);
if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp
Cores[core].MasterL.Mode=(value & 0xE000)/0x2000;
Cores[core].MasterL.Increment=(value & 0x3F) | ((value & 0x800)/0x10);
}
else {
Cores[core].MasterL.Mode=0;
Cores[core].MasterL.Increment=0;
Cores[core].MasterL.Value=value;
}
Cores[core].MasterL.Reg_VOL=value;
break;
case REG_P_MVOLR:
RegLog(1,"MVOLR",rmem,core,value);
if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp
Cores[core].MasterR.Mode=(value & 0xE000)/0x2000;
Cores[core].MasterR.Increment=(value & 0x3F) | ((value & 0x800)/0x10);
}
else {
Cores[core].MasterR.Mode=0;
Cores[core].MasterR.Increment=0;
Cores[core].MasterR.Value=value;
}
Cores[core].MasterR.Reg_VOL=value;
break;
case REG_S_ADMAS:
RegLog(3,"ADMAS",rmem,core,value);
//ConLog(" * SPU2: Core %d AutoDMAControl set to %d (%d)\n",core,value, Cycles);
Cores[core].AutoDMACtrl=value;
return;
if(value==0)
{
Cores[core].AdmaInProgress=0;
}
break;
case REG_S_PMON:
vx=2; for (vc=1;vc<16;vc++) { Cores[core].Voices[vc].Modulated=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.PMON = (Cores[core].Regs.PMON & 0xFFFF0000) | value;
return;
default:
*(regtable[mem>>1])=value;
case (REG_S_PMON + 2):
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].Modulated=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.PMON = (Cores[core].Regs.PMON & 0xFFFF) | (value << 16);
return;
case REG_S_NON:
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].Noise=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.NON = (Cores[core].Regs.NON & 0xFFFF0000) | value;
return;
case (REG_S_NON + 2):
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].Noise=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.NON = (Cores[core].Regs.NON & 0xFFFF) | (value << 16);
return;
case REG_S_VMIXL:
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].DryL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXL = (Cores[core].Regs.VMIXL & 0xFFFF0000) | value;
return;
case (REG_S_VMIXL + 2):
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].DryL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXL = (Cores[core].Regs.VMIXL & 0xFFFF) | (value << 16);
return;
case REG_S_VMIXEL:
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].WetL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXEL = (Cores[core].Regs.VMIXEL & 0xFFFF0000) | value;
return;
case (REG_S_VMIXEL + 2):
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].WetL=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXEL = (Cores[core].Regs.VMIXEL & 0xFFFF) | (value << 16);
return;
case REG_S_VMIXR:
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].DryR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXR = (Cores[core].Regs.VMIXR & 0xFFFF0000) | value;
return;
case (REG_S_VMIXR + 2):
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].DryR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXR = (Cores[core].Regs.VMIXR & 0xFFFF) | (value << 16);
return;
case REG_S_VMIXER:
vx=1; for (vc=0;vc<16;vc++) { Cores[core].Voices[vc].WetR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXER = (Cores[core].Regs.VMIXER & 0xFFFF0000) | value;
return;
case (REG_S_VMIXER + 2):
vx=1; for (vc=16;vc<24;vc++) { Cores[core].Voices[vc].WetR=(s8)((value & vx)/vx); vx<<=1; }
Cores[core].Regs.VMIXER = (Cores[core].Regs.VMIXER & 0xFFFF) | (value << 16);
return;
case REG_P_MMIX:
vx=value;
if (core == 0) vx&=0xFF0;
Cores[core].ExtWetR=(vx & 0x001);
Cores[core].ExtWetL=(vx & 0x002)>>1;
Cores[core].ExtDryR=(vx & 0x004)>>2;
Cores[core].ExtDryL=(vx & 0x008)>>3;
Cores[core].InpWetR=(vx & 0x010)>>4;
Cores[core].InpWetL=(vx & 0x020)>>5;
Cores[core].InpDryR=(vx & 0x040)>>6;
Cores[core].InpDryL=(vx & 0x080)>>7;
Cores[core].SndWetR=(vx & 0x100)>>8;
Cores[core].SndWetL=(vx & 0x200)>>9;
Cores[core].SndDryR=(vx & 0x400)>>10;
Cores[core].SndDryL=(vx & 0x800)>>11;
Cores[core].Regs.MMIX = value;
return;
case (REG_S_KON + 2):
StartVoices(core,((u32)value)<<16);
return;
case REG_S_KON:
StartVoices(core,((u32)value));
return;
case (REG_S_KOFF + 2):
StopVoices(core,((u32)value)<<16);
return;
case REG_S_KOFF:
StopVoices(core,((u32)value));
return;
case REG_S_ENDX:
Cores[core].Regs.ENDX&=0x00FF0000;
return;
case (REG_S_ENDX + 2):
Cores[core].Regs.ENDX&=0xFFFF;
return;
case REG_P_MVOLL:
if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp
Cores[core].MasterL.Mode=(value & 0xE000)/0x2000;
Cores[core].MasterL.Increment=(value & 0x3F) | ((value & 0x800)/0x10);
}
else {
Cores[core].MasterL.Mode=0;
Cores[core].MasterL.Increment=0;
Cores[core].MasterL.Value=value;
}
Cores[core].MasterL.Reg_VOL=value;
return;
case REG_P_MVOLR:
if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp
Cores[core].MasterR.Mode=(value & 0xE000)/0x2000;
Cores[core].MasterR.Increment=(value & 0x3F) | ((value & 0x800)/0x10);
}
else {
Cores[core].MasterR.Mode=0;
Cores[core].MasterR.Increment=0;
Cores[core].MasterR.Value=value;
}
Cores[core].MasterR.Reg_VOL=value;
return;
case REG_S_ADMAS:
//ConLog(" * SPU2: Core %d AutoDMAControl set to %d (%d)\n",core,value, Cycles);
Cores[core].AutoDMACtrl=value;
if(value==0)
{
Cores[core].AdmaInProgress=0;
}
return;
default:
*(regtable[mem>>1]) = value;
break;
}
}
SPU2writeLog(mem,value);
if ((mem>=0x07C0) && (mem<0x07CE))
{
UpdateSpdifMode();
@ -1248,7 +1268,7 @@ void VoiceStart(int core,int vc)
{
if(Cores[core].Voices[vc].StartA&7)
{
fprintf( stderr, " *** Missaligned StartA %05x!\n",Cores[core].Voices[vc].StartA);
fprintf( stderr, " *** Misaligned StartA %05x!\n",Cores[core].Voices[vc].StartA);
Cores[core].Voices[vc].StartA=(Cores[core].Voices[vc].StartA+0xFFFF8)+0x8;
}