From 4c679f1a7adb2f62c64cf680f6ca0f751f150952 Mon Sep 17 00:00:00 2001 From: Matthew Stanley <1379tech@gmail.com> Date: Tue, 27 Oct 2026 08:26:29 -0700 Subject: [PATCH] Repair shared mod fixture linkage and validate the combined bridge --- docs/MMX6_MODERN_SDK_BRIDGE.md | 9 +++++++++ runtime/CMakeLists.txt | 5 ++++- runtime/tests/test_mod_netplay.c | 1 + runtime/tests/test_mod_resident.cpp | 1 - runtime/tests/test_netplay_view_mods.cpp | 15 +++++++++++++++ runtime/tests/test_pgxp_session.cpp | 18 ++++++++++++------ 6 files changed, 41 insertions(+), 8 deletions(-) diff --git a/docs/MMX6_MODERN_SDK_BRIDGE.md b/docs/MMX6_MODERN_SDK_BRIDGE.md index eb9512bd..708dfd19 100644 --- a/docs/MMX6_MODERN_SDK_BRIDGE.md +++ b/docs/MMX6_MODERN_SDK_BRIDGE.md @@ -11,6 +11,15 @@ callbacks use the same explicit ownership restoration. The original validation below is historical evidence; combined source/build/game qualification is tracked in `beads-9zi2` and optimization campaign `beads-fobc`. +The combined GCC15.2 build now passes all18 targeted runtime cases, including +the ordinary scheduler-escape fixture, missing-profile/image checks, loader +negotiation, modern settings profiles, own-view isolation, resident loading and +both PGXP compilation flavors. Replacement codegen, compiled-overlay ABI35 +forwarding and interpreted-entry guard checks also pass. Fixture-only duplicate +definitions/missing link inputs were repaired, and netplay assertions stay active +in Release. This supersedes the historical fixture failures below for this +combined source; built-game and two-peer qualification remain separate. + This branch bridges X6's native replacement and negotiated loading services to modern SDK `6f0ccbc6b67fee626de6a7b0945ca3abb26332aa`. It is a local integration candidate, not a qualified game repin. No games or memory cards were launched. diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 5dd56c23..775e3075 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -987,6 +987,8 @@ if(BUILD_TESTING) # Run the same session fixture in both real compilation flavors. foreach(_pgxp_session_test IN ITEMS pgxp_session_test pgxp_session_hooks_test) add_executable(${_pgxp_session_test} tests/test_pgxp_session.cpp + src/mod_immediate.c src/func_override.c + src/host_overlay.c src/host_span_ring.c src/pgxp_session.cpp src/mod_builtin_pgxp.c src/pgxp.cpp src/psx_ram_geometry.c src/mod_runtime.cpp src/mod_function_replacements.c @@ -1526,6 +1528,7 @@ if(BUILD_TESTING) add_test(NAME resident_sector_test COMMAND resident_sector_test) add_executable(netplay_view_mods_test tests/test_netplay_view_mods.cpp + src/mod_immediate.c src/func_override.c src/host_overlay.c src/iso_reader_c.cpp src/host_span_ring.c src/mod_runtime.cpp src/mod_function_replacements.c @@ -2464,7 +2467,7 @@ endif() # Fixtures compiling the real mod runtime also need its read-only installer. if(BUILD_TESTING) - foreach(fixture pgxp_session_test mod_runtime_test netplay_view_mods_test mod_runtime_cache_test mod_resident_test) + foreach(fixture pgxp_session_test pgxp_session_hooks_test mod_runtime_test netplay_view_mods_test mod_runtime_cache_test mod_resident_test) target_sources(${fixture} PRIVATE src/texture_pack_install.cpp src/duckstation_texture_pack.cpp tests/texture_install_stb.cpp) target_link_libraries(${fixture} PRIVATE psx_texture_image_decode Threads::Threads) endforeach() diff --git a/runtime/tests/test_mod_netplay.c b/runtime/tests/test_mod_netplay.c index abe2119d..4014c179 100644 --- a/runtime/tests/test_mod_netplay.c +++ b/runtime/tests/test_mod_netplay.c @@ -1,6 +1,7 @@ #include "mod_netplay.h" #include "netplay_state_digest.h" #include "crc32.h" +#undef NDEBUG #include #include #include diff --git a/runtime/tests/test_mod_resident.cpp b/runtime/tests/test_mod_resident.cpp index 6bca5d54..5bc21694 100644 --- a/runtime/tests/test_mod_resident.cpp +++ b/runtime/tests/test_mod_resident.cpp @@ -56,7 +56,6 @@ extern "C" int gpu_hd_textures_reload(char*, size_t) { return 1; } extern "C" void psx_projection_reset_session(void) {} extern "C" void gpu_ws_set_native_scene_predicate(int (*)(void)) {} extern "C" int psx_ws_x_margin(void) { return 0; } -extern "C" int psx_netplay_active(void) { return 0; } extern "C" void spu_set_pcm_overlay(PSXModPCMCallback) {} extern "C" void gpu_get_display_info(GpuDisplayInfo* out) { *out = GpuDisplayInfo{}; } extern "C" void dirty_ram_mark_executable_range(uint32_t, uint32_t) {} diff --git a/runtime/tests/test_netplay_view_mods.cpp b/runtime/tests/test_netplay_view_mods.cpp index 0fc16d71..25a08602 100644 --- a/runtime/tests/test_netplay_view_mods.cpp +++ b/runtime/tests/test_netplay_view_mods.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -61,12 +62,26 @@ int memcard_is_present(int) { return 0; } int memcard_read_sector(int, int, uint8_t* buf) { std::memset(buf, 0, 128); return -1; } int memcard_write_sector(int, int, const uint8_t*) { return -1; } void memcard_flush(int) {} +int memcard_last_flush_result(int) { return -1; } /* No cards in this fixture. */ +uint64_t psx_cycle_count=0, psx_next_service_cycle=0; +int psx_in_device_service=0, g_event_step_conservative=0, g_ls_replay_active=0; +uint32_t g_psx_cyc_batch=0, g_psx_cyc_batch_limit=0; +void psx_devices_service_to_now(void) { std::abort(); } +void psx_advance_cycles_slow(uint32_t) { std::abort(); } +void psx_dispatch_call(CPUState*, uint32_t, uint32_t) { std::abort(); } +void spu_set_pcm_overlay(PSXModPCMCallback callback) { if (callback) std::abort(); } } /* The guest bus: main RAM, plus the real SIO (sio.c) at 0x1F801040..5F, so * a bus read of SIO_DATA / SIO_STAT has its hardware side effects here too. * Every MMIO bus access is counted. */ static int mmio_bus_accesses; +extern "C" uint32_t psx_peek_word_untraced(uint32_t address) { + if ((address & 0x1FFFFFFFu) >= ram.size() || (address & 3u)) std::abort(); + uint32_t value; + std::memcpy(&value,ram.data()+(address & 0x1FFFFFFFu),sizeof value); + return value; +} static bool is_sio(uint32_t a) { a &= 0x1fffffffu; return a >= 0x1F801040u && a < 0x1F801060u; diff --git a/runtime/tests/test_pgxp_session.cpp b/runtime/tests/test_pgxp_session.cpp index 80ca03ac..4681b589 100644 --- a/runtime/tests/test_pgxp_session.cpp +++ b/runtime/tests/test_pgxp_session.cpp @@ -128,6 +128,18 @@ extern "C" void psx_write_word(uint32_t a, uint32_t v) { extern "C" void psx_host_write_byte(uint32_t a, uint8_t v) { psx_write_byte(a, v); } extern "C" void psx_host_write_half(uint32_t a, uint16_t v) { psx_write_half(a, v); } extern "C" void psx_host_write_word(uint32_t a, uint32_t v) { psx_write_word(a, v); } +/* This fixture installs presentation policy; it never dispatches guest code, + * credits guest cycles, or installs an audio callback. Fail on accidental use. */ +extern "C" uint32_t psx_peek_word_untraced(uint32_t a) { return psx_read_word(a); } +extern "C" { +uint64_t psx_cycle_count=0, psx_next_service_cycle=0; +int psx_in_device_service=0, g_event_step_conservative=0, g_ls_replay_active=0; +uint32_t g_psx_cyc_batch=0, g_psx_cyc_batch_limit=0; +void psx_devices_service_to_now(void) { std::abort(); } +void psx_advance_cycles_slow(uint32_t) { std::abort(); } +} +extern "C" void psx_dispatch_call(CPUState*, uint32_t, uint32_t) { std::abort(); } +extern "C" void spu_set_pcm_overlay(PSXModPCMCallback callback) { if (callback) std::abort(); } extern "C" uint32_t psx_mod_memory_alloc(uint32_t, uint32_t) { return 0; } extern "C" uint32_t psx_mod_gpu_dma_memory_alloc(uint32_t, uint32_t) { return 0; } extern "C" int psx_ws_x_margin(void) { return 0; } @@ -143,12 +155,6 @@ extern "C" void gpu_ws_set_adaptive_backdrop_preload(int) {} extern "C" void psx_projection_reset_session(void) {} extern "C" void gpu_ws_set_native_scene_predicate(int (*)(void)) {} extern "C" int gpu_ws_configured_x_reveal(void) { return 0; } -extern "C" int psx_netplay_active(void) { return 0; } -extern "C" void gpu_hd_textures_shutdown(void) {} -extern "C" int gpu_hd_textures_configure(const char*, int, int, char*, size_t) { return 1; } -extern "C" void gpu_hd_textures_set_dump_enabled(int) {} -extern "C" void gpu_hd_textures_get_diag(GpuHdTextureDiag* out) { *out = {}; } -extern "C" int gpu_hd_textures_reload(char*, size_t) { return 1; } extern "C" void gpu_ws_set_manual_view_anchor(int, int) {} extern "C" void gpu_ws_tag_hud_prim(uint32_t, int) {} extern "C" void gpu_ws_tag_screen_mask_quad(uint32_t) {}