use crate::memory::MemoryAccessError;
pub trait BitAccess {
fn bit(&self, index: usize) -> bool;
fn set_bit(&mut self, index: usize, value: bool);
}
impl BitAccess for u32 {
fn bit(&self, index: usize) -> bool {
(self >> index) & 1 != 0
}
fn set_bit(&mut self, index: usize, value: bool) {
*self = (*self & !(1 << index)) | ((value as u32) << index);
}
}
impl BitAccess for u16 {
fn bit(&self, index: usize) -> bool {
(self >> index) & 1 != 0
}
fn set_bit(&mut self, index: usize, value: bool) {
*self = (*self & !(1 << index)) | ((value as u16) << index);
}
}
impl BitAccess for u8 {
fn bit(&self, index: usize) -> bool {
(self >> index) & 1 != 0
}
fn set_bit(&mut self, index: usize, value: bool) {
*self = (*self & !(1 << index)) | ((value as u8) << index);
}
}
#[derive(Clone, Copy)]
pub struct MaskedRegister {
pub value: u32,
pub reserved_mask: u32,
pub write_mask: u32,
pub set_mask: u32,
pub clear_at_one_mask: u32,
}
impl MaskedRegister {
pub fn new(value: u32) -> Self {
Self {
value,
reserved_mask: 0,
write_mask: 0xffffffff,
set_mask: 0,
clear_at_one_mask: 0,
}
}
pub fn reserved(self, mask: u32) -> Self {
Self {
reserved_mask: mask,
..self
}
}
pub fn write_mask_reserved(self, mask: u32) -> Self {
Self {
reserved_mask: !mask,
write_mask: mask,
..self
}
}
pub fn write_mask(self, mask: u32) -> Self {
Self {
write_mask: mask,
..self
}
}
pub fn set_mask(self, mask: u32) -> Self {
Self {
set_mask: mask,
..self
}
}
pub fn clear_at_one(self, mask: u32) -> Self {
Self {
clear_at_one_mask: mask,
..self
}
}
pub fn write(&mut self, value: u32) -> Result<(), MemoryAccessError> {
self.value = ((value & self.write_mask) | (value & self.set_mask))
& !(value & self.clear_at_one_mask);
if value & self.reserved_mask != 0 {
return Err(MemoryAccessError::InvalidValue);
}
Ok(())
}
}