From e23dcd6e1bf622e2f2148893534f1024a4077512 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 10 Apr 2022 03:04:31 -0500 Subject: [PATCH] implement hard reset on OPM/OPZ/OPNB --- src/engine/platform/arcade.cpp | 20 ++++++++++++++++++++ src/engine/platform/tx81z.cpp | 23 +++++++++++++++++++++++ src/engine/platform/ym2610.cpp | 24 ++++++++++++++++++++++++ src/engine/platform/ym2610b.cpp | 24 ++++++++++++++++++++++++ 4 files changed, 91 insertions(+) diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index e9618f29b..f570dd6ed 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -369,7 +369,24 @@ void DivPlatformArcade::tick() { } } 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; + } + } immWrite(0x08,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<9; k++) { + immWrite(baseAddr+ADDR_SL_RR,0x0f); + } + } + } chan[i].keyOff=false; } } @@ -605,6 +622,9 @@ int DivPlatformArcade::dispatch(DivCommand c) { immWrite(0x19,0x80|pmDepth); break; } + case DIV_CMD_FM_HARD_RESET: + chan[c.chan].hardReset=c.value; + break; case DIV_CMD_STD_NOISE_FREQ: { if (c.chan!=7) break; if (c.value) { diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index e9e817cd7..aa4cf1f20 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -137,6 +137,9 @@ const char* DivPlatformTX81Z::getEffectName(unsigned char effect) { case 0x1f: return "1Fxx: Set PM depth (0 to 7F)"; break; + case 0x30: + return "30xx: Toggle hard envelope reset on new notes"; + break; } return NULL; } @@ -330,12 +333,29 @@ void DivPlatformTX81Z::tick() { } } 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; + } + } if (isMuted[i]) { immWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)|0x00); } else { //if (chan[i].keyOn) immWrite(0x08,i); immWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)|0x00|(chan[i].chVolR<<7)); } + 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<9; k++) { + immWrite(baseAddr+ADDR_SL_RR,0x0f); + } + } + } chan[i].keyOff=false; } } @@ -596,6 +616,9 @@ int DivPlatformTX81Z::dispatch(DivCommand c) { immWrite(0x19,0x80|pmDepth); break; } + case DIV_CMD_FM_HARD_RESET: + chan[c.chan].hardReset=c.value; + break; case DIV_CMD_STD_NOISE_FREQ: { if (c.chan!=7) break; if (c.value) { diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 77c1243bd..0994f0e55 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -309,6 +309,9 @@ const char* DivPlatformYM2610::getEffectName(unsigned char effect) { case 0x29: return "29xy: Set SSG auto-envelope (x: numerator; y: denominator)"; break; + case 0x30: + return "30xx: Toggle hard envelope reset on new notes"; + break; } return NULL; } @@ -489,7 +492,25 @@ void DivPlatformYM2610::tick() { } 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]); + 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<100; k++) { + immWrite(baseAddr+ADDR_SL_RR,0x0f); + } + } + } chan[i].keyOff=false; } } @@ -930,6 +951,9 @@ int DivPlatformYM2610::dispatch(DivCommand c) { } break; } + case DIV_CMD_FM_HARD_RESET: + chan[c.chan].hardReset=c.value; + break; case DIV_ALWAYS_SET_VOLUME: return 0; break; diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index dfd847235..7e8c25194 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -373,6 +373,9 @@ const char* DivPlatformYM2610B::getEffectName(unsigned char effect) { case 0x29: return "29xy: Set SSG auto-envelope (x: numerator; y: denominator)"; break; + case 0x30: + return "30xx: Toggle hard envelope reset on new notes"; + break; } return NULL; } @@ -553,7 +556,25 @@ void DivPlatformYM2610B::tick() { } 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]); + 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<100; k++) { + immWrite(baseAddr+ADDR_SL_RR,0x0f); + } + } + } chan[i].keyOff=false; } } @@ -993,6 +1014,9 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { } break; } + case DIV_CMD_FM_HARD_RESET: + chan[c.chan].hardReset=c.value; + break; case DIV_ALWAYS_SET_VOLUME: return 0; break;