mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-27 06:53:01 +00:00
OPLL: 85%
compatible drums work (kinda)
This commit is contained in:
parent
79c148849f
commit
77285a65e6
2 changed files with 90 additions and 26 deletions
|
@ -80,6 +80,8 @@ void DivPlatformOPLL::acquire_nuked(short* bufL, short* bufR, size_t start, size
|
||||||
static int os;
|
static int os;
|
||||||
|
|
||||||
for (size_t h=start; h<start+len; h++) {
|
for (size_t h=start; h<start+len; h++) {
|
||||||
|
os=0;
|
||||||
|
for (int i=0; i<9; i++) {
|
||||||
if (!writes.empty() && --delay<0) {
|
if (!writes.empty() && --delay<0) {
|
||||||
// 84 is safe value
|
// 84 is safe value
|
||||||
QueuedWrite& w=writes.front();
|
QueuedWrite& w=writes.front();
|
||||||
|
@ -98,11 +100,11 @@ void DivPlatformOPLL::acquire_nuked(short* bufL, short* bufR, size_t start, size
|
||||||
}
|
}
|
||||||
|
|
||||||
OPLL_Clock(&fm,o);
|
OPLL_Clock(&fm,o);
|
||||||
os=(o[0]+o[1])<<7;
|
os+=(o[0]+o[1]);
|
||||||
|
}
|
||||||
|
os*=50;
|
||||||
if (os<-32768) os=-32768;
|
if (os<-32768) os=-32768;
|
||||||
if (os>32767) os=32767;
|
if (os>32767) os=32767;
|
||||||
//printf("%d\n",o[0]);
|
|
||||||
|
|
||||||
bufL[h]=os;
|
bufL[h]=os;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +241,12 @@ void DivPlatformOPLL::tick() {
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].keyOn || chan[i].keyOff) {
|
||||||
immWrite(0x20+i,(chan[i].freqH)|(chan[i].state.alg?0x20:0));
|
if (chan[i].drums) {
|
||||||
|
drumState&=~(0x10>>(chan[i].note%12));
|
||||||
|
immWrite(0x0e,0x20|drumState);
|
||||||
|
} else {
|
||||||
|
immWrite(0x20+i,(chan[i].freqH)/*|(chan[i].state.alg?0x20:0)*/);
|
||||||
|
}
|
||||||
//chan[i].keyOn=false;
|
//chan[i].keyOn=false;
|
||||||
chan[i].keyOff=false;
|
chan[i].keyOff=false;
|
||||||
}
|
}
|
||||||
|
@ -259,9 +266,16 @@ void DivPlatformOPLL::tick() {
|
||||||
int freqt=toFreq(chan[i].freq);
|
int freqt=toFreq(chan[i].freq);
|
||||||
chan[i].freqH=freqt>>8;
|
chan[i].freqH=freqt>>8;
|
||||||
chan[i].freqL=freqt&0xff;
|
chan[i].freqL=freqt&0xff;
|
||||||
|
if (!chan[i].drums) {
|
||||||
immWrite(0x10+i,freqt&0xff);
|
immWrite(0x10+i,freqt&0xff);
|
||||||
}
|
}
|
||||||
if (chan[i].keyOn || chan[i].freqChanged) {
|
}
|
||||||
|
if (chan[i].keyOn && chan[i].drums) {
|
||||||
|
//printf("%d\n",chan[i].note%12);
|
||||||
|
drumState|=(0x10>>(chan[i].note%12));
|
||||||
|
immWrite(0x0e,0x20|drumState);
|
||||||
|
chan[i].keyOn=false;
|
||||||
|
} else if (chan[i].keyOn || chan[i].freqChanged) {
|
||||||
//immWrite(0x28,0xf0|konOffs[i]);
|
//immWrite(0x28,0xf0|konOffs[i]);
|
||||||
immWrite(0x20+i,(chan[i].freqH)|(chan[i].active<<4)|(chan[i].state.alg?0x20:0));
|
immWrite(0x20+i,(chan[i].freqH)|(chan[i].active<<4)|(chan[i].state.alg?0x20:0));
|
||||||
chan[i].keyOn=false;
|
chan[i].keyOn=false;
|
||||||
|
@ -359,14 +373,52 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
||||||
rWrite(0x06,(mod.sl<<4)|(mod.rr));
|
rWrite(0x06,(mod.sl<<4)|(mod.rr));
|
||||||
rWrite(0x07,(car.sl<<4)|(car.rr));
|
rWrite(0x07,(car.sl<<4)|(car.rr));
|
||||||
}
|
}
|
||||||
|
if (chan[c.chan].state.opllPreset==16) { // compatible drums mode
|
||||||
|
chan[c.chan].drums=true;
|
||||||
|
immWrite(0x16,0x20);
|
||||||
|
immWrite(0x26,0x05);
|
||||||
|
immWrite(0x16,0x20);
|
||||||
|
immWrite(0x26,0x05);
|
||||||
|
immWrite(0x17,0x50);
|
||||||
|
immWrite(0x27,0x05);
|
||||||
|
immWrite(0x17,0x50);
|
||||||
|
immWrite(0x27,0x05);
|
||||||
|
immWrite(0x18,0xC0);
|
||||||
|
immWrite(0x28,0x01);
|
||||||
|
} else {
|
||||||
|
chan[c.chan].drums=false;
|
||||||
rWrite(0x30+c.chan,(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)|(chan[c.chan].state.opllPreset<<4));
|
rWrite(0x30+c.chan,(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)|(chan[c.chan].state.opllPreset<<4));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chan[c.chan].insChanged=false;
|
chan[c.chan].insChanged=false;
|
||||||
|
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
||||||
chan[c.chan].note=c.value;
|
chan[c.chan].note=c.value;
|
||||||
|
|
||||||
|
if (chan[c.chan].drums) {
|
||||||
|
switch (chan[c.chan].note%12) {
|
||||||
|
case 0: // kick
|
||||||
|
drumVol[0]=(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15);
|
||||||
|
break;
|
||||||
|
case 1: // snare
|
||||||
|
drumVol[1]=(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15);
|
||||||
|
break;
|
||||||
|
case 2: // tom
|
||||||
|
drumVol[2]=(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15);
|
||||||
|
break;
|
||||||
|
case 3: // top
|
||||||
|
drumVol[3]=(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15);
|
||||||
|
break;
|
||||||
|
default: // hi-hat
|
||||||
|
drumVol[4]=(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rWrite(0x36,drumVol[0]);
|
||||||
|
rWrite(0x37,drumVol[1]|(drumVol[4]<<4));
|
||||||
|
rWrite(0x38,drumVol[3]|(drumVol[2]<<4));
|
||||||
|
}
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
}
|
}
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
|
@ -392,7 +444,9 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
||||||
if (!chan[c.chan].std.hasVol) {
|
if (!chan[c.chan].std.hasVol) {
|
||||||
chan[c.chan].outVol=c.value;
|
chan[c.chan].outVol=c.value;
|
||||||
}
|
}
|
||||||
|
if (!chan[c.chan].drums) {
|
||||||
rWrite(0x30+c.chan,(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)|(chan[c.chan].state.opllPreset<<4));
|
rWrite(0x30+c.chan,(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)|(chan[c.chan].state.opllPreset<<4));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_GET_VOLUME: {
|
case DIV_CMD_GET_VOLUME: {
|
||||||
|
@ -570,6 +624,13 @@ void DivPlatformOPLL::reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
lastBusy=60;
|
lastBusy=60;
|
||||||
|
drumState=0;
|
||||||
|
|
||||||
|
drumVol[0]=0;
|
||||||
|
drumVol[1]=0;
|
||||||
|
drumVol[2]=0;
|
||||||
|
drumVol[3]=0;
|
||||||
|
drumVol[4]=0;
|
||||||
|
|
||||||
delay=0;
|
delay=0;
|
||||||
}
|
}
|
||||||
|
@ -619,7 +680,7 @@ void DivPlatformOPLL::setFlags(unsigned int flags) {
|
||||||
} else {
|
} else {
|
||||||
chipClock=COLOR_NTSC/4.0;
|
chipClock=COLOR_NTSC/4.0;
|
||||||
}
|
}
|
||||||
rate=chipClock;
|
rate=chipClock/9;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformOPLL::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
int DivPlatformOPLL::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ class DivPlatformOPLL: public DivDispatch {
|
||||||
unsigned char freqH, freqL;
|
unsigned char freqH, freqL;
|
||||||
int freq, baseFreq, pitch, note;
|
int freq, baseFreq, pitch, note;
|
||||||
unsigned char ins;
|
unsigned char ins;
|
||||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta;
|
bool active, insChanged, freqChanged, keyOn, keyOff, drums, portaPause, furnaceDac, inPorta;
|
||||||
int vol, outVol;
|
int vol, outVol;
|
||||||
unsigned char pan;
|
unsigned char pan;
|
||||||
Channel():
|
Channel():
|
||||||
|
@ -51,6 +51,7 @@ class DivPlatformOPLL: public DivDispatch {
|
||||||
freqChanged(false),
|
freqChanged(false),
|
||||||
keyOn(false),
|
keyOn(false),
|
||||||
keyOff(false),
|
keyOff(false),
|
||||||
|
drums(false),
|
||||||
portaPause(false),
|
portaPause(false),
|
||||||
furnaceDac(false),
|
furnaceDac(false),
|
||||||
inPorta(false),
|
inPorta(false),
|
||||||
|
@ -69,6 +70,8 @@ class DivPlatformOPLL: public DivDispatch {
|
||||||
opll_t fm;
|
opll_t fm;
|
||||||
int delay;
|
int delay;
|
||||||
unsigned char lastBusy;
|
unsigned char lastBusy;
|
||||||
|
unsigned char drumState;
|
||||||
|
unsigned char drumVol[5];
|
||||||
|
|
||||||
unsigned char regPool[256];
|
unsigned char regPool[256];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue