Commit Graph

49 Commits

Author SHA1 Message Date
Christopher Williams 18e784df39 phase8: record cycle 3, the SDK-shape verdict, and the worker negative results
Cycle 3 merged 22 claims (worker A's 8 new plus 9 gp rows, worker C's 6 pure-C
rows) at 137 regions / 128 distinct bodies, and closed every near-miss that
Phases 5-7 recorded in the reachable set: 0x800F3160, 0x800F8AEC, 0x800F8B58/6C,
0x800F8FE4, 0x80102B10 (maspsx=off), 0x800F7FB4 x3 (a cc1 loop-shape artifact),
0x8009E8D0 x2 (ordinary matching).

Worker C's SDK-shape investigation refuted its own premise: the COP2 shapes are
reachable, the blocker was never the missing SDK headers, and the stack accessor
needs no asm at all. The 8 COP2/syscall regions are parked pending the
developer's inline-asm convention decision.

Recorded as results, not footnotes: three rules that were tested and bounded. The
commutative-operand rule's direction is right but its trigger fails for a literal
base in a counted loop; the do/while loop rewrite does not transfer to
0x800FBF5C; and the reorg class is a cc1 reorder thread-fill decision that no
assembler can perform for a conditional branch, so it is a bounded negative
rather than a harness gap.
2026-09-23 23:16:08 -04:00
Christopher Williams 2775d2e077 phase8: merge cycle 3 — g0007 and g0030 closed, 137 regions / 128 bodies
22 claims accepted (worker A's 8 new + 9 gp rows, worker C's 6 pure-C rows),
28 skipped as already registered, 0 rejected. Candidate gate c_regions=137, 0
differing bytes, SHA-1 e173426c; promoted, then make check green (200 tests,
regions=137 disagreements=0).

Worker C closed two duplicate groups that other sessions had left as near-matches:

- g0007 (0x800F7FB4 x3 addresses): the unexplained 8-byte frame was cc1 loop
  restructuring, not a calling-convention need. `for (i = n-1; i != -1; i--) *p++ = 0;`
  makes cc1 emit an unused subu/addu sp pair; an explicit guard plus a do/while
  gives the exact 36 bytes.
- g0030 (0x8009E8D0 x2 addresses): the abs-of-3-component-difference function
  that workers A and B both recorded as near-matches.

The two BIOS stubs are still policy-gated (they need an inline-asm statement) and
are not in this merge. Distinct matched bodies: 128.
2026-09-23 23:13:17 -04:00
Christopher Williams 62983c9a8a phase8: syscall returns, so it is not a walk terminator
Worker C found that config/function_extents.tsv mis-split the two BIOS stubs:
it recorded 0x80103FCC..0x80103FD4 (8 bytes) and 0x80103FEC..0x80103FF4, but the
real bodies are 16 bytes (li a0,N / syscall / jr ra / nop). Its evidence: the
first address has four jal callers and the following address has none, syscall
returns to EPC+4 so the body must continue to a jr ra, every neighbouring stub is
16 bytes with the same shape, and an 8-byte body is unreachable from C because
cc1 always appends an epilogue.

Root cause: the walk treated `syscall` as a terminal alongside `break`. On this
target syscall is the BIOS call instruction and it returns to the next word.
`break` still terminates. After the fix both stubs are 16 bytes ending at their
jr ra, and all 115 registered regions still agree with their derived extents.

The fix also exposed three walks in the 0x8017xxxx region that the accidental
syscall stop had been bounding: 0x8017D5C0 now runs out of the payload
(grade=outside), 0x801800C4 becomes a 1860-byte fallthrough, and 0x8018080C a
240708-byte indirect. All three are jal-graded starts whose bodies are almost
certainly data; none is registered and none is matchable. 200 tests pass.
2026-09-23 23:11:38 -04:00
Christopher Williams e98aa102e4 phase8: rules check after P8-T4 2026-09-23 23:07:30 -04:00
Christopher Williams 270cb6201a phase8: record cycles 1-2 and the two harness mechanisms
Control record updated with both verified cycles, the two per-region overrides
that came out of worker findings (maspsx=off and gp=-NAME, with the byte evidence
for each of the six anomaly-class regions), and the coordinator findings: the
stale worklist caught before dispatch, the candidate-first merge that contained a
bad cycle, Ghidra's COP2 pseudo-op collapsing, and the two $gp thunk halves.

