tetanes_core/mapper/
m034_bnrom.rs1use crate::{
6 cart::Cart,
7 common::{Clock, Regional, Reset, Sram},
8 mapper::{
9 self, MapRead, MapWrite, MappedRead, MappedWrite, Mapper, Mirrored, OnBusRead, OnBusWrite,
10 },
11 mem::Banks,
12 ppu::Mirroring,
13};
14use serde::{Deserialize, Serialize};
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
18#[must_use]
19pub struct Bnrom {
20 pub mirroring: Mirroring,
21 pub prg_rom_banks: Banks,
22}
23
24impl Bnrom {
25 const PRG_ROM_WINDOW: usize = 32 * 1024;
26 const CHR_RAM_SIZE: usize = 8 * 1024;
27
28 pub fn load(cart: &mut Cart) -> Result<Mapper, mapper::Error> {
29 if cart.chr_ram.is_empty() {
30 cart.add_chr_ram(Self::CHR_RAM_SIZE);
31 }
32 let bnrom = Self {
33 mirroring: cart.mirroring(),
34 prg_rom_banks: Banks::new(0x8000, 0xFFFF, cart.prg_rom.len(), Self::PRG_ROM_WINDOW)?,
35 };
36 Ok(bnrom.into())
37 }
38}
39
40impl Mirrored for Bnrom {
41 fn mirroring(&self) -> Mirroring {
42 self.mirroring
43 }
44}
45
46impl MapRead for Bnrom {
47 fn map_peek(&self, addr: u16) -> MappedRead {
51 match addr {
52 0x0000..=0x1FFF => MappedRead::Chr(usize::from(addr) & (Self::CHR_RAM_SIZE - 1)),
53 0x8000..=0xFFFF => MappedRead::PrgRom(self.prg_rom_banks.translate(addr)),
54 _ => MappedRead::Bus,
55 }
56 }
57}
58
59impl MapWrite for Bnrom {
60 fn map_write(&mut self, addr: u16, val: u8) -> MappedWrite {
61 match addr {
62 0x0000..=0x1FFF => return MappedWrite::ChrRam(addr.into(), val),
63 0x8000..=0xFFFF => self.prg_rom_banks.set(0, val.into()),
65 _ => (),
66 }
67 MappedWrite::Bus
68 }
69}
70
71impl OnBusRead for Bnrom {}
72impl OnBusWrite for Bnrom {}
73impl Reset for Bnrom {}
74impl Clock for Bnrom {}
75impl Regional for Bnrom {}
76impl Sram for Bnrom {}