parent
d546d135b9
commit
43ba2ff8f2
|
@ -45,6 +45,16 @@ no plans have been made for TX81Z MIDI passthrough, because:
|
||||||
- `1Bxx`: set attack of operator 2.
|
- `1Bxx`: set attack of operator 2.
|
||||||
- `1Cxx`: set attack of operator 3.
|
- `1Cxx`: set attack of operator 3.
|
||||||
- `1Dxx`: set attack of operator 4.
|
- `1Dxx`: set attack of operator 4.
|
||||||
|
- `1Exx`: set LFO AM depth.
|
||||||
|
- `1Fxx`: set LFO PM depth.
|
||||||
|
- `24xx`: set LFO 2 speed.
|
||||||
|
- `25xx`: set LFO 2 waveform. `xx` may be one of the following:
|
||||||
|
- `00`: saw
|
||||||
|
- `01`: square
|
||||||
|
- `02`: triangle
|
||||||
|
- `03`: noise
|
||||||
|
- `26xx`: set LFO 2 AM depth.
|
||||||
|
- `27xx`: set LFO 2 PM depth.
|
||||||
- `28xy`: set reverb of operator.
|
- `28xy`: set reverb of operator.
|
||||||
- `x` is the operator (1-4). a value of 0 means "all operators".
|
- `x` is the operator (1-4). a value of 0 means "all operators".
|
||||||
- `y` is the value.
|
- `y` is the value.
|
||||||
|
|
|
@ -103,9 +103,8 @@ enum DivDispatchCmds {
|
||||||
DIV_CMD_FM_AM_DEPTH, // (depth)
|
DIV_CMD_FM_AM_DEPTH, // (depth)
|
||||||
DIV_CMD_FM_PM_DEPTH, // (depth)
|
DIV_CMD_FM_PM_DEPTH, // (depth)
|
||||||
|
|
||||||
DIV_CMD_GENESIS_LFO, // unused?
|
DIV_CMD_FM_LFO2, // (speed)
|
||||||
|
DIV_CMD_FM_LFO2_WAVE, // (waveform)
|
||||||
DIV_CMD_ARCADE_LFO, // unused?
|
|
||||||
|
|
||||||
DIV_CMD_STD_NOISE_FREQ, // (freq)
|
DIV_CMD_STD_NOISE_FREQ, // (freq)
|
||||||
DIV_CMD_STD_NOISE_MODE, // (mode)
|
DIV_CMD_STD_NOISE_MODE, // (mode)
|
||||||
|
@ -215,6 +214,9 @@ enum DivDispatchCmds {
|
||||||
|
|
||||||
DIV_CMD_SURROUND_PANNING, // (out, val)
|
DIV_CMD_SURROUND_PANNING, // (out, val)
|
||||||
|
|
||||||
|
DIV_CMD_FM_AM2_DEPTH, // (depth)
|
||||||
|
DIV_CMD_FM_PM2_DEPTH, // (depth)
|
||||||
|
|
||||||
DIV_ALWAYS_SET_VOLUME, // () -> alwaysSetVol
|
DIV_ALWAYS_SET_VOLUME, // () -> alwaysSetVol
|
||||||
|
|
||||||
DIV_CMD_MAX
|
DIV_CMD_MAX
|
||||||
|
|
|
@ -41,8 +41,14 @@ class DivPlatformOPM: public DivPlatformFMBase {
|
||||||
0x00, 0x08, 0x10, 0x18
|
0x00, 0x08, 0x10, 0x18
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned char lfoValue, lfoValue2, lfoShape, lfoShape2;
|
||||||
|
|
||||||
DivPlatformOPM():
|
DivPlatformOPM():
|
||||||
DivPlatformFMBase() {}
|
DivPlatformFMBase(),
|
||||||
|
lfoValue(0),
|
||||||
|
lfoValue2(0),
|
||||||
|
lfoShape(0),
|
||||||
|
lfoShape2(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#define ADDR_WS_FINE 0x100
|
#define ADDR_WS_FINE 0x100
|
||||||
// actually 0xc0 but bit 5 of data selects address
|
// actually 0xc0 but bit 5 of data selects address
|
||||||
#define ADDR_EGS_REV 0x120
|
#define ADDR_EGS_REV 0x120
|
||||||
|
// actually 0x38 but bits 7 and 2 select address
|
||||||
|
#define ADDR_FMS2_AMS2 0x140
|
||||||
|
|
||||||
const char* regCheatSheetOPZ[]={
|
const char* regCheatSheetOPZ[]={
|
||||||
"Test", "00",
|
"Test", "00",
|
||||||
|
@ -139,7 +141,8 @@ void DivPlatformTX81Z::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].std.wave.had) {
|
if (chan[i].std.wave.had) {
|
||||||
rWrite(0x1b,chan[i].std.wave.val&3);
|
lfoShape=chan[i].std.wave.val&3;
|
||||||
|
immWrite(0x1b,lfoShape|(lfoShape2<<2));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].std.pitch.had) {
|
if (chan[i].std.pitch.had) {
|
||||||
|
@ -177,7 +180,28 @@ void DivPlatformTX81Z::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].std.ex3.had) {
|
if (chan[i].std.ex3.had) {
|
||||||
immWrite(0x18,chan[i].std.ex3.val);
|
lfoValue=chan[i].std.ex3.val;
|
||||||
|
immWrite(0x18,lfoValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.ex5.had) {
|
||||||
|
amDepth2=chan[i].std.ex5.val;
|
||||||
|
immWrite(0x17,amDepth2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.ex6.had) {
|
||||||
|
pmDepth2=chan[i].std.ex6.val;
|
||||||
|
immWrite(0x17,0x80|pmDepth2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.ex7.had) {
|
||||||
|
lfoValue2=chan[i].std.ex7.val;
|
||||||
|
immWrite(0x16,lfoValue2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.ex8.had) {
|
||||||
|
lfoShape2=chan[i].std.ex8.val&3;
|
||||||
|
immWrite(0x1b,lfoShape|(lfoShape2<<2));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].std.alg.had) {
|
if (chan[i].std.alg.had) {
|
||||||
|
@ -286,6 +310,12 @@ void DivPlatformTX81Z::tick(bool sysTick) {
|
||||||
oldWrites[i]=pendingWrites[i];
|
oldWrites[i]=pendingWrites[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (int i=320; i<328; i++) {
|
||||||
|
if (pendingWrites[i]!=oldWrites[i]) {
|
||||||
|
immWrite(0x38+(i&7),(0x84|pendingWrites[i]));
|
||||||
|
oldWrites[i]=pendingWrites[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int hardResetElapsed=0;
|
int hardResetElapsed=0;
|
||||||
bool mustHardReset=false;
|
bool mustHardReset=false;
|
||||||
|
@ -405,7 +435,7 @@ void DivPlatformTX81Z::commitState(int ch, DivInstrument* ins) {
|
||||||
rWrite(chanOffs[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&7)|(chan[ch].state.fb<<3)|((chan[ch].chVolL&1)<<6)|((chan[ch].chVolR&1)<<7));
|
rWrite(chanOffs[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&7)|(chan[ch].state.fb<<3)|((chan[ch].chVolL&1)<<6)|((chan[ch].chVolR&1)<<7));
|
||||||
}*/
|
}*/
|
||||||
rWrite(chanOffs[ch]+ADDR_FMS_AMS,((chan[ch].state.fms&7)<<4)|(chan[ch].state.ams&3));
|
rWrite(chanOffs[ch]+ADDR_FMS_AMS,((chan[ch].state.fms&7)<<4)|(chan[ch].state.ams&3));
|
||||||
//rWrite(chanOffs[ch]+ADDR_FMS_AMS,0x84|((chan[ch].state.fms2&7)<<4)|(chan[ch].state.ams2&3));
|
rWrite(chanOffs[ch]+ADDR_FMS2_AMS2,((chan[ch].state.fms2&7)<<4)|(chan[ch].state.ams2&3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,11 +558,23 @@ int DivPlatformTX81Z::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_FM_LFO: {
|
case DIV_CMD_FM_LFO: {
|
||||||
rWrite(0x18,c.value);
|
lfoValue=c.value;
|
||||||
|
immWrite(0x18,lfoValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_FM_LFO_WAVE: {
|
case DIV_CMD_FM_LFO_WAVE: {
|
||||||
rWrite(0x1b,c.value&3);
|
lfoShape=c.value&3;
|
||||||
|
immWrite(0x1b,lfoShape|(lfoShape2<<2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_LFO2: {
|
||||||
|
lfoValue2=c.value;
|
||||||
|
immWrite(0x16,lfoValue2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_LFO2_WAVE: {
|
||||||
|
lfoShape2=c.value&3;
|
||||||
|
immWrite(0x1b,lfoShape|(lfoShape2<<2));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_FM_FB: {
|
case DIV_CMD_FM_FB: {
|
||||||
|
@ -810,6 +852,16 @@ int DivPlatformTX81Z::dispatch(DivCommand c) {
|
||||||
immWrite(0x19,0x80|pmDepth);
|
immWrite(0x19,0x80|pmDepth);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DIV_CMD_FM_AM2_DEPTH: {
|
||||||
|
amDepth2=c.value;
|
||||||
|
immWrite(0x17,amDepth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_PM2_DEPTH: {
|
||||||
|
pmDepth2=c.value;
|
||||||
|
immWrite(0x17,0x80|pmDepth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DIV_CMD_FM_HARD_RESET:
|
case DIV_CMD_FM_HARD_RESET:
|
||||||
chan[c.chan].hardReset=c.value;
|
chan[c.chan].hardReset=c.value;
|
||||||
break;
|
break;
|
||||||
|
@ -880,7 +932,7 @@ void DivPlatformTX81Z::forceIns() {
|
||||||
rWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)|((chan[i].chVolL&1)<<6)|((chan[i].chVolR&1)<<7));
|
rWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)|((chan[i].chVolL&1)<<6)|((chan[i].chVolR&1)<<7));
|
||||||
}*/
|
}*/
|
||||||
rWrite(chanOffs[i]+ADDR_FMS_AMS,((chan[i].state.fms&7)<<4)|(chan[i].state.ams&3));
|
rWrite(chanOffs[i]+ADDR_FMS_AMS,((chan[i].state.fms&7)<<4)|(chan[i].state.ams&3));
|
||||||
//rWrite(chanOffs[i]+ADDR_FMS_AMS,0x84|((chan[i].state.fms2&7)<<4)|(chan[i].state.ams2&3));
|
rWrite(chanOffs[i]+ADDR_FMS2_AMS2,((chan[i].state.fms2&7)<<4)|(chan[i].state.ams2&3));
|
||||||
if (chan[i].active) {
|
if (chan[i].active) {
|
||||||
chan[i].keyOn=true;
|
chan[i].keyOn=true;
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
|
@ -888,6 +940,11 @@ void DivPlatformTX81Z::forceIns() {
|
||||||
}
|
}
|
||||||
immWrite(0x19,amDepth);
|
immWrite(0x19,amDepth);
|
||||||
immWrite(0x19,0x80|pmDepth);
|
immWrite(0x19,0x80|pmDepth);
|
||||||
|
immWrite(0x17,amDepth2);
|
||||||
|
immWrite(0x17,0x80|pmDepth2);
|
||||||
|
immWrite(0x18,lfoValue);
|
||||||
|
immWrite(0x16,lfoValue2);
|
||||||
|
immWrite(0x1b,lfoShape|(lfoShape2<<2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformTX81Z::notifyInsChange(int ins) {
|
void DivPlatformTX81Z::notifyInsChange(int ins) {
|
||||||
|
@ -958,12 +1015,19 @@ void DivPlatformTX81Z::reset() {
|
||||||
delay=0;
|
delay=0;
|
||||||
amDepth=0x7f;
|
amDepth=0x7f;
|
||||||
pmDepth=0x7f;
|
pmDepth=0x7f;
|
||||||
|
amDepth2=0x7f;
|
||||||
|
pmDepth2=0x7f;
|
||||||
|
lfoValue=0;
|
||||||
|
lfoValue2=0;
|
||||||
|
lfoShape=0;
|
||||||
|
lfoShape2=0;
|
||||||
|
|
||||||
//rWrite(0x18,0x10);
|
|
||||||
immWrite(0x18,0x00); // LFO Freq Off
|
immWrite(0x18,0x00); // LFO Freq Off
|
||||||
|
immWrite(0x16,0x00);
|
||||||
immWrite(0x19,amDepth);
|
immWrite(0x19,amDepth);
|
||||||
immWrite(0x19,0x80|pmDepth);
|
immWrite(0x19,0x80|pmDepth);
|
||||||
//rWrite(0x1b,0x00);
|
immWrite(0x17,amDepth2);
|
||||||
|
immWrite(0x17,0x80|pmDepth2);
|
||||||
|
|
||||||
extMode=false;
|
extMode=false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ class DivPlatformTX81Z: public DivPlatformOPM {
|
||||||
DivDispatchOscBuffer* oscBuf[8];
|
DivDispatchOscBuffer* oscBuf[8];
|
||||||
int baseFreqOff;
|
int baseFreqOff;
|
||||||
int pcmL, pcmR, pcmCycles;
|
int pcmL, pcmR, pcmCycles;
|
||||||
unsigned char amDepth, pmDepth;
|
unsigned char amDepth, pmDepth, amDepth2, pmDepth2;
|
||||||
|
|
||||||
ymfm::ym2414* fm_ymfm;
|
ymfm::ym2414* fm_ymfm;
|
||||||
ymfm::ym2414::output_data out_ymfm;
|
ymfm::ym2414::output_data out_ymfm;
|
||||||
|
|
|
@ -103,9 +103,8 @@ const char* cmdName[]={
|
||||||
"FM_AM_DEPTH",
|
"FM_AM_DEPTH",
|
||||||
"FM_PM_DEPTH",
|
"FM_PM_DEPTH",
|
||||||
|
|
||||||
"GENESIS_LFO",
|
"FM_LFO2",
|
||||||
|
"FM_LFO2_WAVE",
|
||||||
"ARCADE_LFO",
|
|
||||||
|
|
||||||
"STD_NOISE_FREQ",
|
"STD_NOISE_FREQ",
|
||||||
"STD_NOISE_MODE",
|
"STD_NOISE_MODE",
|
||||||
|
@ -215,6 +214,9 @@ const char* cmdName[]={
|
||||||
|
|
||||||
"SURROUND_PANNING",
|
"SURROUND_PANNING",
|
||||||
|
|
||||||
|
"FM_AM2_DEPTH",
|
||||||
|
"FM_PM2_DEPTH",
|
||||||
|
|
||||||
"ALWAYS_SET_VOLUME"
|
"ALWAYS_SET_VOLUME"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -504,6 +504,10 @@ void DivEngine::registerSystems() {
|
||||||
|
|
||||||
EffectHandlerMap fmOPZPostEffectHandlerMap(fmOPMPostEffectHandlerMap);
|
EffectHandlerMap fmOPZPostEffectHandlerMap(fmOPMPostEffectHandlerMap);
|
||||||
fmOPZPostEffectHandlerMap.insert({
|
fmOPZPostEffectHandlerMap.insert({
|
||||||
|
{0x24, {DIV_CMD_FM_LFO2, "24xx: Set LFO 2 speed"}},
|
||||||
|
{0x25, {DIV_CMD_FM_LFO2_WAVE, "25xx: Set LFO 2 waveform (0 saw, 1 square, 2 triangle, 3 noise)"}},
|
||||||
|
{0x26, {DIV_CMD_FM_AM2_DEPTH, "26xx: Set AM 2 depth (0 to 7F)", effectValAnd<127>}},
|
||||||
|
{0x27, {DIV_CMD_FM_PM2_DEPTH, "27xx: Set PM 2 depth (0 to 7F)", effectValAnd<127>}},
|
||||||
{0x28, {DIV_CMD_FM_REV, "28xy: Set reverb (x: operator from 1 to 4 (0 for all ops); y: reverb from 0 to 7)", effectOpVal<4>, effectValAnd<7>}},
|
{0x28, {DIV_CMD_FM_REV, "28xy: Set reverb (x: operator from 1 to 4 (0 for all ops); y: reverb from 0 to 7)", effectOpVal<4>, effectValAnd<7>}},
|
||||||
{0x2a, {DIV_CMD_FM_WS, "2Axy: Set waveform (x: operator from 1 to 4 (0 for all ops); y: waveform from 0 to 7)", effectOpVal<4>, effectValAnd<7>}},
|
{0x2a, {DIV_CMD_FM_WS, "2Axy: Set waveform (x: operator from 1 to 4 (0 for all ops); y: waveform from 0 to 7)", effectOpVal<4>, effectValAnd<7>}},
|
||||||
{0x2b, {DIV_CMD_FM_EG_SHIFT, "2Bxy: Set envelope generator shift (x: operator from 1 to 4 (0 for all ops); y: shift from 0 to 3)", effectOpVal<4>, effectValAnd<3>}},
|
{0x2b, {DIV_CMD_FM_EG_SHIFT, "2Bxy: Set envelope generator shift (x: operator from 1 to 4 (0 for all ops); y: shift from 0 to 3)", effectOpVal<4>, effectValAnd<3>}},
|
||||||
|
|
Loading…
Reference in New Issue