mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-25 18:05:12 -04:00
ff4be21c90
The v3.0 Japanese (SCPH-5500, 09/09/96) and US (SCPH-5501, 11/18/96) retail BIOS images join SCPH-1001, SCPH-101 and SCPH-5552, so every v3.0 region (J, A, E) has a profile. Both images match SCPH-1001 v2.2 byte for byte in the kernel, ROM [0x80, 0x18000). SCPH-5501's reset vector is identical too; SCPH-5500's differs in 24 bytes. The shell differs in both. So each profile is SCPH1001.toml with its own identity (name, id, rom, sha256 pin, stem): the copy windows and install slots are kernel properties and carry over unchanged. The shell runs through the dirty-RAM interpreter, as for SCPH5552. Each image gets its own seed list, derived by the same rule as phase2_ghidra_seeds_SCPH5552.json: the SCPH-1001 corpus filtered to seeds whose 64-byte ROM window is identical in both images (534 kept, 569 dropped), plus the two architectural vectors and 6 A0/B0/C0 kernel-table targets. The files carry only addresses, labels and rationales, plus the SHA-256 of both ROMs. - psx_bios_known_images.h: CRC-32 FF3EEB8C (SCPH-5500) and 8D8CB7E4 (SCPH-5501), both 512 KiB. A build that does not link these backends builds one from the player's own dump as a loadable module, like SCPH-5552, and the netplay lobby can name the image. - main_cli.cpp: map SCPH5500 / SCPH5501 dumps to their profiles. - build_cli.py: package both profiles with the CLI framework. - docs/BIOS_SELECTION.md: list them among the module-built images.
148 lines
5.4 KiB
Python
148 lines
5.4 KiB
Python
"""Build and package the PSXRecomp developer command-line tools."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import os
|
|
import pathlib
|
|
import platform
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
ROOT = pathlib.Path(__file__).resolve().parent.parent
|
|
TOOLS = ("psxrecomp", "psxrecomp-toml", "psxrecomp-game", "psxrecomp-bios")
|
|
|
|
|
|
def run(command: list[str]) -> None:
|
|
print("+", subprocess.list2cmdline(command), flush=True)
|
|
subprocess.run(command, cwd=ROOT, check=True)
|
|
|
|
|
|
def platform_name() -> str:
|
|
systems = {"Windows": "windows", "Linux": "linux", "Darwin": "macos"}
|
|
machines = {
|
|
"amd64": "x86_64",
|
|
"x86_64": "x86_64",
|
|
"arm64": "arm64",
|
|
"aarch64": "arm64",
|
|
}
|
|
raw_system = platform.system()
|
|
if raw_system.startswith(("MSYS", "MINGW", "CYGWIN")):
|
|
raw_system = "Windows"
|
|
system = systems.get(raw_system, raw_system.lower())
|
|
machine = machines.get(platform.machine().lower(), platform.machine().lower())
|
|
return f"{system}-{machine}"
|
|
|
|
|
|
def find_tool(build_dir: pathlib.Path, name: str, config: str) -> pathlib.Path:
|
|
suffix = ".exe" if os.name == "nt" else ""
|
|
filename = name + suffix
|
|
candidates = (build_dir / filename, build_dir / config / filename)
|
|
for candidate in candidates:
|
|
if candidate.is_file():
|
|
return candidate
|
|
checked = ", ".join(str(path) for path in candidates)
|
|
raise FileNotFoundError(f"{filename} was not built; checked {checked}")
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(
|
|
description="build a redistributable PSXRecomp CLI archive")
|
|
parser.add_argument(
|
|
"configuration", nargs="?", choices=("release", "debug"),
|
|
default="release", help="build configuration (default: release)")
|
|
parser.add_argument(
|
|
"--build-dir", default="recompiler/build-cli",
|
|
help="CMake build directory (default: recompiler/build-cli)")
|
|
parser.add_argument(
|
|
"--dist-dir", default="dist",
|
|
help="package output directory (default: dist)")
|
|
parser.add_argument(
|
|
"--skip-build", action="store_true",
|
|
help="package tools already present in --build-dir")
|
|
args = parser.parse_args()
|
|
|
|
config = "Release" if args.configuration == "release" else "Debug"
|
|
build_dir = (ROOT / args.build_dir).resolve()
|
|
dist_dir = (ROOT / args.dist_dir).resolve()
|
|
|
|
if not args.skip_build:
|
|
if shutil.which("cmake") is None:
|
|
parser.error("CMake is not installed or is not on PATH")
|
|
source_arg = os.path.relpath(ROOT / "recompiler", ROOT)
|
|
build_arg = os.path.relpath(build_dir, ROOT)
|
|
configure = [
|
|
"cmake", "-S", source_arg, "-B", build_arg,
|
|
f"-DCMAKE_BUILD_TYPE={config}",
|
|
"-DPSXRECOMP_STATIC_CLI=ON",
|
|
]
|
|
if not (build_dir / "CMakeCache.txt").exists() and shutil.which("ninja"):
|
|
configure += ["-G", "Ninja"]
|
|
run(configure)
|
|
jobs = str(os.cpu_count() or 2)
|
|
run([
|
|
"cmake", "--build", build_arg, "--config", config,
|
|
"--target", *TOOLS, "--parallel", jobs,
|
|
])
|
|
|
|
package = f"psxrecomp-cli-{platform_name()}"
|
|
stage = dist_dir / package
|
|
archive = dist_dir / f"{package}.zip"
|
|
dist_dir.mkdir(parents=True, exist_ok=True)
|
|
if stage.exists():
|
|
shutil.rmtree(stage)
|
|
if archive.exists():
|
|
archive.unlink()
|
|
stage.mkdir()
|
|
|
|
shutil.copy2(find_tool(build_dir, "psxrecomp", config), stage)
|
|
libexec = stage / "libexec"
|
|
libexec.mkdir()
|
|
for name in TOOLS[1:]:
|
|
shutil.copy2(find_tool(build_dir, name, config), libexec)
|
|
share = stage / "share"
|
|
share.mkdir()
|
|
shutil.copy2(
|
|
ROOT / "recompiler" / "seeds" / "phase2_ghidra_seeds.json", share)
|
|
|
|
framework = stage / "framework"
|
|
source_ignore = shutil.ignore_patterns(
|
|
"build", "build-*", "tests", "__pycache__", "*.pyc", "*.pyo",
|
|
"*.exe", "*.obj", "*.pdb", "*.lib")
|
|
shutil.copytree(ROOT / "runtime", framework / "runtime", ignore=source_ignore)
|
|
shutil.copytree(ROOT / "recompiler", framework / "recompiler", ignore=source_ignore)
|
|
bios_profiles = {
|
|
"OpenBIOS.toml": ROOT / "bios" / "OpenBIOS.toml",
|
|
"SCPH1001.toml": ROOT / "bios" / "SCPH1001.toml",
|
|
"SCPH101.toml": ROOT / "bios" / "SCPH101.toml",
|
|
"SCPH5500.toml": ROOT / "bios" / "SCPH5500.toml",
|
|
"SCPH5501.toml": ROOT / "bios" / "SCPH5501.toml",
|
|
"SCPH5552.toml": ROOT / "bios" / "SCPH5552.toml",
|
|
}
|
|
(framework / "bios").mkdir()
|
|
for filename, source in bios_profiles.items():
|
|
shutil.copy2(source, framework / "bios" / filename)
|
|
shutil.copy2(ROOT / "bios" / "openbios.bin", framework / "bios")
|
|
shutil.copy2(ROOT / "bios" / "OpenBIOS.LICENSE", framework / "bios")
|
|
shutil.copy2(ROOT / ".gitignore", framework)
|
|
shutil.copy2(ROOT / "LICENSE", framework)
|
|
shutil.copy2(ROOT / "THIRD_PARTY_ATTRIBUTION.md", framework)
|
|
shutil.copy2(ROOT / "README.md", stage)
|
|
shutil.copy2(ROOT / "LICENSE", stage)
|
|
shutil.copy2(ROOT / "THIRD_PARTY_ATTRIBUTION.md", stage)
|
|
|
|
shutil.make_archive(str(archive.with_suffix("")), "zip", dist_dir, package)
|
|
print(f"PSXRecomp CLI package: {archive}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
raise SystemExit(main())
|
|
except subprocess.CalledProcessError as exc:
|
|
print(f"build_cli: command failed with exit code {exc.returncode}",
|
|
file=sys.stderr)
|
|
raise SystemExit(exc.returncode)
|