phase11: THE GTE TOKEN SHIPS — include/gtemac.h gains $8-$12, MAC, and a generic gte_cmd()

Finding 122 declared GTE rows a blocked class needing a harness token. The gap was smaller than
it looked: the header already covered $0-$7 and $13-$31 but NOT $8-$12, which is where
IR1/IR2/IR3 ($9/$10/$11) live, and it had no macro for the GTE command instruction itself.

Added gte_ldIR1/2/3, gte_stIR1/2/3, gte_ldMAC1/2/3, gte_stMAC1/2/3, and a GENERIC gte_cmd(field)
so any command whose 25-bit field has been read off the original can be emitted without first
earning a semantic name.

VERIFIED, NOT ASSUMED: the field values are confirmed by counting them over the whole binary
(0x486012 x51, 0x49E012 x11, 0x41E012 x4) and a test compilation emits gte_cmd(0x486012) ->
cop2 0x486012 -> 0x4A486012, exactly the original's word.

Five rows were blocked on this across three workers, all with complete or partial derivations.
The disposition matters as much as the token: three workers independently reached 'no amount of
spelling will find this' and declared it BLOCKED rather than grinding -- which is what made the
gap visible as a TOOLING problem instead of three separate source puzzles.
This commit is contained in:
Christopher Williams
2026-09-24 10:45:33 -04:00
parent 4e4afccdc9
commit d0384a6bca
2 changed files with 68 additions and 0 deletions
+29
View File
@@ -2337,3 +2337,32 @@ tell for a **`2^k − 1` divisor**, not for a large one.
time in the phase that one worker's finding closed another worker's negative, and it is the strongest
argument for the practice of **recording a named open question rather than a vague failure**: D's
write-up is what let C recognise the answer when it arrived from an unrelated row.
### 143. THE GTE TOKEN IS SHIPPED — the missing registers were `$8-$12`, and the command macro is generic
Finding 122 declared GTE rows a **blocked class needing a harness token**. The token now exists, and
the gap was smaller than it looked: `include/gtemac.h` already covered `$0-$7` and `$13-$31` **but
not `$8-$12`** — which is where **IR1/IR2/IR3 (`$9/$10/$11`)** live — and it had **no macro for the
GTE command instruction itself** (only `gte_nRTPS()`, a single proved value).
**Added:**
- `gte_ldIR1/2/3`, `gte_stIR1/2/3` (`mtc2`/`mfc2` `$9`/`$10`/`$11`)
- `gte_ldMAC1/2/3`, `gte_stMAC1/2/3` (`$25`/`$26`/`$27`)
- **`gte_cmd(field)`** — a **generic** macro, `__asm__ volatile ("cop2 " #field)`, so any command whose
25-bit field has been read off the original can be emitted without first earning a semantic name.
**Verified against the original, not assumed.** The field values are confirmed by counting them over
the whole binary: **`0x486012` ×51, `0x49E012` ×11, `0x41E012` ×4**, and a test compilation emits
`gte_cmd(0x486012)` → `cop2 0x486012` → **`0x4A486012`**, exactly the original's word.
**Two harness facts carried forward:** the `cop2` operand is the **25-bit field, not 26**
(`cop2 0x2486012` is an operand-range error — worker A), and a candidate **outside `src/` cannot use
the relative `#include "../include/gtemac.h"`** — use the absolute path or develop in `src/`.
**Five rows were blocked on this:** worker A's `0x800F9BC8` (268 B) and `0x800F3C60` (352 B),
worker B's `0x8001FAFC` (148 B), worker D's `0x80103434` (268 B) and `0x800F3E18`. **All five have
complete or partial derivations recorded.** They are now a batch, not a wall.
**The disposition matters as much as the token: these rows were correctly declared BLOCKED rather than
ground.** Three workers independently reached "no amount of spelling will find this" and stopped — and
that is what made the gap visible as a *tooling* problem instead of three separate source puzzles.
+39
View File
@@ -116,6 +116,29 @@
#define gte_ldDQA(v) __asm__ volatile ("ctc2 %0,$27" : : "r"(v))
#define gte_ldDQB(v) __asm__ volatile ("ctc2 %0,$28" : : "r"(v))
/* --- IR / MAC registers ($8-$12, $25-$27) -------------------------------- */
/* The header originally covered $0-$7 and $13-$31 but NOT $8-$12, which left
* five GTE rows blocked in Phase 11 (worker A's 0x800F9BC8 / 0x800F3C60,
* worker B's 0x8001FAFC, worker D's 0x80103434 / 0x800F3E18).
*
* IR1/IR2/IR3 = $9/$10/$11. Proved by worker B's 0x8001FAFC, which reads
* `mfc2 t0,$12 / mfc2 t1,$13 / mfc2 t2,$14` in the ORIGINAL; the IR1-3 loads
* there are $9/$10/$11 by the same field layout. MAC1-3 = $25/$26/$27 are
* read with `mfc2` after a command in worker A's 0x800F3C60. */
#define gte_ldIR1(v) __asm__ volatile ("mtc2 %0,$9" : : "r"(v))
#define gte_ldIR2(v) __asm__ volatile ("mtc2 %0,$10" : : "r"(v))
#define gte_ldIR3(v) __asm__ volatile ("mtc2 %0,$11" : : "r"(v))
#define gte_stIR1(r) __asm__ volatile ("mfc2 %0,$9" : "=r"(r))
#define gte_stIR2(r) __asm__ volatile ("mfc2 %0,$10" : "=r"(r))
#define gte_stIR3(r) __asm__ volatile ("mfc2 %0,$11" : "=r"(r))
#define gte_stMAC1(r) __asm__ volatile ("mfc2 %0,$25" : "=r"(r))
#define gte_stMAC2(r) __asm__ volatile ("mfc2 %0,$26" : "=r"(r))
#define gte_stMAC3(r) __asm__ volatile ("mfc2 %0,$27" : "=r"(r))
#define gte_ldMAC1(v) __asm__ volatile ("mtc2 %0,$25" : : "r"(v))
#define gte_ldMAC2(v) __asm__ volatile ("mtc2 %0,$26" : : "r"(v))
#define gte_ldMAC3(v) __asm__ volatile ("mtc2 %0,$27" : : "r"(v))
/* --- commands ------------------------------------------------------------ */
/* The 25-bit COP2 command field is written as `cop2 0x...`, which GNU as
@@ -123,6 +146,22 @@
* this batch is nRTPS = 0x180001 (0x80010810, 0x80018CB0). */
#define gte_nRTPS() __asm__ volatile ("cop2 0x180001")
/* Generic form, for the commands whose 25-bit field has been read off the
* original but whose semantic name is not yet earned. GNU as takes the field
* directly, so `gte_cmd(0x486012)` emits exactly 0x4A486012 -- the operand is
* the 25-bit field, NOT 26 (`cop2 0x2486012` is an operand-range error; worker
* A, Phase 11).
*
* Field values CONFIRMED present in the original (counted over the whole
* binary, Phase 11 coordinator):
* 0x486012 x51 -- used by worker A's 0x800F9BC8 and worker D's 0x80103434
* 0x49E012 x11 -- worker A's 0x800F3C60
* 0x41E012 x4 -- worker A's 0x800F3C60
* The low six bits are the GTE command number (0x12 = MVMVA in all three); the
* upper bits select the matrix / vector / translation / shift fields. Do NOT
* name them semantically without evidence -- name them by field value. */
#define gte_cmd(field) __asm__ volatile ("cop2 " #field)
/* --- BIOS call stubs ----------------------------------------------------- */
/* A PsyQ BIOS stub is `li a0,code` / `syscall`, with the compiler's own