mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
aef852e11b
SIO handler alias (0x0CF0 → func_0000641C): Runtime capture showed BIOS installs lui+addiu+jalr to RAM 0x641C at 0x0CF0. New [[recompiler.bios_aliases]] TOML mechanism emits a one-liner wrapper and registers it in the dispatch table. Eliminates 30K dirty_ram blocks/session. Instant disc speed (disc_speed = "instant" in game.toml [runtime]): cdrom_set_speed(0) collapses all seek/read delays to 1 cycle. Correct INT sequence still fires; no artificial wait. "2x" and "4x" divisors available. Default remains authentic 1x. Tomba set to instant. Persistent game miss collector (tools/collect_game_misses.py): Appends newly-seen dirty_ram dispatch misses in the game text range to a file (TombaRecomp/seeds/dirty_ram_misses.txt) for later seeding. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
136 lines
5.8 KiB
C++
136 lines
5.8 KiB
C++
// config_loader.h — shared TOML config loader for psxrecomp-{bios,game}.
|
|
//
|
|
// Mirrors the schema accepted by tools/audit_config.py (Python side). See
|
|
// docs/config_schema.md for the field reference.
|
|
//
|
|
// Two entry points:
|
|
// load_bios_config(path) reads bios/SCPH1001.toml — describes the BIOS
|
|
// load_game_config(path) reads <game>/game.toml — describes a game EXE
|
|
//
|
|
// A runtime/process that needs both calls both; the BIOS one is the
|
|
// always-loaded base, the game one is layered on top (merge semantics are
|
|
// the caller's responsibility for now — recompiler tools consume one or
|
|
// the other independently).
|
|
//
|
|
// Paths inside the TOML are resolved relative to the detected project
|
|
// root (the nearest ancestor of the config file that has .gitignore,
|
|
// .git, or CMakeLists.txt).
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <filesystem>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace PSXRecompV4 {
|
|
|
|
// [runtime] block — consumed by runtime/src/main.cpp. All fields optional;
|
|
// callers that need them check has_* flags or use the supplied defaults.
|
|
struct RuntimeConfig {
|
|
bool has_debug_port = false;
|
|
uint16_t debug_port = 0;
|
|
|
|
bool has_window_title = false;
|
|
std::string window_title;
|
|
|
|
bool has_memcard_dir = false;
|
|
std::filesystem::path memcard_dir; // absolute path (resolved against project root)
|
|
|
|
// disc_speed: "1x" (default) | "2x" | "4x" | "instant"
|
|
// Controls how quickly CD-ROM timing delays fire. "instant" collapses all
|
|
// seek/read delays to 1 cycle — correct INT sequence, no artificial wait.
|
|
bool has_disc_speed = false;
|
|
std::string disc_speed; // raw string; main.cpp converts to divisor
|
|
};
|
|
|
|
// One entry from [[recompiler.bios_vectors]].
|
|
// Describes a BIOS vector dispatch stub (A0/B0/C0) that the BIOS installs
|
|
// into low RAM at boot. The recompiler reads the function pointer table from
|
|
// the ROM binary at build time and emits a static C switch handler so these
|
|
// addresses are resolved as binary-search hits at runtime rather than falling
|
|
// through to dirty_ram_interp.
|
|
struct BiosVectorTable {
|
|
uint32_t ram_addr; // RAM address of the installed stub (e.g. 0xA0)
|
|
int index_reg; // CPU register that holds the function index ($t1 = 9)
|
|
uint32_t table_rom_addr; // ROM virtual address of the function pointer table
|
|
uint32_t table_count; // number of entries to read from the table
|
|
// Runtime RAM address of the live function table (used as fallback for
|
|
// Shell-patched entries not present in ROM). 0 = no runtime fallback.
|
|
uint32_t table_ram_addr;
|
|
};
|
|
|
|
// One entry from [[recompiler.bios_aliases]].
|
|
// A RAM address the BIOS installs a simple fixed-target trampoline at
|
|
// (e.g. the SIO handler at 0x0CF0 which just jalrs to 0x641C). Emitted as
|
|
// a one-liner wrapper in the dispatch table — no table lookup, no switch.
|
|
struct BiosAlias {
|
|
uint32_t ram_addr; // the installed stub address (e.g. 0x0CF0)
|
|
uint32_t target_key; // normalized dispatch key of the target (e.g. 0x641C)
|
|
};
|
|
|
|
struct BiosConfig {
|
|
std::filesystem::path config_path; // the toml file itself
|
|
std::filesystem::path project_root; // resolved via .gitignore/.git/CMakeLists.txt walk
|
|
|
|
// [program] block
|
|
std::string name; // display name, e.g. "SCPH1001 BIOS"
|
|
std::string id; // canonical id, e.g. "SCPH-1001"
|
|
std::filesystem::path rom_path; // absolute path to BIOS ROM
|
|
uint32_t load_address;
|
|
uint32_t entry_pc;
|
|
uint32_t text_size;
|
|
|
|
// [recompiler] block
|
|
std::filesystem::path seeds_path; // absolute path to seeds JSON
|
|
std::filesystem::path out_dir; // absolute path to output dir
|
|
bool strict; // currently always true
|
|
std::string out_stem; // derived if not explicit
|
|
std::vector<BiosVectorTable> bios_vectors; // optional vector dispatch tables
|
|
std::vector<BiosAlias> bios_aliases; // optional fixed-target trampolines
|
|
|
|
// [runtime] block (optional)
|
|
RuntimeConfig runtime;
|
|
};
|
|
|
|
struct GameConfig {
|
|
std::filesystem::path config_path;
|
|
std::filesystem::path project_root;
|
|
|
|
// [game] block
|
|
std::string name; // e.g. "Tomba!"
|
|
std::string id; // e.g. "SCUS-94236"
|
|
std::filesystem::path exe_path; // absolute path to PS-X EXE
|
|
uint32_t load_address;
|
|
uint32_t entry_pc;
|
|
uint32_t text_size;
|
|
uint32_t stack_base; // initial $sp
|
|
// disc paths (Phase D will properly support multi-disc; for now we
|
|
// accept either a single `disc = "..."` or `discs = [...]` and store
|
|
// the union here).
|
|
std::vector<std::filesystem::path> discs;
|
|
|
|
// [recompiler] block
|
|
std::filesystem::path seeds_path; // absolute path to seeds (text or json)
|
|
std::filesystem::path bios_thunks_path; // optional; empty if not set
|
|
std::filesystem::path out_dir;
|
|
bool strict;
|
|
std::string out_stem; // derived if not explicit
|
|
|
|
// [runtime] block (optional)
|
|
RuntimeConfig runtime;
|
|
};
|
|
|
|
// Locate the project root by walking upward from `config_path` until a
|
|
// directory containing `.gitignore`, `.git`, or `CMakeLists.txt` is found.
|
|
// Throws std::runtime_error if not found within 8 levels.
|
|
std::filesystem::path find_project_root(const std::filesystem::path& config_path);
|
|
|
|
// Load a BIOS config TOML. Throws std::runtime_error on schema violations.
|
|
BiosConfig load_bios_config(const std::filesystem::path& config_path);
|
|
|
|
// Load a game config TOML. Throws std::runtime_error on schema violations.
|
|
GameConfig load_game_config(const std::filesystem::path& config_path);
|
|
|
|
} // namespace PSXRecompV4
|