From 6be75e414172d44859ad5b452268812fa2b7dba6 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 12 Jan 2026 19:08:34 -0500 Subject: [PATCH] OPN/A/B: fix SSG writes using YM2608-LLE core issue #2746 --- src/engine/platform/ym2203.cpp | 20 +++++++++++++++++++- src/engine/platform/ym2608.cpp | 2 ++ src/engine/platform/ym2610.cpp | 2 ++ src/engine/platform/ym2610b.cpp | 2 ++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index 1602c4485..86667129f 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -351,8 +351,10 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) { } ay->getRegisterWrites().clear(); + //logI("output"); + while (true) { - bool canWeWrite=fm_lle.prescaler_latch[1]&1; + bool canWeWrite=(fm_lle.prescaler_latch[1]&1); if (canWeWrite) { if (delay>0) { @@ -363,6 +365,8 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) { fm_lle.input.a0=0; fm_lle.input.a1=0; delay=0; + + //logV("idle - delay 3"); } else { fm_lle.input.cs=0; fm_lle.input.rd=0; @@ -371,6 +375,8 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) { fm_lle.input.a1=0; fm_lle.input.data=0; delay=1; + + //logV("waiting"); } } else if (!writes.empty()) { QueuedWrite& w=writes.front(); @@ -383,6 +389,8 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) { fm_lle.input.a0=0; fm_lle.input.data=0; + //logV("idle - PRESCALER WRITE"); + regPool[w.addr&0x1ff]=w.val; writes.pop_front(); } else if (w.addrOrVal) { @@ -393,7 +401,10 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) { fm_lle.input.a0=1; fm_lle.input.data=w.val; + //logV("fucking the value %.2x",w.val); + delay=2; + if (w.addr<0x10) delay=3; regPool[w.addr&0x1ff]=w.val; writes.pop_front(); @@ -405,7 +416,10 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) { fm_lle.input.a0=0; fm_lle.input.data=w.addr&0xff; + //logV("fucking the address %.2x",w.addr); + delay=2; + if (w.addr<0x10) delay=3; w.addrOrVal=true; } @@ -415,12 +429,15 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) { fm_lle.input.wr=1; fm_lle.input.a0=0; fm_lle.input.a1=0; + //logV("idle"); } } FMOPNA_Clock(&fm_lle,0); FMOPNA_Clock(&fm_lle,1); + //logV("CLOCK"); + if (++subSubCycle>=6) { subSubCycle=0; if (subCycle>=0 && subCycle<6 && fm_lle.ac_fm_output_en) { @@ -434,6 +451,7 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) { // check busy status here if (!fm_lle.busy_cnt_en[1]) { delay=0; + //logV("work done"); } } } diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 7a2d9b290..e48026e19 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -589,6 +589,7 @@ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) { fm_lle.input.data=w.val; delay=2; + if (w.addr<0x10) delay=3; regPool[w.addr&0x1ff]=w.val; writes.pop_front(); @@ -601,6 +602,7 @@ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) { fm_lle.input.data=w.addr&0xff; delay=2; + if (w.addr<0x10) delay=3; w.addrOrVal=true; } diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index cc3b70f66..d55b4c9eb 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -511,6 +511,7 @@ void DivPlatformYM2610::acquire_lle(short** buf, size_t len) { fm_lle.input.data=w.val; delay=2; + if (w.addr<0x10) delay=3; regPool[w.addr&0x1ff]=w.val; writes.pop_front(); @@ -523,6 +524,7 @@ void DivPlatformYM2610::acquire_lle(short** buf, size_t len) { fm_lle.input.data=w.addr&0xff; delay=2; + if (w.addr<0x10) delay=3; w.addrOrVal=true; } diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 12f75e1b9..3e1e74208 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -579,6 +579,7 @@ void DivPlatformYM2610B::acquire_lle(short** buf, size_t len) { fm_lle.input.data=w.val; delay=2; + if (w.addr<0x10) delay=3; regPool[w.addr&0x1ff]=w.val; writes.pop_front(); @@ -591,6 +592,7 @@ void DivPlatformYM2610B::acquire_lle(short** buf, size_t len) { fm_lle.input.data=w.addr&0xff; delay=2; + if (w.addr<0x10) delay=3; w.addrOrVal=true; }