mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-15 17:25:06 +00:00
OPL: kind of fix 4-op mode
This commit is contained in:
parent
32581bb228
commit
42df8255fc
2 changed files with 49 additions and 13 deletions
|
@ -349,10 +349,21 @@ void DivPlatformOPL::tick() {
|
|||
|
||||
if (chan[i].keyOn || chan[i].keyOff) {
|
||||
immWrite(chanMap[i]+ADDR_FREQH,0x00|(chan[i].freqH&31));
|
||||
if (chan[i].state.ops==4 && i<6) {
|
||||
immWrite(chanMap[i+1]+ADDR_FREQH,0x00|(chan[i].freqH&31));
|
||||
}
|
||||
chan[i].keyOff=false;
|
||||
}
|
||||
}
|
||||
|
||||
if (update4OpMask) {
|
||||
update4OpMask=false;
|
||||
if (oplType==3) {
|
||||
unsigned char opMask=chan[0].fourOp|(chan[2].fourOp<<1)|(chan[4].fourOp<<2)|(chan[6].fourOp<<3)|(chan[8].fourOp<<4)|(chan[10].fourOp<<5);
|
||||
rWrite(0x104,opMask);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<512; i++) {
|
||||
if (pendingWrites[i]!=oldWrites[i]) {
|
||||
immWrite(i,pendingWrites[i]&0xff);
|
||||
|
@ -368,12 +379,21 @@ void DivPlatformOPL::tick() {
|
|||
chan[i].freqH=freqt>>8;
|
||||
chan[i].freqL=freqt&0xff;
|
||||
immWrite(chanMap[i]+ADDR_FREQ,chan[i].freqL);
|
||||
if (chan[i].state.ops==4 && i<6) {
|
||||
immWrite(chanMap[i+1]+ADDR_FREQ,chan[i].freqL);
|
||||
}
|
||||
}
|
||||
if (chan[i].keyOn) {
|
||||
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(0x20));
|
||||
if (chan[i].state.ops==4 && i<6) {
|
||||
immWrite(chanMap[i+1]+ADDR_FREQH,chan[i].freqH|(0x20));
|
||||
}
|
||||
chan[i].keyOn=false;
|
||||
} else if (chan[i].freqChanged) {
|
||||
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(chan[i].active<<5));
|
||||
if (chan[i].state.ops==4 && i<6) {
|
||||
immWrite(chanMap[i+1]+ADDR_FREQH,chan[i].freqH|(chan[i].active<<5));
|
||||
}
|
||||
}
|
||||
chan[i].freqChanged=false;
|
||||
}
|
||||
|
@ -457,6 +477,8 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
}
|
||||
if (chan[c.chan].insChanged) {
|
||||
int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
|
||||
chan[c.chan].fourOp=(ops==4);
|
||||
update4OpMask=true;
|
||||
for (int i=0; i<ops; i++) {
|
||||
unsigned char slot=slots[i][c.chan];
|
||||
if (slot==255) continue;
|
||||
|
@ -554,16 +576,22 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
chan[c.chan].ins=c.value;
|
||||
break;
|
||||
case DIV_CMD_PANNING: {
|
||||
switch (c.value) {
|
||||
case 0x01:
|
||||
chan[c.chan].pan=1;
|
||||
break;
|
||||
case 0x10:
|
||||
chan[c.chan].pan=2;
|
||||
break;
|
||||
default:
|
||||
if (c.value==0) {
|
||||
chan[c.chan].pan=3;
|
||||
break;
|
||||
} else {
|
||||
chan[c.chan].pan=(((c.value&15)>0)<<1)|((c.value>>4)>0);
|
||||
}
|
||||
int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
|
||||
if (isMuted[c.chan]) {
|
||||
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1));
|
||||
if (ops==4) {
|
||||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1));
|
||||
}
|
||||
} else {
|
||||
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
|
||||
if (ops==4) {
|
||||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
|
||||
}
|
||||
}
|
||||
//rWrite(chanOffs[c.chan]+ADDR_LRAF,(isMuted[c.chan]?0:(chan[c.chan].pan<<6))|(chan[c.chan].state.fms&7)|((chan[c.chan].state.ams&3)<<4));
|
||||
break;
|
||||
|
@ -687,6 +715,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
void DivPlatformOPL::forceIns() {
|
||||
for (int i=0; i<18; i++) {
|
||||
int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2;
|
||||
chan[i].fourOp=(ops==4);
|
||||
for (int j=0; j<ops; j++) {
|
||||
unsigned char slot=slots[j][i];
|
||||
if (slot==255) continue;
|
||||
|
@ -723,6 +752,7 @@ void DivPlatformOPL::forceIns() {
|
|||
}
|
||||
}
|
||||
}
|
||||
update4OpMask=true;
|
||||
}
|
||||
|
||||
void DivPlatformOPL::toggleRegisterDump(bool enable) {
|
||||
|
@ -768,10 +798,15 @@ void DivPlatformOPL::reset() {
|
|||
lfoValue=8;
|
||||
properDrums=properDrumsSys;
|
||||
|
||||
if (oplType==1) { // disable waveforms
|
||||
immWrite(0x01,0x20);
|
||||
}
|
||||
|
||||
if (oplType==3) { // enable OPL3 features
|
||||
immWrite(0x105,1);
|
||||
}
|
||||
|
||||
update4OpMask=true;
|
||||
delay=0;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, note;
|
||||
unsigned char ins;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta, fourOp;
|
||||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
Channel():
|
||||
|
@ -51,6 +51,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
portaPause(false),
|
||||
furnaceDac(false),
|
||||
inPorta(false),
|
||||
fourOp(false),
|
||||
vol(0),
|
||||
pan(3) {}
|
||||
};
|
||||
|
@ -78,7 +79,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
|
||||
unsigned char lfoValue;
|
||||
|
||||
bool useYMFM;
|
||||
bool useYMFM, update4OpMask;
|
||||
|
||||
short oldWrites[512];
|
||||
short pendingWrites[512];
|
||||
|
|
Loading…
Reference in a new issue