Skip to content

Commit

Permalink
md: 32x performance tuning
Browse files Browse the repository at this point in the history
  • Loading branch information
LukeUsher committed Oct 18, 2023
1 parent 7b433f3 commit 0661e98
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 16 deletions.
2 changes: 1 addition & 1 deletion ares/component/processor/sh2/exceptions.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
auto SH2::exceptionHandler() -> void {
if(!exceptions) return;
if(inDelaySlot()) { cyclesUntilSync = 0; return; }
if(inDelaySlot()) { cyclesUntilRecompilerExit = 0; return; }

if(exceptions & ResetCold) {
exceptions &= ~ResetCold;
Expand Down
5 changes: 4 additions & 1 deletion ares/component/processor/sh2/instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ auto SH2::instruction() -> void {
do {
auto block = recompiler.block(PC - 4);
block->execute(*this);
} while (CCR < cyclesUntilSync);
} while (CCR < cyclesUntilRecompilerExit);

// Reset the count as it may have been set to 0 for an early exit
cyclesUntilRecompilerExit = recompilerStepCycles;

step(CCR);
CCR = 0;
Expand Down
2 changes: 1 addition & 1 deletion ares/component/processor/sh2/sh2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ auto SH2::power(bool reset) -> void {
ET = 0;
ID = 0;
exceptions = !reset ? ResetCold : ResetWarm;
cyclesUntilSync = 0;
cyclesUntilRecompilerExit = 0;

cache = {*this};
intc = {*this};
Expand Down
4 changes: 2 additions & 2 deletions ares/component/processor/sh2/sh2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ struct SH2 {
};
u32 exceptions = 0; //delayed exception flags

s32 cyclesUntilSync = 0;
s32 minCyclesBetweenSyncs = 0;
s32 cyclesUntilRecompilerExit = 0;
s32 recompilerStepCycles = 0;

struct Recompiler : recompiler::generic {
SH2& self;
Expand Down
6 changes: 3 additions & 3 deletions ares/component/processor/sh2/sh7604/bus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ template<u32 Origin> auto SH2::writeByte(u32 address, u32 data) -> void {
}

case Area::Uncached: {
cyclesUntilSync = 0;
cyclesUntilRecompilerExit = 0;
return busWriteByte(address & 0x1fff'ffff, data);
}

Expand Down Expand Up @@ -186,7 +186,7 @@ template<u32 Origin> auto SH2::writeWord(u32 address, u32 data) -> void {
}

case Area::Uncached: {
cyclesUntilSync = 0;
cyclesUntilRecompilerExit = 0;
return busWriteWord(address & 0x1fff'fffe, data);
}

Expand Down Expand Up @@ -232,7 +232,7 @@ template<u32 Origin> auto SH2::writeLong(u32 address, u32 data) -> void {
}

case Area::Uncached: {
cyclesUntilSync = 0;
cyclesUntilRecompilerExit = 0;
return busWriteLong(address & 0x1fff'fffc, data);
}

Expand Down
2 changes: 1 addition & 1 deletion ares/component/processor/sh2/sh7604/interrupts.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
auto SH2::INTC::run() -> void {
if(self->inDelaySlot()) { self->cyclesUntilSync = 0; return; }
if(self->inDelaySlot()) { self->cyclesUntilRecompilerExit = 0; return; }

if(self->frt.pendingOutputIRQ) {
if(self->SR.I < iprb.frtip) {
Expand Down
4 changes: 4 additions & 0 deletions ares/md/m32x/io-internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ auto M32X::readInternalIO(n1 upper, n1 lower, n29 address, n16 data) -> n16 {
//hcount
if(address == 0x4004) {
data.byte(0) = io.hperiod;
if(shm.active()) shm.syncOtherSh2();
if(shs.active()) shs.syncOtherSh2();
}

//dreq control register
Expand Down Expand Up @@ -67,6 +69,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();
if(shs.active()) shs.syncOtherSh2();
}

//PWM control
Expand Down
6 changes: 6 additions & 0 deletions ares/md/m32x/m32x.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct M32X {
auto step(u32 clocks) -> void override;
auto power(bool reset) -> void;
auto restart() -> void;
auto syncOtherSh2() -> void;

auto busReadByte(u32 address) -> u32 override;
auto busReadWord(u32 address) -> u32 override;
Expand All @@ -62,6 +63,11 @@ struct M32X {
Source vint; //12
Source vres; //14
} irq;

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

struct VDP {
Expand Down
24 changes: 17 additions & 7 deletions ares/md/m32x/sh7604.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ auto M32X::SH7604::unload() -> void {
}

auto M32X::SH7604::main() -> void {
if(!m32x.io.adapterReset) return step(cyclesUntilSync);
if(!m32x.io.adapterReset) return step(1000);

if(!regs.ID) {
#define raise(type, level, vector, ...) \
if(SH2::inDelaySlot()) cyclesUntilSync = 0; \
if(SH2::inDelaySlot()) SH2::cyclesUntilRecompilerExit = 0; \
else { \
debugger.interrupt(type); \
__VA_ARGS__; \
Expand Down Expand Up @@ -56,31 +56,41 @@ auto M32X::SH7604::step(u32 clocks) -> void {
}

Thread::step(clocks);
cyclesUntilSync -= clocks;
cyclesUntilSh2Sync -= clocks;
cyclesUntilFullSync -= clocks;

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

auto M32X::SH7604::power(bool reset) -> void {
Thread::create(23'000'000, {&M32X::SH7604::main, this});
minCyclesBetweenSyncs = 20;
SH2::recompilerStepCycles = 20; // Minimum cycles for recompiler to run for each batch of instructions
minCyclesBetweenFullSyncs = 200; // Minimum cycles between full sync with the M68K/MD side
minCyclesBetweenSh2Syncs = 10; // Minimum Cycles between sync with the other SH2 (syncOtherSh2)
SH2::power(reset);
irq = {};
irq.vres.enable = 1;
}

auto M32X::SH7604::restart() -> void {
minCyclesBetweenSyncs = 20;
SH2::power(true);
irq = {};
irq.vres.enable = 1;
Thread::restart({&M32X::SH7604::main, this});
}

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::busReadByte(u32 address) -> u32 {
if(address & 1) {
return m32x.readInternal(0, 1, address & ~1).byte(0);
Expand Down

0 comments on commit 0661e98

Please sign in to comment.