Skip to content

Commit

Permalink
md: refactor sync between 32X components
Browse files Browse the repository at this point in the history
Hopefully we don't see any negative impact from this;
I have tested many known timing-sensitive games with no ill effects locally.
  • Loading branch information
LukeUsher committed Feb 6, 2025
1 parent 048d0e3 commit b372f65
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 29 deletions.
4 changes: 2 additions & 2 deletions ares/md/m32x/bus-external.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ auto M32X::writeExternal(n1 upper, n1 lower, n24 address, n16 data) -> void {
}

if(address >= 0x840000 && address <= 0x85ffff) {
if (vdp.framebufferAccess) return;
if(vdp.framebufferAccess) return;
if(!data && (!upper || !lower)) return; //8-bit 0x00 writes do not go through
shm.debugger.tracer.instruction->invalidate(0x0400'0000 | address & 0x1fffe);
shs.debugger.tracer.instruction->invalidate(0x0400'0000 | address & 0x1fffe);
Expand All @@ -50,7 +50,7 @@ auto M32X::writeExternal(n1 upper, n1 lower, n24 address, n16 data) -> void {
}

if(address >= 0x860000 && address <= 0x87ffff) {
if (vdp.framebufferAccess) return;
if(vdp.framebufferAccess) return;
shm.debugger.tracer.instruction->invalidate(0x0402'0000 | address & 0x1fffe);
shs.debugger.tracer.instruction->invalidate(0x0402'0000 | address & 0x1fffe);
if(upper && data.byte(1)) vdp.bbram[address >> 1 & 0xffff].byte(1) = data.byte(1);
Expand Down
4 changes: 2 additions & 2 deletions ares/md/m32x/bus-internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ auto M32X::readInternal(n1 upper, n1 lower, n32 address, n16 data) -> n16 {
if(address >= 0x0200'0000 && address <= 0x023f'ffff) {
while(dreq.vram) {
// SH2 ROM accesses stall while RV is set
if(shm.active()) shm.internalStep(1);
if(shs.active()) shs.internalStep(1);
if(shm.active()) { shm.internalStep(1); shm.syncM68k(true); }
if(shs.active()) { shs.internalStep(1); shs.syncM68k(true); }
}

// TODO: SH2 ROM accesses need to stall while the m68k is on the bus
Expand Down
2 changes: 2 additions & 0 deletions ares/md/m32x/io-internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ auto M32X::readInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> n16 {

//FIFO
if(address == 0x4012) {
if(shm.active()) { shm.syncM68k(); }
if(shs.active()) { shs.syncM68k(); }
data = dreq.fifo.read(data);
shm.dmac.dreq[0] = !dreq.fifo.empty();
shs.dmac.dreq[0] = !dreq.fifo.empty();
Expand Down
4 changes: 1 addition & 3 deletions ares/md/m32x/m32x.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct M32X {
auto power(bool reset) -> void;
auto restart() -> void;
auto syncOtherSh2() -> void;
auto syncM68k() -> void;
auto syncM68k(bool force = false) -> void;

auto busReadByte(u32 address) -> u32 override;
auto busReadWord(u32 address) -> u32 override;
Expand All @@ -70,10 +70,8 @@ struct M32X {

s32 cyclesUntilSh2Sync = 0;
s32 cyclesUntilM68kSync = 0;
s32 cyclesUntilFullSync = 0;
s32 minCyclesBetweenSh2Syncs = 0;
s32 minCyclesBetweenM68kSyncs = 0;
s32 minCyclesBetweenFullSyncs = 0;
};

struct VDP {
Expand Down
46 changes: 24 additions & 22 deletions ares/md/m32x/sh7604.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,28 @@ auto M32X::SH7604::internalStep(u32 clocks) -> void {
auto M32X::SH7604::step(u32 clocks) -> void {
SH2::frt.run(clocks);
SH2::wdt.run(clocks);

Thread::step(clocks);

cyclesUntilSh2Sync -= clocks;
cyclesUntilM68kSync -= clocks;
cyclesUntilFullSync -= clocks;

if(cyclesUntilFullSync <= 0) {
cyclesUntilFullSync = minCyclesBetweenFullSyncs;
if(m32x.shm.active()) Thread::synchronize(m32x.shs, cpu);
if(m32x.shs.active()) Thread::synchronize(m32x.shm, cpu);
if(cyclesUntilSh2Sync <= 0) {
cyclesUntilSh2Sync = minCyclesBetweenSh2Syncs;
if (m32x.shm.active()) Thread::synchronize(m32x.shs);
if (m32x.shs.active()) Thread::synchronize(m32x.shm);
}

if(cyclesUntilM68kSync <= 0) {
cyclesUntilM68kSync = minCyclesBetweenM68kSyncs;
Thread::synchronize(cpu);
}
}

auto M32X::SH7604::power(bool reset) -> void {
Thread::create((system.frequency() / 7.0) * 3.0, {&M32X::SH7604::main, this});
SH2::recompilerStepCycles = 20; // Minimum cycles for recompiler to run for each batch of instructions
minCyclesBetweenFullSyncs = 50; // Minimum cycles between full sync with the M68K/MD side
minCyclesBetweenSh2Syncs = 5; // Minimum Cycles between sync with the other SH2 (syncOtherSh2)
minCyclesBetweenM68kSyncs = 10; // Minimum Cycles between sync with the M68K (syncM68k)
SH2::recompilerStepCycles = 200; //Recompiler will force an exit after at least N cycles have passed
minCyclesBetweenSh2Syncs = 50; //Do not sync SH2s more than once every N cycles
minCyclesBetweenM68kSyncs = 100; //Do not sync M68K more than once every N cycles
SH2::power(reset);
irq = {};
irq.vres.enable = 1;
Expand All @@ -93,18 +96,17 @@ auto M32X::SH7604::restart() -> void {
}

auto M32X::SH7604::syncOtherSh2() -> void {
// avoid synchronizing if we recently have
if(cyclesUntilSh2Sync > 0) return;
if(m32x.shm.active()) Thread::synchronize(m32x.shs);
if(m32x.shs.active()) Thread::synchronize(m32x.shm);
cyclesUntilSh2Sync = minCyclesBetweenSh2Syncs;
}

auto M32X::SH7604::syncM68k() -> void {
// avoid synchronizing if we recently have
if(cyclesUntilM68kSync > 0) return;
Thread::synchronize(cpu);
cyclesUntilM68kSync = minCyclesBetweenM68kSyncs;
SH2::cyclesUntilRecompilerExit = 0;
}

auto M32X::SH7604::syncM68k(bool force) -> void {
SH2::cyclesUntilRecompilerExit = 0;

if(SH2::Accuracy::Recompiler && m32x.shm.recompiler.enabled && force) {
cyclesUntilM68kSync = 0;
step(regs.CCR);
regs.CCR = 0;
}
}

auto M32X::SH7604::busReadByte(u32 address) -> u32 {
Expand Down

0 comments on commit b372f65

Please sign in to comment.