OPL: implement hard reset

fixes #437
This commit is contained in:
tildearrow 2022-05-07 21:48:29 -05:00
parent d582fce862
commit 6fe58a3965
2 changed files with 29 additions and 1 deletions

View file

@ -445,10 +445,34 @@ void DivPlatformOPL::tick(bool sysTick) {
}
if (i<melodicChans) {
if (chan[i].hardReset && chan[i].keyOn) {
for (int j=0; j<ops; j++) {
unsigned char slot=slots[j][i];
if (slot==255) continue;
unsigned short baseAddr=slotMap[slot];
DivInstrumentFM::Operator& op=chan[i].state.op[(ops==4)?orderedOpsL[j]:j];
immWrite(baseAddr+ADDR_SL_RR,0x0f);
immWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
oldWrites[baseAddr+ADDR_SL_RR]=-1;
oldWrites[baseAddr+ADDR_KSL_TL]=-1;
}
}
if (chan[i].keyOn || chan[i].keyOff) {
immWrite(chanMap[i]+ADDR_FREQH,0x00|(chan[i].freqH&31));
chan[i].keyOff=false;
}
if (chan[i].hardReset && chan[i].keyOn) {
for (int j=0; j<ops; j++) {
unsigned char slot=slots[j][i];
if (slot==255) continue;
unsigned short baseAddr=slotMap[slot];
DivInstrumentFM::Operator& op=chan[i].state.op[(ops==4)?orderedOpsL[j]:j];
for (int k=0; k<5; k++) {
immWrite(baseAddr+ADDR_SL_RR,0x0f);
immWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
}
}
}
}
}
@ -1118,6 +1142,9 @@ int DivPlatformOPL::dispatch(DivCommand c) {
}
break;
}
case DIV_CMD_FM_HARD_RESET:
chan[c.chan].hardReset=c.value;
break;
case DIV_ALWAYS_SET_VOLUME:
return 0;
break;

View file

@ -31,7 +31,7 @@ class DivPlatformOPL: public DivDispatch {
DivMacroInt std;
unsigned char freqH, freqL;
int freq, baseFreq, pitch, pitch2, note, ins;
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta, fourOp;
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta, fourOp, hardReset;
int vol, outVol;
unsigned char pan;
void macroInit(DivInstrument* which) {
@ -56,6 +56,7 @@ class DivPlatformOPL: public DivDispatch {
furnaceDac(false),
inPorta(false),
fourOp(false),
hardReset(false),
vol(0),
pan(3) {
state.ops=2;