spectrusty_peripherals/memory/
zxinterface1.rs1use std::rc::Rc;
9use std::io::{self, Read};
10
11use spectrusty_core::memory::{
12 MemoryExtension, ExRom, ZxMemory, ZxMemoryError
13};
14#[cfg(feature = "snapshot")]
15use spectrusty_core::memory::serde::{serialize_mem, deserialize_mem};
16#[cfg(feature = "snapshot")]
17use serde::{Serialize, Deserialize};
18
19#[derive(Clone, Debug)]
24#[cfg_attr(feature = "snapshot", derive(Serialize, Deserialize))]
25pub struct ZxInterface1MemExt {
26 #[cfg_attr(feature = "snapshot",
27 serde(serialize_with = "serialize_mem", deserialize_with = "deserialize_mem"))]
28 #[cfg_attr(feature = "snapshot", serde(default = "exrom_default"))]
29 exrom: ExRom
30}
31
32impl Default for ZxInterface1MemExt {
33 fn default() -> Self {
34 let exrom = Rc::new([]);
35 ZxInterface1MemExt { exrom }
36 }
37}
38
39impl MemoryExtension for ZxInterface1MemExt {
40 #[inline(always)]
41 fn read_opcode<M: ZxMemory>(&mut self, pc: u16, memory: &mut M) -> u8 {
42 match pc {
43 0x0008|0x1708 => {
44 let _ = memory.map_exrom(Rc::clone(&self.exrom), 0);
45 }
46 0x0700 => {
47 let res = memory.read(pc);
48 memory.unmap_exrom(&self.exrom);
49 return res
50 }
51 _ => {}
52 }
53 memory.read(pc)
54 }
55}
56
57impl ZxInterface1MemExt {
58 pub fn load_if1_rom<R: Read>(&mut self, mut rd: R) -> io::Result<()> {
60 let mut exrom = Rc::new([!0u8;0x4000]);
61 let exrom_slice = &mut Rc::get_mut(&mut exrom).unwrap()[0..0x2000];
62 rd.read_exact(exrom_slice)?;
63 self.exrom = exrom;
64 Ok(())
65 }
66 pub fn exrom(&self) -> &ExRom {
68 &self.exrom
69 }
70 pub fn clear_exrom(&mut self) {
76 self.exrom = Rc::new([]);
77 }
78 pub fn map_exrom<M: ZxMemory>(&self, memory: &mut M) -> Result<(), ZxMemoryError> {
83 memory.map_exrom(Rc::clone(&self.exrom), 0)
84 }
85 pub fn unmap_exrom<M: ZxMemory>(&self, memory: &mut M) {
87 memory.unmap_exrom(&self.exrom)
88 }
89 pub fn is_mapped_exrom<M: ZxMemory>(&self, memory: &M) -> bool {
91 memory.has_mapped_exrom(&self.exrom)
92 }
93}
94
95#[cfg(feature = "snapshot")]
96fn exrom_default() -> ExRom {
97 Rc::new([])
98}