diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index 332e4f3..e799858 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace n64 { Interpreter::Interpreter(Mem &mem, Registers ®s) : regs(regs), mem(mem) {} @@ -118,11 +119,18 @@ bool Interpreter::DetectIdleLoop(const std::array(load.rs()) + offset; + u32 paddr; + if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) + panic("Failed to translate load address in DetectIdleLoop"); - return (load.opcode() == Instruction::LW || load.opcode() == Instruction::LWU) && - delay.opcode() == Instruction::ANDI && branch.IsBranch() && branch.offset() == -8 && - load.rt() == delay.rs() && delay.rt() == branch.rs(); + return isLoad && delay.opcode() == Instruction::ANDI && branch.IsBranch() && branch.offset() == -8 && + load.rt() == delay.rs() && delay.rt() == branch.rs() && IsAddressMMIOorRDRAM(paddr); + } } if (len == 4) { @@ -132,12 +140,19 @@ bool Interpreter::DetectIdleLoop(const std::array(load.rs()) + offset; + bool isLoad = load.opcode() == Instruction::LW || load.opcode() == Instruction::LWU; + if (isLoad) { + u32 paddr; + if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) + panic("Failed to translate load address in DetectIdleLoop"); - return (load.opcode() == Instruction::LW || load.opcode() == Instruction::LWU) && - andi.opcode() == Instruction::ANDI && branch.IsBranch() && branch.offset() == -12 && - load.rt() == andi.rs() && andi.rt() == branch.rs(); + return isLoad && andi.opcode() == Instruction::ANDI && branch.IsBranch() && branch.offset() == -12 && + load.rt() == andi.rs() && andi.rt() == branch.rs() && IsAddressMMIOorRDRAM(paddr); + } } return false; diff --git a/src/backend/core/mem/Utils.hpp b/src/backend/core/mem/Utils.hpp new file mode 100644 index 0000000..c2775d8 --- /dev/null +++ b/src/backend/core/mem/Utils.hpp @@ -0,0 +1,17 @@ +#pragma once +#include +#include +#include + +namespace n64 { +static bool IsAddressMMIOorRDRAM(u32 addr) { + if (ircolib::IsInsideRange(addr, RDRAM_REGION_START, RDRAM_REGION_END)) + return true; + + if (ircolib::IsInsideRange(addr, MMIO_REGION_START_1, MMIO_REGION_END_1) || + ircolib::IsInsideRange(addr, MMIO_REGION_START_2, MMIO_REGION_END_2)) + return true; + + return false; +} +} // namespace n64 diff --git a/src/frontend/main.cpp b/src/frontend/main.cpp index 6583399..9b86568 100644 --- a/src/frontend/main.cpp +++ b/src/frontend/main.cpp @@ -2,16 +2,17 @@ #include int main(const int argc, char **argv) { - KaizenGui kaizenGui; - cflags::cflags flags; - flags.add_string_callback('\0', "rom", [&kaizenGui](const std::string& v) { kaizenGui.LoadROM(v); }, "Rom to launch from command-line"); - flags.add_string_callback('\0', "movie", [](const std::string& v) { KaizenGui::LoadTAS(v); }, "Mupen Movie to replay"); + KaizenGui kaizenGui; + cflags::cflags flags; + flags.add_string_callback( + '\0', "rom", [&kaizenGui](const std::string &v) { kaizenGui.LoadROM(v); }, "Rom to launch from command-line"); + flags.add_string_callback( + '\0', "movie", [](const std::string &v) { KaizenGui::LoadTAS(v); }, "Mupen Movie to replay"); - if(!flags.parse(argc, argv)) { - return -1; - } + if (!flags.parse(argc, argv)) + return -1; - kaizenGui.run(); + kaizenGui.run(); - return 0; + return 0; }