YM2612: implement full linear pitch (part 2)

This commit is contained in:
tildearrow 2022-05-10 23:17:40 -05:00
parent 0cc2c06bbf
commit f5dbc37902
4 changed files with 75 additions and 22 deletions

View file

@ -1023,7 +1023,7 @@ double DivEngine::calcBaseFreq(double clock, double divider, int note, bool peri
/* logV("f-num: %d block: %d",bf,block); */ \
return bf|(block<<bits);
unsigned short DivEngine::calcBaseFreqFNumBlock(double clock, double divider, int note, int bits) {
int DivEngine::calcBaseFreqFNumBlock(double clock, double divider, int note, int bits) {
if (song.linearPitch==2) { // full linear
return (note<<7);
}

View file

@ -481,7 +481,7 @@ class DivEngine {
double calcBaseFreq(double clock, double divider, int note, bool period);
// calculate base frequency in f-num/block format
unsigned short calcBaseFreqFNumBlock(double clock, double divider, int note, int bits);
int calcBaseFreqFNumBlock(double clock, double divider, int note, int bits);
// calculate frequency/period
int calcFreq(int base, int pitch, bool period=false, int octave=0, int pitch2=0, double clock=1.0, double divider=1.0, int blockBits=0);

View file

@ -471,6 +471,9 @@ void DivPlatformGenesis::tick(bool sysTick) {
for (int i=0; i<6; i++) {
if (i==2 && extMode) continue;
if (chan[i].freqChanged) {
if (parent->song.linearPitch==2) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
} else {
int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11);
int block=(chan[i].baseFreq&0xf800)>>11;
if (fNum<0) fNum=0;
@ -482,6 +485,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
if (fNum>2047) fNum=2047;
}
chan[i].freq=(block<<11)|fNum;
}
if (chan[i].freq>0x3fff) chan[i].freq=0x3fff;
immWrite(chanOffs[i]+ADDR_FREQH,chan[i].freq>>8);
immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff);
@ -495,8 +499,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
off=(double)s->centerRate/8363.0;
}
}
// TODO: linear
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,1,1)+chan[i].pitch2;
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,4,chan[i].pitch2,1,1);
dacRate=chan[i].freq*off;
if (dacRate<1) dacRate=1;
if (dumpWrites) addWrite(0xffff0001,dacRate);
@ -703,6 +706,29 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
break;
}
case DIV_CMD_NOTE_PORTA: {
if (parent->song.linearPitch==2) {
int destFreq=NOTE_FREQUENCY(c.value2);
bool return2=false;
if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value;
if (chan[c.chan].baseFreq>=destFreq) {
chan[c.chan].baseFreq=destFreq;
return2=true;
}
} else {
chan[c.chan].baseFreq-=c.value;
if (chan[c.chan].baseFreq<=destFreq) {
chan[c.chan].baseFreq=destFreq;
return2=true;
}
}
chan[c.chan].freqChanged=true;
if (return2) {
chan[c.chan].inPorta=false;
return 2;
}
break;
}
if (c.chan==5 && chan[c.chan].furnaceDac && dacMode) {
int destFreq=parent->calcBaseFreq(1,1,c.value2,false);
bool return2=false;

View file

@ -127,6 +127,29 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
break;
}
case DIV_CMD_NOTE_PORTA: {
if (parent->song.linearPitch==2) {
int destFreq=NOTE_FREQUENCY(c.value2);
bool return2=false;
if (destFreq>opChan[ch].baseFreq) {
opChan[ch].baseFreq+=c.value;
if (opChan[ch].baseFreq>=destFreq) {
opChan[ch].baseFreq=destFreq;
return2=true;
}
} else {
opChan[ch].baseFreq-=c.value;
if (opChan[ch].baseFreq<=destFreq) {
opChan[ch].baseFreq=destFreq;
return2=true;
}
}
opChan[ch].freqChanged=true;
if (return2) {
//opChan[ch].inPorta=false;
return 2;
}
break;
}
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);
@ -437,6 +460,9 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
unsigned char writeMask=2;
if (extMode) for (int i=0; i<4; i++) {
if (opChan[i].freqChanged) {
if (parent->song.linearPitch==2) {
opChan[i].freq=parent->calcFreq(opChan[i].baseFreq,opChan[i].pitch,false,4,opChan[i].pitch2,chipClock,CHIP_FREQBASE,11);
} else {
int fNum=parent->calcFreq(opChan[i].baseFreq&0x7ff,opChan[i].pitch,false,4,opChan[i].pitch2);
int block=(opChan[i].baseFreq&0xf800)>>11;
if (fNum<0) fNum=0;
@ -448,6 +474,7 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
if (fNum>2047) fNum=2047;
}
opChan[i].freq=(block<<11)|fNum;
}
if (opChan[i].freq>0x3fff) opChan[i].freq=0x3fff;
immWrite(opChanOffsH[i],opChan[i].freq>>8);
immWrite(opChanOffsL[i],opChan[i].freq&0xff);