From 1a696a851a249de62e9db210a2d2baba35945bb6 Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Fri, 4 Sep 2026 23:49:05 -0600 Subject: [PATCH] =?UTF-8?q?feat(phase-32):=20T2b=20(1)=20=E2=80=94=20MAIN/?= =?UTF-8?q?7=20ONBOARDED=20as=20md=5FMAIN=5F007=20@0x800CEDF8=20(TEXT=5FLO?= =?UTF-8?q?=200x34),=20byte-identical=202ff702b6;=20the=20OPDEMO0=20module?= =?UTF-8?q?=20leaves=20the=20parked=20ledger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tools/new_binary.sh md_MAIN_007 extracted/retail/MAIN.CD.dir/FILE_007 0x800CEDF8 0x34 -> first build BYTE-IDENTICAL sha 2ff702b605ab5cfc18474c464c4c07e5f8ffd48c; A4 applied (symbols.resident.txt not stacked — the window lies inside the resident's symbol region), re-extract + rebuild byte-identical; 19 stubs (802 ins) - BASE EVIDENCE (memory-map §S45 p7, static-derived): STRONG — 9/9 internal jals and 14/16 absolute pointers land on the module's own function starts at 0x800CEDF8 (the boot slot of md_MAIN_001/008/011); lui 0x800C/0x800D - HONEST CAVEAT (R34, measured 2026-09-05): the all-INCLUDE_ASM first build is a NULL oracle for FINE base errors — the same payload builds byte-identical at 0x800CEE00 (+8) — and catches only GROSS ones (at +0x1000 two internal jal targets leave the window: `undefined reference to func_800CEEA4/func_800CF3F4`, link fails). The base therefore rests on the static alignment, and will be byte-proven by the first C bank that calls an internal sibling. Controls: .run/P32/t2b/{control_full,control_fine}.log - registered in modules.mk + the report/diff dicts (R36 citizenship asserted by tools-health at T2c) --- config/check.md_MAIN_007.sha | 1 + config/modules.mk | 23 +++++++- config/splat.md_MAIN_007.yaml | 105 +++++++++++++++++++++++++++++++++ config/symbols.md_MAIN_007.txt | 3 + diff_settings.py | 3 + src/md_MAIN_007/md_MAIN_007.c | 41 +++++++++++++ tools/dup_report.py | 1 + tools/progress.py | 2 + 8 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 config/check.md_MAIN_007.sha create mode 100644 config/splat.md_MAIN_007.yaml create mode 100644 config/symbols.md_MAIN_007.txt create mode 100644 src/md_MAIN_007/md_MAIN_007.c diff --git a/config/check.md_MAIN_007.sha b/config/check.md_MAIN_007.sha new file mode 100644 index 000000000..d104ec029 --- /dev/null +++ b/config/check.md_MAIN_007.sha @@ -0,0 +1 @@ +2ff702b605ab5cfc18474c464c4c07e5f8ffd48c md_MAIN_007 diff --git a/config/modules.mk b/config/modules.mk index f3db523a0..e5bccea35 100644 --- a/config/modules.mk +++ b/config/modules.mk @@ -3,7 +3,7 @@ # absent); the hand-maintained Makefile body is never edited to add a binary. Each md_* loads at # its OWN vram (the §S44 loader table: docs/memory-map.md). _TEXT_LO is a VRAM (code start), read # by 'make sig-modules' as --text-lo (§154-A: bootstrap past the module-id header). -MODULE_BINARIES := md_MAIN_013 md_MAIN_014 md_MAIN_015 md_MAIN_016 md_MAIN_017 md_MAIN_018 md_MAIN_019 md_MAIN_020 md_MAIN_021 md_MAIN_022 md_MAIN_023 md_MAIN_024 md_MAIN_025 md_MAIN_026 md_MAIN_027 md_MAIN_028 md_MAIN_029 md_MAIN_030 md_MAIN_031 md_MAIN_032 md_MAIN_033 md_MAIN_034 md_MAIN_035 md_MAIN_036 md_MAIN_037 md_MAIN_038 md_MAIN_039 md_MAIN_040 md_MAIN_041 md_MAIN_042 md_MAIN_043 md_MAIN_044 md_MAIN_045 md_MAIN_046 md_MAIN_047 md_MAIN_001 md_MAIN_008 md_MAIN_011 md_SC07_003 md_SC07_004 md_MAIN_003 md_SC03_073 md_SC03_074 md_SC03_075 md_SC03_076 md_SC03_077 md_SC03_078 md_SC03_079 md_SC03_132 md_SC03_133 md_SC03_134 md_SC03_135 md_SC03_136 md_SC03_137 md_SC03_138 md_SC04_024 md_SC04_025 md_SC04_026 md_SC04_027 md_SC04_028 md_SC04_029 md_SC04_030 md_SC05_023 md_SC05_024 md_SC05_025 md_SC05_026 md_SC05_027 md_SC05_028 md_SC05_029 md_SC02_009 +MODULE_BINARIES := md_MAIN_013 md_MAIN_014 md_MAIN_015 md_MAIN_016 md_MAIN_017 md_MAIN_018 md_MAIN_019 md_MAIN_020 md_MAIN_021 md_MAIN_022 md_MAIN_023 md_MAIN_024 md_MAIN_025 md_MAIN_026 md_MAIN_027 md_MAIN_028 md_MAIN_029 md_MAIN_030 md_MAIN_031 md_MAIN_032 md_MAIN_033 md_MAIN_034 md_MAIN_035 md_MAIN_036 md_MAIN_037 md_MAIN_038 md_MAIN_039 md_MAIN_040 md_MAIN_041 md_MAIN_042 md_MAIN_043 md_MAIN_044 md_MAIN_045 md_MAIN_046 md_MAIN_047 md_MAIN_001 md_MAIN_008 md_MAIN_011 md_SC07_003 md_SC07_004 md_MAIN_003 md_SC03_073 md_SC03_074 md_SC03_075 md_SC03_076 md_SC03_077 md_SC03_078 md_SC03_079 md_SC03_132 md_SC03_133 md_SC03_134 md_SC03_135 md_SC03_136 md_SC03_137 md_SC03_138 md_SC04_024 md_SC04_025 md_SC04_026 md_SC04_027 md_SC04_028 md_SC04_029 md_SC04_030 md_SC05_023 md_SC05_024 md_SC05_025 md_SC05_026 md_SC05_027 md_SC05_028 md_SC05_029 md_SC02_009 md_MAIN_007 # --- md_MAIN_013 (module, vram 0x800CAE08 — onboarded by new_binary.sh) --- md_MAIN_013_EXE := extracted/retail/MAIN.CD.dir/FILE_013.dir/1.1 @@ -1475,3 +1475,24 @@ md_SC02_009_SRC_DIR := src/md_SC02_009 md_SC02_009_UNDEF_SYMS := build/md_SC02_009/undefined_syms_auto.txt md_SC02_009_UNDEF_FUNCS := build/md_SC02_009/undefined_funcs_auto.txt + +# --- md_MAIN_007 (module, vram 0x800CEDF8 — onboarded by new_binary.sh) --- +md_MAIN_007_EXE := extracted/retail/MAIN.CD.dir/FILE_007 +md_MAIN_007_NAME := md_MAIN_007 +md_MAIN_007_OUT_DIR := build/md_MAIN_007 +md_MAIN_007_OUT := $(md_MAIN_007_OUT_DIR)/$(md_MAIN_007_NAME) +md_MAIN_007_ELF := $(md_MAIN_007_OUT).elf +md_MAIN_007_MAPFILE := $(md_MAIN_007_OUT).map +md_MAIN_007_LD_SCRIPT := $(md_MAIN_007_OUT).ld +md_MAIN_007_SPLAT_YAML := config/splat.md_MAIN_007.yaml +md_MAIN_007_CHECK_SHA := config/check.md_MAIN_007.sha +md_MAIN_007_SYMBOLS := config/symbols.md_MAIN_007.txt +md_MAIN_007_SIG := .run/sig.md_MAIN_007.jsonl +md_MAIN_007_GHIDRA_PROG := md_MAIN_007 +md_MAIN_007_VRAM_BASE := 0x800CEDF8 +md_MAIN_007_TEXT_LO := 0x800CEE2C +md_MAIN_007_TEXT_HI := 0x800D1378 +md_MAIN_007_ASM_DIR := asm/md_MAIN_007 +md_MAIN_007_SRC_DIR := src/md_MAIN_007 +md_MAIN_007_UNDEF_SYMS := build/md_MAIN_007/undefined_syms_auto.txt +md_MAIN_007_UNDEF_FUNCS := build/md_MAIN_007/undefined_funcs_auto.txt diff --git a/config/splat.md_MAIN_007.yaml b/config/splat.md_MAIN_007.yaml new file mode 100644 index 000000000..ccefb8a4b --- /dev/null +++ b/config/splat.md_MAIN_007.yaml @@ -0,0 +1,105 @@ +# splat config TEMPLATE — Brave Fencer Musashi location overlays (SCxx.CD/FILE_nnn/0.4.dec) +# ============================================================================= +# Phase 13: the reusable flat-blob splat config for a LOCATION OVERLAY. ~134 overlays +# all stream into the SAME RAM slot (vram 0x80128158) and chain into the resident engine +# (0x800CEDF8) + the EXE. This is a TEMPLATE: the @TOKEN@ placeholders are substituted to +# produce config/splat..yaml — by tools/new_overlay.sh (Phase 13 T4), or by hand +# (Phase 13 T1a for the first overlay). It is NOT a valid splat config until instantiated. +# +# Placeholders: +# md_MAIN_007 binary alias, ov__ e.g. ov_SC01_077 +# extracted/retail/MAIN.CD.dir/FILE_007 extracted 0.4.dec payload path e.g. extracted/retail/SC01.CD.dir/FILE_077.dir/0.4.dec +# 2ff702b605ab5cfc18474c464c4c07e5f8ffd48c sha1 of the 0.4.dec (the build-identity target; also -> config/check..sha) +# 0x800CEDF8 load vram (the shared overlay slot) e.g. 0x80128158 (constant across overlays today; +# parameterized so a future non-0x80128158 overlay needs no template edit) +# 0xCBC file offset where code ends -> data tail begins (iterated vs the byte check, T1b) +# 0x2580 file size in bytes (the EOF marker; = the 0.4.dec length) +# +# Modeled on config/splat.resident.yaml (the Phase-10 flat-blob recipe), with overlays' +# differences: (1) code at file offset 0x0 (overlays open with a function prologue, NOT a +# leading data word like the resident — so NO leading-rodata trick by default; see the +# commented `head` slot for the rare pre-code-data overlay); (2) symbol_addrs_path ALSO +# stacks config/symbols.resident.txt because overlays reference resident engine globals; +# (3) vram is the overlay slot. Everything else matches the resident options verbatim. +# +# Byte-match is robust to the exact text/data split (splat round-trips the bytes — the +# resident precedent); iterate 0xCBC against `make check BINARY=md_MAIN_007` (Phase-5/10 +# precedent). LZSS is NOT in the verify path — we match the DECOMPRESSED 0.4.dec (repack is Gen3). +name: md_MAIN_007 +sha1: 2ff702b605ab5cfc18474c464c4c07e5f8ffd48c +options: + basename: md_MAIN_007 + target_path: extracted/retail/MAIN.CD.dir/FILE_007 + elf_path: build/md_MAIN_007/md_MAIN_007.elf + # base_path is resolved relative to THIS yaml's dir (config/), so `..` = repo root + base_path: .. + platform: psx + compiler: PSYQ + + asm_path: asm/md_MAIN_007 + src_path: src/md_MAIN_007 + # asset_path scoped per-alias so a `bin` subseg (the trailing-partial-word carve, below) lands at + # assets/md_MAIN_007/*.bin and never collides with another overlay's same-named asset. The Makefile's + # build/assets/%.o rule incbin's it into a linkable object. + asset_path: assets/md_MAIN_007 + # build_path = build (NOT build/): splat writes the .ld's object paths under + # $(build_path), and the Makefile's pattern rules build them at build/asm/** + build/src/**. + # Only the elf/ld/output live in build//. + build_path: build + ld_script_path: build/md_MAIN_007/md_MAIN_007.ld + ld_dependencies: True + + # Per-binary undefined-symbol outputs (under build//), so `make clean`'s `rm -rf build` + # covers them and binaries never share a stale file. + undefined_syms_auto_path: build/md_MAIN_007/undefined_syms_auto.txt + undefined_funcs_auto_path: build/md_MAIN_007/undefined_funcs_auto.txt + + find_file_boundaries: False + # NO gp_value: overlays are -G0 (verify zero ($gp)/%gp_rel in the disasm). Omitting it -> no _gp. + + o_as_suffix: True + use_legacy_include_asm: False + + section_order: [".rodata", ".text", ".data", ".bss"] + + # Stacked symbols: shared engine globals (symbols.us.txt) + resident engine globals the overlay + # calls (symbols.resident.txt) + the overlay-local names/boundaries (symbols..txt, seeded + # T1c from sig_image + duplicates.cross.md; R13/R15-tagged, overlay-region only). + # A4 symbol-window law (SETUP §6.7): this module's window (0x800CEDF8..0x800D1378) lies INSIDE the resident's + # symbol region, so config/symbols.resident.txt is NOT stacked (a resident name inside the window would mint a + # phantom function boundary — DsMix @0x800D1BD8 did exactly that to md_MAIN_011 before this rule). + symbol_addrs_path: + - config/symbols.us.txt + - config/symbols.md_MAIN_007.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 in c-mode (unused for the EXE/resident): + # include_asm_macro_style: maspsx_hack + +segments: + - name: md_MAIN_007 + type: code + start: 0x0 + vram: 0x800CEDF8 + # align 4 (not the code default 16): MIPS is word-aligned; mirrors the EXE/resident choice. + align: 4 + subsegments: + # OPTIONAL leading pre-code data/rodata island (rare): if an overlay begins with a data + # word BEFORE its first function (the resident's case), uncomment a `head` subseg here and + # shift the code start. Mark it `rodata` (section_order places .rodata first) so it lands at + # 0x800CEDF8 ahead of the code, a 1-word analogue of main's rodata-island (no ld_interleave). + # - [0x0, rodata, head] + - [0x0, .rodata, md_MAIN_007] # module-id header (+jtbl/ptr table) — §154-A + - [0x34, c, md_MAIN_007] + - [0xCBC, data, tail] # data tail: pointer tables + packed data (split iterated) + - [0x2580] # EOF marker = the 0.4.dec byte length +# @TRAILING@ (above) is replaced by tools/new_overlay.sh: for a non-4-aligned overlay it becomes +# ` - [0x, bin, trailing]` (the final 1-3 bytes spimdisasm's data path drops); +# for a 4-aligned overlay the marker line is removed. The Makefile build/assets/%.o rule + the +# objcopy end-align TRIM finish the job. Hand-instantiated configs (ov_SC01_077) inline the carve. diff --git a/config/symbols.md_MAIN_007.txt b/config/symbols.md_MAIN_007.txt new file mode 100644 index 000000000..8ebfffa62 --- /dev/null +++ b/config/symbols.md_MAIN_007.txt @@ -0,0 +1,3 @@ +// config/symbols.md_MAIN_007.txt — module md_MAIN_007 local symbols +// R13/R15: this binary's REGION ONLY (vram 0x800CEDF8..0x800D1378); NEVER merged into config/symbols.us.txt. +// count=0 diff --git a/diff_settings.py b/diff_settings.py index 412df0737..e7ee228eb 100644 --- a/diff_settings.py +++ b/diff_settings.py @@ -653,6 +653,9 @@ BINARIES = { "md_SC02_009": dict(baseimg="expected/build/md_SC02_009/md_SC02_009.elf", myimg="build/md_SC02_009/md_SC02_009.elf", mapfile="build/md_SC02_009/md_SC02_009.map"), + "md_MAIN_007": dict(baseimg="expected/build/md_MAIN_007/md_MAIN_007.elf", + myimg="build/md_MAIN_007/md_MAIN_007.elf", + mapfile="build/md_MAIN_007/md_MAIN_007.map"), # <<< overlays: tools/new_overlay.sh inserts ov_* entries above this line (Phase 13) >>> } diff --git a/src/md_MAIN_007/md_MAIN_007.c b/src/md_MAIN_007/md_MAIN_007.c new file mode 100644 index 000000000..03b7fc573 --- /dev/null +++ b/src/md_MAIN_007/md_MAIN_007.c @@ -0,0 +1,41 @@ +#include "common.h" + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CEE2C); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CEEFC); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CEF60); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CEF94); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CEFF8); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF02C); + +INCLUDE_RODATA("asm/md_MAIN_007/nonmatchings/md_MAIN_007", D_800CEDF8); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF068); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF0B8); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF0F4); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF148); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF1CC); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF220); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF268); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF2BC); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF33C); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF390); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF3B0); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF408); + +INCLUDE_ASM("asm/md_MAIN_007/nonmatchings/md_MAIN_007", func_800CF6D0); diff --git a/tools/dup_report.py b/tools/dup_report.py index 9646f262d..e067fb91a 100644 --- a/tools/dup_report.py +++ b/tools/dup_report.py @@ -237,6 +237,7 @@ BINARIES = { "md_SC05_028": dict(sig=".run/sig.md_SC05_028.jsonl", md="docs/duplicates.md_SC05_028.md"), "md_SC05_029": dict(sig=".run/sig.md_SC05_029.jsonl", md="docs/duplicates.md_SC05_029.md"), "md_SC02_009": dict(sig=".run/sig.md_SC02_009.jsonl", md="docs/duplicates.md_SC02_009.md"), + "md_MAIN_007": dict(sig=".run/sig.md_MAIN_007.jsonl", md="docs/duplicates.md_MAIN_007.md"), # <<< overlays: tools/new_overlay.sh inserts ov_* entries above this line (Phase 13) >>> } CROSS_MD = "docs/duplicates.cross.md" diff --git a/tools/progress.py b/tools/progress.py index 4bce52326..df5172708 100644 --- a/tools/progress.py +++ b/tools/progress.py @@ -447,6 +447,8 @@ BINARIES = { src="src/md_SC05_029", asm="asm/md_SC05_029/nonmatchings", out="docs/progress.md_SC05_029.md"), "md_SC02_009": dict(build="build/md_SC02_009/md_SC02_009", check="config/check.md_SC02_009.sha", src="src/md_SC02_009", asm="asm/md_SC02_009/nonmatchings", out="docs/progress.md_SC02_009.md"), + "md_MAIN_007": dict(build="build/md_MAIN_007/md_MAIN_007", check="config/check.md_MAIN_007.sha", + src="src/md_MAIN_007", asm="asm/md_MAIN_007/nonmatchings", out="docs/progress.md_MAIN_007.md"), # <<< overlays: tools/new_overlay.sh inserts ov_* entries above this line (Phase 13) >>> } MAKEFILE = ROOT / "Makefile"