tetanes_core/mapper/
m007_axrom.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 Axrom {
20 pub mirroring: Mirroring,
21 pub prg_rom_banks: Banks,
22}
23
24impl Axrom {
25 const PRG_ROM_WINDOW: usize = 32 * 1024;
26 const CHR_RAM_SIZE: usize = 8 * 1024;
27 const SINGLE_SCREEN_B: u8 = 0x10; pub fn load(cart: &mut Cart) -> Result<Mapper, mapper::Error> {
30 if !cart.has_chr_rom() && cart.chr_ram.is_empty() {
31 cart.add_chr_ram(Self::CHR_RAM_SIZE);
32 }
33 let axrom = Self {
34 mirroring: cart.mirroring(),
35 prg_rom_banks: Banks::new(0x8000, 0xFFFF, cart.prg_rom.len(), Self::PRG_ROM_WINDOW)?,
36 };
37 Ok(axrom.into())
38 }
39}
40
41impl Mirrored for Axrom {
42 fn mirroring(&self) -> Mirroring {
43 self.mirroring
44 }
45
46 fn set_mirroring(&mut self, mirroring: Mirroring) {
47 self.mirroring = mirroring;
48 }
49}
50
51impl MapRead for Axrom {
52 fn map_peek(&self, addr: u16) -> MappedRead {
56 match addr {
57 0x0000..=0x1FFF => MappedRead::Chr(addr.into()),
58 0x8000..=0xFFFF => MappedRead::PrgRom(self.prg_rom_banks.translate(addr)),
59 _ => MappedRead::Bus,
60 }
61 }
62}
63
64impl MapWrite for Axrom {
65 fn map_write(&mut self, addr: u16, val: u8) -> MappedWrite {
66 match addr {
67 0x0000..=0x1FFF => MappedWrite::ChrRam(addr.into(), val),
68 0x8000..=0xFFFF => {
69 self.prg_rom_banks.set(0, (val & 0x0F).into());
70 self.mirroring = if val & Self::SINGLE_SCREEN_B == Self::SINGLE_SCREEN_B {
71 Mirroring::SingleScreenB
72 } else {
73 Mirroring::SingleScreenA
74 };
75 MappedWrite::Bus
76 }
77 _ => MappedWrite::Bus,
78 }
79 }
80}
81
82impl OnBusRead for Axrom {}
83impl OnBusWrite for Axrom {}
84impl Reset for Axrom {}
85impl Clock for Axrom {}
86impl Regional for Axrom {}
87impl Sram for Axrom {}