implement extra FM effects (OPLL and OPL)
This commit is contained in:
		
							parent
							
								
									6731edc568
								
							
						
					
					
						commit
						897bf323f2
					
				| 
						 | 
				
			
			@ -841,6 +841,222 @@ int DivPlatformOPL::dispatch(DivCommand c) {
 | 
			
		|||
      }      
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_DR: {
 | 
			
		||||
      int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
 | 
			
		||||
      if (c.value<0) {
 | 
			
		||||
        for (int i=0; i<ops; i++) {
 | 
			
		||||
          unsigned char slot=slots[i][c.chan];
 | 
			
		||||
          if (slot==255) continue;
 | 
			
		||||
          unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
          DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[i]:i];
 | 
			
		||||
          op.dr=c.value2&15;
 | 
			
		||||
          rWrite(baseAddr+ADDR_AR_DR,(op.ar<<4)|op.dr);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value>=ops) break;
 | 
			
		||||
        DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[c.value]:c.value];
 | 
			
		||||
        op.dr=c.value2&15;
 | 
			
		||||
        unsigned char slot=slots[c.value][c.chan];
 | 
			
		||||
        if (slot==255) break;
 | 
			
		||||
        unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
        rWrite(baseAddr+ADDR_AR_DR,(op.ar<<4)|op.dr);
 | 
			
		||||
      }      
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_SL: {
 | 
			
		||||
      int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
 | 
			
		||||
      if (c.value<0) {
 | 
			
		||||
        for (int i=0; i<ops; i++) {
 | 
			
		||||
          unsigned char slot=slots[i][c.chan];
 | 
			
		||||
          if (slot==255) continue;
 | 
			
		||||
          unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
          DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[i]:i];
 | 
			
		||||
          op.sl=c.value2&15;
 | 
			
		||||
          rWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|op.rr);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value>=ops) break;
 | 
			
		||||
        DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[c.value]:c.value];
 | 
			
		||||
        op.sl=c.value2&15;
 | 
			
		||||
        unsigned char slot=slots[c.value][c.chan];
 | 
			
		||||
        if (slot==255) break;
 | 
			
		||||
        unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
        rWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|op.rr);
 | 
			
		||||
      }      
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_RR: {
 | 
			
		||||
      int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
 | 
			
		||||
      if (c.value<0) {
 | 
			
		||||
        for (int i=0; i<ops; i++) {
 | 
			
		||||
          unsigned char slot=slots[i][c.chan];
 | 
			
		||||
          if (slot==255) continue;
 | 
			
		||||
          unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
          DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[i]:i];
 | 
			
		||||
          op.rr=c.value2&15;
 | 
			
		||||
          rWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|op.rr);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value>=ops) break;
 | 
			
		||||
        DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[c.value]:c.value];
 | 
			
		||||
        op.rr=c.value2&15;
 | 
			
		||||
        unsigned char slot=slots[c.value][c.chan];
 | 
			
		||||
        if (slot==255) break;
 | 
			
		||||
        unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
        rWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|op.rr);
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_AM: {
 | 
			
		||||
      int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
 | 
			
		||||
      if (c.value<0) {
 | 
			
		||||
        for (int i=0; i<ops; i++) {
 | 
			
		||||
          unsigned char slot=slots[i][c.chan];
 | 
			
		||||
          if (slot==255) continue;
 | 
			
		||||
          unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
          DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[i]:i];
 | 
			
		||||
          op.am=c.value2&1;
 | 
			
		||||
          rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,(op.am<<7)|(op.vib<<6)|(op.sus<<5)|(op.ksr<<4)|op.mult);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value>=ops) break;
 | 
			
		||||
        DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[c.value]:c.value];
 | 
			
		||||
        op.am=c.value2&1;
 | 
			
		||||
        unsigned char slot=slots[c.value][c.chan];
 | 
			
		||||
        if (slot==255) break;
 | 
			
		||||
        unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
        rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,(op.am<<7)|(op.vib<<6)|(op.sus<<5)|(op.ksr<<4)|op.mult);
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_VIB: {
 | 
			
		||||
      int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
 | 
			
		||||
      if (c.value<0) {
 | 
			
		||||
        for (int i=0; i<ops; i++) {
 | 
			
		||||
          unsigned char slot=slots[i][c.chan];
 | 
			
		||||
          if (slot==255) continue;
 | 
			
		||||
          unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
          DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[i]:i];
 | 
			
		||||
          op.vib=c.value2&1;
 | 
			
		||||
          rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,(op.am<<7)|(op.vib<<6)|(op.sus<<5)|(op.ksr<<4)|op.mult);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value>=ops) break;
 | 
			
		||||
        DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[c.value]:c.value];
 | 
			
		||||
        op.vib=c.value2&1;
 | 
			
		||||
        unsigned char slot=slots[c.value][c.chan];
 | 
			
		||||
        if (slot==255) break;
 | 
			
		||||
        unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
        rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,(op.am<<7)|(op.vib<<6)|(op.sus<<5)|(op.ksr<<4)|op.mult);
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_SUS: {
 | 
			
		||||
      int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
 | 
			
		||||
      if (c.value<0) {
 | 
			
		||||
        for (int i=0; i<ops; i++) {
 | 
			
		||||
          unsigned char slot=slots[i][c.chan];
 | 
			
		||||
          if (slot==255) continue;
 | 
			
		||||
          unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
          DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[i]:i];
 | 
			
		||||
          op.sus=c.value2&1;
 | 
			
		||||
          rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,(op.am<<7)|(op.vib<<6)|(op.sus<<5)|(op.ksr<<4)|op.mult);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value>=ops) break;
 | 
			
		||||
        DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[c.value]:c.value];
 | 
			
		||||
        op.sus=c.value2&1;
 | 
			
		||||
        unsigned char slot=slots[c.value][c.chan];
 | 
			
		||||
        if (slot==255) break;
 | 
			
		||||
        unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
        rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,(op.am<<7)|(op.vib<<6)|(op.sus<<5)|(op.ksr<<4)|op.mult);
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_KSR: {
 | 
			
		||||
      int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
 | 
			
		||||
      if (c.value<0) {
 | 
			
		||||
        for (int i=0; i<ops; i++) {
 | 
			
		||||
          unsigned char slot=slots[i][c.chan];
 | 
			
		||||
          if (slot==255) continue;
 | 
			
		||||
          unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
          DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[i]:i];
 | 
			
		||||
          op.ksr=c.value2&1;
 | 
			
		||||
          rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,(op.am<<7)|(op.vib<<6)|(op.sus<<5)|(op.ksr<<4)|op.mult);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value>=ops) break;
 | 
			
		||||
        DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[c.value]:c.value];
 | 
			
		||||
        op.ksr=c.value2&1;
 | 
			
		||||
        unsigned char slot=slots[c.value][c.chan];
 | 
			
		||||
        if (slot==255) break;
 | 
			
		||||
        unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
        rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,(op.am<<7)|(op.vib<<6)|(op.sus<<5)|(op.ksr<<4)|op.mult);
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_WS: {
 | 
			
		||||
      if (oplType<2) break;
 | 
			
		||||
      int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
 | 
			
		||||
      if (c.value<0) {
 | 
			
		||||
        for (int i=0; i<ops; i++) {
 | 
			
		||||
          unsigned char slot=slots[i][c.chan];
 | 
			
		||||
          if (slot==255) continue;
 | 
			
		||||
          unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
          DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[i]:i];
 | 
			
		||||
          op.ws=c.value2&7;
 | 
			
		||||
          rWrite(baseAddr+ADDR_WS,op.ws&((oplType==3)?7:3));
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value>=ops) break;
 | 
			
		||||
        DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[c.value]:c.value];
 | 
			
		||||
        op.ws=c.value2&7;
 | 
			
		||||
        unsigned char slot=slots[c.value][c.chan];
 | 
			
		||||
        if (slot==255) break;
 | 
			
		||||
        unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
        rWrite(baseAddr+ADDR_WS,op.ws&((oplType==3)?7:3));
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_RS: {
 | 
			
		||||
      if (oplType<2) break;
 | 
			
		||||
      int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
 | 
			
		||||
      if (c.value<0) {
 | 
			
		||||
        for (int i=0; i<ops; i++) {
 | 
			
		||||
          unsigned char slot=slots[i][c.chan];
 | 
			
		||||
          if (slot==255) continue;
 | 
			
		||||
          unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
          DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[i]:i];
 | 
			
		||||
          op.ksl=c.value2&3;
 | 
			
		||||
          if (isMuted[c.chan]) {
 | 
			
		||||
            rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
 | 
			
		||||
          } else {
 | 
			
		||||
            if (isOutputL[ops==4][chan[c.chan].state.alg][i]) {
 | 
			
		||||
              rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[c.chan].outVol&0x3f))/63))|(op.ksl<<6));
 | 
			
		||||
            } else {
 | 
			
		||||
              rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value>=ops) break;
 | 
			
		||||
        DivInstrumentFM::Operator& op=chan[c.chan].state.op[(ops==4)?orderedOpsL[c.value]:c.value];
 | 
			
		||||
        op.ksl=c.value2&3;
 | 
			
		||||
        unsigned char slot=slots[c.value][c.chan];
 | 
			
		||||
        if (slot==255) break;
 | 
			
		||||
        unsigned short baseAddr=slotMap[slot];
 | 
			
		||||
        if (isMuted[c.chan]) {
 | 
			
		||||
          rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
 | 
			
		||||
        } else {
 | 
			
		||||
          if (isOutputL[ops==4][chan[c.chan].state.alg][c.value]) {
 | 
			
		||||
            rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[c.chan].outVol&0x3f))/63))|(op.ksl<<6));
 | 
			
		||||
          } else {
 | 
			
		||||
            rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_EXTCH: {
 | 
			
		||||
      if (!properDrumsSys) break;
 | 
			
		||||
      properDrums=c.value;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -637,6 +637,150 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
 | 
			
		|||
      rWrite(0x05,(car.ar<<4)|(car.dr));
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_DR: {
 | 
			
		||||
      if (c.chan>=9 && !properDrums) return 0;
 | 
			
		||||
      DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
 | 
			
		||||
      DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
 | 
			
		||||
      if (c.value<0)  {
 | 
			
		||||
        mod.dr=c.value2&15;
 | 
			
		||||
        car.dr=c.value2&15;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value==0) {
 | 
			
		||||
          mod.dr=c.value2&15;
 | 
			
		||||
        } else {
 | 
			
		||||
          car.dr=c.value2&15;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      rWrite(0x04,(mod.ar<<4)|(mod.dr));
 | 
			
		||||
      rWrite(0x05,(car.ar<<4)|(car.dr));
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_SL: {
 | 
			
		||||
      if (c.chan>=9 && !properDrums) return 0;
 | 
			
		||||
      DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
 | 
			
		||||
      DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
 | 
			
		||||
      if (c.value<0)  {
 | 
			
		||||
        mod.sl=c.value2&15;
 | 
			
		||||
        car.sl=c.value2&15;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value==0) {
 | 
			
		||||
          mod.sl=c.value2&15;
 | 
			
		||||
        } else {
 | 
			
		||||
          car.sl=c.value2&15;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      rWrite(0x06,(mod.sl<<4)|(mod.rr));
 | 
			
		||||
      rWrite(0x07,(car.sl<<4)|(car.rr));
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_RR: {
 | 
			
		||||
      if (c.chan>=9 && !properDrums) return 0;
 | 
			
		||||
      DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
 | 
			
		||||
      DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
 | 
			
		||||
      if (c.value<0)  {
 | 
			
		||||
        mod.rr=c.value2&15;
 | 
			
		||||
        car.rr=c.value2&15;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value==0) {
 | 
			
		||||
          mod.rr=c.value2&15;
 | 
			
		||||
        } else {
 | 
			
		||||
          car.rr=c.value2&15;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      rWrite(0x06,(mod.sl<<4)|(mod.rr));
 | 
			
		||||
      rWrite(0x07,(car.sl<<4)|(car.rr));
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_AM: {
 | 
			
		||||
      if (c.chan>=9 && !properDrums) return 0;
 | 
			
		||||
      DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
 | 
			
		||||
      DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
 | 
			
		||||
      if (c.value<0)  {
 | 
			
		||||
        mod.am=c.value2&1;
 | 
			
		||||
        car.am=c.value2&1;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value==0) {
 | 
			
		||||
          mod.am=c.value2&1;
 | 
			
		||||
        } else {
 | 
			
		||||
          car.am=c.value2&1;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult));
 | 
			
		||||
      rWrite(0x01,(car.am<<7)|(car.vib<<6)|((car.ssgEnv&8)<<2)|(car.ksr<<4)|(car.mult));
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_VIB: {
 | 
			
		||||
      if (c.chan>=9 && !properDrums) return 0;
 | 
			
		||||
      DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
 | 
			
		||||
      DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
 | 
			
		||||
      if (c.value<0)  {
 | 
			
		||||
        mod.vib=c.value2&1;
 | 
			
		||||
        car.vib=c.value2&1;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value==0) {
 | 
			
		||||
          mod.vib=c.value2&1;
 | 
			
		||||
        } else {
 | 
			
		||||
          car.vib=c.value2&1;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult));
 | 
			
		||||
      rWrite(0x01,(car.am<<7)|(car.vib<<6)|((car.ssgEnv&8)<<2)|(car.ksr<<4)|(car.mult));
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_KSR: {
 | 
			
		||||
      if (c.chan>=9 && !properDrums) return 0;
 | 
			
		||||
      DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
 | 
			
		||||
      DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
 | 
			
		||||
      if (c.value<0)  {
 | 
			
		||||
        mod.ksr=c.value2&1;
 | 
			
		||||
        car.ksr=c.value2&1;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value==0) {
 | 
			
		||||
          mod.ksr=c.value2&1;
 | 
			
		||||
        } else {
 | 
			
		||||
          car.ksr=c.value2&1;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult));
 | 
			
		||||
      rWrite(0x01,(car.am<<7)|(car.vib<<6)|((car.ssgEnv&8)<<2)|(car.ksr<<4)|(car.mult));
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_SUS: {
 | 
			
		||||
      if (c.chan>=9 && !properDrums) return 0;
 | 
			
		||||
      DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
 | 
			
		||||
      DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
 | 
			
		||||
      if (c.value<0)  {
 | 
			
		||||
        mod.ssgEnv=c.value2?8:0;
 | 
			
		||||
        car.ssgEnv=c.value2?8:0;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value==0) {
 | 
			
		||||
          mod.ssgEnv=c.value2?8:0;
 | 
			
		||||
        } else {
 | 
			
		||||
          car.ssgEnv=c.value2?8:0;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult));
 | 
			
		||||
      rWrite(0x01,(car.am<<7)|(car.vib<<6)|((car.ssgEnv&8)<<2)|(car.ksr<<4)|(car.mult));
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_RS: {
 | 
			
		||||
      if (c.chan>=9 && !properDrums) return 0;
 | 
			
		||||
      DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
 | 
			
		||||
      DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
 | 
			
		||||
      if (c.value<0)  {
 | 
			
		||||
        mod.ksl=c.value2&3;
 | 
			
		||||
        car.ksl=c.value2&3;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (c.value==0) {
 | 
			
		||||
          mod.ksl=c.value2&3;
 | 
			
		||||
        } else {
 | 
			
		||||
          car.ksl=c.value2&3;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      rWrite(0x02,(mod.ksl<<6)|(mod.tl&63));
 | 
			
		||||
      rWrite(0x03,(car.ksl<<6)|((chan[c.chan].state.fms&1)<<4)|((chan[c.chan].state.ams&1)<<3)|chan[c.chan].state.fb);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case DIV_CMD_FM_EXTCH:
 | 
			
		||||
      if (!properDrumsSys) break;
 | 
			
		||||
      if ((int)properDrums==c.value) break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -542,7 +542,6 @@ void DivEngine::registerSystems() {
 | 
			
		|||
      OP_EFFECT_MULTI(0x58,DIV_CMD_FM_DR,1,15);
 | 
			
		||||
 | 
			
		||||
      OP_EFFECT_SINGLE(0x5b,DIV_CMD_FM_KSR,2,1);
 | 
			
		||||
      OP_EFFECT_SINGLE(0x2a,DIV_CMD_FM_WS,4,7);
 | 
			
		||||
      default:
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -608,6 +607,7 @@ void DivEngine::registerSystems() {
 | 
			
		|||
      OP_EFFECT_MULTI(0x5a,DIV_CMD_FM_DR,3,15);
 | 
			
		||||
 | 
			
		||||
      OP_EFFECT_SINGLE(0x5b,DIV_CMD_FM_KSR,4,1);
 | 
			
		||||
      OP_EFFECT_SINGLE(0x2a,DIV_CMD_FM_WS,4,7);
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
        return false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue