mirror of https://git.sr.ht/~asya/copycat
76 lines
1.9 KiB
Rust
76 lines
1.9 KiB
Rust
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
use std::alloc::{alloc, dealloc, Layout};
|
|
|
|
mod consts {
|
|
#![allow(non_upper_case_globals)]
|
|
pub const KiB: u64 = 1024;
|
|
pub const MiB: u64 = 1024 * KiB;
|
|
}
|
|
|
|
pub use consts::*;
|
|
|
|
pub struct Memory {
|
|
memory: *mut u8,
|
|
memory_size: u64,
|
|
}
|
|
|
|
impl Memory {
|
|
pub fn new(size: u64) -> Self {
|
|
Self {
|
|
memory: unsafe {
|
|
alloc(Layout::from_size_align(size.try_into().unwrap(), 1 * MiB as usize).expect("layout error"))
|
|
},
|
|
memory_size: size,
|
|
}
|
|
}
|
|
|
|
pub fn read<const N: usize>(&self, address: u64) -> [u8; N] {
|
|
if address >= self.memory_size {
|
|
return [0; N];
|
|
}
|
|
|
|
unsafe {
|
|
self.memory.offset(address.try_into().unwrap()).cast::<[u8; N]>().read_unaligned()
|
|
}
|
|
}
|
|
|
|
pub fn write<const N: usize>(&mut self, address: u64, value: [u8; N]) {
|
|
if address >= self.memory_size {
|
|
return;
|
|
}
|
|
|
|
unsafe {
|
|
self.memory.offset(address.try_into().unwrap()).cast::<[u8; N]>().write_unaligned(value);
|
|
}
|
|
}
|
|
|
|
pub fn read_u8(&self, address: u64) -> u8 {
|
|
self.read::<1>(address)[0]
|
|
}
|
|
|
|
pub fn write_u8(&mut self, address: u64, value: u8) {
|
|
self.write::<1>(address, [value]);
|
|
}
|
|
|
|
pub fn read_u16(&self, address: u64) -> u16 {
|
|
u16::from_le_bytes(self.read::<2>(address))
|
|
}
|
|
|
|
pub fn write_u16(&mut self, address: u64, value: u16) {
|
|
self.write::<2>(address, value.to_le_bytes());
|
|
}
|
|
}
|
|
|
|
impl Drop for Memory {
|
|
fn drop(&mut self) {
|
|
unsafe {
|
|
dealloc(self.memory, Layout::from_size_align(self.memory_size.try_into().unwrap(), 1 * MiB as usize).expect("layout error"));
|
|
}
|
|
}
|
|
}
|