diff --git a/src/engine/platform/sound/su.cpp b/src/engine/platform/sound/su.cpp index a2fd7653..6637bfa7 100644 --- a/src/engine/platform/sound/su.cpp +++ b/src/engine/platform/sound/su.cpp @@ -238,44 +238,65 @@ void SoundUnit::NextSample(short* l, short* r) { tnsL=(nsL[0]+nsL[1]+nsL[2]+nsL[3]+nsL[4]+nsL[5]+nsL[6]+nsL[7])>>2; tnsR=(nsR[0]+nsR[1]+nsR[2]+nsR[3]+nsR[4]+nsR[5]+nsR[6]+nsR[7])>>2; + IL1=minval(32767,maxval(-32767,tnsL))>>8; + IL2=minval(32767,maxval(-32767,tnsR))>>8; + // write input lines to sample memory if (ILSIZE&64) { if (++ilBufPeriod>=((1+(FIL1>>4))<<2)) { ilBufPeriod=0; unsigned short ilLowerBound=pcmSize-((1+(ILSIZE&63))<<7); + short next; if (ilBufPos>4); + next=((signed char)IL0)+((pcm[ilBufPos]*(FIL1&15))>>4); + if (next<-128) next=-128; + if (next>127) next=127; + pcm[ilBufPos]=next; if (++ilBufPos>=pcmSize) ilBufPos=ilLowerBound; break; case 1: ilFeedback0=ilFeedback1=pcm[ilBufPos]; - pcm[ilBufPos]=IL1+((pcm[ilBufPos]*(FIL1&15))>>4); + next=((signed char)IL1)+((pcm[ilBufPos]*(FIL1&15))>>4); + if (next<-128) next=-128; + if (next>127) next=127; + pcm[ilBufPos]=next; if (++ilBufPos>=pcmSize) ilBufPos=ilLowerBound; break; case 2: ilFeedback0=ilFeedback1=pcm[ilBufPos]; - pcm[ilBufPos]=IL2+((pcm[ilBufPos]*(FIL1&15))>>4); + next=((signed char)IL2)+((pcm[ilBufPos]*(FIL1&15))>>4); + if (next<-128) next=-128; + if (next>127) next=127; + pcm[ilBufPos]=next; if (++ilBufPos>=pcmSize) ilBufPos=ilLowerBound; break; case 3: ilFeedback0=pcm[ilBufPos]; - pcm[ilBufPos]=IL1+((pcm[ilBufPos]*(FIL1&15))>>4); + next=((signed char)IL1)+((pcm[ilBufPos]*(FIL1&15))>>4); + if (next<-128) next=-128; + if (next>127) next=127; + pcm[ilBufPos]=next; if (++ilBufPos>=pcmSize) ilBufPos=ilLowerBound; ilFeedback1=pcm[ilBufPos]; - pcm[ilBufPos]=IL2+((pcm[ilBufPos]*(FIL1&15))>>4); + next=((signed char)IL2)+((pcm[ilBufPos]*(FIL1&15))>>4); + if (next<-128) next=-128; + if (next>127) next=127; + pcm[ilBufPos]=next; if (++ilBufPos>=pcmSize) ilBufPos=ilLowerBound; break; } } - if (ILSIZE&128) { - tnsL+=ilFeedback1*(signed char)FILVOL; - tnsR+=ilFeedback0*(signed char)FILVOL; - } else { - tnsL+=ilFeedback0*(signed char)FILVOL; - tnsR+=ilFeedback1*(signed char)FILVOL; + if (ILCTRL&4) { + if (ILSIZE&128) { + tnsL+=ilFeedback1*(signed char)FILVOL; + tnsR+=ilFeedback0*(signed char)FILVOL; + } else { + tnsL+=ilFeedback0*(signed char)FILVOL; + tnsR+=ilFeedback1*(signed char)FILVOL; + } } } diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 4320798a..6c6b0b32 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -529,6 +529,16 @@ void DivPlatformSoundUnit::reset() { lfoMode=0; lfoSpeed=255; delay=500; + + // set initial IL status + ilCtrl=initIlCtrl; + ilSize=initIlSize; + fil1=initFil1; + echoVol=initEchoVol; + rWrite(0x9c,echoVol); + rWrite(0x9d,ilCtrl); + rWrite(0xbc,ilSize); + rWrite(0xbd,fil1); } bool DivPlatformSoundUnit::isStereo() { @@ -555,6 +565,10 @@ void DivPlatformSoundUnit::setFlags(unsigned int flags) { for (int i=0; i<8; i++) { oscBuf[i]->rate=rate; } + initIlCtrl=3|(flags&4); + initIlSize=((flags>>8)&63)|((flags&4)?0x40:0)|((flags&8)?0x80:0); + initFil1=flags>>16; + initEchoVol=flags>>24; sampleMemSize=flags&16; @@ -575,7 +589,7 @@ const void* DivPlatformSoundUnit::getSampleMem(int index) { } size_t DivPlatformSoundUnit::getSampleMemCapacity(int index) { - return (index==0)?(sampleMemSize?65536:8192):0; + return (index==0)?((sampleMemSize?65536:8192)-((initIlSize&64)?((1+(initIlSize&63))<<7):0)):0; } size_t DivPlatformSoundUnit::getSampleMemUsage(int index) { diff --git a/src/engine/platform/su.h b/src/engine/platform/su.h index e882c398..9972599d 100644 --- a/src/engine/platform/su.h +++ b/src/engine/platform/su.h @@ -97,6 +97,9 @@ class DivPlatformSoundUnit: public DivDispatch { std::queue writes; unsigned char lastPan; bool sampleMemSize; + unsigned char ilCtrl, ilSize, fil1; + unsigned char initIlCtrl, initIlSize, initFil1; + signed char echoVol, initEchoVol; int cycles, curChan, delay; short tempL; diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index 4cc1784a..3259f00c 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -129,11 +129,11 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool } case DIV_SYSTEM_SOUND_UNIT: { ImGui::Text("CPU rate:"); - if (ImGui::RadioButton("6.18MHz (NTSC)",(flags&15)==0)) { - copyOfFlags=(flags&(~15))|0; + if (ImGui::RadioButton("6.18MHz (NTSC)",(flags&3)==0)) { + copyOfFlags=(flags&(~3))|0; } - if (ImGui::RadioButton("5.95MHz (PAL)",(flags&15)==1)) { - copyOfFlags=(flags&(~15))|1; + if (ImGui::RadioButton("5.95MHz (PAL)",(flags&3)==1)) { + copyOfFlags=(flags&(~3))|1; } ImGui::Text("Chip revision (sample memory):"); if (ImGui::RadioButton("A/B/E (8K)",(flags&16)==0)) { @@ -142,6 +142,42 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool if (ImGui::RadioButton("D/F (64K)",(flags&16)==16)) { copyOfFlags=(flags&(~16))|16; } + bool echo=flags&4; + if (ImGui::Checkbox("Enable echo",&echo)) { + copyOfFlags=(flags&(~4))|(echo<<2); + } + bool flipEcho=flags&8; + if (ImGui::Checkbox("Swap echo channels",&flipEcho)) { + copyOfFlags=(flags&(~8))|(flipEcho<<3); + } + ImGui::Text("Echo delay:"); + int echoBufSize=(flags&0x3f00)>>8; + if (CWSliderInt("##EchoBufSize",&echoBufSize,0,63)) { + if (echoBufSize<0) echoBufSize=0; + if (echoBufSize>63) echoBufSize=63; + copyOfFlags=(flags&~0x3f00)|(echoBufSize<<8); + } rightClickable + ImGui::Text("Echo resolution:"); + int echoResolution=(flags&0xf00000)>>20; + if (CWSliderInt("##EchoResolution",&echoResolution,0,15)) { + if (echoResolution<0) echoResolution=0; + if (echoResolution>15) echoResolution=15; + copyOfFlags=(flags&(~0xf00000))|(echoResolution<<20); + } rightClickable + ImGui::Text("Echo feedback:"); + int echoFeedback=(flags&0xf0000)>>16; + if (CWSliderInt("##EchoFeedback",&echoFeedback,0,15)) { + if (echoFeedback<0) echoFeedback=0; + if (echoFeedback>15) echoFeedback=15; + copyOfFlags=(flags&(~0xf0000))|(echoFeedback<<16); + } rightClickable + ImGui::Text("Echo volume:"); + int echoVolume=(signed char)((flags&0xff000000)>>24); + if (CWSliderInt("##EchoVolume",&echoVolume,-128,127)) { + if (echoVolume<-128) echoVolume=-128; + if (echoVolume>127) echoVolume=127; + copyOfFlags=(flags&(~0xff000000))|(((unsigned char)echoVolume)<<24); + } rightClickable break; } case DIV_SYSTEM_GB: {