tetanes_core/mapper/
m034_bnrom.rs

1//! `BNROM` (Mapper 034).
2//!
3//! <https://www.nesdev.org/wiki/BNROM>
4
5use 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/// `BNROM` (Mapper 034).
17#[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    // PPU $0000..=$1FFF 8K CHR-RAM Bank Fixed
48    // CPU $8000..=$FFFF 32K switchable PRG-ROM bank
49
50    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            // Support up to 8MB PRG-ROM
64            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 {}