OPLL: don't write to out of range registers

fixes OPLLTest(1).zip
This commit is contained in:
tildearrow 2022-03-03 18:19:51 -05:00
parent 6132aa666e
commit 3a6f664cf0
1 changed files with 27 additions and 10 deletions

View File

@ -133,8 +133,10 @@ void DivPlatformOPLL::tick() {
if (chan[i].std.hadVol) { if (chan[i].std.hadVol) {
chan[i].outVol=(chan[i].vol*MIN(15,chan[i].std.vol))/15; chan[i].outVol=(chan[i].vol*MIN(15,chan[i].std.vol))/15;
if (i<9) {
rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4)); rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4));
} }
}
if (chan[i].std.hadArp) { if (chan[i].std.hadArp) {
if (!chan[i].inPorta) { if (!chan[i].inPorta) {
@ -201,7 +203,9 @@ void DivPlatformOPLL::tick() {
if (m.hadTl) { if (m.hadTl) {
op.tl=((j==1)?15:63)-m.tl; op.tl=((j==1)?15:63)-m.tl;
if (j==1) { if (j==1) {
if (i<9) {
rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4)); rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4));
}
} else { } else {
rWrite(0x02,(chan[i].state.op[0].ksl<<6)|(op.tl&63)); rWrite(0x02,(chan[i].state.op[0].ksl<<6)|(op.tl&63));
} }
@ -238,8 +242,10 @@ void DivPlatformOPLL::tick() {
drumState&=~(0x10>>(chan[i].note%12)); drumState&=~(0x10>>(chan[i].note%12));
immWrite(0x0e,0x20|drumState); immWrite(0x0e,0x20|drumState);
} else { } else {
if (i<9) {
immWrite(0x20+i,(chan[i].freqH)/*|(chan[i].state.alg?0x20:0)*/); immWrite(0x20+i,(chan[i].freqH)/*|(chan[i].state.alg?0x20:0)*/);
} }
}
//chan[i].keyOn=false; //chan[i].keyOn=false;
chan[i].keyOff=false; chan[i].keyOff=false;
} }
@ -262,8 +268,9 @@ void DivPlatformOPLL::tick() {
immWrite(0x10+drumSlot[i],freqt&0xff); immWrite(0x10+drumSlot[i],freqt&0xff);
immWrite(0x20+drumSlot[i],freqt>>8); immWrite(0x20+drumSlot[i],freqt>>8);
} else if (i<6 || !drums) { } else if (i<6 || !drums) {
if (i<9) {
immWrite(0x10+i,freqt&0xff); immWrite(0x10+i,freqt&0xff);
// TODO high byte? }
} }
chan[i].freqH=freqt>>8; chan[i].freqH=freqt>>8;
} }
@ -281,8 +288,10 @@ void DivPlatformOPLL::tick() {
} else if ((chan[i].keyOn || chan[i].freqChanged) && i<9) { } else if ((chan[i].keyOn || chan[i].freqChanged) && i<9) {
//immWrite(0x28,0xf0|konOffs[i]); //immWrite(0x28,0xf0|konOffs[i]);
if (!(i>=6 && properDrums)) { if (!(i>=6 && properDrums)) {
if (i<9) {
immWrite(0x20+i,(chan[i].freqH)|(chan[i].active<<4)|(chan[i].state.alg?0x20:0)); immWrite(0x20+i,(chan[i].freqH)|(chan[i].active<<4)|(chan[i].state.alg?0x20:0));
} }
}
chan[i].keyOn=false; chan[i].keyOn=false;
} }
chan[i].freqChanged=false; chan[i].freqChanged=false;
@ -413,9 +422,11 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
immWrite(0x0e,0); immWrite(0x0e,0);
} }
} }
if (c.chan<9) {
rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4)); rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4));
} }
} }
}
chan[c.chan].insChanged=false; chan[c.chan].insChanged=false;
@ -481,8 +492,10 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
rWrite(0x38,drumVol[3]|(drumVol[2]<<4)); rWrite(0x38,drumVol[3]|(drumVol[2]<<4));
break; break;
} else if (c.chan<6 || !drums) { } else if (c.chan<6 || !drums) {
if (c.chan<9) {
rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4)); rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4));
} }
}
break; break;
} }
case DIV_CMD_GET_VOLUME: { case DIV_CMD_GET_VOLUME: {
@ -573,8 +586,10 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
} else { } else {
DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
car.tl=c.value2&15; car.tl=c.value2&15;
if (c.chan<9) {
rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4)); rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4));
} }
}
break; break;
} }
case DIV_CMD_FM_AR: { case DIV_CMD_FM_AR: {
@ -641,7 +656,9 @@ void DivPlatformOPLL::forceIns() {
rWrite(0x06,(mod.sl<<4)|(mod.rr)); rWrite(0x06,(mod.sl<<4)|(mod.rr));
rWrite(0x07,(car.sl<<4)|(car.rr)); rWrite(0x07,(car.sl<<4)|(car.rr));
} }
if (i<9) {
rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4)); rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4));
}
if (!(i>=6 && properDrums)) { if (!(i>=6 && properDrums)) {
if (chan[i].active) { if (chan[i].active) {
chan[i].keyOn=true; chan[i].keyOn=true;