From 7f625b6348d24fd9abfad883e1b4207e6ae32029 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Fri, 7 Feb 2025 11:51:48 +0000 Subject: [PATCH] md: more 32X PEN=0 stalls; cleaner multi-device sync --- ares/md/m32x/bus-internal.cpp | 6 +++--- ares/md/m32x/io-external.cpp | 6 +++--- ares/md/m32x/io-internal.cpp | 22 ++++++++++++++-------- ares/md/m32x/m32x.hpp | 3 ++- ares/md/m32x/sh7604.cpp | 19 ++++++++++++++++++- 5 files changed, 40 insertions(+), 16 deletions(-) diff --git a/ares/md/m32x/bus-internal.cpp b/ares/md/m32x/bus-internal.cpp index f83bc4c16..c0683fac0 100644 --- a/ares/md/m32x/bus-internal.cpp +++ b/ares/md/m32x/bus-internal.cpp @@ -22,7 +22,7 @@ auto M32X::readInternal(n1 upper, n1 lower, n32 address, n16 data) -> n16 { } if(address >= 0x0400'0000 && address <= 0x05ff'ffff) { - if (!vdp.framebufferAccess) return data; + if(!vdp.framebufferAccess) return data; if(vdp.framebufferEngaged()) { debug(unusual, "[32X FB] SH2 read while FEN==1"); return data; } // wait instead? if(shm.active()) shm.internalStep(5); if(shs.active()) shs.internalStep(5); return vdp.bbram[address >> 1 & 0xffff]; @@ -44,7 +44,7 @@ auto M32X::writeInternal(n1 upper, n1 lower, n32 address, n16 data) -> void { address &= 0x0403'ffff; if(address >= 0x0400'0000 && address <= 0x0401'ffff) { - if (!vdp.framebufferAccess) return; + if(!vdp.framebufferAccess) return; if(vdp.framebufferEngaged()) { debug(unusual, "[32X FB] SH2 write while FEN==1"); return; } // wait instead? if(!data && (!upper || !lower)) return; //8-bit 0x00 writes do not go through if(shm.active()) shm.internalStep(4); if(shs.active()) shs.internalStep(4); @@ -54,7 +54,7 @@ auto M32X::writeInternal(n1 upper, n1 lower, n32 address, n16 data) -> void { } if(address >= 0x0402'0000 && address <= 0x0403'ffff) { - if (!vdp.framebufferAccess) return; + if(!vdp.framebufferAccess) return; if(vdp.framebufferEngaged()) { debug(unusual, "[32X FB] SH2 overwrite while FEN==1"); return; } // wait instead? if(shm.active()) shm.internalStep(4); if(shs.active()) shs.internalStep(4); if(upper && data.byte(1)) vdp.bbram[address >> 1 & 0xffff].byte(1) = data.byte(1); diff --git a/ares/md/m32x/io-external.cpp b/ares/md/m32x/io-external.cpp index 1ea7fa776..04ce7de55 100644 --- a/ares/md/m32x/io-external.cpp +++ b/ares/md/m32x/io-external.cpp @@ -149,9 +149,9 @@ auto M32X::readExternalIO(n1 upper, n1 lower, n24 address, n16 data) -> n16 { //palette if(address >= 0xa15200 && address <= 0xa153ff) { - if (vdp.framebufferAccess) return data; - while(vdp.paletteEngaged()) - if(cpu.active()) cpu.wait(1);; + if(vdp.framebufferAccess) return data; + while(vdp.paletteEngaged()) { + if(cpu.active()) cpu.wait(1); } data = vdp.cram[address >> 1 & 0xff]; } diff --git a/ares/md/m32x/io-internal.cpp b/ares/md/m32x/io-internal.cpp index 6c9eee35e..57d535570 100644 --- a/ares/md/m32x/io-internal.cpp +++ b/ares/md/m32x/io-internal.cpp @@ -73,8 +73,8 @@ auto M32X::readInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> n16 { //communication if(address >= 0x4020 && address <= 0x402f) { data = communication[address >> 1 & 7]; - if(shm.active()) { shm.syncOtherSh2(); shm.syncM68k(); } - if(shs.active()) { shs.syncOtherSh2(); shs.syncM68k(); } + if(shm.active()) { shm.syncAll(); } + if(shs.active()) { shs.syncAll(); } } //PWM control @@ -155,8 +155,11 @@ auto M32X::readInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> n16 { //palette if(address >= 0x4200 && address <= 0x43ff) { - if (!vdp.framebufferAccess) return data; - if(vdp.paletteEngaged()) { debug(unusual, "[32X CRAM] SH2 read while PEN==0"); return data; } // wait instead? + if(!vdp.framebufferAccess) return data; + while(vdp.paletteEngaged()) { + if(shm.active()) { shm.internalStep(1); shm.syncAll(); } + if(shs.active()) { shs.internalStep(1); shs.syncAll(); } + } if(shm.active()) shm.internalStep(4); if(shs.active()) shs.internalStep(4); data = vdp.cram[address >> 1 & 0xff]; } @@ -233,8 +236,8 @@ auto M32X::writeInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> void { //communication if(address >= 0x4020 && address <= 0x402f) { - if(shm.active()) { shm.syncOtherSh2(); shm.syncM68k(); } - if(shs.active()) { shs.syncOtherSh2(); shs.syncM68k(); } + if(shm.active()) { shm.syncAll(); } + if(shs.active()) { shs.syncAll(); } if(upper) communication[address >> 1 & 7].byte(1) = data.byte(1); if(lower) communication[address >> 1 & 7].byte(0) = data.byte(0); } @@ -342,8 +345,11 @@ auto M32X::writeInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> void { //palette if(address >= 0x4200 && address <= 0x43ff) { - if (!vdp.framebufferAccess) return; - if(vdp.paletteEngaged()) { debug(unusual, "[32X CRAM] SH2 write while PEN==0"); return; } // wait instead? + if(!vdp.framebufferAccess) return; + while(vdp.paletteEngaged()) { + if(shm.active()) { shm.internalStep(1); shm.syncAll(); } + if(shs.active()) { shs.internalStep(1); shs.syncAll(); } + } if(shm.active()) shm.internalStep(4); if(shs.active()) shs.internalStep(4); if(upper) vdp.cram[address >> 1 & 0xff].byte(1) = data.byte(1); if(lower) vdp.cram[address >> 1 & 0xff].byte(0) = data.byte(0); diff --git a/ares/md/m32x/m32x.hpp b/ares/md/m32x/m32x.hpp index 3040761bc..311432997 100644 --- a/ares/md/m32x/m32x.hpp +++ b/ares/md/m32x/m32x.hpp @@ -43,7 +43,8 @@ struct M32X { auto internalStep(u32 clocks) -> void; auto power(bool reset) -> void; auto restart() -> void; - auto syncOtherSh2() -> void; + auto syncAll(bool force = false) -> void; + auto syncOtherSh2(bool force = false) -> void; auto syncM68k(bool force = false) -> void; auto busReadByte(u32 address) -> u32 override; diff --git a/ares/md/m32x/sh7604.cpp b/ares/md/m32x/sh7604.cpp index 58980326f..8cb084d75 100644 --- a/ares/md/m32x/sh7604.cpp +++ b/ares/md/m32x/sh7604.cpp @@ -102,8 +102,25 @@ auto M32X::SH7604::restart() -> void { Thread::restart({&M32X::SH7604::main, this}); } -auto M32X::SH7604::syncOtherSh2() -> void { +auto M32X::SH7604::syncAll(bool force) -> void { SH2::cyclesUntilRecompilerExit = 0; + + if(SH2::Accuracy::Recompiler && m32x.shm.recompiler.enabled && force) { + cyclesUntilSh2Sync = 0; + cyclesUntilM68kSync = 0; + step(regs.CCR); + regs.CCR = 0; + } +} + +auto M32X::SH7604::syncOtherSh2(bool force) -> void { + SH2::cyclesUntilRecompilerExit = 0; + + if(SH2::Accuracy::Recompiler && m32x.shm.recompiler.enabled && force) { + cyclesUntilSh2Sync = 0; + step(regs.CCR); + regs.CCR = 0; + } } auto M32X::SH7604::syncM68k(bool force) -> void {