diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index d453dab2..fe446ad2 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -349,10 +349,21 @@ void DivPlatformOPL::tick() { if (chan[i].keyOn || chan[i].keyOff) { 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; } } + 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++) { if (pendingWrites[i]!=oldWrites[i]) { immWrite(i,pendingWrites[i]&0xff); @@ -368,12 +379,21 @@ void DivPlatformOPL::tick() { chan[i].freqH=freqt>>8; chan[i].freqL=freqt&0xff; 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) { 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; } else if (chan[i].freqChanged) { 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; } @@ -457,6 +477,8 @@ int DivPlatformOPL::dispatch(DivCommand c) { } if (chan[c.chan].insChanged) { 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; i0)<<1)|((c.value>>4)>0); + } + int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2; + if (isMuted[c.chan]) { + rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)); + 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)); + } + } 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)); break; @@ -687,6 +715,7 @@ int DivPlatformOPL::dispatch(DivCommand c) { void DivPlatformOPL::forceIns() { for (int i=0; i<18; i++) { 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