Skip to main content

Mapper

Trait Mapper 

Source
pub trait Mapper: Send {
Show 58 methods // Required methods fn cpu_read(&mut self, addr: u16) -> u8; fn cpu_write(&mut self, addr: u16, value: u8); fn ppu_read(&mut self, addr: u16) -> u8; fn ppu_write(&mut self, addr: u16, value: u8); fn current_mirroring(&self) -> Mirroring; fn save_state(&self) -> Vec<u8> ⓘ; fn load_state(&mut self, data: &[u8]) -> Result<(), MapperError>; // Provided methods fn cpu_read_unmapped(&self, addr: u16) -> bool { ... } fn notify_floating_read(&mut self, _addr: u16, _value: u8) { ... } fn notify_ppu_register_write(&mut self, _addr: u16, _value: u8) { ... } fn nametable_unfolded(&self) -> bool { ... } fn cpu_read_driven_mask(&self, _addr: u16) -> u8 { ... } fn ppu_read_sprite(&mut self, addr: u16) -> u8 { ... } fn chr_phys(&self, _addr: u16) -> Option<u32> { ... } fn chr_reads_are_pure(&self) -> bool { ... } fn set_mmc3_revision_override( &mut self, _revision: Option<Mmc3Revision>, ) -> bool { ... } fn nametable_fetch(&mut self, _addr: u16) -> Option<u8> { ... } fn nametable_write(&mut self, _addr: u16, _value: u8) -> bool { ... } fn peek_ex_attribute(&mut self, _v: u16) -> Option<ExAttribute> { ... } fn bg_split_state( &mut self, _scanline_y: u16, _coarse_x: u16, ) -> Option<BgSplitState> { ... } fn nametable_address(&self, addr: u16) -> u16 { ... } fn notify_a12(&mut self, _level: bool) { ... } fn notify_a12_at_sub_dot(&mut self, level: bool, _sub_dot: u8) { ... } fn notify_cpu_cycle(&mut self) { ... } fn reset(&mut self) { ... } fn notify_frame_event(&mut self, _events: MapperFrameEvents) { ... } fn notify_scanline_start(&mut self) { ... } fn notify_vblank(&mut self) { ... } fn enable_vs_dual_wram(&mut self) { ... } fn set_vs_dual_sub(&mut self) { ... } fn drain_vs_dual_wram_writes(&mut self, dst: &mut Vec<(u16, u8)>) { ... } fn take_vs_dual_wram_writes(&mut self) -> Vec<(u16, u8)> { ... } fn apply_vs_dual_wram_write(&mut self, offset: u16, value: u8) { ... } fn take_vs_dual_wram(&mut self) -> Option<Box<[u8]>> { ... } fn set_vs_dual_wram(&mut self, wram: Box<[u8]>) { ... } fn irq_pending(&self) -> bool { ... } fn irq_acknowledge(&mut self) { ... } fn mix_audio(&mut self) -> i32 { ... } fn caps(&self) -> MapperCaps { ... } fn has_hardwired_mirroring(&self) -> bool { ... } fn disk_side_count(&self) -> usize { ... } fn inserted_disk_side(&self) -> Option<usize> { ... } fn set_disk_side(&mut self, _side: Option<usize>) { ... } fn sram(&self) -> &[u8] ⓘ { ... } fn sram_mut(&mut self) -> &mut [u8] ⓘ { ... } fn save_data(&self) -> &[u8] ⓘ { ... } fn save_data_mut(&mut self) -> &mut [u8] ⓘ { ... } fn clear_save_data(&mut self) { ... } fn enable_fds_trace(&mut self) { ... } fn take_fds_trace(&mut self) -> Vec<FdsTraceRec> { ... } fn disk_image_bytes(&self) -> Vec<u8> ⓘ { ... } fn disk_is_dirty(&self) -> bool { ... } fn clear_disk_dirty(&mut self) { ... } fn set_disk_write_protected(&mut self, _protected: bool) { ... } fn nsf_song_count(&self) -> u8 { ... } fn nsf_current_song(&self) -> u8 { ... } fn nsf_set_song(&mut self, _song: u8) -> bool { ... } fn debug_info(&self) -> MapperDebugInfo { ... }
}
Expand description

