diff --git a/src/cartridge/mmc1.rs b/src/cartridge/mmc1.rs new file mode 100644 index 0000000..5a2cd4f --- /dev/null +++ b/src/cartridge/mmc1.rs @@ -0,0 +1,28 @@ +use super::{Cartridge, Mapper, Mirror}; + +pub struct Mmc1 { + cart: Cartridge, + step: u8, + shift_register: u8, + prg_low_bank: usize, + prg_high_bank: usize, + chr_low_bank: usize, + chr_high_bank: usize, + mirroring: Mirror, +} + +impl Mmc1 { + fn new(cart: Cartridge) -> Self { + Mmc1 + } +} + +impl Mapper for Mmc1 { + fn read(&mut self, address: usize) -> u8 { + 0 + } + + fn write(&mut self, address: usize, value: u8) { + + } +} diff --git a/src/cartridge/mod.rs b/src/cartridge/mod.rs index 829ff0f..d2a8e68 100644 --- a/src/cartridge/mod.rs +++ b/src/cartridge/mod.rs @@ -1,8 +1,19 @@ -mod mappers; +mod nrom; -use mappers::get_mapper_funcs; use std::io::Read; +pub trait Mapper { + fn read(&mut self, address: usize) -> u8; + fn write(&mut self, address: usize, value: u8); +} + +pub enum Mirror { + LowBank, + HighBank, + Horizontal, + Vertical, +} + // To avoid separate read and write functions for every mapper, the mapper functions returns a reference to the CPU or PPU's own // byte of memory, which the calling method can dereference to read or set the value. pub type CpuMapperFunc = fn(&mut crate::cpu::Cpu, usize, bool) -> Option<&mut u8>; diff --git a/src/cartridge/mappers.rs b/src/cartridge/nrom.rs similarity index 94% rename from src/cartridge/mappers.rs rename to src/cartridge/nrom.rs index bed6471..9834311 100644 --- a/src/cartridge/mappers.rs +++ b/src/cartridge/nrom.rs @@ -1,3 +1,9 @@ +use super::Cartridge; + +pub struct Nrom { + cart: Cartridge, +} + pub fn nrom_cpu(cpu: &mut crate::cpu::Cpu, address: usize, writing: bool) -> Option<&mut u8> { // PRG-ROM, not -RAM diff --git a/src/cpu/mod.rs b/src/cpu/mod.rs index 02b50d6..7cfcf47 100644 --- a/src/cpu/mod.rs +++ b/src/cpu/mod.rs @@ -2,6 +2,10 @@ mod addressing_modes; mod opcodes; mod utility; +use std::cell::RefCell; +use std::rc::Rc; +use crate::cartridge::Mapper; + // RAM locations const STACK_OFFSET: usize = 0x100; const NMI_VECTOR: usize = 0xFFFA; @@ -70,8 +74,9 @@ pub struct Cpu { mode_table: Vec, // cartridge data - pub prg_rom: Vec>, // one 16 KiB chunk for each specified in iNES header - mapper_func: crate::cartridge::CpuMapperFunc, + mapper: Rc>, + // pub prg_rom: Vec>, // one 16 KiB chunk for each specified in iNES header + // mapper_func: crate::cartridge::CpuMapperFunc, // ppu pub ppu: super::Ppu, @@ -86,7 +91,7 @@ pub struct Cpu { } impl Cpu { - pub fn new(cart: &super::Cartridge, ppu: super::Ppu, apu: super::Apu) -> Self { + pub fn new(mapper: Rc>, ppu: super::Ppu, apu: super::Apu) -> Self { let mut cpu = Cpu{ mem: vec![0; 0x2000], A: 0, X: 0, Y: 0, @@ -95,8 +100,9 @@ impl Cpu { P: 0x24, // TODO: change this back to 0x34? nestest.nes ROM has it as 0x24 at start. clock: 0, delay: 0, - prg_rom: cart.prg_rom.clone(), - mapper_func: cart.cpu_mapper_func, + mapper: mapper, + // prg_rom: cart.prg_rom.clone(), + // mapper_func: cart.cpu_mapper_func, ppu: ppu, apu: apu, strobe: 0, diff --git a/src/main.rs b/src/main.rs index d99c7f2..c08b23a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -124,7 +124,8 @@ fn main() -> Result<(), String> { TODO: - common mappers -- DMC audio channel, high- and low-pass filters, refactor envelope +- untangle CPU and PPU +- DMC audio channel, high- and low-pass filters, refactor envelope, fix static - name audio variables (dividers, counters, etc.) more consistently - battery-backed RAM solution - GUI? drag and drop ROMs? diff --git a/src/ppu/mod.rs b/src/ppu/mod.rs index ca428c3..572e8cf 100644 --- a/src/ppu/mod.rs +++ b/src/ppu/mod.rs @@ -2,6 +2,10 @@ mod cpu_registers; mod rendering; mod memory; +use std::cell::RefCell; +use std::rc::Rc; +use crate::cartridge::Mapper; + pub struct Ppu { line_cycle: usize, // x coordinate scanline: usize, // y coordinate @@ -14,9 +18,10 @@ pub struct Ppu { w: u8, // First or second write toggle (1 bit) // Cartridge things - pub pattern_tables: Vec>, // CHR-ROM, one 8 KiB chunk for each specified in iNES header - mapper_func: crate::cartridge::PpuMapperFunc, - mirroring: u8, // 0: horizontal, 1: vertical + pub mapper: Rc>, + // pub pattern_tables: Vec>, // CHR-ROM, one 8 KiB chunk for each specified in iNES header + // mapper_func: crate::cartridge::PpuMapperFunc, + // mirroring: u8, // 0: horizontal, 1: vertical // Each nametable byte is a reference to the start of an 8-byte sequence in the pattern table. // That sequence represents an 8x8 tile, from top row to bottom. @@ -85,7 +90,7 @@ pub struct Ppu { } impl Ppu { - pub fn new(cart: &super::Cartridge) -> Self { + pub fn new(mapper: Rc>) -> Self { Ppu { line_cycle: 0, scanline: 0, @@ -94,14 +99,15 @@ impl Ppu { t: 0, x: 0, w: 0, - pattern_tables: cart.chr_rom.clone(), - mapper_func: cart.ppu_mapper_func, - mirroring: cart.mirroring, + mapper: mapper, + // pattern_tables: cart.chr_rom.clone(), + // mapper_func: cart.ppu_mapper_func, + // mirroring: cart.mirroring, nametable_0: vec![0u8; 0x0400], nametable_1: vec![0u8; 0x0400], nametable_2: vec![0u8; 0x0400], nametable_3: vec![0u8; 0x0400], - palette_ram: vec![0u8; 0x0020], + palette_ram: vec![0u8; 0x0020], background_pattern_sr_low: 0, background_pattern_sr_high: 0, nametable_byte: 0,