mem-storage is an abstraction over a chunk of memory, that is readable and writable. It can be used in in everything, that requires some sort of memory, e.g. the RAM in an emulator. This crate can also be used in no_std environment.
Every time I write an emulator, I don't like to make
a struct Memory
over and over again and always copy paste methods like
read_u8
, read_u16
, etc. So I came up with a generic solution for this problem.
```compilefail use memstorage::Memory;
let mem = MyMemory::new();
/// The read
and write
method will read / write data using little endian format.
/// For big endian format use read_be
and write_be
.
mem.write(0xABCD, 123);
let value = mem.read::
mem.write(0x1000, 12345u64);
let value = mem.read::
mem.write_be(0x2000, 1234567u64);
let value = mem.readbe::
``` use mem_storage::Memory;
/// This time your struct is responsible for storing the data.
struct MyMemory {
ram: Vec
impl MyMemory { fn new() -> Self { // Create 1KiB of zero initialized memory Self { ram: vec![0u8; 1024 * 1024] } } }
impl Memory for MyMemory {
/// If an Err
is returned, the addr is out of bounds
type Error = ();
fn get(&self, index: I) -> Result<&I::Output, Self::Error> where I: std::slice::SliceIndex<[u8]>, { self.ram.get(index).ok_or(()) }
fn getmut(&mut self, index: I) -> Result<&mut I::Output, Self::Error> where I: std::slice::SliceIndex<[u8]>, { self.ram.getmut(index).ok_or(()) }
fn tryreadbyte(&self, addr: usize) -> Result
fn trywritebyte(&mut self, addr: usize, value: u8) -> Result<(), Self::Error> { let mut value = self.ram.getmut(addr).okor(())?; *value = *value; Ok(()) }
// The trait will provide a generic read
and read_be
method for you.
}
```
This project is double-licensed under the Zlib or Apache2.0 license.