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::marker::PhantomData;
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use anyhow::anyhow;
use itertools::Itertools;
@ -67,6 +68,7 @@ pub struct Backplane {
cards: Vec<Rc<RefCell<dyn Card>>>,
mmu: Option<usize>,
in_dma: Cell<bool>,
io_at_top_16mb: AtomicBool,
}
impl Display for Backplane {
@ -130,6 +132,7 @@ impl Backplane {
cards,
mmu,
in_dma: Cell::new(false),
io_at_top_16mb: AtomicBool::new(true),
})
}
@ -274,17 +277,35 @@ impl Backplane {
.iter()
.try_find_map(|card| mem_func(address, card.borrow_mut()))
.result(BusError),
(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| {
io_func(address, card.borrow_mut())
(0x00ff_0000..=0x00ff_00ff) | (0xffff_0000..=0xffff_00ff) => {
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 {
backplane_io_func(address)
.optional_result()
.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?;
self.handle_dma();
@ -303,11 +324,22 @@ impl Backplane {
}
}
fn read_byte_io(&self, _address: u8) -> NullableResult<u8, BusError> {
NullableResult::Null
fn read_byte_io(&self, address: u8) -> NullableResult<u8, BusError> {
#[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(())
}