Also excludes 0x80108034 and 0x8010804C from the worklist: they are the two halves
of a $gp-switch thunk and are not matchable as C regions.

Milestone met at 109 distinct bodies (target 70).
2026-09-23 23:06:54 -04:00
Christopher Williams 9a49ee62f7 phase8: close the assembler-anomaly and gp-site classes, reaching 109 bodies
Two harness gaps were closed as per-region overrides, both found by the workers
and implemented by the coordinator:

1. maspsx=off. Worker A isolated the $at-macro-store-in-the-jr-delay-slot shape
   with a decisive experiment: cc1 emits an empty delay slot, maspsx fills it with
   a nop, and GNU as in reorder mode fills it properly by moving the last half of
   the expanded store. Six regions need this, including 0x800F3160 -- Phase 5's
   first recorded bounded negative, unreachable for three phases -- and 0x800F8AEC,
   0x800F8B58, 0x800F8B6C, 0x800F8FE4, 0x80102B10. Worker B reverse-engineered the
   same mechanism independently from the cc1 output.

2. gp=-NAME. The gp marker is per symbol, but the original's access form is per
   SITE: 0x80121F84 is read gp-relative at 0x800A80BC and written absolutely at
   0x8002D288, in the same function. A byte search confirmed 6 gp-relative
   accesses at d=0x64c, so worker B's census row was right and worker A's source
   was right; only a per-region exclusion can express both. This makes cookbook
   finding 10 incomplete.

Both overrides are validated (199 tests, 10 added), and sf3_merge gained
--skip-registered because a worker's claims file is naturally cumulative.

Cycle-2 merge: 66 claims, 58 accepted, 8 skipped, 0 rejected. Candidate gate:
c_regions=115, 0 differing bytes, SHA-1 e173426c. Promoted, then make check green:
199 tests, regions=115 disagreements=0, c_regions=115 MATCH.

Distinct matched bodies: 51 -> 109, past the phase milestone of 70.
2026-09-23 23:05:35 -04:00
Christopher Williams 7c299aca26 phase8: merge worker B's first eight claims and 335 gp rows
P8-T2's protocol record plus worker B's cycle-1 merge.

Worker B verified 8 claims (7 bodies: g0029 is a two-address duplicate group).
It also classified its whole 946-row partition off one objdump and found that 226
rows (24%) access gp-relative globals, staging 335 distinct addresses. Those were
checked before use: every row is arithmetically exact under the list's decimal d
column (335 rows, 0 errors), and four sampled globals were confirmed against my
own Ghidra disassembly (0x564(gp) -> 0x80121E9C and three others). A risk check
for whether a new gp marker could change an already-matched region found only
worker A's unclaimed in-progress files, so no registered region is affected.

323 rows were new (12 already present), taking config/symbols.tsv to 354 rows and
unblocking a quarter of worker B's partition.

Candidate gate: c_regions=57, 0 differing bytes, SHA-1 e173426c. Promoted, then
make check green: 189 tests, regions=57 disagreements=0, c_regions=57 MATCH.
Distinct matched bodies: 34 -> 51.

Worker B also deferred 0x8001D98C (g0053, 436B, GTE 3x3 transform) into the
bounded GTE class, and recorded two byte-proven cookbook findings: BCD nibble
pairs must be their own parenthesised subexpression (a pure association tell, 9
shifted bytes), and a constant absolute address in a load folds the
carry-adjusted low half into the load displacement rather than using lui+ori.
2026-09-23 22:55:42 -04:00
Christopher Williams d7047e08c7 phase8: add the claim-merge tooling and merge worker A's first ten claims
P8-T2 plus the first verified cycle-1 merge.

tools/sf3_merge validates worker claims before anything tracked changes: a claim
is accepted only if its extent exists in the derived extents table and is graded
exact with exactly the claimed end, its source is a repo-relative
src/func_XXXXXXXX.c that exists, and it overlaps neither the registry nor another
worker's claim. Rejections are reported with reasons and nothing is written.

