diff --git a/src/backplane.rs b/src/backplane.rs index 5f1baac..1137c37 100644 --- a/src/backplane.rs +++ b/src/backplane.rs @@ -148,43 +148,51 @@ impl Backplane { } pub fn read_word(&self, address: u32) -> Result { - self.mem_helper( - address, - |mut card| card.read_word(address), - |mut card| card.read_word_io(address as u8), - false, - false, - ) + if let Some(mmu) = self.mmu { + self.cards[mmu] + .borrow_mut() + .try_as_mmu() + .unwrap() + .read_word(address, self) + } else { + self.read_word_phys(address) + } } pub fn read_byte(&self, address: u32) -> Result { - self.mem_helper( - address, - |mut card| card.read_byte(address), - |mut card| card.read_byte_io(address as u8), - false, - false, - ) + if let Some(mmu) = self.mmu { + self.cards[mmu] + .borrow_mut() + .try_as_mmu() + .unwrap() + .read_byte(address, self) + } else { + self.read_byte_phys(address) + } } pub fn write_word(&self, address: u32, data: u16) -> Result<(), BusError> { - self.mem_helper( - address, - |mut card| card.write_word(address, data), - |mut card| card.write_word_io(address as u8, data), - false, - true, - ) + if let Some(mmu) = self.mmu { + self.cards[mmu] + .borrow_mut() + .try_as_mmu() + .unwrap() + .write_word(address, data, self) + } else { + self.write_word_phys(address, data) + } } pub fn write_byte(&self, address: u32, data: u8) -> Result<(), BusError> { - self.mem_helper( - address, - |mut card| card.write_byte(address, data), - |mut card| card.write_byte_io(address as u8, data), - false, - true, - ) + if let Some(mmu) = self.mmu { + self.cards[mmu] + .borrow_mut() + .try_as_mmu() + .unwrap() + .write_byte(address, data, self) + } else { + self.write_byte_phys(address, data) + } } pub fn read_word_phys(&self, address: u32) -> Result { @@ -192,41 +200,30 @@ impl Backplane { address, |mut card| card.read_word(address), |mut card| card.read_word_io(address as u8), - true, - false, ) } - #[allow(dead_code)] pub fn read_byte_phys(&self, address: u32) -> Result { self.mem_helper( address, |mut card| card.read_byte(address), |mut card| card.read_byte_io(address as u8), - true, - false, ) } - #[allow(dead_code)] pub fn write_word_phys(&self, address: u32, data: u16) -> Result<(), BusError> { self.mem_helper( address, |mut card| card.write_word(address, data), |mut card| card.write_word_io(address as u8, data), - true, - true, ) } - #[allow(dead_code)] pub fn write_byte_phys(&self, address: u32, data: u8) -> Result<(), BusError> { self.mem_helper( address, |mut card| card.write_byte(address, data), |mut card| card.write_byte_io(address as u8, data), - true, - true, ) } @@ -235,29 +232,11 @@ impl Backplane { address: u32, mut mem_func: M, mut io_func: I, - bypass_mmu: bool, - write: bool, ) -> Result where M: FnMut(RefMut<'_, dyn Card>) -> NullableResult, I: FnMut(RefMut<'_, dyn Card>) -> NullableResult, { - let address = if bypass_mmu { - address - } else if let Some(card_no) = self.mmu { - match self.cards[card_no] - .borrow_mut() - .try_as_mmu() - .unwrap() - .translate_address(self, address, write) - { - NullableResult::Ok(address) => address, - NullableResult::Err(e) => return Err(e), - NullableResult::Null => return Err(BusError), - } - } else { - address - }; let res = match address { (0..=0x00fe_ffff) | (0x0100_0000..=0xffff_ffff) => self .cards diff --git a/src/card.rs b/src/card.rs index d58b100..cc25027 100644 --- a/src/card.rs +++ b/src/card.rs @@ -141,14 +141,19 @@ pub trait Card: Debug + Display + mopa::Any { mopafy!(Card); pub trait Mmu: Debug { - fn translate_address( - &mut self, - backplane: &Backplane, - address: u32, - write: bool, - ) -> NullableResult; -} + fn read_word(&mut self, address: u32, backplane: &Backplane) -> Result; + fn read_byte(&mut self, address: u32, backplane: &Backplane) -> Result; + fn write_word( + &mut self, + address: u32, + data: u16, + backplane: &Backplane, + ) -> Result<(), BusError>; + + fn write_byte(&mut self, address: u32, data: u8, backplane: &Backplane) + -> Result<(), BusError>; +} #[allow(dead_code)] pub const fn u64_set_be_byte(val: u64, idx: u8, byte: u8) -> u64 { diff --git a/src/mmu.rs b/src/mmu.rs index 1cb4e30..efb7227 100644 --- a/src/mmu.rs +++ b/src/mmu.rs @@ -173,13 +173,13 @@ impl Display for MmuCard { } } -impl Mmu for MmuCard { +impl MmuCard { fn translate_address( &mut self, - backplane: &Backplane, address: u32, + backplane: &Backplane, write: bool, - ) -> NullableResult { + ) -> Result { let print_debug = self.print_debug; if self.enabled { let page = address >> 12; @@ -197,7 +197,7 @@ impl Mmu for MmuCard { if print_debug { println!("No mapping frame for this quarter"); } - return NullableResult::Null; + return Err(BusError); } let map_frame = self.map_frames[(page >> 10) as usize]; let entry_address = (map_frame) | ((page & 0x3FF) << 2); @@ -218,7 +218,7 @@ impl Mmu for MmuCard { if print_debug { println!("Entry not writable"); } - return NullableResult::Err(BusError); + return Err(BusError); } if print_debug { println!( @@ -226,17 +226,49 @@ impl Mmu for MmuCard { (entry.frame << 12) | offset ); } - NullableResult::Ok((entry.frame << 12) | offset) + Ok((entry.frame << 12) | offset) } else { if print_debug { println!("Entry not present"); } - NullableResult::Null + Err(BusError) } } else { - NullableResult::Ok(address) + Ok(address) } } } +impl Mmu for MmuCard { + fn read_word(&mut self, address: u32, backplane: &Backplane) -> Result { + let address = self.translate_address(address, backplane, false)?; + backplane.read_word_phys(address) + } + + fn read_byte(&mut self, address: u32, backplane: &Backplane) -> Result { + let address = self.translate_address(address, backplane, false)?; + backplane.read_byte_phys(address) + } + + fn write_word( + &mut self, + address: u32, + data: u16, + backplane: &Backplane, + ) -> Result<(), BusError> { + let address = self.translate_address(address, backplane, true)?; + backplane.write_word_phys(address, data) + } + + fn write_byte( + &mut self, + address: u32, + data: u8, + backplane: &Backplane, + ) -> Result<(), BusError> { + let address = self.translate_address(address, backplane, true)?; + backplane.write_byte_phys(address, data) + } +} + register!(MmuCard, "mmu");