Trait implemented by every cartridge mapper.

Visible read/write addresses follow docs/architecture.md §Per-memory-access fanout. The PPU bus call covers the whole $0000-$3FFF address space because nametable mirroring is mapper-controlled (see docs/mappers.md §Mirroring).

IRQ-emitting mappers signal pending IRQs via Mapper::irq_pending; the CPU bus polls this on the same cycle it polls APU/external IRQs.

All trait methods are &mut self because every mapper has at least some internal state — open-bus latch, bank registers, IRQ counters, etc. — even on an apparent read.

Required Methods§

Source

fn cpu_read(&mut self, addr: u16) -> u8

Read a byte from the CPU address space $4020-$FFFF.

Source

fn cpu_write(&mut self, addr: u16, value: u8)

Write a byte to the CPU address space $4020-$FFFF.

Source

fn ppu_read(&mut self, addr: u16) -> u8

Read a byte from the PPU address space $0000-$3FFF (pattern table

  • nametable mirror window). Used as the BG-side / generic fetch path.
Source

fn ppu_write(&mut self, addr: u16, value: u8)

Write a byte to the PPU address space $0000-$3FFF.

Source

fn current_mirroring(&self) -> Mirroring

Returns the mapper’s current effective mirroring layout.

Most mappers report the static mirroring set in the cartridge header; mappers with runtime mirroring control (MMC1, MMC3, AxROM, …) report the live state.

Source

fn save_state(&self) -> Vec<u8> ⓘ

Encode the mapper’s mutable state into a tagged save-state blob.

Source

fn load_state(&mut self, data: &[u8]) -> Result<(), MapperError>

Decode a previously Mapper::save_state blob back into the mapper.

§Errors

Returns MapperError when the blob is truncated, has the wrong version tag, or otherwise fails internal consistency checks.

Provided Methods§

Source

fn cpu_read_unmapped(&self, addr: u16) -> bool

Returns true when addr is not wired to mapper-resident memory — i.e. when cpu_read(addr) returns junk and the bus should fall through to the open-bus latch instead of overwriting it. The CPU databus is left floating in this case, so the most recently driven byte stays visible to the next read.

Default impl covers stock NROM-class boards: the entire $4020-$5FFF window is unmapped (no PRG-RAM, no mapper registers), and $6000-$7FFF is unmapped exactly when the board has no save RAM to put there (Self::sram is empty). $8000-$FFFF is PRG-ROM and always mapped. Mappers that DO map any subset of $4020-$5FFF (MMC5 audio + ExRAM, FME-7 IRQ control, VRC family register banks, etc.) must override this to return false for their mapped sub-ranges so the bus uses the real value; a board with ROM or readable registers at $6000-$7FFF but no save RAM must override it for that window.

The $6000-$7FFF rule is v2.7.2 (core audit §5.5). Before it, every board without RAM there read a made-up $00 instead of open bus; a sweep over every mapper number found 205 board variants doing so (tests/prg_ram_window_open_bus.rs). It leans on v2.7.1’s contract that every board holding save RAM exposes it through sram() (tests/battery_sram_exposed.rs), and the same test fails any board the rule would float while it actually drives data there.

This is the canonical hardware oracle for AccuracyCoin’s CPU Behavior :: Open Bus Test 1 (LDA $5000 should read $50, not $00).

Source

fn notify_floating_read(&mut self, _addr: u16, _value: u8)

A CPU read the mapper declined (Self::cpu_read_unmapped) has just completed, and value is what floated on the bus.

Only GTROM (mapper 111) uses it: its register latches on any CPU access to its window, so “reading from the register effectively writes the value of open bus” (nesdev_wiki/output/GTROM.md). Called only on the unmapped path, so PRG fetches never pay for it. Default: nothing. Added in v2.9.6.

Source

fn notify_ppu_register_write(&mut self, _addr: u16, _value: u8)

The CPU wrote value to the PPU register window ($2000-$3FFF), at the undecoded address addr.

