pub trait PpuBus {
// Required methods
fn ppu_read(&mut self, addr: u16) -> u8;
fn ppu_write(&mut self, addr: u16, value: u8);
// Provided methods
fn ppu_read_sprite(&mut self, addr: u16) -> u8 { ... }
fn chr_phys(&self, _addr: u16) -> Option<u32> { ... }
fn peek_nametable(&mut self, _addr: u16) -> Option<u8> { ... }
fn write_nametable(&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 notify_a12(&mut self, _level: bool) { ... }
fn notify_scanline_start(&mut self) { ... }
fn notify_vblank(&mut self) { ... }
fn nametable_address(&self, addr: u16) -> u16 { ... }
}Expand description
Bus interface the PPU sees.
In production the lockstep bus in rustynes-core routes:
- CHR reads/writes (
$0000-$1FFF) → mapper. - Nametable reads/writes (
$2000-$3EFF) → PPU’s own CIRAM, with the mapper-supplied mirroring offset viaPpuBus::nametable_address. - A12 transitions → mapper.
In tests, a small in-memory PpuBus impl owns 8 KiB of CHR-RAM and a
dummy mirroring map.
Required Methods§
Provided Methods§
Sourcefn ppu_read_sprite(&mut self, addr: u16) -> u8
fn ppu_read_sprite(&mut self, addr: u16) -> u8
Read a byte from the pattern-table window ($0000-$1FFF) on behalf
of a sprite tile fetch. MMC5 in 8x16 sprite mode uses a different
CHR bank set ($5120-$5127) for sprite fetches than for BG; other
mappers default to the same path as Self::ppu_read.
Sourcefn chr_phys(&self, _addr: u16) -> Option<u32>
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 (Some(offset)), or None when CHR is RAM (or the
mapper doesn’t expose it). tile_index = offset / 16 keys Mesen CHR-ROM
<tile> replacements; None routes to the CHR-RAM content-hash path.
Default None; only consulted on the HD-pack fetch path.
Sourcefn peek_nametable(&mut self, _addr: u16) -> Option<u8>
fn peek_nametable(&mut self, _addr: u16) -> Option<u8>
Optionally synthesize a nametable byte for addr ($2000-$3EFF).
When the bus returns Some(v), the PPU uses v directly and skips
its CIRAM read. MMC5 uses this for fill mode and ExRAM-as-nametable.
Default returns None.
Sourcefn write_nametable(&mut self, _addr: u16, _value: u8) -> bool
fn write_nametable(&mut self, _addr: u16, _value: u8) -> bool
Optionally absorb a nametable write directly into mapper storage.
Returns true if consumed; PPU then skips its CIRAM write. Default
returns false.
Sourcefn peek_ex_attribute(&mut self, _v: u16) -> Option<ExAttribute>
fn peek_ex_attribute(&mut self, _v: u16) -> Option<ExAttribute>
Optional per-tile extended attribute + CHR-bank override for the BG
tile currently being fetched (loopy-v passed in v). MMC5 in $5104
mode 01 (ExGrafix) returns Some(...) here. Default returns None.
Sourcefn bg_split_state(
&mut self,
_scanline_y: u16,
_coarse_x: u16,
) -> Option<BgSplitState>
fn bg_split_state( &mut self, _scanline_y: u16, _coarse_x: u16, ) -> Option<BgSplitState>
Optional vertical split-screen override for the BG fetch group about
to start at (scanline_y, coarse_x). MMC5 with split enabled
($5200 bit 7) returns Some(...) here for tile columns that fall
within the alt region. Default returns None.
Sourcefn notify_a12(&mut self, _level: bool)
fn notify_a12(&mut self, _level: bool)
Notification of a PPU A12 line transition (rising or falling). The
PPU calls this on every transition, with level = true for high.
MMC3 / MMC5 use this internally for IRQ counter clocking.
Sourcefn notify_scanline_start(&mut self)
fn notify_scanline_start(&mut self)
Notification that the PPU is starting a new rendered scanline (visible or pre-render). MMC5 uses this to drive its scanline IRQ counter. Default no-op.
Sourcefn notify_vblank(&mut self)
fn notify_vblank(&mut self)
Notification that the PPU has entered vertical blank. MMC5 uses this to clear its “in-frame” flag. Default no-op.
Sourcefn nametable_address(&self, addr: u16) -> u16
fn nametable_address(&self, addr: u16) -> u16
Resolve a logical nametable address in $2000-$3EFF to a CIRAM offset
in 0..0x800 under the mapper’s currently-selected mirroring.
Default impl uses a vertical-mirroring fallback so this trait remains
drop-in for ad-hoc test buses; the lockstep bus in rustynes-core
overrides this to delegate to Mapper::nametable_address.