mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-30 16:33:01 +00:00
add 30xx effect to hard reset envelope
currently only for 2612!
This commit is contained in:
parent
0eb02422d5
commit
f42855f170
10 changed files with 117 additions and 13 deletions
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue