1use try_from_discrim::TryFrom;
2
3#[derive(Debug, TryFrom, Clone, Copy)]
4#[from(u16)]
5#[non_exhaustive]
6pub enum HwReg {
8 Ramg = 0x0000,
10 Romb0 = 0x2000,
12 Romb1 = 0x3000,
14 Ramb = 0x4000,
16 Rtclatch = 0x6000,
18
19 P1 = 0xFF00,
21
22 Sb = 0xFF01,
24 Sc = 0xFF02,
26
27 Div = 0xFF04,
29 Tima = 0xFF05,
31 Tma = 0xFF06,
33 Tac = 0xFF07,
35
36 If = 0xFF0F,
38
39 Nr10 = 0xFF10,
41 Nr11 = 0xFF11,
43 Nr12 = 0xFF12,
45 Nr13 = 0xFF13,
47 Nr14 = 0xFF14,
49 Nr21 = 0xFF16,
51 Nr22 = 0xFF17,
53 Nr23 = 0xFF18,
55 Nr24 = 0xFF19,
57 Nr30 = 0xFF1A,
59 Nr31 = 0xFF1B,
61 Nr32 = 0xFF1C,
63 Nr33 = 0xFF1D,
65 Nr34 = 0xFF1E,
67 Nr41 = 0xFF20,
69 Nr42 = 0xFF21,
71 Nr43 = 0xFF22,
73 Nr44 = 0xFF23,
75 Nr50 = 0xFF24,
77 Nr51 = 0xFF25,
79 Nr52 = 0xFF26,
81
82 Wave0 = 0xFF30,
83 Wave1 = 0xFF31,
84 Wave2 = 0xFF32,
85 Wave3 = 0xFF33,
86 Wave4 = 0xFF34,
87 Wave5 = 0xFF35,
88 Wave6 = 0xFF36,
89 Wave7 = 0xFF37,
90 Wave8 = 0xFF38,
91 Wave9 = 0xFF39,
92 WaveA = 0xFF3A,
93 WaveB = 0xFF3B,
94 WaveC = 0xFF3C,
95 WaveD = 0xFF3D,
96 WaveE = 0xFF3E,
97 WaveF = 0xFF3F,
98
99 Lcdc = 0xFF40,
101 Stat = 0xFF41,
103 Scy = 0xFF42,
105 Scx = 0xFF43,
107 Ly = 0xFF44,
109 Lyc = 0xFF45,
111 Dma = 0xFF46,
113 Bgp = 0xFF47,
115 Obp0 = 0xFF48,
117 Obp1 = 0xFF49,
119 Wy = 0xFF4A,
121 Wx = 0xFF4B,
123
124 Key1 = 0xFF4D,
126
127 Vbk = 0xFF4F,
129
130 Hdma1 = 0xFF51,
132 Hdma2 = 0xFF52,
134 Hdma3 = 0xFF53,
136 Hdma4 = 0xFF54,
138 Hdma5 = 0xFF55,
140
141 Rp = 0xFF56,
143
144 Bcps = 0xFF68,
146 Bcpd = 0xFF69,
148 Ocps = 0xFF6A,
150 Ocpd = 0xFF6B,
152
153 Svbk = 0xFF70,
155
156 Pcm12 = 0xFF76,
158 Pcm34 = 0xFF77,
160
161 Ie = 0xFFFF,
163}
164
165impl From<HwReg> for u16 {
166 fn from(reg: HwReg) -> Self {
167 reg as u16
168 }
169}
170
171#[derive(Default)]
172pub struct Mmio {
173 ramg: u8,
174 romb0: u8,
175 romb1: u8,
176 ramb: u8,
177 rtclatch: u8,
178 p1: u8,
179 sb: u8,
180 sc: u8,
181 div: u8,
182 tima: u8,
183 tma: u8,
184 tac: u8,
185 _if: u8,
186 nr10: u8,
188 nr11: u8,
189 nr12: u8,
190 nr13: u8,
191 nr14: u8,
192 nr21: u8,
193 nr22: u8,
194 nr23: u8,
195 nr24: u8,
196 nr30: u8,
197 nr31: u8,
198 nr32: u8,
199 nr33: u8,
200 nr34: u8,
201 nr41: u8,
202 nr42: u8,
203 nr43: u8,
204 nr44: u8,
205 nr50: u8,
206 nr51: u8,
207 nr52: u8,
208 wave_0: u8,
209 wave_1: u8,
210 wave_2: u8,
211 wave_3: u8,
212 wave_4: u8,
213 wave_5: u8,
214 wave_6: u8,
215 wave_7: u8,
216 wave_8: u8,
217 wave_9: u8,
218 wave_a: u8,
219 wave_b: u8,
220 wave_c: u8,
221 wave_d: u8,
222 wave_e: u8,
223 wave_f: u8,
224 lcdc: u8,
225 stat: u8,
226 scy: u8,
227 scx: u8,
228 ly: u8,
229 lyc: u8,
230 dma: u8,
231 bgp: u8,
232 obp0: u8,
233 obp1: u8,
234 wy: u8,
235 wx: u8,
236 key1: u8,
237 vbk: u8,
238 hdma1: u8,
239 hdma2: u8,
240 hdma3: u8,
241 hdma4: u8,
242 hdma5: u8,
243 rp: u8,
244 bcps: u8,
245 bcpd: u8,
246 ocps: u8,
247 ocpd: u8,
248 svbk: u8,
249 pcm12: u8,
250 pcm34: u8,
251 ie: u8,
252}
253
254impl Mmio {
255 pub fn read(&self, register: HwReg) -> u8 {
256 match register {
257 HwReg::Ramg => self.ramg,
258 HwReg::Romb0 => self.romb0,
259 HwReg::Romb1 => self.romb1,
260 HwReg::Ramb => self.ramb,
261 HwReg::Rtclatch => self.rtclatch,
262 HwReg::P1 => {
263 eprintln!("Unit test has no joypad input");
265 self.p1
266 }
267 HwReg::Sb => {
268 eprintln!("Unit test has no serial input");
270 self.sb
271 }
272 HwReg::Sc => self.sc,
273 HwReg::Div => self.div,
274 HwReg::Tima => self.tima,
275 HwReg::Tma => self.tma,
276 HwReg::Tac => self.tac,
277 HwReg::If => self._if,
278 HwReg::Nr10 => self.nr10,
279 HwReg::Nr11 => self.nr11,
280 HwReg::Nr12 => self.nr12,
281 HwReg::Nr13 => self.nr13,
282 HwReg::Nr14 => self.nr14,
283 HwReg::Nr21 => self.nr21,
284 HwReg::Nr22 => self.nr22,
285 HwReg::Nr23 => self.nr23,
286 HwReg::Nr24 => self.nr24,
287 HwReg::Nr30 => self.nr30,
288 HwReg::Nr31 => self.nr31,
289 HwReg::Nr32 => self.nr32,
290 HwReg::Nr33 => self.nr33,
291 HwReg::Nr34 => self.nr34,
292 HwReg::Nr41 => self.nr41,
293 HwReg::Nr42 => self.nr42,
294 HwReg::Nr43 => self.nr43,
295 HwReg::Nr44 => self.nr44,
296 HwReg::Nr50 => self.nr50,
297 HwReg::Nr51 => self.nr51,
298 HwReg::Nr52 => self.nr52,
299 HwReg::Wave0 => self.wave_0,
300 HwReg::Wave1 => self.wave_1,
301 HwReg::Wave2 => self.wave_2,
302 HwReg::Wave3 => self.wave_3,
303 HwReg::Wave4 => self.wave_4,
304 HwReg::Wave5 => self.wave_5,
305 HwReg::Wave6 => self.wave_6,
306 HwReg::Wave7 => self.wave_7,
307 HwReg::Wave8 => self.wave_8,
308 HwReg::Wave9 => self.wave_9,
309 HwReg::WaveA => self.wave_a,
310 HwReg::WaveB => self.wave_b,
311 HwReg::WaveC => self.wave_c,
312 HwReg::WaveD => self.wave_d,
313 HwReg::WaveE => self.wave_e,
314 HwReg::WaveF => self.wave_f,
315 HwReg::Lcdc => self.lcdc,
316 HwReg::Stat => self.stat,
317 HwReg::Scy => self.scy,
318 HwReg::Scx => self.scx,
319 HwReg::Ly => self.ly,
320 HwReg::Lyc => self.lyc,
321 HwReg::Dma => self.dma,
322 HwReg::Bgp => self.bgp,
323 HwReg::Obp0 => self.obp0,
324 HwReg::Obp1 => self.obp1,
325 HwReg::Wy => self.wy,
326 HwReg::Wx => self.wx,
327 HwReg::Key1 => self.key1,
328 HwReg::Vbk => self.vbk,
329 HwReg::Hdma1 => self.hdma1,
330 HwReg::Hdma2 => self.hdma2,
331 HwReg::Hdma3 => self.hdma3,
332 HwReg::Hdma4 => self.hdma4,
333 HwReg::Hdma5 => self.hdma5,
334 HwReg::Rp => self.rp,
335 HwReg::Bcps => self.bcps,
336 HwReg::Bcpd => self.bcpd,
337 HwReg::Ocps => self.ocps,
338 HwReg::Ocpd => self.ocpd,
339 HwReg::Svbk => self.svbk,
340 HwReg::Pcm12 => self.pcm12,
341 HwReg::Pcm34 => self.pcm34,
342 HwReg::Ie => self.ie,
343 }
344 }
345
346 pub fn write(&mut self, register: HwReg, value: u8) {
347 match register {
348 HwReg::Ramg => self.ramg = value,
349 HwReg::Romb0 => self.romb0 = value,
350 HwReg::Romb1 => self.romb1 = value,
351 HwReg::Ramb => self.ramb = value,
352 HwReg::Rtclatch => self.rtclatch = value,
353 HwReg::P1 => self.p1 = value,
354 HwReg::Sb => self.sb = value,
355 HwReg::Sc => self.sc = value,
356 HwReg::Div => self.div = value,
357 HwReg::Tima => self.tima = value,
358 HwReg::Tma => self.tma = value,
359 HwReg::Tac => self.tac = value,
360 HwReg::If => self._if = value,
361 HwReg::Nr10 => self.nr10 = value,
362 HwReg::Nr11 => self.nr11 = value,
363 HwReg::Nr12 => self.nr12 = value,
364 HwReg::Nr13 => self.nr13 = value,
365 HwReg::Nr14 => self.nr14 = value,
366 HwReg::Nr21 => self.nr21 = value,
367 HwReg::Nr22 => self.nr22 = value,
368 HwReg::Nr23 => self.nr23 = value,
369 HwReg::Nr24 => self.nr24 = value,
370 HwReg::Nr30 => self.nr30 = value,
371 HwReg::Nr31 => self.nr31 = value,
372 HwReg::Nr32 => self.nr32 = value,
373 HwReg::Nr33 => self.nr33 = value,
374 HwReg::Nr34 => self.nr34 = value,
375 HwReg::Nr41 => self.nr41 = value,
376 HwReg::Nr42 => self.nr42 = value,
377 HwReg::Nr43 => self.nr43 = value,
378 HwReg::Nr44 => self.nr44 = value,
379 HwReg::Nr50 => self.nr50 = value,
380 HwReg::Nr51 => self.nr51 = value,
381 HwReg::Nr52 => self.nr52 = value,
382 HwReg::Wave0 => self.wave_0 = value,
383 HwReg::Wave1 => self.wave_1 = value,
384 HwReg::Wave2 => self.wave_2 = value,
385 HwReg::Wave3 => self.wave_3 = value,
386 HwReg::Wave4 => self.wave_4 = value,
387 HwReg::Wave5 => self.wave_5 = value,
388 HwReg::Wave6 => self.wave_6 = value,
389 HwReg::Wave7 => self.wave_7 = value,
390 HwReg::Wave8 => self.wave_8 = value,
391 HwReg::Wave9 => self.wave_9 = value,
392 HwReg::WaveA => self.wave_a = value,
393 HwReg::WaveB => self.wave_b = value,
394 HwReg::WaveC => self.wave_c = value,
395 HwReg::WaveD => self.wave_d = value,
396 HwReg::WaveE => self.wave_e = value,
397 HwReg::WaveF => self.wave_f = value,
398 HwReg::Lcdc => self.lcdc = value,
399 HwReg::Stat => self.stat = value,
400 HwReg::Scy => self.scy = value,
401 HwReg::Scx => self.scx = value,
402 HwReg::Ly => self.ly = value,
403 HwReg::Lyc => self.lyc = value,
404 HwReg::Dma => self.dma = value,
405 HwReg::Bgp => self.bgp = value,
406 HwReg::Obp0 => self.obp0 = value,
407 HwReg::Obp1 => self.obp1 = value,
408 HwReg::Wy => self.wy = value,
409 HwReg::Wx => self.wx = value,
410 HwReg::Key1 => self.key1 = value,
411 HwReg::Vbk => self.vbk = value,
412 HwReg::Hdma1 => self.hdma1 = value,
413 HwReg::Hdma2 => self.hdma2 = value,
414 HwReg::Hdma3 => self.hdma3 = value,
415 HwReg::Hdma4 => self.hdma4 = value,
416 HwReg::Hdma5 => self.hdma5 = value,
417 HwReg::Rp => self.rp = value,
418 HwReg::Bcps => self.bcps = value,
419 HwReg::Bcpd => self.bcpd = value,
420 HwReg::Ocps => self.ocps = value,
421 HwReg::Ocpd => self.ocpd = value,
422 HwReg::Svbk => self.svbk = value,
423 HwReg::Pcm12 => self.pcm12 = value,
424 HwReg::Pcm34 => self.pcm34 = value,
425 HwReg::Ie => self.ie = value,
426 }
427 }
428
429 pub fn new() -> Mmio {
430 Default::default()
431 }
432}