use crate::word::Word; use crate::word::MEM_SIZE; use rand::Rng; pub struct Memory([u8; MEM_SIZE as usize]); impl Default for Memory { fn default() -> Self { Self([0u8; MEM_SIZE as usize]) } } impl From for Memory { fn from(mut rng: R) -> Self { let mut mem = Memory::default(); for i in 0..(MEM_SIZE - 1) { mem.0[i as usize] = rng.gen() } mem } } impl std::ops::Index for Memory { type Output = u8; fn index(&self, index: Word) -> &Self::Output { &self.0[usize::from(index)] } } impl std::ops::IndexMut for Memory { fn index_mut(&mut self, index: Word) -> &mut Self::Output { &mut self.0[usize::from(index)] } } pub trait PeekPoke { /// Read a byte from a given address. fn peek(&self, addr: Word) -> u8; /// Write a byte to a given address. fn poke(&mut self, addr: Word, val: u8); /// Read a slice, starting from a given address. fn peek_slice(&self, addr: Word, buffer: &mut [u8]) { for (i, byte) in buffer.iter_mut().enumerate() { *byte = self.peek(addr + i); } } /// Write a slice, starting at a given address. fn poke_slice(&mut self, addr: Word, buffer: &[u8]) { for (i, byte) in buffer.iter().enumerate() { self.poke(addr + i, *byte); } } } pub trait PeekPokeExt { fn peek8>(&self, addr: A) -> u8; fn poke8, V: Into>(&mut self, addr: A, val: V); fn peek24>(&self, addr: A) -> Word; fn poke24, V: Into>(&mut self, addr: A, val: V); } impl PeekPokeExt for T { fn peek8>(&self, addr: A) -> u8 { self.peek(addr.into()) } fn poke8, V: Into>(&mut self, addr: A, val: V) { self.poke(addr.into(), val.into()); } fn peek24>(&self, addr: A) -> Word { let mut bytes = [0u8; 3]; self.peek_slice(addr.into(), &mut bytes); bytes.into() } fn poke24, V: Into>(&mut self, addr: A, val: V) { let addr = addr.into(); let val = val.into(); self.poke_slice(addr, &val.to_bytes()); } } impl PeekPoke for Memory { fn peek(&self, addr: Word) -> u8 { self[addr] } fn poke(&mut self, addr: Word, val: u8) { self[addr] = val; } } #[cfg(test)] mod tests { use super::*; #[test] fn test_mem_peek_poke() { let mut mem = Memory::default(); assert_eq!(mem.peek24(35), 0); mem.poke24(35, 45); assert_eq!(mem.peek24(35), 45); assert_eq!(mem.peek24(36), 0); } #[test] fn test_mem_word_fns() { let mut mem = Memory::default(); mem.poke24(10, 0x123456); assert_eq!(mem.peek8(10), 0x56); assert_eq!(mem.peek8(11), 0x34); assert_eq!(mem.peek8(12), 0x12); assert_eq!(mem.peek24(10), 0x123456); assert_eq!(mem.peek24(11), 0x001234); } }