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

View file

@ -150,8 +150,9 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
os[0]=0; os[1]=0; os[0]=0; os[1]=0;
for (int i=0; i<6; i++) { for (int i=0; i<6; i++) {
if (delay<=0 && !writes.empty()) { if (!writes.empty()) {
QueuedWrite& w=writes.front(); QueuedWrite& w=writes.front();
if (delay<=0 || w.urgent) {
if (w.addr==0xfffffffe) { if (w.addr==0xfffffffe) {
delay=w.val*3; delay=w.val*3;
writes.pop_front(); writes.pop_front();
@ -176,6 +177,17 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
w.addrOrVal=true; w.addrOrVal=true;
} }
} }
} else {
if (dacWrite>=0) {
if (!canWriteDAC) {
canWriteDAC=true;
} else {
urgentWrite(0x2a,dacWrite);
dacWrite=-1;
canWriteDAC=writes.empty();
}
}
}
} else { } else {
canWriteDAC=true; canWriteDAC=true;
if (dacWrite>=0) { if (dacWrite>=0) {