YM2612: add an "urgent" flag to queued writes

to let DAC writes through during delay (due to hard reset) and avoid clicks
issue #2475

ymfm and LLE implementations currently missing
This commit is contained in:
tildearrow 2025-06-17 19:57:16 -05:00
parent 3cbc69aa56
commit b1f824c3bf
2 changed files with 31 additions and 24 deletions

View file

@ -79,8 +79,10 @@ class DivPlatformFMBase: public DivDispatch {
unsigned int addr;
unsigned short val;
bool addrOrVal;
QueuedWrite(): addr(0), val(0), addrOrVal(false) {}
QueuedWrite(unsigned int a, unsigned char v): addr(a), val(v), addrOrVal(false) {}
bool urgent;
QueuedWrite(): addr(0), val(0), addrOrVal(false), urgent(false) {}
QueuedWrite(unsigned int a, unsigned char v): addr(a), val(v), addrOrVal(false), urgent(false) {}
QueuedWrite(unsigned int a, unsigned char v, bool u): addr(a), val(v), addrOrVal(false), urgent(u) {}
};
FixedQueue<QueuedWrite,2048> writes;
@ -108,14 +110,7 @@ class DivPlatformFMBase: public DivDispatch {
// only used by OPN2 for DAC writes
inline void urgentWrite(unsigned short a, unsigned char v) {
if (!skipRegisterWrites && !flushFirst) {
if (!writes.empty()) {
// check for hard reset
if (writes.front().addr==0xf0) {
// replace hard reset with DAC write
writes.pop_front();
}
}
writes.push_front(QueuedWrite(a,v));
writes.push_front(QueuedWrite(a,v,true));
if (dumpWrites) {
addWrite(a,v);
}

View file

@ -150,17 +150,34 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
os[0]=0; os[1]=0;
for (int i=0; i<6; i++) {
if (delay<=0 && !writes.empty()) {
if (!writes.empty()) {
QueuedWrite& w=writes.front();
if (w.addr==0xfffffffe) {
delay=w.val*3;
writes.pop_front();
} else if (w.addrOrVal) {
//logV("%.3x=%.2x",w.addr,w.val);
OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val);
regPool[w.addr&0x1ff]=w.val;
writes.pop_front();
if (delay<=0 || w.urgent) {
if (w.addr==0xfffffffe) {
delay=w.val*3;
writes.pop_front();
} else if (w.addrOrVal) {
//logV("%.3x=%.2x",w.addr,w.val);
OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val);
regPool[w.addr&0x1ff]=w.val;
writes.pop_front();
if (dacWrite>=0) {
if (!canWriteDAC) {
canWriteDAC=true;
} else {
urgentWrite(0x2a,dacWrite);
dacWrite=-1;
canWriteDAC=writes.empty();
}
}
} else {
if (fm.write_busy==0) {
OPN2_Write(&fm,0x0+((w.addr>>8)<<1),w.addr);
w.addrOrVal=true;
}
}
} else {
if (dacWrite>=0) {
if (!canWriteDAC) {
canWriteDAC=true;
@ -170,11 +187,6 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
canWriteDAC=writes.empty();
}
}
} else {
if (fm.write_busy==0) {
OPN2_Write(&fm,0x0+((w.addr>>8)<<1),w.addr);
w.addrOrVal=true;
}
}
} else {
canWriteDAC=true;