diff options
| author | taitep <taitep@taitep.se> | 2025-09-27 17:48:56 +0200 |
|---|---|---|
| committer | taitep <taitep@taitep.se> | 2025-09-27 17:48:56 +0200 |
| commit | 5919041f07c1e49b53833a38002f22d8712230de (patch) | |
| tree | 044811adf36df62dd5bfeb23e9e7031d84bdd920 /src | |
| parent | 4a2272ae49942eba487cb51c4d7e8466c2ee0af1 (diff) | |
actually no NOW the memory interface is "done"
Diffstat (limited to 'src')
| -rw-r--r-- | src/mem.rs | 136 |
1 files changed, 130 insertions, 6 deletions
@@ -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) } } } |
