pub struct Memory {
data: Vec<u64>
}
impl Memory {
pub fn new() -> Self {
Memory {
data: vec![]
}
}
pub fn init(&mut self, capacity: u64) {
for _i in 0..((capacity + 7) / 8) {
self.data.push(0);
}
}
pub fn read_byte(&self, address: u64) -> u8 {
let index = (address >> 3) as usize;
let pos = ((address % 8) as u64) * 8;
(self.data[index] >> pos) as u8
}
pub fn read_halfword(&self, address: u64) -> u16 {
if (address % 2) == 0 {
let index = (address >> 3) as usize;
let pos = ((address % 8) as u64) * 8;
(self.data[index] >> pos) as u16
} else {
self.read_bytes(address, 2) as u16
}
}
pub fn read_word(&self, address: u64) -> u32 {
if (address % 4) == 0 {
let index = (address >> 3) as usize;
let pos = ((address % 8) as u64) * 8;
(self.data[index] >> pos) as u32
} else {
self.read_bytes(address, 4) as u32
}
}
pub fn read_doubleword(&self, address: u64) -> u64 {
if (address % 8) == 0 {
let index = (address >> 3) as usize;
self.data[index]
} else if (address % 4) == 0 {
(self.read_word(address) as u64) | ((self.read_word(address.wrapping_add(4)) as u64) << 4)
} else {
self.read_bytes(address, 8)
}
}
pub fn read_bytes(&self, address: u64, width: u64) -> u64 {
let mut data = 0 as u64;
for i in 0..width {
data |= (self.read_byte(address.wrapping_add(i)) as u64) << (i * 8);
}
data
}
pub fn write_byte(&mut self, address: u64, value: u8) {
let index = (address >> 3) as usize;
let pos = ((address % 8) as u64) * 8;
self.data[index] = (self.data[index] & !(0xff << pos)) | ((value as u64) << pos);
}
pub fn write_halfword(&mut self, address: u64, value: u16) {
if (address % 2) == 0 {
let index = (address >> 3) as usize;
let pos = ((address % 8) as u64) * 8;
self.data[index] = (self.data[index] & !(0xffff << pos)) | ((value as u64) << pos);
} else {
self.write_bytes(address, value as u64, 2);
}
}
pub fn write_word(&mut self, address: u64, value: u32) {
if (address % 4) == 0 {
let index = (address >> 3) as usize;
let pos = ((address % 8) as u64) * 8;
self.data[index] = (self.data[index] & !(0xffffffff << pos)) | ((value as u64) << pos);
} else {
self.write_bytes(address, value as u64, 4);
}
}
pub fn write_doubleword(&mut self, address: u64, value: u64) {
if (address % 8) == 0 {
let index = (address >> 3) as usize;
self.data[index] = value;
} else if (address % 4) == 0 {
self.write_word(address, (value & 0xffffffff) as u32);
self.write_word(address.wrapping_add(4), (value >> 32) as u32);
} else {
self.write_bytes(address, value, 8);
}
}
pub fn write_bytes(&mut self, address: u64, value: u64, width: u64) {
for i in 0..width {
self.write_byte(address.wrapping_add(i), (value >> (i * 8)) as u8);
}
}
pub fn validate_address(&self, address: u64) -> bool {
return (address as usize) < self.data.len()
}
}