Only MMC5 (mapper 5) uses it: the chip is “known to listen to the same address as the PPU to find out when to enable the 8x16 sprite mode”, decoding $2000 and $2001 fully, so a write to a mirror such as $2008 is not seen (nesdev_wiki/output/MMC5.md). The address is passed undecoded for that reason. Called once per PPU register write, never per cycle. Default: nothing. Added in v2.9.9.

Source

fn nametable_unfolded(&self) -> bool

Whether PPU $3000-$3EFF is independent RAM on this cartridge rather than a mirror of $2000-$2EFF.

When true, Self::nametable_fetch and Self::nametable_write receive $3000-$3EFF unfolded. Two boards need it: GTROM’s “bonus RAM” (GTROM.md) and UNROM 512’s four-screen board (UNROM_512.md), whose nametable RAM covers the whole $2000-$3EFF window. Only $2007 accesses reach $3xxx (rendering fetches never do), and the PPU asks only for those, so rendering pays nothing. Default: false, the console’s own mirroring. Added in v2.9.6.

Source

fn cpu_read_driven_mask(&self, _addr: u16) -> u8

Which data bits a mapped read in the register window ($4020-$5FFF) actually drives; the rest float and keep the bus’s open-bus value.

A register that drives only part of the byte is common on cheap ASICs: the Sachen SA-020A (mappers 150 / 243) returns its 3-bit registers on D2-D0 and leaves D7-D3 floating (nesdev_wiki/INES_Mapper_150.xhtml). Returning the undriven bits as 0 from Self::cpu_read would let the bus latch those zeros; this mask lets it keep what was floating there instead (core audit §4.5).

Consulted only for $4020-$5FFF, so it costs nothing on the $6000-$FFFF fetches that dominate CPU time. Default: all 8 bits.

Source

fn ppu_read_sprite(&mut self, addr: u16) -> u8

Read a byte from the PPU pattern-table window ($0000-$1FFF) on behalf of a sprite tile fetch. MMC5 in 8x16 sprite mode uses a separate set of CHR bank registers ($5120-$5127) for sprite fetches; other mappers default to forwarding to Mapper::ppu_read.

Source

fn chr_phys(&self, _addr: u16) -> Option<u32>

HD-pack tile identity: the ABSOLUTE post-banking offset into CHR-ROM for a pattern-space address $0000-$1FFF (Some(offset)), or None for CHR-RAM (content-hashed instead). tile_index = offset / 16 is the key Mesen uses for CHR-ROM <tile> replacements. Default None so an unported mapper falls back to the content-hash path (no worse than before); the common CHR-ROM mappers override it by exposing their internal CHR mapping.

Source

fn chr_reads_are_pure(&self) -> bool

v3.1.0 (T-SPRITE-LIMIT) — whether Self::ppu_read and Self::ppu_read_sprite on $0000-$1FFF change nothing but return a byte. true (the default) lets the PPU’s “disable sprite limit” option make extra, display-only pattern reads on this board.

Override to false for any board whose CHR read has an effect: a latch that switches banks on a tile (MMC2, MMC4), an IRQ counter clocked by reads (the J.Y. ASIC), or address bits latched from the read (Bandai 96, Nanjing 163). every_board_that_claims_pure_chr_reads_has_them checks the claim against save_state for every mapper id, so a new impure board that keeps the default fails a test rather than letting the option change emulation.

Source

fn set_mmc3_revision_override( &mut self, _revision: Option<Mmc3Revision>, ) -> bool

v3.1.0 (T-MMC3-NEC-OVERRIDE, ACC-13) — force an MMC3’s IRQ revision (Some), or return to the one its header selected (None). Returns whether this board is an MMC3 that applied it; every other board ignores it (the default). Lets an iNES 1.0 dump, which cannot name its MMC3 revision, run under the alternate (Nec) behaviour.

Source

fn nametable_fetch(&mut self, _addr: u16) -> Option<u8>

Optionally synthesize a nametable byte for addr ($2000-$3EFF).

When the mapper returns Some(v), the PPU uses v directly and skips its CIRAM read. MMC5 uses this for “fill mode” ($5105 per-1KiB selector value 0b11), where every nametable-byte fetch returns the fill tile ($5106) and every attribute-byte fetch returns a 2-bit attribute ($5107) replicated 4 ways.

