mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-25 14:05:12 +00:00
also enable backward on Windows XP
This commit is contained in:
parent
b3b84d41b6
commit
4df1c59698
6 changed files with 201 additions and 53 deletions
|
@ -15,7 +15,7 @@ fi
|
||||||
cd xpbuild
|
cd xpbuild
|
||||||
|
|
||||||
# TODO: potential Arch-ism?
|
# TODO: potential Arch-ism?
|
||||||
i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=ON -DWITH_RENDER_DX11=OFF -DSDL_SSE2=OFF -DSDL_SSE3=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=OFF -DENABLE_AVX=OFF -DENABLE_AVX2=OFF .. || exit 1
|
i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=ON -DWITH_RENDER_DX11=OFF -DSDL_SSE2=OFF -DSDL_SSE3=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=OFF -DENABLE_AVX=OFF -DENABLE_AVX2=OFF -DUSE_BACKWARD=ON .. || exit 1
|
||||||
make -j8 || exit 1
|
make -j8 || exit 1
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
//#define rWrite(a,v) pendingWrites[a]=v;
|
//#define rWrite(a,v) pendingWrites[a]=v;
|
||||||
#define rWrite(a,v) if (!skipRegisterWrites) {writes.push(QueuedWrite(a,v)); if (dumpWrites) {addWrite(a,v);} }
|
#define rWrite(a,v) if (!skipRegisterWrites) {writes.push(QueuedWrite(a,v)); if (dumpWrites) {addWrite(a,v);} }
|
||||||
|
|
||||||
#define CHIP_DIVIDER 32
|
#define CHIP_DIVIDER 8
|
||||||
|
|
||||||
const char* regCheatSheetDave[]={
|
const char* regCheatSheetDave[]={
|
||||||
"Freq0", "00",
|
"Freq0", "00",
|
||||||
|
@ -48,36 +48,54 @@ const char* regCheatSheetDave[]={
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unsigned char snapPeriodLong[15]={
|
||||||
|
0, 1, 3, 3, 3, 6, 6, 7, 7, 10, 10, 12, 12, 13, 13
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned char snapPeriodShort[15]={
|
||||||
|
2, 2, 2, 2, 5, 5, 5, 8, 8, 8, 11, 11, 11, 11, 11
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned char waveMap[8]={
|
||||||
|
0, 1, 1, 2, 3, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
const char** DivPlatformDave::getRegisterSheet() {
|
const char** DivPlatformDave::getRegisterSheet() {
|
||||||
return regCheatSheetDave;
|
return regCheatSheetDave;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformDave::acquire(short** buf, size_t len) {
|
void DivPlatformDave::acquire(short** buf, size_t len) {
|
||||||
for (size_t h=0; h<len; h++) {
|
for (size_t h=0; h<len; h++) {
|
||||||
// PCM part
|
|
||||||
for (int i=4; i<6; i++) {
|
for (int i=4; i<6; i++) {
|
||||||
if (chan[i].dacSample!=-1) {
|
if (chan[i].dacSample!=-1) {
|
||||||
chan[i].dacPeriod+=chan[i].dacRate;
|
chan[i].dacPeriod+=chan[i].freq;
|
||||||
if (chan[i].dacPeriod>rate) {
|
if (chan[i].dacPeriod>rate) {
|
||||||
DivSample* s=parent->getSample(chan[i].dacSample);
|
DivSample* s=parent->getSample(chan[i].dacSample);
|
||||||
if (s->samples<=0) {
|
if (s->samples<=0) {
|
||||||
chan[i].dacSample=-1;
|
chan[i].dacSample=-1;
|
||||||
|
writeControl=true;
|
||||||
|
chan[0].writeVol=true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
signed char dacData=((signed char)((unsigned char)s->data8[chan[i].dacPos]^0x80))>>3;
|
signed char dacData=(s->data8[chan[i].dacPos]*chan[i].outVol)>>8;
|
||||||
chan[i].dacOut=CLAMP(dacData,-16,15);
|
chan[i].dacOut=dacData+32;
|
||||||
chan[i].dacPos++;
|
chan[i].dacPos++;
|
||||||
|
if (!isMuted[i]) {
|
||||||
|
rWrite(8+((i-4)<<2),chan[i].dacOut&0x3f);
|
||||||
|
}
|
||||||
if (s->isLoopable() && chan[i].dacPos>=(unsigned int)s->loopEnd) {
|
if (s->isLoopable() && chan[i].dacPos>=(unsigned int)s->loopEnd) {
|
||||||
chan[i].dacPos=s->loopStart;
|
chan[i].dacPos=s->loopStart;
|
||||||
} else if (chan[i].dacPos>=s->samples) {
|
} else if (chan[i].dacPos>=s->samples) {
|
||||||
chan[i].dacSample=-1;
|
chan[i].dacSample=-1;
|
||||||
|
writeControl=true;
|
||||||
|
chan[0].writeVol=true;
|
||||||
}
|
}
|
||||||
chan[i].dacPeriod-=rate;
|
chan[i].dacPeriod-=rate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!writes.empty()) {
|
if (!writes.empty()) {
|
||||||
QueuedWrite w=writes.front();
|
QueuedWrite w=writes.front();
|
||||||
dave->writePort(w.addr,w.val);
|
dave->writePort(w.addr,w.val);
|
||||||
regPool[w.addr&0x1f]=w.val;
|
regPool[w.addr&0x1f]=w.val;
|
||||||
|
@ -101,18 +119,24 @@ void DivPlatformDave::tick(bool sysTick) {
|
||||||
chan[i].writeVol=true;
|
chan[i].writeVol=true;
|
||||||
}
|
}
|
||||||
if (chan[i].std.duty.had) {
|
if (chan[i].std.duty.had) {
|
||||||
|
chan[i].noiseFreq=chan[i].std.duty.val&3;
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
if (NEW_ARP_STRAT) {
|
if (NEW_ARP_STRAT) {
|
||||||
chan[i].handleArp();
|
chan[i].handleArp();
|
||||||
} else if (chan[i].std.arp.had) {
|
} else if (chan[i].std.arp.had) {
|
||||||
if (!chan[i].inPorta) {
|
if (!chan[i].inPorta) {
|
||||||
chan[i].baseFreq=parent->calcArp(chan[i].note,chan[i].std.arp.val);
|
if (i>=4) {
|
||||||
|
chan[i].baseFreq=parent->calcBaseFreq(1,1,parent->calcArp(chan[i].note,chan[i].std.arp.val),false);
|
||||||
|
} else {
|
||||||
|
chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
if (chan[i].std.wave.had) {
|
if (chan[i].std.wave.had) {
|
||||||
chan[i].wave=chan[i].std.wave.val;
|
chan[i].wave=chan[i].std.wave.val&7;
|
||||||
|
if (i==3 && chan[i].wave>3) chan[i].wave=3;
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
if (chan[i].std.panL.had) {
|
if (chan[i].std.panL.had) {
|
||||||
|
@ -124,6 +148,13 @@ void DivPlatformDave::tick(bool sysTick) {
|
||||||
if (chan[i].std.panL.had || chan[i].std.panR.had) {
|
if (chan[i].std.panL.had || chan[i].std.panR.had) {
|
||||||
chan[i].writeVol=true;
|
chan[i].writeVol=true;
|
||||||
}
|
}
|
||||||
|
if (chan[i].std.ex1.had) {
|
||||||
|
chan[i].highPass=chan[i].std.ex1.val&1;
|
||||||
|
chan[i].ringMod=chan[i].std.ex1.val&2;
|
||||||
|
chan[i].swapCounters=chan[i].std.ex1.val&4;
|
||||||
|
chan[i].lowPass=chan[i].std.ex1.val&8;
|
||||||
|
chan[i].freqChanged=true;
|
||||||
|
}
|
||||||
if (chan[i].std.pitch.had) {
|
if (chan[i].std.pitch.had) {
|
||||||
if (chan[i].std.pitch.mode) {
|
if (chan[i].std.pitch.mode) {
|
||||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||||
|
@ -140,53 +171,135 @@ void DivPlatformDave::tick(bool sysTick) {
|
||||||
chan[i].dacPeriod=0;
|
chan[i].dacPeriod=0;
|
||||||
chan[i].keyOn=true;
|
chan[i].keyOn=true;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
chan[i].resetPhase=true;
|
||||||
|
writeControl=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].writeVol) {
|
if (chan[i].writeVol) {
|
||||||
if (chan[i].active) {
|
if (i<4) {
|
||||||
rWrite(8+i,(63+chan[i].outVol*chan[i].panL)>>6);
|
if (chan[i].active && !isMuted[i]) {
|
||||||
rWrite(12+i,(63+chan[i].outVol*chan[i].panR)>>6);
|
if (i!=0 || chan[4].dacSample<0) {
|
||||||
} else {
|
rWrite(8+i,(63+chan[i].outVol*chan[i].panL)>>6);
|
||||||
rWrite(8+i,0);
|
}
|
||||||
rWrite(12+i,0);
|
if (i!=0 || chan[5].dacSample<0) {
|
||||||
|
rWrite(12+i,(63+chan[i].outVol*chan[i].panR)>>6);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (i!=0 || chan[4].dacSample<0) {
|
||||||
|
rWrite(8+i,0);
|
||||||
|
}
|
||||||
|
if (i!=0 || chan[5].dacSample<0) {
|
||||||
|
rWrite(12+i,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
chan[i].writeVol=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_PCE);
|
if (i>=4) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,0,chan[i].pitch2,1,1);
|
||||||
if (chan[i].freq<1) chan[i].freq=1;
|
} else {
|
||||||
if (chan[i].freq>4095) chan[i].freq=4095;
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
|
||||||
|
}
|
||||||
|
|
||||||
if (i<3) {
|
if (i<3) {
|
||||||
rWrite((i<<1),chan[i].freq&0xff);
|
switch (chan[i].wave) {
|
||||||
rWrite(1+(i<<1),(chan[i].freq>>8)|((chan[i].wave&3)<<4));
|
case 0:
|
||||||
|
chan[i].freq>>=2;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
chan[i].freq/=5;
|
||||||
|
chan[i].freq>>=1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
chan[i].freq/=15;
|
||||||
|
chan[i].freq>>=1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
chan[i].freq/=63;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
chan[i].freq>>=5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].keyOn) {
|
if (i<4) {
|
||||||
|
if (chan[i].freq<1) chan[i].freq=1;
|
||||||
|
if (chan[i].freq>4095) chan[i].freq=4095;
|
||||||
}
|
}
|
||||||
if (chan[i].keyOff) {
|
|
||||||
|
if (i<3) {
|
||||||
|
if (chan[i].wave==1) { // short 1
|
||||||
|
chan[i].freq=15*(chan[i].freq/15)+snapPeriodShort[(chan[i].freq%15)];
|
||||||
|
} else if (chan[i].wave==2) { // long 1
|
||||||
|
chan[i].freq=15*(chan[i].freq/15)+snapPeriodLong[(chan[i].freq%15)];
|
||||||
|
} else if (chan[i].wave==3) { // long 2 (30, 61, 92, 123... result in silence)
|
||||||
|
if ((chan[i].freq%30)==(chan[i].freq/30)-1) chan[i].freq++;
|
||||||
|
}
|
||||||
|
rWrite((i<<1),chan[i].freq&0xff);
|
||||||
|
rWrite(1+(i<<1),(chan[i].freq>>8)|((waveMap[chan[i].wave])<<4)|(chan[i].highPass?0x40:0)|(chan[i].ringMod?0x80:0));
|
||||||
|
} else if (i==3) {
|
||||||
|
rWrite(6,(chan[i].noiseFreq&3)|((chan[i].wave&3)<<2)|(chan[i].swapCounters?0x10:0)|(chan[i].lowPass?0x20:0)|(chan[i].highPass?0x40:0)|(chan[i].ringMod?0x80:0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].keyOn) chan[i].keyOn=false;
|
if (chan[i].keyOn) chan[i].keyOn=false;
|
||||||
if (chan[i].keyOff) chan[i].keyOff=false;
|
if (chan[i].keyOff) chan[i].keyOff=false;
|
||||||
chan[i].freqChanged=false;
|
chan[i].freqChanged=false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (writeControl) {
|
||||||
|
rWrite(7,(chan[0].resetPhase?1:0)|(chan[1].resetPhase?2:0)|(chan[2].resetPhase?4:0)|((chan[4].dacSample>=0)?8:0)|((chan[5].dacSample>=0)?16:0));
|
||||||
|
rWrite(7,((chan[4].dacSample>=0)?8:0)|((chan[5].dacSample>=0)?16:0));
|
||||||
|
chan[0].resetPhase=false;
|
||||||
|
chan[1].resetPhase=false;
|
||||||
|
chan[2].resetPhase=false;
|
||||||
|
chan[3].resetPhase=false;
|
||||||
|
writeControl=false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformDave::dispatch(DivCommand c) {
|
int DivPlatformDave::dispatch(DivCommand c) {
|
||||||
switch (c.cmd) {
|
switch (c.cmd) {
|
||||||
case DIV_CMD_NOTE_ON: {
|
case DIV_CMD_NOTE_ON: {
|
||||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_PCE);
|
DivInstrument* ins=NULL;
|
||||||
// TODO: handle DAC
|
// DAC
|
||||||
if (c.chan>=4) break;
|
if (c.chan>=4) {
|
||||||
chan[c.chan].sampleNote=DIV_NOTE_NULL;
|
ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA);
|
||||||
chan[c.chan].sampleNoteDelta=0;
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
chan[c.chan].dacSample=ins->amiga.getSample(c.value);
|
||||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
chan[c.chan].sampleNote=c.value;
|
||||||
chan[c.chan].freqChanged=true;
|
c.value=ins->amiga.getFreq(c.value);
|
||||||
chan[c.chan].note=c.value;
|
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
|
||||||
|
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
|
||||||
|
chan[c.chan].dacSample=ins->amiga.getSample(chan[c.chan].sampleNote);
|
||||||
|
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
|
||||||
|
}
|
||||||
|
if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) {
|
||||||
|
chan[c.chan].dacSample=-1;
|
||||||
|
chan[0].writeVol=true;
|
||||||
|
}
|
||||||
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
|
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false);
|
||||||
|
chan[c.chan].freqChanged=true;
|
||||||
|
chan[c.chan].note=c.value;
|
||||||
|
}
|
||||||
|
chan[c.chan].dacPos=0;
|
||||||
|
chan[c.chan].dacPeriod=0;
|
||||||
|
writeControl=true;
|
||||||
|
} else {
|
||||||
|
ins=parent->getIns(chan[c.chan].ins,DIV_INS_DAVE);
|
||||||
|
chan[c.chan].sampleNote=DIV_NOTE_NULL;
|
||||||
|
chan[c.chan].sampleNoteDelta=0;
|
||||||
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
|
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||||
|
chan[c.chan].freqChanged=true;
|
||||||
|
chan[c.chan].note=c.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
chan[c.chan].active=true;
|
chan[c.chan].active=true;
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
|
@ -202,6 +315,11 @@ int DivPlatformDave::dispatch(DivCommand c) {
|
||||||
chan[c.chan].active=false;
|
chan[c.chan].active=false;
|
||||||
chan[c.chan].keyOff=true;
|
chan[c.chan].keyOff=true;
|
||||||
chan[c.chan].writeVol=true;
|
chan[c.chan].writeVol=true;
|
||||||
|
if (c.chan>=4) {
|
||||||
|
chan[c.chan].dacSample=-1;
|
||||||
|
chan[0].writeVol=true;
|
||||||
|
writeControl=true;
|
||||||
|
}
|
||||||
chan[c.chan].macroInit(NULL);
|
chan[c.chan].macroInit(NULL);
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_NOTE_OFF_ENV:
|
case DIV_CMD_NOTE_OFF_ENV:
|
||||||
|
@ -220,6 +338,7 @@ int DivPlatformDave::dispatch(DivCommand c) {
|
||||||
if (!chan[c.chan].std.vol.has) {
|
if (!chan[c.chan].std.vol.has) {
|
||||||
chan[c.chan].outVol=c.value;
|
chan[c.chan].outVol=c.value;
|
||||||
if (chan[c.chan].active) {
|
if (chan[c.chan].active) {
|
||||||
|
chan[c.chan].writeVol=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +355,7 @@ int DivPlatformDave::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_WAVE:
|
case DIV_CMD_WAVE:
|
||||||
chan[c.chan].wave=c.value;
|
chan[c.chan].wave=c.value;
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].freqChanged=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_NOTE_PORTA: {
|
case DIV_CMD_NOTE_PORTA: {
|
||||||
int destFreq=NOTE_PERIODIC(c.value2+chan[c.chan].sampleNoteDelta);
|
int destFreq=NOTE_PERIODIC(c.value2+chan[c.chan].sampleNoteDelta);
|
||||||
|
@ -267,13 +386,13 @@ int DivPlatformDave::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_LEGATO:
|
case DIV_CMD_LEGATO:
|
||||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)));
|
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+chan[c.chan].sampleNoteDelta);
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
chan[c.chan].note=c.value;
|
chan[c.chan].note=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_PORTA:
|
case DIV_CMD_PRE_PORTA:
|
||||||
if (chan[c.chan].active && c.value2) {
|
if (chan[c.chan].active && c.value2) {
|
||||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_PCE));
|
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_DAVE));
|
||||||
}
|
}
|
||||||
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
|
@ -298,14 +417,16 @@ int DivPlatformDave::dispatch(DivCommand c) {
|
||||||
|
|
||||||
void DivPlatformDave::muteChannel(int ch, bool mute) {
|
void DivPlatformDave::muteChannel(int ch, bool mute) {
|
||||||
isMuted[ch]=mute;
|
isMuted[ch]=mute;
|
||||||
// TODO
|
chan[ch].writeVol=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformDave::forceIns() {
|
void DivPlatformDave::forceIns() {
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
chan[i].insChanged=true;
|
chan[i].insChanged=true;
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
|
chan[i].writeVol=true;
|
||||||
}
|
}
|
||||||
|
writeControl=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* DivPlatformDave::getChanState(int ch) {
|
void* DivPlatformDave::getChanState(int ch) {
|
||||||
|
@ -364,16 +485,8 @@ void DivPlatformDave::reset() {
|
||||||
if (dumpWrites) {
|
if (dumpWrites) {
|
||||||
addWrite(0xffffffff,0);
|
addWrite(0xffffffff,0);
|
||||||
}
|
}
|
||||||
|
writeControl=false;
|
||||||
dave->reset(true);
|
dave->reset(true);
|
||||||
lastPan=0xff;
|
|
||||||
cycles=0;
|
|
||||||
curChan=-1;
|
|
||||||
// set global volume
|
|
||||||
rWrite(0,0);
|
|
||||||
rWrite(0x01,0xff);
|
|
||||||
// set per-channel initial panning
|
|
||||||
for (int i=0; i<6; i++) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformDave::getOutputCount() {
|
int DivPlatformDave::getOutputCount() {
|
||||||
|
|
|
@ -29,10 +29,11 @@ class DivPlatformDave: public DivDispatch {
|
||||||
int dacPeriod, dacRate, dacOut;
|
int dacPeriod, dacRate, dacOut;
|
||||||
unsigned int dacPos;
|
unsigned int dacPos;
|
||||||
int dacSample;
|
int dacSample;
|
||||||
|
unsigned char noiseFreq;
|
||||||
unsigned char panL;
|
unsigned char panL;
|
||||||
unsigned char panR;
|
unsigned char panR;
|
||||||
unsigned char wave;
|
unsigned char wave;
|
||||||
bool writeVol;
|
bool writeVol, highPass, ringMod, swapCounters, lowPass, resetPhase;
|
||||||
Channel():
|
Channel():
|
||||||
SharedChannel<signed char>(63),
|
SharedChannel<signed char>(63),
|
||||||
dacPeriod(0),
|
dacPeriod(0),
|
||||||
|
@ -40,10 +41,16 @@ class DivPlatformDave: public DivDispatch {
|
||||||
dacOut(0),
|
dacOut(0),
|
||||||
dacPos(0),
|
dacPos(0),
|
||||||
dacSample(-1),
|
dacSample(-1),
|
||||||
|
noiseFreq(0),
|
||||||
panL(63),
|
panL(63),
|
||||||
panR(63),
|
panR(63),
|
||||||
wave(0),
|
wave(0),
|
||||||
writeVol(false) {}
|
writeVol(false),
|
||||||
|
highPass(false),
|
||||||
|
ringMod(false),
|
||||||
|
swapCounters(false),
|
||||||
|
lowPass(false),
|
||||||
|
resetPhase(false) {}
|
||||||
};
|
};
|
||||||
Channel chan[6];
|
Channel chan[6];
|
||||||
DivDispatchOscBuffer* oscBuf[6];
|
DivDispatchOscBuffer* oscBuf[6];
|
||||||
|
@ -55,9 +62,8 @@ class DivPlatformDave: public DivDispatch {
|
||||||
QueuedWrite(unsigned char a, unsigned char v): addr(a), val(v) {}
|
QueuedWrite(unsigned char a, unsigned char v): addr(a), val(v) {}
|
||||||
};
|
};
|
||||||
FixedQueue<QueuedWrite,512> writes;
|
FixedQueue<QueuedWrite,512> writes;
|
||||||
unsigned char lastPan;
|
bool writeControl;
|
||||||
|
|
||||||
int cycles, curChan;
|
|
||||||
Ep128::Dave* dave;
|
Ep128::Dave* dave;
|
||||||
unsigned char regPool[32];
|
unsigned char regPool[32];
|
||||||
friend void putDispatchChip(void*,int);
|
friend void putDispatchChip(void*,int);
|
||||||
|
|
|
@ -2003,7 +2003,7 @@ void DivEngine::registerSystems() {
|
||||||
);
|
);
|
||||||
|
|
||||||
sysDefs[DIV_SYSTEM_DAVE]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_DAVE]=new DivSysDef(
|
||||||
"Dave", NULL, 0xd5, 0, 6, false, true, 0, false, 0, 0, 0,
|
"Dave", NULL, 0xd5, 0, 6, false, true, 0, false, 1U<<DIV_SAMPLE_DEPTH_8BIT, 0, 0,
|
||||||
"this chip was featured in the Enterprise 128 computer. it is similar to POKEY, but with stereo output.",
|
"this chip was featured in the Enterprise 128 computer. it is similar to POKEY, but with stereo output.",
|
||||||
{"Channel 1", "Channel 2", "Channel 3", "Noise", "DAC Left", "DAC Right"},
|
{"Channel 1", "Channel 2", "Channel 3", "Noise", "DAC Left", "DAC Right"},
|
||||||
{"CH1", "CH2", "CH3", "NO", "L", "R"},
|
{"CH1", "CH2", "CH3", "NO", "L", "R"},
|
||||||
|
|
|
@ -336,6 +336,10 @@ const char* powerNoiseSlopeControlBits[7]={
|
||||||
"invert B", "invert A", "reset B", "reset A", "clip B", "clip A", NULL
|
"invert B", "invert A", "reset B", "reset A", "clip B", "clip A", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char* daveControlBits[5]={
|
||||||
|
"high pass", "ring mod", "swap counters (noise)", "low pass (noise)", NULL
|
||||||
|
};
|
||||||
|
|
||||||
const char* panBits[5]={
|
const char* panBits[5]={
|
||||||
"right", "left", "rear right", "rear left", NULL
|
"right", "left", "rear right", "rear left", NULL
|
||||||
};
|
};
|
||||||
|
@ -6916,6 +6920,10 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
if (ins->type==DIV_INS_POWERNOISE_SLOPE) {
|
if (ins->type==DIV_INS_POWERNOISE_SLOPE) {
|
||||||
dutyMax=0;
|
dutyMax=0;
|
||||||
}
|
}
|
||||||
|
if (ins->type==DIV_INS_DAVE) {
|
||||||
|
dutyLabel="Noise Freq";
|
||||||
|
dutyMax=3;
|
||||||
|
}
|
||||||
|
|
||||||
const char* waveLabel="Waveform";
|
const char* waveLabel="Waveform";
|
||||||
int waveMax=(ins->type==DIV_INS_VERA)?3:(MAX(1,e->song.waveLen-1));
|
int waveMax=(ins->type==DIV_INS_VERA)?3:(MAX(1,e->song.waveLen-1));
|
||||||
|
@ -6953,7 +6961,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
if (ins->type==DIV_INS_POWERNOISE) waveMax=0;
|
if (ins->type==DIV_INS_POWERNOISE) waveMax=0;
|
||||||
if (ins->type==DIV_INS_POWERNOISE_SLOPE) waveMax=0;
|
if (ins->type==DIV_INS_POWERNOISE_SLOPE) waveMax=0;
|
||||||
if (ins->type==DIV_INS_SU || ins->type==DIV_INS_POKEY) waveMax=7;
|
if (ins->type==DIV_INS_SU || ins->type==DIV_INS_POKEY) waveMax=7;
|
||||||
if (ins->type==DIV_INS_DAVE) waveMax=3;
|
if (ins->type==DIV_INS_DAVE) waveMax=4;
|
||||||
if (ins->type==DIV_INS_PET) {
|
if (ins->type==DIV_INS_PET) {
|
||||||
waveMax=8;
|
waveMax=8;
|
||||||
waveBitMode=true;
|
waveBitMode=true;
|
||||||
|
@ -7020,12 +7028,15 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ex1Max=5;
|
ex1Max=5;
|
||||||
ex2Max=11;
|
ex2Max=11;
|
||||||
}
|
}
|
||||||
|
if (ins->type==DIV_INS_DAVE) {
|
||||||
|
ex1Max=4;
|
||||||
|
}
|
||||||
|
|
||||||
int panMin=0;
|
int panMin=0;
|
||||||
int panMax=0;
|
int panMax=0;
|
||||||
bool panSingle=false;
|
bool panSingle=false;
|
||||||
bool panSingleNoBit=false;
|
bool panSingleNoBit=false;
|
||||||
if (ins->type==DIV_INS_STD ||//Game Gear
|
if (ins->type==DIV_INS_STD || // Game Gear
|
||||||
ins->type==DIV_INS_FM ||
|
ins->type==DIV_INS_FM ||
|
||||||
ins->type==DIV_INS_OPM ||
|
ins->type==DIV_INS_OPM ||
|
||||||
ins->type==DIV_INS_GB ||
|
ins->type==DIV_INS_GB ||
|
||||||
|
@ -7097,6 +7108,9 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
if (ins->type==DIV_INS_POWERNOISE_SLOPE) {
|
if (ins->type==DIV_INS_POWERNOISE_SLOPE) {
|
||||||
panMax=15;
|
panMax=15;
|
||||||
}
|
}
|
||||||
|
if (ins->type==DIV_INS_DAVE) {
|
||||||
|
panMax=63;
|
||||||
|
}
|
||||||
|
|
||||||
if (volMax>0) {
|
if (volMax>0) {
|
||||||
macroList.push_back(FurnaceGUIMacroDesc(volumeLabel,&ins->std.volMacro,volMin,volMax,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
|
macroList.push_back(FurnaceGUIMacroDesc(volumeLabel,&ins->std.volMacro,volMin,volMax,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
|
||||||
|
@ -7186,7 +7200,8 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ins->type==DIV_INS_TED ||
|
ins->type==DIV_INS_TED ||
|
||||||
ins->type==DIV_INS_ESFM ||
|
ins->type==DIV_INS_ESFM ||
|
||||||
ins->type==DIV_INS_POWERNOISE ||
|
ins->type==DIV_INS_POWERNOISE ||
|
||||||
ins->type==DIV_INS_POWERNOISE_SLOPE) {
|
ins->type==DIV_INS_POWERNOISE_SLOPE ||
|
||||||
|
ins->type==DIV_INS_DAVE) {
|
||||||
macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
|
macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
|
||||||
}
|
}
|
||||||
if (ex1Max>0) {
|
if (ex1Max>0) {
|
||||||
|
@ -7220,6 +7235,8 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
macroList.push_back(FurnaceGUIMacroDesc("Special",&ins->std.ex1Macro,0,ex1Max,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,snesModeBits));
|
macroList.push_back(FurnaceGUIMacroDesc("Special",&ins->std.ex1Macro,0,ex1Max,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,snesModeBits));
|
||||||
} else if (ins->type==DIV_INS_MSM5232) {
|
} else if (ins->type==DIV_INS_MSM5232) {
|
||||||
macroList.push_back(FurnaceGUIMacroDesc("Group Attack",&ins->std.ex1Macro,0,ex1Max,96,uiColors[GUI_COLOR_MACRO_OTHER]));
|
macroList.push_back(FurnaceGUIMacroDesc("Group Attack",&ins->std.ex1Macro,0,ex1Max,96,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||||
|
} else if (ins->type==DIV_INS_DAVE) {
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.ex1Macro,0,ex1Max,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,daveControlBits));
|
||||||
} else {
|
} else {
|
||||||
macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.ex1Macro,0,ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER]));
|
macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.ex1Macro,0,ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||||
}
|
}
|
||||||
|
|
|
@ -952,6 +952,12 @@ void FurnaceGUI::initSystemPresets() {
|
||||||
CH(DIV_SYSTEM_SAA1099, 1.0f, 0, "")
|
CH(DIV_SYSTEM_SAA1099, 1.0f, 0, "")
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
ENTRY(
|
||||||
|
"Enterprise 128", {
|
||||||
|
CH(DIV_SYSTEM_DAVE, 1.0f, 0, "")
|
||||||
|
},
|
||||||
|
"tickRate=50"
|
||||||
|
);
|
||||||
ENTRY(
|
ENTRY(
|
||||||
"BBC Micro", {
|
"BBC Micro", {
|
||||||
CH(DIV_SYSTEM_SMS, 1.0f, 0,
|
CH(DIV_SYSTEM_SMS, 1.0f, 0,
|
||||||
|
@ -2778,6 +2784,12 @@ void FurnaceGUI::initSystemPresets() {
|
||||||
CH(DIV_SYSTEM_POWERNOISE, 1.0f, 0, "")
|
CH(DIV_SYSTEM_POWERNOISE, 1.0f, 0, "")
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
ENTRY(
|
||||||
|
"Dave", {
|
||||||
|
CH(DIV_SYSTEM_DAVE, 1.0f, 0, "")
|
||||||
|
},
|
||||||
|
"tickRate=50"
|
||||||
|
);
|
||||||
CATEGORY_END;
|
CATEGORY_END;
|
||||||
|
|
||||||
CATEGORY_BEGIN("DefleMask-compatible","these configurations are compatible with DefleMask.\nselect this if you need to save as .dmf or work with that program.");
|
CATEGORY_BEGIN("DefleMask-compatible","these configurations are compatible with DefleMask.\nselect this if you need to save as .dmf or work with that program.");
|
||||||
|
|
Loading…
Reference in a new issue