#include "mod_runtime.h" #include #include #include #include #include #include namespace fs = std::filesystem; static std::array ram; static int failures; extern "C" uint8_t psx_read_byte(uint32_t address) { return ram[address & 0x1fffffu]; } extern "C" void psx_write_byte(uint32_t address, uint8_t value) { ram[address & 0x1fffffu] = value; } extern "C" void dirty_ram_mark_executable_range(uint32_t, uint32_t) {} static void check(bool value, const char* message) { if (!value) { std::cerr << "FAIL: " << message << "\n"; failures++; } } static void write_text(const fs::path& path, const std::string& text) { fs::create_directories(path.parent_path()); std::ofstream out(path); out << text; } int main() { const fs::path root = fs::temp_directory_path() / "psxrecomp-mod-runtime-test"; std::error_code ec; fs::remove_all(root, ec); write_text(root / "packages/runtime.test/1.0.0/manifest.toml", "format_version = 1\n" "id = \"runtime.test\"\n" "version = \"1.0.0\"\n" "name = \"Runtime Test\"\n" "[[target]]\n" "game_id = \"SLUS-RUNTIME\"\n" "[[patch]]\n" "target = \"main_exe\"\n" "address = 2147487744\n" "expected = \"01020304\"\n" "replace = \"a1a2a3a4\"\n" "[[patch]]\n" "target = \"disc_raw\"\n" "offset = 4714\n" "expected = \"aa\"\n" "replace = \"bb\"\n"); write_text(root / "state.toml", "format_version = 1\n" "[[package]]\n" "id = \"runtime.test\"\n" "enabled = true\n" "version = \"1.0.0\"\n"); std::string error; check(PSXRecompV4::mod_runtime_initialize( root, "SLUS-RUNTIME", 0x80002000, {}, &error), error.c_str()); check(PSXRecompV4::mod_runtime_commit({}, &error), error.c_str()); ram[0x1000] = 1; ram[0x1001] = 2; ram[0x1002] = 3; ram[0x1003] = 4; mod_runtime_on_dispatch(0x80001000); check(ram[0x1000] == 1, "patch must wait for the configured entry point"); mod_runtime_on_dispatch(0x80002000); check(ram[0x1000] == 0xa1 && ram[0x1003] == 0xa4, "main-EXE patch must apply before entry execution"); std::array sector{}; sector[10] = 0xaa; mod_runtime_patch_disc_sector(2, 1, sector.data(), (uint32_t)sector.size()); check(sector[10] == 0xaa, "disc overlay must stay off during reference reads"); mod_runtime_enable_disc_patches(); mod_runtime_patch_disc_sector(2, 1, sector.data(), (uint32_t)sector.size()); check(sector[10] == 0xbb, "raw disc overlay must patch matching sectors"); fs::remove_all(root, ec); if (failures) return 1; std::cout << "mod runtime tests passed\n"; return 0; }