eeric_core/rv_core/
memory.rs

1use std::collections::VecDeque;
2
3use super::snapshot::Snapshotable;
4
5#[derive(Clone, PartialEq, Debug)]
6pub struct Memory {
7    raw: VecDeque<u8>,
8    data_ptr: usize,
9}
10
11impl Snapshotable for Memory {
12    type Snapshot = VecDeque<u8>;
13
14    fn snapshot(&self) -> Self::Snapshot {
15        self.raw.clone()
16    }
17}
18
19impl Memory {
20    pub fn new(raw: impl ExactSizeIterator<Item = u8>) -> Self {
21        Self {
22            raw: VecDeque::from_iter(raw),
23            data_ptr: 0,
24        }
25    }
26
27    pub fn get<const BYTES: usize>(&self, address: usize) -> [u8; BYTES] {
28        let mut bytes = [0; BYTES];
29
30        bytes[..BYTES].copy_from_slice(&self.raw.as_slices().0[address..(BYTES + address)]);
31
32        bytes
33    }
34
35    pub fn fallible_get<const BYTES: usize>(&self, address: usize) -> Option<[u8; BYTES]> {
36        let mut bytes = [0; BYTES];
37
38        for (offset, byte_element) in bytes.iter_mut().enumerate().take(BYTES) {
39            let Some(byte) = self.raw.get(address + offset).cloned() else {
40                return None;
41            };
42
43            *byte_element = byte;
44        }
45
46        Some(bytes)
47    }
48
49    pub fn set<const BYTES: usize>(&mut self, address: usize, value: [u8; BYTES]) {
50        self.raw.as_mut_slices().0[address..(BYTES + address)].copy_from_slice(&value[..BYTES]);
51    }
52
53    pub fn len(&self) -> usize {
54        self.raw.len()
55    }
56
57    pub fn assign(&mut self, data: &[u8]) {
58        self.raw.as_mut_slices().0[self.data_ptr..self.data_ptr + data.len()].copy_from_slice(data);
59        self.data_ptr += data.len();
60    }
61}
62
63impl Default for Memory {
64    fn default() -> Self {
65        Self::new(vec![0; 0x1000].into_iter())
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn assign_works() {
75        let mut mem = Memory::new(vec![0; 0x10].into_iter());
76
77        assert_eq!(mem.data_ptr, 0);
78
79        mem.assign(&[1, 2]);
80
81        assert_eq!(mem.data_ptr, 2);
82        assert_eq!(mem.raw, &[1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
83
84        mem.assign(&[5, 10, 15]);
85
86        assert_eq!(mem.data_ptr, 5);
87        assert_eq!(mem.raw, &[1, 2, 5, 10, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
88    }
89}