Merge branch 'master' into ZSMv1

This commit is contained in:
ZeroByteOrg 2022-07-11 12:59:59 -05:00
commit 850508e1b8
70 changed files with 342 additions and 65 deletions

View file

@ -355,6 +355,7 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_SAMPLE_POS:

View file

@ -827,6 +827,7 @@ int DivPlatformArcade::dispatch(DivCommand c) {
return 127;
break;
case DIV_CMD_PRE_PORTA:
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_LINEAR(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_PRE_NOTE:

View file

@ -471,9 +471,12 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
return 15;
break;
case DIV_CMD_PRE_PORTA:
// TODO: FIX wtr_envelope.dmf
// the brokenPortaArp update broke it
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AY));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_PRE_NOTE:

View file

@ -506,6 +506,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AY8930));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_PRE_NOTE:

View file

@ -250,6 +250,7 @@ int DivPlatformBubSysWSG::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SCC));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -369,6 +369,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
chan[c.chan].keyOn=true;
}
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_PRE_NOTE:

View file

@ -406,6 +406,7 @@ int DivPlatformFDS::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_FDS));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -393,6 +393,7 @@ int DivPlatformGB::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_GB));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GB_SWEEP_DIR:

View file

@ -387,6 +387,7 @@ int DivPlatformLynx::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_MIKEY));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -324,6 +324,7 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -121,6 +121,7 @@ int DivPlatformMSM6258::dispatch(DivCommand c) {
chan[c.chan].outVol=chan[c.chan].vol;
}
sample=ins->amiga.getSample(c.value);
samplePos=0;
if (sample>=0 && sample<parent->song.sampleLen) {
//DivSample* s=parent->getSample(chan[c.chan].sample);
if (c.value!=DIV_NOTE_NULL) {
@ -144,8 +145,8 @@ int DivPlatformMSM6258::dispatch(DivCommand c) {
//DivSample* s=parent->getSample(12*sampleBank+c.value%12);
sample=12*sampleBank+c.value%12;
samplePos=0;
msm->ctrl_w(1);
msm->ctrl_w(2);
rWrite(0,1);
rWrite(0,2);
}
break;
}

View file

@ -562,6 +562,7 @@ int DivPlatformN163::dispatch(DivCommand c) {
chan[c.chan].keyOn=true;
}
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -442,6 +442,7 @@ int DivPlatformNamcoWSG::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_PCE));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -573,6 +573,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -1434,6 +1434,9 @@ int DivPlatformOPL::dispatch(DivCommand c) {
return 63;
break;
case DIV_CMD_PRE_PORTA:
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) {
chan[c.chan].baseFreq=(c.chan==adpcmChan)?(NOTE_ADPCMB(chan[c.chan].note)):(NOTE_FREQUENCY(chan[c.chan].note));
}
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_PRE_NOTE:
@ -1539,7 +1542,7 @@ void DivPlatformOPL::reset() {
}
*/
if (downsample) {
const unsigned int downsampledRate=(unsigned int)(49716.0*(double(rate)/chipRateBase));
const unsigned int downsampledRate=(unsigned int)((double)rate*rate/chipRateBase);
OPL3_Reset(&fm,downsampledRate);
} else {
OPL3_Reset(&fm,rate);
@ -1669,7 +1672,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
slots=drums?slotsDrums:slotsNonDrums;
chanMap=drums?chanMapOPL2Drums:chanMapOPL2;
outChanMap=outChanMapOPL2;
chipFreqBase=9440540*0.25;
chipFreqBase=32768*72;
chans=9;
melodicChans=drums?6:9;
totalChans=drums?11:9;
@ -1683,7 +1686,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
slots=drums?slotsDrums:slotsNonDrums;
chanMap=drums?chanMapOPL3Drums:chanMapOPL3;
outChanMap=outChanMapOPL3;
chipFreqBase=9440540;
chipFreqBase=32768*288;
chans=18;
melodicChans=drums?15:18;
totalChans=drums?20:18;
@ -1735,9 +1738,6 @@ void DivPlatformOPL::setFlags(unsigned int flags) {
default:
case 1: case 2: case 8950:
switch (flags&0xff) {
case 0x00:
chipClock=COLOR_NTSC;
break;
case 0x01:
chipClock=COLOR_PAL*4.0/5.0;
break;
@ -1753,15 +1753,15 @@ void DivPlatformOPL::setFlags(unsigned int flags) {
case 0x05:
chipClock=3500000.0;
break;
default:
chipClock=COLOR_NTSC;
break;
}
rate=chipClock/72;
chipRateBase=double(rate);
chipRateBase=rate;
break;
case 3:
switch (flags&0xff) {
case 0x00:
chipClock=COLOR_NTSC*4.0;
break;
case 0x01:
chipClock=COLOR_PAL*16.0/5.0;
break;
@ -1774,28 +1774,31 @@ void DivPlatformOPL::setFlags(unsigned int flags) {
case 0x04:
chipClock=15000000.0;
break;
default:
chipClock=COLOR_NTSC*4.0;
break;
}
rate=chipClock/288;
chipRateBase=double(rate);
chipRateBase=rate;
break;
case 4:
switch (flags&0xff) {
case 0x02:
chipClock=33868800.0;
break;
case 0x00:
chipClock=COLOR_NTSC*8.0;
break;
case 0x01:
chipClock=COLOR_PAL*32.0/5.0;
break;
case 0x02:
chipClock=33868800.0;
break;
default:
chipClock=COLOR_NTSC*8.0;
break;
}
chipRateBase=double(chipClock)/684.0;
rate=chipClock/768;
chipRateBase=chipClock/684;
break;
case 759:
rate=48000;
chipRateBase=double(rate);
chipRateBase=rate;
chipClock=rate*288;
break;
}

View file

@ -95,7 +95,7 @@ class DivPlatformOPL: public DivDispatch {
const unsigned char** slots;
const unsigned short* chanMap;
const unsigned char* outChanMap;
double chipFreqBase, chipRateBase;
int chipFreqBase, chipRateBase;
int delay, chipType, oplType, chans, melodicChans, totalChans, adpcmChan, sampleBank;
unsigned char lastBusy;
unsigned char drumState;

View file

@ -831,6 +831,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
break;
case DIV_CMD_PRE_PORTA:
if (c.chan>=9 && !properDrums) return 0;
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_PRE_NOTE:

View file

@ -445,6 +445,7 @@ int DivPlatformPCE::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_PCE));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -471,6 +471,7 @@ int DivPlatformPCSpeaker::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -239,6 +239,7 @@ int DivPlatformPET::dispatch(DivCommand c) {
if (chan.active && c.value2) {
if (parent->song.resetMacroOnPorta) chan.macroInit(parent->getIns(chan.ins,DIV_INS_PET));
}
if (!chan.inPorta && c.value && !parent->song.brokenPortaArp && chan.std.arp.will) chan.baseFreq=NOTE_PERIODIC(chan.note);
chan.inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -496,6 +496,7 @@ int DivPlatformQSound::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=QS_NOTE_FREQUENCY(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -265,6 +265,7 @@ int DivPlatformRF5C68::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_SAMPLE_POS:

View file

@ -335,6 +335,7 @@ int DivPlatformSAA1099::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SAA1099));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_PRE_NOTE:

View file

@ -267,6 +267,7 @@ int DivPlatformSCC::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SCC));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -365,6 +365,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
return 127;
break;
case DIV_CMD_PRE_PORTA:
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=(chan[c.chan].note<<6);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_PRE_NOTE:

