diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index f193c9ac7..c00f800fa 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -222,6 +222,34 @@ static const short amigaPanTable[128]={ 0xFE0, 0xFE4, 0xFE8, 0xFEC, 0xFF0, 0xFF4, 0xFF8, 0xFFF }; +void DivPlatformES5506::updateNoteChangesAsNeeded(int ch) { + if (chan[ch].noteChanged.changed) { // note value changed or frequency offset is changed + if (chan[ch].noteChanged.offs) { + if (chan[ch].pcm.freqOffs!=chan[ch].pcm.nextFreqOffs) { + chan[ch].pcm.freqOffs=chan[ch].pcm.nextFreqOffs; + chan[ch].nextFreq=NOTE_ES5506(ch,chan[ch].currNote); + chan[ch].noteChanged.freq=1; + chan[ch].freqChanged=true; + } + } + if (chan[ch].noteChanged.note) { + chan[ch].currNote=chan[ch].nextNote; + const int nextFreq=NOTE_ES5506(ch,chan[ch].nextNote); + if (chan[ch].nextFreq!=nextFreq) { + chan[ch].nextFreq=nextFreq; + chan[ch].noteChanged.freq=1; + } + } + if (chan[ch].noteChanged.freq) { + if (chan[ch].baseFreq!=chan[ch].nextFreq) { + chan[ch].baseFreq=chan[ch].nextFreq; + chan[ch].freqChanged=true; + } + } + chan[ch].noteChanged.changed=0; + } +} + void DivPlatformES5506::tick(bool sysTick) { for (int i=0; i<=chanMax; i++) { chan[i].std.next(); @@ -592,31 +620,7 @@ void DivPlatformES5506::tick(bool sysTick) { } chan[i].envChanged.changed=0; } - if (chan[i].noteChanged.changed) { // note value changed or frequency offset is changed - if (chan[i].noteChanged.offs) { - if (chan[i].pcm.freqOffs!=chan[i].pcm.nextFreqOffs) { - chan[i].pcm.freqOffs=chan[i].pcm.nextFreqOffs; - chan[i].nextFreq=NOTE_ES5506(i,chan[i].currNote); - chan[i].noteChanged.freq=1; - chan[i].freqChanged=true; - } - } - if (chan[i].noteChanged.note) { - chan[i].currNote=chan[i].nextNote; - const int nextFreq=NOTE_ES5506(i,chan[i].nextNote); - if (chan[i].nextFreq!=nextFreq) { - chan[i].nextFreq=nextFreq; - chan[i].noteChanged.freq=1; - } - } - if (chan[i].noteChanged.freq) { - if (chan[i].baseFreq!=chan[i].nextFreq) { - chan[i].baseFreq=chan[i].nextFreq; - chan[i].freqChanged=true; - } - } - chan[i].noteChanged.changed=0; - } + updateNoteChangesAsNeeded(i); if (chan[i].pcm.setPos) { if (chan[i].active) { const unsigned int start=chan[i].pcm.start; @@ -832,6 +836,7 @@ int DivPlatformES5506::dispatch(DivCommand c) { chan[c.chan].pcmChanged.changed=0xff; chan[c.chan].noteChanged.changed=0xff; chan[c.chan].volChanged.changed=0xff; + updateNoteChangesAsNeeded(c.chan); } if (!chan[c.chan].std.vol.will) { if (amigaVol) { diff --git a/src/engine/platform/es5506.h b/src/engine/platform/es5506.h index de368c77e..ae7a316a2 100644 --- a/src/engine/platform/es5506.h +++ b/src/engine/platform/es5506.h @@ -281,6 +281,8 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf { DivMemoryComposition memCompo; unsigned char regPool[4*16*128]; // 7 bit page x 16 registers per page x 32 bit per registers + void updateNoteChangesAsNeeded(int ch); + friend void putDispatchChip(void*,int); friend void putDispatchChan(void*,int,int); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 77e885f69..541c761d7 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1039,26 +1039,6 @@ void DivEngine::processRow(int i, bool afterDelay) { clockDrift=0; subticks=0; break; - case 0xf1: // single pitch ramp up - case 0xf2: // single pitch ramp down - if (effect==0xf1) { - chan[i].portaNote=song.limitSlides?0x60:255; - } else { - chan[i].portaNote=song.limitSlides?disCont[dispatchOfChan[i]].dispatch->getPortaFloor(dispatchChanOfChan[i]):-60; - } - chan[i].portaSpeed=effectVal; - chan[i].portaStop=true; - chan[i].nowYouCanStop=false; - chan[i].stopOnOff=false; - chan[i].scheduledSlideReset=false; - chan[i].inPorta=false; - if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,true,0)); - dispatchCmd(DivCommand(DIV_CMD_NOTE_PORTA,i,chan[i].portaSpeed*(song.linearPitch==2?song.pitchSlideSpeed:1),chan[i].portaNote)); - chan[i].portaNote=-1; - chan[i].portaSpeed=-1; - chan[i].inPorta=false; - if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0)); - break; case 0xf3: // fine volume ramp up // tremolo and vol slides are incompatible chan[i].tremoloDepth=0; @@ -1198,7 +1178,30 @@ void DivEngine::processRow(int i, bool afterDelay) { if (effectVal==-1) effectVal=0; effectVal&=255; - perSystemPostEffect(i,effect,effectVal); + if (!perSystemPostEffect(i,effect,effectVal)) { + switch (effect) { + case 0xf1: // single pitch ramp up + case 0xf2: // single pitch ramp down + if (effect==0xf1) { + chan[i].portaNote=song.limitSlides?0x60:255; + } else { + chan[i].portaNote=song.limitSlides?disCont[dispatchOfChan[i]].dispatch->getPortaFloor(dispatchChanOfChan[i]):-60; + } + chan[i].portaSpeed=effectVal; + chan[i].portaStop=true; + chan[i].nowYouCanStop=false; + chan[i].stopOnOff=false; + chan[i].scheduledSlideReset=false; + chan[i].inPorta=false; + if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,true,0)); + dispatchCmd(DivCommand(DIV_CMD_NOTE_PORTA,i,chan[i].portaSpeed*(song.linearPitch==2?song.pitchSlideSpeed:1),chan[i].portaNote)); + chan[i].portaNote=-1; + chan[i].portaSpeed=-1; + chan[i].inPorta=false; + if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0)); + break; + } + } } }