# rtl/gif_gs

GIF path and Graphics Synthesizer logic. Matches `docs/contracts/gif_gs.md`.

## Current contents

- `gs_stub.sv` — GS shell with **two architecturally distinct write ports**
  (Ch75 namespace split):
  - `reg_wr_*` — privileged-block writes (16-bit offset within `0x12000000`).
    Latches `BGCOLOR` (offset `0x00E0`) into `bg_{r,g,b}`; other offsets emit
    `EV_MODE`.
  - `gif_reg_*` — GIF A+D register-number writes (8-bit reg# + 64-bit data).
    Decodes `PRIM=0x00`, `RGBAQ=0x01`, `XYZF2=0x04`, `XYZ2=0x05`,
    `FRAME_1=0x4C`, `ZBUF_1=0x4E` into per-register 64-bit latches; unknown
    reg numbers emit `EV_MODE`.
  - No VRAM, no drawing yet — that is the next architectural step.

- `gif_path_stub.sv` — Wave 2 minimal GIF packet logger; project-local
  single-qword register-write format. Used by `tb_bgcolor_via_dma`.

- `gif_packed_stub.sv` — real PS2 GIFtag parser (Ch72-Ch75). Handles PACKED
  (FLG=0), REGLIST (FLG=1), IMAGE (FLG=2), DISABLE (FLG=3). The
  `REAL_AD_REG_MAP` parameter selects the A+D dispatch port:
  - `REAL_AD_REG_MAP=0` (default, back-compat) — drives `gs_stub.reg_wr_*`
    using a project-local 16-bit offset carried in `in_data[79:64]`.
  - `REAL_AD_REG_MAP=1` — drives `gs_stub.gif_reg_*` using the real PS2
    8-bit reg# carried in `in_data[71:64]`. Source-of-truth: PCSX2
    `GSRegs.h`.

## BGCOLOR reset value

At reset, `bg_{r,g,b}` default to `0x40` each (mid-grey) rather than black.
Rationale: this makes "gs_stub reset but no BGCOLOR write yet" visually
distinct from "video output disabled / black frame" in Milestone A. Override
is a `BGCOLOR` write from the test harness.

## Pitfall: namespace conflation

Ch74 conflated GIF A+D reg numbers with GS privileged-block offsets and
mapped e.g. `0x14`→PMODE@`0x0000`. That is fiction — those are separate
namespaces. Ch75 split them. **`ZBUF_1` is `0x4E`, not `0x4F` (that's
`ZBUF_2`).** When adding a new GIF-context register, source the reg# from
PCSX2 `GSRegs.h`, never from the privileged-block map.
