summaryrefslogtreecommitdiff
path: root/src/memory.rs
blob: 755c4bc7b33e042b254c2d2f54a19530b4c594c4 (plain) (blame)
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
pub struct Memory {
    pub mem: [u8; 65536],
    pub pc: u16,
}

impl Memory {
    pub fn new() -> Self {
        Self {
            mem: [0; 65536],
            pc: 0,
        }
    }

    pub fn load_program(&mut self, bytecode: &[u8]) {
        self.mem[..bytecode.len()].copy_from_slice(bytecode)
    }

    pub fn read_u8(&self, addr: u16) -> u8 {
        self.mem[addr as usize]
    }

    pub fn write_u8(&mut self, val: u8, addr: u16) {
        self.mem[addr as usize] = val;
    }

    pub fn read_u8_next(&mut self) -> u8 {
        let byte = self.mem[self.pc as usize];
        self.pc = self.pc.wrapping_add(1);
        byte
    }

    pub fn read_u16(&self, addr: u16) -> u16 {
        let byte_high = self.read_u8(addr);
        let byte_low = self.read_u8(addr.wrapping_add(1));
        u16::from_be_bytes([byte_high, byte_low])
    }

    pub fn write_u16(&mut self, val: u16, addr: u16) {
        let [byte_high, byte_low] = val.to_be_bytes();
        self.write_u8(byte_high, addr);
        self.write_u8(byte_low, addr.wrapping_add(1));
    }

    pub fn read_u16_next(&mut self) -> u16 {
        let byte_high = self.read_u8_next();
        let byte_low = self.read_u8_next();
        u16::from_be_bytes([byte_high, byte_low])
    }

    pub fn read_pc(&self) -> u16 {
        self.pc
    }

    pub fn write_pc(&mut self, val: u16) {
        self.pc = val;
    }

    pub fn reset(&mut self) {
        self.mem.fill(0);
        self.pc = 0;
    }
}