1use crate::{
6 common::{Clock, Regional, Reset, Sram},
7 mem,
8 ppu::Mirroring,
9};
10use enum_dispatch::enum_dispatch;
11use serde::{Deserialize, Serialize};
12
13pub use bandai_fcg::BandaiFCG; pub use m000_nrom::Nrom;
15pub use m001_sxrom::{Revision as Mmc1Revision, Sxrom};
16pub use m002_uxrom::Uxrom;
17pub use m003_cnrom::Cnrom;
18pub use m004_txrom::{Revision as Mmc3Revision, Txrom};
19pub use m005_exrom::Exrom;
20pub use m007_axrom::Axrom;
21pub use m009_pxrom::Pxrom;
22pub use m010_fxrom::Fxrom;
23pub use m011_color_dreams::ColorDreams;
24pub use m018_jalecoss88006::JalecoSs88006;
25pub use m019_namco163::Namco163;
26pub use m024_m026_vrc6::Vrc6;
27pub use m034_bnrom::Bnrom;
28pub use m034_nina001::Nina001;
29pub use m066_gxrom::Gxrom;
30pub use m069_sunsoft_fme7::SunsoftFme7;
31pub use m071_bf909x::{Bf909x, Revision as Bf909Revision};
32pub use m076_dxrom::Dxrom as Dxrom76;
33pub use m079_nina003_006::Nina003006;
34pub use m088_dxrom::Dxrom as Dxrom88;
35pub use m095_dxrom::Dxrom as Dxrom95;
36pub use m154_dxrom::Dxrom as Dxrom154;
37pub use m206_dxrom::Dxrom as Dxrom206;
38
39pub mod bandai_fcg;
40pub mod m000_nrom;
41pub mod m001_sxrom;
42pub mod m002_uxrom;
43pub mod m003_cnrom;
44pub mod m004_txrom;
45pub mod m005_exrom;
46pub mod m007_axrom;
47pub mod m009_pxrom;
48pub mod m010_fxrom;
49pub mod m011_color_dreams;
50pub mod m018_jalecoss88006;
51pub mod m019_namco163;
52pub mod m024_m026_vrc6;
53pub mod m034_bnrom;
54pub mod m034_nina001;
55pub mod m066_gxrom;
56pub mod m069_sunsoft_fme7;
57pub mod m071_bf909x;
58pub mod m076_dxrom;
59pub mod m079_nina003_006;
60pub mod m088_dxrom;
61pub mod m095_dxrom;
62pub mod m154_dxrom;
63pub mod m206_dxrom;
64pub mod vrc_irq;
65
66#[derive(thiserror::Error, Debug)]
68#[must_use]
69pub enum Error {
70 #[error(transparent)]
72 Bank(#[from] mem::Error),
73}
74
75#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
77#[must_use]
78pub enum MapperRevision {
79 Mmc3(Mmc3Revision),
82 Bf909(Bf909Revision),
84}
85
86impl std::fmt::Display for MapperRevision {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 let s = match self {
89 Self::Mmc3(rev) => match rev {
90 Mmc3Revision::A => "MMC3A",
91 Mmc3Revision::BC => "MMC3B/C",
92 Mmc3Revision::Acc => "MMC3Acc",
93 },
94 Self::Bf909(rev) => match rev {
95 Bf909Revision::Bf909x => "BF909x",
96 Bf909Revision::Bf9097 => "BF9097",
97 },
98 };
99 write!(f, "{s}")
100 }
101}
102
103#[enum_dispatch]
104#[derive(Debug, Clone, Serialize, Deserialize)]
105#[allow(clippy::large_enum_variant)]
106#[must_use]
107pub enum Mapper {
108 None,
109 Nrom,
111 Sxrom,
113 Uxrom,
115 Cnrom,
117 Txrom,
119 Exrom,
121 Axrom,
123 Pxrom,
125 Fxrom,
127 ColorDreams,
129 BandaiFCG,
131 JalecoSs88006,
133 Namco163,
135 Vrc6,
137 Bnrom,
139 Nina001,
141 Gxrom,
143 SunsoftFme7,
145 Bf909x,
147 Dxrom76,
149 Nina003006,
151 Dxrom88,
153 Dxrom95,
155 Dxrom154,
157 Dxrom206,
159}
160
161impl Mapper {
162 pub fn none() -> Self {
163 None.into()
164 }
165
166 pub const fn is_none(&self) -> bool {
167 matches!(self, Self::None(_))
168 }
169}
170
171impl Default for Mapper {
172 fn default() -> Self {
173 Self::none()
174 }
175}
176
177#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
179#[must_use]
180pub enum MappedRead {
181 Bus,
184 Chr(usize),
186 CIRam(usize),
189 ExRam(usize),
191 PrgRom(usize),
193 PrgRam(usize),
195 Data(u8),
197}
198
199#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
201#[must_use]
202pub enum MappedWrite {
203 None,
205 Bus,
207 ChrRam(usize, u8),
209 CIRam(usize, u8),
212 ExRam(usize, u8),
214 PrgRam(usize, u8),
216 PrgRamProtect(bool),
218}
219
220#[enum_dispatch(Mapper)]
221pub trait MapRead {
222 fn map_read(&mut self, addr: u16) -> MappedRead {
223 self.map_peek(addr)
224 }
225
226 fn map_peek(&self, _addr: u16) -> MappedRead {
227 MappedRead::Bus
228 }
229}
230
231#[enum_dispatch(Mapper)]
232pub trait MapWrite {
233 fn map_write(&mut self, _addr: u16, _val: u8) -> MappedWrite {
234 MappedWrite::Bus
235 }
236}
237
238#[derive(Debug, Copy, Clone, PartialEq, Eq)]
239#[must_use]
240pub enum BusKind {
241 Cpu,
242 Ppu,
243}
244
245#[enum_dispatch(Mapper)]
246pub trait OnBusRead {
247 fn on_bus_read(&mut self, _addr: u16, _kind: BusKind) {}
248}
249
250#[enum_dispatch(Mapper)]
251pub trait OnBusWrite {
252 fn on_bus_write(&mut self, _addr: u16, _val: u8, _kind: BusKind) {}
253}
254
255#[enum_dispatch(Mapper)]
256pub trait Mirrored {
257 fn mirroring(&self) -> Mirroring {
258 Mirroring::default()
259 }
260 fn set_mirroring(&mut self, _mirroring: Mirroring) {}
261}
262
263#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
264#[must_use]
265pub struct None;
266
267impl MapRead for None {}
268impl MapWrite for None {}
269impl OnBusRead for None {}
270impl OnBusWrite for None {}
271impl Mirrored for None {}
272impl Clock for None {}
273impl Regional for None {}
274impl Reset for None {}
275impl Sram for None {}