diff --git a/core/cheats.cpp b/core/cheats.cpp index 77a20a9e6..45b427d85 100644 --- a/core/cheats.cpp +++ b/core/cheats.cpp @@ -481,6 +481,19 @@ void CheatManager::reset(const std::string& gameId) else if (gameId == "MKG TKOB 2 KOR VER1.000-") // mushik2k setMushikingCheats(0x706084); } + else if (gameId == "T-8120N") // Dave Mirra BMX (US) + { + setActive(true); + cheats.emplace_back(Cheat::Type::setValue, "fix main loop time", true, 32, 0x0030b8cc, 0x42040000); // 33.0 ms + cheats.back().builtIn = true; + } + else if (gameId == "T8120D 50") // Dave Mirra BMX (EU) + { + setActive(true); + cheats.emplace_back(Cheat::Type::setValue, "fix main loop time", true, 32, 0x003011cc, 0x42200000); // 40.0 ms + cheats.back().builtIn = true; + } + } if (config::WidescreenGameHacks) { diff --git a/core/hw/sh4/sh4_cycles.h b/core/hw/sh4/sh4_cycles.h index 46354980f..1d517c675 100644 --- a/core/hw/sh4/sh4_cycles.h +++ b/core/hw/sh4/sh4_cycles.h @@ -53,16 +53,48 @@ public: sh4_opcodelistentry *opcode = OpDesc[op]; int cycles = 0; #ifndef STRICT_MODE - if (opcode->ex_type == 2 || opcode->ex_type == 3 - || opcode->ex_type == 5 || opcode->ex_type == 6 || opcode->ex_type == 7 - // cache mgmt || opcode->ex_type == 10 || opcode->ex_type == 11 - || opcode->ex_type == 12 - || opcode->ex_type == 17 || opcode->ex_type == 18 || opcode->ex_type == 19 - || opcode->ex_type == 22 || opcode->ex_type == 23 || opcode->ex_type == 25 - || opcode->ex_type == 27 || opcode->ex_type == 29 || opcode->ex_type == 31 - || opcode->ex_type == 33 || opcode->ex_type == 35) + static const bool isMemOp[45] { + false, + false, + true, // all mem moves, ldtlb, sts.l FPUL/FPSCR, @-Rn, lds.l @Rn+,FPUL + true, // gbr-based load/store + false, + true, // tst.b #, @(R0,GBR) + true, // and/or/xor.b #, @(R0,GBR) + true, // tas.b @Rn + false, + false, + false, + false, + true, // movca.l R0, @Rn + false, + false, + false, + false, + true, // ldc.l @Rn+, VBR/SPC/SSR/Rn_Bank/DBR + true, // ldc.l @Rn+, GBR/SGR + true, // ldc.l @Rn+, SR + false, + false, + true, // stc.l DBR/SR/GBR/VBR/SSR/SPC/Rn_Bank, @-Rn + true, // stc.l SGR, @-Rn + false, + true, // lds.l @Rn+, PR + false, + true, // sts.l PR, @-Rn + false, + true, // lds.l @Rn+, MACH/MACL + false, + true, // sts.l MACH/MACL, @-Rn + false, + true, // lds.l @Rn+,FPSCR + false, + true, // mac.wl @Rm+,@Rn+ + }; + if (isMemOp[opcode->ex_type]) { - cycles = mmu_enabled() ? 5 : 2; + if (++memOps < 4) + cycles = mmu_enabled() ? 5 : 2; } // TODO only for mem read? #endif @@ -86,6 +118,7 @@ public: void reset() { lastUnit = CO; + memOps = 0; } static u64 now() { @@ -108,6 +141,7 @@ private: sh4_eu lastUnit = CO; const int cpuRatio; + int memOps = 0; }; extern Sh4Cycles sh4cycles;