1use std::fs::{self};
2use std::io::{Error, ErrorKind};
3
4pub trait CPUMemory {
8 fn read(&self, address: u16) -> u8;
10 fn write(&mut self, address: u16, data: u8);
12}
13
14pub struct BasicCPUMemory {
16 buffer: Vec<u8>
17}
18
19impl BasicCPUMemory {
20 pub fn from_file(path: &String, offset: u16) -> Result<Self, std::io::Error> {
24 match fs::read(path) {
25 Ok(mut buffer) => {
26 if buffer.len() > (65536 - offset as usize) {
27 Err(Error::new(ErrorKind::Other, "File is too large to be loaded into 64KB buffer with current offset."))
28 } else {
29 let mut memory: Vec<u8> = vec![0; 65536];
30 let start = offset;
31 for i in 0..buffer.len() {
32 memory[i + start as usize] = memory[i];
33 }
34 buffer.resize(65536, 0);
35 Ok(BasicCPUMemory {
36 buffer: memory
37 })
38 }
39 },
40 Err(err) => {
41 Err(err)
42 }
43 }
44
45 }
46}
47impl Default for BasicCPUMemory {
48 fn default() -> Self {
49 BasicCPUMemory { buffer: vec![0; 65536] }
50 }
51}
52
53
54impl TryFrom<Vec<u8>> for BasicCPUMemory {
55 type Error = ();
56
57 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
61 if value.len() > 65536 {
62 Err(())
63 } else {
64 let mut buffer: Vec<u8> = vec![0; 65536];
65 for (index, ele) in value.iter().enumerate() {
66 buffer[index] = *ele;
67 }
68 Ok(BasicCPUMemory { buffer })
69 }
70 }
71}
72
73impl CPUMemory for BasicCPUMemory {
74 fn read(&self, address: u16) -> u8 {
75 self.buffer[address as usize]
76 }
77
78 fn write(&mut self, address: u16, data: u8) {
79 self.buffer[address as usize] = data;
80 }
81}