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 serde_yaml::Mapping;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
@ -48,77 +48,65 @@ impl Backplane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_word(&mut self, address: u32) -> Result<u16, BusError> {
|
pub fn read_word(&mut self, address: u32) -> Result<u16, BusError> {
|
||||||
match address {
|
self.mem_helper(
|
||||||
(0..=0x00fe_ffff) | (0x0100_0000..=0xFFFF_FFFF) => self
|
address,
|
||||||
.cards
|
|card| card.read_word(address),
|
||||||
.iter_mut()
|
|card| card.read_word_io(address as u8),
|
||||||
.try_find_map(|card| card.read_word(address))
|
0,
|
||||||
.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))
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_byte(&mut self, address: u32) -> Result<u8, BusError> {
|
pub fn read_byte(&mut self, address: u32) -> Result<u8, BusError> {
|
||||||
match address {
|
self.mem_helper(
|
||||||
(0..=0x00fe_ffff) | (0x0100_0000..=0xFFFF_FFFF) => self
|
address,
|
||||||
.cards
|
|card| card.read_byte(address),
|
||||||
.iter_mut()
|
|card| card.read_byte_io(address as u8),
|
||||||
.try_find_map(|card| card.read_byte(address))
|
0,
|
||||||
.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))
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_word(&mut self, address: u32, data: u16) -> Result<(), BusError> {
|
pub fn write_word(&mut self, address: u32, data: u16) -> Result<(), BusError> {
|
||||||
match address {
|
self.mem_helper(
|
||||||
(0..=0x00fe_ffff) | (0x0100_0000..=0xFFFF_FFFF) => self
|
address,
|
||||||
.cards
|
|card| card.write_word(address, data),
|
||||||
.iter_mut()
|
|card| card.write_word_io(address as u8, data),
|
||||||
.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(()))
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_byte(&mut self, address: u32, data: u8) -> Result<(), BusError> {
|
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 {
|
match address {
|
||||||
(0..=0x00fe_ffff) | (0x0100_0000..=0xFFFF_FFFF) => self
|
(0..=0x00fe_ffff) | (0x0100_0000..=0xffff_ffff) => self
|
||||||
.cards
|
.cards
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.try_find_map(|card| card.write_byte(address, data))
|
.try_find_map(&mut mem_func)
|
||||||
.result(BusError),
|
.result(BusError),
|
||||||
(0x00ff_0000..=0x00ff_00ff) => Ok(()),
|
(0x00ff_0000..=0x00ff_00ff) => Ok(io_default),
|
||||||
(0x00ff_0100..=0x00ff_ffff) => self
|
(0x00ff_0100..=0x00ff_ffff) => self
|
||||||
.cards
|
.cards
|
||||||
.get_mut(((address >> 8) as u8 - 1) as usize)
|
.get_mut(((address >> 8) as u8 - 1) as usize)
|
||||||
.map_or(Ok(()), |card| {
|
.map_or(Ok(io_default), |card| {
|
||||||
card.write_byte_io(address as u8, data)
|
io_func(card).optional_result().unwrap_or(Ok(io_default))
|
||||||
.optional_result()
|
|
||||||
.unwrap_or(Ok(()))
|
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user