use crate::native_core::cpu::{Cpu6502, CpuBus}; use crate::native_core::ines::{InesHeader, InesRom, Mirroring}; pub(crate) struct TestRamBus(pub [u8; 0x10000]); impl TestRamBus { pub(crate) fn new() -> Self { Self([0; 0x10000]) } pub(crate) fn load(&mut self, start: u16, bytes: &[u8]) { for (i, b) in bytes.iter().copied().enumerate() { self.0[start as usize + i] = b; } } } impl CpuBus for TestRamBus { fn read(&mut self, addr: u16) -> u8 { self.0[addr as usize] } fn write(&mut self, addr: u16, value: u8) { self.0[addr as usize] = value; } } pub(crate) fn cpu_setup_with_reset(prog: &[u8]) -> (Cpu6502, TestRamBus) { let mut bus = TestRamBus::new(); bus.load(0x8000, prog); bus.0[0xFFFC] = 0x00; bus.0[0xFFFD] = 0x80; let mut cpu = Cpu6502::default(); cpu.reset(&mut bus); (cpu, bus) } pub(crate) struct MapperRomBuilder { mapper: u16, submapper: u8, prg_banks_16k: u16, chr_banks_8k: u16, mirroring: Mirroring, } impl MapperRomBuilder { pub(crate) fn new(mapper: u16) -> Self { Self { mapper, submapper: 0, prg_banks_16k: 1, chr_banks_8k: 1, mirroring: Mirroring::Horizontal, } } pub(crate) fn submapper(mut self, submapper: u8) -> Self { self.submapper = submapper; self } pub(crate) fn prg_banks_16k(mut self, banks: u16) -> Self { self.prg_banks_16k = banks; self } pub(crate) fn chr_banks_8k(mut self, banks: u16) -> Self { self.chr_banks_8k = banks; self } pub(crate) fn mirroring(mut self, mirroring: Mirroring) -> Self { self.mirroring = mirroring; self } pub(crate) fn build(self) -> InesRom { let prg_rom_len = self.prg_banks_16k as usize * 16 * 1024; let chr_len = if self.chr_banks_8k == 0 { 8 * 1024 } else { self.chr_banks_8k as usize * 8 * 1024 }; let chr_data = if self.chr_banks_8k == 0 { vec![0; chr_len] } else { (0..chr_len).map(|v| (v & 0xFF) as u8).collect() }; InesRom { header: InesHeader { mapper: self.mapper, submapper: self.submapper, is_nes2: false, prg_rom_banks_16k: self.prg_banks_16k, chr_rom_banks_8k: self.chr_banks_8k, has_trainer: false, has_battery: false, mirroring: self.mirroring, prg_ram_shift: 0, prg_nvram_shift: 0, chr_ram_shift: 0, chr_nvram_shift: 0, cpu_ppu_timing_mode: 0, vs_hardware_type: 0, vs_ppu_type: 0, misc_rom_count: 0, default_expansion_device: 0, }, prg_rom: (0..prg_rom_len).map(|v| (v & 0xFF) as u8).collect(), chr_data, chr_is_ram: self.chr_banks_8k == 0, } } }