The workflow it enables is stronger than the plan's wording: merge to a CANDIDATE
registry, gate the candidate, and promote only on MATCH, so the tracked registry
never contains an unverified claim.

Worker A reported 10 claims (target 8) and correctly refused to edit the shared
symbol registry itself, instead requesting 9 gp-marked rows; each was checked
arithmetically as gp + d. Candidate gate: c_regions=49, 0 differing bytes, SHA-1
e173426c. Promoted, then make check green: 189 tests, regions=49
disagreements=0, c_regions=49 MATCH.

Worker A also reported a significant blocker: two of the remaining duplicate
groups are GTE (COP2) bodies -- 0x80018CB0 (3 addresses) and 0x8001084C (2
addresses, the 712-byte shared body) -- plus 0x80103A94 and 0x80103B60. That is
four GTE functions, which raises the value of the bounded SDK-shape
investigation in P8-T5.
2026-09-23 22:52:08 -04:00
Christopher Williams 5f07614247 phase8: open the control record, revalidate the baseline, and hand off to two workers
P8-T1 of the coordinated multi-session phase. Baseline re-run green: make clean,
make all, cmp, SHA-1 e173426c..., 168 synthetic tests, extents agreement 39/39,
and the ordered gate at c_regions=39 with 0 differing bytes. No tracked path
under a prohibited root.

