add 30xx effect to hard reset envelope

currently only for 2612!
This commit is contained in:
tildearrow 2022-04-10 02:11:36 -05:00
parent 0eb02422d5
commit f42855f170
10 changed files with 117 additions and 13 deletions

View file

@ -56,6 +56,7 @@ enum DivDispatchCmds {
DIV_CMD_SAMPLE_BANK, DIV_CMD_SAMPLE_BANK,
DIV_CMD_SAMPLE_POS, DIV_CMD_SAMPLE_POS,
DIV_CMD_FM_HARD_RESET,
DIV_CMD_FM_LFO, DIV_CMD_FM_LFO,
DIV_CMD_FM_LFO_WAVE, DIV_CMD_FM_LFO_WAVE,
DIV_CMD_FM_TL, DIV_CMD_FM_TL,

View file

@ -132,6 +132,9 @@ const char* DivPlatformArcade::getEffectName(unsigned char effect) {
case 0x1f: case 0x1f:
return "1Fxx: Set PM depth (0 to 7F)"; return "1Fxx: Set PM depth (0 to 7F)";
break; break;
case 0x30:
return "30xx: Toggle hard envelope reset on new notes";
break;
} }
return NULL; return NULL;
} }

View file

@ -39,10 +39,30 @@ class DivPlatformArcade: public DivDispatch {
int freq, baseFreq, pitch, note; int freq, baseFreq, pitch, note;
unsigned char ins; unsigned char ins;
signed char konCycles; signed char konCycles;
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, portaPause, furnacePCM; bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, portaPause, furnacePCM, hardReset;
int vol, outVol; int vol, outVol;
unsigned char chVolL, chVolR; unsigned char chVolL, chVolR;
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), note(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), inPorta(false), portaPause(false), furnacePCM(false), vol(0), outVol(0), chVolL(127), chVolR(127) {} Channel():
freqH(0),
freqL(0),
freq(0),
baseFreq(0),
pitch(0),
note(0),
ins(-1),
active(false),
insChanged(true),
freqChanged(false),
keyOn(false),
keyOff(false),
inPorta(false),
portaPause(false),
furnacePCM(false),
hardReset(false),
vol(0),
outVol(0),
chVolL(127),
chVolR(127) {}
}; };
Channel chan[8]; Channel chan[8];
struct QueuedWrite { struct QueuedWrite {

View file

@ -74,8 +74,8 @@ const char* DivPlatformGenesis::getEffectName(unsigned char effect) {
case 0x1d: case 0x1d:
return "1Dxx: Set attack of operator 4 (0 to 1F)"; return "1Dxx: Set attack of operator 4 (0 to 1F)";
break; break;
case 0x20: case 0x30:
return "20xy: Set PSG noise mode (x: preset freq/ch3 freq; y: thin pulse/noise)"; return "30xx: Toggle hard envelope reset on new notes";
break; break;
} }
return NULL; return NULL;
@ -346,7 +346,25 @@ void DivPlatformGenesis::tick() {
} }
if (chan[i].keyOn || chan[i].keyOff) { if (chan[i].keyOn || chan[i].keyOff) {
if (chan[i].hardReset && chan[i].keyOn) {
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
immWrite(baseAddr+ADDR_SL_RR,0x0f);
immWrite(baseAddr+ADDR_TL,0x7f);
oldWrites[baseAddr+ADDR_SL_RR]=-1;
oldWrites[baseAddr+ADDR_TL]=-1;
//rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
}
}
immWrite(0x28,0x00|konOffs[i]); immWrite(0x28,0x00|konOffs[i]);
if (chan[i].hardReset && chan[i].keyOn) {
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
for (int k=0; k<5; k++) {
immWrite(baseAddr+ADDR_SL_RR,0x0f);
}
}
}
chan[i].keyOff=false; chan[i].keyOff=false;
} }
} }
@ -715,9 +733,11 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]]; unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6)); rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
} }
break; break;
} }
case DIV_CMD_FM_HARD_RESET:
chan[c.chan].hardReset=c.value;
break;
case DIV_ALWAYS_SET_VOLUME: case DIV_ALWAYS_SET_VOLUME:
return 0; return 0;
break; break;

View file

@ -38,7 +38,7 @@ class DivPlatformGenesis: public DivDispatch {
unsigned char freqH, freqL; unsigned char freqH, freqL;
int freq, baseFreq, pitch, note; int freq, baseFreq, pitch, note;
unsigned char ins; unsigned char ins;
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta; bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta, hardReset;
int vol, outVol; int vol, outVol;
unsigned char pan; unsigned char pan;
Channel(): Channel():
@ -57,6 +57,7 @@ class DivPlatformGenesis: public DivDispatch {
portaPause(false), portaPause(false),
furnaceDac(false), furnaceDac(false),
inPorta(false), inPorta(false),
hardReset(false),
vol(0), vol(0),
pan(3) {} pan(3) {}
}; };

View file

