Skip to main content

CPU_SNAPSHOT_VERSION

Constant CPU_SNAPSHOT_VERSION 

Source
pub const CPU_SNAPSHOT_VERSION: u8 = 4;
Expand description

Schema version for the CPU snapshot blob.

  • v1 (v0.9.0 ..): registers + interrupt latches + cycle bookkeeping.
  • v2 (W3-Stage-4 promotion, 2026-06-10): appends the master-clock substrate pipeline — master_clock (u64) + the mc_need_nmi / mc_prev_need_nmi / mc_run_irq / mc_prev_run_irq / mc_prev_nmi_line latches (1 byte each).
  • v3 (v2.0.0 “Timebase” rc.1, ADR 0028): the byte layout is IDENTICAL to v2 — cycles and master_clock are both still written, unchanged. What changes is the guarantee: as of the beta.1–beta.4 one-clock promote, cycles is no longer an independently-tracked counter (it is assigned from Bus::cycle_count() at every start_cycle, see cpu.rs), so a v3 blob’s cycles/master_clock pair is guaranteed internally consistent by construction in a way a pre-promote v1/v2 blob was only coincidentally consistent (kept in sync by parallel increments, not derivation). The version bump exists to make that distinction an explicit, checked contract rather than an implicit assumption — see ADR 0028 for the full MAJOR-boundary decision. v1/v2 blobs are no longer upconverted; Cpu::restore rejects any version other than CPU_SNAPSHOT_VERSION (the caller-side Nes::restore_inner already enforced this via a strict per-section equality check before this bump — the upconvert path removed here was dead code, unreachable through the only real caller).
  • v4 (v2.6.7 “Detent”): appends skip_irq_sample_q (1 byte), the one-cycle delay of skip_irq_sample that handle_interrupts reads. nesdev’s CPU_interrupts states that interrupts are polled before an instruction’s second cycle but not before the third cycle of a TAKEN BRANCH, so suppressing the poll needs the flag’s value on the previous cycle as well as this one. It is genuine emulation state read back on the next tick, not derivable from the rest of the blob — a restore that dropped it would resume with the NMI dispatch gate (the mc_prev_need_nmi copy; the edge latch mc_need_nmi runs every cycle regardless) re-opened a cycle early on any snapshot landing inside a taken branch. Serialized rather than allowlisted, which snapshot_schema_audit says has been the right answer every time it has come up.