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, 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<T: Default, M, I>(
fn mem_helper<T: Default, M, I, B>(
&self,
address: u32,
mut mem_func: M,
mut io_func: I,
mut backplane_io_func: B,
bypass_mmu: bool,
write: bool,
) -> Result<T, BusError>
where
M: 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 {
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<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(())
}
}