Add support for disabling IO space in lower 16MB of memory

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

View File

@ -3,6 +3,7 @@ use std::cell::{Cell, RefCell, RefMut};
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::rc::Rc; use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use anyhow::anyhow; use anyhow::anyhow;
use itertools::Itertools; use itertools::Itertools;
@ -67,6 +68,7 @@ pub struct Backplane {
cards: Vec<Rc<RefCell<dyn Card>>>, cards: Vec<Rc<RefCell<dyn Card>>>,
mmu: Option<usize>, mmu: Option<usize>,
in_dma: Cell<bool>, in_dma: Cell<bool>,
io_at_top_16mb: AtomicBool,
} }
impl Display for Backplane { impl Display for Backplane {
@ -130,6 +132,7 @@ impl Backplane {
cards, cards,
mmu, mmu,
in_dma: Cell::new(false), in_dma: Cell::new(false),
io_at_top_16mb: AtomicBool::new(true),
}) })
} }
@ -274,17 +277,35 @@ impl Backplane {
.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) | (0xffff_0000..=0xffff_00ff) => backplane_io_func(address) (0x00ff_0000..=0x00ff_00ff) | (0xffff_0000..=0xffff_00ff) => {
.optional_result() if address < 0x0100_0000 && !self.io_at_top_16mb.load(Ordering::Relaxed) {
.unwrap_or(Ok(T::default())), self.cards
(0x00ff_0100..=0x00ff_ffff) | (0xffff_0100..=0xffff_ffff) => self .iter()
.cards .try_find_map(|card| mem_func(address, card.borrow_mut()))
.get(((address >> 8) as u8 - 1) as usize) .result(BusError)
.map_or(Ok(T::default()), |card| { } else {
io_func(address, card.borrow_mut()) backplane_io_func(address)
.optional_result() .optional_result()
.unwrap_or(Ok(T::default())) .unwrap_or(Ok(T::default()))
}), }
}
(0x00ff_0100..=0x00ff_ffff) | (0xffff_0100..=0xffff_ffff) => {
if address < 0x0100_0000 && !self.io_at_top_16mb.load(Ordering::Relaxed) {
self.cards
.iter()
.try_find_map(|card| mem_func(address, card.borrow_mut()))
.result(BusError)
} else {
self.cards.get(((address >> 8) as u8 - 1) as usize).map_or(
Ok(T::default()),
|card| {
io_func(address, card.borrow_mut())
.optional_result()
.unwrap_or(Ok(T::default()))
},
)
}
}
}; };
let val = res?; let val = res?;
self.handle_dma(); self.handle_dma();
@ -303,11 +324,22 @@ impl Backplane {
} }
} }
fn read_byte_io(&self, _address: u8) -> NullableResult<u8, BusError> { fn read_byte_io(&self, address: u8) -> NullableResult<u8, BusError> {
NullableResult::Null #[allow(clippy::single_match)]
match address {
0x1 => NullableResult::Ok(self.io_at_top_16mb.load(Ordering::Relaxed) as u8),
_ => NullableResult::Ok(0),
}
} }
fn write_byte_io(&self, _address: u8, _data: u8) -> NullableResult<(), BusError> { fn write_byte_io(&self, address: u8, data: u8) -> NullableResult<(), BusError> {
#[allow(clippy::single_match)]
match address {
0x1 => self
.io_at_top_16mb
.store((data & 0x1) > 0, Ordering::Relaxed),
_ => (),
}
NullableResult::Ok(()) NullableResult::Ok(())
} }