Add support for backplane IO space

This commit is contained in:
pjht 2023-03-23 11:32:48 -05:00
parent cdb0f1d8d7
commit 0abd42021f
Signed by: pjht
GPG Key ID: 7B5F6AFBEC7EE78E

View File

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