From b90fb02e635a4208f1207acb4be99892786fa59d Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 1 Mar 2022 23:07:29 -0500 Subject: [PATCH] OPLL: 99.9% all features usable, except for custom patchsets (not sure how am i gonna implement it) --- extern/Nuked-OPLL/opll.c | 22 +++++++++++++++++++ extern/Nuked-OPLL/opll.h | 2 ++ src/engine/platform/opll.cpp | 34 ++++++++++++++++++++++-------- src/engine/platform/opll.h | 2 ++ src/engine/song.h | 12 +++++++++++ src/gui/gui.cpp | 41 ++++++++++++++++++++++++++++++++++++ 6 files changed, 104 insertions(+), 9 deletions(-) diff --git a/extern/Nuked-OPLL/opll.c b/extern/Nuked-OPLL/opll.c index fd2aa239f..ecff69fd3 100644 --- a/extern/Nuked-OPLL/opll.c +++ b/extern/Nuked-OPLL/opll.c @@ -290,6 +290,28 @@ static void OPLL_DoModeWrite(opll_t *chip) { } } +const opll_patch_t* OPLL_GetPatchROM(uint32_t chip_type) { + switch (chip_type) { + case opll_type_ds1001: + return patch_ds1001; + break; + case opll_type_ymf281: + case opll_type_ymf281b: + return patch_ymf281; + break; + case opll_type_ym2423: + return patch_ym2423; + break; + case opll_type_ym2413: + case opll_type_ym2413b: + case opll_type_ym2420: + default: + return patch_ym2413; + break; + } + return patch_ym2413; +} + void OPLL_Reset(opll_t *chip, uint32_t chip_type) { uint32_t i; memset(chip, 0, sizeof(opll_t)); diff --git a/extern/Nuked-OPLL/opll.h b/extern/Nuked-OPLL/opll.h index 706eb9f3b..85c721a78 100644 --- a/extern/Nuked-OPLL/opll.h +++ b/extern/Nuked-OPLL/opll.h @@ -193,6 +193,8 @@ typedef struct { } opll_t; +const opll_patch_t* OPLL_GetPatchROM(uint32_t chip_type); + void OPLL_Reset(opll_t *chip, uint32_t chip_type); void OPLL_Clock(opll_t *chip, int32_t *buffer); void OPLL_Write(opll_t *chip, uint32_t port, uint8_t data); diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index b9949aa0d..08d46cf9d 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -25,7 +25,7 @@ #define rWrite(a,v) if (!skipRegisterWrites) {pendingWrites[a]=v;} #define immWrite(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} } -#define CHIP_FREQBASE 295017 +#define CHIP_FREQBASE 1180068 const char* DivPlatformOPLL::getEffectName(unsigned char effect) { switch (effect) { @@ -693,6 +693,20 @@ void DivPlatformOPLL::reset() { OPLL_Reset(&fm,opll_type_ds1001); } else { OPLL_Reset(&fm,opll_type_ym2413); + switch (patchSet) { + case 0: + fm.patchrom=OPLL_GetPatchROM(opll_type_ym2413); + break; + case 1: + fm.patchrom=OPLL_GetPatchROM(opll_type_ymf281); + break; + case 2: + fm.patchrom=OPLL_GetPatchROM(opll_type_ym2423); + break; + case 3: + fm.patchrom=OPLL_GetPatchROM(opll_type_ds1001); + break; + } } if (dumpWrites) { addWrite(0xffffffff,0); @@ -763,22 +777,24 @@ void DivPlatformOPLL::setYMFM(bool use) { } void DivPlatformOPLL::setFlags(unsigned int flags) { - if (flags==3) { - chipClock=COLOR_NTSC; - } else if (flags==2) { - chipClock=8000000.0; - } else if (flags==1) { - chipClock=COLOR_PAL*1.0/5.0; + if ((flags&15)==3) { + chipClock=COLOR_NTSC/2.0; + } else if ((flags&15)==2) { + chipClock=4000000.0; + } else if ((flags&15)==1) { + chipClock=COLOR_PAL*4.0/5.0; } else { - chipClock=COLOR_NTSC/4.0; + chipClock=COLOR_NTSC; } - rate=chipClock/9; + rate=chipClock/36; + patchSet=flags>>4; } int DivPlatformOPLL::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { parent=p; dumpWrites=false; skipRegisterWrites=false; + patchSet=0; for (int i=0; i<11; i++) { isMuted[i]=false; } diff --git a/src/engine/platform/opll.h b/src/engine/platform/opll.h index 382c23636..4a7a4c97f 100644 --- a/src/engine/platform/opll.h +++ b/src/engine/platform/opll.h @@ -78,6 +78,8 @@ class DivPlatformOPLL: public DivDispatch { bool drums; bool properDrums, properDrumsSys; bool vrc7; + + unsigned char patchSet; short oldWrites[256]; short pendingWrites[256]; diff --git a/src/engine/song.h b/src/engine/song.h index 85752288e..a992aa49f 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -220,6 +220,18 @@ struct DivSong { // - bit 0-11: echo delay length // - Valid values are 0-2725 // - 0 is max length, 2725 is min length + // - OPLL: + // - bit 0-3: clock rate + // - 0: NTSC (3.58MHz) + // - 1: PAL (3.55MHz) + // - 2: Other (4MHz) + // - 3: half NTSC (1.79MHz) + // - bit 4-7: patch set + // - 0: YM2413 + // - 1: YMF281 + // - 2: YM2423 + // - 3: VRC7 + // - 4: custom (TODO) unsigned int systemFlags[32]; // song information diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 50f45c1eb..50e883012 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -4635,6 +4635,47 @@ bool FurnaceGUI::loop() { } break; } + case DIV_SYSTEM_OPLL: + case DIV_SYSTEM_OPLL_DRUMS: + case DIV_SYSTEM_VRC7: { + ImGui::Text("Clock rate:"); + if (ImGui::RadioButton("NTSC (3.58MHz)",(flags&15)==0)) { + e->setSysFlags(i,(flags&(~15))|0,restart); + updateWindowTitle(); + } + if (ImGui::RadioButton("PAL (3.55MHz)",(flags&15)==1)) { + e->setSysFlags(i,(flags&(~15))|1,restart); + updateWindowTitle(); + } + if (ImGui::RadioButton("BBC Micro (4MHz)",(flags&15)==2)) { + e->setSysFlags(i,(flags&(~15))|2,restart); + updateWindowTitle(); + } + if (ImGui::RadioButton("Half NTSC (1.79MHz)",(flags&15)==3)) { + e->setSysFlags(i,(flags&(~15))|3,restart); + updateWindowTitle(); + } + if (e->song.system[i]!=DIV_SYSTEM_VRC7) { + ImGui::Text("Patch set:"); + if (ImGui::RadioButton("Yamaha YM2413",((flags>>4)&15)==0)) { + e->setSysFlags(i,(flags&(~0xf0))|0,restart); + updateWindowTitle(); + } + if (ImGui::RadioButton("Yamaha YMF281",((flags>>4)&15)==1)) { + e->setSysFlags(i,(flags&(~0xf0))|0x10,restart); + updateWindowTitle(); + } + if (ImGui::RadioButton("Yamaha YM2423",((flags>>4)&15)==2)) { + e->setSysFlags(i,(flags&(~0xf0))|0x20,restart); + updateWindowTitle(); + } + if (ImGui::RadioButton("Konami VRC7",((flags>>4)&15)==3)) { + e->setSysFlags(i,(flags&(~0xf0))|0x30,restart); + updateWindowTitle(); + } + } + break; + } case DIV_SYSTEM_YM2151: if (ImGui::RadioButton("NTSC (3.58MHz)",flags==0)) { e->setSysFlags(i,0,restart);