OPN(A/B/2/B-B): fix absolutely everything
This commit is contained in:
		
							parent
							
								
									3d4f2cfa13
								
							
						
					
					
						commit
						2fa51e482a
					
				| 
						 | 
					@ -32,4 +32,65 @@
 | 
				
			||||||
#define ADDR_FB_ALG 0xb0
 | 
					#define ADDR_FB_ALG 0xb0
 | 
				
			||||||
#define ADDR_LRAF 0xb4
 | 
					#define ADDR_LRAF 0xb4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PLEASE_HELP_ME(_targetChan) \
 | 
				
			||||||
 | 
					  int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false); \
 | 
				
			||||||
 | 
					  int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false); \
 | 
				
			||||||
 | 
					  int destFreq=NOTE_FNUM_BLOCK(c.value2,11); \
 | 
				
			||||||
 | 
					  int newFreq; \
 | 
				
			||||||
 | 
					  bool return2=false; \
 | 
				
			||||||
 | 
					  if (_targetChan.portaPause) { \
 | 
				
			||||||
 | 
					    if (parent->song.oldOctaveBoundary) { \
 | 
				
			||||||
 | 
					      if ((_targetChan.portaPauseFreq&0xf800)>(_targetChan.baseFreq&0xf800)) { \
 | 
				
			||||||
 | 
					        _targetChan.baseFreq=((_targetChan.baseFreq&0x7ff)>>1)|(_targetChan.portaPauseFreq&0xf800); \
 | 
				
			||||||
 | 
					      } else { \
 | 
				
			||||||
 | 
					        _targetChan.baseFreq=((_targetChan.baseFreq&0x7ff)<<1)|(_targetChan.portaPauseFreq&0xf800); \
 | 
				
			||||||
 | 
					      } \
 | 
				
			||||||
 | 
					      c.value*=2; \
 | 
				
			||||||
 | 
					    } else { \
 | 
				
			||||||
 | 
					      _targetChan.baseFreq=_targetChan.portaPauseFreq; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					  } \
 | 
				
			||||||
 | 
					  if (destFreq>_targetChan.baseFreq) { \
 | 
				
			||||||
 | 
					    newFreq=_targetChan.baseFreq+c.value; \
 | 
				
			||||||
 | 
					    if (newFreq>=destFreq) { \
 | 
				
			||||||
 | 
					      newFreq=destFreq; \
 | 
				
			||||||
 | 
					      return2=true; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					  } else { \
 | 
				
			||||||
 | 
					    newFreq=_targetChan.baseFreq-c.value; \
 | 
				
			||||||
 | 
					    if (newFreq<=destFreq) { \
 | 
				
			||||||
 | 
					      newFreq=destFreq; \
 | 
				
			||||||
 | 
					      return2=true; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					  } \
 | 
				
			||||||
 | 
					  /* check for octave boundary */ \
 | 
				
			||||||
 | 
					  /* what the heck! */ \
 | 
				
			||||||
 | 
					  if (!_targetChan.portaPause) { \
 | 
				
			||||||
 | 
					    if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) { \
 | 
				
			||||||
 | 
					      if (parent->song.fbPortaPause) { \
 | 
				
			||||||
 | 
					        _targetChan.portaPauseFreq=(boundaryBottom)|((newFreq+0x800)&0xf800); \
 | 
				
			||||||
 | 
					        _targetChan.portaPause=true; \
 | 
				
			||||||
 | 
					        break; \
 | 
				
			||||||
 | 
					      } else { \
 | 
				
			||||||
 | 
					        newFreq=((newFreq&0x7ff)>>1)|((newFreq+0x800)&0xf800); \
 | 
				
			||||||
 | 
					      } \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					    if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) { \
 | 
				
			||||||
 | 
					      if (parent->song.fbPortaPause) { \
 | 
				
			||||||
 | 
					        _targetChan.portaPauseFreq=newFreq=(boundaryTop-1)|((newFreq-0x800)&0xf800); \
 | 
				
			||||||
 | 
					        _targetChan.portaPause=true; \
 | 
				
			||||||
 | 
					        break; \
 | 
				
			||||||
 | 
					      } else { \
 | 
				
			||||||
 | 
					        newFreq=((newFreq&0x7ff)<<1)|((newFreq-0x800)&0xf800); \
 | 
				
			||||||
 | 
					      } \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					  } \
 | 
				
			||||||
 | 
					  _targetChan.portaPause=false; \
 | 
				
			||||||
 | 
					  _targetChan.freqChanged=true; \
 | 
				
			||||||
 | 
					  _targetChan.baseFreq=newFreq; \
 | 
				
			||||||
 | 
					  if (return2) { \
 | 
				
			||||||
 | 
					    _targetChan.inPorta=false; \
 | 
				
			||||||
 | 
					    return 2; \
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -756,56 +756,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
 | 
					      PLEASE_HELP_ME(chan[c.chan]);
 | 
				
			||||||
      int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
 | 
					 | 
				
			||||||
      int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
 | 
					 | 
				
			||||||
      int newFreq;
 | 
					 | 
				
			||||||
      bool return2=false;
 | 
					 | 
				
			||||||
      if (chan[c.chan].portaPause) {
 | 
					 | 
				
			||||||
        chan[c.chan].baseFreq=chan[c.chan].portaPauseFreq;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (destFreq>chan[c.chan].baseFreq) {
 | 
					 | 
				
			||||||
        newFreq=chan[c.chan].baseFreq+c.value;
 | 
					 | 
				
			||||||
        if (newFreq>=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        newFreq=chan[c.chan].baseFreq-c.value;
 | 
					 | 
				
			||||||
        if (newFreq<=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // check for octave boundary
 | 
					 | 
				
			||||||
      // what the heck!
 | 
					 | 
				
			||||||
      if (!chan[c.chan].portaPause) {
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            chan[c.chan].portaPauseFreq=(parent->song.oldOctaveBoundary?(newFreq>>1):boundaryBottom)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
            chan[c.chan].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            chan[c.chan].portaPauseFreq=newFreq=(parent->song.oldOctaveBoundary?(newFreq<<1):(boundaryTop-1))|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
            chan[c.chan].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      chan[c.chan].portaPause=false;
 | 
					 | 
				
			||||||
      chan[c.chan].freqChanged=true;
 | 
					 | 
				
			||||||
      chan[c.chan].baseFreq=newFreq;
 | 
					 | 
				
			||||||
      if (return2) {
 | 
					 | 
				
			||||||
        chan[c.chan].inPorta=false;
 | 
					 | 
				
			||||||
        return 2;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case DIV_CMD_SAMPLE_MODE: {
 | 
					    case DIV_CMD_SAMPLE_MODE: {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,52 +150,7 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
 | 
					      PLEASE_HELP_ME(opChan[ch]);
 | 
				
			||||||
      int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
 | 
					 | 
				
			||||||
      int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
 | 
					 | 
				
			||||||
      int newFreq;
 | 
					 | 
				
			||||||
      bool return2=false;
 | 
					 | 
				
			||||||
      if (opChan[ch].portaPause) {
 | 
					 | 
				
			||||||
        opChan[ch].baseFreq=opChan[ch].portaPauseFreq;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (destFreq>opChan[ch].baseFreq) {
 | 
					 | 
				
			||||||
        newFreq=opChan[ch].baseFreq+c.value;
 | 
					 | 
				
			||||||
        if (newFreq>=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        newFreq=opChan[ch].baseFreq-c.value;
 | 
					 | 
				
			||||||
        if (newFreq<=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // what the heck!
 | 
					 | 
				
			||||||
      if (!opChan[ch].portaPause) {
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            opChan[ch].portaPauseFreq=(boundaryBottom)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
            opChan[ch].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            opChan[ch].portaPauseFreq=newFreq=(boundaryTop-1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
            opChan[ch].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      opChan[ch].portaPause=false;
 | 
					 | 
				
			||||||
      opChan[ch].freqChanged=true;
 | 
					 | 
				
			||||||
      opChan[ch].baseFreq=newFreq;
 | 
					 | 
				
			||||||
      if (return2) return 2;
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case DIV_CMD_SAMPLE_MODE: {
 | 
					    case DIV_CMD_SAMPLE_MODE: {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@ class DivPlatformGenesisExt: public DivPlatformGenesis {
 | 
				
			||||||
    unsigned char freqH, freqL;
 | 
					    unsigned char freqH, freqL;
 | 
				
			||||||
    int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins;
 | 
					    int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins;
 | 
				
			||||||
    signed char konCycles;
 | 
					    signed char konCycles;
 | 
				
			||||||
    bool active, insChanged, freqChanged, keyOn, keyOff, portaPause;
 | 
					    bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta;
 | 
				
			||||||
    int vol;
 | 
					    int vol;
 | 
				
			||||||
    unsigned char pan;
 | 
					    unsigned char pan;
 | 
				
			||||||
    OpChannel():
 | 
					    OpChannel():
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,7 @@ class DivPlatformGenesisExt: public DivPlatformGenesis {
 | 
				
			||||||
      keyOn(false),
 | 
					      keyOn(false),
 | 
				
			||||||
      keyOff(false),
 | 
					      keyOff(false),
 | 
				
			||||||
      portaPause(false),
 | 
					      portaPause(false),
 | 
				
			||||||
 | 
					      inPorta(false),
 | 
				
			||||||
      vol(0),
 | 
					      vol(0),
 | 
				
			||||||
      pan(3) {}
 | 
					      pan(3) {}
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -659,56 +659,7 @@ int DivPlatformYM2203::dispatch(DivCommand c) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
 | 
					      PLEASE_HELP_ME(chan[c.chan]);
 | 
				
			||||||
      int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
 | 
					 | 
				
			||||||
      int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
 | 
					 | 
				
			||||||
      int newFreq;
 | 
					 | 
				
			||||||
      bool return2=false;
 | 
					 | 
				
			||||||
      if (chan[c.chan].portaPause) {
 | 
					 | 
				
			||||||
        chan[c.chan].baseFreq=chan[c.chan].portaPauseFreq;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (destFreq>chan[c.chan].baseFreq) {
 | 
					 | 
				
			||||||
        newFreq=chan[c.chan].baseFreq+c.value;
 | 
					 | 
				
			||||||
        if (newFreq>=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        newFreq=chan[c.chan].baseFreq-c.value;
 | 
					 | 
				
			||||||
        if (newFreq<=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // check for octave boundary
 | 
					 | 
				
			||||||
      // what the heck!
 | 
					 | 
				
			||||||
      if (!chan[c.chan].portaPause) {
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            chan[c.chan].portaPauseFreq=(parent->song.oldOctaveBoundary?(newFreq>>1):boundaryBottom)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
            chan[c.chan].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            chan[c.chan].portaPauseFreq=newFreq=(parent->song.oldOctaveBoundary?(newFreq<<1):(boundaryTop-1))|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
            chan[c.chan].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      chan[c.chan].portaPause=false;
 | 
					 | 
				
			||||||
      chan[c.chan].freqChanged=true;
 | 
					 | 
				
			||||||
      chan[c.chan].baseFreq=newFreq;
 | 
					 | 
				
			||||||
      if (return2) {
 | 
					 | 
				
			||||||
        chan[c.chan].inPorta=false;
 | 
					 | 
				
			||||||
        return 2;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case DIV_CMD_LEGATO: {
 | 
					    case DIV_CMD_LEGATO: {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,52 +143,7 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
 | 
					      PLEASE_HELP_ME(opChan[ch]);
 | 
				
			||||||
      int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
 | 
					 | 
				
			||||||
      int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
 | 
					 | 
				
			||||||
      int newFreq;
 | 
					 | 
				
			||||||
      bool return2=false;
 | 
					 | 
				
			||||||
      if (opChan[ch].portaPause) {
 | 
					 | 
				
			||||||
        opChan[ch].baseFreq=opChan[ch].portaPauseFreq;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (destFreq>opChan[ch].baseFreq) {
 | 
					 | 
				
			||||||
        newFreq=opChan[ch].baseFreq+c.value;
 | 
					 | 
				
			||||||
        if (newFreq>=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        newFreq=opChan[ch].baseFreq-c.value;
 | 
					 | 
				
			||||||
        if (newFreq<=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // what the heck!
 | 
					 | 
				
			||||||
      if (!opChan[ch].portaPause) {
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            opChan[ch].portaPauseFreq=(boundaryBottom)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
            opChan[ch].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            opChan[ch].portaPauseFreq=newFreq=(boundaryTop-1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
            opChan[ch].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      opChan[ch].portaPause=false;
 | 
					 | 
				
			||||||
      opChan[ch].freqChanged=true;
 | 
					 | 
				
			||||||
      opChan[ch].baseFreq=newFreq;
 | 
					 | 
				
			||||||
      if (return2) return 2;
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case DIV_CMD_LEGATO: {
 | 
					    case DIV_CMD_LEGATO: {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,10 +27,12 @@ class DivPlatformYM2203Ext: public DivPlatformYM2203 {
 | 
				
			||||||
    unsigned char freqH, freqL;
 | 
					    unsigned char freqH, freqL;
 | 
				
			||||||
    int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins;
 | 
					    int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins;
 | 
				
			||||||
    signed char konCycles;
 | 
					    signed char konCycles;
 | 
				
			||||||
    bool active, insChanged, freqChanged, keyOn, keyOff, portaPause;
 | 
					    bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta;
 | 
				
			||||||
    int vol;
 | 
					    int vol;
 | 
				
			||||||
    unsigned char pan;
 | 
					    unsigned char pan;
 | 
				
			||||||
    OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), portaPauseFreq(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), vol(0), pan(3) {}
 | 
					    // UGLY
 | 
				
			||||||
 | 
					    OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), portaPauseFreq(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false),
 | 
				
			||||||
 | 
					     inPorta(false), vol(0), pan(3) {}
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  OpChannel opChan[4];
 | 
					  OpChannel opChan[4];
 | 
				
			||||||
  bool isOpMuted[4];
 | 
					  bool isOpMuted[4];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -980,56 +980,7 @@ int DivPlatformYM2608::dispatch(DivCommand c) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
 | 
					      PLEASE_HELP_ME(chan[c.chan]);
 | 
				
			||||||
      int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
 | 
					 | 
				
			||||||
      int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
 | 
					 | 
				
			||||||
      int newFreq;
 | 
					 | 
				
			||||||
      bool return2=false;
 | 
					 | 
				
			||||||
      if (chan[c.chan].portaPause) {
 | 
					 | 
				
			||||||
        chan[c.chan].baseFreq=chan[c.chan].portaPauseFreq;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (destFreq>chan[c.chan].baseFreq) {
 | 
					 | 
				
			||||||
        newFreq=chan[c.chan].baseFreq+c.value;
 | 
					 | 
				
			||||||
        if (newFreq>=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        newFreq=chan[c.chan].baseFreq-c.value;
 | 
					 | 
				
			||||||
        if (newFreq<=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // check for octave boundary
 | 
					 | 
				
			||||||
      // what the heck!
 | 
					 | 
				
			||||||
      if (!chan[c.chan].portaPause) {
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            chan[c.chan].portaPauseFreq=(parent->song.oldOctaveBoundary?(newFreq>>1):boundaryBottom)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
            chan[c.chan].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            chan[c.chan].portaPauseFreq=newFreq=(parent->song.oldOctaveBoundary?(newFreq<<1):(boundaryTop-1))|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
            chan[c.chan].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      chan[c.chan].portaPause=false;
 | 
					 | 
				
			||||||
      chan[c.chan].freqChanged=true;
 | 
					 | 
				
			||||||
      chan[c.chan].baseFreq=newFreq;
 | 
					 | 
				
			||||||
      if (return2) {
 | 
					 | 
				
			||||||
        chan[c.chan].inPorta=false;
 | 
					 | 
				
			||||||
        return 2;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case DIV_CMD_SAMPLE_BANK:
 | 
					    case DIV_CMD_SAMPLE_BANK:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,52 +143,7 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
 | 
					      PLEASE_HELP_ME(opChan[ch]);
 | 
				
			||||||
      int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
 | 
					 | 
				
			||||||
      int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
 | 
					 | 
				
			||||||
      int newFreq;
 | 
					 | 
				
			||||||
      bool return2=false;
 | 
					 | 
				
			||||||
      if (opChan[ch].portaPause) {
 | 
					 | 
				
			||||||
        opChan[ch].baseFreq=opChan[ch].portaPauseFreq;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (destFreq>opChan[ch].baseFreq) {
 | 
					 | 
				
			||||||
        newFreq=opChan[ch].baseFreq+c.value;
 | 
					 | 
				
			||||||
        if (newFreq>=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        newFreq=opChan[ch].baseFreq-c.value;
 | 
					 | 
				
			||||||
        if (newFreq<=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // what the heck!
 | 
					 | 
				
			||||||
      if (!opChan[ch].portaPause) {
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            opChan[ch].portaPauseFreq=(boundaryBottom)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
            opChan[ch].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            opChan[ch].portaPauseFreq=newFreq=(boundaryTop-1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
            opChan[ch].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      opChan[ch].portaPause=false;
 | 
					 | 
				
			||||||
      opChan[ch].freqChanged=true;
 | 
					 | 
				
			||||||
      opChan[ch].baseFreq=newFreq;
 | 
					 | 
				
			||||||
      if (return2) return 2;
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case DIV_CMD_LEGATO: {
 | 
					    case DIV_CMD_LEGATO: {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,10 +27,12 @@ class DivPlatformYM2608Ext: public DivPlatformYM2608 {
 | 
				
			||||||
    unsigned char freqH, freqL;
 | 
					    unsigned char freqH, freqL;
 | 
				
			||||||
    int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins;
 | 
					    int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins;
 | 
				
			||||||
    signed char konCycles;
 | 
					    signed char konCycles;
 | 
				
			||||||
    bool active, insChanged, freqChanged, keyOn, keyOff, portaPause;
 | 
					    bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta;
 | 
				
			||||||
    int vol;
 | 
					    int vol;
 | 
				
			||||||
    unsigned char pan;
 | 
					    unsigned char pan;
 | 
				
			||||||
    OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), portaPauseFreq(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), vol(0), pan(3) {}
 | 
					    // UGLY
 | 
				
			||||||
 | 
					    OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), portaPauseFreq(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false),
 | 
				
			||||||
 | 
					    inPorta(false), vol(0), pan(3) {}
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  OpChannel opChan[4];
 | 
					  OpChannel opChan[4];
 | 
				
			||||||
  bool isOpMuted[4];
 | 
					  bool isOpMuted[4];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1027,56 +1027,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
 | 
					      PLEASE_HELP_ME(chan[c.chan]);
 | 
				
			||||||
      int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
 | 
					 | 
				
			||||||
      int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
 | 
					 | 
				
			||||||
      int newFreq;
 | 
					 | 
				
			||||||
      bool return2=false;
 | 
					 | 
				
			||||||
      if (chan[c.chan].portaPause) {
 | 
					 | 
				
			||||||
        chan[c.chan].baseFreq=chan[c.chan].portaPauseFreq;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (destFreq>chan[c.chan].baseFreq) {
 | 
					 | 
				
			||||||
        newFreq=chan[c.chan].baseFreq+c.value;
 | 
					 | 
				
			||||||
        if (newFreq>=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        newFreq=chan[c.chan].baseFreq-c.value;
 | 
					 | 
				
			||||||
        if (newFreq<=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // check for octave boundary
 | 
					 | 
				
			||||||
      // what the heck!
 | 
					 | 
				
			||||||
      if (!chan[c.chan].portaPause) {
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            chan[c.chan].portaPauseFreq=(parent->song.oldOctaveBoundary?(newFreq>>1):boundaryBottom)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
            chan[c.chan].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            chan[c.chan].portaPauseFreq=newFreq=(parent->song.oldOctaveBoundary?(newFreq<<1):(boundaryTop-1))|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
            chan[c.chan].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      chan[c.chan].portaPause=false;
 | 
					 | 
				
			||||||
      chan[c.chan].freqChanged=true;
 | 
					 | 
				
			||||||
      chan[c.chan].baseFreq=newFreq;
 | 
					 | 
				
			||||||
      if (return2) {
 | 
					 | 
				
			||||||
        chan[c.chan].inPorta=false;
 | 
					 | 
				
			||||||
        return 2;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case DIV_CMD_SAMPLE_BANK:
 | 
					    case DIV_CMD_SAMPLE_BANK:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1005,56 +1005,7 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
 | 
					      PLEASE_HELP_ME(chan[c.chan]);
 | 
				
			||||||
      int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
 | 
					 | 
				
			||||||
      int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
 | 
					 | 
				
			||||||
      int newFreq;
 | 
					 | 
				
			||||||
      bool return2=false;
 | 
					 | 
				
			||||||
      if (chan[c.chan].portaPause) {
 | 
					 | 
				
			||||||
        chan[c.chan].baseFreq=chan[c.chan].portaPauseFreq;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (destFreq>chan[c.chan].baseFreq) {
 | 
					 | 
				
			||||||
        newFreq=chan[c.chan].baseFreq+c.value;
 | 
					 | 
				
			||||||
        if (newFreq>=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        newFreq=chan[c.chan].baseFreq-c.value;
 | 
					 | 
				
			||||||
        if (newFreq<=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // check for octave boundary
 | 
					 | 
				
			||||||
      // what the heck!
 | 
					 | 
				
			||||||
      if (!chan[c.chan].portaPause) {
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            chan[c.chan].portaPauseFreq=(parent->song.oldOctaveBoundary?(newFreq>>1):boundaryBottom)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
            chan[c.chan].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            chan[c.chan].portaPauseFreq=newFreq=(parent->song.oldOctaveBoundary?(newFreq<<1):(boundaryTop-1))|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
            chan[c.chan].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      chan[c.chan].portaPause=false;
 | 
					 | 
				
			||||||
      chan[c.chan].freqChanged=true;
 | 
					 | 
				
			||||||
      chan[c.chan].baseFreq=newFreq;
 | 
					 | 
				
			||||||
      if (return2) {
 | 
					 | 
				
			||||||
        chan[c.chan].inPorta=false;
 | 
					 | 
				
			||||||
        return 2;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case DIV_CMD_SAMPLE_BANK:
 | 
					    case DIV_CMD_SAMPLE_BANK:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,52 +143,7 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
 | 
					      PLEASE_HELP_ME(opChan[ch]);
 | 
				
			||||||
      int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
 | 
					 | 
				
			||||||
      int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
 | 
					 | 
				
			||||||
      int newFreq;
 | 
					 | 
				
			||||||
      bool return2=false;
 | 
					 | 
				
			||||||
      if (opChan[ch].portaPause) {
 | 
					 | 
				
			||||||
        opChan[ch].baseFreq=opChan[ch].portaPauseFreq;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (destFreq>opChan[ch].baseFreq) {
 | 
					 | 
				
			||||||
        newFreq=opChan[ch].baseFreq+c.value;
 | 
					 | 
				
			||||||
        if (newFreq>=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        newFreq=opChan[ch].baseFreq-c.value;
 | 
					 | 
				
			||||||
        if (newFreq<=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // what the heck!
 | 
					 | 
				
			||||||
      if (!opChan[ch].portaPause) {
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            opChan[ch].portaPauseFreq=(boundaryBottom)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
            opChan[ch].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            opChan[ch].portaPauseFreq=newFreq=(boundaryTop-1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
            opChan[ch].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      opChan[ch].portaPause=false;
 | 
					 | 
				
			||||||
      opChan[ch].freqChanged=true;
 | 
					 | 
				
			||||||
      opChan[ch].baseFreq=newFreq;
 | 
					 | 
				
			||||||
      if (return2) return 2;
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case DIV_CMD_LEGATO: {
 | 
					    case DIV_CMD_LEGATO: {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,10 +27,12 @@ class DivPlatformYM2610BExt: public DivPlatformYM2610B {
 | 
				
			||||||
    unsigned char freqH, freqL;
 | 
					    unsigned char freqH, freqL;
 | 
				
			||||||
    int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins;
 | 
					    int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins;
 | 
				
			||||||
    signed char konCycles;
 | 
					    signed char konCycles;
 | 
				
			||||||
    bool active, insChanged, freqChanged, keyOn, keyOff, portaPause;
 | 
					    bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta;
 | 
				
			||||||
    int vol;
 | 
					    int vol;
 | 
				
			||||||
    unsigned char pan;
 | 
					    unsigned char pan;
 | 
				
			||||||
    OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), portaPauseFreq(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), vol(0), pan(3) {}
 | 
					    // UGLY
 | 
				
			||||||
 | 
					    OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), portaPauseFreq(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false),
 | 
				
			||||||
 | 
					    inPorta(false), vol(0), pan(3) {}
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  OpChannel opChan[4];
 | 
					  OpChannel opChan[4];
 | 
				
			||||||
  bool isOpMuted[4];
 | 
					  bool isOpMuted[4];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,52 +143,7 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      int boundaryBottom=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,0,false);
 | 
					      PLEASE_HELP_ME(opChan[ch]);
 | 
				
			||||||
      int boundaryTop=parent->calcBaseFreq(chipClock,CHIP_FREQBASE,12,false);
 | 
					 | 
				
			||||||
      int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
 | 
					 | 
				
			||||||
      int newFreq;
 | 
					 | 
				
			||||||
      bool return2=false;
 | 
					 | 
				
			||||||
      if (opChan[ch].portaPause) {
 | 
					 | 
				
			||||||
        opChan[ch].baseFreq=opChan[ch].portaPauseFreq;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (destFreq>opChan[ch].baseFreq) {
 | 
					 | 
				
			||||||
        newFreq=opChan[ch].baseFreq+c.value;
 | 
					 | 
				
			||||||
        if (newFreq>=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        newFreq=opChan[ch].baseFreq-c.value;
 | 
					 | 
				
			||||||
        if (newFreq<=destFreq) {
 | 
					 | 
				
			||||||
          newFreq=destFreq;
 | 
					 | 
				
			||||||
          return2=true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // what the heck!
 | 
					 | 
				
			||||||
      if (!opChan[ch].portaPause) {
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)>boundaryTop && (newFreq&0xf800)<0x3800) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            opChan[ch].portaPauseFreq=(boundaryBottom)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
            opChan[ch].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq>>1)|((newFreq+0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((newFreq&0x7ff)<boundaryBottom && (newFreq&0xf800)>0) {
 | 
					 | 
				
			||||||
          if (parent->song.fbPortaPause) {
 | 
					 | 
				
			||||||
            opChan[ch].portaPauseFreq=newFreq=(boundaryTop-1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
            opChan[ch].portaPause=true;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            newFreq=(newFreq<<1)|((newFreq-0x800)&0xf800);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      opChan[ch].portaPause=false;
 | 
					 | 
				
			||||||
      opChan[ch].freqChanged=true;
 | 
					 | 
				
			||||||
      opChan[ch].baseFreq=newFreq;
 | 
					 | 
				
			||||||
      if (return2) return 2;
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case DIV_CMD_LEGATO: {
 | 
					    case DIV_CMD_LEGATO: {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,10 +27,12 @@ class DivPlatformYM2610Ext: public DivPlatformYM2610 {
 | 
				
			||||||
    unsigned char freqH, freqL;
 | 
					    unsigned char freqH, freqL;
 | 
				
			||||||
    int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins;
 | 
					    int freq, baseFreq, pitch, pitch2, portaPauseFreq, ins;
 | 
				
			||||||
    signed char konCycles;
 | 
					    signed char konCycles;
 | 
				
			||||||
    bool active, insChanged, freqChanged, keyOn, keyOff, portaPause;
 | 
					    bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta;
 | 
				
			||||||
    int vol;
 | 
					    int vol;
 | 
				
			||||||
    unsigned char pan;
 | 
					    unsigned char pan;
 | 
				
			||||||
    OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), portaPauseFreq(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), vol(0), pan(3) {}
 | 
					    // UGLY
 | 
				
			||||||
 | 
					    OpChannel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), pitch2(0), portaPauseFreq(0), ins(-1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false),
 | 
				
			||||||
 | 
					    inPorta(false), vol(0), pan(3) {}
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  OpChannel opChan[4];
 | 
					  OpChannel opChan[4];
 | 
				
			||||||
  bool isOpMuted[4];
 | 
					  bool isOpMuted[4];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue