From d9f076ef642031403165dd5f2f4b3435c447fb05 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 15 May 2021 14:18:16 -0500 Subject: [PATCH] prepare to add SMS platform plays but no macro yet --- CMakeLists.txt | 1 + src/engine/engine.cpp | 4 ++ src/engine/platform/sms.cpp | 74 +++++++++++++++++++++++++++ src/engine/platform/sms.h | 21 ++++++++ src/engine/platform/sound/sn76496.cpp | 2 +- src/engine/playback.cpp | 9 ++++ 6 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 src/engine/platform/sms.cpp create mode 100644 src/engine/platform/sms.h diff --git a/CMakeLists.txt b/CMakeLists.txt index bb7105023..8d90ccdfc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ src/engine/engine.cpp src/engine/playback.cpp src/engine/platform/abstract.cpp src/engine/platform/genesis.cpp +src/engine/platform/sms.cpp src/engine/platform/dummy.cpp) #imgui/imgui.cpp diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 016ba75a6..ef8e80f5b 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -3,6 +3,7 @@ #include "../ta-log.h" #include "../audio/sdl.h" #include "platform/genesis.h" +#include "platform/sms.h" #include "platform/dummy.h" #include #include @@ -671,6 +672,9 @@ bool DivEngine::init() { case DIV_SYSTEM_GENESIS: dispatch=new DivPlatformGenesis; break; + case DIV_SYSTEM_SMS: + dispatch=new DivPlatformSMS; + break; default: dispatch=new DivPlatformDummy; break; diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp new file mode 100644 index 000000000..ea486c36c --- /dev/null +++ b/src/engine/platform/sms.cpp @@ -0,0 +1,74 @@ +#include "sms.h" +#include + +void DivPlatformSMS::acquire(short& l, short& r) { + short v; + sn->sound_stream_update(&v,1); + l=v; + r=v; +} + +void DivPlatformSMS::tick() { + for (int i=0; i<3; i++) { + if (chan[i].freqChanged) { + sn->write(0x80|i<<5|(chan[i].freq&15)); + sn->write(chan[i].freq>>4); + chan[i].freqChanged=false; + } + } + if (chan[3].freqChanged || updateSNMode) { + updateSNMode=false; + chan[3].freqChanged=false; + if (snNoiseMode&2) { // take period from channel 3 + if (snNoiseMode&1) { + sn->write(0xe7); + } else { + sn->write(0xe3); + } + sn->write(0xdf); + sn->write(0xc0|(chan[3].freq&15)); + sn->write(chan[3].freq>>4); + } else { // 3 fixed values + unsigned char value=chan[3].note%12; + if (value>2) value=2; + value=2-value; + sn->write(0xe0|value|((snNoiseMode&1)<<2)); + } + } +} + +int DivPlatformSMS::dispatch(DivCommand c) { + switch (c.cmd) { + case DIV_CMD_NOTE_ON: + chan[c.chan].freq=3430/pow(2.0f,((float)c.value/12.0f)); + chan[c.chan].freqChanged=true; + chan[c.chan].note=c.value; + chan[c.chan].active=true; + sn->write(0x90|c.chan<<5|(15-chan[c.chan].vol)); + break; + case DIV_CMD_NOTE_OFF: + chan[c.chan].active=false; + break; + case DIV_CMD_VOLUME: + chan[c.chan].vol=c.value; + sn->write(0x90|c.chan<<5|(15-chan[c.chan].vol)); + break; + case DIV_CMD_STD_NOISE_MODE: + snNoiseMode=(c.value&1)|((c.value&16)>>3); + updateSNMode=true; + break; + default: + break; + } + return 1; +} + +int DivPlatformSMS::init(DivEngine* p, int channels, int sugRate) { + parent=p; + rate=223722; + sn=new sn76496_device("sn",223722); + sn->device_start(); + snNoiseMode=0; + updateSNMode=false; + return 4; +} diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h new file mode 100644 index 000000000..a8ef61d5e --- /dev/null +++ b/src/engine/platform/sms.h @@ -0,0 +1,21 @@ +#include "../dispatch.h" +#include "sound/sn76496.h" + +class DivPlatformSMS: public DivDispatch { + struct Channel { + int freq, baseFreq, pitch; + unsigned char ins, note; + bool active, insChanged, freqChanged, keyOn, keyOff; + signed char vol; + Channel(): freq(0), baseFreq(0), pitch(0), ins(0), note(0), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), vol(15) {} + }; + Channel chan[4]; + unsigned char snNoiseMode; + bool updateSNMode; + sn76496_device* sn; + public: + void acquire(short& l, short& r); + int dispatch(DivCommand c); + void tick(); + int init(DivEngine* parent, int channels, int sugRate); +}; diff --git a/src/engine/platform/sound/sn76496.cpp b/src/engine/platform/sound/sn76496.cpp index ef578b0a5..5e876c38b 100644 --- a/src/engine/platform/sound/sn76496.cpp +++ b/src/engine/platform/sound/sn76496.cpp @@ -165,7 +165,7 @@ sn76496_base_device::sn76496_base_device( } sn76496_device::sn76496_device(const char *tag, uint32_t clock) - : sn76496_base_device(tag, 0x10000, 0x04, 0x08, false, 8, false, true, clock) + : sn76496_base_device(tag, 0x8000, 0x01, 0x08, true, 1, false, false, clock) { } diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 2e3fa62ed..6fcaa530b 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -33,6 +33,15 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe return false; } break; + case DIV_SYSTEM_SMS: + switch (effect) { + case 0x20: // SN noise mode + dispatch->dispatch(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); + break; + default: + return false; + } + break; default: return false; }