OPM/OPZ: new hard reset strat

also fix weird envelope after hard reset
This commit is contained in:
tildearrow 2023-01-20 04:28:18 -05:00
parent 7fbc188532
commit c0d1fe9c65
7 changed files with 116 additions and 51 deletions

View file

@ -319,27 +319,6 @@ void DivPlatformArcade::tick(bool sysTick) {
rWrite(baseAddr+ADDR_DT2_D2R,(op.d2r&31)|(op.dt2<<6));
}
}
if (chan[i].keyOn || chan[i].keyOff) {
if (chan[i].hardReset && chan[i].keyOn) {
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
immWrite(baseAddr+ADDR_SL_RR,0x0f);
immWrite(baseAddr+ADDR_TL,0x7f);
oldWrites[baseAddr+ADDR_SL_RR]=-1;
oldWrites[baseAddr+ADDR_TL]=-1;
}
}
immWrite(0x08,i);
if (chan[i].hardReset && chan[i].keyOn) {
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
for (int k=0; k<9; k++) {
immWrite(baseAddr+ADDR_SL_RR,0x0f);
}
}
}
chan[i].keyOff=false;
}
}
for (int i=0; i<256; i++) {
@ -349,6 +328,24 @@ void DivPlatformArcade::tick(bool sysTick) {
}
}
int hardResetElapsed=0;
bool mustHardReset=false;
for (int i=0; i<8; i++) {
if (chan[i].keyOn || chan[i].keyOff) {
immWrite(0x08,i);
if (chan[i].hardReset && chan[i].keyOn) {
mustHardReset=true;
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
immWrite(baseAddr+ADDR_SL_RR,0x0f);
hardResetElapsed++;
}
}
chan[i].keyOff=false;
}
}
for (int i=0; i<8; i++) {
if (chan[i].freqChanged) {
chan[i].freq=chan[i].baseFreq+(chan[i].pitch>>1)-64+chan[i].pitch2;
@ -363,14 +360,37 @@ void DivPlatformArcade::tick(bool sysTick) {
if (chan[i].freq>=(95<<6)) chan[i].freq=(95<<6)-1;
immWrite(i+0x28,hScale(chan[i].freq>>6));
immWrite(i+0x30,chan[i].freq<<2);
hardResetElapsed+=2;
chan[i].freqChanged=false;
}
if (chan[i].keyOn || chan[i].opMaskChanged) {
if ((chan[i].keyOn || chan[i].opMaskChanged) && !chan[i].hardReset) {
immWrite(0x08,(chan[i].opMask<<3)|i);
hardResetElapsed++;
chan[i].opMaskChanged=false;
chan[i].keyOn=false;
}
}
// hard reset handling
if (mustHardReset) {
for (unsigned int i=hardResetElapsed; i<hardResetCycles; i++) {
immWrite(0x1f,i&0xff);
}
for (int i=0; i<8; i++) {
if ((chan[i].keyOn || chan[i].opMaskChanged) && chan[i].hardReset) {
// restore SL/RR
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j];
immWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
}
immWrite(0x08,(chan[i].opMask<<3)|i);
chan[i].opMaskChanged=false;
chan[i].keyOn=false;
}
}
}
}
void DivPlatformArcade::muteChannel(int ch, bool mute) {

View file

@ -483,7 +483,6 @@ void DivPlatformGenesis::tick(bool sysTick) {
mustHardReset=true;
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
oldWrites[baseAddr+ADDR_SL_RR]=-1;
immWrite(baseAddr+ADDR_SL_RR,0x0f);
hardResetElapsed++;
}
@ -552,6 +551,12 @@ void DivPlatformGenesis::tick(bool sysTick) {
if (i==2 && extMode) continue;
if ((chan[i].keyOn || chan[i].opMaskChanged) && chan[i].hardReset) {
if (i<6) {
// restore SL/RR
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j];
immWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
}
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
}
chan[i].opMaskChanged=false;

View file

@ -266,28 +266,6 @@ void DivPlatformTX81Z::tick(bool sysTick) {
rWrite(baseAddr+ADDR_DT2_D2R,(op.d2r&31)|(op.dt2<<6));
}
}
if (chan[i].keyOn || chan[i].keyOff) {
if (chan[i].hardReset && chan[i].keyOn) {
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
immWrite(baseAddr+ADDR_SL_RR,0x0f);
immWrite(baseAddr+ADDR_TL,0x7f);
oldWrites[baseAddr+ADDR_SL_RR]=-1;
oldWrites[baseAddr+ADDR_TL]=-1;
}
}
//if (chan[i].keyOn) immWrite(0x08,i);
immWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)|0x00|(chan[i].chVolR<<7));
if (chan[i].hardReset && chan[i].keyOn) {
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
for (int k=0; k<9; k++) {
immWrite(baseAddr+ADDR_SL_RR,0x0f);
}
}
}
chan[i].keyOff=false;
}
}
for (int i=0; i<256; i++) {
@ -309,6 +287,24 @@ void DivPlatformTX81Z::tick(bool sysTick) {
}
}
int hardResetElapsed=0;
bool mustHardReset=false;
for (int i=0; i<8; i++) {
if (chan[i].keyOn || chan[i].keyOff) {
immWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)|0x00|(chan[i].chVolR<<7));
if (chan[i].hardReset && chan[i].keyOn) {
mustHardReset=true;
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
immWrite(baseAddr+ADDR_SL_RR,0x0f);
hardResetElapsed++;
}
}
chan[i].keyOff=false;
}
}
for (int i=0; i<8; i++) {
if (chan[i].freqChanged) {
chan[i].freq=chan[i].baseFreq+(chan[i].pitch>>1)-64+chan[i].pitch2;
@ -323,14 +319,34 @@ void DivPlatformTX81Z::tick(bool sysTick) {
if (chan[i].freq>=(95<<6)) chan[i].freq=(95<<6)-1;
immWrite(i+0x28,hScale(chan[i].freq>>6));
immWrite(i+0x30,(chan[i].freq<<2)|(chan[i].chVolL==chan[i].chVolR));
hardResetElapsed+=2;
chan[i].freqChanged=false;
}
if (chan[i].keyOn) {
//immWrite(0x08,i);
if (chan[i].keyOn && !chan[i].hardReset) {
immWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)|0x40|(chan[i].chVolR<<7));
chan[i].keyOn=false;
}
}
// hard reset handling
if (mustHardReset) {
for (unsigned int i=hardResetElapsed; i<hardResetCycles; i++) {
immWrite(0x1f,i&0xff);
}
for (int i=0; i<8; i++) {
if (chan[i].keyOn && chan[i].hardReset) {
// restore SL/RR
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j];
immWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
}
immWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)|0x40|(chan[i].chVolR<<7));
chan[i].keyOn=false;
}
}
}
}
void DivPlatformTX81Z::muteChannel(int ch, bool mute) {

View file

@ -431,7 +431,6 @@ void DivPlatformYM2203::tick(bool sysTick) {
mustHardReset=true;
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
oldWrites[baseAddr+ADDR_SL_RR]=-1;
immWrite(baseAddr+ADDR_SL_RR,0x0f);
hardResetElapsed++;
}
@ -480,6 +479,13 @@ void DivPlatformYM2203::tick(bool sysTick) {
for (int i=0; i<3; i++) {
if (i==2 && extMode) continue;
if ((chan[i].keyOn || chan[i].opMaskChanged) && chan[i].hardReset) {
// restore SL/RR
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j];
immWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
}
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
chan[i].opMaskChanged=false;
chan[i].keyOn=false;

View file

@ -626,7 +626,6 @@ void DivPlatformYM2608::tick(bool sysTick) {
mustHardReset=true;
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
oldWrites[baseAddr+ADDR_SL_RR]=-1;
immWrite(baseAddr+ADDR_SL_RR,0x0f);
hardResetElapsed++;
}
@ -807,6 +806,13 @@ void DivPlatformYM2608::tick(bool sysTick) {
for (int i=0; i<6; i++) {
if (i==2 && extMode) continue;
if ((chan[i].keyOn || chan[i].opMaskChanged) && chan[i].hardReset) {
// restore SL/RR
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j];
immWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
}
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
chan[i].opMaskChanged=false;
chan[i].keyOn=false;

View file

@ -559,7 +559,6 @@ void DivPlatformYM2610::tick(bool sysTick) {
mustHardReset=true;
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
oldWrites[baseAddr+ADDR_SL_RR]=-1;
immWrite(baseAddr+ADDR_SL_RR,0x0f);
hardResetElapsed++;
}
@ -740,6 +739,13 @@ void DivPlatformYM2610::tick(bool sysTick) {
for (int i=0; i<psgChanOffs; i++) {
if (i==1 && extMode) continue;
if ((chan[i].keyOn || chan[i].opMaskChanged) && chan[i].hardReset) {
// restore SL/RR
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j];
immWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
}
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
chan[i].opMaskChanged=false;
chan[i].keyOn=false;

View file

@ -626,7 +626,6 @@ void DivPlatformYM2610B::tick(bool sysTick) {
mustHardReset=true;
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
oldWrites[baseAddr+ADDR_SL_RR]=-1;
immWrite(baseAddr+ADDR_SL_RR,0x0f);
hardResetElapsed++;
}
@ -807,6 +806,13 @@ void DivPlatformYM2610B::tick(bool sysTick) {
for (int i=0; i<psgChanOffs; i++) {
if (i==2 && extMode) continue;
if ((chan[i].keyOn || chan[i].opMaskChanged) && chan[i].hardReset) {
// restore SL/RR
for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j];
immWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
}
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
chan[i].opMaskChanged=false;
chan[i].keyOn=false;