From e2c1233b12605c75d14883078a877c386b0e93b8 Mon Sep 17 00:00:00 2001 From: Laurens Holst Date: Fri, 13 May 2022 16:34:48 +0200 Subject: [PATCH] Reset period counter when writing to period registers. This is what happens on real SCC. See also e.g. openMSX core: https://github.com/openMSX/openMSX/blob/master/src/sound/SCC.cc#L390 To reduce the noise introduced by this, we add extra checks to only write the period when it has actually changed. --- src/engine/platform/scc.cpp | 10 ++++++++-- src/engine/platform/scc.h | 3 ++- src/engine/platform/sound/scc/scc.cpp | 2 ++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/engine/platform/scc.cpp b/src/engine/platform/scc.cpp index 88132b12..5c480907 100644 --- a/src/engine/platform/scc.cpp +++ b/src/engine/platform/scc.cpp @@ -161,9 +161,14 @@ void DivPlatformSCC::tick(bool sysTick) { chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER)-1; if (chan[i].freq<0) chan[i].freq=0; if (chan[i].freq>4095) chan[i].freq=4095; - rWrite(regBase+0+i*2,chan[i].freq&0xff); - rWrite(regBase+1+i*2,chan[i].freq>>8); + if (!chan[i].freqInit || regPool[regBase+0+i*2]!=(chan[i].freq&0xff)) { + rWrite(regBase+0+i*2,chan[i].freq&0xff); + } + if (!chan[i].freqInit || regPool[regBase+1+i*2]!=(chan[i].freq>>8)) { + rWrite(regBase+1+i*2,chan[i].freq>>8); + } chan[i].freqChanged=false; + chan[i].freqInit=!skipRegisterWrites; } } } @@ -286,6 +291,7 @@ void DivPlatformSCC::forceIns() { for (int i=0; i<5; i++) { chan[i].insChanged=true; chan[i].freqChanged=true; + chan[i].freqInit=false; if (isPlus || i<3) { updateWave(i); } diff --git a/src/engine/platform/scc.h b/src/engine/platform/scc.h index 11d6521c..df6ef84e 100644 --- a/src/engine/platform/scc.h +++ b/src/engine/platform/scc.h @@ -29,7 +29,7 @@ class DivPlatformSCC: public DivDispatch { struct Channel { int freq, baseFreq, pitch, pitch2, note, ins; - bool active, insChanged, freqChanged, inPorta; + bool active, insChanged, freqChanged, freqInit, inPorta; signed char vol, outVol, wave; signed char waveROM[32] = {0}; // 4 bit PROM per channel on bubble system DivMacroInt std; @@ -48,6 +48,7 @@ class DivPlatformSCC: public DivDispatch { active(false), insChanged(true), freqChanged(false), + freqInit(false), inPorta(false), vol(15), outVol(15), diff --git a/src/engine/platform/sound/scc/scc.cpp b/src/engine/platform/sound/scc/scc.cpp index db74d3f0..427461e6 100644 --- a/src/engine/platform/sound/scc/scc.cpp +++ b/src/engine/platform/sound/scc/scc.cpp @@ -454,6 +454,7 @@ void scc_core::freq_vol_enable_w(u8 address, u8 data) if (m_test.resetpos) // Reset address m_voice[voice_freq].addr = 0; m_voice[voice_freq].pitch = (m_voice[voice_freq].pitch & ~0x0ff) | data; + m_voice[voice_freq].counter = m_voice[voice_freq].pitch; break; case 0x1: // 0x*1 Voice 0 Pitch MSB case 0x3: // 0x*3 Voice 1 Pitch MSB @@ -463,6 +464,7 @@ void scc_core::freq_vol_enable_w(u8 address, u8 data) if (m_test.resetpos) // Reset address m_voice[voice_freq].addr = 0; m_voice[voice_freq].pitch = (m_voice[voice_freq].pitch & ~0xf00) | (u16(bitfield(data, 0, 4)) << 8); + m_voice[voice_freq].counter = m_voice[voice_freq].pitch; break; case 0xa: // 0x*a Voice 0 Volume case 0xb: // 0x*b Voice 1 Volume