Files
retroDE_ps2/docs/ch301_closeout.md
T
thejayman77 ec82764bef Initial commit: retroDE_ps2 — first-of-its-kind PS2 GS FPGA core (DE25-Nano / Agilex 5)
RTL (GS rasterizer, EE core stub, platform bridge, LPDDR4B path), sim regression
(272 TBs), docs, and tooling. Copyrighted PS2 content (BIOS, game code, GS dumps,
and all dump-derived textures/traces) is excluded via .gitignore and stays local.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 20:10:50 -04:00

4.7 KiB

Ch301 closeout — syscall 0x17 HLE; second paired-call pattern surfaces at 0x13

Status: Closed. Verdict from re-running qbert.elf: elf_first_unhandled_syscall (pc=0x00112A64 $v1=0x13 (=19)) with arguments identical to the just-HLE'd 0x17 call. qbert advanced 28,708 → 28,726 retires (+18) through the syscall 0x17 and into a companion call.

The second paired-call pattern

Field Syscall 0x17 (Ch301) Syscall 0x13 (Ch302 blocker)
PC 0x00112A84 0x00112A64
$a0 0x00000005 0x00000005
$a1 0x00000000 0x00000000
$a2 0xFFFFFFFF 0xFFFFFFFF
$a3 0x00137568 0x00137568

All four args identical. This mirrors the Ch290/291 0x12/0x16 discovery — Add*Handler + Enable*Handler style paired calls. PS2 syscall 19 (0x13) and syscall 23 (0x17) are adjacent in the standard kernel table; plausibly a "set" + "register" pair for the same per-channel resource.

The two paired-call discoveries on the syscall track:

  • Ch290/291: 0x12 + 0x16 with (5, fn_ptr, 0, global_ctx)
  • Ch301/Ch302: 0x17 + 0x13 with (5, 0, -1, new_ctx_0x00137568)

Both involve $a0 = 5 (channel id). Different $a3 context pointers though — the second pair uses a different kernel-state region (0x00137568 vs 0x001328C0).

What landed

Dispatcher case — rtl/ee/ee_core_stub.sv

9th narrow $v0=0 case in the Ch273 dispatcher:

32'h0000_0017: begin
    regfile[2]   <= 32'd0;
    gpr128[2]    <= 128'd0;
    pc           <= pc + 32'd4;
    retire_pulse <= 1'b1;
    state        <= S_IFETCH_REQ;
end

TB extension — tb_ee_core_syscall_hle.sv

Standard 4-slot subcase + latch + assertion + display. The TB now covers ten known syscall numbers (3C / 3D / 40 / 64 / 78 / 12 / 16 / 7A with $a0=0 and $a0=4 / 79 / 77 / 17) plus the unknown-halt path.

Runner observer — tb_ee_core_elf_runner.sv

6th observer in the library, second to use the richer distinct-tuple tracking (after Ch297 0x77). From qbert's run:

syscall_0x17 = count=1 distinct_tuples=1 first_pc=0x00112a84
  $a0=0x00000005 $a1=0x00000000 $a2=0xffffffff $a3=0x00137568 → $v0=0
  0x17 tuple[0] = (...same...) count=1

Single call with the args Codex flagged. count=1 means no iteration, no spin — qbert called 0x17 once and moved on. The $a3 context-shift Codex worried about is captured cleanly in the SUMMARY for downstream analysis.

qbert progression

Chapter Blocker retire_count
Post-Ch300 (PCPYH) syscall $v1=0x17 at 0x00112A84 28,708
Post-Ch301 (syscall 0x17) syscall $v1=0x13 at 0x00112A64 (identical args) 28,726 (+18)

The +18 retires include the 0x17 retire + 17 instructions of glue code + the 0x13 syscall trap. PC walks backward (0x00112A84 → 0x00112A64), same pattern as Ch290/291's paired-call discovery.

Ch302 framing — syscall 0x13

Args identical to the 0x17 call we just HLE'd. High-confidence mechanical recipe:

  1. 10th narrow $v0=0 case in the dispatcher.
  2. Runner observer with distinct-tuple tracking (will likely confirm count=1 with the same args — confirmation surface).
  3. Standard 4-slot TB subcase.

If qbert then progresses normally, the paired-call pattern is fully unblocked. If it misbranches or spins, the symmetric arg shape suggests we'd need to model the actual per-channel state mutation — but that's Ch303+ if needed.

Pattern review (31 chapters)

Era Effect
Opcode-blocker (Ch271..286) exhausted
MMIO stubs (Ch287..288) exhausted
Syscall HLE narrow (~10 cases now) active
Narrow NOP-class (Ch286/292) exhausted
Investigation/unblock cycles (Ch293-295, Ch297-299) reusable pattern
MMI op extensions (Ch300+) ride Ch283 gpr128 seam
Paired-call discoveries 2 instances now (0x12/0x16, 0x17/0x13)

The "paired-call" pattern is now the second observed structural discovery (after the "$a0-aware HLE" of Ch295). Both came out of the runner observer instrumentation Codex pushed for. Each one shortens the next chapter's framing time because the args are predictable.

Files changed

  • rtl/ee/ee_core_stub.sv — 1 new HLE case (~25 LOC with comment).
  • sim/tb/integration/tb_ee_core_syscall_hle.sv — 4 new slots + 1 latch + 1 assertion + 1 display field.
  • sim/tb/integration/tb_ee_core_elf_runner.sv — 1 new observer block (with distinct-tuple tracking) + SUMMARY display.

No new TB, no new Makefile target; regression count unchanged at 177/177.

Regression

177/177 PASS (unchanged from Ch300; no new TB).