diff --git a/src/engine/platform/fmshared_OPN.h b/src/engine/platform/fmshared_OPN.h index b1aa07b32..672e89fd9 100644 --- a/src/engine/platform/fmshared_OPN.h +++ b/src/engine/platform/fmshared_OPN.h @@ -165,6 +165,7 @@ class DivPlatformOPN: public DivPlatformFMBase { double fmFreqBase; unsigned int fmDivBase; unsigned int ayDiv; + int tfxRate; unsigned char csmChan; unsigned char lfoValue; unsigned char lastExtChPan; diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index 86667129f..aba149081 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -175,8 +175,8 @@ void DivPlatformYM2203::acquire_combo(short** buf, size_t len) { for (size_t h=0; h OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; @@ -269,8 +269,8 @@ void DivPlatformYM2203::acquire_ymfm(short** buf, size_t len) { for (size_t h=0; h OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; @@ -342,8 +342,8 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) { } // AY -> OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; @@ -1446,6 +1446,17 @@ void DivPlatformYM2203::setFlags(const DivConfig& flags) { } else { rate=fm->sample_rate(chipClock); } + switch (ayDiv) { + case 4: + tfxRate=rate/2; + break; + case 8: + tfxRate=rate; + break; + default: + tfxRate=rate*2; + break; + } for (int i=0; i<7; i++) { oscBuf[i]->setRate(rate); } diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index e48026e19..ddc393199 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -326,8 +326,8 @@ void DivPlatformYM2608::acquire_combo(short** buf, size_t len) { for (size_t h=0; h OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; @@ -453,8 +453,8 @@ void DivPlatformYM2608::acquire_ymfm(short** buf, size_t len) { for (size_t h=0; h OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; @@ -533,8 +533,8 @@ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) { unsigned char subSubCycle=0; // AY -> OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; @@ -2038,6 +2038,17 @@ void DivPlatformYM2608::setFlags(const DivConfig& flags) { } else { rate=fm->sample_rate(chipClock); } + switch (ayDiv) { + case 8: + tfxRate=rate; + break; + case 16: + tfxRate=rate*2; + break; + default: + tfxRate=rate*4; + break; + } for (int i=0; i<17; i++) { oscBuf[i]->setRate(rate); } diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index d55b4c9eb..71cfb92fc 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -262,8 +262,8 @@ void DivPlatformYM2610::acquire_combo(short** buf, size_t len) { for (size_t h=0; h OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; @@ -287,8 +287,8 @@ void DivPlatformYM2610::acquire_combo(short** buf, size_t len) { fm->write(0x1+((w.addr>>8)<<1),w.val); regPool[w.addr&0x1ff]=w.val; + delay=(w.addr>15)?32:1; writes.pop_front(); - delay=32; } else { // Nuked write if (w.addrOrVal) { @@ -387,8 +387,8 @@ void DivPlatformYM2610::acquire_ymfm(short** buf, size_t len) { for (size_t h=0; h OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; @@ -397,8 +397,11 @@ void DivPlatformYM2610::acquire_ymfm(short** buf, size_t len) { ay->getRegisterWrites().clear(); os[0]=0; os[1]=0; - if (!writes.empty()) { - if (--delay<1 && !(fm->read(0)&0x80)) { + while (!writes.empty()) { + if (!(fm->read(0)&0x80)) { + delay=0; + } + if (delay<1) { QueuedWrite& w=writes.front(); if (w.addr==0xfffffffe) { delay=w.val*2; @@ -406,10 +409,11 @@ void DivPlatformYM2610::acquire_ymfm(short** buf, size_t len) { fm->write(0x0+((w.addr>>8)<<1),w.addr); fm->write(0x1+((w.addr>>8)<<1),w.val); regPool[w.addr&0x1ff]=w.val; - delay=1; + if (w.addr>15) delay=1; } writes.pop_front(); } + if (delay>0) break; } fm->generate(&fmout); @@ -466,8 +470,8 @@ void DivPlatformYM2610::acquire_lle(short** buf, size_t len) { unsigned char subSubCycle=0; // AY -> OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 3e1e74208..52ad0692f 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -326,8 +326,8 @@ void DivPlatformYM2610B::acquire_combo(short** buf, size_t len) { for (size_t h=0; h OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; @@ -351,8 +351,8 @@ void DivPlatformYM2610B::acquire_combo(short** buf, size_t len) { fm->write(0x1+((w.addr>>8)<<1),w.val); regPool[w.addr&0x1ff]=w.val; + delay=(w.addr>15)?32:1; writes.pop_front(); - delay=32; } else { // Nuked write if (w.addrOrVal) { @@ -453,8 +453,8 @@ void DivPlatformYM2610B::acquire_ymfm(short** buf, size_t len) { for (size_t h=0; h OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; @@ -463,8 +463,11 @@ void DivPlatformYM2610B::acquire_ymfm(short** buf, size_t len) { ay->getRegisterWrites().clear(); os[0]=0; os[1]=0; - if (!writes.empty()) { - if (--delay<1 && !(fm->read(0)&0x80)) { + while (!writes.empty()) { + if (!(fm->read(0)&0x80)) { + delay=0; + } + if (delay<1) { QueuedWrite& w=writes.front(); if (w.addr==0xfffffffe) { delay=w.val*2; @@ -472,10 +475,11 @@ void DivPlatformYM2610B::acquire_ymfm(short** buf, size_t len) { fm->write(0x0+((w.addr>>8)<<1),w.addr); fm->write(0x1+((w.addr>>8)<<1),w.val); regPool[w.addr&0x1ff]=w.val; - delay=1; + if (w.addr>15) delay=1; } writes.pop_front(); } + if (delay>0) break; } fm->generate(&fmout); @@ -534,8 +538,8 @@ void DivPlatformYM2610B::acquire_lle(short** buf, size_t len) { unsigned char subSubCycle=0; // AY -> OPN - ay->runDAC(); - ay->runTFX(rate); + ay->runDAC(tfxRate); + ay->runTFX(tfxRate); ay->flushWrites(); for (DivRegWrite& i: ay->getRegisterWrites()) { if (i.addr>15) continue; diff --git a/src/engine/platform/ym2610shared.h b/src/engine/platform/ym2610shared.h index d3add1723..dbea16c44 100644 --- a/src/engine/platform/ym2610shared.h +++ b/src/engine/platform/ym2610shared.h @@ -319,6 +319,7 @@ class DivPlatformYM2610Base: public DivPlatformOPN { } else { rate=fm->sample_rate(chipClock); } + tfxRate=rate*4; for (int i=0; i<17; i++) { oscBuf[i]->setRate(rate); }