Commit Graph

20 Commits

Author SHA1 Message Date
Drew T a30b80b600 docs(phase-33): E2 — docs/outreach/archipelago.md: the Archipelago note with the decomp's answers to the BFM AP world's data (dow byte 0x80078EBA CONFIRMED via func_8014B084 — our dayCounter row corrected u8->u16 and 'dow not yet separable' resolved; their patch sites + Time-Sanity hook resolved to shared engine functions by a 141-image sig scan; the town-ID patch retired as historic; memory-map Q#13 ANSWERED: BASLUS-00726MUSASHI at 0x80072DFC in EXE .data, the client's 0x072e02 fallback is +4 off); GitHub-issue text + Discord short form, plain style, SEND AFTER THE FLIP; SETUP row + E2 section; doc_links default; log + checkpoint (36 of 41: nothing left for Claude before the flip) 2026-09-07 13:29:48 -06:00
Drew T d379537322 docs(phase-33): B6 dumps — dumps/CHECKSUMS.sha1 (28 rows, --check 28/28) committed before the .bin leave git; INDEX.md status rewritten (LOCAL-ONLY from the flip, archive repo holds the copy, a re-capture is a new snapshot never byte-identical); memory-map Source-index row for the corpus; checkpoint -> NEXT = B7 2026-09-06 20:33:29 -06:00
Drew T 1e843c607a feat(phase-32): T2b (4) — SC03/56 ONBOARDED as md_SC03_056 @0x801CBB50 (ov_SC03_002's DESTPTR), byte-identical bc768a6b; ALL FIVE parked payloads are now binaries (fleet 213 -> 218); evidence tool v2
- md_SC03_056 (TEXT_LO 0x4, 4 stubs / 61 ins): 15/17 pointers cluster inside at 0x801CBB50; one outward call
  (0x8018151C) hits a function only 3 overlays have, ov_SC03_002 among them; req_fit 9/9 for ov_SC03_002
- payload_base_evidence.py v2 (controls 7/7 throughout): (a) STRONG = internal jals + fn-ptr-table entries on the
  module's own starts >= 2 (SC03/53 STRONG); (b) OUTWARD-EXPLAINED — a pure jal-vote base whose "internal" targets
  are function starts of the fleet's overlays is downgraded: SC03/56's 0x80178C8C was two SHARED-engine functions
  spaced like two of its five starts (and nobody's DESTPTR), a false STRONG; (c) the requester cross-check is
  informational only — shared engine code makes every requester fit (an R39 control caught it scoring: 6/7)
- memory-map §S45 p7 amended: all five rows ONBOARDED + the two instrument findings (the first build is a NULL
  oracle for FINE base errors — +8 builds byte-identical, +0x1000 fails the link; outward-explained vote bases);
  SETUP row amended. The parked-for-L3 ledger is EMPTY pending `make audit-disc` (T2c).
2026-09-04 23:52:58 -06:00
Drew T 848c7c50ab feat(phase-32): T2a — tools/payload_base_evidence.py (controls-gated static base evidence) + memory-map §S45 p7: the parked five get candidate bases
- the instrument: module-id word, TEXT_LO estimate, absolute-pointer set, lui hi-half histogram, and a
  jal->function-start VOTE (starts = prologues ∪ the word after every `jr $ra`+delay — leaf functions have no
  prologue, the recall killer of S45's vote_base 4/12); scores a BOUNDED candidate list (5 §S44 slots ∪ 134
  IDXTAB DESTPTRs ∪ vote bases): STRONG / CONSISTENT / INCONSISTENT / NO-EVIDENCE; AMBIGUOUS tie sets are
  printed, never picked; a payload with no self-reference is REFUSED as base-independent (R43)
- R39 controls run before any emission: md_MAIN_008/011/013/042, md_SC03_073, md_SC02_009, md_SC07_004
  re-derive their byte-proven bases top-ranked from their payloads alone (7/7); TEXT_LO estimates == yaml
  (incl. the header-table modules 0x7C/0x14/0x158). The first draft of the scorer FAILED 5/7 (prologue-only
  starts; a top-rank assertion on modules the bytes cannot discriminate) — fixed by the controls, not shipped
- the five (G5 static-derived, US): MAIN/7 STRONG 0x800CEDF8 (9/9 jals, 14/16 ptrs on starts); MAIN/9 STRONG
  0x800CD348 (6/6, 9/9); SC03/53 + SC03/54 CONSISTENT with 0x801EF468 top of a 12-way tie; SC03/56 SPLIT
  (jal vote 0x80178C8C vs pointers/lui ~0x801CBB50). T2b probes each with new_binary.sh — the byte gate decides
- SETUP row (R21); evidence rows .run/P32/t2a/evidence.json
2026-09-04 23:42:53 -06:00
Drew T 78ef96f606 docs: cookbook §426/§434, memory-map extent, Makefile overlay comment
* §426 listed three localizer verdicts; there are four, and the missing TABLE REJECT is
  the dominant residual on main's switch functions (§433). Its span-B table also still
  advertised SaveLoadRoutine as an unlockable owner — it is the §434 frame pair.
* §434 quoted SaveLoadRoutine at 1139 instructions; the .s has 1165.
* docs/memory-map.md:309 recorded saveHeaderTemplate @0x80072DF0 with 'handler code ptrs
  @+0x54' at the ledger's HIGHEST confidence. 0x80072DF0+0x54 = 0x80072E44, which is
  jtbl_80072E44 — func_8002B0B4's dispatch table and the first 12 bytes of the S72 span-B
  carve. The row's extent is wrong past +0x54 and now says so; a 'verified' row that
  overlaps a carve boundary is how a future resegmentation gets talked out of itself.
* Makefile's overlay --front/--tail comment sat directly under main's --order call with
  nothing distinguishing them; now says which is which.
2026-09-02 17:17:07 -06:00
Drew T 9351b17f48 feat(phase-30 S46-2): the master IDXTAB/DESTPTR load map — and the tracker blind spot that hid it
Drew's S45 idea, delivered fleet-wide + wired into the permanent references.

- THE BLOCKER WAS OUR INSTRUMENT (R35, the 3rd time): the S45 plan ("require a
  register-verified reference to the run's address") returns ZERO for both byte-proved
  tables. They are read by gcc's indexed global-array form —
      lui $at,0x8019 ; addu $at,$at,$a0 ; lh $v0,-0x2844($at)  -> 0x8018D7BC
  — where the address exists only as (lui imm, LOAD offset) with the index add between.
  find_addr_refs killed the lui register at the addu, so the halves never rejoined and
  the tables looked unreachable. Now it carries the hi half through the index add (still
  strictly register-tracked, never window-paired) and labels those hits `-indexed`.
- tools/idxtab_map.py (NEW): fleet-wide payload -> owning binary -> load address.
  Controls-gated (refuses to emit unless ov_SC01_000 0x8017EEC8/37 + *0x801A3234, and
  ov_SC03_001 0x8018D7BC/5 + *0x801EBC68 reproduce from the images alone). Index space
  DERIVED from the extracted tree (reproduces §S44's table independently). Process-pooled.
  Rejects all-zero and majority-zero runs (132 of the first pass's 452 "tables" were that).
- RESULT: 213 binaries -> 143 with a referenced table (294), 141 with a DESTPTR (141/141
  resolved from the binary's OWN image), 61 payloads. The two dominant tables are
  fleet-wide CONSTANTS (5-entry and 37-entry, identical in all 141 overlays); the
  per-binary variable is the destination (134 distinct).
- CORRECTION 1 (R14): §S45 p6's "the SC03 trio are owned by ov_SC03_001" is refuted —
  that 5-entry table is identical in ALL 141 overlays. The byte-observed parts stand.
- CORRECTION 2 (P9): this route CANNOT settle MAIN/7+9. They are absent from all 294
  tables — but so are MAIN/13/20/34/42/44, which are byte-proved to load. Absence here
  means "not on this route", nothing more. Recorded so it is not re-derived as a finding.
- Confidence is stated per-claim in docs/idxtab-map.md: proven (controls) / high (283
  fleet-wide-class tables) / low (3 named rare rows) / UNMEASURED (recall — no oracle
  for "all tables" exists beyond the 2 controls).
- Wired in permanently: docs/idxtab-map.md (the how/when/limits), memory-map.md §S46,
  cookbook §155c (the generalizable law: "no code references X" is a claim about your
  DECODER until it is shown to recognise the forms the compiler emits), SETUP.md
  tooling inventory (R21).
2026-08-07 22:09:05 -06:00
Drew T 537bd90a9a feat(phase-30 S45p6): SOLVED — the SC03 trio are ov_SC03_001's script modules (static decode)
Found the IDXTAB: ov_SC03_001 @0x8018D7BC holds 5 s16 entries, -1 terminated:
224, 231, 232, 234, 233 — i.e. the ENTIRE parked trio (SC03/53/54/56) plus its DATA
companion (SC03/55 = 233), in one table, in the binary whose *DESTPTR points at the
script-module slot the tracer watched load live an hour earlier.

THE CHAIN (every link register-verified or byte-observed):
  ov_SC03_001 IDXTAB @0x8018D7BC  -> indices 231/232/234 (+233 data, +224)
  func_80128CFC (the S44 wrapper) -> cdFileLocTable[idx] -> {loc,size}
      register-tracked: addiu->0x800AE830, lw[0x800AE834] size, lw[0x800AE830] loc
  *DESTPTR @0x801EBC68 = 0x801EF468 -> the script slot
      the ONLY occurrence of that word fleet-wide; read 8x by code, 2x from inside func_80128CFC
  slot confirmed LIVE by tools/cdtrace.py: SC03/76 and SC03/34 both loaded there
  and 0x801EF468 lies inside SC03/54's independently-derived base window [0x801EDED0..0x801EF6C8]

VERDICT: LIVE script modules owned by ov_SC03_001. Not dead code, not boss-gated, not
chapter-gated (that framing retired — scripts swap per SCENE). Every sweep missed them
because the SC03 scenes we visited run DIFFERENT overlays (124/125/051).

WHY THE EARLIER HUNTS COULD NOT WORK: the index never appears in CODE — it lives in a
per-overlay DATA table, and so does the destination. Both invisible to fleet-wide code
scans. That is the structural reason four value-scans and three payload-side oracles failed.

NOT PROVED: the exact load BASE within the slot (the three differ in size; none observed
loading). The byte-gate arbitrates — onboard at 0x801EF468 and let the first build decide.

New tool: tools/find_addr_refs.py — register-tracked absolute-address search (cookbook 155:
no window-pairing), self-tested against cdFileLocTable, with a STRICT addu-index rule
(full-address match, not page match — 342 loose hits -> 7 real ones).

METHOD: a runtime observation supplied ONE constant, and that made a previously-impossible
static decode trivial. Neither alone sufficed. Pair the oracles, don't choose between them.
2026-08-07 20:41:18 -06:00
Drew T de02dc750c feat(phase-30 S45p6): tools/cdtrace.py — a runtime CD-load oracle; 7 routing-table addresses confirmed live
Three static oracles failed to derive the parked payloads' load addresses this session. The
runtime answer needed NO breakpoints, no Lua (no pcsx.lua wedge hazard) and no GDB stub: the
loader mirrors its whole request in RAM (cdReq_curSector / cdReq_dest), and CdReadRequest's
own MATCHED signature says cdlFile points INTO cdFileLocTable -- so (ptr-0x800AE830)/8 is the
global file index and cdReq_dest is the destination. Both readable from the RAM-dump API we
already had working.

VALIDATED FIRST (R35): cdFileLocTable's live sizes reproduce our extractor's file sizes exactly
for all five parked payloads. Then confirmed 7x against independently byte-proved addresses --
loadDestPtrTable slots [0]/[1]/[3], MAIN/10 (Phase-3 resident), MAIN/3 (S45-p2 md_MAIN_003),
MAIN/12 (the resident's func_800CF94C row), and the LIST.CD bootstrap read from matched C.
This is the R34 second oracle for the whole S44 routing table, which was static-only until now.

FINDING: the script-module slot 0x801EF468 is live and GENERAL. SC03/76 AND SC03/34 both load
there; 34 is outside the SC03/73-79 block, so S45's "chapter-2 period" label described one
tenant, not the slot -- scripts swap PER SCENE.

PRE-REGISTERED HYPOTHESIS (written before the test, kept honest): slot CONFIRMED (it lies inside
SC03/54's independently-derived base window); "chapter-gated" WEAKENED (per-scene, not per-chapter);
trio 0 sightings across 38 load events, 2 saves, multiple SC03 scenes.

NEXT (static, no emulator): 0x801EF468 is now a concrete anchor. Register-track the code that
loads into it and decode its scene->script-index SELECTOR -- answers all three at once instead
of sweeping rooms. The correctly-scoped successor to the four refuted value-scans.

Also lands the attract-cycle load map (.run/attract_loadmap.jsonl): MAIN/7 + MAIN/9 absent
across a complete 304s cycle.
2026-08-07 20:36:04 -06:00
Drew T 0499c1ec88 docs(phase-30 S45 p5): exclusion proof needs a consumer-side instrument; 4th value-scan refuted
- exclusion_proof.py tried the proven S44 {u32 idx,u32 param} table shape; its R32
  control FAILED (neither known resident table re-found) -> output void per R35.
- STANDING VERDICT: no value/shape-based scan can establish the exclusion. Small
  indices (7,9) are indistinguishable from ordinary data; 4/4 attempts refuted.
  Do not attempt a 5th (cookbook 155a).
- The sound instrument is CONSUMER-side: enumerate every register-tracked reference
  to cdFileLocTable across all 213 binaries, resolve each index source, collect the
  reachable index set. Bounded, but real work.
- Partial: the discriminating indices 231/234 appear in no pair-shaped table fleet-wide.
2026-08-07 16:08:08 -06:00
Drew T 0bd334c30d docs(phase-30 S45 p5): MAIN/7+9 identified as the OPDEMO modules; 3 base oracles refuted; the event-module region is runtime-allocated
- MAIN/7 (id 0x3A) and MAIN/9 (id 0x2D) carry 'C:\TIMPACK\OPDEMO0.PAT' /
  'OPDEMO1.PAT' path strings -> they are the OPENING/ATTRACT-DEMO modules. S45 p2
  checked 'OPENING' negative, so the live target is attract-mode (idle at title),
  a different state. Turns a blind search into a targeted capture.
- THREE payload-side base oracles built and ALL refuted by their own controls
  (R32/R35 assertions did their job; none of their answers were used):
    derive_base  0/4  -- 'code follows the table' is false (MAIN/34: 0x208 gap)
    vote_base    4/12 -- calls are outward + MIPS leaf fns have no prologue
    vote_base2   0/4  -- self-jals 0/N: there are NO internal jal calls at all
  The third is structural: a module's bytes do NOT encode its base, because its
  functions are reached indirectly via the header pointer table (jalr), not jal.
- The one real constraint: SC03/54's 19 header pointers (0x801EF718..0x801EFEE8)
  confine its base to [0x801EDED0..0x801EF6C8]. That window lies INSIDE SC02/9's
  span (0x801E4C60+70784=0x801F60E0) -> SC02/9 + the SC03 trio are mutually
  exclusive event modules sharing a ~0x801Exxxx region at DIFFERENT bases.
- => event-module destinations are per-scene/runtime-allocated, not a static slot.
  This explains the empty resourceIdMap branch and why the emulator resolved SC02/9.
  The CD-read tracer stays the correct instrument (R11 + Drew).
2026-08-07 15:45:56 -06:00
Drew T a3976d73e5 docs(phase-30 S45 p5): the resourceIdMap branch is REFUTED for all 5 parked payloads
- resourceIdMap @0x80063138 decoded from the EXE using the index math in our OWN
  matched C (ResourceGetCdLoc is byte-exact): exactly 162 6-byte records, 2 negative
  non-CD sentinels, streamIds >=0x100 -- self-consistent with the C in every field.
- FINDING: its 98 distinct global indices include NONE of gi 7/9/231/232/234, so the
  five parked payloads cannot reach ResourceGetCdLoc/StreamLoadStateMachine/D_80068B60.
  The S44 'descriptor path' branch of the parked-dest disjunction is refuted; only the
  per-overlay IDXTAB/DESTPTR route survives.
- R34 corroboration: loadDestPtrTable's 5 u32s re-derived independently and reproduce
  the S44 table exactly (0x800CEDF8/0x80128158/0x800CAE08/0x800CCB1C/0x800C7F08).
- R14 CORRECTION to S44: 'IDXTAB ... same list fleet-wide' is wrong. The 37-entry list
  at 0x8017EEC8 is real for ov_SC01_000 only; 140 of 141 overlays hold unrelated bytes
  there. IDXTAB is per-overlay data at a per-overlay address; only the mechanism is shared.
- NEGATIVE TOOLING RESULT (cookbook 155a): a shape-only IDXTAB scan passes its R32
  coverage assertion and is still non-discriminating (664 'tables'; hits are (offset,count)
  pair data). Coverage != discrimination -- two different oracles (R34). Recorded so it
  is not repeated; next instrument is a register-tracked decode of func_80128CFC (155).
2026-08-07 15:34:13 -06:00
Drew T 7e9394f691 fix(phase-30 S45 p4): R14 correction — the MAIN/7/SC03-trio 'loader fn' leads were scanner phantoms
- the quick hi/lo sweep paired lui/lo16 WITHOUT tracking base registers -> phantom refs
  (0x800AE868 read where the true target was 0x8018E868); register-tracked rescan: the ONLY
  literal loc-table ref fleet-wide is SC02/9's (solved)
- standing truth: MAIN/7, MAIN/9, SC03/53/54/56 all load via table-INDEXED paths; homework
  respecified (descriptor-data hunt + ResourceGetCdLoc/StreamLoad index math)
- fn 0x80161E08's real gate: currentLocationId vs {0x3012,0x3054,0x3079,0x3096} — the
  'variable 0x800C3054' never existed; cookbook §155 (track the register)
2026-08-07 15:13:50 -06:00
Drew T 788f33d523 feat(phase-30 S45 L3-p3): SC02/9 = the Steam Knight boss module — decoded, captured, retro-verified, onboarded; parked = 5
- the gate DECODED from matched C (func_8012832C case 0x300E -> func_80128998 -> streaming
  API with &cdFileLocTable[144]) -> scene arithmetic named the 1ST-BOSS arena -> ONE targeted
  load captured it at 0x801E4C60
- RETRO-VERIFIED: Phase-3's dumps/ram_castle.bin (2026-06-14) holds it at the SAME address,
  same 6,764-B exact prefix — R10 two independent datapoints two months apart;
  bossHp_SteamKnight (0x801E4398) lives inside this module's image
- onboarded md_SC02_009 (id 0x3E, TLO 0x4): BYTE-IDENTICAL first build; fleet 213;
  R22 213/213; tools-health OK; audit-disc UNCLAIMED 6 -> 5, residue 0
- the last 5 (MAIN/7, MAIN/9, SC03/53/54/56) reclassified emulator->STATIC-RE targets with
  decoded leads (memory-map §S45 p3); loc-id map appended to docs/debug-menu-list.txt
- negatives banked: pause menu, memory-box prompt, new-game intro, high/low game, Minku
  spawn (slot-A actor 0x15 = md_MAIN_015 candidate naming)
2026-08-07 15:07:55 -06:00
Drew T fa7b9d4c71 feat(phase-30 S45 L3): the emulator tour — all 28 script modules + MAIN/3 onboarded; fleet 212, R22 212/212
- THE TOUR (Drew driving the retail debug menu; mode-7 hammer over the Redux web API):
  all 28 script modules captured live at four byte-verified per-chapter slots
  (SC03/73-79 @0x801EF468 ch2-period, SC03/132-138 @0x801E25E8 ch3, SC04/24-30
  @0x801E7B28, SC05/23-29 @0x801ED988); the routing law: debug-menu AREA selects the
  chapter, each CITY interior streams its own module (member k <-> interior k).
  md_MAIN_011/DISELECT byte-proven 24,236/24,240 in RAM; slots A/B/boot R34-verified live.
- MAIN/3 DISCOVERED: the main-menu module (id 0x39, 121,884 B), mis-bucketed as data by
  BOTH audit oracles; live byte-proven @0x800CEDF8 (42,632-B exact prefix); onboarded.
- 29 onboardings BYTE-IDENTICAL on first build -> fleet 212; R22 212/212 after three
  md_MAIN_003 catches: the A4 DsMix leak; an extract-order-sensitive splat boundary
  (bytes: a 1-word data sentinel in .text + fn at +4 -> pinned in symbols file);
  corpus.stubs now treats D_*/jtbl_* INCLUDE_ASM as blob includes (mirrors progress.py)
- module-id census (offline, disc-wide): 77 id-law code payloads, 0 further misses;
  SC03/55 = confirmed DATA. audit-disc: UNCLAIMED 34 -> 6, residue 0 — the 6 carry
  byte-checked negative evidence; next tier = the CD-read tracer
- docs: memory-map §S45 (slots + routing + debug-menu ops), disc-completeness S45
  addendum, decision-log R31 entry, docs/debug-menu-list.txt (Drew's transcription)
- .run/s45 evidence allowlisted (tour logs/scripts/rosters); 104 ram dumps LOCAL-ONLY
- new baseline: 93.8% instr / 95.68% fn / 87.2% distinct over 212
2026-08-07 14:03:51 -06:00
Drew T c697746462 docs(phase-30 S44 I.0): the static loader routing table + the full tool audit — knowledge captured
Plan-approved campaign (Fable5Max, ~/.claude/plans/optimized-squishing-engelbart.md). I.0 = capture
while hot (R30/R31), before any code:

- memory-map.md §"Phase 30 S44": the COMPLETE loader routing table, static-derived (G5) — the EXE's
  loadDestPtrTable (0x80072C70: resident/overlay/slotA/slotB/type-7), the boot k-set {1,3,8,10,11},
  the RESIDENT's index tables D_800D3764 (29x8, MAIN/13-41 -> 0x800CAE08) and D_800D384C (6x8,
  MAIN/42-47 -> 0x800CCB1C), resident.c:641 (MAIN/12 -> 0x80128158), the SC07 pair's header-derived
  0x801A00D8, gbase arithmetic (LIST.CD carries LBA+len ONLY), the slot-adjacency proof, the
  module-id-word law (word0, dense 0x13..0x73, resident=0x36; MAIN/9-vs-39 duplicate flagged), and
  "PAC type 1 = uncompressed overlay, type 4 = LZSS". SUPERSEDES P3-T5's "entries [1]+ are
  runtime-indexed (no static xref)".
- disc-completeness.md: the "only knowable by runtime RE" doctrine REFUTED in place (H5, original
  kept) — 46 of 78 addresses are static; the runtime-only remainder is 28 script modules + 4
  stragglers, parked for L3 with evidence. Byte-sum correction (rows 3,406,325 B vs bucket
  3,564,021 incl. PAC headers), MAIN/7 raw-path exception, MAIN/0≡1.
- tooling-audit.md §S44: EVERY tool classified with file:line — 8 must-change (family_remap VRAM
  const, Makefile+modules.mk, sig-target generalization, audit_binaries de-ov_, family_hseq/
  progress:647/audit_frontier globs, corpus.sig_is_independent), 7 one-line registrations, 5
  retirements (disc_code_sweep superseded by disc_audit; reconcile_decls; 3 rollout one-shots;
  ImportOverlay/VerifyOverlay.java), rest auto-OK/N-A. new_overlay.sh -> new_binary.sh design.
- decision-log (R31): the pivot entry — the emulator dependency dissolves; the "modules" mostly
  dissolve into overlays (~75-77% h_exact-known; 802 novel fns); why the doctrine was missable for
  30 phases (a confident negative doctrine is a claim like any other — date it, cite it, re-measure).
- cookbook §154 + index regen (454 sections): module-id word / dual base-voting (h_exact ~500:1 +
  jal-alignment, must AGREE; thin votes => park, P9) / diff a mystery payload's head against classes
  you already own before inventing a new one.
2026-08-06 10:52:07 -06:00
Drew T 9a70f7179c docs(phase-12): T4 — script/event system + SQV driver determinations (byte-backed)
- memory-map.md: RESOLVE the "Script VM instruction set" open question — BFM has NO bytecode
  VM. "Scripting" is compiled-MIPS state machines dispatched via function-pointer tables
  indexed by game-state vars, proven by the matched resident dispatchers (D_800D3430[
  D_800B99F0](), D_800D3480/3488/3490[state](), the func_800D2Fxx cluster) mirroring the EXE's
  GameModeDispatch[gameMode](). Overlays = compiled MIPS that call the resident, not bytecode.
  Basis for the gen2-roadmap criterion #2 amendment (T6).
- formats.md §5: SQV driver = semi-custom — thin Square wrappers/glue over stock PsyQ libsnd;
  DsMix @0x800D1BD8 is a custom 2-line wrapper (NOT stock libsnd; the 4.7 sig was coincidental,
  T1). Bytes matched in the harvest; deep playback semantics deferred (Gen3, not needed for the
  byte-match).
2026-06-16 14:14:57 -06:00
Drew T d55882b4b8 feat(phase-5): splat config + all-asm byte-identical build of SLUS_007.26
- config/splat.us.exe.yaml: splat PSX config (platform psx, compiler PSYQ,
  subalign 2, gp_value 0x80074750, base_path .., main segment align 4); one
  asm text seg [0x800] + data seg [0x531DC], header via splat's header segtype
- Makefile: implement extract (splat split) / build (as -> ld(splat .ld +
  undefined_*_auto) -> objcopy) / check (SHA1 vs config/check.us.sha, auto-run)
  / expected (asm-differ baseline) / clean; check-env untouched
- config/check.us.sha: committed build-check hash (validation stage 2)
- config/symbols.us.txt: now hand-curated — 15 2D_* -> gfx2D_* (illegal leading
  digit broke as), +D_800629D4 label; header flags re-merge + Ghidra-mirror (G6)
- .gitignore: ignore regenerable splat outputs (asm/, include macros,
  undefined_*_auto.txt); refine the earlier commit-asm/ note
- docs: SETUP.md §4.5 binutils 2.42 = byte-clean (no 2.35 downgrade), §5.3 +
  ledger #8 RESOLVED -G0, §6.3 as-built; memory-map.md gp0 -> -G0 + text/data split
- MILESTONE: make extract && make build && make check -> build/us/SLUS_007.26
  SHA1 143dbb89... == original (BYTE-IDENTICAL), 100% asm, check fails on corruption
- rule R15 (symbol file = curated, valid-identifier build input, Ghidra-mirrored)
- bumps project version 1.4.0 -> 1.5.0
2026-06-14 12:05:38 -06:00
Drew T 3207d52491 feat(phase-3.5): prototype research spike — go/no-go (protos don't accelerate Gen1 matching)
- extract_proto_exe.py: subdir-aware proto main-EXE extraction (reuses iso9660); extracted
  sep8 SLUS_007.26 (413,696 B) + aug31 MUSASHI/USA_DEMO.EXE (415,744 B, base 0x80018000)
- ghidra_import.sh: reusable headless import; both protos imported into the bfm project
  (sep8 1726 funcs, aug31 1737 funcs, both PsyQ 4.0.0), R9-verified
- DumpFunctionSignatures.java + match_protos.py: 3-tier (exact/norm/seq) cross-binary
  correspondence; MIPS normalizer validated by anchors
- FINDINGS: (T2) no debug symbols in either proto — Hidden Palace "no symbols" VERIFIED;
  recon "Sep-8 less-stripped" REFUTED by per-file byte compare. (T3) Sep-8 99.6% byte-identical
  to retail (only 3 funcs differ: DebugMenuHandler, CdReadSectorReadyCB, SaveLoadRoutine);
  Aug-31 66% norm-identical, 862 1:1 correspondences. (T4) demo shares retail's 18-entry
  game-mode dispatch architecture but the handler code diverged — Q#10 resolved
- VERDICT (docs/proto-correspondence.md): NO-GO as a Gen1 label/symbol accelerator; GO to retain
  Sep-8 (Phase-6 compiler corroborant) + both (Gen2 assets); proto-side labels in
  config/symbols.proto-{sep8,demo}.txt (R13-tagged, never feed symbols.us.txt)
- reorg extracted/ into per-ROM subfolders (extracted/retail/, extracted/proto/); nested
  gitignore allowlist; extractor defaults updated; manifest --verify PASS
- memory-map.md: Phase-3.5 block + demo dispatch anchors; Q#10 RESOLVED; §5 proto notes VERIFIED
- ghidra_mcp_start.sh: PROG arg to serve a prototype
- rules R13 (proto-provenance/confidence tagging), R14 (verify recon counts vs bytes)
- bumps project version 1.3.0 -> 1.3.1
2026-06-14 03:19:23 -06:00
Drew T bd5e21b366 feat(phase-3): file-loader & overlay-map RE + PCSX-Redux runtime oracle
- RE'd the full file-loader/overlay subsystem in Ghidra via MCP: CdReadRequest ->
  CdReadStateMachine (hand-rolled CdControl SeekL/ReadN reader, NOT PsyQ CdRead);
  LIST.CD RAM cache cdFileLocTable + ResourceGetCdLoc/resourceIdMap lookup; LZSS
  staging buffer 0x80079A70; loadDestPtrTable; ~50 symbols named (T1-T5,T8)
- T6b MILESTONE: resident blob @0x800CEDF8 + location overlay @0x80128158 proven
  byte-identical (sha1-equal contiguous prefixes) vs live PCSX-Redux RAM; blobs
  imported into Ghidra (ImportOverlay.java); overlay-map table -> memory-map.md §4.3
- PCSX-Redux runtime oracle: Windows-native build, WSL reads RAM via the web API
  at 172.17.208.1:8081; ledger #4 resolved
- live-verified player/time state: gold(/10) HP BP day hour tiredness boss-HP;
  save-header template (Q#5) + debug-menu dispatch (Q#9: DEBUG.BIN path is dead)
- overlay map: 13 area-states across SC01/02/03, 2 duplicate pairs, location x
  chapter keying, free-roam vs menu-hub granularity
- resolves Open Q#1/#3/#4/#5/#6/#8/#9/#12; corrects SLUS-90029 (FF8 demo, not BFM)
- 2 US prototypes acquired + CRC-verified (Aug-31 1369DE07, Sep-8 5C24728E)
- rules R9 (verify persistence), R10 (>=3-datapoint live verification),
  R11 (runtime oracle Windows-native, bridged to WSL)
- bumps project version 1.2.0 -> 1.3.0
2026-06-14 02:04:28 -06:00
Drew T d4334fc1ca plan files created 2026-06-10 22:02:07 -06:00