Default returns None (mapper does not synthesize; PPU reads CIRAM).

Source

fn nametable_write(&mut self, _addr: u16, _value: u8) -> bool

Optionally absorb a nametable write for addr ($2000-$3EFF) directly into mapper-resident storage.

Returns true if the mapper consumed the write (PPU should NOT also write its CIRAM). MMC5 uses this for ExRAM-mapped nametables and for fill mode (where writes are silently dropped).

Default returns false (PPU continues with the CIRAM write path).

Source

fn peek_ex_attribute(&mut self, _v: u16) -> Option<ExAttribute>

Optionally provide per-tile extended attribute + CHR-bank override for the BG tile currently being fetched.

v is the PPU’s loopy-v register value at NT-byte fetch time (fetch_nt); the lower 12 bits encode the 32x30 tile coordinate. MMC5 in $5104 mode 01 returns Some here. The PPU uses the returned palette to override the AT byte. The mapper itself caches the chr_bank internally so that the subsequent BG pattern fetches (ppu_read calls during the same 8-dot fetch group) consult it instead of the standard BG bank registers.

Default returns None (no extended attribute mode active).

Source

fn bg_split_state( &mut self, _scanline_y: u16, _coarse_x: u16, ) -> Option<BgSplitState>

Optionally redirect a BG fetch group into a vertical split-screen “alt region”.

Called by the PPU at the NT-byte fetch boundary of each 8-dot BG fetch group, once per tile column (32 times per visible scanline). scanline_y is the current visible-scanline index in 0..=239 (the pre-render line passes 0 here to keep the path branchless). coarse_x is the loopy-v coarse-X (0..=31) for the tile about to be fetched.

Returning Some(state) instructs the PPU to use the supplied nt_addr / at_addr / fine_y instead of those derived from v, and instructs the mapper to internally latch the CHR bank for the pattern fetches that immediately follow.

Default returns None.

Source

fn nametable_address(&self, addr: u16) -> u16

Resolve a nametable address in $2000-$3EFF to a CIRAM offset in 0..0x800. The PPU owns the 2 KiB CIRAM and uses this hook to apply per-mapper mirroring without giving the mapper direct access to the console-side VRAM.

Default impl applies the mirroring reported by Mapper::current_mirroring via crate::Mirroring::physical_bank. Mappers with on-cart 4-screen VRAM (Gauntlet, Rad Racer II) can override this; the lockstep bus will trampoline the read/write back through the mapper for any offset outside 0..0x800 if needed (Phase 4).

Source

fn notify_a12(&mut self, _level: bool)

Notify of a PPU A12 line transition. Default no-op; MMC3 / MMC5 override this for IRQ counter clocking.

Source

fn notify_a12_at_sub_dot(&mut self, level: bool, _sub_dot: u8)

Notify of a PPU A12 line transition with the current sub-dot of the host CPU cycle (0 / 1 = M2-low half; 2 = M2-high half). Default impl falls through to Self::notify_a12 so existing mappers compile unchanged; MMC3 overrides this for the M2-phase-aware IRQ-output propagation delay required by mmc3_test_2/4-scanline_timing sub-test #3 (C1 step B4 successor).

Source

fn notify_cpu_cycle(&mut self)

Notify of a CPU cycle. Default no-op; VRC2/4/6, FME-7, Namco 163 override this for IRQ counter clocking.

Source

fn reset(&mut self)

The console’s RESET button (a soft reset, not a power cycle).

A cartridge sees reset only on the boards that wire the CIC’s reset line, or /RESET itself, into their logic, so the default does nothing and almost every board keeps its registers across a reset, exactly as on a console. The boards that clear something are documented per page: mapper 37’s outer latch (INES_Mapper_037.md), mapper 45’s outer registers, NES-EVENT’s PRG lock (mapper 105), the 76-in-1 BMC’s two registers (mapper 226, since v2.9.8), and Action 52’s register (mapper 228). Added in v2.9.6; a power cycle rebuilds the mapper instead and never calls this.

Source

fn notify_frame_event(&mut self, _events: MapperFrameEvents)

