From ec007b44430825ec4f89d196988af00018012297 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 7 Mar 2022 18:19:25 -0500 Subject: [PATCH] OPL: more work - still not there yet --- src/engine/platform/opl.cpp | 95 +++++++++++++++++++------------------ src/gui/gui.cpp | 12 +++++ src/gui/insEdit.cpp | 17 ++++++- 3 files changed, 77 insertions(+), 47 deletions(-) diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 50cdda389..fbcc643bb 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -30,14 +30,14 @@ // N = invalid #define N 255 -const unsigned char slotsOPL2[4][20]={ +const unsigned char slotsOPL2i[4][20]={ {0, 1, 2, 6, 7, 8, 12, 13, 14}, // OP1 {3, 4, 5, 9, 10, 11, 15, 16, 17}, // OP2 {N, N, N, N, N, N, N, N, N}, {N, N, N, N, N, N, N, N, N} }; -const unsigned char slotsOPL2Drums[4][20]={ +const unsigned char slotsOPL2Drumsi[4][20]={ {0, 1, 2, 6, 7, 8, 12, 16, 14, 17, 13}, // OP1 {3, 4, 5, 9, 10, 11, 15, N, N, N, N}, // OP2 {N, N, N, N, N, N, N, N, N, N, N}, @@ -48,14 +48,28 @@ const unsigned short chanMapOPL2[20]={ 0, 1, 2, 3, 4, 5, 6, 7, 8, N, N, N, N, N, N, N, N, N, N, N }; -const unsigned char slotsOPL3[4][20]={ +const unsigned char* slotsOPL2[4]={ + slotsOPL2i[0], + slotsOPL2i[1], + slotsOPL2i[2], + slotsOPL2i[3] +}; + +const unsigned char* slotsOPL2Drums[4]={ + slotsOPL2Drumsi[0], + slotsOPL2Drumsi[1], + slotsOPL2Drumsi[2], + slotsOPL2Drumsi[3] +}; + +const unsigned char slotsOPL3i[4][20]={ {0, 6, 1, 7, 2, 8, 18, 24, 19, 25, 20, 26, 30, 31, 32, 12, 13, 14}, // OP1 {3, 9, 4, 10, 5, 11, 21, 27, 22, 28, 23, 29, 33, 34, 35, 15, 16, 17}, // OP2 {6, N, 7, N, 8, N, 24, N, 25, N, 26, N, N, N, N, N, N, N}, // OP3 {9, N, 10, N, 11, N, 27, N, 28, N, 29, N, N, N, N, N, N, N} // OP4 }; -const unsigned char slotsOPL3Drums[4][20]={ +const unsigned char slotsOPL3Drumsi[4][20]={ {0, 6, 1, 7, 2, 8, 18, 24, 19, 25, 20, 26, 30, 31, 32, 12, 16, 14, 17, 13}, // OP1 {3, 9, 4, 10, 5, 11, 21, 27, 22, 28, 23, 29, 33, 34, 35, N, N, N, N, N}, // OP2 {6, N, 7, N, 8, N, 24, N, 25, N, 26, N, N, N, N, N, N, N, N, N}, // OP3 @@ -66,6 +80,20 @@ const unsigned short chanMapOPL3[20]={ 0, 3, 1, 4, 2, 5, 0x100, 0x103, 0x101, 0x104, 0x102, 0x105, 0x106, 0x107, 0x108, 6, 7, 8, N, N }; +const unsigned char* slotsOPL3[4]={ + slotsOPL3i[0], + slotsOPL3i[1], + slotsOPL3i[2], + slotsOPL3i[3] +}; + +const unsigned char* slotsOPL3Drums[4]={ + slotsOPL3Drumsi[0], + slotsOPL3Drumsi[1], + slotsOPL3Drumsi[2], + slotsOPL3Drumsi[3] +}; + const unsigned int slotMap[36]={ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, @@ -167,18 +195,8 @@ void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_ if (!writes.empty() && --delay<0) { delay=12; QueuedWrite& w=writes.front(); - if (w.addrOrVal) { - OPL3_WriteReg(&fm,0x1+((w.addr>>8)<<1),w.val); - //printf("write: %x = %.2x\n",w.addr,w.val); - lastBusy=0; - regPool[w.addr&0x1ff]=w.val; - writes.pop(); - } else { - lastBusy++; - //printf("busycounter: %d\n",lastBusy); - OPL3_WriteReg(&fm,0x0+((w.addr>>8)<<1),w.addr); - w.addrOrVal=true; - } + OPL3_WriteReg(&fm,w.addr,w.val); + writes.pop(); } OPL3_Generate(&fm,o); os[0]+=o[0]; os[1]+=o[1]; @@ -203,11 +221,10 @@ void DivPlatformOPL::acquire(short* bufL, short* bufR, size_t start, size_t len) } void DivPlatformOPL::tick() { - /* for (int i=0; i<20; i++) { - if (i==2 && extMode) continue; chan[i].std.next(); + /* if (chan[i].std.hadVol) { chan[i].outVol=(chan[i].vol*MIN(127,chan[i].std.vol))/127; for (int j=0; j<4; j++) { @@ -327,13 +344,13 @@ void DivPlatformOPL::tick() { rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15); } } + */ if (chan[i].keyOn || chan[i].keyOff) { - immWrite(0x28,0x00|konOffs[i]); + immWrite(chanMap[i]+ADDR_FREQH,0x00|(chan[i].freqH&31)); chan[i].keyOff=false; } } - */ for (int i=0; i<512; i++) { if (pendingWrites[i]!=oldWrites[i]) { @@ -342,36 +359,23 @@ void DivPlatformOPL::tick() { } } - /* for (int i=0; i<20; i++) { if (chan[i].freqChanged) { chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq)); if (chan[i].freq>262143) chan[i].freq=262143; int freqt=toFreq(chan[i].freq); - immWrite(chanOffs[i]+ADDR_FREQH,freqt>>8); - immWrite(chanOffs[i]+ADDR_FREQ,freqt&0xff); - if (chan[i].furnaceDac && dacMode) { - double off=1.0; - if (dacSample>=0 && dacSamplesong.sampleLen) { - DivSample* s=parent->getSample(dacSample); - if (s->centerRate<1) { - off=1.0; - } else { - off=8363.0/(double)s->centerRate; - } - } - dacRate=(1280000*1.25*off)/MAX(1,chan[i].baseFreq); - if (dacRate<1) dacRate=1; - if (dumpWrites) addWrite(0xffff0001,1280000/dacRate); - } - chan[i].freqChanged=false; + chan[i].freqH=freqt>>8; + chan[i].freqL=freqt&0xff; + immWrite(chanMap[i]+ADDR_FREQ,chan[i].freqL); } if (chan[i].keyOn) { - immWrite(0x28,0xf0|konOffs[i]); + immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(0x20)); chan[i].keyOn=false; + } else if (chan[i].freqChanged) { + immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(chan[i].active<<5)); } + chan[i].freqChanged=false; } - */ } int DivPlatformOPL::octave(int freq) { @@ -395,6 +399,7 @@ int DivPlatformOPL::octave(int freq) { return 1; } +// TODO int DivPlatformOPL::toFreq(int freq) { if (freq>=82432) { return 0x3800|((freq>>7)&0x7ff); @@ -659,7 +664,7 @@ int DivPlatformOPL::dispatch(DivCommand c) { return 0; break; case DIV_CMD_GET_VOLMAX: - return 127; + return 63; break; case DIV_CMD_PRE_PORTA: chan[c.chan].inPorta=c.value; @@ -801,14 +806,14 @@ void DivPlatformOPL::setYMFM(bool use) { void DivPlatformOPL::setOPLType(int type, bool drums) { switch (type) { case 1: case 2: - slotsNonDrums=(const unsigned char**)slotsOPL2; - slotsDrums=(const unsigned char**)slotsOPL2Drums; + slotsNonDrums=slotsOPL2; + slotsDrums=slotsOPL2Drums; slots=drums?slotsDrums:slotsNonDrums; chanMap=chanMapOPL2; break; case 3: - slotsNonDrums=(const unsigned char**)slotsOPL3; - slotsDrums=(const unsigned char**)slotsOPL3Drums; + slotsNonDrums=slotsOPL3; + slotsDrums=slotsOPL3Drums; slots=drums?slotsDrums:slotsNonDrums; chanMap=chanMapOPL3; break; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index fb3e6fc31..06f102de1 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -4629,6 +4629,12 @@ bool FurnaceGUI::loop() { sysAddOption(DIV_SYSTEM_OPLL); sysAddOption(DIV_SYSTEM_OPLL_DRUMS); sysAddOption(DIV_SYSTEM_VRC7); + sysAddOption(DIV_SYSTEM_OPL); + sysAddOption(DIV_SYSTEM_OPL_DRUMS); + sysAddOption(DIV_SYSTEM_OPL2); + sysAddOption(DIV_SYSTEM_OPL2_DRUMS); + sysAddOption(DIV_SYSTEM_OPL3); + sysAddOption(DIV_SYSTEM_OPL3_DRUMS); sysAddOption(DIV_SYSTEM_TIA); sysAddOption(DIV_SYSTEM_SAA1099); sysAddOption(DIV_SYSTEM_AY8930); @@ -4974,6 +4980,12 @@ bool FurnaceGUI::loop() { sysChangeOption(i,DIV_SYSTEM_OPLL); sysChangeOption(i,DIV_SYSTEM_OPLL_DRUMS); sysChangeOption(i,DIV_SYSTEM_VRC7); + sysChangeOption(i,DIV_SYSTEM_OPL); + sysChangeOption(i,DIV_SYSTEM_OPL_DRUMS); + sysChangeOption(i,DIV_SYSTEM_OPL2); + sysChangeOption(i,DIV_SYSTEM_OPL2_DRUMS); + sysChangeOption(i,DIV_SYSTEM_OPL3); + sysChangeOption(i,DIV_SYSTEM_OPL3_DRUMS); sysChangeOption(i,DIV_SYSTEM_TIA); sysChangeOption(i,DIV_SYSTEM_SAA1099); sysChangeOption(i,DIV_SYSTEM_AY8930); diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 6ff30896f..b05f315ef 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -796,7 +796,8 @@ void FurnaceGUI::drawInsEdit() { int asInt[256]; float loopIndicator[256]; int opCount=4; - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL) opCount=2; + if (ins->type==DIV_INS_OPLL) opCount=2; + if (ins->type==DIV_INS_OPL) opCount=(ins->fm.ops==4)?4:2; if (ImGui::BeginTabItem("FM")) { if (ImGui::BeginTable("fmDetails",3,ImGuiTableFlags_SizingStretchSame)) { @@ -816,7 +817,19 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextColumn(); drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); break; - case DIV_INS_OPL: + case DIV_INS_OPL: { + bool fourOp=(ins->fm.ops==4); + ImGui::TableNextColumn(); + P(ImGui::SliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER + ins->fm.ops=fourOp?4:2; + } + ImGui::TableNextColumn(); + P(ImGui::SliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + drawAlgorithm(ins->fm.alg&1,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + break; + } case DIV_INS_OPLL: { bool dc=ins->fm.fms; bool dm=ins->fm.ams;