also enable backward on Windows XP

This commit is contained in:
tildearrow 2024-02-04 02:05:00 -05:00
parent b3b84d41b6
commit 4df1c59698
6 changed files with 201 additions and 53 deletions

View file

@ -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 ..

View file

@ -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() {

View file

@ -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);

View file

@ -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"},

View file

@ -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]));
} }

View file

@ -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.");