Files
BFM-decomp/config/splat.us.exe.yaml
T
Drew T 02f060f607 feat(phase-31): S79 #5 — the libpad 4.2.1 + libapi 4.2 band and the apicard region LINKED from real objects: 13 stubs + 4 TUs + the reorder island gone; main 16 stubs, fleet 38
800c3 (0x8005CE18-0x8005FC68, one contiguous run of 33 interleaved Sony objects) is now four
stub rows — libapi1 (21 BIOS trampolines + COUNTER), libpad1 (PADENTRY + PADMAIN 760), libapi2
(L02/L03), libpad2 (PADCMD PADIF PADPORTD PADSEQD WAITRC2) — fed by two WINDOWED psyq_integrate
calls from the raw .run/obj42/{libapi42,libpad421} dirs (integrate tiles each stub with one
library; every boundary checked against .text SECTION sizes). The apicard region's three
"game code" rows were libapi 4.2's C objects to the byte: 800c2 = FIRST.o (firstfile + the
"no jump table wall" stub func_80062144), 800c2_2 = PAD.o, 800c2_3 = PATCH.o + CHCLRPAD.o ->
apicard5/6/7; make_apicard_used.py sources libapi from 4.2 (the EXE's real libapi; libcard
stays 4.0) into .run/obj42/apicard_used, 26 objects / 7 blocks, no game code left in
0x80061F38-0x80062888. src/800c3.c (129 hand-matched "C", 62 verbatim bodies, 19 stubs incl.
the four §332 %lo-in-a-delay-slot "walls"), src/800c2.c, src/800c2_2.c, src/800c2_3.c removed;
REORDER_TUS is empty (mechanism kept). Cookbook §490.

Two stale instruments fixed: exclude_audit let a pinned WALL outrank LINKED (PopMatrix/
PushMatrix had sat as walls since S68 while living in libgte3, linked since Phase 8) — LINKED
dominates now, config/wave_exclude.txt 13 -> 3; frontier_classify carried a hard-coded 49-name
LINKED set (R51) and reported 337 "stubs" — derived from the Makefile now.

