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

View File

@ -367,6 +367,7 @@
Name="VCResourceCompilerTool" Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG" PreprocessorDefinitions="_DEBUG"
Culture="3082" Culture="3082"
AdditionalIncludeDirectories=""
/> />
<Tool <Tool
Name="VCPreLinkEventTool" 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; 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) EXPORT_C_(void) SPU2write(u32 rmem, u16 value)
{ {
#ifdef S2R_ENABLE #ifdef S2R_ENABLE

View File

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

View File

@ -19,7 +19,44 @@
#include "spu2.h" #include "spu2.h"
#include "regtable.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 // 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), 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) U16P(zero)
}; };
#pragma pack()

View File

@ -21,40 +21,9 @@
#define U16P(x) ((u16*)&(x)) #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! // Yay! Global namespace pollution 101!
static const u16 zero=0; extern const u16 zero;
extern u16* regtable[]; extern u16* regtable[0x800];
#endif #endif

View File

@ -744,8 +744,8 @@ void RegWriteLog(u32 core,u16 value);
void SPU2writeLog(u32 rmem, u16 value) void SPU2writeLog(u32 rmem, u16 value)
{ {
#ifndef PUBLIC #ifndef PUBLIC
u32 vx=0, vc=0, core=0, omem=rmem, mem=rmem&0x7FF; u32 vx=0, vc=0, core=0, omem, mem;
omem=mem=mem&0x7FF; //FFFF; omem=mem=rmem & 0x7FF; //FFFF;
if (mem & 0x400) { omem^=0x400; core=1; } 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); 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; omem=mem; core=0;
if (mem >= 0x0788) {omem-=0x28; core=1;} if (mem >= 0x0788) {omem-=0x28; core=1;}
switch(omem) { switch(omem) {
@ -817,7 +818,9 @@ void SPU2writeLog(u32 rmem, u16 value)
UpdateSpdifMode(); UpdateSpdifMode();
} }
else else
switch(omem) { {
switch(omem)
{
case REG_C_ATTR: case REG_C_ATTR:
RegLog(4,"ATTR",rmem,core,value); RegLog(4,"ATTR",rmem,core,value);
break; break;
@ -945,7 +948,9 @@ void SPU2writeLog(u32 rmem, u16 value)
LOG_REVB_REG(MIX_DEST_B0,"MIX_DEST_B0") LOG_REVB_REG(MIX_DEST_B0,"MIX_DEST_B0")
LOG_REVB_REG(MIX_DEST_B1,"MIX_DEST_B1") 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 #endif
} }
@ -956,31 +961,42 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
omem=mem=rmem & 0x7FF; //FFFF; omem=mem=rmem & 0x7FF; //FFFF;
if (mem & 0x400) { omem^=0x400; core=1; } if (mem & 0x400) { omem^=0x400; core=1; }
//else if ((omem >= 0x0000) && (omem < 0x0180)) { // Voice Params SPU2writeLog(mem,value);
if (omem < 0x0180) { // Voice Params
u32 voice=(omem & 0x1F0) >> 4; if (omem < 0x0180) // Voice Params
u32 param=(omem & 0xF)>>1; {
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); //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) 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.Mode=(value & 0xF000)>>12;
Cores[core].Voices[voice].VolumeL.Increment=(value & 0x3F); Cores[core].Voices[voice].VolumeL.Increment=(value & 0x3F);
} }
else { else
{
Cores[core].Voices[voice].VolumeL.Mode=0; Cores[core].Voices[voice].VolumeL.Mode=0;
Cores[core].Voices[voice].VolumeL.Increment=0; Cores[core].Voices[voice].VolumeL.Increment=0;
if(value&0x4000) if(value&0x4000)
value=0x3fff - (value&0x3fff); value=0x3fff - (value&0x3fff);
Cores[core].Voices[voice].VolumeL.Value=value<<1; 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) 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.Mode=(value & 0xF000)>>12;
Cores[core].Voices[voice].VolumeR.Increment=(value & 0x3F); Cores[core].Voices[voice].VolumeR.Increment=(value & 0x3F);
} }
else { else
{
Cores[core].Voices[voice].VolumeR.Mode=0; Cores[core].Voices[voice].VolumeR.Mode=0;
Cores[core].Voices[voice].VolumeR.Increment=0; Cores[core].Voices[voice].VolumeR.Increment=0;
Cores[core].Voices[voice].VolumeR.Value=value<<1; Cores[core].Voices[voice].VolumeR.Value=value<<1;
@ -1011,9 +1027,10 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
jNO_DEFAULT; jNO_DEFAULT;
} }
} }
else if ((omem >= 0x01C0) && (omem < 0x02DE)) { else if ((omem >= 0x01C0) && (omem < 0x02DE))
u32 voice =((omem-0x01C0) / 12); {
u32 address =((omem-0x01C0) % 12)>>1; 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); //FileLog("[%10d] SPU2 write mem %08x (Core %d Voice %d Address %s) value %x\n",Cycles,rmem,core,voice,AddressNames[address],value);
switch (address) { switch (address) {
@ -1041,9 +1058,10 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
} }
} }
else else
switch(omem) { {
switch(omem)
{
case REG_C_ATTR: case REG_C_ATTR:
RegLog(4,"ATTR",rmem,core,value);
{ {
int irqe=Cores[core].IRQEnable; int irqe=Cores[core].IRQEnable;
int bit0=Cores[core].AttrBit0; int bit0=Cores[core].AttrBit0;
@ -1091,67 +1109,69 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
} }
} }
break; return;
case REG_S_PMON: 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; } 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; Cores[core].Regs.PMON = (Cores[core].Regs.PMON & 0xFFFF0000) | value;
break; return;
case (REG_S_PMON + 2): 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; } 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); Cores[core].Regs.PMON = (Cores[core].Regs.PMON & 0xFFFF) | (value << 16);
break; return;
case REG_S_NON: 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; } 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; Cores[core].Regs.NON = (Cores[core].Regs.NON & 0xFFFF0000) | value;
break; return;
case (REG_S_NON + 2): 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; } 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); Cores[core].Regs.NON = (Cores[core].Regs.NON & 0xFFFF) | (value << 16);
break; return;
case REG_S_VMIXL: 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; } 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; Cores[core].Regs.VMIXL = (Cores[core].Regs.VMIXL & 0xFFFF0000) | value;
return;
case (REG_S_VMIXL + 2): 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; } 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); Cores[core].Regs.VMIXL = (Cores[core].Regs.VMIXL & 0xFFFF) | (value << 16);
return;
case REG_S_VMIXEL: 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; } 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; Cores[core].Regs.VMIXEL = (Cores[core].Regs.VMIXEL & 0xFFFF0000) | value;
break; return;
case (REG_S_VMIXEL + 2): 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; } 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); Cores[core].Regs.VMIXEL = (Cores[core].Regs.VMIXEL & 0xFFFF) | (value << 16);
break; return;
case REG_S_VMIXR: 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; } 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; Cores[core].Regs.VMIXR = (Cores[core].Regs.VMIXR & 0xFFFF0000) | value;
break; return;
case (REG_S_VMIXR + 2): 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; } 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); Cores[core].Regs.VMIXR = (Cores[core].Regs.VMIXR & 0xFFFF) | (value << 16);
break; return;
case REG_S_VMIXER: 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; } 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; Cores[core].Regs.VMIXER = (Cores[core].Regs.VMIXER & 0xFFFF0000) | value;
break; return;
case (REG_S_VMIXER + 2): 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; } 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); Cores[core].Regs.VMIXER = (Cores[core].Regs.VMIXER & 0xFFFF) | (value << 16);
break; return;
case REG_P_MMIX: case REG_P_MMIX:
RegLog(1,"MMIX",rmem,core,value);
vx=value; vx=value;
if (core == 0) vx&=0xFF0; if (core == 0) vx&=0xFF0;
Cores[core].ExtWetR=(vx & 0x001); Cores[core].ExtWetR=(vx & 0x001);
@ -1167,33 +1187,33 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
Cores[core].SndDryR=(vx & 0x400)>>10; Cores[core].SndDryR=(vx & 0x400)>>10;
Cores[core].SndDryL=(vx & 0x800)>>11; Cores[core].SndDryL=(vx & 0x800)>>11;
Cores[core].Regs.MMIX = value; Cores[core].Regs.MMIX = value;
break; return;
case (REG_S_KON + 2): case (REG_S_KON + 2):
RegLog(2,"KON1",rmem,core,value);
StartVoices(core,((u32)value)<<16); StartVoices(core,((u32)value)<<16);
break; return;
case REG_S_KON: case REG_S_KON:
RegLog(2,"KON0",rmem,core,value);
StartVoices(core,((u32)value)); StartVoices(core,((u32)value));
break; return;
case (REG_S_KOFF + 2): case (REG_S_KOFF + 2):
RegLog(2,"KOFF1",rmem,core,value);
StopVoices(core,((u32)value)<<16); StopVoices(core,((u32)value)<<16);
break; return;
case REG_S_KOFF: case REG_S_KOFF:
RegLog(2,"KOFF0",rmem,core,value);
StopVoices(core,((u32)value)); StopVoices(core,((u32)value));
break; return;
case REG_S_ENDX: case REG_S_ENDX:
//ConLog(" * SPU2: Core %d ENDX cleared!\n",core); Cores[core].Regs.ENDX&=0x00FF0000;
RegLog(2,"ENDX0",rmem,core,value); return;
Cores[core].Regs.ENDX&=0x00FF0000; break;
case (REG_S_ENDX + 2): case (REG_S_ENDX + 2):
//ConLog(" * SPU2: Core %d ENDX cleared!\n",core); Cores[core].Regs.ENDX&=0xFFFF;
RegLog(2,"ENDX1",rmem,core,value); return;
Cores[core].Regs.ENDX&=0xFFFF; break;
case REG_P_MVOLL: case REG_P_MVOLL:
RegLog(1,"MVOLL",rmem,core,value);
if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp
Cores[core].MasterL.Mode=(value & 0xE000)/0x2000; Cores[core].MasterL.Mode=(value & 0xE000)/0x2000;
Cores[core].MasterL.Increment=(value & 0x3F) | ((value & 0x800)/0x10); Cores[core].MasterL.Increment=(value & 0x3F) | ((value & 0x800)/0x10);
@ -1204,9 +1224,9 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
Cores[core].MasterL.Value=value; Cores[core].MasterL.Value=value;
} }
Cores[core].MasterL.Reg_VOL=value; Cores[core].MasterL.Reg_VOL=value;
break; return;
case REG_P_MVOLR: case REG_P_MVOLR:
RegLog(1,"MVOLR",rmem,core,value);
if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp if (value & 0x8000) { // +Lin/-Lin/+Exp/-Exp
Cores[core].MasterR.Mode=(value & 0xE000)/0x2000; Cores[core].MasterR.Mode=(value & 0xE000)/0x2000;
Cores[core].MasterR.Increment=(value & 0x3F) | ((value & 0x800)/0x10); Cores[core].MasterR.Increment=(value & 0x3F) | ((value & 0x800)/0x10);
@ -1217,9 +1237,9 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
Cores[core].MasterR.Value=value; Cores[core].MasterR.Value=value;
} }
Cores[core].MasterR.Reg_VOL=value; Cores[core].MasterR.Reg_VOL=value;
break; return;
case REG_S_ADMAS: case REG_S_ADMAS:
RegLog(3,"ADMAS",rmem,core,value);
//ConLog(" * SPU2: Core %d AutoDMAControl set to %d (%d)\n",core,value, Cycles); //ConLog(" * SPU2: Core %d AutoDMAControl set to %d (%d)\n",core,value, Cycles);
Cores[core].AutoDMACtrl=value; Cores[core].AutoDMACtrl=value;
@ -1227,14 +1247,14 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
{ {
Cores[core].AdmaInProgress=0; Cores[core].AdmaInProgress=0;
} }
break; return;
default: default:
*(regtable[mem>>1]) = value; *(regtable[mem>>1]) = value;
break; break;
} }
}
SPU2writeLog(mem,value);
if ((mem>=0x07C0) && (mem<0x07CE)) if ((mem>=0x07C0) && (mem<0x07CE))
{ {
UpdateSpdifMode(); UpdateSpdifMode();
@ -1248,7 +1268,7 @@ void VoiceStart(int core,int vc)
{ {
if(Cores[core].Voices[vc].StartA&7) 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; Cores[core].Voices[vc].StartA=(Cores[core].Voices[vc].StartA+0xFFFF8)+0x8;
} }