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