actually no NOW the memory interface is "done"
This commit is contained in:
136
src/mem.rs
136
src/mem.rs
@@ -19,10 +19,11 @@ pub struct MemConfig {
|
||||
}
|
||||
|
||||
impl MemConfig {
|
||||
pub fn find_device_by_page(&self, page: PageNum) -> Option<Arc<dyn MemDeviceInterface>> {
|
||||
#[allow(clippy::needless_borrow)]
|
||||
pub fn find_device_by_page(&self, page: PageNum) -> Option<&DeviceEntry> {
|
||||
for entry in self.devices.iter() {
|
||||
if page_in_range(page, entry.base, entry.size) {
|
||||
return Some(entry.interface.clone());
|
||||
return Some(&entry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,11 +32,134 @@ impl MemConfig {
|
||||
|
||||
pub fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, MemAccessFault> {
|
||||
if page_in_range(page, self.ram_start, self.ram.pages) {
|
||||
self.ram.read_dword(page, offset)
|
||||
self.ram.read_dword(page - self.ram_start, offset)
|
||||
} else {
|
||||
self.find_device_by_page(page)
|
||||
.ok_or(MemAccessFault)?
|
||||
.read_dword(page, offset)
|
||||
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||
|
||||
entry.interface.read_dword(page - entry.base, offset)
|
||||
}
|
||||
}
|
||||
pub fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, MemAccessFault> {
|
||||
if page_in_range(page, self.ram_start, self.ram.pages) {
|
||||
self.ram.read_word(page - self.ram_start, offset)
|
||||
} else {
|
||||
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||
|
||||
entry.interface.read_word(page - entry.base, offset)
|
||||
}
|
||||
}
|
||||
pub fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, MemAccessFault> {
|
||||
if page_in_range(page, self.ram_start, self.ram.pages) {
|
||||
self.ram.read_hword(page - self.ram_start, offset)
|
||||
} else {
|
||||
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||
|
||||
entry.interface.read_hword(page - entry.base, offset)
|
||||
}
|
||||
}
|
||||
pub fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, MemAccessFault> {
|
||||
if page_in_range(page, self.ram_start, self.ram.pages) {
|
||||
self.ram.read_byte(page - self.ram_start, offset)
|
||||
} else {
|
||||
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||
|
||||
entry.interface.read_byte(page - entry.base, offset)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_dword(
|
||||
&self,
|
||||
page: PageNum,
|
||||
offset: u16,
|
||||
value: DWord,
|
||||
) -> Result<(), MemAccessFault> {
|
||||
if page_in_range(page, self.ram_start, self.ram.pages) {
|
||||
self.ram.write_dword(page - self.ram_start, offset, value)
|
||||
} else {
|
||||
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||
entry
|
||||
.interface
|
||||
.write_dword(page - entry.base, offset, value)
|
||||
}
|
||||
}
|
||||
pub fn write_word(
|
||||
&self,
|
||||
page: PageNum,
|
||||
offset: u16,
|
||||
value: Word,
|
||||
) -> Result<(), MemAccessFault> {
|
||||
if page_in_range(page, self.ram_start, self.ram.pages) {
|
||||
self.ram.write_word(page - self.ram_start, offset, value)
|
||||
} else {
|
||||
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||
entry.interface.write_word(page - entry.base, offset, value)
|
||||
}
|
||||
}
|
||||
pub fn write_hword(
|
||||
&self,
|
||||
page: PageNum,
|
||||
offset: u16,
|
||||
value: HWord,
|
||||
) -> Result<(), MemAccessFault> {
|
||||
if page_in_range(page, self.ram_start, self.ram.pages) {
|
||||
self.ram.write_hword(page - self.ram_start, offset, value)
|
||||
} else {
|
||||
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||
entry
|
||||
.interface
|
||||
.write_hword(page - entry.base, offset, value)
|
||||
}
|
||||
}
|
||||
pub fn write_byte(
|
||||
&self,
|
||||
page: PageNum,
|
||||
offset: u16,
|
||||
value: Byte,
|
||||
) -> Result<(), MemAccessFault> {
|
||||
if page_in_range(page, self.ram_start, self.ram.pages) {
|
||||
self.ram.write_byte(page - self.ram_start, offset, value)
|
||||
} else {
|
||||
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||
entry.interface.write_byte(page - entry.base, offset, value)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_atomic_dword(
|
||||
&self,
|
||||
page: PageNum,
|
||||
offset: u16,
|
||||
) -> Result<&AtomicU64, MemAccessFault> {
|
||||
if page_in_range(page, self.ram_start, self.ram.pages) {
|
||||
debug_assert!(((offset * 8) as usize) < PAGE_SIZE);
|
||||
let index = page * (PAGE_SIZE / 8) + (offset as usize);
|
||||
unsafe {
|
||||
self.ram
|
||||
.buf_transmuted::<AtomicU64>()
|
||||
.get(index)
|
||||
.ok_or(MemAccessFault)
|
||||
}
|
||||
} else {
|
||||
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||
entry.interface.get_atomic_dword(page - entry.base, offset)
|
||||
}
|
||||
}
|
||||
pub fn get_atomic_word(
|
||||
&self,
|
||||
page: PageNum,
|
||||
offset: u16,
|
||||
) -> Result<&AtomicU32, MemAccessFault> {
|
||||
if page_in_range(page, self.ram_start, self.ram.pages) {
|
||||
debug_assert!(((offset * 4) as usize) < PAGE_SIZE);
|
||||
let index = page * (PAGE_SIZE / 4) + (offset as usize);
|
||||
unsafe {
|
||||
self.ram
|
||||
.buf_transmuted::<AtomicU32>()
|
||||
.get(index)
|
||||
.ok_or(MemAccessFault)
|
||||
}
|
||||
} else {
|
||||
let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
|
||||
entry.interface.get_atomic_word(page - entry.base, offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user