diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index 7d44fe8a8..6e925c9a0 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -255,6 +255,10 @@ void DivPlatformArcade::tick(bool sysTick) { chan[i].state.ams=chan[i].std.ams.val; rWrite(chanOffs[i]+ADDR_FMS_AMS,((chan[i].state.fms&7)<<4)|(chan[i].state.ams&3)); } + if (chan[i].std.ex4.had && chan[i].active) { + chan[i].opMask=chan[i].std.ex4.val&15; + chan[i].opMaskChanged=true; + } for (int j=0; j<4; j++) { unsigned short baseAddr=chanOffs[i]|opOffs[j]; DivInstrumentFM::Operator& op=chan[i].state.op[j]; @@ -347,8 +351,9 @@ void DivPlatformArcade::tick(bool sysTick) { immWrite(i+0x30,chan[i].freq<<2); chan[i].freqChanged=false; } - if (chan[i].keyOn) { + if (chan[i].keyOn || chan[i].opMaskChanged) { immWrite(0x08,(chan[i].opMask<<3)|i); + chan[i].opMaskChanged=false; chan[i].keyOn=false; } } diff --git a/src/engine/platform/arcade.h b/src/engine/platform/arcade.h index 683394e3b..2a9c2b40c 100644 --- a/src/engine/platform/arcade.h +++ b/src/engine/platform/arcade.h @@ -43,7 +43,7 @@ class DivPlatformArcade: public DivPlatformOPM { int freq, baseFreq, pitch, pitch2, note; int ins; signed char konCycles; - bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, portaPause, furnacePCM, hardReset; + bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, portaPause, furnacePCM, hardReset, opMaskChanged; int vol, outVol; unsigned char chVolL, chVolR, opMask; void macroInit(DivInstrument* which) { @@ -68,6 +68,7 @@ class DivPlatformArcade: public DivPlatformOPM { portaPause(false), furnacePCM(false), hardReset(false), + opMaskChanged(false), vol(0), outVol(0), chVolL(127), diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index 46696b8ac..1c3488006 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -273,6 +273,10 @@ void DivPlatformYM2203::tick(bool sysTick) { chan[i].state.fb=chan[i].std.fb.val; rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)); } + if (chan[i].std.ex4.had && chan[i].active) { + chan[i].opMask=chan[i].std.ex4.val&15; + chan[i].opMaskChanged=true; + } for (int j=0; j<4; j++) { unsigned short baseAddr=chanOffs[i]|opOffs[j]; DivInstrumentFM::Operator& op=chan[i].state.op[j]; @@ -385,8 +389,9 @@ void DivPlatformYM2203::tick(bool sysTick) { immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff); chan[i].freqChanged=false; } - if (chan[i].keyOn) { + if (chan[i].keyOn || chan[i].opMaskChanged) { immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]); + chan[i].opMaskChanged=false; chan[i].keyOn=false; } } diff --git a/src/engine/platform/ym2203.h b/src/engine/platform/ym2203.h index 921c1d94b..756603651 100644 --- a/src/engine/platform/ym2203.h +++ b/src/engine/platform/ym2203.h @@ -45,7 +45,7 @@ class DivPlatformYM2203: public DivPlatformOPN { int freq, baseFreq, pitch, pitch2, portaPauseFreq, note, ins; unsigned char psgMode, autoEnvNum, autoEnvDen, opMask; signed char konCycles; - bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset; + bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset, opMaskChanged; int vol, outVol; int sample; DivMacroInt std; @@ -76,6 +76,7 @@ class DivPlatformYM2203: public DivPlatformOPN { inPorta(false), furnacePCM(false), hardReset(false), + opMaskChanged(false), vol(0), outVol(15), sample(-1) {} diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 801bab329..ec90c1c6b 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -441,6 +441,10 @@ void DivPlatformYM2608::tick(bool sysTick) { chan[i].state.ams=chan[i].std.ams.val; rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4)); } + if (chan[i].std.ex4.had && chan[i].active) { + chan[i].opMask=chan[i].std.ex4.val&15; + chan[i].opMaskChanged=true; + } for (int j=0; j<4; j++) { unsigned short baseAddr=chanOffs[i]|opOffs[j]; DivInstrumentFM::Operator& op=chan[i].state.op[j]; @@ -581,8 +585,9 @@ void DivPlatformYM2608::tick(bool sysTick) { immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff); chan[i].freqChanged=false; } - if (chan[i].keyOn) { + if (chan[i].keyOn || chan[i].opMaskChanged) { immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]); + chan[i].opMaskChanged=false; chan[i].keyOn=false; } } diff --git a/src/engine/platform/ym2608.h b/src/engine/platform/ym2608.h index 1689436ee..ed850bf85 100644 --- a/src/engine/platform/ym2608.h +++ b/src/engine/platform/ym2608.h @@ -50,7 +50,7 @@ class DivPlatformYM2608: public DivPlatformOPN { int freq, baseFreq, pitch, pitch2, portaPauseFreq, note, ins; unsigned char psgMode, autoEnvNum, autoEnvDen, opMask; signed char konCycles; - bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset; + bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset, opMaskChanged; int vol, outVol; int sample; unsigned char pan; @@ -82,6 +82,7 @@ class DivPlatformYM2608: public DivPlatformOPN { inPorta(false), furnacePCM(false), hardReset(false), + opMaskChanged(false), vol(0), outVol(15), sample(-1), diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 63a6d72e3..6a8509d55 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -482,6 +482,10 @@ void DivPlatformYM2610::tick(bool sysTick) { chan[i].state.ams=chan[i].std.ams.val; rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4)); } + if (chan[i].std.ex4.had && chan[i].active) { + chan[i].opMask=chan[i].std.ex4.val&15; + chan[i].opMaskChanged=true; + } for (int j=0; j<4; j++) { unsigned short baseAddr=chanOffs[i]|opOffs[j]; DivInstrumentFM::Operator& op=chan[i].state.op[j]; @@ -618,8 +622,9 @@ void DivPlatformYM2610::tick(bool sysTick) { immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff); chan[i].freqChanged=false; } - if (chan[i].keyOn) { + if (chan[i].keyOn || chan[i].opMaskChanged) { immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]); + chan[i].opMaskChanged=false; chan[i].keyOn=false; } } diff --git a/src/engine/platform/ym2610.h b/src/engine/platform/ym2610.h index 0e363329a..4f1a16642 100644 --- a/src/engine/platform/ym2610.h +++ b/src/engine/platform/ym2610.h @@ -73,7 +73,7 @@ class DivPlatformYM2610: public DivPlatformYM2610Base { int freq, baseFreq, pitch, pitch2, portaPauseFreq, note, ins; unsigned char psgMode, autoEnvNum, autoEnvDen; signed char konCycles; - bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset; + bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset, opMaskChanged; int vol, outVol; int sample; unsigned char pan, opMask; @@ -104,6 +104,7 @@ class DivPlatformYM2610: public DivPlatformYM2610Base { inPorta(false), furnacePCM(false), hardReset(false), + opMaskChanged(false), vol(0), outVol(15), sample(-1), diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index f01f39b42..31cd7b3ff 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -465,6 +465,10 @@ void DivPlatformYM2610B::tick(bool sysTick) { chan[i].state.ams=chan[i].std.ams.val; rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4)); } + if (chan[i].std.ex4.had && chan[i].active) { + chan[i].opMask=chan[i].std.ex4.val&15; + chan[i].opMaskChanged=true; + } for (int j=0; j<4; j++) { unsigned short baseAddr=chanOffs[i]|opOffs[j]; DivInstrumentFM::Operator& op=chan[i].state.op[j]; @@ -600,8 +604,9 @@ void DivPlatformYM2610B::tick(bool sysTick) { immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff); chan[i].freqChanged=false; } - if (chan[i].keyOn) { + if (chan[i].keyOn || chan[i].opMaskChanged) { immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]); + chan[i].opMaskChanged=false; chan[i].keyOn=false; } } diff --git a/src/engine/platform/ym2610b.h b/src/engine/platform/ym2610b.h index 87500e9b0..1d5fc1f31 100644 --- a/src/engine/platform/ym2610b.h +++ b/src/engine/platform/ym2610b.h @@ -40,7 +40,7 @@ class DivPlatformYM2610B: public DivPlatformYM2610Base { int freq, baseFreq, pitch, pitch2, portaPauseFreq, note, ins; unsigned char psgMode, autoEnvNum, autoEnvDen; signed char konCycles; - bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset; + bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM, hardReset, opMaskChanged; int vol, outVol; int sample; unsigned char pan, opMask; @@ -71,6 +71,7 @@ class DivPlatformYM2610B: public DivPlatformYM2610Base { inPorta(false), furnacePCM(false), hardReset(false), + opMaskChanged(false), vol(0), outVol(15), sample(-1),