diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 693a26c5f..fe9dc210e 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -263,6 +263,8 @@ enum DivDispatchCmds { DIV_CMD_BIFURCATOR_STATE_LOAD, DIV_CMD_BIFURCATOR_PARAMETER, + DIV_CMD_FDS_MOD_AUTO, + DIV_CMD_MULTIPCM_MIX_FM, // (value) DIV_CMD_MULTIPCM_MIX_PCM, // (value) DIV_CMD_MULTIPCM_LFO, // (value) diff --git a/src/engine/platform/fds.cpp b/src/engine/platform/fds.cpp index 6d6a3c768..1e42738af 100644 --- a/src/engine/platform/fds.cpp +++ b/src/engine/platform/fds.cpp @@ -200,6 +200,15 @@ void DivPlatformFDS::tick(bool sysTick) { } rWrite(0x4082,chan[i].freq&0xff); rWrite(0x4083,(chan[i].freq>>8)&15); + + if (chan[i].autoModNum>0 && chan[i].autoModDen>0) { + chan[i].modFreq=(chan[i].freq*chan[i].autoModNum)/chan[i].autoModDen; + if (chan[i].modFreq>4095) chan[i].modFreq=4095; + if (chan[i].modFreq<0) chan[i].modFreq=0; + rWrite(0x4086,chan[i].modFreq&0xff); + rWrite(0x4087,chan[i].modFreq>>8); + } + if (chan[i].keyOn) chan[i].keyOn=false; if (chan[i].keyOff) chan[i].keyOff=false; chan[i].freqChanged=false; @@ -342,6 +351,13 @@ int DivPlatformFDS::dispatch(DivCommand c) { rWrite(0x4087,chan[c.chan].modFreq>>8); break; } + case DIV_CMD_FDS_MOD_AUTO: + chan[c.chan].autoModNum=c.value>>4; + chan[c.chan].autoModDen=c.value&15; + chan[c.chan].freqChanged=true; + chan[c.chan].modOn=(chan[c.chan].autoModNum && chan[c.chan].autoModDen); + rWrite(0x4084,(chan[c.chan].modOn<<7)|0x40|chan[c.chan].modDepth); + break; case DIV_CMD_NOTE_PORTA: { int destFreq=NOTE_FREQUENCY(c.value2); bool return2=false; diff --git a/src/engine/platform/fds.h b/src/engine/platform/fds.h index 49b52d063..57c8ff0bc 100644 --- a/src/engine/platform/fds.h +++ b/src/engine/platform/fds.h @@ -29,6 +29,7 @@ class DivPlatformFDS: public DivDispatch { struct Channel: public SharedChannel { int prevFreq, modFreq; unsigned char duty, sweep, modDepth, modPos; + unsigned char autoModNum, autoModDen; bool sweepChanged, modOn; signed short wave; signed char modTable[32]; @@ -40,6 +41,8 @@ class DivPlatformFDS: public DivDispatch { sweep(8), modDepth(0), modPos(0), + autoModNum(0), + autoModDen(0), sweepChanged(false), modOn(false), wave(-1) { diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 85ac44aa7..d2094d49c 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -263,6 +263,8 @@ const char* cmdName[]={ "BIFURCATOR_STATE_LOAD", "BIFURCATOR_PARAMETER", + "FDS_MOD_AUTO", + "MULTIPCM_MIX_FM", "MULTIPCM_MIX_PCM", "MULTIPCM_LFO", diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index d94dbe46e..f56f50a1e 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1072,6 +1072,7 @@ void DivEngine::registerSystems() { {0x13, {DIV_CMD_FDS_MOD_LOW, _("13xx: Set modulation speed low byte")}}, {0x14, {DIV_CMD_FDS_MOD_POS, _("14xx: Set modulator position")}}, {0x15, {DIV_CMD_FDS_MOD_WAVE, _("15xx: Set modulator table to waveform")}}, + {0x16, {DIV_CMD_FDS_MOD_AUTO, _("16xy: Automatic modulation speed (x: numerator; y: denominator)")}}, } );