From f483292a88dc1e89bd5ced889f1f921289006757 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 28 Jun 2022 01:16:46 -0500 Subject: [PATCH] OPN[A/B/2]?: implement 18xx effect --- src/engine/platform/fmshared_OPN.h | 6 ++++-- src/engine/platform/genesis.cpp | 7 +++++++ src/engine/platform/genesisext.cpp | 12 +++++++++++- src/engine/platform/ym2203.cpp | 7 +++++++ src/engine/platform/ym2203ext.cpp | 10 ++++++++++ src/engine/platform/ym2608.cpp | 7 +++++++ src/engine/platform/ym2608ext.cpp | 10 ++++++++++ src/engine/platform/ym2610.cpp | 7 +++++++ src/engine/platform/ym2610b.cpp | 7 +++++++ src/engine/platform/ym2610bext.cpp | 12 +++++++++++- src/engine/platform/ym2610ext.cpp | 12 +++++++++++- 11 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/engine/platform/fmshared_OPN.h b/src/engine/platform/fmshared_OPN.h index 0aaad16d4..406d7281b 100644 --- a/src/engine/platform/fmshared_OPN.h +++ b/src/engine/platform/fmshared_OPN.h @@ -104,12 +104,14 @@ class DivPlatformOPN: public DivPlatformFMBase { double fmFreqBase; unsigned int fmDivBase; unsigned int ayDiv; + bool extSys; - DivPlatformOPN(double f=9440540.0, unsigned int d=72, unsigned int a=32): + DivPlatformOPN(double f=9440540.0, unsigned int d=72, unsigned int a=32, bool isExtSys=false): DivPlatformFMBase(), fmFreqBase(f), fmDivBase(d), - ayDiv(a) {} + ayDiv(a), + extSys(isExtSys) {} }; diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index b3afdd2a3..fa06a699d 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -886,6 +886,13 @@ int DivPlatformGenesis::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; break; } + case DIV_CMD_FM_EXTCH: { + if (extSys) { + extMode=c.value; + immWrite(0x27,extMode?0x40:0); + } + break; + } case DIV_CMD_FM_LFO: { if (c.chan>=6) break; lfoValue=(c.value&7)|((c.value>>4)<<3); diff --git a/src/engine/platform/genesisext.cpp b/src/engine/platform/genesisext.cpp index cd4d603c1..1c44bcfb9 100644 --- a/src/engine/platform/genesisext.cpp +++ b/src/engine/platform/genesisext.cpp @@ -34,6 +34,10 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { } int ch=c.chan-2; int ordch=orderedOps[ch]; + if (!extMode) { + c.chan=2; + return DivPlatformGenesis::dispatch(c); + } switch (c.cmd) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM); @@ -173,6 +177,11 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { opChan[ch].freqChanged=true; break; } + case DIV_CMD_FM_EXTCH: { + extMode=c.value; + immWrite(0x27,extMode?0x40:0); + break; + } case DIV_CMD_FM_LFO: { lfoValue=(c.value&7)|((c.value>>4)<<3); rWrite(0x22,lfoValue); @@ -489,7 +498,7 @@ void DivPlatformGenesisExt::forceIns() { for (int j=0; j<4; j++) { unsigned short baseAddr=chanOffs[i]|opOffs[j]; DivInstrumentFM::Operator& op=chan[i].state.op[j]; - if (i==2) { // extended channel + if (i==2 && extMode) { // extended channel if (isOpMuted[j]) { rWrite(baseAddr+0x40,127); } else if (isOutput[chan[i].state.alg][j]) { @@ -592,6 +601,7 @@ int DivPlatformGenesisExt::init(DivEngine* parent, int channels, int sugRate, un for (int i=0; i<4; i++) { isOpMuted[i]=false; } + extSys=true; reset(); return 13; diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index e0bbe1a32..83c93c58e 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -659,6 +659,13 @@ int DivPlatformYM2203::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; break; } + case DIV_CMD_FM_EXTCH: { + if (extSys) { + extMode=c.value; + immWrite(0x27,extMode?0x40:0); + } + break; + } case DIV_CMD_FM_FB: { if (c.chan>2) break; chan[c.chan].state.fb=c.value&7; diff --git a/src/engine/platform/ym2203ext.cpp b/src/engine/platform/ym2203ext.cpp index d3fd3487b..3ff24eb74 100644 --- a/src/engine/platform/ym2203ext.cpp +++ b/src/engine/platform/ym2203ext.cpp @@ -34,6 +34,10 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) { } int ch=c.chan-2; int ordch=orderedOps[ch]; + if (!extMode) { + c.chan=2; + return DivPlatformYM2203::dispatch(c); + } switch (c.cmd) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM); @@ -151,6 +155,11 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) { opChan[ch].freqChanged=true; break; } + case DIV_CMD_FM_EXTCH: { + extMode=c.value; + immWrite(0x27,extMode?0x40:0); + break; + } case DIV_CMD_FM_LFO: { rWrite(0x22,(c.value&7)|((c.value>>4)<<3)); break; @@ -514,6 +523,7 @@ int DivPlatformYM2203Ext::init(DivEngine* parent, int channels, int sugRate, uns for (int i=0; i<4; i++) { isOpMuted[i]=false; } + extSys=true; reset(); return 9; diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 733f04812..b70efaf03 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -988,6 +988,13 @@ int DivPlatformYM2608::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; break; } + case DIV_CMD_FM_EXTCH: { + if (extSys) { + extMode=c.value; + immWrite(0x27,extMode?0x40:0); + } + break; + } case DIV_CMD_FM_LFO: { rWrite(0x22,(c.value&7)|((c.value>>4)<<3)); break; diff --git a/src/engine/platform/ym2608ext.cpp b/src/engine/platform/ym2608ext.cpp index 91c3a897f..63503ccc3 100644 --- a/src/engine/platform/ym2608ext.cpp +++ b/src/engine/platform/ym2608ext.cpp @@ -34,6 +34,10 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) { } int ch=c.chan-2; int ordch=orderedOps[ch]; + if (!extMode) { + c.chan=2; + return DivPlatformYM2608::dispatch(c); + } switch (c.cmd) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM); @@ -151,6 +155,11 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) { opChan[ch].freqChanged=true; break; } + case DIV_CMD_FM_EXTCH: { + extMode=c.value; + immWrite(0x27,extMode?0x40:0); + break; + } case DIV_CMD_FM_LFO: { rWrite(0x22,(c.value&7)|((c.value>>4)<<3)); break; @@ -528,6 +537,7 @@ int DivPlatformYM2608Ext::init(DivEngine* parent, int channels, int sugRate, uns for (int i=0; i<4; i++) { isOpMuted[i]=false; } + extSys=true; reset(); return 19; diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index bed59c203..1a67c4288 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -1032,6 +1032,13 @@ int DivPlatformYM2610::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; break; } + case DIV_CMD_FM_EXTCH: { + if (extSys) { + extMode=c.value; + immWrite(0x27,extMode?0x40:0); + } + break; + } case DIV_CMD_FM_LFO: { rWrite(0x22,(c.value&7)|((c.value>>4)<<3)); break; diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index a2291c3f4..600c89fd3 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -1014,6 +1014,13 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; break; } + case DIV_CMD_FM_EXTCH: { + if (extSys) { + extMode=c.value; + immWrite(0x27,extMode?0x40:0); + } + break; + } case DIV_CMD_FM_LFO: { rWrite(0x22,(c.value&7)|((c.value>>4)<<3)); break; diff --git a/src/engine/platform/ym2610bext.cpp b/src/engine/platform/ym2610bext.cpp index b5e1ac9fb..7c8247ff8 100644 --- a/src/engine/platform/ym2610bext.cpp +++ b/src/engine/platform/ym2610bext.cpp @@ -34,6 +34,10 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) { } int ch=c.chan-2; int ordch=orderedOps[ch]; + if (!extMode) { + c.chan=2; + return DivPlatformYM2610B::dispatch(c); + } switch (c.cmd) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM); @@ -151,6 +155,11 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) { opChan[ch].freqChanged=true; break; } + case DIV_CMD_FM_EXTCH: { + extMode=c.value; + immWrite(0x27,extMode?0x40:0); + break; + } case DIV_CMD_FM_LFO: { rWrite(0x22,(c.value&7)|((c.value>>4)<<3)); break; @@ -427,7 +436,7 @@ void DivPlatformYM2610BExt::forceIns() { for (int j=0; j<4; j++) { unsigned short baseAddr=chanOffs[i]|opOffs[j]; DivInstrumentFM::Operator& op=chan[i].state.op[j]; - if (i==2) { // extended channel + if (i==2 && extMode) { // extended channel if (isOpMuted[j]) { rWrite(baseAddr+0x40,127); } else if (isOutput[chan[i].state.alg][j]) { @@ -528,6 +537,7 @@ int DivPlatformYM2610BExt::init(DivEngine* parent, int channels, int sugRate, un for (int i=0; i<4; i++) { isOpMuted[i]=false; } + extSys=true; reset(); return 19; diff --git a/src/engine/platform/ym2610ext.cpp b/src/engine/platform/ym2610ext.cpp index 6f9c8700d..b2bd06a8c 100644 --- a/src/engine/platform/ym2610ext.cpp +++ b/src/engine/platform/ym2610ext.cpp @@ -34,6 +34,10 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) { } int ch=c.chan-1; int ordch=orderedOps[ch]; + if (!extMode) { + c.chan=2; + return DivPlatformYM2610::dispatch(c); + } switch (c.cmd) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM); @@ -151,6 +155,11 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) { opChan[ch].freqChanged=true; break; } + case DIV_CMD_FM_EXTCH: { + extMode=c.value; + immWrite(0x27,extMode?0x40:0); + break; + } case DIV_CMD_FM_LFO: { rWrite(0x22,(c.value&7)|((c.value>>4)<<3)); break; @@ -427,7 +436,7 @@ void DivPlatformYM2610Ext::forceIns() { for (int j=0; j<4; j++) { unsigned short baseAddr=chanOffs[i]|opOffs[j]; DivInstrumentFM::Operator& op=chan[i].state.op[j]; - if (i==1) { // extended channel + if (i==1 && extMode) { // extended channel if (isOpMuted[j]) { rWrite(baseAddr+0x40,127); } else if (isOutput[chan[i].state.alg][j]) { @@ -528,6 +537,7 @@ int DivPlatformYM2610Ext::init(DivEngine* parent, int channels, int sugRate, uns for (int i=0; i<4; i++) { isOpMuted[i]=false; } + extSys=true; reset(); return 17;