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>
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
# Ch296 closeout — syscall 0x79 HLE; new arg-shape surfaces at syscall 0x77
|
||||
|
||||
**Status:** Closed. **Verdict from re-running qbert.elf:**
|
||||
`elf_first_unhandled_syscall (pc=0x00111D84 $v1=0x77 (=119))` — qbert
|
||||
advanced 27,996 → **28,101 retires (+105)** through the Ch296
|
||||
0x79 acceptance and into a new function entry with a markedly
|
||||
different arg shape.
|
||||
|
||||
## What landed
|
||||
|
||||
The 7th narrow $v0=0 case in the Ch273 dispatcher, plus the 5th
|
||||
runner-side observer. Mechanical recipe — identical structure to
|
||||
Ch289/290/291/293's extensions.
|
||||
|
||||
### Dispatcher case — `rtl/ee/ee_core_stub.sv`
|
||||
|
||||
```sv
|
||||
32'h0000_0079: 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 eight known syscall numbers (3C / 3D / 40 / 64 / 78 / 12 / 16
|
||||
/ 7A with $a0=0 and $a0=4 / 79) plus the unknown-halt path. Result:
|
||||
|
||||
```
|
||||
$v0_after_3C=0x001e0000 $v0_after_3D=0x00000000 $v0_after_64=0x00000000
|
||||
$v0_after_40=0x00000000 $v0_after_78=0x00000000 $v0_after_12=0x00000000
|
||||
$v0_after_16=0x00000000 $v0_after_7A=0x00000000 $v0_after_7A_a0_4=0x00020000
|
||||
$v0_after_79=0x00000000 $v1_at_halt=0x00007777
|
||||
```
|
||||
|
||||
### Runner observer — `tb_ee_core_elf_runner.sv`
|
||||
|
||||
The 5th observer. Captures first-PC + args + count. From qbert's
|
||||
run:
|
||||
|
||||
```
|
||||
syscall_0x79 = seen=1 count=2 first_pc=0x00111d94
|
||||
$a0=0x80000000 $a1=0 $a2=0 $a3=0x001328c0 → $v0=0
|
||||
```
|
||||
|
||||
**count=2** — qbert called syscall 0x79 twice during the run. The
|
||||
first call was at PC 0x00111d94 with the kseg0-base + global-ctx
|
||||
arg shape; the second is in nearby code (not separately observed).
|
||||
|
||||
## The new arg-shape signal at syscall 0x77
|
||||
|
||||
The next blocker has a **completely different arg shape** from
|
||||
every prior syscall we've HLE'd:
|
||||
|
||||
| Field | This blocker (0x77) | Prior pattern |
|
||||
|-------|---------------------|---------------|
|
||||
| PC | 0x00111D84 | 0x00111D24..D94 (similar region) |
|
||||
| $a0 | **0x001DFD50** (heap addr) | 0x80000000 (kseg0 base) OR 5 (slot id) |
|
||||
| $a1 | **1** | 0 or fn_ptr (0x00112AB0) |
|
||||
| $a2 | 0 | 0 or 0x20000000 |
|
||||
| $a3 | **20** (= 0x14) | **0x001328C0 (global ctx pointer)** |
|
||||
|
||||
**$a3 has flipped from "global ctx pointer" to "small int 20."**
|
||||
This is a strong signal that qbert is now in a *different
|
||||
subsystem* of its init/runtime, calling kernel services with
|
||||
different argument conventions. The kernel-handler-install /
|
||||
sema / sync chain we've been tracking through 0x78/0x12/0x16/0x7A/
|
||||
0x79 seems to be **done** (it threaded $a3=0x001328C0 throughout).
|
||||
|
||||
PS2 syscall 119 (0x77) in standard references is commonly cited
|
||||
as `SetVTLBRefillHandler` or similar — distinct from the
|
||||
DMAC/interrupt-handler family. The args ($a0=address, $a1=1,
|
||||
$a3=20) could plausibly be:
|
||||
- `SetVTLBRefillHandler(addr, ???, ???, 20)` — 20 might be a
|
||||
TLB entry count or buffer size
|
||||
- `RegisterLibraryEntries(addr, 1, 0, 20)` — a registration call
|
||||
with a count
|
||||
- A memory-allocation / heap-management call with a size
|
||||
|
||||
Codex framing: any of these can take `$v0=0` for the first pass.
|
||||
If qbert misbranches downstream, the arg shape gives more clues.
|
||||
|
||||
## qbert progression
|
||||
|
||||
| Chapter | Blocker | retire_count |
|
||||
|---|---|---|
|
||||
| Post-Ch295 ($a0-aware 0x7A) | syscall $v1=0x79 at 0x00111D94 | 27,996 |
|
||||
| **Post-Ch296 (syscall 0x79)** | **syscall $v1=0x77 at 0x00111D84** | **28,101 (+105)** |
|
||||
|
||||
Small advance (+105 retires) but the verdict-shape transition is
|
||||
clean: another mechanical syscall HLE chapter advanced exactly
|
||||
one step. The arg-shape change at the new blocker indicates a
|
||||
subsystem boundary.
|
||||
|
||||
## Ch297 framing — syscall 0x77
|
||||
|
||||
Per Codex's established precedent: narrow $v0=0 dispatcher case
|
||||
+ runner observer for syscall 0x77 (= 119). Mechanical.
|
||||
|
||||
**Notable for Ch297:** since the arg shape changed (no global ctx
|
||||
in $a3), worth instrumenting the observer to track $a0/$a1/$a3
|
||||
values — the args may CHANGE between calls (count > 1 might show
|
||||
different shapes per call).
|
||||
|
||||
Watch points for the Ch297 qbert run:
|
||||
- If `count_0x77 == 1` and qbert proceeds: good, continue
|
||||
mechanical recipe.
|
||||
- If `count_0x77 >> 1` with constant args: might be another wait
|
||||
loop (like Ch293's 0x7A spin) — autopsy needed.
|
||||
- If `count_0x77 > 1` with varying args: qbert is iterating over
|
||||
something — likely processing a list/table.
|
||||
|
||||
## Pattern review (26 chapters)
|
||||
|
||||
| Ch | Syscall | Args (qbert) | Pattern |
|
||||
|----|---------|--------------|---------|
|
||||
| 273 | 0x3C/0x3D/0x64 | init crt0 | initial dispatcher |
|
||||
| 285 | 0x40 | (no observer) | narrow $v0=0 |
|
||||
| 289 | 0x78 | (0, 0x130000, 0x20000000, ctx) | narrow $v0=0 + 1st observer |
|
||||
| 290 | 0x12 | (5, fn, 0, ctx) | handler-install |
|
||||
| 291 | 0x16 | (5, fn, 0, ctx) — identical to 0x12 | paired enable |
|
||||
| 293 | 0x7A | varying $a0 | wait-loop trigger |
|
||||
| 295 | 0x7A ($a0=4) | poll case | **$a0-aware HLE** (experimental) |
|
||||
| 296 | 0x79 | (kseg0_base, 0, 0, ctx) | finalize/adjacent |
|
||||
| **(Ch297)** | **0x77** | **(heap_addr, 1, 0, 20)** | **NEW subsystem — non-ctx args** |
|
||||
|
||||
The cumulative HLE coverage is now 9 distinct $v1 values. The
|
||||
runner observer library tracks 5 of them with full arg shape +
|
||||
counts. The Ch295 $a0-aware pattern is available for any future
|
||||
syscall where a single $v0 isn't sufficient.
|
||||
|
||||
## Files changed
|
||||
|
||||
- `rtl/ee/ee_core_stub.sv` — 1 new HLE case (~15 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 + SUMMARY line.
|
||||
|
||||
No new TB, no new Makefile target; regression count unchanged at
|
||||
**176/176**.
|
||||
|
||||
## Regression
|
||||
|
||||
**176/176 PASS** (unchanged from Ch295; no new TB).
|
||||
Reference in New Issue
Block a user