mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
60919f5a87
Bundled releases link OpenBIOS only; retail-BIOS-derived C never ships.
"Bring your own BIOS" now works without it: when a dump matching a shipped
profile (psx_bios_known_images.h) is selected, the runtime builds that
backend on the player's machine with the overlay toolchain the release
already carries, caches it, and loads it as one more registered backend.
- runtime/include/psx_bios_module.h: the module contract. An overlay-style
self-contained shared library (no imports from the executable) exporting
psx_bios_module_{abi,codegen_hash,init,backend}; reaches the runtime only
through OverlayCallbacks plus a new PsxBiosModuleCallbacks table (traps,
dirty-RAM/kernel-bless probes, fntrace, log_probe) and pointer aliases of
the globals the generated dispatcher touches. Its #defines rewrite the
emitter's own extern lines, so the generated C compiles unchanged.
- runtime/include/psx_bios_module_glue.c.inc: module-side forwarders and the
four exports, compiled after overlay_dispatch_preamble.c.inc.
- runtime/src/psx_bios_module.c: host side. Cache path
<exe>/cache/bios/<os-arch>/bm<abi>_<codegen hash>_f<flavor>/<STEM>_<crc>,
ABI + codegen-hash gated load, callback fill, and a blocking build via
overlay_toolchain/bios_module_build.py (gcc via compiler.txt or PATH,
else tcc), then psx_bios_register().
- psx_bios_backend.c: the registry is now a mutable table seeded from the
CMake-generated psx_bios_builtin_registry by a constructor, with
psx_bios_register(); every existing walker keeps working.
- main.cpp: validate_bios_for_launch acquires a module (announcing a first
build) before declaring a mismatch; discovery accepts a buildable dump;
the launcher verify reports it usable ("ready" / "compiled on first
launch") with no Generate & rebuild; the BIOS row shows whenever the
toolchain is present; bundled_only respects module support.
- emitter: the CPS-marker constructor is not emitted in a module build.
- overlay_api.h: OverlayCallbacks gains a struct tag;
overlay_loader_callbacks() exposes the host table before loader init.
- tools/bios_module_build.py (ships in the toolchain): identity + profile
SHA-256 gate, staged emitter tree, emit, three-TU compile, ctypes
self-check, atomic publish. release_stage.py stages psxrecomp-bios, every
bios/*.toml, the seeds and the builder into overlay_toolchain/.
- Tests: runtime/tests/test_bios_module_host.c against three fake modules
(good / wrong ABI / wrong hash) on real dlopen; recompiler/tests/
test_bios_module_build.py builds the bundled OpenBIOS end to end and reads
the descriptor back; guards extended.
Verified on Twisted Metal 4 (bundled build + staged toolchain, headless):
first launch with --bios SCPH1001.BIN builds and loads the module and boots
on image=SCPH-1001; the second launch loads it from cache.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
75 lines
2.5 KiB
C
75 lines
2.5 KiB
C
/* A fake BIOS module for test_bios_module_host.c: exports the four entry
|
|
* points psx_bios_module.h requires, with a descriptor whose identity the
|
|
* test can assert, and records what init was handed. Built as a shared
|
|
* library by runtime/CMakeLists.txt; never shipped.
|
|
*
|
|
* Which ABI/hash it reports is chosen at compile time so the same source
|
|
* builds the good module and the two bad ones the host must reject. */
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include "cpu_state.h"
|
|
#include "overlay_api.h"
|
|
#include "psx_bios_backend.h"
|
|
#include "psx_bios_module.h"
|
|
|
|
#ifndef FAKE_ABI_TAG
|
|
#define FAKE_ABI_TAG PSX_BIOS_MODULE_ABI_TAG
|
|
#endif
|
|
#ifndef FAKE_CODEGEN_HASH
|
|
#define FAKE_CODEGEN_HASH PSX_OVERLAY_CODEGEN_HASH
|
|
#endif
|
|
|
|
#if defined(_WIN32)
|
|
# define FAKE_EXPORT __declspec(dllexport)
|
|
#else
|
|
# define FAKE_EXPORT __attribute__((visibility("default")))
|
|
#endif
|
|
|
|
static int s_dispatch_calls;
|
|
static void fake_dispatch(struct CPUState *cpu, uint32_t addr) {
|
|
(void)cpu; (void)addr;
|
|
s_dispatch_calls++;
|
|
}
|
|
static void fake_dispatch_call(struct CPUState *cpu, uint32_t addr, uint32_t ra) {
|
|
(void)cpu; (void)addr; (void)ra;
|
|
s_dispatch_calls++;
|
|
}
|
|
|
|
static const PsxBiosImageInfo s_image = {
|
|
0, 0, 0,
|
|
0, 0,
|
|
524288u, 0xDEADBEEFu, 0u,
|
|
"0000000000000000000000000000000000000000000000000000000000000000",
|
|
"FAKE-0001",
|
|
0,
|
|
};
|
|
|
|
static const PsxBiosBackend s_backend = {
|
|
&s_image, fake_dispatch, fake_dispatch_call, 0, 0, 0, 0,
|
|
};
|
|
|
|
/* What init received, for the test to inspect through psx_bios_module_fake_probe. */
|
|
static uint32_t s_init_bcbs_size;
|
|
static int s_init_ok;
|
|
static int *s_seen_depth;
|
|
|
|
FAKE_EXPORT int psx_bios_module_abi(void) { return FAKE_ABI_TAG; }
|
|
FAKE_EXPORT uint32_t psx_bios_module_codegen_hash(void) { return (uint32_t)FAKE_CODEGEN_HASH; }
|
|
FAKE_EXPORT int psx_bios_module_init(const OverlayCallbacks *cbs,
|
|
const PsxBiosModuleCallbacks *bcbs) {
|
|
if (!cbs || !bcbs || bcbs->size < sizeof(PsxBiosModuleCallbacks)) return 0;
|
|
s_init_bcbs_size = bcbs->size;
|
|
s_seen_depth = bcbs->dispatch_depth;
|
|
s_init_ok = 1;
|
|
return 1;
|
|
}
|
|
FAKE_EXPORT const PsxBiosBackend *psx_bios_module_backend(void) { return &s_backend; }
|
|
|
|
/* Test-only probe: 1 if init ran with a full table and the depth pointer
|
|
* aliases the host's (the host passes &g_psx_dispatch_depth). */
|
|
FAKE_EXPORT int psx_bios_module_fake_probe(int *host_depth) {
|
|
return s_init_ok && s_init_bcbs_size == sizeof(PsxBiosModuleCallbacks) &&
|
|
s_seen_depth == host_depth;
|
|
}
|