diff --git a/src/backplane.rs b/src/backplane.rs index 4256eca..b23416d 100644 --- a/src/backplane.rs +++ b/src/backplane.rs @@ -152,6 +152,7 @@ impl Backplane { address, |address, mut card| card.read_word(address), |address, mut card| card.read_word_io(address as u8), + |address| self.read_word_io(address as u8), false, false, ) @@ -162,6 +163,7 @@ impl Backplane { address, |address, mut card| card.read_byte(address), |address, mut card| card.read_byte_io(address as u8), + |address| self.read_byte_io(address as u8), false, false, ) @@ -172,6 +174,7 @@ impl Backplane { address, |address, mut card| card.write_word(address, data), |address, mut card| card.write_word_io(address as u8, data), + |address| self.write_word_io(address as u8, data), false, true, ) @@ -182,6 +185,7 @@ impl Backplane { address, |address, mut card| card.write_byte(address, data), |address, mut card| card.write_byte_io(address as u8, data), + |address| self.write_byte_io(address as u8, data), false, true, ) @@ -192,6 +196,7 @@ impl Backplane { address, |address, mut card| card.read_word(address), |address, mut card| card.read_word_io(address as u8), + |address| self.read_word_io(address as u8), true, false, ) @@ -203,6 +208,7 @@ impl Backplane { address, |address, mut card| card.read_byte(address), |address, mut card| card.read_byte_io(address as u8), + |address| self.read_byte_io(address as u8), true, false, ) @@ -214,6 +220,7 @@ impl Backplane { address, |address, mut card| card.write_word(address, data), |address, mut card| card.write_word_io(address as u8, data), + |address| self.write_word_io(address as u8, data), true, true, ) @@ -225,22 +232,25 @@ impl Backplane { address, |address, mut card| card.write_byte(address, data), |address, mut card| card.write_byte_io(address as u8, data), + |address| self.write_byte_io(address as u8, data), true, true, ) } - fn mem_helper( + fn mem_helper( &self, address: u32, mut mem_func: M, mut io_func: I, + mut backplane_io_func: B, bypass_mmu: bool, write: bool, ) -> Result where M: FnMut(u32, RefMut<'_, dyn Card>) -> NullableResult, I: FnMut(u32, RefMut<'_, dyn Card>) -> NullableResult, + B: FnMut(u32) -> NullableResult, { let address = if bypass_mmu { address @@ -259,13 +269,15 @@ impl Backplane { address }; let res = match address { - (0..=0x00fe_ffff) | (0x0100_0000..=0xffff_ffff) => self + (0..=0x00fe_ffff) | (0x0100_0000..=0xfffe_ffff) => self .cards .iter() .try_find_map(|card| mem_func(address, card.borrow_mut())) .result(BusError), - (0x00ff_0000..=0x00ff_00ff) => Ok(T::default()), - (0x00ff_0100..=0x00ff_ffff) => self + (0x00ff_0000..=0x00ff_00ff) | (0xffff_0000..=0xffff_00ff) => backplane_io_func(address) + .optional_result() + .unwrap_or(Ok(T::default())), + (0x00ff_0100..=0x00ff_ffff) | (0xffff_0100..=0xffff_ffff) => self .cards .get(((address >> 8) as u8 - 1) as usize) .map_or(Ok(T::default()), |card| { @@ -290,4 +302,26 @@ impl Backplane { self.in_dma.set(false); } } + + fn read_byte_io(&self, _address: u8) -> NullableResult { + NullableResult::Null + } + + fn write_byte_io(&self, _address: u8, _data: u8) -> NullableResult<(), BusError> { + NullableResult::Ok(()) + } + + fn read_word_io(&self, address: u8) -> NullableResult { + assert!((address & 0x1) == 0); + let upper_byte = self.read_byte_io(address)?; + let lower_byte = self.read_byte_io(address + 1)?; + NullableResult::Ok((u16::from(upper_byte) << 8) | u16::from(lower_byte)) + } + + fn write_word_io(&self, address: u8, data: u16) -> NullableResult<(), BusError> { + assert!((address & 0x1) == 0); + self.write_byte_io(address, (data >> 8) as u8)?; + self.write_byte_io(address + 1, data as u8)?; + NullableResult::Ok(()) + } }