cge_nes 0.1.0

Cycle-accurate NES (Nintendo Entertainment System) emulator library: CPU, PPU, cartridge, input, and iNES ROM loading.
Documentation
//! NES Cartridge interface and components
//!
//! This crate provides the core abstractions for implementing NES cartridges.
//! A cartridge in the NES contains the game program (PRG ROM) and character data (CHR ROM/RAM),
//! along with optional hardware for memory mapping and other special features.
//!
//! # Key Components
//!
//! - `Cartridge` trait: The main interface that all cartridge implementations must provide
//! - `ChrRomContentStatus`: Tracks whether CHR ROM/RAM content has been modified
//!
//! # Example Usage
//!
//! ```no_run
//! use cge_nes::{Cartridge, ChrRomContentStatus};
//!
//! struct MyCartridge { /* ... */ }
//!
//! impl Cartridge for MyCartridge {
//!     fn read_cpu_mapped(&self, addr: u16) -> u8 { /* ... */ 0 }
//!     fn write_cpu_mapped(&mut self, data: u8, addr: u16) -> ChrRomContentStatus {
//!         ChrRomContentStatus::Unchanged
//!     }
//!     fn read_ppu_mapped(&mut self, addr: u16) -> u8 { /* ... */ 0 }
//!     fn write_ppu_mapped(&mut self, data: u8, addr: u16) -> ChrRomContentStatus {
//!         ChrRomContentStatus::Changed
//!     }
//! }
//! ```

#![deny(missing_docs)]

/// Represents whether CHR ROM/RAM content has been modified during a write operation
///
/// This is used to track when character data is modified, which helps emulators know
/// when to update PPU-related caches or trigger redraws.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum ChrRomContentStatus {
    /// Indicates the CHR ROM/RAM content was modified
    Changed,
    /// Indicates the CHR ROM/RAM content remained the same
    Unchanged,
}

/// Core interface for NES cartridge implementations
///
/// This trait defines the required methods for implementing a NES cartridge,
/// providing memory mapping for both CPU and PPU address spaces.
///
/// # Memory Mapping
///
/// - CPU address space: 0x4020-0xFFFF
/// - PPU pattern tables: 0x0000-0x1FFF
///
/// # Returns
///
/// Write operations return a [`ChrRomContentStatus`] to indicate if character data was modified
pub trait Cartridge: Send {
    /// Reads a byte from the cartridge's CPU address space
    ///
    /// # Arguments
    /// * `addr` - CPU address to read from (0x4020-0xFFFF)
    fn read_cpu_mapped(&self, addr: u16) -> u8;

    /// Writes a byte to the cartridge's CPU address space
    ///
    /// # Arguments
    /// * `data` - Byte to write
    /// * `addr` - CPU address to write to (0x4020-0xFFFF)
    fn write_cpu_mapped(&mut self, data: u8, addr: u16) -> ChrRomContentStatus;

    /// Reads a byte from the cartridge's PPU pattern table or name tables
    ///
    /// # Arguments
    /// * `addr` - Pattern table address (0x0000-0x1FFF) or name table address (0x2000-0x3EFF)
    fn read_ppu_mapped(&mut self, addr: u16) -> u8;

    /// Writes a byte to the cartridge's PPU pattern table space
    ///
    /// # Arguments
    /// * `data` - Byte to write
    /// * `addr` - Pattern table address (0x0000-0x1FFF) or name table address (0x2000-0x3EFF)
    fn write_ppu_mapped(&mut self, data: u8, addr: u16) -> ChrRomContentStatus;

    /// Returns current value of the IRQ pin if used (always false in default implementation)
    fn irq_pin(&self) -> bool {
        false
    }

    /// Returns whether the cartridge requires accurate simulation of sprite chr rom reads for IRQ
    fn requires_cycle_accurate_sprites(&self) -> bool {
        false
    }

    /// Notifies the cartridge that the PPU VRAM address has transitioned from
    /// `old_addr` to `new_addr` (typically as a result of the `$2007` auto-
    /// increment). Cartridges with A12-clocked counters should detect rising
    /// edges on bit 12 and update their counter accordingly. The default
    /// implementation does nothing.
    fn notify_vram_addr_change(&mut self, _old_addr: u16, _new_addr: u16) {}
}