dev89 - C64: add test/gate macro

and "don't test/gate before new note" setting
This commit is contained in:
tildearrow 2022-04-27 23:54:45 -05:00
parent 3e9c0dd066
commit 4a9855f090
6 changed files with 30 additions and 11 deletions

View file

@ -44,8 +44,8 @@
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
#define BUSY_END isBusy.unlock(); softLocked=false;
#define DIV_VERSION "dev88"
#define DIV_ENGINE_VERSION 88
#define DIV_VERSION "dev89"
#define DIV_ENGINE_VERSION 89
// for imports
#define DIV_VERSION_MOD 0xff01

View file

@ -503,6 +503,9 @@ void DivInstrument::putInsData(SafeWriter* w) {
w->writeC(std.ex6Macro.mode);
w->writeC(std.ex7Macro.mode);
w->writeC(std.ex8Macro.mode);
// C64 no test
w->writeC(c64.noTest);
}
DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
@ -1006,6 +1009,11 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
std.ex8Macro.mode=reader.readC();
}
// C64 no test
if (version>=89) {
c64.noTest=reader.readC();
}
return DIV_DATA_SUCCESS;
}

View file

@ -265,7 +265,7 @@ struct DivInstrumentC64 {
unsigned char a, d, s, r;
unsigned short duty;
unsigned char ringMod, oscSync;
bool toFilter, volIsCutoff, initFilter, dutyIsAbs, filterIsAbs;
bool toFilter, volIsCutoff, initFilter, dutyIsAbs, filterIsAbs, noTest;
unsigned char res;
unsigned short cut;
bool hp, lp, bp, ch3off;
@ -287,6 +287,7 @@ struct DivInstrumentC64 {
initFilter(false),
dutyIsAbs(false),
filterIsAbs(false),
noTest(false),
res(0),
cut(0),
hp(false),

View file

@ -170,16 +170,17 @@ void DivPlatformC64::tick(bool sysTick) {
if (chan[i].testWhen>0) {
if (--chan[i].testWhen<1) {
if (!chan[i].resetMask && !chan[i].inPorta) {
DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_C64);
rWrite(i*7+5,0);
rWrite(i*7+6,0);
rWrite(i*7+4,(chan[i].wave<<4)|8|(chan[i].ring<<2)|(chan[i].sync<<1));
rWrite(i*7+4,(chan[i].wave<<4)|(ins->c64.noTest?0:8)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1));
}
}
}
}
if (chan[i].std.wave.had) {
chan[i].wave=chan[i].std.wave.val;
rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].ring<<2)|(chan[i].sync<<1)|(int)(chan[i].active));
rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)|(int)(chan[i].active));
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
@ -196,6 +197,11 @@ void DivPlatformC64::tick(bool sysTick) {
chan[i].sync=chan[i].std.ex3.val&1;
chan[i].ring=chan[i].std.ex3.val&2;
chan[i].freqChanged=true;
rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)|(int)(chan[i].active));
}
if (chan[i].std.ex4.had) {
chan[i].test=chan[i].std.ex4.val&1;
rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)|(int)(chan[i].active));
}
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
@ -204,12 +210,12 @@ void DivPlatformC64::tick(bool sysTick) {
if (chan[i].keyOn) {
rWrite(i*7+5,(chan[i].attack<<4)|(chan[i].decay));
rWrite(i*7+6,(chan[i].sustain<<4)|(chan[i].release));
rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].ring<<2)|(chan[i].sync<<1)|1);
rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)|1);
}
if (chan[i].keyOff) {
rWrite(i*7+5,(chan[i].attack<<4)|(chan[i].decay));
rWrite(i*7+6,(chan[i].sustain<<4)|(chan[i].release));
rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].ring<<2)|(chan[i].sync<<1)|0);
rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)|0);
}
rWrite(i*7,chan[i].freq&0xff);
rWrite(i*7+1,chan[i].freq>>8);
@ -231,6 +237,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
}
chan[c.chan].active=true;
chan[c.chan].keyOn=true;
chan[c.chan].test=false;
if (chan[c.chan].insChanged || chan[c.chan].resetDuty || ins->std.waveMacro.len>0) {
chan[c.chan].duty=ins->c64.duty;
rWrite(c.chan*7+2,chan[c.chan].duty&0xff);
@ -335,7 +342,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
break;
case DIV_CMD_WAVE:
chan[c.chan].wave=c.value;
rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active));
rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].test<<3)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active));
break;
case DIV_CMD_LEGATO:
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value+((chan[c.chan].std.arp.will && !chan[c.chan].std.arp.mode)?(chan[c.chan].std.arp.val):(0)));
@ -416,11 +423,11 @@ int DivPlatformC64::dispatch(DivCommand c) {
break;
case 4:
chan[c.chan].ring=c.value;
rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active));
rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].test<<3)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active));
break;
case 5:
chan[c.chan].sync=c.value;
rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active));
rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].test<<3)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active));
break;
case 6:
filtControl&=7;

View file

@ -30,7 +30,7 @@ class DivPlatformC64: public DivDispatch {
unsigned char sweep, wave, attack, decay, sustain, release;
short duty;
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, filter;
bool resetMask, resetFilter, resetDuty, ring, sync;
bool resetMask, resetFilter, resetDuty, ring, sync, test;
signed char vol, outVol;
DivMacroInt std;
Channel():
@ -61,6 +61,7 @@ class DivPlatformC64: public DivDispatch {
resetDuty(false),
ring(false),
sync(false),
test(false),
vol(15) {}
};
Channel chan[3];

View file

@ -2433,6 +2433,7 @@ void FurnaceGUI::drawInsEdit() {
P(ImGui::Checkbox("Volume Macro is Cutoff Macro",&ins->c64.volIsCutoff));
P(ImGui::Checkbox("Absolute Cutoff Macro",&ins->c64.filterIsAbs));
P(ImGui::Checkbox("Absolute Duty Macro",&ins->c64.dutyIsAbs));
P(ImGui::Checkbox("Don't test/gate before new note",&ins->c64.noTest));
ImGui::EndTabItem();
}
if (ins->type==DIV_INS_AMIGA) if (ImGui::BeginTabItem("Sample")) {
@ -2926,6 +2927,7 @@ void FurnaceGUI::drawInsEdit() {
}
if (ins->type==DIV_INS_C64) {
NORMAL_MACRO(ins->std.ex3Macro,0,2,"ex3","Special",32,ins->std.ex3Macro.open,true,c64SpecialBits,false,NULL,0,0,0,0,false,0,macroDummyMode,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,2,NULL,false);
NORMAL_MACRO(ins->std.ex4Macro,0,1,"ex4","Test/Gate",32,ins->std.ex4Macro.open,true,NULL,false,NULL,0,0,0,0,false,0,macroDummyMode,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[7],0,1,NULL,false);
}
if (ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930 || ins->type==DIV_INS_X1_010) {
NORMAL_MACRO(ins->std.ex3Macro,0,15,"ex3","AutoEnv Num",96,ins->std.ex3Macro.open,false,NULL,false,NULL,0,0,0,0,false,0,macroDummyMode,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,15,NULL,false);