Notify the mapper of the APU frame-counter events fired on the current CPU cycle (quarter-frame envelope clock, half-frame length clock). Only on-cart audio extensions that re-use the 2A03 frame counter cadence need to handle this (MMC5 audio’s two pulse channels). Default no-op.

Source

fn notify_scanline_start(&mut self)

Notify the mapper that the PPU is starting a new rendered scanline.

Called by the PPU at the start of each visible scanline (and the pre-render line) before any tile fetches happen. MMC5 uses this to drive its scanline IRQ counter (which clocks at PPU cycle 4 of each rendered line — different from MMC3’s A12-edge-driven counter).

Default is a no-op; only mappers with scanline-counter IRQs override.

Source

fn notify_vblank(&mut self)

Notify the mapper that the PPU has entered vertical blank.

MMC5 uses this to clear its “in-frame” flag (bit 6 of $5204). Default no-op.

Source

fn enable_vs_dual_wram(&mut self)

v2.0.0 beta.5 (Vs. DualSystem): provision the board’s shared 2 KiB work RAM at $6000-$7FFF (mirrored across the 8 KiB window — MAME vsnes.cpp: map(0x6000, 0x67ff).mirror(0x1800).ram()). Only the Vs. System board (mapper 99) implements this — the DualSystem cabinets carry a 2 KiB RAM shared between the two consoles, absent on UniSystem carts (whose $6000 window stays open bus, byte-identically). Called by the VsDualSystem wrapper at construction on both consoles: each console holds its own COPY, and the wrapper converges the copies by draining the write log (below) after every stepped instruction — MAME’s fully-shared .share("nvram") model at soft-lockstep granularity. Default no-op.

Source

fn set_vs_dual_sub(&mut self)

v2.0.0 beta.5 (Vs. DualSystem): mark this mapper instance as the cabinet’s SUB console — it banks the second 32 KiB PRG half and the upper CHR pages (the two CPUs run DIFFERENT programs; MAME balonfgt loads distinct sub-region ROMs, Mesen2 uses prgOuter = IsVsMainConsole() ? 0 : 4). Applied by the VsDualSystem wrapper at construction, like the bus’s sub identity. Default no-op.

Source

fn drain_vs_dual_wram_writes(&mut self, dst: &mut Vec<(u16, u8)>)

v2.0.0 beta.5 (Vs. DualSystem): drain this console’s shared-WRAM write log — every (offset, value) the CPU wrote to the window since the last drain, in order — by APPENDING into dst (never clearing it first). The wrapper replays them into the partner’s copy (Self::apply_vs_dual_wram_write), which is what makes the RAM behave as ONE simultaneously-shared memory (MAME’s model; nesdev also documents a $4016-bit-1 access mux, but MAME — where the four DualSystem games verifiably run — shares the RAM unconditionally, and Balloon Fight’s boot handshake requires the partner to see writes made while the mux would deny it access).

Implementations MUST drain their internal log via Vec::drain (or equivalent) rather than replacing it, so the log’s own allocated capacity is retained across calls — pump_comms calls this after EVERY stepped instruction on a DualSystem cart, so a reallocating drain here is a real hot-path allocation, not a theoretical one. Default: no-op (boards without the dual WRAM).

Source

fn take_vs_dual_wram_writes(&mut self) -> Vec<(u16, u8)>

Convenience wrapper around Self::drain_vs_dual_wram_writes for callers that don’t already hold a reusable buffer (diagnostics, tests) — NOT used by the hot pump_comms path, which owns and reuses its own scratch buffer instead.

Source

fn apply_vs_dual_wram_write(&mut self, offset: u16, value: u8)

v2.0.0 beta.5 (Vs. DualSystem): replay one partner-console write into this console’s copy of the shared WRAM (see Self::take_vs_dual_wram_writes). Does NOT re-log the write (no echo loop). Default no-op.

Source

fn take_vs_dual_wram(&mut self) -> Option<Box<[u8]>>

v2.0.0 beta.5 (Vs. DualSystem): take the console’s shared-WRAM copy (used by the wrapper’s snapshot-restore normalization — the two copies are re-converged from one buffer after a restore). Returns None on boards without the dual WRAM. Default None.

Source

fn set_vs_dual_wram(&mut self, wram: Box<[u8]>)

