Compare commits

...

2 Commits

5 changed files with 109 additions and 95 deletions

View File

@ -123,7 +123,7 @@ impl Backplane {
card: Rc::clone(&cards[interconnect.a_index]),
card_no: interconnect.a_index,
},
)
);
}
Ok(Self {
@ -134,7 +134,7 @@ impl Backplane {
}
pub fn reset(&self) {
for card in self.cards.iter() {
for card in &self.cards {
card.borrow_mut().reset();
}
}
@ -148,43 +148,51 @@ impl Backplane {
}
pub fn read_word(&self, address: u32) -> Result<u16, BusError> {
self.mem_helper(
address,
|mut card| card.read_word(address),
|mut card| card.read_word_io(address as u8),
false,
false,
)
if let Some(mmu) = self.mmu {
self.cards[mmu]
.borrow_mut()
.try_as_mmu()
.unwrap()
.read_word(address, self)
} else {
self.read_word_phys(address)
}
}
pub fn read_byte(&self, address: u32) -> Result<u8, BusError> {
self.mem_helper(
address,
|mut card| card.read_byte(address),
|mut card| card.read_byte_io(address as u8),
false,
false,
)
if let Some(mmu) = self.mmu {
self.cards[mmu]
.borrow_mut()
.try_as_mmu()
.unwrap()
.read_byte(address, self)
} else {
self.read_byte_phys(address)
}
}
pub fn write_word(&self, address: u32, data: u16) -> Result<(), BusError> {
self.mem_helper(
address,
|mut card| card.write_word(address, data),
|mut card| card.write_word_io(address as u8, data),
false,
true,
)
if let Some(mmu) = self.mmu {
self.cards[mmu]
.borrow_mut()
.try_as_mmu()
.unwrap()
.write_word(address, data, self)
} else {
self.write_word_phys(address, data)
}
}
pub fn write_byte(&self, address: u32, data: u8) -> Result<(), BusError> {
self.mem_helper(
address,
|mut card| card.write_byte(address, data),
|mut card| card.write_byte_io(address as u8, data),
false,
true,
)
if let Some(mmu) = self.mmu {
self.cards[mmu]
.borrow_mut()
.try_as_mmu()
.unwrap()
.write_byte(address, data, self)
} else {
self.write_byte_phys(address, data)
}
}
pub fn read_word_phys(&self, address: u32) -> Result<u16, BusError> {
@ -192,41 +200,30 @@ impl Backplane {
address,
|mut card| card.read_word(address),
|mut card| card.read_word_io(address as u8),
true,
false,
)
}
#[allow(dead_code)]
pub fn read_byte_phys(&self, address: u32) -> Result<u8, BusError> {
self.mem_helper(
address,
|mut card| card.read_byte(address),
|mut card| card.read_byte_io(address as u8),
true,
false,
)
}
#[allow(dead_code)]
pub fn write_word_phys(&self, address: u32, data: u16) -> Result<(), BusError> {
self.mem_helper(
address,
|mut card| card.write_word(address, data),
|mut card| card.write_word_io(address as u8, data),
true,
true,
)
}
#[allow(dead_code)]
pub fn write_byte_phys(&self, address: u32, data: u8) -> Result<(), BusError> {
self.mem_helper(
address,
|mut card| card.write_byte(address, data),
|mut card| card.write_byte_io(address as u8, data),
true,
true,
)
}
@ -235,29 +232,11 @@ impl Backplane {
address: u32,
mut mem_func: M,
mut io_func: I,
bypass_mmu: bool,
write: bool,
) -> Result<T, BusError>
where
M: FnMut(RefMut<'_, dyn Card>) -> NullableResult<T, BusError>,
I: FnMut(RefMut<'_, dyn Card>) -> NullableResult<T, BusError>,
{
let address = if bypass_mmu {
address
} else if let Some(card_no) = self.mmu {
match self.cards[card_no]
.borrow_mut()
.try_as_mmu()
.unwrap()
.translate_address(self, address, write)
{
NullableResult::Ok(address) => address,
NullableResult::Err(e) => return Err(e),
NullableResult::Null => return Err(BusError),
}
} else {
address
};
let res = match address {
(0..=0x00fe_ffff) | (0x0100_0000..=0xffff_ffff) => self
.cards
@ -282,9 +261,9 @@ impl Backplane {
fn handle_dma(&self) {
if !self.in_dma.get() {
self.in_dma.set(true);
for card in self.cards.iter() {
for card in &self.cards {
if let Ok(mut card) = card.try_borrow_mut() {
card.handle_dma(self)
card.handle_dma(self);
}
}
self.in_dma.set(false);

View File

@ -120,7 +120,7 @@ pub trait Card: Debug + Display + mopa::Any {
fn handle_dma(&mut self, _backplane: &Backplane) {}
fn try_as_mmu(&mut self) -> Option<&mut dyn MMU> {
fn try_as_mmu(&mut self) -> Option<&mut dyn Mmu> {
None
}
@ -138,17 +138,23 @@ pub trait Card: Debug + Display + mopa::Any {
fn handle_interconnect_message(&mut self, _interconnect_no: usize, _message: Box<dyn Any>) {}
}
pub trait MMU: Card {
fn translate_address(
&mut self,
backplane: &Backplane,
address: u32,
write: bool,
) -> NullableResult<u32, BusError>;
}
mopafy!(Card);
pub trait Mmu: Debug {
fn read_word(&mut self, address: u32, backplane: &Backplane) -> Result<u16, BusError>;
fn read_byte(&mut self, address: u32, backplane: &Backplane) -> Result<u8, BusError>;
fn write_word(
&mut self,
address: u32,
data: u16,
backplane: &Backplane,
) -> Result<(), BusError>;
fn write_byte(&mut self, address: u32, data: u8, backplane: &Backplane)
-> Result<(), BusError>;
}
#[allow(dead_code)]
pub const fn u64_set_be_byte(val: u64, idx: u8, byte: u8) -> u64 {
let mut bytes = val.to_be_bytes();

View File

@ -336,7 +336,7 @@ fn main() -> Result<(), anyhow::Error> {
state.cpu.bus_mut().write_word(address, data)?;
} else {
let data = parse::<u8>(args.get_one::<String>("data").unwrap())?;
state.cpu.bus_mut().write_byte(address, data as u8)?;
state.cpu.bus_mut().write_byte(address, data)?;
}
Ok(None)
}
@ -369,7 +369,7 @@ fn main() -> Result<(), anyhow::Error> {
Err(_) => {
break;
}
}
}
}
out.pop(); // Remove trailing newline
Ok(Some(out))
@ -384,7 +384,7 @@ fn main() -> Result<(), anyhow::Error> {
.short('a')
.action(ArgAction::SetTrue)
.requires("file")
.conflicts_with_all(&["delete", "set-active"])
.conflicts_with_all(["delete", "set-active"])
.help("Append the file's symbols to the loaded list of symbols"),
)
.arg(
@ -393,7 +393,7 @@ fn main() -> Result<(), anyhow::Error> {
.short('d')
.action(ArgAction::SetTrue)
.requires("file")
.conflicts_with_all(&["append", "set-active"])
.conflicts_with_all(["append", "set-active"])
.help("Delete the symbol table instead of loading it"),
)
.arg(
@ -403,7 +403,7 @@ fn main() -> Result<(), anyhow::Error> {
.value_parser(BoolishValueParser::new())
.requires("file")
.conflicts_with_all(&["append", "delete"])
.conflicts_with_all(["append", "delete"])
.help("Set whether the symbol table is active or not"),
)
.about("Load symbols from an ELF file, or list symbols if no file provided"),
@ -524,12 +524,12 @@ fn disas_fmt(
symbol_tables: &SymbolTables,
) -> (String, Result<u32, DisassemblyError<DetailedBusError>>) {
let addr_fmt = if let Some((table, symbol, offset)) = symbol_tables.address_to_symbol(addr) {
format!("{}:{} + {} (0x{:x})", table, symbol, offset, addr)
format!("{table}:{symbol} + {offset} (0x{addr:x})")
} else {
format!("0x{:x}", addr)
format!("0x{addr:x}")
};
match cpu.disassemble(addr) {
Ok((ins, new_addr)) => (format!("{}: {}\n", addr_fmt, ins), Ok(new_addr)),
Err(e) => (format!("{}: {}\n", addr_fmt, e), Err(e)),
Ok((ins, new_addr)) => (format!("{addr_fmt}: {ins}\n"), Ok(new_addr)),
Err(e) => (format!("{addr_fmt}: {e}\n"), Err(e)),
}
}

View File

@ -4,7 +4,7 @@ use nullable_result::NullableResult;
use crate::{
backplane::Backplane,
card::{u16_get_be_byte, u32_get_be_byte, u32_set_be_byte, Card, MMU},
card::{u16_get_be_byte, u32_get_be_byte, u32_set_be_byte, Card, Mmu},
m68k::BusError,
register,
};
@ -53,7 +53,7 @@ impl Card for MmuCard {
})
}
fn try_as_mmu(&mut self) -> Option<&mut dyn MMU> {
fn try_as_mmu(&mut self) -> Option<&mut dyn Mmu> {
Some(self)
}
@ -173,16 +173,13 @@ impl Display for MmuCard {
}
}
#[derive(Debug)]
pub struct Mmu;
impl MMU for MmuCard {
impl MmuCard {
fn translate_address(
&mut self,
backplane: &Backplane,
address: u32,
backplane: &Backplane,
write: bool,
) -> NullableResult<u32, BusError> {
) -> Result<u32, BusError> {
let print_debug = self.print_debug;
if self.enabled {
let page = address >> 12;
@ -200,7 +197,7 @@ impl MMU for MmuCard {
if print_debug {
println!("No mapping frame for this quarter");
}
return NullableResult::Null;
return Err(BusError);
}
let map_frame = self.map_frames[(page >> 10) as usize];
let entry_address = (map_frame) | ((page & 0x3FF) << 2);
@ -221,7 +218,7 @@ impl MMU for MmuCard {
if print_debug {
println!("Entry not writable");
}
return NullableResult::Err(BusError);
return Err(BusError);
}
if print_debug {
println!(
@ -229,17 +226,49 @@ impl MMU for MmuCard {
(entry.frame << 12) | offset
);
}
NullableResult::Ok((entry.frame << 12) | offset)
Ok((entry.frame << 12) | offset)
} else {
if print_debug {
println!("Entry not present");
}
NullableResult::Null
Err(BusError)
}
} else {
NullableResult::Ok(address)
Ok(address)
}
}
}
impl Mmu for MmuCard {
fn read_word(&mut self, address: u32, backplane: &Backplane) -> Result<u16, BusError> {
let address = self.translate_address(address, backplane, false)?;
backplane.read_word_phys(address)
}
fn read_byte(&mut self, address: u32, backplane: &Backplane) -> Result<u8, BusError> {
let address = self.translate_address(address, backplane, false)?;
backplane.read_byte_phys(address)
}
fn write_word(
&mut self,
address: u32,
data: u16,
backplane: &Backplane,
) -> Result<(), BusError> {
let address = self.translate_address(address, backplane, true)?;
backplane.write_word_phys(address, data)
}
fn write_byte(
&mut self,
address: u32,
data: u8,
backplane: &Backplane,
) -> Result<(), BusError> {
let address = self.translate_address(address, backplane, true)?;
backplane.write_byte_phys(address, data)
}
}
register!(MmuCard, "mmu");

View File

@ -27,8 +27,8 @@ struct Config {
bitflags! {
struct Status: u16 {
const BUSY = 0b00000001;
const DATA_READY = 0b00000010;
const BUSY = 0b000_00001;
const DATA_READY = 0b0000_0010;
}
}