OPL: more work - still not there yet

This commit is contained in:
tildearrow 2022-03-07 18:19:25 -05:00
parent 03d2f87804
commit ec007b4443
3 changed files with 77 additions and 47 deletions

View file

@ -30,14 +30,14 @@
// N = invalid // N = invalid
#define N 255 #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 {0, 1, 2, 6, 7, 8, 12, 13, 14}, // OP1
{3, 4, 5, 9, 10, 11, 15, 16, 17}, // OP2 {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},
{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 {0, 1, 2, 6, 7, 8, 12, 16, 14, 17, 13}, // OP1
{3, 4, 5, 9, 10, 11, 15, N, N, N, N}, // OP2 {3, 4, 5, 9, 10, 11, 15, N, N, N, N}, // OP2
{N, N, N, N, N, N, N, N, N, N, N}, {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 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 {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 {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 {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 {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 {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 {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 {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 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]={ const unsigned int slotMap[36]={
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 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) { if (!writes.empty() && --delay<0) {
delay=12; delay=12;
QueuedWrite& w=writes.front(); QueuedWrite& w=writes.front();
if (w.addrOrVal) { OPL3_WriteReg(&fm,w.addr,w.val);
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(); writes.pop();
} else {
lastBusy++;
//printf("busycounter: %d\n",lastBusy);
OPL3_WriteReg(&fm,0x0+((w.addr>>8)<<1),w.addr);
w.addrOrVal=true;
}
} }
OPL3_Generate(&fm,o); os[0]+=o[0]; os[1]+=o[1]; 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() { void DivPlatformOPL::tick() {
/*
for (int i=0; i<20; i++) { for (int i=0; i<20; i++) {
if (i==2 && extMode) continue;
chan[i].std.next(); chan[i].std.next();
/*
if (chan[i].std.hadVol) { if (chan[i].std.hadVol) {
chan[i].outVol=(chan[i].vol*MIN(127,chan[i].std.vol))/127; chan[i].outVol=(chan[i].vol*MIN(127,chan[i].std.vol))/127;
for (int j=0; j<4; j++) { for (int j=0; j<4; j++) {
@ -327,13 +344,13 @@ void DivPlatformOPL::tick() {
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15); rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
} }
} }
*/
if (chan[i].keyOn || chan[i].keyOff) { 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; chan[i].keyOff=false;
} }
} }
*/
for (int i=0; i<512; i++) { for (int i=0; i<512; i++) {
if (pendingWrites[i]!=oldWrites[i]) { if (pendingWrites[i]!=oldWrites[i]) {
@ -342,36 +359,23 @@ void DivPlatformOPL::tick() {
} }
} }
/*
for (int i=0; i<20; i++) { for (int i=0; i<20; i++) {
if (chan[i].freqChanged) { if (chan[i].freqChanged) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq)); 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; if (chan[i].freq>262143) chan[i].freq=262143;
int freqt=toFreq(chan[i].freq); int freqt=toFreq(chan[i].freq);
immWrite(chanOffs[i]+ADDR_FREQH,freqt>>8); chan[i].freqH=freqt>>8;
immWrite(chanOffs[i]+ADDR_FREQ,freqt&0xff); chan[i].freqL=freqt&0xff;
if (chan[i].furnaceDac && dacMode) { immWrite(chanMap[i]+ADDR_FREQ,chan[i].freqL);
double off=1.0;
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
DivSample* s=parent->getSample(dacSample);
if (s->centerRate<1) {
off=1.0;
} else {
off=8363.0/(double)s->centerRate;
} }
} if (chan[i].keyOn) {
dacRate=(1280000*1.25*off)/MAX(1,chan[i].baseFreq); immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(0x20));
if (dacRate<1) dacRate=1; chan[i].keyOn=false;
if (dumpWrites) addWrite(0xffff0001,1280000/dacRate); } else if (chan[i].freqChanged) {
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(chan[i].active<<5));
} }
chan[i].freqChanged=false; chan[i].freqChanged=false;
} }
if (chan[i].keyOn) {
immWrite(0x28,0xf0|konOffs[i]);
chan[i].keyOn=false;
}
}
*/
} }
int DivPlatformOPL::octave(int freq) { int DivPlatformOPL::octave(int freq) {
@ -395,6 +399,7 @@ int DivPlatformOPL::octave(int freq) {
return 1; return 1;
} }
// TODO
int DivPlatformOPL::toFreq(int freq) { int DivPlatformOPL::toFreq(int freq) {
if (freq>=82432) { if (freq>=82432) {
return 0x3800|((freq>>7)&0x7ff); return 0x3800|((freq>>7)&0x7ff);
@ -659,7 +664,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
return 0; return 0;
break; break;
case DIV_CMD_GET_VOLMAX: case DIV_CMD_GET_VOLMAX:
return 127; return 63;
break; break;
case DIV_CMD_PRE_PORTA: case DIV_CMD_PRE_PORTA:
chan[c.chan].inPorta=c.value; chan[c.chan].inPorta=c.value;
@ -801,14 +806,14 @@ void DivPlatformOPL::setYMFM(bool use) {
void DivPlatformOPL::setOPLType(int type, bool drums) { void DivPlatformOPL::setOPLType(int type, bool drums) {
switch (type) { switch (type) {
case 1: case 2: case 1: case 2:
slotsNonDrums=(const unsigned char**)slotsOPL2; slotsNonDrums=slotsOPL2;
slotsDrums=(const unsigned char**)slotsOPL2Drums; slotsDrums=slotsOPL2Drums;
slots=drums?slotsDrums:slotsNonDrums; slots=drums?slotsDrums:slotsNonDrums;
chanMap=chanMapOPL2; chanMap=chanMapOPL2;
break; break;
case 3: case 3:
slotsNonDrums=(const unsigned char**)slotsOPL3; slotsNonDrums=slotsOPL3;
slotsDrums=(const unsigned char**)slotsOPL3Drums; slotsDrums=slotsOPL3Drums;
slots=drums?slotsDrums:slotsNonDrums; slots=drums?slotsDrums:slotsNonDrums;
chanMap=chanMapOPL3; chanMap=chanMapOPL3;
break; break;

View file

@ -4629,6 +4629,12 @@ bool FurnaceGUI::loop() {
sysAddOption(DIV_SYSTEM_OPLL); sysAddOption(DIV_SYSTEM_OPLL);
sysAddOption(DIV_SYSTEM_OPLL_DRUMS); sysAddOption(DIV_SYSTEM_OPLL_DRUMS);
sysAddOption(DIV_SYSTEM_VRC7); 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_TIA);
sysAddOption(DIV_SYSTEM_SAA1099); sysAddOption(DIV_SYSTEM_SAA1099);
sysAddOption(DIV_SYSTEM_AY8930); sysAddOption(DIV_SYSTEM_AY8930);
@ -4974,6 +4980,12 @@ bool FurnaceGUI::loop() {
sysChangeOption(i,DIV_SYSTEM_OPLL); sysChangeOption(i,DIV_SYSTEM_OPLL);
sysChangeOption(i,DIV_SYSTEM_OPLL_DRUMS); sysChangeOption(i,DIV_SYSTEM_OPLL_DRUMS);
sysChangeOption(i,DIV_SYSTEM_VRC7); 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_TIA);
sysChangeOption(i,DIV_SYSTEM_SAA1099); sysChangeOption(i,DIV_SYSTEM_SAA1099);
sysChangeOption(i,DIV_SYSTEM_AY8930); sysChangeOption(i,DIV_SYSTEM_AY8930);

View file

@ -796,7 +796,8 @@ void FurnaceGUI::drawInsEdit() {
int asInt[256]; int asInt[256];
float loopIndicator[256]; float loopIndicator[256];
int opCount=4; 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::BeginTabItem("FM")) {
if (ImGui::BeginTable("fmDetails",3,ImGuiTableFlags_SizingStretchSame)) { if (ImGui::BeginTable("fmDetails",3,ImGuiTableFlags_SizingStretchSame)) {
@ -816,7 +817,19 @@ void FurnaceGUI::drawInsEdit() {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
break; 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: { case DIV_INS_OPLL: {
bool dc=ins->fm.fms; bool dc=ins->fm.fms;
bool dm=ins->fm.ams; bool dm=ins->fm.ams;