v2.0.0 beta.5 (Vs. DualSystem): install a shared-WRAM copy (the other half of the restore normalization). Default no-op.

Source

fn irq_pending(&self) -> bool

Returns true if the mapper is currently asserting an IRQ.

Source

fn irq_acknowledge(&mut self)

Acknowledge a pending IRQ. Default no-op; mappers that latch IRQ state override this.

Source

fn mix_audio(&mut self) -> i32

Return one signed audio sample for mappers with on-cart audio (VRC6/7, MMC5, Sunsoft 5B, Namco 163, FDS). Default returns silence.

i32, widened from i16 in v2.2.3 (A1). The bus scales this by / 65536.0 into roughly the same [-0.5, 0.5] range as the APU mixer’s own output, so the old i16 return capped a chip’s representable level at 32767 / 65536 ≈ 0.5. That was fine for every board except the Sunsoft 5B, whose logarithmic DAC needs ~3.6x the 2A03 pulse at full volume — and three simultaneous full-volume tones (Gimmick!, Hebereke) several times more. The 5B’s absolute level was therefore a documented, deliberately un-calibrated gap purely because the return type could not hold it. Widening the type is what unblocks it; see docs/accuracy-ledger.md §Expansion-audio levels and SUNSOFT5B_MIX_SCALE.

Boards other than the 5B return exactly the values they always did — the widening is representational only and changes no mixed output.

Source

fn caps(&self) -> MapperCaps

v2.8.0 Phase 4 — the mapper’s per-CPU-cycle capability flags.

The bus fans four virtual calls out to the mapper EVERY CPU cycle (~30 k/frame each): Self::notify_cpu_cycle, Self::mix_audio, Self::notify_frame_event, and Self::irq_pending. For most boards all four are the default no-ops, so the bus caches these flags at construction and skips the dispatch entirely.

The contract is mechanical: a flag may be false ONLY when the mapper does not override the corresponding default method (skipping a default no-op is provably byte-identical). The default returns MapperCaps::ALL, so an unannotated mapper keeps every dispatch — always correct, just slower.

Source

fn has_hardwired_mirroring(&self) -> bool

Whether this mapper’s nametable mirroring is hardwired by the cartridge (solder pads / the iNES header bit) rather than controlled by the mapper’s own registers at runtime.

This gates whether an external mirroring correction (e.g. a per-game database entry, applied via Nes::set_mirroring_override) may be honored. A static override is only meaningful for a hardwired board whose header bit can be wrong; forcing a static mirroring onto a mapper that switches mirroring itself (MMC1/3/5, AxROM, VRC, Sunsoft FME-7, Namco 163, …) corrupts its rendering — e.g. AxROM‘s mid-frame single-screen A↔B flip that draws Wizards & Warriors’ status bar, whose GoodNES-derived game-DB row lists a spurious Horizontal that, when force-applied, blanks the bottom of the screen and hangs the game.

Default: false (assume the mapper controls its own mirroring). This is the safe default — a mapper that omits an annotation merely declines a rarely-needed, cosmetic header correction; it can never break a working game. Only the classic fixed-mirroring discrete boards (NROM, UxROM, CNROM, GxROM, …) override this to true.

Source

fn disk_side_count(&self) -> usize

Number of disk sides in the inserted image (0 for non-FDS mappers).

Source

fn inserted_disk_side(&self) -> Option<usize>

The currently inserted disk side index, or None when ejected (or for non-FDS mappers).

Source

fn set_disk_side(&mut self, _side: Option<usize>)

Insert disk side i (Some) or eject the disk (None). No-op for non-FDS mappers; an out-of-range index is ignored by the FDS device.

Source

fn sram(&self) -> &[u8] ⓘ

Returns a reference to the mapper’s internal SRAM/PRG-RAM. By default, returns an empty slice if unsupported.

Source

fn sram_mut(&mut self) -> &mut [u8] ⓘ

Returns a mutable reference to the mapper’s internal SRAM/PRG-RAM. By default, returns an empty mutable slice if unsupported.

Source

fn save_data(&self) -> &[u8] ⓘ

The cartridge’s non-volatile data: what a battery save persists and a power cycle keeps. For almost every board that is its battery-backed RAM, Self::sram, and the default says so.

