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
use super::{
    constants::{DEFAULT_PROGRAM_ADDRESS, FONT_SPRITE_SIZE},
    font::FONT_SPRITES,
    Chip8,
};

impl Chip8 {
    fn load_font_sprites(&mut self) {
        for (i, sprite) in FONT_SPRITES.iter().enumerate() {
            self.memory[i * FONT_SPRITE_SIZE..(i + 1) * FONT_SPRITE_SIZE].copy_from_slice(sprite);
        }
    }

    pub fn load_program_to_address(&mut self, program: &[u8], address: usize) -> Result<(), ()> {
        let program_memory_range = address..address + program.len();

        let allowed_program_memory_range = 0x200..self.memory.len();

        if !allowed_program_memory_range.contains(&program_memory_range.start)
            || !allowed_program_memory_range.contains(&program_memory_range.end)
        {
            return Err(());
        }

        self.load_font_sprites();
        self.memory[program_memory_range].copy_from_slice(program);
        self.memory[address + program.len()..].fill(0);
        self.program_counter = address;

        Ok(())
    }

    pub fn load_program(&mut self, program: &[u8]) -> Result<(), ()> {
        self.load_program_to_address(program, DEFAULT_PROGRAM_ADDRESS)
    }
}