YM2612: new experimental hard reset strategy

This commit is contained in:
tildearrow 2023-01-19 14:36:15 -05:00
parent 231b5c3694
commit 48a1e6a976
2 changed files with 33 additions and 15 deletions

View file

@ -83,6 +83,7 @@ class DivPlatformFMBase: public DivDispatch {
unsigned char lastBusy; unsigned char lastBusy;
int delay; int delay;
unsigned int hardResetCycles;
bool flushFirst; bool flushFirst;
unsigned char regPool[512]; unsigned char regPool[512];
@ -123,6 +124,7 @@ class DivPlatformFMBase: public DivDispatch {
DivDispatch(), DivDispatch(),
lastBusy(0), lastBusy(0),
delay(0), delay(0),
hardResetCycles(0),
flushFirst(false) {} flushFirst(false) {}
}; };

View file

@ -472,26 +472,20 @@ void DivPlatformGenesis::tick(bool sysTick) {
} }
} }
int hardResetElapsed=0;
bool mustHardReset=false;
for (int i=0; i<6; i++) { for (int i=0; i<6; i++) {
if (i==2 && extMode) continue; if (i==2 && extMode) continue;
if (chan[i].keyOn || chan[i].keyOff) { 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;
//rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
}
}
immWrite(0x28,0x00|konOffs[i]); immWrite(0x28,0x00|konOffs[i]);
if (chan[i].hardReset && chan[i].keyOn) { if (chan[i].hardReset && chan[i].keyOn) {
mustHardReset=true;
for (int j=0; j<4; j++) { for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j]; unsigned short baseAddr=chanOffs[i]|opOffs[j];
for (int k=0; k<5; k++) { oldWrites[baseAddr+ADDR_SL_RR]=-1;
immWrite(baseAddr+ADDR_SL_RR,0x0f); immWrite(baseAddr+ADDR_SL_RR,0x0f);
} hardResetElapsed++;
} }
} }
chan[i].keyOff=false; chan[i].keyOff=false;
@ -520,6 +514,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
if (i<6) { if (i<6) {
immWrite(chanOffs[i]+ADDR_FREQH,chan[i].freq>>8); immWrite(chanOffs[i]+ADDR_FREQH,chan[i].freq>>8);
immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff); immWrite(chanOffs[i]+ADDR_FREQ,chan[i].freq&0xff);
hardResetElapsed+=2;
} }
if (chan[i].furnaceDac && chan[i].dacMode) { if (chan[i].furnaceDac && chan[i].dacMode) {
double off=1.0; double off=1.0;
@ -538,12 +533,31 @@ void DivPlatformGenesis::tick(bool sysTick) {
} }
chan[i].freqChanged=false; chan[i].freqChanged=false;
} }
if (chan[i].keyOn || chan[i].opMaskChanged) { if ((chan[i].keyOn || chan[i].opMaskChanged) && !chan[i].hardReset) {
if (i<6) immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]); if (i<6) {
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
hardResetElapsed++;
}
chan[i].opMaskChanged=false; chan[i].opMaskChanged=false;
chan[i].keyOn=false; chan[i].keyOn=false;
} }
} }
// hard reset handling
if (mustHardReset) {
for (unsigned int i=hardResetElapsed; i<hardResetCycles; i++) {
immWrite(0xf0,i&0xff);
}
for (int i=0; i<csmChan; i++) {
if ((chan[i].keyOn || chan[i].opMaskChanged) && chan[i].hardReset) {
if (i<6) {
immWrite(0x28,(chan[i].opMask<<4)|konOffs[i]);
}
chan[i].opMaskChanged=false;
chan[i].keyOn=false;
}
}
}
} }
void DivPlatformGenesis::muteChannel(int ch, bool mute) { void DivPlatformGenesis::muteChannel(int ch, bool mute) {
@ -1306,6 +1320,8 @@ void DivPlatformGenesis::setFlags(const DivConfig& flags) {
} else { } else {
rate=chipClock/36; rate=chipClock/36;
} }
// 2ms
hardResetCycles=(chipClock/144)/500;
for (int i=0; i<10; i++) { for (int i=0; i<10; i++) {
oscBuf[i]->rate=rate; oscBuf[i]->rate=rate;
} }