Self-flashable boards differ (v2.9.6). GTROM and a flashable UNROM 512 save by rewriting their own PRG flash, so their save is the flash image, and they have no RAM at $6000 at all. Keeping the two apart is the point. sram() goes on meaning “the RAM in the $6000 window”, which the open-bus rule, the libretro memory map and RetroAchievements all rely on. Only the save paths read this.

Source

fn save_data_mut(&mut self) -> &mut [u8] ⓘ

Mutable Self::save_data, for loading a save.

Source

fn clear_save_data(&mut self)

Return the save data to the state of a cartridge that has never been saved to. That is zeroed RAM by default. On a flash board it is the PRG image as loaded, since a zero-filled flash would be a ROM with no program in it. A power-on movie calls this (power_on_for_movie).

Source

fn enable_fds_trace(&mut self)

Start recording the diagnostic FDS read-stream trace (off by default; observation-only). No-op for non-FDS mappers. See crate::FdsTraceRec.

Source

fn take_fds_trace(&mut self) -> Vec<FdsTraceRec>

Drain the accumulated FDS read-stream trace records (empty for non-FDS mappers / when tracing was never enabled).

Source

fn disk_image_bytes(&self) -> Vec<u8> ⓘ

Re-serialize the (possibly-modified) disk image to its byte layout for host persistence. Returns an empty vector for non-FDS mappers.

Source

fn disk_is_dirty(&self) -> bool

Whether the disk image has unsaved writes. Always false for non-FDS mappers.

Source

fn clear_disk_dirty(&mut self)

Clear the disk dirty flag (a host calls this after persisting). No-op for non-FDS mappers.

Source

fn set_disk_write_protected(&mut self, _protected: bool)

Mark the inserted disk read-only (true) or writable (false). No-op for non-FDS mappers.

Source

fn nsf_song_count(&self) -> u8

Number of selectable songs (0 for a non-NSF mapper).

Source

fn nsf_current_song(&self) -> u8

The currently-selected 0-based song (0 for a non-NSF mapper).

Source

fn nsf_set_song(&mut self, _song: u8) -> bool

Select a 0-based song. Returns true if this is an NSF mapper (so the caller knows to re-run the reset that re-vectors into the driver’s init). Default no-op returning false.

Source

fn debug_info(&self) -> MapperDebugInfo

Surface read-only debug info for the UI. Override per mapper to expose bank registers, IRQ counters, etc. Default returns a minimal entry naming the mapper id.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl Mapper for Action52M228

Source§

impl Mapper for Action53M28

Source§

impl Mapper for AxRom

Source§

impl Mapper for Bandai74

Source§

impl Mapper for Bandai96

Source§

impl Mapper for Bandai152

Source§

impl Mapper for BandaiFcg

Source§

impl Mapper for Bitcorp38

Source§

impl Mapper for Bxrom241

Source§

impl Mapper for Caltron41

Source§

impl Mapper for Camerica

Source§

impl Mapper for Camerica232

Source§

impl Mapper for CnRom

Source§

impl Mapper for CnRom185

Source§

impl Mapper for Cne240

Source§

impl Mapper for ColorDreams

Source§

impl Mapper for Cony83

Source§

impl Mapper for Cprom

Source§

impl Mapper for Cufrom29

Source§

impl Mapper for Daou156

Source§

impl Mapper for Decathlon244

Source§

impl Mapper for DiscreteMapper

Source§

impl Mapper for Fds

Source§

impl Mapper for Fme7

Source§

impl Mapper for FongShenBang246

Source§

impl Mapper for Gtrom111

Source§

impl Mapper for GxRom

Source§

impl Mapper for Hengedianzi177

Source§

impl Mapper for Hengedianzi179

Source§

impl Mapper for Inl31

Source§

impl Mapper for Irem77

Source§

impl Mapper for Irem97

Source§

impl Mapper for IremG101

Source§

impl Mapper for IremH3001

Source§

impl Mapper for Jaleco72

Source§

impl Mapper for Jaleco86

Source§

impl Mapper for Jaleco87

Source§

impl Mapper for Jaleco92

Source§

