Boot path
What the game does between disc-spin and title screen. Three jobs, in order: read the PROT.DAT directory into RAM, wire up the asset-type dispatcher, and hand control to the title-screen overlay.
How it works
Almost every PSX game has a built-in archive that bundles the small files together so the disc can stream them efficiently. Legaia's archive is PROT.DAT, and it has its own table of contents (TOC) — a list saying "entry N starts at sector S and is L bytes long". Before the game can do anything, it has to read that table into RAM. That's job one.
Job two is wiring up a small asset-type dispatcher. The PROT entries don't all hold the same kind of data — some are textures, some are 3D meshes, some are dialog blobs, some are animation containers. Each entry's first byte is a type tag, and there's a single function that reads that tag and routes the bytes to the right per-format parser. Once the dispatcher's helper tables are populated, every later "load this entry" call works.
Job three: the boot code reaches a top-level game-mode state machine. This is a 28-entry table where each slot is a function pointer for one major mode of the game — boot, title, field, battle, world map, menu, cutscene, etc. The mode pointer changes whenever the game transitions; the per-frame loop just calls "whatever the current mode's handler says". The title-screen overlay is loaded next, and the actor VM inside it starts ticking the splash animation.
One important quirk: the script that drives every running script — the field VM — is not in the main executable. It lives in a RAM overlay loaded from the disc when you enter a town or field map. That's why the boot path here is so short: most of the gameplay code isn't in SCUS_942.54 at all.
TOC loader
- Function
FUN_8003E4E8- Reads
- First three sectors of
PROT.DAT(= 6 KB) - Lands at
0x801C70F0in RAM- Called from
FUN_8003EFE8andFUN_8003F08Cat boot
The on-disc TOC and the in-RAM TOC have different strides — the on-disc-to-in-RAM transformation runs once at boot, but its function hasn't been reversed yet. See the PROT.DAT format spec for the byte layout.
After the TOC is in RAM, two resolvers are usable:
| Resolver | Mode | Used by |
|---|---|---|
FUN_8003E8A8 | Index-based (PROT entry number in) | Streaming loader, dev-build sound branch |
FUN_8003E6BC | Path-based (resolves data\battle\efect.dat, h:\PROT\FIELD\<scene>\…) | Most retail-build code paths |
The path-based opener runs the dev-style filename through the CDNAME.TXT name map to find the index, then delegates to the index-based resolver. It's a thin layer.
Asset-type dispatcher
- Function
FUN_8001F05C- Calling convention
result = FUN_8001F05C(byte *src_data, u32 type_and_size, int param3, int copy_only)- Encoding
type_and_sizepacks the type byte in the high 8 bits, size in the low 24 bits
Every TIM, TMD, MES, ANM, etc. is reached through this one function. The boot path doesn't call it itself — it just makes sure the buffer pointers it writes to are valid. FUN_80020224 (the asset descriptor walker) is one of the dispatcher's two static call sites and is invoked from the town overlay's FUN_801D6704 (MAIN_INIT) at runtime. See Asset loader for the full story.
Game-mode state machine
The 28-mode state machine table at 0x8007078C is the top-level "what is the game doing" dispatcher. Each entry is a (handler_addr, …) tuple corresponding to a major mode — boot, title, field, battle, world map, menu, cutscene, and so on.
The script VM that drives every running script is not in SCUS_942.54. It lives in RAM overlays at 0x801C0000+, loaded on demand:
| VM | Driver | Lives in |
|---|---|---|
| Actor / sprite VM | FUN_801D6628 | Title-screen overlay |
| Field / event VM | FUN_801DE840 | Town / field overlay |
| Effect VM cluster | FUN_801DE914 / 801DFDF8 / 801E0088 | Battle overlay |
Debug flags
Two RAM bytes that several subsystems branch on at boot time and beyond:
| Address | Role |
|---|---|
_DAT_8007B8C2 | Dev/retail build toggle. Sound init, the field loader, and the monster-bank loader all carry an "if dev" branch keyed on this byte. |
_DAT_8007B98F | Separate debug-mode flag (NA build offset; JP retail uses 0x07D51F, an 0x1B90 build-shift). |
Neither flag has a writer in SCUS_942.54. The input dispatcher FUN_8001822C reads them but doesn't write them. The writers must live in an unswept overlay (most likely the option-menu / cheat-menu cluster), and TCRF GameShark codes confirm both flags are runtime-writable.