1use std::convert::TryFrom;
2use std::ops::{Deref, DerefMut, Range};
3use std::{fmt, mem, slice};
4
5use log::trace;
6use thiserror::Error;
7
8pub use feo3boy_memdev_derive::MemDevice;
9
10use crate::apu::ApuRegs;
11use crate::input::ButtonRegister;
12use crate::interrupts::{InterruptContext, InterruptEnable, InterruptFlags, Interrupts};
13use crate::ppu::PpuRegs;
14use crate::serial::SerialRegs;
15use crate::timer::TimerRegs;
16
17pub use cartridge::{
18 Cartridge, Mbc1Rom, Mbc3Rom, ParseCartridgeError, RamBank, RomBank, RomOnly, SaveData,
19};
20
21mod cartridge;
22
23pub trait RangeOverlaps {
24 fn encloses(&self, other: &Self) -> bool;
26}
27
28impl RangeOverlaps for Range<usize> {
29 fn encloses(&self, other: &Self) -> bool {
30 self.start <= other.start && self.end >= other.end
31 }
32}
33
34#[derive(Copy, Clone, Debug)]
37pub struct RelativeAddr {
38 raw: u16,
40 relative: u16,
42}
43
44impl From<u16> for RelativeAddr {
45 #[inline]
48 fn from(raw: u16) -> Self {
49 Self::new(raw)
50 }
51}
52
53impl RelativeAddr {
54 pub const fn new(raw: u16) -> Self {
57 RelativeAddr { raw, relative: raw }
58 }
59
60 pub const fn device_start(addr: u16) -> Self {
64 RelativeAddr {
65 raw: addr,
66 relative: 0,
67 }
68 }
69
70 pub const fn raw(&self) -> u16 {
72 self.raw
73 }
74
75 pub const fn relative(&self) -> u16 {
77 self.relative
78 }
79
80 pub const fn index(&self) -> usize {
83 self.relative as usize
84 }
85
86 pub const fn offset(&self) -> u16 {
88 self.raw - self.relative
89 }
90
91 pub const fn range(&self, len: usize) -> Range<usize> {
93 self.index()..self.index() + len
94 }
95
96 pub const fn offset_by(&self, shift: u16) -> Self {
104 assert!(
105 shift <= self.relative,
106 "Attempting to offset with overflow."
107 );
108 RelativeAddr {
109 raw: self.raw,
110 relative: self.relative - shift,
111 }
112 }
113
114 pub const fn skip_over(&self, skipped: u16) -> Self {
119 RelativeAddr {
120 raw: self.raw,
121 relative: match self.relative.checked_add(skipped) {
122 Some(val) => val,
123 None => {
124 panic!("Attempting to skip_over with overflow.")
125 }
126 },
127 }
128 }
129
130 pub const fn move_forward_by(&self, added: u16) -> Self {
133 RelativeAddr {
134 raw: self.raw + added,
135 relative: self.relative + added,
136 }
137 }
138
139 pub const fn move_forward_by_wrapping(&self, added: u16) -> Self {
142 RelativeAddr {
143 raw: self.raw.wrapping_add(added),
144 relative: self.relative.wrapping_add(added),
145 }
146 }
147}
148
149impl fmt::Display for RelativeAddr {
150 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
151 write!(f, "{:x}h({:x}h)", self.raw, self.relative)
152 }
153}
154
155pub trait MemDevice {
157 const LEN: usize;
159
160 #[inline]
163 fn read_relative_into<V>(&self, addr: RelativeAddr, dest: &mut V)
164 where
165 V: MemValue,
166 {
167 struct Reader<'a, M: ?Sized> {
168 addr: RelativeAddr,
169 device: &'a M,
170 }
171 impl<'a, M: MemDevice + ?Sized> MemSource for Reader<'a, M> {
172 #[inline(always)]
173 fn get_byte(self) -> u8 {
174 self.device.read_byte_relative(self.addr)
175 }
176 #[inline(always)]
177 fn get_bytes(self, data: &mut [u8]) {
178 self.device.read_bytes_relative(self.addr, data)
179 }
180 }
181
182 dest.copy_from_mem(Reader { addr, device: self })
183 }
184
185 #[inline]
188 fn read_relative<V>(&self, addr: RelativeAddr) -> V
189 where
190 V: MemValue + Default,
191 {
192 let mut val = V::default();
193 self.read_relative_into(addr, &mut val);
194 val
195 }
196
197 #[inline]
200 fn write_relative_from<V>(&mut self, addr: RelativeAddr, source: &V)
201 where
202 V: MemValue,
203 {
204 struct Writer<'a, M: ?Sized> {
205 addr: RelativeAddr,
206 device: &'a mut M,
207 }
208 impl<'a, M: MemDevice + ?Sized> MemDest for Writer<'a, M> {
209 #[inline(always)]
210 fn set_byte(self, val: u8) {
211 self.device.write_byte_relative(self.addr, val)
212 }
213 #[inline(always)]
214 fn set_bytes(self, data: &[u8]) {
215 self.device.write_bytes_relative(self.addr, data)
216 }
217 }
218
219 source.copy_to_mem(Writer { addr, device: self })
220 }
221
222 #[inline]
225 fn write_relative<V>(&mut self, addr: RelativeAddr, val: V)
226 where
227 V: MemValue,
228 {
229 self.write_relative_from(addr, &val)
230 }
231
232 #[inline]
238 fn read_byte_relative(&self, addr: RelativeAddr) -> u8 {
239 let mut out = 0;
240 self.read_bytes_relative(addr, slice::from_mut(&mut out));
241 out
242 }
243
244 fn read_bytes_relative(&self, addr: RelativeAddr, data: &mut [u8]);
247
248 #[inline]
254 fn write_byte_relative(&mut self, addr: RelativeAddr, data: u8) {
255 self.write_bytes_relative(addr, slice::from_ref(&data));
256 }
257
258 fn write_bytes_relative(&mut self, addr: RelativeAddr, data: &[u8]);
261}
262
263pub trait RootMemDevice: MemDevice {
273 #[inline]
276 fn read_into<V>(&self, addr: u16, dest: &mut V)
277 where
278 V: MemValue,
279 {
280 struct Reader<'a, M: ?Sized> {
281 addr: u16,
282 device: &'a M,
283 }
284 impl<'a, M: RootMemDevice + ?Sized> MemSource for Reader<'a, M> {
285 #[inline(always)]
286 fn get_byte(self) -> u8 {
287 self.device.read_byte(self.addr)
288 }
289 #[inline(always)]
290 fn get_bytes(self, data: &mut [u8]) {
291 self.device.read_bytes(self.addr, data)
292 }
293 }
294
295 dest.copy_from_mem(Reader { addr, device: self })
296 }
297
298 #[inline]
301 fn read<V>(&self, addr: u16) -> V
302 where
303 V: MemValue + Default,
304 {
305 let mut val = V::default();
306 self.read_into(addr, &mut val);
307 val
308 }
309
310 #[inline]
313 fn write_from<V>(&mut self, addr: u16, source: &V)
314 where
315 V: MemValue,
316 {
317 struct Writer<'a, M: ?Sized> {
318 addr: u16,
319 device: &'a mut M,
320 }
321 impl<'a, M: RootMemDevice + ?Sized> MemDest for Writer<'a, M> {
322 #[inline(always)]
323 fn set_byte(self, val: u8) {
324 self.device.write_byte(self.addr, val)
325 }
326 #[inline(always)]
327 fn set_bytes(self, data: &[u8]) {
328 self.device.write_bytes(self.addr, data)
329 }
330 }
331
332 source.copy_to_mem(Writer { addr, device: self })
333 }
334
335 #[inline]
338 fn write<V>(&mut self, addr: u16, val: V)
339 where
340 V: MemValue,
341 {
342 self.write_from(addr, &val)
343 }
344
345 #[inline]
347 fn read_byte(&self, addr: u16) -> u8 {
348 self.read_byte_relative(addr.into())
349 }
350
351 fn read_bytes(&self, mut addr: u16, mut data: &mut [u8]) {
353 const SIZE: usize = u16::MAX as usize + 1;
354 loop {
355 let len = SIZE - addr as usize;
356 if len < data.len() {
357 let (current, rest) = data.split_at_mut(len);
358 self.read_bytes_relative(addr.into(), current);
359 data = rest;
360 addr = 0;
361 } else {
362 self.read_bytes_relative(addr.into(), data);
363 break;
364 }
365 }
366 }
367
368 #[inline]
370 fn write_byte(&mut self, addr: u16, val: u8) {
371 self.write_byte_relative(addr.into(), val);
372 }
373
374 fn write_bytes(&mut self, mut addr: u16, mut data: &[u8]) {
376 const SIZE: usize = u16::MAX as usize + 1;
377 loop {
378 let len = SIZE - addr as usize;
379 if len < data.len() {
380 let (current, rest) = data.split_at(len);
381 self.write_bytes_relative(addr.into(), current);
382 data = rest;
383 addr = 0;
384 } else {
385 self.write_bytes_relative(addr.into(), data);
386 break;
387 }
388 }
389 }
390}
391
392pub trait MemSource {
398 fn get_byte(self) -> u8;
400 fn get_bytes(self, data: &mut [u8]);
402}
403
404pub trait MemDest {
410 fn set_byte(self, val: u8);
412 fn set_bytes(self, data: &[u8]);
414}
415
416pub trait MemValue {
418 fn copy_from_mem<S: MemSource>(&mut self, source: S);
420
421 fn copy_to_mem<D: MemDest>(&self, dest: D);
422}
423
424impl MemValue for u8 {
425 #[inline]
426 fn copy_from_mem<S: MemSource>(&mut self, source: S) {
427 *self = source.get_byte()
428 }
429
430 #[inline]
431 fn copy_to_mem<D: MemDest>(&self, dest: D) {
432 dest.set_byte(*self)
433 }
434}
435
436impl<const N: usize> MemValue for [u8; N] {
437 #[inline]
438 fn copy_from_mem<S: MemSource>(&mut self, source: S) {
439 source.get_bytes(self.as_mut())
440 }
441
442 #[inline]
443 fn copy_to_mem<D: MemDest>(&self, dest: D) {
444 dest.set_bytes(self.as_ref())
445 }
446}
447
448impl MemValue for i8 {
449 #[inline]
450 fn copy_from_mem<S: MemSource>(&mut self, source: S) {
451 *self = source.get_byte() as i8
452 }
453
454 #[inline]
455 fn copy_to_mem<D: MemDest>(&self, dest: D) {
456 dest.set_byte(*self as u8)
457 }
458}
459
460impl MemValue for u16 {
461 #[inline]
462 fn copy_from_mem<S: MemSource>(&mut self, source: S) {
463 let mut bytes = [0u8; 2];
464 source.get_bytes(bytes.as_mut());
465 *self = u16::from_le_bytes(bytes);
466 }
467
468 #[inline]
469 fn copy_to_mem<D: MemDest>(&self, dest: D) {
470 let bytes = self.to_le_bytes();
471 dest.set_bytes(bytes.as_ref());
472 }
473}
474
475pub trait MemContext {
477 type Mem: RootMemDevice;
479
480 fn mem(&self) -> &Self::Mem;
482
483 fn mem_mut(&mut self) -> &mut Self::Mem;
485}
486
487#[derive(Debug, Clone, Eq, PartialEq)]
490#[repr(transparent)]
491pub struct RootExtend<M>(M);
492
493impl<M> RootExtend<M> {
494 #[inline]
496 pub fn wrap_ref<'a>(m: &'a M) -> &'a Self {
497 unsafe { mem::transmute(m) }
501 }
502
503 #[inline]
505 pub fn wrap_mut<'a>(m: &'a mut M) -> &'a mut Self {
506 unsafe { mem::transmute(m) }
510 }
511}
512
513impl<M: MemDevice> MemDevice for RootExtend<M> {
514 const LEN: usize = u16::MAX as usize + 1;
515
516 fn read_byte_relative(&self, addr: RelativeAddr) -> u8 {
517 assert!(
518 addr.relative() == addr.raw(),
519 "Using RootExtend with offset address {}",
520 addr
521 );
522 if addr.index() < M::LEN {
523 self.0.read_byte_relative(addr)
524 } else {
525 check_addr!(RootExtend<M>, addr);
526 0xff
527 }
528 }
529
530 fn read_bytes_relative(&self, addr: RelativeAddr, mut data: &mut [u8]) {
531 assert!(
532 addr.relative() == addr.raw(),
533 "Using RootExtend with offset address {}",
534 addr
535 );
536 check_addr!(RootExtend<M>, addr, data.len());
537 if addr.index() < M::LEN {
538 let num_read = (M::LEN - addr.index()).min(data.len());
539 self.0.read_bytes_relative(addr, &mut data[..num_read]);
540 data = &mut data[num_read..];
541 }
542 data.fill(0xff);
545 }
546
547 fn write_byte_relative(&mut self, addr: RelativeAddr, data: u8) {
548 assert!(
549 addr.relative() == addr.raw(),
550 "Using RootExtend with offset address {}",
551 addr
552 );
553 if addr.index() < M::LEN {
554 self.0.write_byte_relative(addr, data)
555 } else {
556 check_addr!(RootExtend<M>, addr);
557 }
558 }
559
560 fn write_bytes_relative(&mut self, addr: RelativeAddr, data: &[u8]) {
561 assert!(
562 addr.relative() == addr.raw(),
563 "Using RootExtend with offset address {}",
564 addr
565 );
566 check_addr!(RootExtend<M>, addr, data.len());
567 if addr.index() < M::LEN {
568 let num_written = (M::LEN - addr.index()).min(data.len());
569 self.0.write_bytes_relative(addr, &data[..num_written]);
570 }
571 }
572}
573
574impl<M: MemDevice> RootMemDevice for RootExtend<M> {}
575
576#[repr(transparent)]
578#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
579pub struct ReadOnly<M>(M);
580
581impl<M> Deref for ReadOnly<M> {
582 type Target = M;
583
584 fn deref(&self) -> &Self::Target {
585 &self.0
586 }
587}
588
589impl<M> ReadOnly<M> {
590 pub fn new(mem: M) -> Self {
592 Self(mem)
593 }
594
595 pub fn into_inner(self) -> M {
597 self.0
598 }
599}
600
601impl<M: MemDevice> MemDevice for ReadOnly<M> {
602 const LEN: usize = M::LEN;
603
604 #[inline]
605 fn read_bytes_relative(&self, addr: RelativeAddr, data: &mut [u8]) {
606 self.0.read_bytes_relative(addr, data);
607 }
608
609 #[inline]
610 fn read_byte_relative(&self, addr: RelativeAddr) -> u8 {
611 self.0.read_byte_relative(addr)
612 }
613
614 #[inline]
615 fn write_bytes_relative(&mut self, addr: RelativeAddr, data: &[u8]) {
616 check_addr!(ReadOnly<M>, addr, data.len());
617 }
618
619 #[inline]
620 fn write_byte_relative(&mut self, addr: RelativeAddr, _data: u8) {
621 check_addr!(ReadOnly<M>, addr);
622 }
623}
624
625impl<M: RootMemDevice> RootMemDevice for ReadOnly<M> {
626 fn read_byte(&self, addr: u16) -> u8 {
627 self.0.read_byte(addr)
628 }
629
630 fn read_bytes(&self, addr: u16, data: &mut [u8]) {
631 self.0.read_bytes(addr, data)
632 }
633
634 fn write_byte(&mut self, _addr: u16, _val: u8) {}
635
636 fn write_bytes(&mut self, _addr: u16, _data: &[u8]) {}
637}
638
639pub struct NullRom<const N: usize>;
642
643impl<const N: usize> MemDevice for NullRom<N> {
644 const LEN: usize = N;
645
646 fn read_bytes_relative(&self, addr: RelativeAddr, data: &mut [u8]) {
647 check_addr!(NullRom<N>, addr, data.len());
648 data.fill(0xff);
649 }
650
651 fn write_bytes_relative(&mut self, addr: RelativeAddr, data: &[u8]) {
652 check_addr!(NullRom<N>, addr, data.len());
653 }
654}
655
656const BIOS_LEN: usize = 0x100;
657
658#[repr(transparent)]
660#[derive(Copy, Clone, Debug, Eq, PartialEq, MemDevice)]
661#[memdev(passthrough)]
662pub struct BiosRom(ReadOnly<[u8; BIOS_LEN]>);
663
664impl BiosRom {
665 pub fn new(data: [u8; BIOS_LEN]) -> Self {
667 Self(ReadOnly::new(data))
668 }
669
670 pub fn try_from_slice(data: &[u8]) -> Result<Self, BiosSizeError> {
675 Self::try_from(data)
676 }
677}
678
679impl Deref for BiosRom {
680 type Target = [u8];
681
682 fn deref(&self) -> &Self::Target {
683 self.0.as_ref()
684 }
685}
686
687impl Default for BiosRom {
688 fn default() -> Self {
689 Self(ReadOnly::new([0; BIOS_LEN]))
690 }
691}
692
693#[derive(Copy, Clone, Debug, Error)]
696#[error("Expected exactly 256 bytes, got {0}")]
697pub struct BiosSizeError(pub usize);
698
699impl TryFrom<&[u8]> for BiosRom {
700 type Error = BiosSizeError;
701
702 fn try_from(data: &[u8]) -> Result<Self, BiosSizeError> {
703 if data.len() != BIOS_LEN {
704 Err(BiosSizeError(data.len()))
705 } else {
706 let mut arr = [0; BIOS_LEN];
707 arr.copy_from_slice(data);
708 Ok(Self(ReadOnly::new(arr)))
709 }
710 }
711}
712
713impl TryFrom<Vec<u8>> for BiosRom {
714 type Error = BiosSizeError;
715
716 fn try_from(data: Vec<u8>) -> Result<Self, BiosSizeError> {
717 Self::try_from(&*data)
718 }
719}
720
721#[derive(Debug, Clone, Eq, PartialEq, MemDevice)]
723#[memdev(byte, read = Self::get_byte, write = Self::set_byte)]
724pub struct BiosEnable(bool);
725
726impl BiosEnable {
727 pub fn enabled(&self) -> bool {
729 self.0
730 }
731
732 fn get_byte(&self) -> u8 {
733 self.0 as u8
734 }
735
736 fn set_byte(&mut self, data: u8) {
737 self.0 = self.0 && data == 0;
739 }
740}
741
742impl Default for BiosEnable {
743 fn default() -> Self {
744 Self(true)
745 }
746}
747
748impl<const N: usize> MemDevice for [u8; N] {
749 const LEN: usize = N;
750
751 fn read_byte_relative(&self, addr: RelativeAddr) -> u8 {
752 match self.get(addr.index()) {
753 Some(val) => *val,
754 None => panic!("Address {} out of range for {} byte memory array", addr, N),
755 }
756 }
757
758 fn write_byte_relative(&mut self, addr: RelativeAddr, value: u8) {
759 match self.get_mut(addr.index()) {
760 Some(val) => *val = value,
761 None => panic!("Address {} out of range for {} byte memory array", addr, N),
762 }
763 }
764
765 fn read_bytes_relative(&self, addr: RelativeAddr, data: &mut [u8]) {
766 match self.get(addr.range(data.len())) {
767 Some(vals) => data.copy_from_slice(vals),
768 None => panic!(
769 "Address {} + {} byte slice out of range for {} byte memory array",
770 addr,
771 data.len(),
772 N
773 ),
774 }
775 }
776
777 fn write_bytes_relative(&mut self, addr: RelativeAddr, data: &[u8]) {
778 match self.get_mut(addr.range(data.len())) {
779 Some(vals) => vals.copy_from_slice(data),
780 None => panic!(
781 "Address {} + {} byte slice out of range for {} byte memory array",
782 addr,
783 data.len(),
784 N
785 ),
786 }
787 }
788}
789
790impl RootMemDevice for [u8; 0x10000] {
791 fn read_byte(&self, addr: u16) -> u8 {
792 self[addr as usize]
793 }
794
795 fn write_byte(&mut self, addr: u16, val: u8) {
796 self[addr as usize] = val;
797 }
798}
799
800pub trait CustomDefault {
803 fn custom_default() -> Self;
804}
805
806impl<const N: usize> CustomDefault for [u8; N] {
807 fn custom_default() -> Self {
808 [0; N]
809 }
810}
811
812#[derive(Clone, Default, Debug, PartialEq, Eq)]
813pub struct MaskableMem<M> {
814 device: M,
815 masked: bool,
816}
817
818impl<M: CustomDefault> MaskableMem<M> {
819 pub fn new() -> Self {
820 MaskableMem::custom_default()
821 }
822}
823
824impl<M> MaskableMem<M> {
825 pub fn mask(&mut self) {
826 self.masked = true;
827 }
828
829 pub fn unmask(&mut self) {
830 self.masked = false;
831 }
832
833 pub fn bypass(&self) -> &M {
835 &self.device
836 }
837
838 pub fn bypass_mut(&mut self) -> &mut M {
840 &mut self.device
841 }
842}
843
844impl<M: CustomDefault> CustomDefault for MaskableMem<M> {
845 fn custom_default() -> Self {
846 MaskableMem {
847 device: M::custom_default(),
848 masked: false,
849 }
850 }
851}
852
853impl<M: MemDevice> MemDevice for MaskableMem<M> {
854 const LEN: usize = M::LEN;
855
856 fn read_byte_relative(&self, addr: RelativeAddr) -> u8 {
857 if !self.masked {
858 self.device.read_byte_relative(addr)
859 } else {
860 check_addr!(MaskableMem<M>, addr);
861 0xff
862 }
863 }
864
865 fn write_byte_relative(&mut self, addr: RelativeAddr, value: u8) {
866 if !self.masked {
867 self.device.write_byte_relative(addr, value)
868 } else {
869 check_addr!(MaskableMem<M>, addr);
870 }
871 }
872
873 fn read_bytes_relative(&self, addr: RelativeAddr, data: &mut [u8]) {
874 if !self.masked {
875 self.device.read_bytes_relative(addr, data)
876 } else {
877 check_addr!(MaskableMem<M>, addr, data.len());
878 data.fill(0xff);
879 }
880 }
881
882 fn write_bytes_relative(&mut self, addr: RelativeAddr, data: &[u8]) {
883 if !self.masked {
884 self.device.write_bytes_relative(addr, data)
885 } else {
886 check_addr!(MaskableMem<M>, addr, data.len());
887 }
888 }
889}
890
891impl<M: RootMemDevice> RootMemDevice for MaskableMem<M> {}
892
893impl<M> Deref for MaskableMem<M> {
894 type Target = M;
895 fn deref(&self) -> &Self::Target {
896 &self.device
897 }
898}
899
900impl<M> DerefMut for MaskableMem<M> {
901 fn deref_mut(&mut self) -> &mut Self::Target {
902 &mut self.device
903 }
904}
905
906impl MemDevice for u8 {
908 const LEN: usize = 1;
909
910 #[inline]
911 fn read_byte_relative(&self, addr: RelativeAddr) -> u8 {
912 check_addr!(u8, addr);
913 *self
914 }
915
916 #[inline]
917 fn write_byte_relative(&mut self, addr: RelativeAddr, val: u8) {
918 check_addr!(u8, addr);
919 *self = val;
920 }
921
922 #[inline]
923 fn read_bytes_relative(&self, addr: RelativeAddr, data: &mut [u8]) {
924 check_addr!(u8, addr, data.len());
925 match data.first_mut() {
926 Some(out) => *out = *self,
927 None => {}
928 }
929 }
930
931 #[inline]
932 fn write_bytes_relative(&mut self, addr: RelativeAddr, data: &[u8]) {
933 check_addr!(u8, addr, data.len());
934 match data.first() {
935 Some(val) => *self = *val,
936 None => {}
937 }
938 }
939}
940
941impl<D: MemDevice> MemDevice for Box<D> {
944 const LEN: usize = D::LEN;
945
946 #[inline]
947 fn read_byte_relative(&self, addr: RelativeAddr) -> u8 {
948 (**self).read_byte_relative(addr)
949 }
950
951 #[inline]
952 fn write_byte_relative(&mut self, addr: RelativeAddr, value: u8) {
953 (**self).write_byte_relative(addr, value)
954 }
955
956 #[inline]
957 fn read_bytes_relative(&self, addr: RelativeAddr, data: &mut [u8]) {
958 (**self).read_bytes_relative(addr, data)
959 }
960
961 #[inline]
962 fn write_bytes_relative(&mut self, addr: RelativeAddr, data: &[u8]) {
963 (**self).write_bytes_relative(addr, data)
964 }
965}
966
967impl<D: RootMemDevice> RootMemDevice for Box<D> {
968 #[inline]
969 fn read_byte(&self, addr: u16) -> u8 {
970 (**self).read_byte(addr)
971 }
972
973 #[inline]
974 fn read_bytes(&self, addr: u16, data: &mut [u8]) {
975 (**self).read_bytes(addr, data)
976 }
977
978 #[inline]
979 fn write_byte(&mut self, addr: u16, data: u8) {
980 (**self).write_byte(addr, data)
981 }
982
983 #[inline]
984 fn write_bytes(&mut self, addr: u16, data: &[u8]) {
985 (**self).write_bytes(addr, data)
986 }
987}
988
989#[derive(Clone, Default, Debug, PartialEq, Eq)]
991pub struct MemMappedIo {
992 pub buttons: ButtonRegister,
993 pub serial_regs: SerialRegs,
995 pub timer_regs: TimerRegs,
997 pub interrupt_flags: InterruptFlags,
999 pub apu_regs: ApuRegs,
1001 pub ppu_regs: PpuRegs,
1003 pub bios_enable: BiosEnable,
1004}
1005
1006impl MemMappedIo {
1007 pub fn new() -> Self {
1009 Default::default()
1010 }
1011}
1012
1013memdev_fields!(MemMappedIo, len: 0x80, {
1014 0x00 => buttons,
1015 0x01..=0x02 => serial_regs,
1016 0x03 => 0xff,
1017 0x04..=0x07 => timer_regs,
1018 0x08..=0x0e => 0xff,
1019 0x0f => interrupt_flags,
1020 0x10..=0x3f => apu_regs,
1021 0x40..=0x4b => ppu_regs,
1022 0x4c..=0x4f => 0xff,
1023 0x50 => bios_enable,
1024 0x51..=0x7f => 0xff,
1025});
1026
1027pub type Vram = MaskableMem<MaskableMem<[u8; 0x2000]>>;
1028pub type Oam = MaskableMem<MaskableMem<[u8; 160]>>;
1029
1030#[derive(Debug, MemDevice)]
1036#[memdev(passthrough)]
1037pub struct AllRam(Box<[u8; 0x10000]>);
1038
1039impl RootMemDevice for AllRam {
1040 #[inline]
1041 fn read_byte(&self, addr: u16) -> u8 {
1042 self.0.read_byte(addr)
1043 }
1044
1045 #[inline]
1046 fn read_bytes(&self, addr: u16, data: &mut [u8]) {
1047 self.0.read_bytes(addr, data)
1048 }
1049
1050 #[inline]
1051 fn write_byte(&mut self, addr: u16, val: u8) {
1052 self.0.write_byte(addr, val);
1053 }
1054
1055 #[inline]
1056 fn write_bytes(&mut self, addr: u16, data: &[u8]) {
1057 self.0.write_bytes(addr, data)
1058 }
1059}
1060
1061impl From<&[u8]> for AllRam {
1062 fn from(bytes: &[u8]) -> Self {
1064 assert!(bytes.len() <= 0x10000);
1065 let mut ram = Box::new([0; 0x10000]);
1066 ram[..bytes.len()].copy_from_slice(bytes);
1067 Self(ram)
1068 }
1069}
1070
1071impl<const N: usize> From<&[u8; N]> for AllRam {
1072 fn from(bytes: &[u8; N]) -> Self {
1075 (&bytes[..]).into()
1076 }
1077}
1078
1079#[derive(Clone, Debug, Eq, PartialEq)]
1081pub struct GbMmu {
1082 pub bios: BiosRom,
1084 pub cart: Cartridge,
1086 pub vram: Vram,
1088 pub wram: [u8; 0x2000],
1090 pub oam: Oam,
1092 pub io: MemMappedIo,
1095 pub zram: [u8; 127],
1098 pub interrupt_enable: InterruptEnable,
1100}
1101
1102impl GbMmu {
1103 pub fn new(bios: BiosRom, cart: Cartridge) -> GbMmu {
1106 GbMmu {
1107 bios,
1108 cart,
1109 vram: Vram::new(),
1110 wram: [0; 0x2000],
1111 oam: Oam::new(),
1112 io: MemMappedIo::new(),
1113 zram: [0; 127],
1114 interrupt_enable: InterruptEnable(InterruptFlags::empty()),
1115 }
1116 }
1117}
1118
1119impl Default for GbMmu {
1120 fn default() -> Self {
1121 Self::new(Default::default(), Cartridge::None)
1122 }
1123}
1124
1125impl MemDevice for GbMmu {
1126 const LEN: usize = u16::MAX as usize + 1;
1127
1128 fn read_byte_relative(&self, addr: RelativeAddr) -> u8 {
1129 assert!(
1130 addr.relative() == addr.raw(),
1131 "Using Root MMU with offset address {}",
1132 addr
1133 );
1134 trace!("Read from MMU address {:#x}", addr.raw);
1135 dispatch_memdev_byte!(GbMmu, addr, |addr| {
1136 0x0..=0xff if self.io.bios_enable.enabled() => self.bios.read_byte_relative(addr),
1137 0x0..=0x7fff => self.cart.read_byte_relative(addr),
1138 0x8000..=0x9fff => self.vram.read_byte_relative(addr),
1139 0xa000..=0xbfff => self.cart.read_byte_relative(addr.skip_over(0x8000)),
1142 0xc000..=0xdfff => self.wram.read_byte_relative(addr),
1143 0xe000..=0xfdff => self.wram.read_byte_relative(addr),
1144 0xfe00..=0xfe9f => self.oam.read_byte_relative(addr),
1145 0xfea0..=0xfeff => 0xff,
1147 0xff00..=0xff7f => self.io.read_byte_relative(addr),
1148 0xff80..=0xfffe => self.zram.read_byte_relative(addr),
1149 0xffff => self.interrupt_enable.read_byte_relative(addr),
1150 })
1151 }
1152
1153 fn read_bytes_relative(&self, addr: RelativeAddr, data: &mut [u8]) {
1154 assert!(
1155 addr.relative() == addr.raw(),
1156 "Using Root MMU with offset address {}",
1157 addr
1158 );
1159 trace!("Read {} bytes from MMU address {:#x}", data.len(), addr.raw);
1160 dispatch_memdev_bytes!(GbMmu, addr, data, |addr, mut data| {
1161 0x0..=0xff if self.io.bios_enable.enabled() => self.bios.read_bytes_relative(addr, data),
1162 0x0..=0x7fff => self.cart.read_bytes_relative(addr, data),
1163 0x8000..=0x9fff => self.vram.read_bytes_relative(addr, data),
1164 0xa000..=0xbfff => self.cart.read_bytes_relative(addr.skip_over(0x8000), data),
1167 0xc000..=0xdfff => self.wram.read_bytes_relative(addr, data),
1168 0xe000..=0xfdff => self.wram.read_bytes_relative(addr, data),
1169 0xfe00..=0xfe9f => self.oam.read_bytes_relative(addr, data),
1170 0xfea0..=0xfeff => data.fill(0xff),
1172 0xff00..=0xff7f => self.io.read_bytes_relative(addr, data),
1173 0xff80..=0xfffe => self.zram.read_bytes_relative(addr, data),
1174 0xffff => self.interrupt_enable.read_bytes_relative(addr, data),
1175 });
1176 }
1177
1178 fn write_byte_relative(&mut self, addr: RelativeAddr, value: u8) {
1179 assert!(
1180 addr.relative() == addr.raw(),
1181 "Using Root MMU with offset address {}",
1182 addr
1183 );
1184 trace!("Write at MMU address {:#x}", addr.raw);
1185 dispatch_memdev_byte!(GbMmu, addr, |addr| {
1187 0x0..=0xff if self.io.bios_enable.enabled() => self.bios.write_byte_relative(addr, value),
1188 0x0..=0x7fff => self.cart.write_byte_relative(addr, value),
1189 0x8000..=0x9fff => self.vram.write_byte_relative(addr, value),
1190 0xa000..=0xbfff => self.cart.write_byte_relative(addr.skip_over(0x8000), value),
1193 0xc000..=0xdfff => self.wram.write_byte_relative(addr, value),
1194 0xe000..=0xfdff => self.wram.write_byte_relative(addr, value),
1195 0xfe00..=0xfe9f => self.oam.write_byte_relative(addr, value),
1196 0xfea0..=0xfeff => (),
1198 0xff00..=0xff7f => self.io.write_byte_relative(addr, value),
1199 0xff80..=0xfffe => self.zram.write_byte_relative(addr, value),
1200 0xffff => self.interrupt_enable.write_byte_relative(addr, value),
1201 })
1202 }
1203
1204 fn write_bytes_relative(&mut self, addr: RelativeAddr, data: &[u8]) {
1205 assert!(
1206 addr.relative() == addr.raw(),
1207 "Using Root MMU with offset address {}",
1208 addr
1209 );
1210 trace!("Write {} bytes at MMU address {:#x}", data.len(), addr.raw);
1211 dispatch_memdev_bytes!(GbMmu, addr, data, |addr, ref data| {
1212 0x0..=0xff if self.io.bios_enable.enabled() => self.bios.write_bytes_relative(addr, data),
1213 0x0..=0x7fff => self.cart.write_bytes_relative(addr, data),
1214 0x8000..=0x9fff => self.vram.write_bytes_relative(addr, data),
1215 0xa000..=0xbfff => self.cart.write_bytes_relative(addr.skip_over(0x8000), data),
1218 0xc000..=0xdfff => self.wram.write_bytes_relative(addr, data),
1219 0xe000..=0xfdff => self.wram.write_bytes_relative(addr, data),
1220 0xfe00..=0xfe9f => self.oam.write_bytes_relative(addr, data),
1221 0xfea0..=0xfeff => {},
1223 0xff00..=0xff7f => self.io.write_bytes_relative(addr, data),
1224 0xff80..=0xfffe => self.zram.write_bytes_relative(addr, data),
1225 0xffff => self.interrupt_enable.write_bytes_relative(addr, data),
1226 });
1227 }
1228}
1229
1230impl RootMemDevice for GbMmu {}
1231
1232impl MemContext for GbMmu {
1233 type Mem = Self;
1234
1235 fn mem(&self) -> &Self::Mem {
1236 self
1237 }
1238
1239 fn mem_mut(&mut self) -> &mut Self::Mem {
1240 self
1241 }
1242}
1243
1244impl InterruptContext for GbMmu {
1245 type Interrupts = Self;
1246
1247 fn interrupts(&self) -> &Self::Interrupts {
1248 self
1249 }
1250
1251 fn interrupts_mut(&mut self) -> &mut Self::Interrupts {
1252 self
1253 }
1254}
1255
1256impl Interrupts for GbMmu {
1257 #[inline]
1258 fn queued(&self) -> InterruptFlags {
1259 self.io.interrupt_flags
1260 }
1261
1262 #[inline]
1263 fn set_queued(&mut self, flags: InterruptFlags) {
1264 self.io.interrupt_flags = flags;
1265 }
1266
1267 #[inline]
1268 fn enabled(&self) -> InterruptFlags {
1269 self.interrupt_enable.0
1270 }
1271
1272 #[inline]
1273 fn set_enabled(&mut self, flags: InterruptFlags) {
1274 self.interrupt_enable.0 = flags;
1275 }
1276}
1277
1278#[cfg(test)]
1279mod tests {
1280 use super::*;
1281
1282 use rand::distributions::Uniform;
1283 use rand::{Rng, SeedableRng};
1284 use rand_pcg::Pcg64Mcg;
1285
1286 fn init() {
1287 let _ = env_logger::builder().is_test(true).try_init();
1288 }
1289
1290 #[test]
1291 fn mmu_range_readwrite() {
1292 init();
1293
1294 let mut bios = BiosRom::new([0u8; 0x100]);
1295 for (i, byte) in bios.0 .0.iter_mut().enumerate() {
1296 *byte = i as u8;
1297 }
1298 let mut mmu_individual = GbMmu::new(bios, Cartridge::None);
1299 let mut mmu_slice = GbMmu::new(bios, Cartridge::None);
1300
1301 let mut input_buf = vec![];
1302 let mut output_buf_individual = vec![];
1303 let mut output_buf_slice = vec![];
1304 let mut rng =
1305 Pcg64Mcg::from_seed([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF]);
1306
1307 let len_dist = Uniform::new_inclusive(1, 0x400);
1308
1309 assert_eq!(mmu_individual, mmu_slice);
1310
1311 for _ in 0..0x80000 {
1312 let addr: u16 = rng.gen();
1313 let len = rng.sample(&len_dist);
1314 input_buf.resize(len, 0u8);
1315 rng.fill(&mut input_buf[..]);
1316
1317 for (i, &val) in input_buf.iter().enumerate() {
1318 mmu_individual.write_byte(addr.wrapping_add(i as u16), val);
1319 }
1320 mmu_slice.write_bytes(addr, &input_buf);
1321
1322 output_buf_individual.resize(len, 0u8);
1323 for (i, res) in output_buf_individual.iter_mut().enumerate() {
1324 *res = mmu_individual.read_byte(addr.wrapping_add(i as u16));
1325 }
1326 output_buf_slice.resize(len, 0u8);
1327 mmu_slice.read_bytes(addr, &mut output_buf_slice);
1328
1329 assert_eq!(output_buf_individual, output_buf_slice);
1330 }
1331
1332 assert_eq!(mmu_individual, mmu_slice);
1334 }
1335}