impl Mapper for Jaleco101

Source§

impl Mapper for Jaleco140

Source§

impl Mapper for JalecoSs88006

Source§

impl Mapper for Jy91

Source§

impl Mapper for JyAsic

Source§

impl Mapper for KonamiVs

Source§

impl Mapper for M34

Source§

impl Mapper for M78

Source§

impl Mapper for MagicDragon107

Source§

impl Mapper for MagicFloor218

Source§

impl Mapper for Mapper42

Source§

impl Mapper for Mapper50

Source§

impl Mapper for Maxi15M234

Source§

impl Mapper for Mmc1

Source§

impl Mapper for Mmc2

Source§

impl Mapper for Mmc3

Source§

impl Mapper for Mmc4

Source§

impl Mapper for Mmc5

Source§

impl Mapper for Mmc3Board

Source§

impl Mapper for Mmc3CloneMapper

Source§

impl Mapper for Multicart15

Source§

impl Mapper for Multicart58

Source§

impl Mapper for Multicart60

Source§

impl Mapper for Multicart61

Source§

impl Mapper for Multicart62

Source§

impl Mapper for Multicart200

Source§

impl Mapper for Multicart201

Source§

impl Mapper for Multicart202

Source§

impl Mapper for Multicart203

Source§

impl Mapper for Multicart212

Source§

impl Mapper for Multicart213

Source§

impl Mapper for Multicart214

Source§

impl Mapper for Multicart225

Source§

impl Mapper for Multicart226

Source§

impl Mapper for Multicart227

Source§

impl Mapper for Multicart229

Source§

impl Mapper for Multicart231

Source§

impl Mapper for Multicart233

Source§

impl Mapper for Namco118

Source§

impl Mapper for Namco163

Source§

impl Mapper for Namco175

Source§

impl Mapper for Namcot3425M95

Source§

impl Mapper for Namcot3446M76

Source§

impl Mapper for Nanjing163

Source§

impl Mapper for NesEvent105

Source§

impl Mapper for Nichibutsu180

Source§

impl Mapper for Nina006M113

Source§

impl Mapper for Nina0379

Source§

impl Mapper for Nitra250

Source§

impl Mapper for Nrom

Source§

impl Mapper for NsfMapper

Source§

impl Mapper for Ntdec63

Source§

impl Mapper for Ntdec81

Source§

impl Mapper for Ntdec174

Source§

impl Mapper for Ntdec2722M40

Source§

impl Mapper for NtdecAsder112

Source§

impl Mapper for Rambo1

Source§

impl Mapper for Sachen133

Source§

impl Mapper for Sachen145

Source§

impl Mapper for Sachen146

Source§

impl Mapper for Sachen148

Source§

impl Mapper for Sachen149

Source§

impl Mapper for Sachen150

Source§

impl Mapper for Sachen8259

Source§

impl Mapper for Sachen3018M147

Source§

impl Mapper for Sachen8259M137

Source§

impl Mapper for SachenTca01M143

Source§

impl Mapper for Subor39

Source§

impl Mapper for Sunsoft1

Source§

impl Mapper for Sunsoft2

Source§

impl Mapper for Sunsoft3

Source§

impl Mapper for Sunsoft4

Source§

impl Mapper for Sunsoft3r

Source§

impl Mapper for TaitoTc0190

Source§

impl Mapper for TaitoTc0690

Source§

impl Mapper for TaitoX1005

Source§

impl Mapper for TaitoX1017

Source§

impl Mapper for Tqrom

Source§

impl Mapper for TxSrom

Source§

impl Mapper for Txc36

Source§

impl Mapper for Txc132

Source§

impl Mapper for Un1rom94

Source§

impl Mapper for Unrom512M30

Source§

impl Mapper for UxRom

Source§

impl Mapper for Vrc1

Source§

impl Mapper for Vrc2

Source§

impl Mapper for Vrc3

Source§

impl Mapper for Vrc4

Source§

impl Mapper for Vrc6

Source§

impl Mapper for Vrc7

Source§

impl Mapper for VsSystem

Source§

impl Mapper for Waixing178

Source§

impl Mapper for Waixing242

Source§

impl Mapper for WaixingFs304M162