diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index 8382a57bd..855d7b45d 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -407,6 +407,12 @@ void DivPlatformES5506::tick(bool sysTick) { pageWriteMask(0x00|i,0x5f,0x00,chan[i].pcm.pause?0x0002:0x0000,0x0002); } } + if (chan[i].pcm.direction!=(bool)(chan[i].std.alg.val&2)) { + chan[i].pcm.direction=chan[i].std.alg.val&2; + if (!chan[i].keyOn) { + pageWriteMask(0x00|i,0x5f,0x00,chan[i].pcm.isReversed()?0x0040:0x0000,0x0040); + } + } } if (chan[i].pcm.isNoteMap) { // note map macros @@ -510,7 +516,7 @@ void DivPlatformES5506::tick(bool sysTick) { } if (sampleVaild) { if (!chan[i].keyOn) { - pageWrite(0x20|i,0x03,(chan[i].pcm.reversed)?chan[i].pcm.end:chan[i].pcm.start); + pageWrite(0x20|i,0x03,(chan[i].pcm.isReversed())?chan[i].pcm.end:chan[i].pcm.start); } chan[i].pcmChanged.slice=1; } @@ -544,7 +550,7 @@ void DivPlatformES5506::tick(bool sysTick) { } if (chan[i].pcmChanged.loopBank) { if (!chan[i].keyOn) { - unsigned int loopFlag=(chan[i].pcm.bank<<14)|(chan[i].pcm.reversed?0x0040:0x0000); + unsigned int loopFlag=(chan[i].pcm.bank<<14)|(chan[i].pcm.isReversed()?0x0040:0x0000); chan[i].isReverseLoop=false; switch (chan[i].pcm.loopMode) { case DIV_SAMPLE_LOOP_FORWARD: // Forward loop @@ -641,11 +647,11 @@ void DivPlatformES5506::tick(bool sysTick) { chan[i].freq=CLAMP(parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].pitch2,chipClock,chan[i].pcm.freqOffs),0,0x1ffff); if (chan[i].keyOn) { if (chan[i].pcm.index>=0 && chan[i].pcm.indexsong.sampleLen) { - unsigned int startPos=chan[i].pcm.reversed?chan[i].pcm.end:chan[i].pcm.start; + unsigned int startPos=chan[i].pcm.isReversed()?chan[i].pcm.end:chan[i].pcm.start; if (chan[i].pcm.nextPos) { const unsigned int start=chan[i].pcm.start; const unsigned int end=chan[i].pcm.length; - startPos=start+((chan[i].pcm.reversed?(end-chan[i].pcm.nextPos):(chan[i].pcm.nextPos))<<11); + startPos=start+((chan[i].pcm.isReversed()?(end-chan[i].pcm.nextPos):(chan[i].pcm.nextPos))<<11); chan[i].pcm.nextPos=0; } chan[i].k1Prev=0xffff; @@ -713,7 +719,7 @@ void DivPlatformES5506::tick(bool sysTick) { chan[i].k1Prev=k1; pageWrite(0x00|i,0x02,chan[i].resLVol); pageWrite(0x00|i,0x04,chan[i].resRVol); - unsigned int loopFlag=chan[i].pcm.reversed?0x0040:0x0000; + unsigned int loopFlag=chan[i].pcm.isReversed()?0x0040:0x0000; chan[i].isReverseLoop=false; switch (chan[i].pcm.loopMode) { case DIV_SAMPLE_LOOP_FORWARD: // Forward loop @@ -1036,8 +1042,8 @@ int DivPlatformES5506::dispatch(DivCommand c) { if (chan[c.chan].active) { const unsigned int start=chan[c.chan].pcm.start; const unsigned int end=chan[c.chan].pcm.length; - const unsigned int pos=chan[c.chan].pcm.reversed?(end-c.value):c.value; - if ((chan[c.chan].pcm.reversed && pos>0) || ((!chan[c.chan].pcm.reversed) && pos0) || ((!chan[c.chan].pcm.isReversed()) && pos { struct PCM { + bool isReversed() { return reversed^direction; } bool isNoteMap; int index, next; int note; double freqOffs; double nextFreqOffs; - bool reversed, pause; + bool reversed, pause, direction; unsigned int bank; unsigned int start; unsigned int end; @@ -55,6 +56,7 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf { nextFreqOffs(1.0), reversed(false), pause(false), + direction(false), bank(0), start(0), end(0), diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 62615d2f7..f9a88ed79 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1497,7 +1497,8 @@ void DivEngine::registerSystems() { {0x24, {DIV_CMD_ES5506_ENVELOPE_K1RAMP, "24xx: Set envelope filter coefficient k1 ramp (signed) (00 to FF)",effectVal,constVal<0>}}, {0x25, {DIV_CMD_ES5506_ENVELOPE_K1RAMP, "25xx: Set envelope filter coefficient k1 ramp (signed, slower) (00 to FF)",effectVal,constVal<1>}}, {0x26, {DIV_CMD_ES5506_ENVELOPE_K2RAMP, "26xx: Set envelope filter coefficient k2 ramp (signed) (00 to FF)",effectVal,constVal<0>}}, - {0x27, {DIV_CMD_ES5506_ENVELOPE_K2RAMP, "27xx: Set envelope filter coefficient k2 ramp (signed, slower) (00 to FF)",effectVal,constVal<1>}} + {0x27, {DIV_CMD_ES5506_ENVELOPE_K2RAMP, "27xx: Set envelope filter coefficient k2 ramp (signed, slower) (00 to FF)",effectVal,constVal<1>}}, + {0xdf, {DIV_CMD_SAMPLE_DIR, "DFxx: Set sample playback direction (0: normal; 1: reverse)"}} }; EffectHandlerMap es5506PostEffectHandlerMap={ {0x12, {DIV_CMD_ES5506_PAUSE, "120x: Set pause (bit 0)",effectValAnd<1>}} diff --git a/src/gui/debug.cpp b/src/gui/debug.cpp index 436afde02..8fa585673 100644 --- a/src/gui/debug.cpp +++ b/src/gui/debug.cpp @@ -947,6 +947,8 @@ void putDispatchChan(void* data, int chanNum, int type) { ImGui::TextColored(ch->pcmChanged.loopBank?colorOn:colorOff,">> PCMLoopBankChanged"); ImGui::TextColored(ch->isReverseLoop?colorOn:colorOff,">> IsReverseLoop"); ImGui::TextColored(ch->pcm.reversed?colorOn:colorOff,">> PCMReversed"); + ImGui::TextColored(ch->pcm.pause?colorOn:colorOff,">> PCMPause"); + ImGui::TextColored(ch->pcm.direction?colorOn:colorOff,">> PCMDirection"); ImGui::TextColored(ch->envelope.k1Slow?colorOn:colorOff,">> EnvK1Slow"); ImGui::TextColored(ch->envelope.k2Slow?colorOn:colorOff,">> EnvK2Slow"); ImGui::TextColored(ch->overwrite.envelope.k1Slow?colorOn:colorOff,">> EnvK1SlowOverwrite"); diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 63bbc7f62..3c41d1d5c 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -291,8 +291,8 @@ const char* es5506EnvelopeModes[3]={ "k1 slowdown", "k2 slowdown", NULL }; -const char* es5506ControlModes[2]={ - "pause", NULL +const char* es5506ControlModes[3]={ + "pause", "reverse", NULL }; const int orderedOps[4]={ @@ -5411,7 +5411,7 @@ void FurnaceGUI::drawInsEdit() { macroList.push_back(FurnaceGUIMacroDesc("Envelope K1 ramp",&ins->std.ex6Macro,-128,127,160,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc("Envelope K2 ramp",&ins->std.ex7Macro,-128,127,160,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc("Envelope mode",&ins->std.ex8Macro,0,2,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,es5506EnvelopeModes)); - macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.algMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,es5506ControlModes)); + macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.algMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,es5506ControlModes)); } if (ins->type==DIV_INS_MSM5232) { macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.ex3Macro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));