1use crate::{
6    common::{Clock, ResetKind, NesRegion, Regional, Reset},
7    ppu::Mirroring,
8};
9use enum_dispatch::enum_dispatch;
10use serde::{Deserialize, Serialize};
11
12pub use m000_nrom::Nrom;
13pub use m001_sxrom::{Mmc1Revision, Sxrom};
14pub use m002_uxrom::Uxrom;
15pub use m003_cnrom::Cnrom;
16pub use m004_txrom::{Mmc3Revision, Txrom};
17pub use m005_exrom::Exrom;
18pub use m007_axrom::Axrom;
19pub use m009_pxrom::Pxrom;
20pub use m024_m026_vrc6::Vrc6;
21pub use m066_gxrom::Gxrom;
22pub use m071_bf909x::{Bf909Revision, Bf909x};
23
24pub mod m000_nrom;
25pub mod m001_sxrom;
26pub mod m002_uxrom;
27pub mod m003_cnrom;
28pub mod m004_txrom;
29pub mod m005_exrom;
30pub mod m007_axrom;
31pub mod m009_pxrom;
32pub mod m024_m026_vrc6;
33pub mod m066_gxrom;
34pub mod m071_bf909x;
35pub mod vrc_irq;
36
37#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
38#[must_use]
39pub enum MapperRevision {
40    Mmc1(Mmc1Revision),
41    Mmc3(Mmc3Revision),
42    Bf909(Bf909Revision),
43}
44
45#[enum_dispatch]
46#[derive(Debug, Clone, Serialize, Deserialize)]
47#[allow(clippy::large_enum_variant)]
48#[must_use]
49pub enum Mapper {
50    Empty,
51    Nrom,
52    Sxrom,
53    Uxrom,
54    Cnrom,
55    Txrom,
56    Exrom,
57    Axrom,
58    Pxrom,
59    Vrc6,
60    Gxrom,
61    Bf909x,
62}
63
64impl Mapper {
65    pub fn none() -> Self {
66        Empty.into()
67    }
68}
69
70impl Default for Mapper {
71    fn default() -> Self {
72        Self::none()
73    }
74}
75
76#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
77#[must_use]
78pub enum MappedRead {
79    None,
80    Chr(usize),
81    CIRam(usize),
82    ExRam(usize),
83    PrgRom(usize),
84    PrgRam(usize),
85    Data(u8),
86}
87
88#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
89#[must_use]
90pub enum MappedWrite {
91    None,
92    Chr(usize, u8),
93    CIRam(usize, u8),
94    ExRam(usize, u8),
95    PrgRam(usize, u8),
96    PrgRamProtect(bool),
97}
98
99#[enum_dispatch(Mapper)]
100pub trait MemMap {
101    fn map_read(&mut self, addr: u16) -> MappedRead {
102        self.map_peek(addr)
103    }
104
105    fn map_peek(&self, _addr: u16) -> MappedRead {
106        MappedRead::None
107    }
108
109    fn map_write(&mut self, _addr: u16, _val: u8) -> MappedWrite {
110        MappedWrite::None
111    }
112}
113
114#[enum_dispatch(Mapper)]
115pub trait Mapped {
116    #[must_use]
117    fn irq_pending(&self) -> bool {
118        false
119    }
120    fn mirroring(&self) -> Mirroring {
121        Mirroring::default()
122    }
123    fn set_mirroring(&mut self, _mirroring: Mirroring) {}
124    fn ppu_bus_read(&mut self, _addr: u16) {}
125    fn ppu_bus_write(&mut self, _addr: u16, _val: u8) {}
126    fn cpu_bus_read(&mut self, _addr: u16) {}
127    fn cpu_bus_write(&mut self, _addr: u16, _val: u8) {}
128}
129
130#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
131#[must_use]
132pub struct Empty;
133
134impl MemMap for Empty {}
135impl Mapped for Empty {}
136impl Clock for Empty {}
137impl Regional for Empty {}
138impl Reset for Empty {}