nes_core/mapper/
m066_gxrom.rs1use crate::{
6 cart::Cart,
7 common::{Clock, Regional, Reset},
8 mapper::{Mapped, MappedRead, MappedWrite, Mapper, MemMap},
9 mem::MemBanks,
10 ppu::Mirroring,
11};
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15#[must_use]
16pub struct Gxrom {
17 mirroring: Mirroring,
18 chr_banks: MemBanks,
19 prg_rom_banks: MemBanks,
20}
21
22impl Gxrom {
23 const PRG_ROM_WINDOW: usize = 32 * 1024;
24 const CHR_WINDOW: usize = 8 * 1024;
25
26 const CHR_BANK_MASK: u8 = 0x0F; const PRG_BANK_MASK: u8 = 0x30; pub fn load(cart: &mut Cart) -> Mapper {
30 let gxrom = Self {
31 mirroring: cart.mirroring(),
32 chr_banks: MemBanks::new(0x0000, 0x1FFF, cart.chr_rom.len(), Self::CHR_WINDOW),
33 prg_rom_banks: MemBanks::new(0x8000, 0xFFFF, cart.prg_rom.len(), Self::PRG_ROM_WINDOW),
34 };
35 gxrom.into()
36 }
37}
38
39impl MemMap for Gxrom {
40 fn map_peek(&self, addr: u16) -> MappedRead {
44 match addr {
45 0x0000..=0x1FFF => MappedRead::Chr(self.chr_banks.translate(addr)),
46 0x8000..=0xFFFF => MappedRead::PrgRom(self.prg_rom_banks.translate(addr)),
47 _ => MappedRead::None,
48 }
49 }
50
51 fn map_write(&mut self, addr: u16, val: u8) -> MappedWrite {
52 if matches!(addr, 0x8000..=0xFFFF) {
53 self.chr_banks.set(0, (val & Self::CHR_BANK_MASK).into());
54 self.prg_rom_banks
55 .set(0, ((val & Self::PRG_BANK_MASK) >> 4).into());
56 }
57 MappedWrite::None
58 }
59}
60
61impl Mapped for Gxrom {
62 #[inline]
63 fn mirroring(&self) -> Mirroring {
64 self.mirroring
65 }
66
67 #[inline]
68 fn set_mirroring(&mut self, mirroring: Mirroring) {
69 self.mirroring = mirroring;
70 }
71}
72
73impl Clock for Gxrom {}
74impl Regional for Gxrom {}
75impl Reset for Gxrom {}