port ExtCh op macro code to OPN family, part 3

This commit is contained in:
tildearrow 2022-12-21 21:50:49 -05:00
parent 246048e8ed
commit 2c36706d22
7 changed files with 64 additions and 51 deletions

View File

@ -150,6 +150,7 @@ class DivPlatformOPN: public DivPlatformFMBase {
unsigned int fmDivBase;
unsigned int ayDiv;
unsigned char csmChan;
unsigned char lfoValue;
bool extSys;
DivConfig ayFlags;
@ -162,6 +163,7 @@ class DivPlatformOPN: public DivPlatformFMBase {
fmDivBase(d),
ayDiv(a),
csmChan(cc),
lfoValue(0),
extSys(isExtSys) {}
};

View File

@ -81,8 +81,6 @@ class DivPlatformGenesis: public DivPlatformOPN {
ymfm::ym2612* fm_ymfm;
ymfm::ym2612::output_data out_ymfm;
DivYM2612Interface iface;
unsigned char lfoValue;
int softPCMTimer;

View File

@ -219,14 +219,14 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
rWrite(chanOffs[2]+ADDR_FB_ALG,(chan[2].state.alg&7)|(chan[2].state.fb<<3));
break;
}
case DIV_CMD_FM_MULT: { // TODO
case DIV_CMD_FM_MULT: {
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
op.mult=c.value2&15;
rWrite(baseAddr+0x30,(op.mult&15)|(dtTable[op.dt&7]<<4));
break;
}
case DIV_CMD_FM_TL: { // TODO
case DIV_CMD_FM_TL: {
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
op.tl=c.value2;

View File

@ -173,8 +173,9 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) {
immWrite(0x27,extMode?0x40:0);
break;
}
case DIV_CMD_FM_LFO: {
rWrite(0x22,(c.value&7)|((c.value>>4)<<3));
case DIV_CMD_FM_LFO: { // ???
lfoValue=(c.value&7)|((c.value>>4)<<3);
rWrite(0x22,lfoValue);
break;
}
case DIV_CMD_FM_FB: {
@ -182,20 +183,23 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) {
rWrite(chanOffs[2]+ADDR_FB_ALG,(chan[2].state.alg&7)|(chan[2].state.fb<<3));
break;
}
case DIV_CMD_FM_MULT: { // TODO
case DIV_CMD_FM_MULT: {
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
DivInstrumentFM::Operator op=ins->fm.op[orderedOps[c.value]];
rWrite(baseAddr+0x30,(c.value2&15)|(dtTable[op.dt&7]<<4));
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
op.mult=c.value2&15;
rWrite(baseAddr+0x30,(op.mult&15)|(dtTable[op.dt&7]<<4));
break;
}
case DIV_CMD_FM_TL: { // TODO
case DIV_CMD_FM_TL: {
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
if (isOutput[ins->fm.alg][c.value]) {
rWrite(baseAddr+0x40,127-(((127-c.value2)*(opChan[ch].vol&0x7f))/127));
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
op.tl=c.value2;
if (isOpMuted[ch]) {
rWrite(baseAddr+0x40,127);
} else if (KVS(2,c.value)) {
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
} else {
rWrite(baseAddr+0x40,c.value2);
rWrite(baseAddr+0x40,op.tl);
}
break;
}

View File

@ -140,14 +140,13 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) {
} else {
opChan[ch].pan=(c.value2>0)|((c.value>0)<<1);
}
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
if (parent->song.sharedExtStat) {
for (int i=0; i<4; i++) {
if (ch==i) continue;
opChan[i].pan=opChan[ch].pan;
}
}
rWrite(chanOffs[2]+0xb4,(opChan[ch].pan<<6)|(ins->fm.fms&7)|((ins->fm.ams&3)<<4));
rWrite(chanOffs[2]+0xb4,(IS_EXTCH_MUTED?0:(opChan[ch].pan<<6))|(chan[2].state.fms&7)|((chan[2].state.ams&3)<<4));
break;
}
case DIV_CMD_PITCH: {
@ -193,7 +192,8 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) {
break;
}
case DIV_CMD_FM_LFO: {
rWrite(0x22,(c.value&7)|((c.value>>4)<<3));
lfoValue=(c.value&7)|((c.value>>4)<<3);
rWrite(0x22,lfoValue);
break;
}
case DIV_CMD_FM_FB: {
@ -201,20 +201,23 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) {
rWrite(chanOffs[2]+ADDR_FB_ALG,(chan[2].state.alg&7)|(chan[2].state.fb<<3));
break;
}
case DIV_CMD_FM_MULT: { // TODO
case DIV_CMD_FM_MULT: {
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
DivInstrumentFM::Operator op=ins->fm.op[orderedOps[c.value]];
rWrite(baseAddr+0x30,(c.value2&15)|(dtTable[op.dt&7]<<4));
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
op.mult=c.value2&15;
rWrite(baseAddr+0x30,(op.mult&15)|(dtTable[op.dt&7]<<4));
break;
}
case DIV_CMD_FM_TL: { // TODO
case DIV_CMD_FM_TL: {
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
if (isOutput[ins->fm.alg][c.value]) {
rWrite(baseAddr+0x40,127-(((127-c.value2)*(opChan[ch].vol&0x7f))/127));
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
op.tl=c.value2;
if (isOpMuted[ch]) {
rWrite(baseAddr+0x40,127);
} else if (KVS(2,c.value)) {
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
} else {
rWrite(baseAddr+0x40,c.value2);
rWrite(baseAddr+0x40,op.tl);
}
break;
}

View File

@ -136,14 +136,13 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) {
} else {
opChan[ch].pan=(c.value2>0)|((c.value>0)<<1);
}
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
if (parent->song.sharedExtStat) {
for (int i=0; i<4; i++) {
if (ch==i) continue;
opChan[i].pan=opChan[ch].pan;
}
}
rWrite(chanOffs[extChanOffs]+0xb4,(opChan[ch].pan<<6)|(ins->fm.fms&7)|((ins->fm.ams&3)<<4));
rWrite(chanOffs[extChanOffs]+0xb4,(IS_EXTCH_MUTED?0:(opChan[ch].pan<<6))|(chan[extChanOffs].state.fms&7)|((chan[extChanOffs].state.ams&3)<<4));
break;
}
case DIV_CMD_PITCH: {
@ -189,7 +188,8 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) {
break;
}
case DIV_CMD_FM_LFO: {
rWrite(0x22,(c.value&7)|((c.value>>4)<<3));
lfoValue=(c.value&7)|((c.value>>4)<<3);
rWrite(0x22,lfoValue);
break;
}
case DIV_CMD_FM_FB: {
@ -197,20 +197,23 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) {
rWrite(chanOffs[extChanOffs]+ADDR_FB_ALG,(chan[extChanOffs].state.alg&7)|(chan[extChanOffs].state.fb<<3));
break;
}
case DIV_CMD_FM_MULT: { // TODO
case DIV_CMD_FM_MULT: {
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[orderedOps[c.value]];
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
DivInstrumentFM::Operator op=ins->fm.op[orderedOps[c.value]];
rWrite(baseAddr+0x30,(c.value2&15)|(dtTable[op.dt&7]<<4));
DivInstrumentFM::Operator& op=chan[extChanOffs].state.op[orderedOps[c.value]];
op.mult=c.value2&15;
rWrite(baseAddr+0x30,(op.mult&15)|(dtTable[op.dt&7]<<4));
break;
}
case DIV_CMD_FM_TL: { // TODO
case DIV_CMD_FM_TL: {
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[orderedOps[c.value]];
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
if (isOutput[ins->fm.alg][c.value]) {
rWrite(baseAddr+0x40,127-(((127-c.value2)*(opChan[ch].vol&0x7f))/127));
DivInstrumentFM::Operator& op=chan[extChanOffs].state.op[orderedOps[c.value]];
op.tl=c.value2;
if (isOpMuted[ch]) {
rWrite(baseAddr+0x40,127);
} else if (KVS(2,c.value)) {
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
} else {
rWrite(baseAddr+0x40,c.value2);
rWrite(baseAddr+0x40,op.tl);
}
break;
}

View File

@ -136,14 +136,13 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) {
} else {
opChan[ch].pan=(c.value2>0)|((c.value>0)<<1);
}
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
if (parent->song.sharedExtStat) {
for (int i=0; i<4; i++) {
if (ch==i) continue;
opChan[i].pan=opChan[ch].pan;
}
}
rWrite(chanOffs[extChanOffs]+0xb4,(opChan[ch].pan<<6)|(ins->fm.fms&7)|((ins->fm.ams&3)<<4));
rWrite(chanOffs[extChanOffs]+0xb4,(IS_EXTCH_MUTED?0:(opChan[ch].pan<<6))|(chan[extChanOffs].state.fms&7)|((chan[extChanOffs].state.ams&3)<<4));
break;
}
case DIV_CMD_PITCH: {
@ -189,7 +188,8 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) {
break;
}
case DIV_CMD_FM_LFO: {
rWrite(0x22,(c.value&7)|((c.value>>4)<<3));
lfoValue=(c.value&7)|((c.value>>4)<<3);
rWrite(0x22,lfoValue);
break;
}
case DIV_CMD_FM_FB: {
@ -197,20 +197,23 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) {
rWrite(chanOffs[extChanOffs]+ADDR_FB_ALG,(chan[extChanOffs].state.alg&7)|(chan[extChanOffs].state.fb<<3));
break;
}
case DIV_CMD_FM_MULT: { // TODO
case DIV_CMD_FM_MULT: {
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[orderedOps[c.value]];
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
DivInstrumentFM::Operator op=ins->fm.op[orderedOps[c.value]];
rWrite(baseAddr+0x30,(c.value2&15)|(dtTable[op.dt&7]<<4));
DivInstrumentFM::Operator& op=chan[extChanOffs].state.op[orderedOps[c.value]];
op.mult=c.value2&15;
rWrite(baseAddr+0x30,(op.mult&15)|(dtTable[op.dt&7]<<4));
break;
}
case DIV_CMD_FM_TL: { // TODO
case DIV_CMD_FM_TL: {
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[orderedOps[c.value]];
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
if (isOutput[ins->fm.alg][c.value]) {
rWrite(baseAddr+0x40,127-(((127-c.value2)*(opChan[ch].vol&0x7f))/127));
DivInstrumentFM::Operator& op=chan[extChanOffs].state.op[orderedOps[c.value]];
op.tl=c.value2;
if (isOpMuted[ch]) {
rWrite(baseAddr+0x40,127);
} else if (KVS(2,c.value)) {
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
} else {
rWrite(baseAddr+0x40,c.value2);
rWrite(baseAddr+0x40,op.tl);
}
break;
}