From 68a966f9bd8c2d365df454bb4e779fbf5e56eb69 Mon Sep 17 00:00:00 2001 From: wrapper Date: Sun, 29 Mar 2026 18:06:32 +0700 Subject: [PATCH] read code and halt --- bindings/python/dynemu/__init__.pyi | 4 ++++ src/lib/sys_emulator.cpp | 3 +++ src/pybind/dynemu.cpp | 10 ++++++++++ 3 files changed, 17 insertions(+) diff --git a/bindings/python/dynemu/__init__.pyi b/bindings/python/dynemu/__init__.pyi index 41d1274..9df14b3 100644 --- a/bindings/python/dynemu/__init__.pyi +++ b/bindings/python/dynemu/__init__.pyi @@ -18,6 +18,8 @@ class Dynemu: ARM7_ARM9: typing.ClassVar[Dynemu.DCCType] # value = def __init__(self, dcc_type: Dynemu.DCCType = DCCType.ARM7_ARM9, no_opts: bool = False, big_endian: bool = False) -> None: ... + def _read_code(self, vaddr: typing.SupportsInt | typing.SupportsIndex) -> int | None: + ... def dcc_read(self) -> int: ... def dcc_write(self, value: typing.SupportsInt | typing.SupportsIndex) -> None: @@ -26,6 +28,8 @@ class Dynemu: ... def get_reg(self, reg_num: typing.SupportsInt | typing.SupportsIndex) -> int: ... + def halt(self) -> None: + ... def memory_map(self, vaddr: typing.SupportsInt | typing.SupportsIndex, size: typing.SupportsInt | typing.SupportsIndex) -> None: ... @typing.overload diff --git a/src/lib/sys_emulator.cpp b/src/lib/sys_emulator.cpp index f00662a..f1b831d 100644 --- a/src/lib/sys_emulator.cpp +++ b/src/lib/sys_emulator.cpp @@ -419,6 +419,9 @@ namespace Dynemu { Dynarmic::HaltReason returnCode = cpu->Run(); cpu->ClearCache(); + if (returnCode == Dynarmic::HaltReason::MemoryAbort) + throw std::runtime_error("attempted to access outside memory bounds"); + return cpu->Regs()[0]; } diff --git a/src/pybind/dynemu.cpp b/src/pybind/dynemu.cpp index ed5243d..6442fea 100644 --- a/src/pybind/dynemu.cpp +++ b/src/pybind/dynemu.cpp @@ -72,6 +72,10 @@ struct Emu { return emu.env.MemoryRead64(vaddr); } + std::optional read_code(u32 vaddr) { + return emu.env.MemoryReadCode(vaddr); + } + void write_u8(u32 vaddr, u8 value) { emu.env.MemoryWrite8(vaddr, value); } @@ -109,6 +113,10 @@ struct Emu { return emu.env.Execute(pc, stub_mode); } + void halt() { + emu.env.cpu->HaltExecution(Dynarmic::HaltReason::Step); + } + u32 get_reg(u8 reg_num) { return emu.env.cpu->Regs()[reg_num]; } @@ -155,6 +163,7 @@ PYBIND11_MODULE(_dynemu, module, py::mod_gil_not_used()) { .def("read_u16", &Emu::read_u16, py::arg("vaddr")) .def("read_u32", &Emu::read_u32, py::arg("vaddr")) .def("read_u64", &Emu::read_u64, py::arg("vaddr")) + .def("_read_code", &Emu::read_code, py::arg("vaddr")) .def("write_u8", &Emu::write_u8, py::arg("vaddr"), py::arg("value")) .def("write_u16", &Emu::write_u16, py::arg("vaddr"), py::arg("value")) .def("write_u32", &Emu::write_u32, py::arg("vaddr"), py::arg("value")) @@ -163,6 +172,7 @@ PYBIND11_MODULE(_dynemu, module, py::mod_gil_not_used()) { .def("write_bytes", static_cast(&Emu::write_bytes), py::arg("vaddr"), py::arg("data")) .def("write_bytes", static_cast(&Emu::write_bytes), py::arg("vaddr"), py::arg("data")) .def("execute", &Emu::execute, py::arg("pc"), py::arg("stub_mode") = true) + .def("halt", &Emu::halt) .def("get_reg", &Emu::get_reg, py::arg("reg_num")) .def("set_reg", &Emu::set_reg, py::arg("reg_num"), py::arg("value")) .def("dcc_read", &Emu::dcc_read)