OPL: kind of fix 4-op mode

This commit is contained in:
tildearrow 2022-03-14 02:30:25 -05:00
parent 32581bb228
commit 42df8255fc
2 changed files with 49 additions and 13 deletions

View File

@ -349,10 +349,21 @@ void DivPlatformOPL::tick() {
if (chan[i].keyOn || chan[i].keyOff) { if (chan[i].keyOn || chan[i].keyOff) {
immWrite(chanMap[i]+ADDR_FREQH,0x00|(chan[i].freqH&31)); immWrite(chanMap[i]+ADDR_FREQH,0x00|(chan[i].freqH&31));
if (chan[i].state.ops==4 && i<6) {
immWrite(chanMap[i+1]+ADDR_FREQH,0x00|(chan[i].freqH&31));
}
chan[i].keyOff=false; chan[i].keyOff=false;
} }
} }
if (update4OpMask) {
update4OpMask=false;
if (oplType==3) {
unsigned char opMask=chan[0].fourOp|(chan[2].fourOp<<1)|(chan[4].fourOp<<2)|(chan[6].fourOp<<3)|(chan[8].fourOp<<4)|(chan[10].fourOp<<5);
rWrite(0x104,opMask);
}
}
for (int i=0; i<512; i++) { for (int i=0; i<512; i++) {
if (pendingWrites[i]!=oldWrites[i]) { if (pendingWrites[i]!=oldWrites[i]) {
immWrite(i,pendingWrites[i]&0xff); immWrite(i,pendingWrites[i]&0xff);
@ -368,12 +379,21 @@ void DivPlatformOPL::tick() {
chan[i].freqH=freqt>>8; chan[i].freqH=freqt>>8;
chan[i].freqL=freqt&0xff; chan[i].freqL=freqt&0xff;
immWrite(chanMap[i]+ADDR_FREQ,chan[i].freqL); immWrite(chanMap[i]+ADDR_FREQ,chan[i].freqL);
if (chan[i].state.ops==4 && i<6) {
immWrite(chanMap[i+1]+ADDR_FREQ,chan[i].freqL);
}
} }
if (chan[i].keyOn) { if (chan[i].keyOn) {
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(0x20)); immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(0x20));
if (chan[i].state.ops==4 && i<6) {
immWrite(chanMap[i+1]+ADDR_FREQH,chan[i].freqH|(0x20));
}
chan[i].keyOn=false; chan[i].keyOn=false;
} else if (chan[i].freqChanged) { } else if (chan[i].freqChanged) {
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(chan[i].active<<5)); immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(chan[i].active<<5));
if (chan[i].state.ops==4 && i<6) {
immWrite(chanMap[i+1]+ADDR_FREQH,chan[i].freqH|(chan[i].active<<5));
}
} }
chan[i].freqChanged=false; chan[i].freqChanged=false;
} }
@ -457,6 +477,8 @@ int DivPlatformOPL::dispatch(DivCommand c) {
} }
if (chan[c.chan].insChanged) { if (chan[c.chan].insChanged) {
int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2; int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
chan[c.chan].fourOp=(ops==4);
update4OpMask=true;
for (int i=0; i<ops; i++) { for (int i=0; i<ops; i++) {
unsigned char slot=slots[i][c.chan]; unsigned char slot=slots[i][c.chan];
if (slot==255) continue; if (slot==255) continue;
@ -554,16 +576,22 @@ int DivPlatformOPL::dispatch(DivCommand c) {
chan[c.chan].ins=c.value; chan[c.chan].ins=c.value;
break; break;
case DIV_CMD_PANNING: { case DIV_CMD_PANNING: {
switch (c.value) { if (c.value==0) {
case 0x01: chan[c.chan].pan=3;
chan[c.chan].pan=1; } else {
break; chan[c.chan].pan=(((c.value&15)>0)<<1)|((c.value>>4)>0);
case 0x10: }
chan[c.chan].pan=2; int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
break; if (isMuted[c.chan]) {
default: rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1));
chan[c.chan].pan=3; if (ops==4) {
break; rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1));
}
} else {
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
if (ops==4) {
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
}
} }
//rWrite(chanOffs[c.chan]+ADDR_LRAF,(isMuted[c.chan]?0:(chan[c.chan].pan<<6))|(chan[c.chan].state.fms&7)|((chan[c.chan].state.ams&3)<<4)); //rWrite(chanOffs[c.chan]+ADDR_LRAF,(isMuted[c.chan]?0:(chan[c.chan].pan<<6))|(chan[c.chan].state.fms&7)|((chan[c.chan].state.ams&3)<<4));
break; break;
@ -687,6 +715,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
void DivPlatformOPL::forceIns() { void DivPlatformOPL::forceIns() {
for (int i=0; i<18; i++) { for (int i=0; i<18; i++) {
int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2; int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2;
chan[i].fourOp=(ops==4);
for (int j=0; j<ops; j++) { for (int j=0; j<ops; j++) {
unsigned char slot=slots[j][i]; unsigned char slot=slots[j][i];
if (slot==255) continue; if (slot==255) continue;
@ -723,6 +752,7 @@ void DivPlatformOPL::forceIns() {
} }
} }
} }
update4OpMask=true;
} }
void DivPlatformOPL::toggleRegisterDump(bool enable) { void DivPlatformOPL::toggleRegisterDump(bool enable) {
@ -768,10 +798,15 @@ void DivPlatformOPL::reset() {
lfoValue=8; lfoValue=8;
properDrums=properDrumsSys; properDrums=properDrumsSys;
if (oplType==1) { // disable waveforms
immWrite(0x01,0x20);
}
if (oplType==3) { // enable OPL3 features if (oplType==3) { // enable OPL3 features
immWrite(0x105,1); immWrite(0x105,1);
} }
update4OpMask=true;
delay=0; delay=0;
} }

View File

@ -32,7 +32,7 @@ class DivPlatformOPL: public DivDispatch {
unsigned char freqH, freqL; unsigned char freqH, freqL;
int freq, baseFreq, pitch, note; int freq, baseFreq, pitch, note;
unsigned char ins; unsigned char ins;
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta; bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta, fourOp;
int vol, outVol; int vol, outVol;
unsigned char pan; unsigned char pan;
Channel(): Channel():
@ -51,6 +51,7 @@ class DivPlatformOPL: public DivDispatch {
portaPause(false), portaPause(false),
furnaceDac(false), furnaceDac(false),
inPorta(false), inPorta(false),
fourOp(false),
vol(0), vol(0),
pan(3) {} pan(3) {}
}; };
@ -78,7 +79,7 @@ class DivPlatformOPL: public DivDispatch {
unsigned char lfoValue; unsigned char lfoValue;
bool useYMFM; bool useYMFM, update4OpMask;
short oldWrites[512]; short oldWrites[512];
short pendingWrites[512]; short pendingWrites[512];