Both peers were probed rather than assumed: 01a0d143 and 01a0d145 are live in
this repository at HEAD 42c9b1d with shell and a full tool set, but neither had
read the project docs, so both charters are self-contained. Hard rules were
restated with the probe: the tracked registries, build/ and all writing git
commands are coordinator-only, and only new src/*.c files inside a worker's own
partition may be created.

Before dispatching, the partitions were checked against config/regions.tsv and
the tracked worklist was found STALE -- it was generated in P7-T4 with only 12
regions registered, so it still listed 23 candidates Phase 7 later matched.
Regenerating it gives 1893 listed with 39 excluded as already registered, which
is exactly the 39 regions. Partitions are now 947/946 rows, disjoint
(intersection 0), union equal to the worklist. Worker B's charter was corrected
immediately because it quoted the old bounds.

The charters carry a standing safety net: a worker that finds a row already in
config/regions.tsv must skip it and report, because that means the file went
stale again.
2026-09-23 22:48:25 -04:00
Christopher Williams 42c9b1d9bc phase8: draft the coordinated multi-session plan
Phase 7 made matching possible at scale; Phase 8 makes it parallel. Three pi
sessions in one worktree, coordinated over pi-intercom: one coordinator that
dispatches charters, merges claims and independently verifies them, and two
workers that match concurrently.

The plan's centre of gravity is concurrency safety, because three sessions share
one worktree: src/*.c is partitioned disjointly so no two sessions can write the
same file, the tracked registries and build/ and git are coordinator-only, and
worker deliverables stage in ignored paths. The safety property is that a
worker's claim is never trusted -- the coordinator's own clean make gate over the
whole 1,886,208-byte executable is the only authority, so a fabricated match
breaks the SHA-1, and make extents-verify stops a hand-chosen end address.

Target: at least 70 distinct bodies (from 34), staged across three cycles so a
stall shows up early, plus one bounded investigation into the SDK-header shapes
Phase 7 deferred.

Draft, awaiting approval. Decisions flagged for the developer: this session
coordinates, workers match while the coordinator verifies, the two already-live
peers (01a0d143, 01a0d145) are probed rather than assumed, and the target size.
2026-09-23 22:42:52 -04:00
Christopher Williams 2f05e821fc phase7: close the phase with the verification milestone
Developer-confirmed milestone: 34 distinct byte-identical function bodies across
39 registered regions, up from 11 / 12 at Phase 6 close. Every region end is now
derived from control flow and enforced by make check, duplicate bodies are
censused, match targets come from a ranked worklist, and cross-references no
longer need hand-written symbol rows.

Adds PhaseEnd_Phase7.md and the digest entry, and archives CURRENT_PHASE.md as
logs/Phase7.md.

Final gates: 168 synthetic tests; make clean, make all, cmp and SHA-1
e173426c...; make check green at c_regions=39 with 0 differing bytes and
regions=39 disagreements=0. 121 tracked files, none under a prohibited root.
2026-09-23 22:40:26 -04:00
Christopher Williams 0e3ff39ea9 phase7: record the verification gate and the new conventions
Phase 7 closes the milestone: 34 distinct byte-identical bodies across 39
registered regions, up from 11 bodies / 12 regions at Phase 6 close, with every
region end derived from control flow instead of by hand.

New cookbook findings, each byte-proven:

- 13: a store-only function leaves its constant in v0 as scratch. Writing
  `return 1` costs an instruction in the delay slot (0x8003636C: 12 vs 16 bytes).
- 14: the gp-relative offsets proved so far, with the global each one names.
- 15: shapes plain C cannot reach without SDK headers (GTE/COP2 code, BIOS
  syscall wrappers, stack-pointer accessors).

Conventions updated: a region end comes from config/function_extents.tsv and is
enforced by make check; the duplicate check is the tracked census rather than a
manual search; the worklist is the ranked queue; and address-named symbols
resolve implicitly while anything else fails loudly.

Clean-state gates all exit 0: make clean, make all, cmp, both files SHA-1
e173426c..., and make check (168 tests, regions=39 disagreements=0,
c_regions=39, 0 differing bytes). 121 tracked files, none under a prohibited
root. Milestone confirmation requested before any PhaseEnd.
2026-09-23 22:37:16 -04:00
Christopher Williams dd807ffb8c phase7: match 22 more function bodies from the worklist
Both batch targets are met in one pass: 22 new bodies (23 including the P7-T5
match), taking the project from 11 distinct bodies to 34 -- past the phase
milestone of 30 -- across 39 registered regions.

The batch is dominated by the small leaf shapes the worklist ranks first:
empty function (4 duplicate addresses), byte/halfword/word setters, field
getters, a word-buffer clearer, and eight gp-relative getters/setters. Every one
was byte-identical on the first or second attempt, and every extent came from
tools/sf3_extents rather than a hand-derived end.

Three shapes needed diagnosis, and two were solved:

- 0x8003636C was 16 bytes instead of 12 because `return 1` forced a second
  `li v0,1` into the delay slot; the original leaves 1 in v0 as scratch, so the
  function is `void`.
- 0x800F7FB4 needed the parameter reused as the loop counter.

Four candidates are recorded as bounded negatives or deferrals rather than
guesses:

- 0x800F7FB4: the loop body reproduces exactly, but the original has no frame
  and every tested formulation allocates 8 bytes (five C forms, and an
  -O1/-O2/-O3/-fomit-frame-pointer matrix). Stopped after two distinct attempts.
- 0x800F8AEC: the original schedules `lui` / `jr ra` / `addiu` with the low half
  in the delay slot; the reconstruction emits `lui` / `addiu` / `jr ra` / `nop`.
- 0x80010810: GTE (COP2) code needing the SDK's GTE macros, which the build has
  no headers for.
- 0x800FB5D4 (`move v0,sp`) and 0x80103FCC/0x80103FEC (BIOS `syscall` wrappers)
  and 0x8001EAFC (a shared jump block, not a standalone function).

make gate: c_regions=39, 0 differing bytes, SHA-1 e173426c. Extents verify agrees
on all 39 regions. 168 synthetic tests.
2026-09-23 22:34:02 -04:00
Christopher Williams 399da98a83 phase7: resolve address-named symbols implicitly and fail loudly otherwise
Every cross-reference used to need a hand-written config/symbols.tsv row, which
does not scale to a batch. A symbol whose name is an address now resolves to that
address with no row: func_XXXXXXXX, D_XXXXXXXX, g_XXXXXXXX, lbl_XXXXXXXX. This is
the convention the registry already used, applied without the row.

The names come from the object's own undefined-symbol list (nm -u), not from a
guess about the source, so a name the source defines but never references is
never mistaken for one needing resolution. A registry row still wins, which is
how a gp marker or a real name is attached. Anything neither registered nor
address-shaped now fails before the link with a message naming the symbol and the
fix, instead of a bare ld diagnostic.

First match from the worklist: func_800F8F9C (36 bytes, worklist rank 3), a
duplicate-group representative with a frame and a call. It matched on the first
attempt and is registered twice (0x800F8F9C, 0x80109314) against one source, so
two functions were matched for one body. Its callee needed no registry row.
Ghidra's independent body agrees with the derived extent.

make gate: c_regions=14, 0 differing bytes, SHA-1 e173426c. 168 synthetic tests.
2026-09-23 22:26:08 -04:00
Christopher Williams a6af8b3cd2 phase7: replace hand-picked targets with a ranked, reproducible worklist
Phase 6 chose match targets by eye from the boundary inventory. tools/sf3_triage
now ranks every eligible candidate by (tier, size, address) from tracked inputs
alone and records why everything else was excluded.

Eligibility: an exact or fallthrough extent, a non-degenerate body, not already
registered, not the header entry, not named by --exclude. indirect, escape,
outside, runaway, contained and standalone are excluded and counted.

Tiers: 0 duplicate-group representative (one match, several addresses), 1 exact
leaf (no cross-references, so no symbol rows), 2 exact non-leaf, 3 fallthrough.

Result: 1916 listed (tier 0: 9, tier 1: 509, tier 2: 1394, tier 3: 4), with 252
degenerate bodies, 88 low-confidence grades, 12 registered, 1 header entry and
2 named near-misses excluded. The nine tier-0 entries are the real duplicate
groups: matching those nine bodies registers 22 function addresses.

The two deferred near-misses are excluded by name in the Makefile so the
exclusion stays visible rather than buried in the tool. 160 synthetic tests pass.
2026-09-23 22:19:39 -04:00
Christopher Williams 2000cc4101 phase7: census duplicate bodies and expose a zero band of false positives
Matching conventions require a duplicate check before registering, because a
shared body is matched once and registered once per address. Phase 6 did that
check by hand and found one 12-byte pair. tools/sf3_dupes now hashes every
derived extent body and groups exact duplicates.

Results: 2284 extents, 65 multi-address groups, 2104 singletons. Only 10 groups
contain code (24 addresses, all exact-graded); 55 are all-zero bodies. The
hand-found pair 0x800262E0/0x800262EC is reproduced as g0002, which is the check
that the census measures what it claims. The largest real groups are 712 bytes
(0x8001084C/0x800189E8) and 436 bytes.

The zero groups are a real finding: 252 extents have all-zero bodies, 245 inside
the zero band 0x80147000..0x80170000. The cause is the inventory's jal grade,
which decodes every word as an instruction -- in a data region a word with
opcode 3 is graded as a call whose target lands in the zero band. The census
flags those groups rather than hiding them, and the worklist must exclude
degenerate bodies.

The census is tracked rather than ignored as the plan said, because it holds
addresses, sizes and grades only (the same class as the tracked inventory and
extents tables) and the worklist must be reproducible from tracked inputs. The
content hash is computed and never written.
2026-09-23 22:15:51 -04:00
Christopher Williams 6988ca96b0 phase7: derive evidence-graded function extents from control flow
Phase 6 graded function starts and left every end to be derived by hand. This
adds tools/sf3_extents, which explores all reachable control flow from each hard
start (jal/entry) and reports an extent plus how far it can be trusted.

Measured decisions, not stylistic ones:

- Soft starts are not walk boundaries. A body's second instruction can satisfy
  the prologue grade exactly (0x800152AC is lw v1,8(gp) / addiu sp,sp,-176, so
  0x800152B0 looks like a start). Enforcing soft boundaries stopped 155 of 416
  walks inside a real body.
- The walk is a full reachability computation, not a first-terminal search: a
  function whose paths return at different addresses must report the whole body.

Grades: exact 1940 (1666 packed, gap=0), fallthrough 256, indirect 73,
escape 15, contained 153, standalone 438; 63.8% of the payload covered.

Verification: all 12 registered regions reproduce exactly (make extents-verify,
now part of make check), 29 new synthetic tests (115 total), byte-identical
across two runs, and Ghidra's independent body for FUN_80017ad4 agrees. Two
defects were caught by writing the tests first and are recorded: reach had to be
an exclusive end, and a terminal j's delay slot must not continue linearly.

The table holds addresses, sizes, grades and site addresses only -- no bytes.
2026-09-23 22:12:31 -04:00
Christopher Williams 97ee078142 phase7: open the phase control record, revalidate the baseline, and triage the open items
Approved plan: phase-ends/Phase7_PLAN.md. Goal is scale -- evidence-graded
function extents and a duplicate-body census first, then a batch that takes the
project past thirty distinct byte-identical functions.

P7-T1 re-ran every entry gate green: 86 synthetic tests, clean make all with
cmp exit 0 and both files SHA-1 e173426c..., make gate at c_regions=12 with 0
differing bytes. No tracked path under a prohibited root.

Triage splits the Phase 6 open items into four class blockers (missing function
ends, unknown duplicate bodies, no candidate ranking, per-function symbol-row
cost) and the deferred or unresolved single items (0x8005DEF8, 0x800F3160, the
numeric -G, the CRT entry, library versus game code).

Also ignore .pi/, the agent harness's local task-log state, which was untracked
but not ignored.
2026-09-23 21:59:37 -04:00
Christopher Williams 6ca8ac1a3c phase6: close the phase with the verification milestone 2026-09-23 21:51:44 -04:00
Christopher Williams ce43b7b42b phase6: document the Ghidra-draft workflow and record the verification gate 2026-09-23 21:50:03 -04:00
Christopher Williams 2507994ac3 phase6: correct the compiler to PsyQ 4.0 (gcc-2.7.2-psx) and register the framed batch 2026-09-23 21:37:15 -04:00
Christopher Williams 8ece49c130 phase6: register the leaf/gp batch and record the framed-function blocker 2026-09-23 21:24:15 -04:00
Christopher Williams d951e49b1d phase6: add the evidence-graded function-boundary inventory 2026-09-23 21:12:54 -04:00
Christopher Williams d379b84ec3 phase6: reproduce a gp-relative function and record the small-data evidence 2026-09-23 21:09:07 -04:00
Christopher Williams 4688662cf4 phase6: wire maspsx and link-time symbols, resolving the ASPSX la form 2026-09-23 21:01:20 -04:00
Christopher Williams 673edb2ded phase6: add the symbol registry and per-region flag overrides, and register 0x8002D2A0 2026-09-23 20:54:10 -04:00
Christopher Williams 73e8cd9a2e phase6: open the phase control record and triage the open items 2026-09-23 20:48:15 -04:00
Christopher Williams 87c01c9c7e phase5: close the toolchain identification milestone and draft phase 6
Closes Phase 5: writes phase-ends/PhaseEnd_Phase5.md, adds the Phase 5 entry to
the digest, and archives CURRENT_PHASE.md as phase-ends/logs/Phase5.md.

Phase 5 outcome: the original compiler is identified with byte evidence as
egcs-2.91.66 (egcs-1.1.2) target mips-sony-psx -- PsyQ 4.5 CC1PSX -- with the
open gcc-2.91.66-psx build verified instruction-identical to the real SDK binary;
the entry is determined to be CRT startup rather than C; and func_80017AD4 is
matched instruction-identical with a green clean full-binary gate. Gates: 53
tests, make clean/all/cmp/SHA-1 green, 62 tracked files with none under a
prohibited root.

Also adds phase-ends/Phase6_PLAN.md as a DRAFT requiring developer approval, and
updates the README status. No Phase 6 task is started.
2026-09-23 20:46:09 -04:00
Christopher Williams defbf446eb phase5: cookbook, conventions, and verification record
P5-T6. Adds docs/MATCHING_COOKBOOK.md (nine byte-proven compiler/assembler
findings, each with basis and limit), docs/MATCHING_CONVENTIONS.md (what counts
as a match, registry format, source naming, duplicate sharing, symbols, the
verification procedure, the firewall) and docs/PHASE5_VERIFICATION.md (outcome,
clean gates, bounded negatives, milestone request).

Tooling: make test and make check targets; region objects are now
symbol-localized so the documented duplicate-sharing mechanism (N registry rows
-> 1 source) links, covered by a synthetic test (53 tests).

Clean gates: 53/53 tests; make clean/all/cmp/SHA-1 green; make gate with one C
region -> c_regions=1, 0 differing bytes, SHA-1 e173426c...; 57 tracked files, 0
under any prohibited root. Phase 5 is not closed until the milestone is
confirmed.
2026-09-23 20:43:33 -04:00
Christopher Williams ff35291d40 phase5: determine the entry is CRT startup and match the first C function
P5-T5. Part A: the entry [0x800FB368,0x800FB410) is not compiler output. The
return address is round-tripped through an absolute global around the first
call, the range ends in break, the stack pointer is built from linker globals,
and the clear loop falls through with no jr ra. Two bounded compile experiments
failed and were stopped; the entry stays fallback and no C is claimed.

Part B: first byte-identical C match -- func_80017AD4 at 0x80017AD4..0x80017AE8
(20 bytes), src/func_80017AD4.c, registered in config/regions.tsv. make gate
reports c_regions=1, 0 differing bytes, SHA-1 e173426c157384ebf1b6caf8c6fea18a85a14af9.
Body is unique with one caller at 0x80014C14; a shared-tail near-miss was
checked and rejected as a duplicate. The Phase 3 baseline is unaffected.

Records six codegen findings, notably that GNU as expands the la macro with ori
while the original assembler (ASPSX 2.81) uses addiu, so la-using functions will
need maspsx. No ROM-derived material is tracked.
2026-09-23 20:39:40 -04:00
Christopher Williams c594e1b8bc phase5: report the C region count so an empty gate cannot be misread
make gate on the empty registry prints result=MATCH, which is the data baseline
being copied through the ordered layout, not a C match. The harness now prints
c_regions=<n> and, when zero, an explicit note that the build contains no C.
Adds two synthetic tests (52 total).
2026-09-23 20:35:47 -04:00
Christopher Williams f0237f1549 phase5: add the tracked matching harness and ordered-layout gate
P5-T4: tools/sf3_match provides range/plan/build/gate. It compiles a C candidate
with the identified toolchain (egcs-2.91.66 psx, -O2 -G0 -mno-split-addresses),
compares the exact instruction range byte-for-byte against the original, and
builds the address-ordered executable from the tracked registry config/regions.tsv
(header 0x800 + data gaps + C regions, LMA 0x800, metadata discarded).

Promotes the Phase 4 ordered workflow from an ignored experiment to tracked
tooling. Verified: make gate with an empty registry and with one real C region
both reproduce SHA-1 e173426c...; the Phase 3 baseline is unchanged and green;
the synthetic suite is now 50 tests including deliberate-corruption failures and
safe refusal of an existing destination. No ROM-derived material is tracked.
2026-09-23 20:32:11 -04:00
Christopher Williams c22d2aef60 docs: add project README with the identified toolchain
Adds a top-level README describing the target, the honest current state
(all-assembly baseline green, 0 functions matched to C), the build-from-your-own
-disc steps, the repository layout, the governance model, the no-ROM policy, and
third-party provenance.

The toolchain section records the Phase 5 identification: the original compiler
is egcs-2.91.66 (egcs-1.1.2) target mips-sony-psx -- PsyQ 4.5's CC1PSX -- with
the open decompals/old-gcc gcc-2.91.66-psx build as a byte-identical substitute,
-O2 -G0 -mno-split-addresses, ASPSX 2.81, and GNU mipsel binutils.

No game data or ROM-derived content is included.
2026-09-23 20:26:02 -04:00
Christopher Williams 147eb4abf8 phase5: identify the compiler as egcs-2.91.66 (PSX) / PsyQ 4.5 CC1PSX
P5-T3 revised: obtained the real PsyQ 4.4/4.5/4.6 SDK compilers (proprietary,
kept ignored) and ran CC1PSX 4.5 under the ignored wibo Win32 loader. The SDK's
own README and the binary agree: PsyQ 4.5 CC1PSX = egcs-2.91.66 (egcs-1.1.2),
target mips-sony-psx, assembler ASPSX 2.81.

The open decompals/old-gcc gcc-2.91.66-psx produces instruction-identical
output to the real CC1PSX across ~990 instructions in twelve probe files, so no
proprietary compiler is needed for the matching build. Five reconstructed
original functions are byte-identical with -O2 -G0 -mno-split-addresses.

Corrects the earlier gcc-2.7.2-psx selection, which was an artifact of the
invalid -mcpu=3000 spelling. Records the unresolved 0x8005DEF8 reconstruction.
2026-09-23 20:23:05 -04:00
Christopher Williams f80ada2e07 phase5: record 2.5.7-psx/2.6.0-psx provenance and old-gcc build origin
P5-T3 follow-up: tested the two remaining GPL psx candidates. Both match the
same signatures as 2.7.2-psx but also synthesize the constant multiply, so
neither resolves the recorded divergence. SETUP now also records that the
old-gcc '-psx' builds are community GCC+patch reconstructions, and that the
real Sony PsyQ compilers exist in the mkst/esa psyq-binaries release (not
downloaded).
2026-09-23 20:15:20 -04:00
Christopher Williams 073da76a8a phase5: select gcc-2.7.2-psx from the old-gcc ladder
P5-T3: fingerprinted all eight decompals/old-gcc 0.17 cc1 candidates with
self-authored probes. gcc-2.7.2-psx is the only candidate matching the
ASPSX-style $at symbolic store, the same-register symbolic load, the
unsigned-char default, and the mfhi <scratch> magic-division allocation.
Five reconstructed original functions are byte-identical; 2.6.3-psx, vanilla
2.7.2, 2.7.2-cdk and 2.8.0/2.8.1/2.91.66/2.95.2 are eliminated. One bounded
constant-multiply synthesis divergence is recorded. No ROM-derived material is
tracked.
2026-09-23 20:10:46 -04:00
Christopher Williams e0d994d49d phase5: acquire vintage cc1 candidate ladder with provenance
P5-T2: downloaded decompals/old-gcc 0.17 prebuilt cc1 binaries (GCC 2.6.3/2.7.2/
2.8.0/2.8.1/2.91.66/2.95.2 psx variants plus vanilla 2.7.2 and cygnus cdk) into
ignored tools/old-gcc/. All eight run on this host and self-identify; the two
sha256 values cross-checked against an independent project matched exactly.
Local GNU as accepts COP2/GTE with -march=r3000 -G0.
2026-09-23 19:58:31 -04:00
Christopher Williams ed2f249397 phase5: activate phase and record toolchain evidence inventory
P5-T1: revalidated the clean payload-data baseline (28 tests, make clean/all,
cmp, SHA-1 e173426c...), reviewed the firewall and Git state, and inventoried the
USA toolchain-relevant codegen signatures and SDK version-marker provenance.
No ROM-derived bytes, strings, or listings are tracked.
2026-09-23 19:51:47 -04:00
Christopher Williams b9543e5213 phase4: close code recovery evidence milestone 2026-09-23 19:46:17 -04:00
Christopher Williams 494c6d6c7f phase3: close assembly baseline milestone 2026-09-23 18:44:51 -04:00
Christopher Williams 7b0879f8da phase3: add assembly baseline pipeline 2026-09-23 18:41:28 -04:00
Christopher Williams 9513844b73 chore: track project MCP configuration 2026-09-23 18:01:41 -04:00
Christopher Williams cb87942249 chore(phase-2): close archive loader investigation 2026-09-23 17:46:32 -04:00
Christopher Williams 1dd720d998 chore(phase-1): close extraction and import milestone 2026-09-23 15:03:12 -04:00
Christopher Williams 04331bd5b4 feat(phase-1): add disc extraction and EXE validation 2026-09-23 14:30:45 -04:00
Christopher Williams 58346a4d99 chore(phase-0): close governance and disc characterization 2026-09-23 09:44:58 -04:00
Christopher Williams 98af7d5388 docs(phase-0): approve phase-1 extraction import plan 2026-09-23 09:41:59 -04:00
Christopher Williams 14dc2b2620 docs(phase-0): characterize MODE2 ISO9660 disc image 2026-09-23 09:38:10 -04:00
Christopher Williams 23e9a8871c chore(phase-0): establish ROM-safe project baseline 2026-09-23 09:36:50 -04:00