Files
psxrecomp/overlay_toolchain/bios/OpenBIOS.toml
T
Matthew Stanley fe42da2744 Merge release/native-rendering-20261003 into master
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>
2026-10-04 19:27:02 -07:00

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.