Verified: main 143dbb89f34491258bbc27810d0a12ec8b43a8dd WITH all SDK dirs and WITHOUT them from
a fresh extract; make tools-health OK; R22 fleet extract-all 212/212 + check-all 213/213.
Metrics: main REAL 839->773, LINKED 1,150->1,256, VERBATIM 29->3, stubs 29->16, byte-identical
2,075/2,091 = 99.2%; game-code weighted 93.3% (38,748/41,534), remainder 2,786 = the open-stub
sum; fleet stubs 51->38 (frontier_classify: 39 rows incl. the data word). Verbatim manifest
33 -> 6. Docs: worklist rows + "S79 task #5", SETUP (fresh-clone obj42 commands, Makefile
blocks, exclude_audit), decision-log "S79 addendum 2", accelerators "S79 (2)", CURRENT_PHASE
S79 FINAL refreshed (census, metrics, the task #6 brief).
2026-09-04 17:56:31 -06:00

282 lines
24 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# splat config — Brave Fencer Musashi main EXE (SLUS-00726, USA)
# Phase 5: rebuild SLUS_007.26 byte-for-byte from disassembly (all-asm skeleton).
#
# Derived from splat 0.41.0's own `python -m splat create_config <PS-X EXE>`
# (splat/scripts/create_config.py::create_psx_config), adapted to this repo's
# paths and the Phase-3 symbol export. PSX-specific values that the generator
# pins (do NOT "tidy" them without evidence): compiler PSYQ, subalign 2,
# section_order rodata/text/data/bss, find_file_boundaries False, gp_value from
# the EXE header's Initial-GP field.
#
# Boundaries (file offsets) come from splat's psxexeinfo estimate:
# text @ file 0x800 (vram 0x80010000)
# data @ file 0x531DC (vram 0x800629DC) <- iterate if the link/bytes disagree
# end @ file 0x65000 (= 413,696 B)
name: SLUS_007.26
sha1: 143dbb89f34491258bbc27810d0a12ec8b43a8dd
options:
basename: SLUS_007.26
target_path: extracted/retail/SLUS_007.26
elf_path: build/us/SLUS_007.26.elf
# base_path is resolved relative to THIS yaml's dir (config/), so `..` = repo root
base_path: ..
platform: psx
compiler: PSYQ
asm_path: asm
src_path: src
build_path: build
ld_script_path: build/us/SLUS_007.26.ld
ld_dependencies: True
find_file_boundaries: False
gp_value: 0x80074750
o_as_suffix: True
use_legacy_include_asm: False
section_order: [".rodata", ".text", ".data", ".bss"]
symbol_addrs_path:
- config/symbols.us.txt
# main-scoped symbols OUTSIDE main's image (high RAM the overlays reuse as CODE).
# NEVER stacked by an overlay/resident — see the header of that file (Phase 26-A).
- config/symbols.us.ram.txt
subalign: 2
string_encoding: ASCII
data_string_encoding: ASCII
rodata_string_guesser_level: 2
data_string_guesser_level: 2
# Enable if maspsx reorders INCLUDE_ASM output once the code segment is `c`
# (https://github.com/mkst/maspsx#include_asm-reordering-workaround-hack):
# include_asm_macro_style: maspsx_hack
segments:
- name: header
type: header
start: 0x0
- name: main
type: code
start: 0x800
vram: 0x80010000
# align 4 (not the code-segment default 16): the text→data boundary at vram
# 0x800629DC is word-aligned but not 16-aligned, so ALIGN(.,16) would inject
# 4 padding bytes the original lacks. MIPS is word-aligned, so ALIGN(.,4) is a
# no-op at every real boundary here.
align: 4
subsegments:
# Per-module optimization mixing (SETUP §5.5): the boot/main/game-mode-dispatch
# module (vram 0x80010000-0x800123F0) was compiled at -O0; the rest of the text at
# -O2. Split into two c-subsegments so the Makefile applies per-file flags
# (build/src/boot.o is overridden to -O0). The split is byte-identical at 100%
# INCLUDE_ASM (Phase-7 regression gate) — opt level only affects matched C, not stubs.
# Boundary = func_800123F0 (vram 0x800123F0 -> file vram-0x8000F800 = 0x2BF0).
- [0x800, c, boot] # -O0 boot module -> src/boot.c (vram 0x80010000-0x800123F0)
# P31 S72 — SPLIT AT THE JTBL-SPAN TU BOUNDARIES. One code object contributes exactly ONE
# contiguous `.rodata` run, so each jump-table span needs its own object. The span owners'
# address ranges are DISJOINT AND ORDERED, which is the evidence that these are (at least
# some of) the original translation-unit boundaries — tables pack tight WITHIN a TU and are
# separated by other data ACROSS TUs (§8e/§426). Splitting here is therefore both the fix
# and the minimum: any extra split would be speculation. `800` keeps its legacy name so the
# matched fns + their asm/nonmatchings/800 paths don't migrate.
- [0x2BF0, c, 800] # -O2 game code -> src/800.c (vram 0x800123F0-0x8002B0B4); owns .rodata span A
# P31 S77 — 3-way cut for the -O0 island func_8002C410 (0x8002C410-0x8002C8BC). gcc-2.7.2
# has no per-function optimize pragma, so the opt level is per FILE (§116): the island needs
# its own object for the Makefile -O0 glob. The outer pieces stay -O2.
- [0x1B8B4, c, 800_b] # -O2 -> src/800_b.c (vram 0x8002B0B4-0x8002C410); owns .rodata span B (front)
- [0x1CC10, c, 800_b_o0a] # -O0 ISLAND -> src/800_b_o0a.c (vram 0x8002C410-0x8002C8BC)
- [0x1D0BC, c, 800_b_2] # -O2 -> src/800_b_2.c (vram 0x8002C8BC-0x80035270); owns .rodata span B (tail)
- [0x25A70, c, 800_c] # -O2 game code -> src/800_c.c (vram 0x80035270-0x8003A444); owns .rodata span C
# PsyQ libspu+libsnd COMBINED sound region (Phase 8): the two SDK sound libs are interleaved here,
# so they link as one 63-object region (curated by tools/make_snd_used.py; 3 addresses excluded as
# cross-object-common/false-positive stubs: S_R/S_W 0x3C438, S_GRMDT* 0x3D424, S_IH/UT_RON 0x3D94C).
# VM_F 0x3FA64 was the 4th exclusion (scattered-.bss) until P31 S78 #4: psyq_integrate now splits
# such a .bss into per-base NOLOAD pieces at link-prepare (psyq_bss_split, cookbook §489) and it
# links as snd12. Subsegs via gen_lib_subsegs.py; integrate window 0x3A444..0x4239C. snd1..snd12
# link; sgap* = game code + the 3 excluded stubs. (libsnd SSGM.o @0x1BD80 stays a stub in 800.)
- [0x2AC44, c, snd1] # snd block 1: 15 obj (S_INI.o..S_SK.o) vram 0x8003A444-0x8003C438
- [0x2CC38, c, sgap] # game code (vram 0x8003C438-0x8003C498)
- [0x2CC98, c, snd2] # snd block 2: 8 obj (S_STSA.o..S_SRMD.o) vram 0x8003C498-0x8003D424
- [0x2DC24, c, sgap_2] # game code + excluded S_GRMDT stub (vram 0x8003D424-0x8003D434)
- [0x2DC34, c, snd3] # snd block 3: 4 obj (S_GRMD.o..SSINIT.o) vram 0x8003D434-0x8003D630
- [0x2DE30, c, sgap_3] # game code (vram 0x8003D630-0x8003D650)
- [0x2DE50, c, snd4] # snd block 4: 3 obj (SSSATTR.o..SSCALL.o) vram 0x8003D650-0x8003DC90
- [0x2E490, c, sgap_4] # game code (vram 0x8003DC90-0x8003E248)
- [0x2EA48, c, snd5] # snd block 5: 1 obj (PAUSE.o) vram 0x8003E248-0x8003E2E4
- [0x2EAE4, c, sgap_5] # game code (vram 0x8003E2E4-0x8003E310)
- [0x2EB10, c, snd6] # snd block 6: 12 obj (MIDIREAD.o..VM_ALOC2.o) vram 0x8003E310-0x8003FA54
- [0x30254, c, sgap_6] # game code: func_8003FA54, 4 ins (vram 0x8003FA54-0x8003FA64)
- [0x30264, c, snd12] # snd block 12 (S78 #4): VM_F.o (237 ins, exact tile; .bss split ×2 at link-prepare, §489) vram 0x8003FA64-0x8003FE18 — carved off sgap_6
- [0x30618, c, snd7] # snd block 7: 5 obj (S_SNV.o..VM_N2P.o) vram 0x8003FE18-0x800403A4
- [0x30BA4, c, snd10] # snd block 10 (S78): VM_NO1.o (305 ins, exact tile) vram 0x800403A4-0x80040868 — was 'sgap_7' game code (§485)
- [0x31068, c, snd8] # snd block 8: 1 obj (VM_NOWOF.o) vram 0x80040868-0x80040938
- [0x31138, c, snd11] # snd block 11 (S78): VM_NOWON.o (300 ins, exact tile) vram 0x80040938-0x80040DE8 — carved off the old sgap_8
- [0x315E8, c, sgap_8] # game code (vram 0x80040DE8-0x800414E4)
- [0x31CE4, c, snd9] # snd block 9: 11 obj (VM_VSU.o..VS_VTC.o) vram 0x800414E4-0x8004239C
# PsyQ libetc region (Phase 8): 5 objects (VSYNC/INTR/INTR_VB/INTR_DMA/VMODE) form ONE
# contiguous block at the tail of the old 800 subseg, ending exactly at libcd1 (0x80043088).
# psyq_integrate swaps src/libetc.o(.text) -> build/psyq/libetc/*.o + NOLOAD data (libcd model).
- [0x32B9C, c, libetc] # libetc block -> src/libetc.c (vram 0x8004239C-0x80043088, 5 objs)
# PsyQ libcd region (Phase 7 Task 2'): the real libcd objects are linked here in place of
# stubs (the .ld swaps build/src/libcd{1,2}.o -> build/psyq/libcd/*.o + NOLOAD data). The
# 18 objects form two contiguous blocks split by a 76-B non-libcd gap (stays a stub).
- [0x33888, c, libcd1] # libcd block 1 -> src/libcd1.c (vram 0x80043088-0x80046980, 11 objs)
- [0x37180, c, gap] # non-libcd gap -> src/gap.c (vram 0x80046980-0x800469CC, stub)
- [0x371CC, c, libcd2] # libcd block 2 -> src/libcd2.c (vram 0x800469CC-0x8004787C, 7 objs)
# PsyQ libgs (Phase 7 Task #9, FULL integration; S78 #3/#4): 34 libgs objects in 8 blocks
# across vram 0x8005080C-0x80057928. psyq_integrate swaps each block stub's
# build/src/libgsN.o(.text) for the real objects + NOLOAD data (same mechanism as libcd).
# The 4 remaining gaps (gsgap1/2/4/5: 80 / 48 / 48 / 304 B) are libgte objects, wired as
# libgte27-30 (S78 #3). The 1536 B gap gsgap3 was GS_001, EXCLUDED from Phase 7 to P31 S78 as the
# scattered-.bss "hard case" (cookbook §9.1; six bases): psyq_integrate now splits such a .bss
# into per-base NOLOAD pieces at link-prepare (psyq_bss_split, cookbook §489), so it links as
# libgs8 (S78 #4). GS_106 (block 4) is an 8-ins object that only anchors uniquely within the
# libgs window, so make extract passes 0x8005080C 0x80057928 to psyq_integrate. Object lists +
# disambiguation: tools/make_libgs.sh.
# PsyQ libgte (Phase 8): GTE matrix/vector math, 53 objects in 22 blocks across the old 800b region,
# interleaved with game code (800b/800b_2..800b_7). Subseg lines generated by gen_lib_subsegs.py
# (section-size-correct boundaries). integrate window 0x4787C..0x51804. The 5 libgs-gap libgte
# objects (MTX_05/07/11/REG03/REG11) are DEFERRED — gsgap1/2/4/5 stay stubs (see worklist).
- [0x3807C, c, libgte1] # libgte block 1: 5 obj (GEO_00.o..MSC00.o) vram 0x8004787C-0x80047D3C
- [0x3853C, c, libgte23] # libgte block 23 (S78): MSC01/MSC02/MSC05/MSC09 (276 ins, exact tile) vram 0x80047D3C-0x8004818C — was '800b' game code
- [0x3898C, c, libgte2] # libgte block 2: 2 obj (MTX_000.o..MTX_001.o) vram 0x8004818C-0x8004838C
- [0x38B8C, c, libgte3] # libgte block 3: 5 obj (MTX_003.o..MTX_009.o) vram 0x8004838C-0x8004880C
- [0x3900C, c, libgte4] # libgte block 4: 3 obj (MTX_00B.o..MTX_01.o) vram 0x8004880C-0x80048CAC
- [0x394AC, c, libgte5] # libgte block 5: 5 obj (MTX_02.o..MTX_08.o) vram 0x80048CAC-0x8004914C
- [0x3994C, c, libgte6] # libgte block 6: 7 obj (MTX_09.o..REG12.o) vram 0x8004914C-0x8004923C
- [0x39A3C, c, libgte7] # libgte block 7: 1 obj (REG13.o) vram 0x8004923C-0x8004924C
- [0x39A4C, c, libgte24] # libgte block 24 (S78): SMP_00.o (132 ins, exact tile) vram 0x8004924C-0x8004945C — was '800b_2'
- [0x39C5C, c, libgte8] # libgte block 8: 3 obj (SMP_01.o..SMP_03.o) vram 0x8004945C-0x800495EC
- [0x39DEC, c, libgte9] # libgte block 9 (S78 re-derived): SMP_05.o NormalClip (12 ins, byte-identical over the whole span; SMP_06 NormalClipS is its nested sub-pattern) vram 0x800495EC-0x8004961C — absorbs the old 800b_3 / 800b_4 'game code' and the 3-nop pad
- [0x39E1C, c, libgte10] # libgte block 10: 1 obj (CMB_00.o) vram 0x8004961C-0x8004969C
- [0x39E9C, c, libgte11] # libgte block 11: 2 obj (CMB_05.o..FGO_00.o) vram 0x8004969C-0x8004978C
- [0x39F8C, c, libgte25] # libgte block 25 (S78): FGO_01..FGO_06 (804 ins, exact tile) vram 0x8004978C-0x8004A41C — was '800b_5'
- [0x3AC1C, c, libgte12] # libgte block 12: 2 obj (PRS_F3.o..PRS_F4.o) vram 0x8004A41C-0x8004AE3C
- [0x3B63C, c, libgte13] # libgte block 13: 3 obj (PRS_G3.o..PRS_FT3.o) vram 0x8004AE3C-0x8004BE8C
- [0x3C68C, c, libgte14] # libgte block 14: 2 obj (PRS_FT4.o..PRS_GT3.o) vram 0x8004BE8C-0x8004C98C
- [0x3D18C, c, libgte15] # libgte block 15: 1 obj (PRS_GT4.o) vram 0x8004C98C-0x8004CFEC
- [0x3D7EC, c, libgte16] # libgte block 16: 1 obj (RATAN.o) vram 0x8004CFEC-0x8004D16C
- [0x3D96C, c, libgte26] # libgte block 26 (S78): PATCHGTE.o (40 ins, exact tile) vram 0x8004D16C-0x8004D20C — was '800b_6'
- [0x3DA0C, c, libgte17] # libgte block 17: 1 obj (TRR.o) vram 0x8004D20C-0x8004D6BC
- [0x3DEBC, c, libgte18] # libgte block 18: 2 obj (F3.o..F4.o) vram 0x8004D6BC-0x8004E19C
- [0x3E99C, c, libgte19] # libgte block 19: 1 obj (G3.o) vram 0x8004E19C-0x8004E74C
- [0x3EF4C, c, libgte20] # libgte block 20: 1 obj (G4.o) vram 0x8004E74C-0x8004EE0C
- [0x3F60C, c, libgte21] # libgte block 21: 2 obj (FT3.o..FT4.o) vram 0x8004EE0C-0x8004FA5C
- [0x4025C, c, libgte22] # libgte block 22: 2 obj (GT3.o..GT4.o) vram 0x8004FA5C-0x8005080C
- [0x4100C, c, libgs7] # libgs block 7 (S78): 2D_BG0.o + 2D_BG1.o (1022 ins, exact tile) -> src/libgs7.c (vram 0x8005080C-0x80051804) — was '800b_7' game code (§485)
- [0x42004, c, libgs1] # libgs block 1: 2D_COM0 -> src/libgs1.c (vram 0x80051804-0x80051D78, 1 obj)
- [0x42578, c, libgte27] # libgte block 27 (S78): MTX_05.o (20 ins, exact tile) vram 0x80051D78-0x80051DC8 — was gsgap1
- [0x425C8, c, libgs2] # libgs block 2: 2D_LIN0/COM1/SP0 -> src/libgs2.c (vram 0x80051DC8-0x80052430, 3 objs)
- [0x42C30, c, libgte28] # libgte block 28 (S78): MTX_07.o (12 ins, exact tile) vram 0x80052430-0x80052460 — was gsgap2
- [0x42C60, c, libgs3] # libgs block 3: 2D_SP1 -> src/libgs3.c (vram 0x80052460-0x800525DC, 1 obj)
- [0x42DDC, c, libgs8] # libgs block 8 (S78 #4): GS_001.o (384 ins, exact tile; .bss split ×6 at link-prepare, §489) -> src/libgs8.c (vram 0x800525DC-0x80052BDC) — was the 'gsgap3' stub (hand-matched as game C)
- [0x433DC, c, libgs4] # libgs block 4: GS_002/003/MATRIX/103/104/105/106/107 -> src/libgs4.c (vram 0x80052BDC-0x800538BC, 8 objs)
- [0x440BC, c, libgte29] # libgte block 29 (S78): MTX_11.o (12 ins, exact tile) vram 0x800538BC-0x800538EC — was gsgap4
- [0x440EC, c, libgs5] # libgs block 5: GS_108/109 -> src/libgs5.c (vram 0x800538EC-0x800539C8, 2 objs)
- [0x441C8, c, libgte30] # libgte block 30 (S78): REG03.o + REG11.o (76 ins, exact tile) vram 0x800539C8-0x80053AF8 — was gsgap5
- [0x442F8, c, libgs6] # libgs block 6 (16 objs) -> src/libgs6.c (vram 0x80053AF8-0x80057928)
- [0x48128, c, 800b2] # -O2 game code (post-libgs, pre-libgpu) -> src/800b2.c (vram 0x80057928-0x80058890)
# PsyQ libgpu (Phase 8; S78 #4): EXT/PRIM linked as `libgpu`; SYS.o (3109 ins) was EXCLUDED from
# Phase 8 to P31 S78 as scattered-.bss commons (cookbook §9.1, the GS_001 class: SYS references
# .bss by section+offset but the original linker scattered the commons across 0x80078xxx/
# 0x800c5xxx, so no single NOLOAD base reproduces it) and sat in `800c` as 56 hand-matched SDK
# functions + 62 verbatim frags — 100% SYS.o, the span IS the object's .text size.
# P31 S77 (cookbook §484): "no single base" is TRUE; "therefore unlinkable" is NOT —
# tools/psyq_bss_probe.py derived exactly TWO bases from the bytes with DISJOINT offset ranges
# (0x0000-0x0044 @ 0x80078830, 0x0148-0x0150 @ 0x800c53cc).
# P31 S78 #4 (cookbook §489): psyq_integrate now SPLITS such a section into per-base NOLOAD
# pieces at link-prepare (tools/psyq_bss_split.py: .bss [0,0x144) @0x80078830 + .bss2 = `_que`
# @0x800C5510), so SYS.o links byte-identical as `libgpu2`. No curated dir any more: LIBGPU_ELF is
# the raw .run/obj40/libgpu (psyq_identify drops the 8 objects the EXE does not link). The same
# split takes GS_001.o (libgs8, six pieces) and VM_F.o (snd12). 2D_BG0.o / VM_NO1.o have NO .bss
# and were wired in S78 #3.
- [0x49090, c, libgpu] # libgpu block 1 -> src/libgpu.c (vram 0x80058890-0x80059234, EXT+PRIM)
- [0x49A34, c, libgpu2] # libgpu block 2 (S78 #4): SYS.o (3109 ins, exact tile; .bss split ×2 at link-prepare, §489) -> src/libgpu2.c (vram 0x80059234-0x8005C2C8) — was '800c'
# PsyQ libc2 (Phase 8): C stdlib. Main block = 16 objs (BZERO/MEMCPY/STRCMP/PRINTF/PRNT[jtbl ok]/
# …/SETJMP); STRCAT.o is a 2nd block at 0x80061E90 (start of the old 800c2). integrate libc2_1,libc2_2.
- [0x4CAC8, c, libc2_1] # libc2 main block (16 objs) -> src/libc2_1.c (vram 0x8005C2C8-0x8005CE18);
# end = SETJMP.o's .text SECTION size (0x80, 8-aligned), NOT its 30-ins
# count (0x78) — the trailing 8-byte align pad belongs to the object.
# PsyQ LIBAPI 4.2 + LIBPAD 4.2.1 band (P31 S78 #12 named it, S79 #13 found the archive, S79 #5 wired it):
# 0x8005CE18-0x8005FC68 is ONE contiguous run of 33 Sony objects, interleaved libapi/libpad, every one
# byte-identical from tools/psyq/lib421 (SCE's 1998-02-26 "libpad.lib 4.2.1 for the DUAL SHOCK" patch,
# shipped with libapi.lib 4.2 — the EXE's 4.2 / 4.2.1x `Ps` stamps). It used to be src/800c3.c: 129
# hand-matched "C", 62 verbatim bodies and 19 stubs incl. the four §332 "%lo-in-a-delay-slot walls" —
# all of it Sony code assembled in reorder mode (§332b), none of it game code. Split into 4 rows because
# psyq_integrate tiles each stub with ONE library's objects (windows: libapi 0x8005CE18..0x8005E188,
# libpad 0x8005D0D8..0x8005FC68). Object sizes are .text SECTION sizes (exact tile, verified S79).
- [0x4D618, c, libapi1] # libapi 4.2 block 1: C57 C68 C73 C114 A07-A13 A23-A25 A36 A37 A52 A53 A91 L10 (21 trampolines) + COUNTER (92) -> src/libapi1.c (vram 0x8005CE18-0x8005D0D8)
- [0x4D8D8, c, libpad1] # libpad 4.2.1 block 1: PADENTRY (300) + PADMAIN (760) -> src/libpad1.c (vram 0x8005D0D8-0x8005E168)
- [0x4E968, c, libapi2] # libapi 4.2 block 2: L02 + L03 (SysEnqIntRP/SysDeqIntRP) -> src/libapi2.c (vram 0x8005E168-0x8005E188)
- [0x4E988, c, libpad2] # libpad 4.2.1 block 2: PADCMD (600) PADIF (376) PADPORTD (408) PADSEQD (288) WAITRC2 (48) -> src/libpad2.c (vram 0x8005E188-0x8005FC68)
# PsyQ libmcrd (Phase 8): 2 objects — LIBMCRD.o (2186 ins; the 55 LIBMCRD_OBJ_* + _card_* memcard
# I/O) and USERFUNC.o (68 ins, at the very end), 2 non-adjacent blocks split by game/libc2/libapi/
# libcard code (800c2). psyq_integrate libmcrd1,libmcrd2. (The GAME save logic / Q#5 is Phase 12.)
- [0x50468, c, libmcrd1] # libmcrd block 1: LIBMCRD.o -> src/libmcrd1.c (vram 0x8005FC68-0x80061E90)
- [0x52690, c, libc2_2] # libc2 block 2: STRCAT.o -> src/libc2_2.c (vram 0x80061E90-0x80061F38)
# PsyQ libapi+libcard COMBINED 800c2 region (Phase 8; S79 #5): BIOS syscall trampolines + card I/O,
# now 26 objects in 7 blocks tiling 0x80061F38-0x80062888 with NO game code between them (curated by
# tools/make_apicard_used.py: libapi from tools/psyq/lib421 = 4.2, the EXE's real libapi; libcard 4.0,
# byte-identical; C112.o shared, no exclusions). integrate window 0x61F38..0x62888. The three former
# "game code" rows were libapi 4.2's C objects: 800c2 = FIRST.o (168 ins, `firstfile` + the "wall"
# stub func_80062144), 800c2_2 = PAD.o (192), 800c2_3 = PATCH.o (40) + CHCLRPAD.o (28) — exact tiles.
- [0x52738, c, apicard1] # apicard block 1: 7 obj (C112.o..A69.o) vram 0x80061F38-0x80061FA8
- [0x527A8, c, apicard5] # apicard block 5 (S79 #5): FIRST.o (168 ins, exact tile) vram 0x80061FA8-0x80062248 — was '800c2'
- [0x52A48, c, apicard2] # apicard block 2: 7 obj (A66.o..INIT.o) vram 0x80062248-0x80062388
- [0x52B88, c, apicard6] # apicard block 6 (S79 #5): PAD.o (192 ins, exact tile) vram 0x80062388-0x80062688 — was '800c2_2'
- [0x52E88, c, apicard3] # apicard block 3: 4 obj (A18.o..A21.o) vram 0x80062688-0x800626C8
- [0x52EC8, c, apicard7] # apicard block 7 (S79 #5): PATCH.o (40) + CHCLRPAD.o (28), exact tile, vram 0x800626C8-0x800627D8 — was '800c2_3'
- [0x52FD8, c, apicard4] # apicard block 4: 4 obj (A74.o..END.o) vram 0x800627D8-0x80062888
- [0x53088, c, libmcrd2] # libmcrd block 2: USERFUNC.o -> src/libmcrd2.c (vram 0x80062888-0x80062998)
# Phase 7 (Task 2' / LZSS) — SURGICAL rodata carve for the LZSS switch only.
# The rodata island (0x80072A38-0x80074750) interleaves game jtbls, game data
# (loadDestPtrTable @0x80072C70 etc.) and library jtbls (PRESET/OBJT/PRNT @0x800737CC+),
# so a full-island migration is messy and hits the +24 .align-3 library artifact.
# But LZSS's jtbl_80072A38 is the FIRST jtbl (right after LzssStateTable/D_80072A34,
# right before jtbl_80072A4C), so carve ONLY it: a dotted .rodata sibling of the "800"
# code subseg covering exactly 0x63238-0x6324C migrates jtbl_80072A38 into
# asm/nonmatchings/800/LzssDecodeSector.s; everything else stays raw in the tail data.
# tools/ld_interleave.py then places .data(front) -> .rodata(LZSS jtbl) -> .data(tail).
# front data starts at 0x53198 (vram 0x80062998), NOT 0x531DC: the 68-B data descriptor
# table at 0x80062998-0x800629DC (boot.c's __do_global_dtors references D_80062998/D_800629D4)
# is data-in-text (cookbook §8). The big-800b era auto-labelled it; the libgs6 resegment made
# splat mis-detect it as func_80062998 (shadowing D_80062998). Carving it as the head of the
# front-data subseg forces the data labels deterministically. (ld_interleave FRONT_DATA matches.)
- [0x53198, data, 53198] # data table + front data (vram 0x80062998-0x80072A38)
# P31 S72 — SPAN EXTENSION. The Phase-7 carve stopped at the LZSS table because a FULL
# island migration hits the interleaved game data and the library jtbls. But the island
# opens with a CONTIGUOUS run of game tables owned entirely by subseg 800:
# 0x80072A38 jtbl (LzssDecodeSector, matched, cc1-emitted)
# 0x80072A4C A7C A94 AB4 ADC B0C B24 B3C B64 B88 BFC (11 tables, 8 stubbed owners)
# 0x80072C70 loadDestPtrTable <- first non-table datum, the span's hard end
# One code object may contribute exactly ONE contiguous .rodata run, and this whole run is
# 800.o's, in address order = src/800.c source order. So the span carves as one piece and
# the 3-piece data->rodata->data sandwich is unchanged in SHAPE, only in where it splits.
# This is what blocked every main switch function: gcc emits the drafted function's table
# into .rodata while the raw copy stayed here, so the image GREW (measured +28/+52/+76/+84
# on four drafts) and all 238 symbols above 0x80072A4C shifted. 25 of main's 59 frontier
# functions (6,215 of 12,912 instructions) are in that class.
# The island is data -> rodata -> data -> rodata -> data -> rodata -> data. Each `.rodata`
# piece is dotted onto the code subseg that OWNS those tables, so spimdisasm migrates each
# table into its referencing function and ld_interleave --order lays the pieces back down in
# address order. Span D (0x80073494-0x80073514) belongs to snd2, not to game code.
- [0x63238, .rodata, 800] # span A: LZSS jtbl + 11 game jtbls (vram 0x80072A38-0x80072C70)
- [0x63470, data, 63470] # loadDestPtrTable + globals (vram 0x80072C70-0x80072E44)
# P31 S77 — span B is now split, because the 3-way code cut for the -O0 island put its two
# jtbl owners in DIFFERENT objects (func_8002B0B4 in 800_b, func_800335B8 in 800_b_2) and
# one code object may contribute exactly ONE contiguous .rodata run. The boundary is
# DERIVED, not guessed: 800_b.o's compiled .rodata is 0xf8 bytes, so the front run ends at
# 0x80072E44+0xf8. The build's own jtbl_rodata_pads is what caught the missing piece
# ("no yaml .rodata piece is bound to TU '800_b_2' — cannot place it"). The -O0 island
# itself references no jump table, so it needs no piece.
- [0x63644, .rodata, 800_b] # span B front: func_8002B0B4's jtbls (vram 0x80072E44-0x80072F3C)
- [0x6373C, .rodata, 800_b_2] # span B tail (vram 0x80072F3C-0x80073140)
- [0x63940, data, 63940] # globals (vram 0x80073140-0x800732A0)
- [0x63AA0, .rodata, 800_c] # span C: 8 game jtbls (vram 0x800732A0-0x8007344C)
- [0x63C4C, data, 63C4C] # tail: snd2 jtbls + globals (vram 0x8007344C-0x80074800)
- [0x65000]