Factor out common parts of backplane memory code
This commit is contained in:
parent
41af1a55d9
commit
ec7db304b8
100
src/backplane.rs
100
src/backplane.rs
@ -1,4 +1,4 @@
|
||||
use nullable_result::GeneralIterExt;
|
||||
use nullable_result::{GeneralIterExt, NullableResult};
|
||||
use serde_yaml::Mapping;
|
||||
use thiserror::Error;
|
||||
|
||||
@ -48,77 +48,65 @@ impl Backplane {
|
||||
}
|
||||
|
||||
pub fn read_word(&mut self, address: u32) -> Result<u16, BusError> {
|
||||
match address {
|
||||
(0..=0x00fe_ffff) | (0x0100_0000..=0xFFFF_FFFF) => self
|
||||
.cards
|
||||
.iter_mut()
|
||||
.try_find_map(|card| card.read_word(address))
|
||||
.result(BusError),
|
||||
(0x00ff_0000..=0x00ff_00ff) => Ok(0),
|
||||
(0x00ff_0100..=0x00ff_ffff) => self
|
||||
.cards
|
||||
.get_mut(((address >> 8) as u8 - 1) as usize)
|
||||
.map_or(Ok(0), |card| {
|
||||
card.read_word_io(address as u8)
|
||||
.optional_result()
|
||||
.unwrap_or(Ok(0))
|
||||
}),
|
||||
}
|
||||
self.mem_helper(
|
||||
address,
|
||||
|card| card.read_word(address),
|
||||
|card| card.read_word_io(address as u8),
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn read_byte(&mut self, address: u32) -> Result<u8, BusError> {
|
||||
match address {
|
||||
(0..=0x00fe_ffff) | (0x0100_0000..=0xFFFF_FFFF) => self
|
||||
.cards
|
||||
.iter_mut()
|
||||
.try_find_map(|card| card.read_byte(address))
|
||||
.result(BusError),
|
||||
(0x00ff_0000..=0x00ff_00ff) => Ok(0),
|
||||
(0x00ff_0100..=0x00ff_ffff) => self
|
||||
.cards
|
||||
.get_mut(((address >> 8) as u8 - 1) as usize)
|
||||
.map_or(Ok(0), |card| {
|
||||
card.read_byte_io(address as u8)
|
||||
.optional_result()
|
||||
.unwrap_or(Ok(0))
|
||||
}),
|
||||
}
|
||||
self.mem_helper(
|
||||
address,
|
||||
|card| card.read_byte(address),
|
||||
|card| card.read_byte_io(address as u8),
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn write_word(&mut self, address: u32, data: u16) -> Result<(), BusError> {
|
||||
match address {
|
||||
(0..=0x00fe_ffff) | (0x0100_0000..=0xFFFF_FFFF) => self
|
||||
.cards
|
||||
.iter_mut()
|
||||
.try_find_map(|card| card.write_word(address, data))
|
||||
.result(BusError),
|
||||
(0x00ff_0000..=0x00ff_00ff) => Ok(()),
|
||||
(0x00ff_0100..=0x00ff_ffff) => self
|
||||
.cards
|
||||
.get_mut(((address >> 8) as u8 - 1) as usize)
|
||||
.map_or(Ok(()), |card| {
|
||||
card.write_word_io(address as u8, data)
|
||||
.optional_result()
|
||||
.unwrap_or(Ok(()))
|
||||
}),
|
||||
}
|
||||
self.mem_helper(
|
||||
address,
|
||||
|card| card.write_word(address, data),
|
||||
|card| card.write_word_io(address as u8, data),
|
||||
(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn write_byte(&mut self, address: u32, data: u8) -> Result<(), BusError> {
|
||||
self.mem_helper(
|
||||
address,
|
||||
|card| card.write_byte(address, data),
|
||||
|card| card.write_byte_io(address as u8, data),
|
||||
(),
|
||||
)
|
||||
}
|
||||
|
||||
fn mem_helper<T, M, I>(
|
||||
&mut self,
|
||||
address: u32,
|
||||
mut mem_func: M,
|
||||
mut io_func: I,
|
||||
io_default: T,
|
||||
) -> Result<T, BusError>
|
||||
where
|
||||
M: FnMut(&mut Box<dyn Card>) -> NullableResult<T, BusError>,
|
||||
I: FnMut(&mut Box<dyn Card>) -> NullableResult<T, BusError>,
|
||||
T: Copy,
|
||||
{
|
||||
match address {
|
||||
(0..=0x00fe_ffff) | (0x0100_0000..=0xFFFF_FFFF) => self
|
||||
(0..=0x00fe_ffff) | (0x0100_0000..=0xffff_ffff) => self
|
||||
.cards
|
||||
.iter_mut()
|
||||
.try_find_map(|card| card.write_byte(address, data))
|
||||
.try_find_map(&mut mem_func)
|
||||
.result(BusError),
|
||||
(0x00ff_0000..=0x00ff_00ff) => Ok(()),
|
||||
(0x00ff_0000..=0x00ff_00ff) => Ok(io_default),
|
||||
(0x00ff_0100..=0x00ff_ffff) => self
|
||||
.cards
|
||||
.get_mut(((address >> 8) as u8 - 1) as usize)
|
||||
.map_or(Ok(()), |card| {
|
||||
card.write_byte_io(address as u8, data)
|
||||
.optional_result()
|
||||
.unwrap_or(Ok(()))
|
||||
.map_or(Ok(io_default), |card| {
|
||||
io_func(card).optional_result().unwrap_or(Ok(io_default))
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user