Files
retroDE_ps2/docs/ch418_authentic_display_mapping_prefit.md
thejayman77 ba74bbd5aa Snapshot: fog implementation + fidelity tooling baseline (pre bilinear-clamp fix)
Per-vertex GS fog end-to-end (gs_stub emit incl. persp_emit5, gs_prim_list_feeder
XYZ2->XYZF2 on PRIM.FGE, gs_make_sh3_scheduler_fixture.py F/FGE packing), new fog
TBs, fidelity attribution tooling. Functional baseline before removing the dead
bilinear lerp8 clamps (Codex: 161-node comb loop -> -0.042ns setup fail).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 19:56:46 -04:00

3.6 KiB

Ch418 — authentic SH3 display presentation mapping (prefit)

Objective

Fix the large presentation mismatch between the accepted Ch417 framebuffer and the PCSX2 224139 frame without changing any rasterized framebuffer byte. Ch418 is scanout-only: it maps the captured GS display source onto the board's 640x480 HDMI/VGA active raster.

Captured register evidence

The vendored PCSX2 GSPrivRegSet layout was used to decode the initial and all eight per-vsync register snapshots in dump 224139. The active context is DISPLAY2 (PMODE.EN2=1), stable in every snapshot:

  • DISPFB2 = 0x0001000000009000 (FBP rotates later), FBW=8, PSM=1, DBX=0, DBY=32;
  • DISPLAY2 = 0x0037f9ff0203228c, DX=652, DY=50, MAGH=4, MAGV=0, DW=2559, DH=895.

Therefore the display source is 512 pixels wide (FBW*64) and 448 interlaced source lines beginning at framebuffer line 32. DISPLAY2 expands each source pixel to five VCKs (MAGH+1) across 2560 display clocks. Reducing that captured display to the board raster gives the exact integer maps:

source_x = floor(output_x * 4 / 5)       // 0..639 -> 0..511
source_y = 32 + floor(output_y * 14 / 15) // 0..479 -> 32..479

RTL change

gs_lpddr_scanout_lb now has opt-in divider-free presentation mapping:

  • a five-state horizontal phase accumulator implements 512 -> 640;
  • a fifteen-state vertical phase accumulator implements 448 -> 480;
  • vertical prefetch starts at captured DBY=32;
  • buffer parity, prefetch throttling, and underflow checks use mapped source y;
  • all default parameters retain the legacy 1:1 behavior.

Only GS_SH3_LPDDR_FB_640 enables the mapping in the DE25 top. The OSD remains in the 640x480 output domain and the LPDDR framebuffer/dump remains byte-exact to Ch417.

The mapper contains no / or variable multiply in synthesizable RTL. Its datapath is one small phase decrement and one coordinate increment per output pixel/line, both in the 25 MHz video domain.

Prefit verification

  • New two-axis scanout oracle: 600/600 RGB pixels exact, including horizontal repeats, vertical repeats, DBY offset, alternating line buffers, zero underflow, and zero AXI read errors.
  • Legacy PSMCT16 line-buffer regression: PASS, underflow=0, read errors=0.
  • Legacy PSMCT32 line-buffer/concurrency regression: 49,152 pixels exact, underflow=0, read errors=0, 325/325 probes good.
  • The actual QSF profile macros plus USE_QSYS_TOP elaborate cleanly under Icarus (unavailable vendor IP treated as black boxes); no RTL binding or syntax errors.
  • git diff --check and the preview utility's Python compile pass.

Expected HDMI preview:

sim/data/top_psmct32_raster_demo/sh3_zsrt139f17_ch418_scanout.png

Preview SHA-256:

b710aa7a09db6992faacdaa5a6257d490f1d4fa0112f6c6d20fc388f4b580a63

The preview moves the already-rendered lamppost and character onto the PCSX2 landmark positions. Full-frame RGB MAE rises from 20.12 to 21.02 because the board is still missing large bright/background draws that the transform now spreads over more output pixels; that global statistic is a coverage metric at this stage, not an alignment metric. The mapping is justified by the captured registers and visible landmark alignment, not by claiming a false MAE win.

Owner fit gate

Ready for the owner-controlled Quartus 26.1 GUI compile. Required acceptance:

  • Analysis & Synthesis succeeds with no inferred display divider;
  • setup, hold, recovery, removal, and minimum pulse all close;
  • after deployment, the unchanged 263-epoch board run still passes and the framebuffer dump remains byte-identical to Ch417;
  • HDMI shows the 512x448 captured source presented across 640x480.