use std::collections::BTreeMap;
use crate::emulator::{Error, Memory};
use crate::soc::Width;
#[derive(Debug, Default)]
pub(crate) struct Laid(pub(crate) BTreeMap<u64, u8>);
impl Laid {
pub(crate) fn bytes(&mut self, address: u64, bytes: &[u8]) {
for (at, &byte) in (address..).zip(bytes) {
self.0.insert(at, byte);
}
}
pub(crate) fn word(&mut self, address: u64, value: u32) {
self.bytes(address, &value.to_le_bytes());
}
pub(crate) fn read(&self, address: u64, width: Width) -> Option<u64> {
(0..u64::from(width.bytes()))
.rev()
.try_fold(0, |value, offset| {
Some(value << 8 | u64::from(*self.0.get(&(address + offset))?))
})
}
}
impl Memory for Laid {
fn read(&mut self, address: u64, width: Width) -> Result<u64, Error> {
Laid::read(self, address, width).ok_or(Error::Memory { address, width })
}
fn write(&mut self, address: u64, width: Width, value: u64) -> Result<(), Error> {
let bytes = value.to_le_bytes();
self.bytes(address, &bytes[..width.bytes() as usize]);
Ok(())
}
}