feat(bios): ship OpenBIOS as a runtime dependency

This commit is contained in:
Matthew Stanley
2026-07-25 18:11:57 -07:00
parent a162aa7fb1
commit 4bf868da4f
9 changed files with 145 additions and 70 deletions
+19 -16
View File
@@ -286,16 +286,18 @@ release from the [Games](#games) table.
3. It boots on the bundled OpenBIOS. To use your own dump instead, pick it in
settings.
The package includes OpenBIOS but no retail PS1 BIOS, game disc image, generated
game code, or save data. If you choose your own BIOS, that path is remembered
next to the executable as `bios.cfg`; clear the choice (or delete that file) to
go back to OpenBIOS.
The package includes `bios/openbios.bin` and its MIT notice at
`bios/OpenBIOS.LICENSE`, but no retail PS1 BIOS, game disc image, generated game
code, or save data. If you choose your own BIOS, that path is remembered next
to the executable as `bios.cfg`; clear the choice (or delete that file) to go
back to OpenBIOS.
The game recomp projects use the same runtime picker contract but ship a
**Dear ImGui launcher**: on first run it prompts for your legally obtained BIOS
and game disc image, then lets you configure video, controls, and per-game
settings before launching. Keyboard/controller mappings live in each game's repo
and launcher, not here.
**Dear ImGui launcher**: on first run it asks for the game disc image and uses
OpenBIOS automatically. The optional BIOS row lets you select your own verified
retail dump or clear that choice to return to OpenBIOS. The launcher also
configures video, controls, and per-game settings. Keyboard/controller mappings
live in each game's repo and launcher, not here.
## Setup
@@ -322,7 +324,7 @@ Build the framework (recompiler tool + BIOS-only runtime):
git clone --recurse-submodules https://github.com/mstan/psxrecomp.git && cd psxrecomp
cmake -S recompiler -B recompiler/build -G Ninja -DCMAKE_BUILD_TYPE=Release && cmake --build recompiler/build
cmake -S runtime -B runtime/build -G Ninja -DCMAKE_BUILD_TYPE=Release && cmake --build runtime/build --target psx-runtime
cmake -S runtime -B runtime/build -G Ninja -DCMAKE_BUILD_TYPE=Release -DPSX_RECOMP_UI=OFF && cmake --build runtime/build --target psx-runtime
```
On Windows swap `-G Ninja` for your generator if you prefer (e.g.
@@ -425,13 +427,14 @@ discussion happens in the **R.A.I.D.** Discord (invite below).
PolyForm Noncommercial 1.0.0. See `LICENSE`.
The PSX BIOS and game disc images remain copyrighted by their respective
owners. This project distributes no BIOS images, no disc images, and no
game assets — those are always supplied by the user from their own
collection. Release executables (and per-game overlay caches) contain
statically recompiled (machine-translated) builds of the original code,
the same distribution model used by other static recompilation projects
such as N64: Recompiled.
Retail PS1 BIOS images and game disc images remain copyrighted by their
respective owners and are not distributed. This project does distribute the
from-scratch, MIT-licensed OpenBIOS image under the notice in
[`bios/OpenBIOS.LICENSE`](bios/OpenBIOS.LICENSE). Game assets and disc data are
always supplied by the user from their own collection. Release executables (and
per-game overlay caches) contain statically recompiled (machine-translated)
builds of the original code, the same distribution model used by other static
recompilation projects such as N64: Recompiled.
---
+11 -9
View File
@@ -1,17 +1,19 @@
# PSXRecomp v0.1.0-alpha
# PSXRecomp OpenBIOS integration
Initial public BIOS-only framework release package.
OpenBIOS is now a first-class, redistributable runtime backend.
Highlights:
- Packages the PSXRecomp v4 BIOS runtime as `PSXRecomp.exe`.
- Prompts for a user-provided `SCPH1001.BIN` BIOS on first launch.
- Saves the selected BIOS path in `bios.cfg` next to the executable.
- Bundles PCSX-Redux OpenBIOS and its MIT notice.
- Uses OpenBIOS when the player has not explicitly selected another BIOS.
- Keeps a verified, user-provided `SCPH1001.BIN` as an optional runtime choice.
- Lets launcher users clear a retail selection and return to OpenBIOS.
- Prevents savestates created under one BIOS from loading under the other.
- Adds Xbox-style controller support through SDL/XInput.
- Adds configurable controller mapping via `input.ini`.
- Includes the recent Tomba-driven renderer/runtime fixes for the BIOS logo,
menu text seams, dialog/pause panel seams, terrain shading, and shaded
textured primitives.
- Includes the load-delay ownership fix validated in Tomba!, plus OpenBIOS
smoke coverage in Ape Escape, Tomba! 2, and Mega Man X6.
This package does not include a PS1 BIOS, game disc image, generated game code,
save data, or copyrighted Sony/game assets.
This package does not include a retail PS1 BIOS, game disc image, generated game
code, save data, or copyrighted Sony/game assets.
+3 -4
View File
@@ -1,6 +1,6 @@
# Third-Party Attribution
## OpenBIOS — PCSX-Redux's free PS1 BIOS (optional recompilation target)
## OpenBIOS — PCSX-Redux's free PS1 BIOS
[OpenBIOS](https://github.com/grumpycoders/pcsx-redux) (src/mips/openbios) by
the PCSX-Redux authors, licensed **MIT** (notice: `bios/OpenBIOS.LICENSE`;
@@ -9,9 +9,8 @@ the binary also links permissively-licensed code from
as the prebuilt image `bios/openbios.bin` (pin and build recipe recorded in
`bios/OpenBIOS.toml`) and statically recompiled by
`psxrecomp-bios --config bios/OpenBIOS.toml` exactly like the retail BIOS.
Because MIT permits redistribution, a game verified against OpenBIOS can ship
it with the build (`[program.image] redistributable = true`) so players supply
only a disc; `bios/OpenBIOS.LICENSE` must ride along with the shipped image.
Normal runtime builds stage it automatically so players supply only a disc;
`bios/OpenBIOS.LICENSE` always rides alongside the shipped image.
## sljit — stack-less JIT compiler (Tier-2 in-process overlay backend)
+8 -2
View File
@@ -6,8 +6,10 @@ allowed to redistribute — so a player can be handed a build and a disc image a
just play. A player who prefers their own dumped retail BIOS can use that
instead.
Both BIOSes are compiled into every build. Which one runs is decided when the
game launches, not when it is built.
Both recompiled BIOS backends are linked into every normal build. The OpenBIOS
image itself and its MIT notice are staged in `bios/` beside the executable;
the retail image is never shipped and comes from the player. Which backend runs
is decided when the game launches, not when it is built.
## The rule
@@ -110,5 +112,9 @@ with the upstream source pin and build recipe in `bios/OpenBIOS.toml` and
attribution in `THIRD_PARTY_ATTRIBUTION.md`. Builds that ship it credit the
PCSX-Redux authors in the launcher, whether or not the licence compels it.
Native runtime builds automatically stage both `bios/openbios.bin` and
`bios/OpenBIOS.LICENSE`. Release packaging must copy that directory as a unit;
shipping the image without its notice violates the distribution contract.
Retail BIOS images are **not** redistributable and are never shipped. A player
using one supplies their own dump.
+25 -23
View File
@@ -10,7 +10,7 @@ Silicon & Intel), and **Linux**. There are two things you can build:
For the retail **`SCPH1001.BIN` BIOS** you supply your own dump; the
MIT-licensed **OpenBIOS** alternative is bundled (`bios/openbios.bin`, see
[Selecting the BIOS to recompile](#selecting-the-bios-to-recompile)). For a
[Regenerating BIOS backends](#regenerating-bios-backends)). For a
game you always supply your own legally-obtained **disc image** — this
project ships no game data.
@@ -77,14 +77,15 @@ Two CMake trees: the recompiler (a tool) and the runtime (the engine).
cmake -S recompiler -B recompiler/build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build recompiler/build
# 2. (Optional) regenerate the BIOS C from your SCPH1001.BIN
# Requires bios/SCPH1001.BIN to be present. To target the bundled
# OpenBIOS instead: --config bios/OpenBIOS.toml (see "Selecting the
# BIOS to recompile" below).
bash tools/regen_bios.sh
# 2. (Optional) regenerate either statically recompiled BIOS backend.
# OpenBIOS can always be regenerated from the tracked image. Regenerating
# the retail backend requires your own bios/SCPH1001.BIN dump.
bash tools/regen_bios.sh --config bios/OpenBIOS.toml
bash tools/regen_bios.sh --config bios/SCPH1001.toml
# 3. Runtime → produces psx-runtime (BIOS-only for this repo)
cmake -S runtime -B runtime/build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake -S runtime -B runtime/build -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DPSX_RECOMP_UI=OFF
cmake --build runtime/build --target psx-runtime
```
@@ -197,28 +198,29 @@ pack beside the repo at `../sdl2-msvc/SDL2-*`. Use the MSYS2/MinGW toolchain
for the `gcc` tier; otherwise areas stay in the interpreter. See
[`EXECUTION_MODEL.md`](EXECUTION_MODEL.md).
## Selecting the BIOS to recompile
## Regenerating BIOS backends
The runtime links exactly one statically recompiled BIOS (generated symbols
collide across images), chosen at configure time:
Every normal runtime links both statically recompiled BIOS backends. OpenBIOS
symbols and retail SCPH-1001 symbols are namespaced so they coexist in one
executable; the active backend is selected at launch:
```bash
# Retail SCPH1001 (default; user supplies the dump at first launch)
tools/regen_bios.sh # == --config bios/SCPH1001.toml
cmake -B build ... # PSXRECOMP_BIOS_STEM defaults to SCPH1001
# OpenBIOS (redistributable; ships with the game, player supplies only a disc)
# OpenBIOS (tracked and redistributable)
tools/regen_bios.sh --config bios/OpenBIOS.toml
cmake -B build -DPSXRECOMP_BIOS_STEM=OpenBIOS \
-DPSXRECOMP_BIOS_PROFILE=$PWD/bios/OpenBIOS.toml ...
# Retail SCPH-1001 (requires your own local dump)
tools/regen_bios.sh --config bios/SCPH1001.toml
```
Game repos set `DEFAULT_BIOS_PATH` (psxrecomp_add_runtime_target) to the
image the profile names, and `[recompiler] bios_config` in game.toml so game
codegen folds BIOS-copy RAM aliases through the same profile. Per-title
compatibility is NOT implied: verify a title on the target BIOS in a
reference emulator before switching its build (the identity gate refuses a
mismatched image at launch either way).
`PSXRECOMP_BIOS_STEMS` defaults to `OpenBIOS;SCPH1001`. The runtime build
automatically stages `bios/openbios.bin` and `bios/OpenBIOS.LICENSE` beside
every native executable. A release packager must copy that `bios/` directory
unchanged.
At runtime, no explicit player choice means OpenBIOS. A retail BIOS selected
with the launcher, `settings.toml`, or `--bios` wins after its exact identity is
verified. `[runtime] openbios = false` is reserved for a title with a verified
OpenBIOS incompatibility. See [`BIOS_SELECTION.md`](BIOS_SELECTION.md).
OpenBIOS seeds come from its ELF symbol tables (no Ghidra pass needed):
see the pin + regeneration recipe in `bios/OpenBIOS.toml`.
+5 -4
View File
@@ -250,15 +250,16 @@ These are noted here so future work knows where to slot them:
One profile per BIOS image; the profile is the single source of truth for the
image identity, the relocation windows, and the runtime anchors. Two ship:
`bios/SCPH1001.toml` (retail; user supplies the dump) and `bios/OpenBIOS.toml`
(MIT, redistributable, shipped with the build). Selected at configure time:
`-DPSXRECOMP_BIOS_STEM=<stem> -DPSXRECOMP_BIOS_PROFILE=<path>`, and per game
by `[recompiler] bios_config` in game.toml.
(MIT, redistributable, shipped with the build). Normal runtimes link both
generated backends (`PSXRECOMP_BIOS_STEMS=OpenBIOS;SCPH1001`) and select one at
launch. The recompiler's `[recompiler] bios_config` identifies the profile used
for game code generation; it does not choose the player's runtime BIOS.
```toml
[program.image] # identity; recompiler refuses a mismatched ROM
sha256 = "..." # pins the exact image (empty = unchecked)
redistributable = false # true: BIOS ships with the game; runtime hides
# the whole BIOS-selection surface
# any requirement to provide that image
[recompiler.address_model] # boot-time bulk code copies out of ROM
normalize_mask = "0x1FFFFFFF"
+1
View File
@@ -30,6 +30,7 @@ psxrecomp_add_runtime_target(psx-runtime
DEBUG_PORT 4370
WINDOW_TITLE "psxrecomp - BIOS"
DEFAULT_BIOS_PATH "${PSXRECOMP_ROOT}/bios/SCPH1001.BIN"
EXE_NAME "PSXRecomp"
)
if(BUILD_TESTING)
+46
View File
@@ -262,6 +262,10 @@ endif()
# cross-checking them, and it linked cleanly when they disagreed.
set(PSXRECOMP_BUNDLED_BIOS_PATH "bios/openbios.bin" CACHE STRING
"Bundled redistributable BIOS image, relative to the executable")
set(PSXRECOMP_BUNDLED_BIOS_SOURCE "${PSXRECOMP_ROOT}/bios/openbios.bin" CACHE FILEPATH
"Source image copied into native runtime builds as the bundled BIOS")
set(PSXRECOMP_BUNDLED_BIOS_LICENSE "${PSXRECOMP_ROOT}/bios/OpenBIOS.LICENSE" CACHE FILEPATH
"License notice copied alongside the bundled BIOS")
set(PSXRECOMP_BIOS_STEMS "OpenBIOS;SCPH1001" CACHE STRING
"Recompiled BIOS stems to link (first bundled/redistributable one is the default at runtime)")
# The profile is still needed as the staleness-stamp input for the primary stem.
@@ -619,6 +623,48 @@ function(psxrecomp_add_runtime_target target)
$<$<CXX_COMPILER_ID:MSVC>:SDL_MAIN_HANDLED>
)
# OpenBIOS is part of the native runtime product, not a developer-machine
# prerequisite. Stage both the exact ROM consumed by the compiled backend
# and its required MIT notice beside every native executable. Release
# packagers copy this directory as a unit.
if(NOT PSXRT_ORACLE)
list(FIND PSXRECOMP_BIOS_STEMS "OpenBIOS" _psxrt_openbios_index)
if(NOT _psxrt_openbios_index EQUAL -1)
if(NOT EXISTS "${PSXRECOMP_BUNDLED_BIOS_SOURCE}")
message(FATAL_ERROR
"Bundled OpenBIOS image is missing: "
"${PSXRECOMP_BUNDLED_BIOS_SOURCE}")
endif()
if(NOT EXISTS "${PSXRECOMP_BUNDLED_BIOS_LICENSE}")
message(FATAL_ERROR
"Bundled OpenBIOS license is missing: "
"${PSXRECOMP_BUNDLED_BIOS_LICENSE}")
endif()
get_filename_component(
_psxrt_bundled_bios_dir
"${PSXRECOMP_BUNDLED_BIOS_PATH}"
DIRECTORY)
get_filename_component(
_psxrt_bundled_bios_license_name
"${PSXRECOMP_BUNDLED_BIOS_LICENSE}"
NAME)
add_custom_command(TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
"$<TARGET_FILE_DIR:${target}>/${_psxrt_bundled_bios_dir}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${PSXRECOMP_BUNDLED_BIOS_SOURCE}"
"$<TARGET_FILE_DIR:${target}>/${PSXRECOMP_BUNDLED_BIOS_PATH}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${PSXRECOMP_BUNDLED_BIOS_LICENSE}"
"$<TARGET_FILE_DIR:${target}>/${_psxrt_bundled_bios_dir}/${_psxrt_bundled_bios_license_name}"
COMMENT "Staging bundled OpenBIOS image and MIT notice"
VERBATIM)
set_property(TARGET ${target} APPEND PROPERTY LINK_DEPENDS
"${PSXRECOMP_BUNDLED_BIOS_SOURCE}"
"${PSXRECOMP_BUNDLED_BIOS_LICENSE}")
endif()
endif()
if(PSXRT_ORACLE)
target_compile_definitions(${target} PRIVATE PSX_ORACLE_BUILD=1)
else()
+27 -12
View File
@@ -14,7 +14,10 @@ $MingwBin = "C:\msys64\mingw64\bin"
$env:PATH = "$MingwBin;$env:PATH"
cmake -S (Join-Path $Root "runtime") -B $BuildPath -G Ninja -DCMAKE_BUILD_TYPE=Release -DPSX_DEBUG_TOOLS=OFF
cmake -S (Join-Path $Root "runtime") -B $BuildPath -G Ninja `
-DCMAKE_BUILD_TYPE=Release `
-DPSX_DEBUG_TOOLS=OFF `
-DPSX_RECOMP_UI=OFF
cmake --build $BuildPath --target psx-runtime -j $env:NUMBER_OF_PROCESSORS
if (Test-Path $StageRoot) {
@@ -23,16 +26,18 @@ if (Test-Path $StageRoot) {
New-Item -ItemType Directory -Force $Stage | Out-Null
New-Item -ItemType Directory -Force (Join-Path $Stage "saves") | Out-Null
Copy-Item (Join-Path $BuildPath "psx-runtime.exe") (Join-Path $Stage "PSXRecomp.exe")
Copy-Item (Join-Path $BuildPath "PSXRecomp.exe") (Join-Path $Stage "PSXRecomp.exe")
Copy-Item (Join-Path $Root "README.md") $Stage
Copy-Item (Join-Path $Root "LICENSE") $Stage
Copy-Item -Recurse -Force (Join-Path $BuildPath "bios") (Join-Path $Stage "bios")
Copy-Item (Join-Path $Root "THIRD_PARTY_ATTRIBUTION.md") $Stage
if (Test-Path (Join-Path $Root "RELEASE_NOTES.md")) {
Copy-Item (Join-Path $Root "RELEASE_NOTES.md") $Stage
}
# The Release build is statically linked (PSX_STATIC_RUNTIME defaults ON for
# MinGW Release in runtime.cmake), so the exe imports ONLY Windows system DLLs
# — no SDL2.dll / libgcc_s_seh-1.dll / libstdc++-6.dll to bundle. Shipping
# so there is no SDL2.dll / libgcc_s_seh-1.dll / libstdc++-6.dll to bundle. Shipping
# those side-by-side was the cause of the 0xc000007b launch crash on user
# machines that had a mismatched copy earlier on the DLL search path.
#
@@ -47,7 +52,7 @@ $systemDlls = @("kernel32.dll","user32.dll","gdi32.dll","shell32.dll","msvcrt.dl
"dinput8.dll","rpcrt4.dll","hid.dll","cfgmgr32.dll")
$nonSystem = $imports | Where-Object { $systemDlls -notcontains $_.ToLower() }
if ($nonSystem) {
throw "Release exe is NOT self-contained — imports non-system DLL(s): $($nonSystem -join ', ')"
throw "Release exe is NOT self-contained; imports non-system DLL(s): $($nonSystem -join ', ')"
}
Write-Host "Verified self-contained: imports only system DLLs ($($imports.Count) total)"
@@ -58,11 +63,13 @@ $exeBytes = [System.IO.File]::ReadAllBytes((Join-Path $Stage "PSXRecomp.exe"))
$exeText = [System.Text.Encoding]::ASCII.GetString($exeBytes)
$bakedBios = [regex]::Matches($exeText, '[A-Za-z]:[/\\][ -~]*?SCPH1001\.BIN') | ForEach-Object { $_.Value } | Select-Object -Unique
if ($bakedBios) {
throw "Release exe contains baked absolute BIOS path(s): $($bakedBios -join '; ') — build with a relative DEFAULT_BIOS_PATH"
throw "Release exe contains baked absolute BIOS path(s): $($bakedBios -join '; '); build with a relative DEFAULT_BIOS_PATH"
}
Write-Host "Verified no baked absolute BIOS path in the exe"
# No user-machine or copyrighted files may ride along in the stage.
# No user-machine or copyrighted files may ride along in the stage. OpenBIOS
# is intentionally present and redistributable; retail SCPH images remain
# forbidden.
$strayPatterns = @("SCPH*.BIN","*.cue","*.iso","*.mcd","bios.cfg","disc.cfg",
"settings.toml","keybinds.ini","overlay_captures.json")
$stray = foreach ($pat in $strayPatterns) { Get-ChildItem $Stage -Recurse -File -Filter $pat -ErrorAction SilentlyContinue }
@@ -73,7 +80,14 @@ $savesFiles = Get-ChildItem (Join-Path $Stage "saves") -Recurse -File -ErrorActi
if ($savesFiles) {
throw "Stage saves/ directory must be empty, contains: $(($savesFiles | ForEach-Object FullName) -join '; ')"
}
Write-Host "Verified stage carries no BIOS/disc/save/sidecar files"
$bundledBios = Join-Path $Stage "bios/openbios.bin"
$bundledLicense = Join-Path $Stage "bios/OpenBIOS.LICENSE"
if (!(Test-Path $bundledBios) -or
(Get-Item $bundledBios).Length -ne 524288 -or
!(Test-Path $bundledLicense)) {
throw "Stage must contain the 512 KiB OpenBIOS image and its MIT notice"
}
Write-Host "Verified bundled OpenBIOS + notice; no retail BIOS/disc/save/sidecar files"
@"
; PSXRecomp input mapping. PSX buttons are active when any listed source is pressed.
@@ -108,15 +122,16 @@ select = back
@"
PSXRecomp $Version
This package does not include a PlayStation BIOS, game disc image, generated
game source, save data, or any copyrighted Sony/game assets.
This package includes the MIT-licensed OpenBIOS from PCSX-Redux. Its notice is
in bios/OpenBIOS.LICENSE. It does not include a retail PlayStation BIOS, game
disc image, generated game source, save data, or copyrighted Sony/game assets.
First launch:
1. Run PSXRecomp.exe.
2. Select your legally obtained SCPH1001.BIN BIOS when prompted.
2. OpenBIOS runs by default. No external BIOS is required.
The selected BIOS path is saved in bios.cfg next to the executable. Delete that
file if you want to pick a different BIOS later.
You can select your legally obtained SCPH1001.BIN instead. The selected path is
saved in bios.cfg next to the executable; clear it to return to OpenBIOS.
This framework package is BIOS-only. Game-specific PSXRecomp releases use the
same BIOS picker and additionally prompt for the required game disc image.