# 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 ` # (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) - [0x2BF0, c, 800] # -O2 game code -> src/800.c (vram 0x800123F0-0x8003A444); name "800" kept (legacy) so the matched fns + their asm/nonmatchings/800 paths don't migrate # PsyQ libspu+libsnd COMBINED sound region (Phase 8): the two SDK sound libs are interleaved here, # so they link as one 60-object region (curated by tools/make_snd_used.py; 4 addresses excluded as # scattered-.bss/false-positive stubs: S_R/S_W 0x3C438, S_GRMDT* 0x3D424, S_IH/UT_RON 0x3D94C, # VM_F 0x3FA64). Subsegs via gen_lib_subsegs.py; integrate window 0x3A444..0x4239C. snd1..snd9 link; # sgap* = game code + the 4 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 + excluded VM_F stub (vram 0x8003FA54-0x8003FE18) - [0x30618, c, snd7] # snd block 7: 5 obj (S_SNV.o..VM_N2P.o) vram 0x8003FE18-0x800403A4 - [0x30BA4, c, sgap_7] # game code (vram 0x800403A4-0x80040868) - [0x31068, c, snd8] # snd block 8: 1 obj (VM_NOWOF.o) vram 0x80040868-0x80040938 - [0x31138, c, sgap_8] # game code (vram 0x80040938-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): 31 libgs objects in 6 contiguous blocks # across vram 0x80051804-0x80057928, separated by 5 non-libgs gaps. psyq_integrate swaps each # block stub's build/src/libgsN.o(.text) for the real objects + NOLOAD data (same mechanism as # libcd). The 5 gaps stay asm stubs (gsgapN): 80 / 48 / 1536[GS_001] / 48 / 304 B. GS_001 is # EXCLUDED (scattered-.bss hard case, cookbook §9.1) and stays a stub (gsgap3). GS_106 (block 4) # is an 8-ins object that only anchors uniquely within the libgs window, so make extract passes # 0x80051804 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, 800b] # game code (vram 0x80047D3C-0x8004818C) - [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, 800b_2] # game code (vram 0x8004924C-0x8004945C) - [0x39C5C, c, libgte8] # libgte block 8: 3 obj (SMP_01.o..SMP_03.o) vram 0x8004945C-0x800495EC - [0x39DEC, c, 800b_3] # game code (vram 0x800495EC-0x80049600) - [0x39E00, c, libgte9] # libgte block 9: 1 obj (SMP_06.o) vram 0x80049600-0x80049610 - [0x39E10, c, 800b_4] # game code (vram 0x80049610-0x8004961C) - [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, 800b_5] # game code (vram 0x8004978C-0x8004A41C) - [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, 800b_6] # game code (vram 0x8004D16C-0x8004D20C) - [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, 800b_7] # game code (vram 0x8005080C-0x80051804) - [0x42004, c, libgs1] # libgs block 1: 2D_COM0 -> src/libgs1.c (vram 0x80051804-0x80051D78, 1 obj) - [0x42578, c, gsgap1] # gap 80 B (non-libgs stub) -> src/gsgap1.c (vram 0x80051D78-0x80051DC8) - [0x425C8, c, libgs2] # libgs block 2: 2D_LIN0/COM1/SP0 -> src/libgs2.c (vram 0x80051DC8-0x80052430, 3 objs) - [0x42C30, c, gsgap2] # gap 48 B (non-libgs stub) -> src/gsgap2.c (vram 0x80052430-0x80052460) - [0x42C60, c, libgs3] # libgs block 3: 2D_SP1 -> src/libgs3.c (vram 0x80052460-0x800525DC, 1 obj) - [0x42DDC, c, gsgap3] # gap 1536 B: GS_001 excluded -> src/gsgap3.c (vram 0x800525DC-0x80052BDC) - [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, gsgap4] # gap 48 B (non-libgs stub) -> src/gsgap4.c (vram 0x800538BC-0x800538EC) - [0x440EC, c, libgs5] # libgs block 5: GS_108/109 -> src/libgs5.c (vram 0x800538EC-0x800539C8, 2 objs) - [0x441C8, c, gsgap5] # gap 304 B (non-libgs stub) -> src/gsgap5.c (vram 0x800539C8-0x80053AF8) - [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): EXT/PRIM linked; SYS.o EXCLUDED — 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). SYS stays a stub # in 800c. Curated dir .run/obj40/libgpu_used = {EXT,PRIM}. - [0x49090, c, libgpu] # libgpu block -> src/libgpu.c (vram 0x80058890-0x80059234, EXT+PRIM) - [0x49A34, c, 800c] # -O2 game code (incl. excluded libgpu SYS stub) -> src/800c.c (vram 0x80059234-0x8005C2C8) # 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. - [0x4D618, c, 800c3] # -O2 game code -> src/800c3.c (vram 0x8005CE18-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): BIOS syscall trampolines + card I/O, # 22 objects in 4 blocks (curated by tools/make_apicard_used.py; C112.o shared, no exclusions). # integrate window 0x61F38..0x62888. (libapi's ~22 objects in the 800c3 region are DEFERRED.) - [0x52738, c, apicard1] # apicard block 1: 7 obj (C112.o..A69.o) vram 0x80061F38-0x80061FA8 - [0x527A8, c, 800c2] # game code (vram 0x80061FA8-0x80062248) - [0x52A48, c, apicard2] # apicard block 2: 7 obj (A66.o..INIT.o) vram 0x80062248-0x80062388 - [0x52B88, c, 800c2_2] # game code (vram 0x80062388-0x80062688) - [0x52E88, c, apicard3] # apicard block 3: 4 obj (A18.o..A21.o) vram 0x80062688-0x800626C8 - [0x52EC8, c, 800c2_3] # game code (vram 0x800626C8-0x800627D8) - [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) - [0x63238, .rodata, 800] # LZSS jtbl_80072A38 ONLY (vram 0x80072A38-0x80072A4C) -> migrates into LzssDecodeSector - [0x6324C, data, 6324C] # tail data: rest of island (raw) + globals (vram 0x80072A4C-0x80074800) - [0x65000]