From 701448be2c3c58e30960d46f090bf08adfc02832 Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Thu, 3 Jul 2025 14:53:16 +1200 Subject: Initial commit --- src/components/program_memory.rs | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/components/program_memory.rs (limited to 'src/components/program_memory.rs') diff --git a/src/components/program_memory.rs b/src/components/program_memory.rs new file mode 100644 index 0000000..8770556 --- /dev/null +++ b/src/components/program_memory.rs @@ -0,0 +1,66 @@ +use crate::*; + + +pub struct ProgramMemory { + pub mem: [u8; 65536], + pub pc: u16, +} + +impl ProgramMemory { + pub fn new() -> Self { + Self { + mem: [0; 65536], + pc: 0, + } + } + + /// Load a program into memory, resetting the program counter. + pub fn load_program(&mut self, bytecode: &[u8]) { + let length = std::cmp::min(bytecode.len(), 65536); + self.mem[..length].copy_from_slice(&bytecode[..length]); + self.mem[length..65536].fill(0); + self.pc = 0; + } + + pub fn metadata(&self) -> Option { + Metadata::from(self.mem.as_slice()) + } + + /// Read a u8 from a memory address. + pub fn read_u8(&self, addr: u16) -> u8 { + self.mem[addr as usize] + } + + /// Write a u8 to a memory address. + pub fn write_u8(&mut self, val: u8, addr: u16) { + self.mem[addr as usize] = val; + } + + /// Read a u8 using the program counter. + pub fn read_u8_next(&mut self) -> u8 { + let byte = self.mem[self.pc as usize]; + self.pc = self.pc.wrapping_add(1); + byte + } + + /// Read a u16 from a memory address. + 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]) + } + + /// Write a u16 to a memory address. + 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)); + } + + /// Read a u8 using the program counter. + 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]) + } +} -- cgit v1.2.3-70-g09d2