NVS295 / G98 EMULATOR - VERSION HISTORY
========================================

Eight files, in order:

v1_original_working.py
    The original "GPU EMPORIUM" script as first pasted. Simpler flat
    register-map design (single NVS295 class, enum-based Register map).
    Runs and PASSes as-is.

v2_upgrade_broken.py
    The "upgrade, not yet working" rewrite as first pasted (G98 class,
    PCI/PMC/PFIFO/PGRAPH split into real classes, register database with
    documented/reconstructed/emulator confidence tiers). BROKEN: PMC.NEW_ID
    bit-packing corrupts the device ID field, and validate() masks it with
    the wrong width regardless, so it can never pass. Also claims 128 MiB
    VRAM against a real 256 MiB spec.

v3_bugfix.py
    Fixed PMC.NEW_ID's bit layout (each field gets non-overlapping bits)
    and validate()'s mask (0xFFFF, not 0xFF). First version that PASSes.

v4_scaffold.py
    Added HardwareSpec: real published G98S die facts (process, transistor
    count, unit counts, clocks, memory config) plus formulas that derive
    theoretical throughput (pixel rate, texture rate, FLOPS, bandwidth) and
    check it against the manufacturer's published numbers — 4/4 match
    exactly. Fixed VRAM to the real 256 MiB. Added fill/blit timing
    (formula-based: pixels / unit count).

v5_elemental_units.py
    Replaced the formula-based timing with real per-instance objects:
    ALULane, TextureMappingUnit, RasterOutputUnit, generated in the exact
    counts HardwareSpec specifies (8/4/4). Fill and blit now dispatch every
    pixel through actual unit instances with their own cycle counters, and
    validate() cross-checks that the bottom-up simulation total matches the
    top-down formula exactly.

v6_subsystems.py
    Same treatment applied to four more subsystems: MemoryPartition/
    MemoryController (bus width -> partition count), CacheLine/L2Cache
    (cache size -> line count, real hit/miss tracking), a pre-generated
    128-entry PFIFO channel pool (documented G80-family channel count), and
    display heads generated from spec.display_outputs instead of two
    hand-written objects.

v7_registerfile_alu_isa.py
    PBUS's placeholder register offsets replaced with the real documented
    NV_PBUS_PCI_NV_0/1 shadow addresses. Added RegisterFile: one counter
    instance per register-database entry, uniform access instrumentation
    across every block. ALULane stopped being a color-passthrough stub and
    now executes a real tiny instruction set (MOV_IMM/MOV/ADD/MUL/OUT)
    against its own register file.

v8_agnostic_final.py
    PMC/PFIFO/PGRAPH/PBUS/DisplayHead no longer have their own read/write
    dispatch methods. Every register binds its behavior (a read_fn/write_fn
    callback, or plain storage if none) into one shared, engine-agnostic
    RegisterSpace at construction time. The top-level MMIO dispatcher
    shrank from ~60 lines of address-range branching to a single lookup —
    it no longer needs to know PMC/PFIFO/PGRAPH/PBUS/display exist as
    distinct blocks at all. This is the current, final version.

VERIFICATION
------------
v1 and v3 through v8 all print "HARD EMULATOR = PASS" when run with
`py <file> --quiet --ppm out.ppm`. v2 fails with the exact original bug
(AssertionError: bad PMC.NEW_ID device field: 0x098016fd).

v3 through v7 were reconstructed by replaying the exact edits made during
this session (not re-typed from memory) onto v2, checkpointing after each
turn. v8 was cross-checked by applying the final turn's edits to a copy of
v7 and diffing the result against the actual, independently-arrived-at
current file — they matched byte-for-byte after normalizing line endings,
which validates the entire replay chain back to v2.
