Merge branch 'master' of https://github.com/tildearrow/furnace into es5506_alt
This commit is contained in:
commit
0a49d4bfd0
449 changed files with 36799 additions and 10388 deletions
|
|
@ -27,108 +27,6 @@
|
|||
|
||||
#define IS_REALLY_MUTED(x) (isMuted[x] && (x<5 || !softPCM || (isMuted[5] && isMuted[6])))
|
||||
|
||||
const char* DivPlatformGenesis::getEffectName(unsigned char effect) {
|
||||
switch (effect) {
|
||||
case 0x10:
|
||||
return "10xy: Setup LFO (x: enable; y: speed)";
|
||||
break;
|
||||
case 0x11:
|
||||
return "11xx: Set feedback (0 to 7)";
|
||||
break;
|
||||
case 0x12:
|
||||
return "12xx: Set level of operator 1 (0 highest, 7F lowest)";
|
||||
break;
|
||||
case 0x13:
|
||||
return "13xx: Set level of operator 2 (0 highest, 7F lowest)";
|
||||
break;
|
||||
case 0x14:
|
||||
return "14xx: Set level of operator 3 (0 highest, 7F lowest)";
|
||||
break;
|
||||
case 0x15:
|
||||
return "15xx: Set level of operator 4 (0 highest, 7F lowest)";
|
||||
break;
|
||||
case 0x16:
|
||||
return "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)";
|
||||
break;
|
||||
case 0x17:
|
||||
return "17xx: Enable channel 6 DAC";
|
||||
break;
|
||||
case 0x18:
|
||||
return "18xx: Toggle extended channel 3 mode";
|
||||
break;
|
||||
case 0x19:
|
||||
return "19xx: Set attack of all operators (0 to 1F)";
|
||||
break;
|
||||
case 0x1a:
|
||||
return "1Axx: Set attack of operator 1 (0 to 1F)";
|
||||
break;
|
||||
case 0x1b:
|
||||
return "1Bxx: Set attack of operator 2 (0 to 1F)";
|
||||
break;
|
||||
case 0x1c:
|
||||
return "1Cxx: Set attack of operator 3 (0 to 1F)";
|
||||
break;
|
||||
case 0x1d:
|
||||
return "1Dxx: Set attack of operator 4 (0 to 1F)";
|
||||
break;
|
||||
case 0x30:
|
||||
return "30xx: Toggle hard envelope reset on new notes";
|
||||
break;
|
||||
case 0x50:
|
||||
return "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)";
|
||||
break;
|
||||
case 0x51:
|
||||
return "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)";
|
||||
break;
|
||||
case 0x52:
|
||||
return "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)";
|
||||
break;
|
||||
case 0x53:
|
||||
return "53xy: Set detune (x: operator from 1 to 4 (0 for all ops); y: detune where 3 is center)";
|
||||
break;
|
||||
case 0x54:
|
||||
return "54xy: Set envelope scale (x: operator from 1 to 4 (0 for all ops); y: scale from 0 to 3)";
|
||||
break;
|
||||
case 0x55:
|
||||
return "55xy: Set SSG envelope (x: operator from 1 to 4 (0 for all ops); y: 0-7 on, 8 off)";
|
||||
break;
|
||||
case 0x56:
|
||||
return "56xx: Set decay of all operators (0 to 1F)";
|
||||
break;
|
||||
case 0x57:
|
||||
return "57xx: Set decay of operator 1 (0 to 1F)";
|
||||
break;
|
||||
case 0x58:
|
||||
return "58xx: Set decay of operator 2 (0 to 1F)";
|
||||
break;
|
||||
case 0x59:
|
||||
return "59xx: Set decay of operator 3 (0 to 1F)";
|
||||
break;
|
||||
case 0x5a:
|
||||
return "5Axx: Set decay of operator 4 (0 to 1F)";
|
||||
break;
|
||||
case 0x5b:
|
||||
return "5Bxx: Set decay 2 of all operators (0 to 1F)";
|
||||
break;
|
||||
case 0x5c:
|
||||
return "5Cxx: Set decay 2 of operator 1 (0 to 1F)";
|
||||
break;
|
||||
case 0x5d:
|
||||
return "5Dxx: Set decay 2 of operator 2 (0 to 1F)";
|
||||
break;
|
||||
case 0x5e:
|
||||
return "5Exx: Set decay 2 of operator 3 (0 to 1F)";
|
||||
break;
|
||||
case 0x5f:
|
||||
return "5Fxx: Set decay 2 of operator 4 (0 to 1F)";
|
||||
break;
|
||||
case 0xdf:
|
||||
return "DFxx: Set sample playback direction (0: normal; 1: reverse)";
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DivPlatformGenesis::processDAC() {
|
||||
if (softPCM) {
|
||||
softPCMTimer+=chipClock/576;
|
||||
|
|
@ -153,15 +51,13 @@ void DivPlatformGenesis::processDAC() {
|
|||
if (chan[i].dacPeriod>=(chipClock/576)) {
|
||||
if (s->samples>0) {
|
||||
while (chan[i].dacPeriod>=(chipClock/576)) {
|
||||
chan[i].dacPos++;
|
||||
if (((s->loopMode!=DIV_SAMPLE_LOOPMODE_ONESHOT) && chan[i].dacPos>=s->loopEnd) || (chan[i].dacPos>=s->samples)) {
|
||||
if (s->isLoopable() && !chan[i].getDacDirection()) {
|
||||
chan[i].dacPos=s->loopStart;
|
||||
} else {
|
||||
chan[i].dacSample=-1;
|
||||
chan[i].dacPeriod=0;
|
||||
break;
|
||||
}
|
||||
++chan[i].dacPos;
|
||||
if (!chan[i].dacDirection && (s->isLoopable() && chan[i].dacPos>=(unsigned int)s->loopEnd)) {
|
||||
chan[i].dacPos=s->loopStart;
|
||||
} else if (chan[i].dacPos>=s->samples) {
|
||||
chan[i].dacSample=-1;
|
||||
chan[i].dacPeriod=0;
|
||||
break;
|
||||
}
|
||||
chan[i].dacPeriod-=(chipClock/576);
|
||||
}
|
||||
|
|
@ -202,14 +98,12 @@ void DivPlatformGenesis::processDAC() {
|
|||
}
|
||||
}
|
||||
chan[5].dacPos++;
|
||||
if (((s->loopMode!=DIV_SAMPLE_LOOPMODE_ONESHOT) && chan[5].dacPos>=s->loopEnd) || (chan[5].dacPos>=s->samples)) {
|
||||
if (s->isLoopable() && !chan[5].getDacDirection()) {
|
||||
chan[5].dacPos=s->loopStart;
|
||||
} else {
|
||||
chan[5].dacSample=-1;
|
||||
if (parent->song.brokenDACMode) {
|
||||
rWrite(0x2b,0);
|
||||
}
|
||||
if (!chan[5].dacDirection && (s->isLoopable() && chan[5].dacPos>=(unsigned int)s->loopEnd)) {
|
||||
chan[5].dacPos=s->loopStart;
|
||||
} else if (chan[5].dacPos>=s->samples) {
|
||||
chan[5].dacSample=-1;
|
||||
if (parent->song.brokenDACMode) {
|
||||
rWrite(0x2b,0);
|
||||
}
|
||||
}
|
||||
while (chan[5].dacPeriod>=rate) chan[5].dacPeriod-=rate;
|
||||
|
|
@ -360,7 +254,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
if (isMuted[i]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
} else {
|
||||
if (isOutput[chan[i].state.alg][j]) {
|
||||
if (KVS(i,j)) {
|
||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||
|
|
@ -369,26 +263,40 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
|
||||
if (chan[i].std.arp.had) {
|
||||
if (!chan[i].inPorta) {
|
||||
if (chan[i].std.arp.mode) {
|
||||
chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].std.arp.val,11);
|
||||
} else {
|
||||
chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note+(signed char)chan[i].std.arp.val,11);
|
||||
if (i>=5 && chan[i].furnaceDac) {
|
||||
if (chan[i].std.arp.had) {
|
||||
if (!chan[i].inPorta) {
|
||||
chan[i].baseFreq=parent->calcBaseFreq(1,1,parent->calcArp(chan[i].note,chan[i].std.arp.val),false);
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
} else {
|
||||
if (chan[i].std.arp.mode && chan[i].std.arp.finished) {
|
||||
chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note,11);
|
||||
if (chan[i].std.arp.had) {
|
||||
if (!chan[i].inPorta) {
|
||||
chan[i].baseFreq=NOTE_FNUM_BLOCK(parent->calcArp(chan[i].note,chan[i].std.arp.val),11);
|
||||
}
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (chan[i].std.panL.had) {
|
||||
chan[i].pan=chan[i].std.panL.val&3;
|
||||
if (i<6) {
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_REALLY_MUTED(i)?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
if (i>=5 && chan[i].furnaceDac) {
|
||||
if (chan[i].std.panL.had) {
|
||||
chan[5].pan&=1;
|
||||
chan[5].pan|=chan[i].std.panL.val?2:0;
|
||||
}
|
||||
if (chan[i].std.panR.had) {
|
||||
chan[5].pan&=2;
|
||||
chan[5].pan|=chan[i].std.panR.val?1:0;
|
||||
}
|
||||
if (chan[i].std.panL.had || chan[i].std.panR.had) {
|
||||
rWrite(chanOffs[5]+ADDR_LRAF,(IS_REALLY_MUTED(i)?0:(chan[5].pan<<6))|(chan[5].state.fms&7)|((chan[5].state.ams&3)<<4));
|
||||
}
|
||||
} else {
|
||||
if (chan[i].std.panL.had) {
|
||||
chan[i].pan=chan[i].std.panL.val&3;
|
||||
if (i<6) {
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_REALLY_MUTED(i)?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -419,7 +327,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
if (isMuted[i]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
} else {
|
||||
if (isOutput[chan[i].state.alg][j]) {
|
||||
if (KVS(i,j)) {
|
||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||
|
|
@ -439,6 +347,10 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
chan[i].state.ams=chan[i].std.ams.val;
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_REALLY_MUTED(i)?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
}
|
||||
if (chan[i].std.ex4.had && chan[i].active) {
|
||||
chan[i].opMask=chan[i].std.ex4.val&15;
|
||||
chan[i].opMaskChanged=true;
|
||||
}
|
||||
for (int j=0; j<4; j++) {
|
||||
unsigned short baseAddr=chanOffs[i]|opOffs[j];
|
||||
DivInstrumentFM::Operator& op=chan[i].state.op[j];
|
||||
|
|
@ -472,7 +384,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
if (isMuted[i]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
} else {
|
||||
if (isOutput[chan[i].state.alg][j]) {
|
||||
if (KVS(i,j)) {
|
||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||
|
|
@ -571,8 +483,9 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
}
|
||||
chan[i].freqChanged=false;
|
||||
}
|
||||
if (chan[i].keyOn) {
|
||||
if (i<6) immWrite(0x28,0xf0|konOffs[i]);
|
||||
if (chan[i].keyOn || chan[i].opMaskChanged) {
|
||||
if (i<6) immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
|
||||
chan[i].opMaskChanged=false;
|
||||
chan[i].keyOn=false;
|
||||
}
|
||||
}
|
||||
|
|
@ -588,7 +501,7 @@ void DivPlatformGenesis::muteChannel(int ch, bool mute) {
|
|||
if (isMuted[ch]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
} else {
|
||||
if (isOutput[chan[ch].state.alg][j]) {
|
||||
if (KVS(ch,j)) {
|
||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[ch].outVol&0x7f,127));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||
|
|
@ -688,6 +601,11 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
|
||||
if (chan[c.chan].insChanged) {
|
||||
chan[c.chan].state=ins->fm;
|
||||
chan[c.chan].opMask=
|
||||
(chan[c.chan].state.op[0].enable?1:0)|
|
||||
(chan[c.chan].state.op[2].enable?2:0)|
|
||||
(chan[c.chan].state.op[1].enable?4:0)|
|
||||
(chan[c.chan].state.op[3].enable?8:0);
|
||||
}
|
||||
|
||||
chan[c.chan].macroInit(ins);
|
||||
|
|
@ -701,7 +619,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
if (isMuted[c.chan]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
} else {
|
||||
if (isOutput[chan[c.chan].state.alg][i]) {
|
||||
if (KVS(c.chan,i)) {
|
||||
if (!chan[c.chan].active || chan[c.chan].insChanged) {
|
||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[c.chan].outVol&0x7f,127));
|
||||
}
|
||||
|
|
@ -774,7 +692,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
if (isMuted[c.chan]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
} else {
|
||||
if (isOutput[chan[c.chan].state.alg][i]) {
|
||||
if (KVS(c.chan,i)) {
|
||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[c.chan].outVol&0x7f,127));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||
|
|
@ -947,7 +865,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
if (isMuted[c.chan]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
} else {
|
||||
if (isOutput[chan[c.chan].state.alg][c.value]) {
|
||||
if (KVS(c.chan,c.value)) {
|
||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[c.chan].outVol&0x7f,127));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||
|
|
@ -1138,7 +1056,7 @@ void DivPlatformGenesis::forceIns() {
|
|||
if (isMuted[i]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
} else {
|
||||
if (isOutput[chan[i].state.alg][j]) {
|
||||
if (KVS(i,j)) {
|
||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue