-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmem.rs
65 lines (52 loc) · 1.58 KB
/
mem.rs
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
pub type ReadCallback = fn(addr: u16) -> Option<(u16, u8)>;
pub type WriteCallback = fn(addr: u16, value: u8) -> Option<(u16, u8)>;
pub struct Memory {
bytes: [u8; 64 * 1024],
read_callback: Option<ReadCallback>,
write_callback: Option<WriteCallback>,
}
impl Default for Memory {
fn default() -> Self {
Self::new()
}
}
impl Memory {
pub fn new() -> Memory {
Memory {
bytes: [0; 64 * 1024],
read_callback: None,
write_callback: None,
}
}
pub fn load(&mut self, addr: u16, data: &[u8]) {
let program_end_addr = data.len() + addr as usize;
self.bytes[(addr as usize)..program_end_addr].clone_from_slice(data);
}
pub fn register_read_callback(&mut self, cb: ReadCallback) {
self.read_callback = Some(cb);
}
pub fn register_write_callback(&mut self, cb: WriteCallback) {
self.write_callback = Some(cb);
}
pub fn set(&mut self, addr: u16, value: u8) {
self.bytes[addr as usize] = value;
if let Some(cb) = self.write_callback {
self.process_callback(cb(addr, value));
}
}
fn process_callback(&mut self, result: Option<(u16, u8)>) {
if let Some((addr, value)) = result {
self.bytes[addr as usize] = value;
}
}
pub fn get(&mut self, addr: u16) -> u8 {
let value = self.bytes[addr as usize];
if let Some(cb) = self.read_callback {
self.process_callback(cb(addr));
}
value
}
pub fn bytes(&self) -> &[u8] {
&self.bytes
}
}