tetanes_core/mapper/
m066_gxrom.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 Gxrom {
20 pub mirroring: Mirroring,
21 pub chr_banks: Banks,
22 pub prg_rom_banks: Banks,
23}
24
25impl Gxrom {
26 const PRG_ROM_WINDOW: usize = 32 * 1024;
27 const CHR_WINDOW: usize = 8 * 1024;
28
29 const CHR_BANK_MASK: u8 = 0x0F; const PRG_BANK_MASK: u8 = 0x30; pub fn load(cart: &mut Cart) -> Result<Mapper, mapper::Error> {
33 let gxrom = Self {
34 mirroring: cart.mirroring(),
35 chr_banks: Banks::new(0x0000, 0x1FFF, cart.chr_rom.len(), Self::CHR_WINDOW)?,
36 prg_rom_banks: Banks::new(0x8000, 0xFFFF, cart.prg_rom.len(), Self::PRG_ROM_WINDOW)?,
37 };
38 Ok(gxrom.into())
39 }
40}
41
42impl Mirrored for Gxrom {
43 fn mirroring(&self) -> Mirroring {
44 self.mirroring
45 }
46
47 fn set_mirroring(&mut self, mirroring: Mirroring) {
48 self.mirroring = mirroring;
49 }
50}
51
52impl MapRead for Gxrom {
53 fn map_peek(&self, addr: u16) -> MappedRead {
57 match addr {
58 0x0000..=0x1FFF => MappedRead::Chr(self.chr_banks.translate(addr)),
59 0x8000..=0xFFFF => MappedRead::PrgRom(self.prg_rom_banks.translate(addr)),
60 _ => MappedRead::Bus,
61 }
62 }
63}
64
65impl MapWrite for Gxrom {
66 fn map_write(&mut self, addr: u16, val: u8) -> MappedWrite {
67 if matches!(addr, 0x8000..=0xFFFF) {
68 self.chr_banks.set(0, (val & Self::CHR_BANK_MASK).into());
69 self.prg_rom_banks
70 .set(0, ((val & Self::PRG_BANK_MASK) >> 4).into());
71 }
72 MappedWrite::Bus
73 }
74}
75
76impl OnBusRead for Gxrom {}
77impl OnBusWrite for Gxrom {}
78impl Reset for Gxrom {}
79impl Clock for Gxrom {}
80impl Regional for Gxrom {}
81impl Sram for Gxrom {}