View file

@ -133,7 +133,7 @@ void DivPlatformSMS::tick(bool sysTick) {
if (i==3) CHIP_DIVIDER=noiseDivider;
chan[i].std.next();
if (chan[i].std.vol.had) {
chan[i].outVol=MIN(15,chan[i].std.vol.val)-(15-(chan[i].vol&15));
chan[i].outVol=VOL_SCALE_LOG(chan[i].std.vol.val,chan[i].vol,15);
if (chan[i].outVol<0) chan[i].outVol=0;
// old formula
// ((chan[i].vol&15)*MIN(15,chan[i].std.vol.val))>>4;
@ -353,9 +353,8 @@ int DivPlatformSMS::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
// TODO: pre porta cancel arp compat flag
//if (chan[c.chan].inPorta) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
break;
case DIV_CMD_GET_VOLMAX:
return 15;

View file

@ -454,6 +454,7 @@ int DivPlatformSoundUnit::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SU));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -431,6 +431,7 @@ int DivPlatformSwan::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SWAN));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -259,6 +259,7 @@ int DivPlatformTIA::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_TIA));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=(chan[c.chan].note<<8);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_PRE_NOTE:

View file

@ -933,6 +933,7 @@ int DivPlatformTX81Z::dispatch(DivCommand c) {
return 127;
break;
case DIV_CMD_PRE_PORTA:
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_LINEAR(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_PRE_NOTE:

View file

@ -361,6 +361,7 @@ int DivPlatformVERA::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VERA));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=calcNoteFreq(c.chan,chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_STD_NOISE_MODE:

View file

@ -243,6 +243,7 @@ int DivPlatformVIC20::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VIC));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -399,6 +399,7 @@ int DivPlatformVRC6::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_VRC6));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX:

View file

@ -732,6 +732,7 @@ int DivPlatformX1_010::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_X1_010));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NoteX1_010(c.chan,chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_SAMPLE_FREQ:

View file

@ -293,6 +293,7 @@ int DivPlatformYMZ280B::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_SAMPLE_POS:

View file

@ -224,6 +224,7 @@ int DivPlatformZXBeeper::dispatch(DivCommand c) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will) chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
break;
case DIV_CMD_GET_VOLMAX: