OPLL: more drum fixes!

This commit is contained in:
tildearrow 2022-03-01 22:10:03 -05:00
parent 1e5d7a623a
commit ceb1cd0181
3 changed files with 47 additions and 5 deletions

View file

@ -275,7 +275,7 @@ void DivPlatformOPLL::tick() {
drumState|=(0x10>>(chan[i].note%12)); drumState|=(0x10>>(chan[i].note%12));
immWrite(0x0e,0x20|drumState); immWrite(0x0e,0x20|drumState);
chan[i].keyOn=false; chan[i].keyOn=false;
} else if (chan[i].keyOn || chan[i].freqChanged) { } else if ((chan[i].keyOn || chan[i].freqChanged) && i<9) {
//immWrite(0x28,0xf0|konOffs[i]); //immWrite(0x28,0xf0|konOffs[i]);
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;
@ -347,9 +347,9 @@ void DivPlatformOPLL::muteChannel(int ch, bool mute) {
} }
int DivPlatformOPLL::dispatch(DivCommand c) { int DivPlatformOPLL::dispatch(DivCommand c) {
if (c.chan>=9 && !properDrums) return 0;
switch (c.cmd) { switch (c.cmd) {
case DIV_CMD_NOTE_ON: { case DIV_CMD_NOTE_ON: {
if (c.chan>=9 && !properDrums) return 0;
DivInstrument* ins=parent->getIns(chan[c.chan].ins); DivInstrument* ins=parent->getIns(chan[c.chan].ins);
if (chan[c.chan].insChanged) { if (chan[c.chan].insChanged) {
chan[c.chan].state=ins->fm; chan[c.chan].state=ins->fm;
@ -445,24 +445,35 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_NOTE_OFF: case DIV_CMD_NOTE_OFF:
if (c.chan>=9 && !properDrums) return 0;
chan[c.chan].keyOff=true; chan[c.chan].keyOff=true;
chan[c.chan].keyOn=false; chan[c.chan].keyOn=false;
chan[c.chan].active=false; chan[c.chan].active=false;
break; break;
case DIV_CMD_NOTE_OFF_ENV: case DIV_CMD_NOTE_OFF_ENV:
if (c.chan>=9 && !properDrums) return 0;
chan[c.chan].keyOff=true; chan[c.chan].keyOff=true;
chan[c.chan].keyOn=false; chan[c.chan].keyOn=false;
chan[c.chan].active=false; chan[c.chan].active=false;
chan[c.chan].std.release(); chan[c.chan].std.release();
break; break;
case DIV_CMD_ENV_RELEASE: case DIV_CMD_ENV_RELEASE:
if (c.chan>=9 && !properDrums) return 0;
chan[c.chan].std.release(); chan[c.chan].std.release();
break; break;
case DIV_CMD_VOLUME: { case DIV_CMD_VOLUME: {
if (c.chan>=9 && !properDrums) return 0;
chan[c.chan].vol=c.value; chan[c.chan].vol=c.value;
if (!chan[c.chan].std.hasVol) { if (!chan[c.chan].std.hasVol) {
chan[c.chan].outVol=c.value; chan[c.chan].outVol=c.value;
} }
if (c.chan>=6 || properDrums) {
drumVol[c.chan-6]=15-chan[c.chan].outVol;
rWrite(0x36,drumVol[0]);
rWrite(0x37,drumVol[1]|(drumVol[4]<<4));
rWrite(0x38,drumVol[3]|(drumVol[2]<<4));
break;
}
if (c.chan<6 || !drums) { if (c.chan<6 || !drums) {
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));
} }
@ -479,11 +490,13 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
chan[c.chan].ins=c.value; chan[c.chan].ins=c.value;
break; break;
case DIV_CMD_PITCH: { case DIV_CMD_PITCH: {
if (c.chan>=9 && !properDrums) return 0;
chan[c.chan].pitch=c.value; chan[c.chan].pitch=c.value;
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
} }
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
if (c.chan>=9 && !properDrums) return 0;
int destFreq=NOTE_FREQUENCY(c.value2); int destFreq=NOTE_FREQUENCY(c.value2);
int newFreq; int newFreq;
bool return2=false; bool return2=false;
@ -516,12 +529,14 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
if (c.chan>=9 && !properDrums) return 0;
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
} }
case DIV_CMD_FM_FB: { case DIV_CMD_FM_FB: {
if (c.chan>=9 && !properDrums) return 0;
DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
//DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; //DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
chan[c.chan].state.fb=c.value&7; chan[c.chan].state.fb=c.value&7;
@ -530,6 +545,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
} }
case DIV_CMD_FM_MULT: { case DIV_CMD_FM_MULT: {
if (c.chan>=9 && !properDrums) return 0;
if (c.value==0) { if (c.value==0) {
DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
mod.mult=c.value2&15; mod.mult=c.value2&15;
@ -542,6 +558,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_FM_TL: { case DIV_CMD_FM_TL: {
if (c.chan>=9 && !properDrums) return 0;
if (c.value==0) { if (c.value==0) {
DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
@ -555,6 +572,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_FM_AR: { case DIV_CMD_FM_AR: {
if (c.chan>=9 && !properDrums) return 0;
DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
if (c.value<0) { if (c.value<0) {
@ -571,6 +589,18 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
rWrite(0x05,(car.ar<<4)|(car.dr)); rWrite(0x05,(car.ar<<4)|(car.dr));
break; break;
} }
case DIV_CMD_FM_EXTCH:
if (!properDrumsSys) break;
if (properDrums==c.value) break;
if (c.value) {
properDrums=true;
immWrite(0x0e,0x20);
} else {
properDrums=false;
immWrite(0x0e,0x00);
drumState=0;
}
break;
case DIV_ALWAYS_SET_VOLUME: case DIV_ALWAYS_SET_VOLUME:
return 0; return 0;
break; break;
@ -578,6 +608,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
return 15; return 15;
break; break;
case DIV_CMD_PRE_PORTA: case DIV_CMD_PRE_PORTA:
if (c.chan>=9 && !properDrums) return 0;
chan[c.chan].inPorta=c.value; chan[c.chan].inPorta=c.value;
break; break;
case DIV_CMD_PRE_NOTE: case DIV_CMD_PRE_NOTE:
@ -622,6 +653,7 @@ void DivPlatformOPLL::forceIns() {
immWrite(0x18,0xC0); immWrite(0x18,0xC0);
immWrite(0x28,0x01); immWrite(0x28,0x01);
} }
drumState=0;
} }
void DivPlatformOPLL::toggleRegisterDump(bool enable) { void DivPlatformOPLL::toggleRegisterDump(bool enable) {
@ -634,6 +666,7 @@ void DivPlatformOPLL::setVRC7(bool vrc) {
void DivPlatformOPLL::setProperDrums(bool pd) { void DivPlatformOPLL::setProperDrums(bool pd) {
properDrums=pd; properDrums=pd;
properDrumsSys=pd;
} }
@ -682,6 +715,8 @@ void DivPlatformOPLL::reset() {
drumVol[4]=0; drumVol[4]=0;
delay=0; delay=0;
drums=false;
properDrums=properDrumsSys;
if (properDrums) { if (properDrums) {
immWrite(0x0e,0x20); immWrite(0x0e,0x20);

View file

@ -76,7 +76,7 @@ class DivPlatformOPLL: public DivDispatch {
bool useYMFM; bool useYMFM;
bool drums; bool drums;
bool properDrums; bool properDrums, properDrumsSys;
bool vrc7; bool vrc7;
short oldWrites[256]; short oldWrites[256];

View file

@ -232,6 +232,15 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe
} }
return false; return false;
break; break;
case DIV_SYSTEM_OPLL_DRUMS:
switch (effect) {
case 0x18: // drum mode toggle
dispatchCmd(DivCommand(DIV_CMD_FM_EXTCH,ch,effectVal));
break;
default:
return false;
}
break;
case DIV_SYSTEM_QSOUND: case DIV_SYSTEM_QSOUND:
switch (effect) { switch (effect) {
case 0x10: // echo feedback case 0x10: // echo feedback
@ -389,8 +398,6 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
dispatchCmd(DivCommand(DIV_CMD_FM_MULT,ch,(effectVal>>4)-1,effectVal&15)); dispatchCmd(DivCommand(DIV_CMD_FM_MULT,ch,(effectVal>>4)-1,effectVal&15));
} }
break; break;
case 0x18: // drum mode toggle
break;
case 0x19: // AR global case 0x19: // AR global
dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,-1,effectVal&31)); dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,-1,effectVal&31));
break; break;