use std::fs::{self};
use std::io::{Error, ErrorKind};
pub trait CPUMemory {
fn read(&self, address: u16) -> u8;
fn write(&mut self, address: u16, data: u8);
}
pub struct BasicCPUMemory {
buffer: Vec<u8>
}
impl BasicCPUMemory {
pub fn from_file(path: &String, offset: u16) -> Result<Self, std::io::Error> {
match fs::read(path) {
Ok(mut buffer) => {
if buffer.len() > (65536 - offset as usize) {
Err(Error::new(ErrorKind::Other, "File is too large to be loaded into 64KB buffer with current offset."))
} else {
let mut memory: Vec<u8> = vec![0; 65536];
let start = offset;
for i in 0..buffer.len() {
memory[i + start as usize] = memory[i];
}
buffer.resize(65536, 0);
Ok(BasicCPUMemory {
buffer: memory
})
}
},
Err(err) => {
Err(err)
}
}
}
}
impl Default for BasicCPUMemory {
fn default() -> Self {
BasicCPUMemory { buffer: vec![0; 65536] }
}
}
impl TryFrom<Vec<u8>> for BasicCPUMemory {
type Error = ();
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
if value.len() > 65536 {
Err(())
} else {
let mut buffer: Vec<u8> = vec![0; 65536];
for (index, ele) in value.iter().enumerate() {
buffer[index] = *ele;
}
Ok(BasicCPUMemory { buffer })
}
}
}
impl CPUMemory for BasicCPUMemory {
fn read(&self, address: u16) -> u8 {
self.buffer[address as usize]
}
fn write(&mut self, address: u16, data: u8) {
self.buffer[address as usize] = data;
}
}