@ -38,10 +38,30 @@ class DivPlatformTX81Z: public DivDispatch {
int freq, baseFreq, pitch, note; int freq, baseFreq, pitch, note;
unsigned char ins; unsigned char ins;
signed char konCycles; signed char konCycles;
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, portaPause, furnacePCM; bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, portaPause, furnacePCM, hardReset;
int vol, outVol; int vol, outVol;
unsigned char chVolL, chVolR; unsigned char chVolL, chVolR;
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), note(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), inPorta(false), portaPause(false), furnacePCM(false), vol(0), outVol(0), chVolL(127), chVolR(127) {} Channel():
freqH(0),
freqL(0),
freq(0),
baseFreq(0),
pitch(0),
note(0),
ins(-1),
active(false),
insChanged(true),
freqChanged(false),
keyOn(false),
keyOff(false),
inPorta(false),
portaPause(false),
furnacePCM(false),
hardReset(false),
vol(0),
outVol(0),
chVolL(127),
chVolR(127) {}
}; };
Channel chan[8]; Channel chan[8];
struct QueuedWrite { struct QueuedWrite {

View file

@ -46,7 +46,7 @@ class DivPlatformYM2610: public DivDispatch {
int freq, baseFreq, pitch, note; int freq, baseFreq, pitch, note;
unsigned char ins, psgMode, autoEnvNum, autoEnvDen; unsigned char ins, psgMode, autoEnvNum, autoEnvDen;
signed char konCycles; signed char konCycles;
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM; bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset;
int vol, outVol; int vol, outVol;
int sample; int sample;
unsigned char pan; unsigned char pan;
@ -70,6 +70,7 @@ class DivPlatformYM2610: public DivDispatch {
portaPause(false), portaPause(false),
inPorta(false), inPorta(false),
furnacePCM(false), furnacePCM(false),
hardReset(false),
vol(0), vol(0),
outVol(15), outVol(15),
sample(-1), sample(-1),

View file

@ -38,7 +38,7 @@ class DivPlatformYM2610B: public DivDispatch {
int freq, baseFreq, pitch, note; int freq, baseFreq, pitch, note;
unsigned char ins, psgMode, autoEnvNum, autoEnvDen; unsigned char ins, psgMode, autoEnvNum, autoEnvDen;
signed char konCycles; signed char konCycles;
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM; bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset;
int vol, outVol; int vol, outVol;
int sample; int sample;
unsigned char pan; unsigned char pan;
@ -62,6 +62,7 @@ class DivPlatformYM2610B: public DivDispatch {
portaPause(false), portaPause(false),
inPorta(false), inPorta(false),
furnacePCM(false), furnacePCM(false),
hardReset(false),
vol(0), vol(0),
outVol(15), outVol(15),
sample(-1), sample(-1),

View file

@ -61,6 +61,7 @@ const char* cmdName[DIV_CMD_MAX]={
"SAMPLE_BANK", "SAMPLE_BANK",
"SAMPLE_POS", "SAMPLE_POS",
"FM_HARD_RESET",
"FM_LFO", "FM_LFO",
"FM_LFO_WAVE", "FM_LFO_WAVE",
"FM_TL", "FM_TL",
@ -240,6 +241,23 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe
case 0x20: // SN noise mode case 0x20: // SN noise mode
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal));
break; break;
case 0x30: // toggle hard-reset
dispatchCmd(DivCommand(DIV_CMD_FM_HARD_RESET,ch,effectVal));
break;
default:
return false;
}
break;
case DIV_SYSTEM_YM2151:
case DIV_SYSTEM_YM2610:
case DIV_SYSTEM_YM2610_EXT:
case DIV_SYSTEM_YM2610B:
case DIV_SYSTEM_YM2610B_EXT:
case DIV_SYSTEM_OPZ:
switch (effect) {
case 0x30: // toggle hard-reset
dispatchCmd(DivCommand(DIV_CMD_FM_HARD_RESET,ch,effectVal));
break;
default: default:
return false; return false;
} }
@ -340,6 +358,22 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe
case 0x18: // drum mode toggle case 0x18: // drum mode toggle
dispatchCmd(DivCommand(DIV_CMD_FM_EXTCH,ch,effectVal)); dispatchCmd(DivCommand(DIV_CMD_FM_EXTCH,ch,effectVal));
break; break;
case 0x30: // toggle hard-reset
dispatchCmd(DivCommand(DIV_CMD_FM_HARD_RESET,ch,effectVal));
break;
default:
return false;
}
break;
case DIV_SYSTEM_OPLL:
case DIV_SYSTEM_VRC7:
case DIV_SYSTEM_OPL:
case DIV_SYSTEM_OPL2:
case DIV_SYSTEM_OPL3:
switch (effect) {
case 0x30: // toggle hard-reset
dispatchCmd(DivCommand(DIV_CMD_FM_HARD_RESET,ch,effectVal));
break;
default: default:
return false; return false;
} }

View file

@ -143,12 +143,15 @@ struct DivSong {
// - 9: v3.9 // - 9: v3.9
// - introduces Genesis system // - introduces Genesis system
// - introduces system number // - introduces system number
// - patterns now stored in current known format
// - 7: ??? // - 7: ???
// - 5: BETA 3 (?) // - 5: BETA 3
// - adds arpeggio tick // - adds arpeggio tick
// - 3: BETA 2 // - 4: BETA 2
// - 3: BETA 1
// - possibly the first version that could save // - possibly the first version that could save
// - basic format, no system number, 16 instruments, one speed, YMU759-only // - basic format, no system number, 16 instruments, one speed, YMU759-only
// - patterns were stored in a different format (chars instead of shorts)
// - if somebody manages to find a version 2 or even 1 module, please tell me as it will be worth more than a luxury vehicle // - if somebody manages to find a version 2 or even 1 module, please tell me as it will be worth more than a luxury vehicle
unsigned short version; unsigned short version;
bool isDMF; bool isDMF;