re: read the ISL branch handlers -- it is a condition-code machine

Closes the backlog item that was the last thing between the flat decode and a
per-phase clear condition, and closes isl-builtins.md's standing "op10 + op13 look
like a switch -- NOT confirmed".

op10 resolves two operands, issues a SIGNED cmp, and writes three condition bits to
a bitset at phase+24: bit 0 = EQ, bit 1 = GT, bit 2 = LT.  op11 is the same machine
for floats via fcmpu.  op13-op18 branch on those bits to [phase+232] + word@+4 --
the same phase-relative target form as the unconditional op12:

  13 bit0 set    beq      16 bits 2 then 0   ble
  14 bit0 clear  bne      18 bits 1 then 0   bge
  15 bit2 set    blt      17 bit1 set        bgt

13/14/15/17 are byte-identical apart from the bit index and the polarity.  All six
relations are present and each appears exactly once; that completeness is the check
that the reading is right, rather than the usage pattern -- which the item
explicitly warned against.

Operand order recorded because it is easy to reverse: LHS = (kind byte[1], word@+4),
RHS = (kind byte[0], word@+8).

Method note in the doc: the jump table at 0x822635FC holds THUNKS, and the handler
is the bl target inside each.  My first pass guessed handler addresses at a fixed
stride, landed mid-function, and produced a 20-line "difference" that was pure
misalignment.

isl.py names the ops; data/isl-stage02.txt is regenerated and every diff line pairs
exactly, only the op-name column changing (op10->cmp.i x5, op13->beq x4,
op14->bne x1).  data/isl-stage02-phase-ends.txt now shows the phase-3 poll loop
reading as one: unit_state(ADT308) -> op23 -> cmp.i -> beq back to 0xFEB4.

Left unnamed on purpose: op23 (0x82271C30) and op21 (0x82175C20).
This commit is contained in:
Sylpheed RE agent
2026-08-27 05:10:50 +00:00
parent f41847701c
commit bad96eb54a
6 changed files with 226 additions and 56 deletions

View File

@@ -1387,9 +1387,20 @@ premise was wrong.**
🟡 **But `END_PHASE`'s call site is the WRONG place to read the condition:**
all 12 Stage-02 `END_PHASE` sites sit in one stereotyped outro
(`wait_cmds_drained → fade_sound(3) → builtin85(3) → wait_s(3) → END_PHASE →
end_coroutine`). ▶️ **Next, and it is now the only thing in the way: read the
end_coroutine`). ~~▶️ **Next, and it is now the only thing in the way: read the
five branch handlers** `op10` (`0x82271598`), `op13` (`0x82271830`), `op14`,
`op21`, `op23`. The condition lives in the `op10`/`op13` poll loop upstream of
`op21`, `op23`.~~**(2026-08-27) DONE for the branches —
[structures/isl-branches](structures/isl-branches.md).** `op10`/`op11` are
signed/float COMPARE, writing three condition bits (0=EQ, 1=GT, 2=LT) to a
bitset at `phase+24`; `op13``op18` are the six relational branches
`beq/bne/blt/ble/bgt/bge` on those bits, targeting `[phase+232] + word@+4`
exactly like `op12`. All six relations present, each once — the completeness is
the check. Handler addresses come from the `bl` inside each dispatcher thunk;
guessing them at a fixed stride lands mid-function. ▶️ **Still open:** `op23`
(`0x82271C30`, takes a built-in's result to `phase+168`) and `op21`
(`0x82175C20`) are characterised but NOT named, and naming the branch does not
yet give each stage's clear condition — that needs the operand chain feeding
each compare. The condition lives in the `op10`/`op13` poll loop upstream of
the outro — e.g. phase 3 polls `unit_state(ADT308)` and branches back to
`0xFEB4` until it passes. Artefact: `data/isl-stage02-phase-ends.txt`.
* 🐛 **(2026-08-25) The nav fix is NOT fully reliable.** `dialog_up.py` works on