mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-27 10:38:46 -04:00
fe42da2744
Keeps both lines: master's PGXP session, draw-distance clamps, masked rejects and saturated-winding NCLIP; the release's render-pass kit additions, verified media/disc extents, timeline/present rings, cull-scale sites. Overlay ABI v30. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
153 lines
7.5 KiB
TOML
153 lines
7.5 KiB
TOML
# bios/OpenBIOS.toml — BIOS build profile for PCSX-Redux OpenBIOS.
|
|
#
|
|
# OpenBIOS is the PCSX-Redux project's from-scratch, MIT-licensed PS1 BIOS
|
|
# (https://github.com/grumpycoders/pcsx-redux, src/mips/openbios). MIT means
|
|
# the image is REDISTRIBUTABLE: a game verified against it ships its BIOS
|
|
# with the build and the player supplies only a disc (redistributable=true
|
|
# below removes the whole BIOS-selection surface at runtime).
|
|
#
|
|
# Pinned build (bios/openbios.bin + the ELFs the seeds derive from):
|
|
# pcsx-redux 55fbf0468345acfbe5512628a3be5c0cfe3f22e7
|
|
# uC-sdk 69e06871824e2d62069487a7426ded09090ceb69
|
|
# toolchain g++-mipsel-none-elf (GCC 16.1.0, static.grumpycoder.net build)
|
|
# build make -C src/mips/openbios PREFIX=mipsel-none-elf FORMAT=elf32-littlemips
|
|
# Regenerating seeds after a re-pin (--extra is REQUIRED to keep the 5
|
|
# empirically-discovered dispatch-miss seeds; without it they are silently
|
|
# dropped and the regenerated set has 641 entries, not 646):
|
|
# tools/gen_bios_seeds_from_elf.py --profile bios/OpenBIOS.toml \
|
|
# --elf .../openbios.elf --elf .../shell.elf \
|
|
# --extra recompiler/seeds/openbios_dispatch_miss.json \
|
|
# --out recompiler/seeds/openbios_elf_seeds.json
|
|
#
|
|
# The address model below was established by direct disassembly of the boot
|
|
# path (reset vector -> copy loops), each copy confirmed twice (boot + the
|
|
# warm-restart path reloading lengths from ROM constants; the shell length
|
|
# additionally confirmed by the blob's own self-relocation constants).
|
|
|
|
[program]
|
|
name = "PCSX-Redux OpenBIOS"
|
|
id = "OPENBIOS"
|
|
rom = "bios/openbios.bin"
|
|
load_address = "0xBFC00000"
|
|
entry_pc = "0xBFC00000"
|
|
text_size = "0x80000"
|
|
|
|
[program.image]
|
|
sha256 = "fabe498fbf224e4721f12f31b6f5fe0659205e341dc4e5c5f91b9bd1a1011c57"
|
|
license = "MIT"
|
|
redistributable = true
|
|
|
|
[recompiler]
|
|
seeds = "recompiler/seeds/openbios_elf_seeds.json"
|
|
out_dir = "generated"
|
|
out_stem = "OpenBIOS"
|
|
strict = true
|
|
|
|
# OpenBIOS's boot-time bulk code copies. Windows are BYTE-PROVEN against
|
|
# openbios.elf (readelf -lW program headers give the .data LMA; the embedded
|
|
# shell blob was located by content search; both ranges memcmp-verified
|
|
# ELF-content == image-content — an earlier hand-disassembly of the copy
|
|
# routines mis-read both source offsets by 0xB8/0x2C0-class deltas, which
|
|
# emitted every shell/ramtext function from shifted bytes):
|
|
# - kernel .data (VMA 0x500, WAX — code+data): LMA 0xBFC1E4D4, FileSiz
|
|
# 0x46A0, copied to RAM 0x500 at boot. Byte-verbatim -> kernel_bless.
|
|
# - shell blob (objcopy of shell.elf, linked at 0x80030000): embedded in
|
|
# .rodata at ROM 0xA500, size 0x13D44, copied to RAM 0x80030000. The
|
|
# first-crash a1=0xBFC1E244 was exactly this blob's END pointer mid-copy.
|
|
# NOT modeled, by design:
|
|
# - the 4x16-byte vector stubs copied to RAM 0x80/0xA0/0xB0/0xC0
|
|
# (runtime-written trampolines -> dirty-RAM interp territory, rule 18);
|
|
# - the RAM->RAM A0-table move (0x4844 -> 0x200): nothing dispatches TO the
|
|
# table, discovery gets entries from ELF symbols, and runtime dispatch
|
|
# keys on the actual jump targets.
|
|
[recompiler.address_model]
|
|
normalize_mask = "0x1FFFFFFF"
|
|
|
|
[[recompiler.address_model.copy]]
|
|
name = "Kernel ramtext"
|
|
rom_lo = "0x1FC1E4D4"
|
|
rom_hi = "0x1FC22B74"
|
|
ram_lo = "0x00000500"
|
|
runtime_base = "0x00000500"
|
|
dispatch_key = "ram"
|
|
kernel_bless = true
|
|
|
|
[[recompiler.address_model.copy]]
|
|
name = "Shell"
|
|
rom_lo = "0x1FC0A500"
|
|
rom_hi = "0x1FC1E244"
|
|
ram_lo = "0x00030000"
|
|
runtime_base = "0x80030000"
|
|
dispatch_key = "rom"
|
|
kernel_bless = false
|
|
|
|
# Kernel-RAM RANGES the guest's Psy-Q libapi patchers overwrite at runtime
|
|
# (CLAUDE.md rule 18; docs/dynamic_handler_install.md). See SCPH1001.toml for
|
|
# what `len` and `resume` mean. OpenBIOS declared none until 2026-09-11; the
|
|
# consequence was that its exception handler failed the kernel-bless memcmp
|
|
# from the first card access onward and interpreted for the life of the
|
|
# process — 1.22 billion instructions in one measured title.
|
|
#
|
|
# Measured on a live boot of Breath of Fire III (SLPS-00990, Psy-Q SDK 3.70)
|
|
# against the ROM source, 30 s in. The shapes are the same three the retail
|
|
# image shows, because the patchers are the game's, not the BIOS's.
|
|
|
|
[[recompiler.install_slots]]
|
|
ram_addr = "0x000027B4" # exceptionHandler: register-save prologue
|
|
len = "0x30" # shifted two words + an inserted mfc0 v0,Cause
|
|
resume = "fallthrough"
|
|
|
|
[[recompiler.install_slots]]
|
|
ram_addr = "0x0000281C" # stub into exceptionHandlerCardFastTrack
|
|
len = "0x10" # lui/addiu/jalr/nop over ROM zeros; installed
|
|
resume = "jalr" # on the first card access, not at boot
|
|
|
|
[[recompiler.install_slots]]
|
|
ram_addr = "0x0000357C" # exceptionHandlerCardFastTrack: the kernel's
|
|
len = "0x10" # card handler replaced by jr into boot EXE
|
|
resume = "none" # 0x8017EAA0 (_patch_card payload)
|
|
|
|
# NOT declared: the three pad-table words after readPadHighLevel (0x45FC,
|
|
# 0x460C, 0x461C). They are data, not instructions, so they unbless nothing
|
|
# and a range there would only widen what the verifier stops checking.
|
|
|
|
# HLE anchors: only the boot-skip anchor is exported. deliver_event_ret is
|
|
# deliberately ABSENT (0) until the B0 event services are validated against
|
|
# this kernel's EvCB behavior (they are believed compatible — OpenBIOS
|
|
# reimplements the documented kernel ABI, EvCB anchor 0x120/0x124, TCB
|
|
# 0x108/0x110 — but believed is not verified). Absent = the kernel-call HLE
|
|
# tier is STRUCTURALLY UNAVAILABLE here and config/env cannot force it on.
|
|
#
|
|
# That refusal is scoped to kernel calls ONLY. The boot-skip is a separate axis
|
|
# gated on shell_entry_phys alone and works under pure LLE, so `bios_hle` (and
|
|
# the deprecated `fast_boot` alias) skips the boot animation and goes straight
|
|
# to the game on THIS image exactly as it does on retail SCPH-1001 — the flag
|
|
# means one thing on every BIOS. Both axes are decided in one pure place,
|
|
# psx_bios_hle_plan() (runtime/include/bios_hle_plan.h), which exists because
|
|
# deriving the boot-skip from the anchor-gated call tier silently took the skip
|
|
# away on this image (fixed 2026-07-27).
|
|
#
|
|
# shell_entry_phys was verified against the generated C (2026-07-23):
|
|
# - startShell (ELF symbol, ROM 0xBFC074DC) ends `lui $t9,0x8003; jr $t9`
|
|
# (0xBFC07534/38) — a TAIL jump to the RAM shell copy at 0x80030000
|
|
# that goes through the dispatch trampoline, where the hook fires on
|
|
# the pre-normalize phys 0x00030000;
|
|
# - $ra at that point is the jal link 0xBFC06EA8 (startShell restores its
|
|
# stack before the tail jump), so the intercept's resume-at-$ra lands
|
|
# exactly at the shell call's continuation;
|
|
# - that continuation OVERWRITES $v0 immediately (addiu $v0,$zero,8 — a
|
|
# boot-progress POST byte), so the intercept's v0=0 is never observed,
|
|
# and the boot proceeds unconditionally to the SYSTEM.CNF/EXE load
|
|
# (gameMainThunk), exactly the retail LoadRunShell contract the skip
|
|
# models. The shell's own animation (waitVSync/flip/convexHull in
|
|
# shell.elf) is the only thing skipped.
|
|
[recompiler.runtime_exports]
|
|
shell_entry_phys = "0x00030000"
|
|
|
|
# No [runtime] block: a BIOS profile states facts about an image, never runtime
|
|
# preferences, and load_bios_config rejects one outright. This file used to end
|
|
# with `[runtime] bios_hle = false`, which nothing read — the recompiler parsed
|
|
# it into a field with no consumers. Runtime options live in game.toml /
|
|
# settings.toml; per-image HLE capability is expressed by which anchors
|
|
# [recompiler.runtime_exports] above does and does not export.
|