mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-16 01:35:07 +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) {
|
if (chan[i].keyOn || chan[i].keyOff) {
|
||||||
immWrite(chanMap[i]+ADDR_FREQH,0x00|(chan[i].freqH&31));
|
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;
|
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++) {
|
for (int i=0; i<512; i++) {
|
||||||
if (pendingWrites[i]!=oldWrites[i]) {
|
if (pendingWrites[i]!=oldWrites[i]) {
|
||||||
immWrite(i,pendingWrites[i]&0xff);
|
immWrite(i,pendingWrites[i]&0xff);
|
||||||
|
@ -368,12 +379,21 @@ void DivPlatformOPL::tick() {
|
||||||
chan[i].freqH=freqt>>8;
|
chan[i].freqH=freqt>>8;
|
||||||
chan[i].freqL=freqt&0xff;
|
chan[i].freqL=freqt&0xff;
|
||||||
immWrite(chanMap[i]+ADDR_FREQ,chan[i].freqL);
|
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) {
|
if (chan[i].keyOn) {
|
||||||
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(0x20));
|
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;
|
chan[i].keyOn=false;
|
||||||
} else if (chan[i].freqChanged) {
|
} else if (chan[i].freqChanged) {
|
||||||
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(chan[i].active<<5));
|
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;
|
chan[i].freqChanged=false;
|
||||||
}
|
}
|
||||||
|
@ -457,6 +477,8 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
if (chan[c.chan].insChanged) {
|
if (chan[c.chan].insChanged) {
|
||||||
int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
|
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++) {
|
for (int i=0; i<ops; i++) {
|
||||||
unsigned char slot=slots[i][c.chan];
|
unsigned char slot=slots[i][c.chan];
|
||||||
if (slot==255) continue;
|
if (slot==255) continue;
|
||||||
|
@ -554,16 +576,22 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
chan[c.chan].ins=c.value;
|
chan[c.chan].ins=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PANNING: {
|
case DIV_CMD_PANNING: {
|
||||||
switch (c.value) {
|
if (c.value==0) {
|
||||||
case 0x01:
|
chan[c.chan].pan=3;
|
||||||
chan[c.chan].pan=1;
|
} else {
|
||||||
break;
|
chan[c.chan].pan=(((c.value&15)>0)<<1)|((c.value>>4)>0);
|
||||||
case 0x10:
|
}
|
||||||
chan[c.chan].pan=2;
|
int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
|
||||||
break;
|
if (isMuted[c.chan]) {
|
||||||
default:
|
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;
|
if (ops==4) {
|
||||||
break;
|
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));
|
//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;
|
break;
|
||||||
|
@ -687,6 +715,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
void DivPlatformOPL::forceIns() {
|
void DivPlatformOPL::forceIns() {
|
||||||
for (int i=0; i<18; i++) {
|
for (int i=0; i<18; i++) {
|
||||||
int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2;
|
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++) {
|
for (int j=0; j<ops; j++) {
|
||||||
unsigned char slot=slots[j][i];
|
unsigned char slot=slots[j][i];
|
||||||
if (slot==255) continue;
|
if (slot==255) continue;
|
||||||
|
@ -723,6 +752,7 @@ void DivPlatformOPL::forceIns() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
update4OpMask=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformOPL::toggleRegisterDump(bool enable) {
|
void DivPlatformOPL::toggleRegisterDump(bool enable) {
|
||||||
|
@ -768,10 +798,15 @@ void DivPlatformOPL::reset() {
|
||||||
lfoValue=8;
|
lfoValue=8;
|
||||||
properDrums=properDrumsSys;
|
properDrums=properDrumsSys;
|
||||||
|
|
||||||
|
if (oplType==1) { // disable waveforms
|
||||||
|
immWrite(0x01,0x20);
|
||||||
|
}
|
||||||
|
|
||||||
if (oplType==3) { // enable OPL3 features
|
if (oplType==3) { // enable OPL3 features
|
||||||
immWrite(0x105,1);
|
immWrite(0x105,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update4OpMask=true;
|
||||||
delay=0;
|
delay=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ class DivPlatformOPL: 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, portaPause, furnaceDac, inPorta, fourOp;
|
||||||
int vol, outVol;
|
int vol, outVol;
|
||||||
unsigned char pan;
|
unsigned char pan;
|
||||||
Channel():
|
Channel():
|
||||||
|
@ -51,6 +51,7 @@ class DivPlatformOPL: public DivDispatch {
|
||||||
portaPause(false),
|
portaPause(false),
|
||||||
furnaceDac(false),
|
furnaceDac(false),
|
||||||
inPorta(false),
|
inPorta(false),
|
||||||
|
fourOp(false),
|
||||||
vol(0),
|
vol(0),
|
||||||
pan(3) {}
|
pan(3) {}
|
||||||
};
|
};
|
||||||
|
@ -78,7 +79,7 @@ class DivPlatformOPL: public DivDispatch {
|
||||||
|
|
||||||
unsigned char lfoValue;
|
unsigned char lfoValue;
|
||||||
|
|
||||||
bool useYMFM;
|
bool useYMFM, update4OpMask;
|
||||||
|
|
||||||
short oldWrites[512];
|
short oldWrites[512];
|
||||||
short pendingWrites[512];
|
short pendingWrites[512];
|
||||||
|
|
Loading…
Reference in a new issue