diff --git a/src/backplane.rs b/src/backplane.rs index b7d1175..b0f1222 100644 --- a/src/backplane.rs +++ b/src/backplane.rs @@ -148,7 +148,7 @@ impl Backplane { .get(card_num as usize) .ok_or_else(|| anyhow!("Card {} does not exist", card_num))? .borrow_mut() - .cmd(cmd, &self) + .cmd(cmd, self) } pub fn read_word(&self, address: u32, supervisor: bool) -> Result { diff --git a/src/card.rs b/src/card.rs index 9e53509..a905ef8 100644 --- a/src/card.rs +++ b/src/card.rs @@ -58,6 +58,7 @@ pub trait Card: Debug + Display + mopa::Any { fn new(data: Value) -> anyhow::Result where Self: Sized; + fn new_dyn(data: Value) -> anyhow::Result>> where Self: Sized + 'static, @@ -65,9 +66,7 @@ pub trait Card: Debug + Display + mopa::Any { let card = Self::new(data)?; Ok(Rc::new(RefCell::new(card))) } - fn display(&self) -> String { - String::new() - } + fn read_byte(&mut self, _address: u32) -> NullableResult { NullableResult::Null } diff --git a/src/m68k.rs b/src/m68k.rs index e26b476..fcaa338 100644 --- a/src/m68k.rs +++ b/src/m68k.rs @@ -24,7 +24,7 @@ impl Display for BusError { impl Error for BusError {} -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum BusErrorCause { ReadingByte, ReadingWord, @@ -33,6 +33,15 @@ pub enum BusErrorCause { ReadingInstruction, } +impl BusErrorCause { + fn is_write(self) -> bool { + self == Self::WritingByte || self == Self::WritingWord + } + fn is_byte(self) -> bool { + self == Self::ReadingByte || self == Self::WritingByte + } +} + impl Display for BusErrorCause { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -286,20 +295,10 @@ impl M68K { } self.handling_bus_error = true; self.store_mem_cycles = false; - let (write, ins, byte_access) = match bus_error.cause { - BusErrorCause::ReadingByte => (false, false, true), - BusErrorCause::WritingByte => (true, false, true), - BusErrorCause::ReadingWord => (false, false, false), - BusErrorCause::WritingWord => (true, false, false), - BusErrorCause::ReadingInstruction => (false, true, false), - }; let stored_mem_cycles_len = self.stored_mem_cycles.len(); let last_cycle = &self.stored_mem_cycles[stored_mem_cycles_len - 1]; if let Err(snd_bus_error) = self.berr_trap( - write, - ins, - byte_access, - bus_error.address, + bus_error, last_cycle.try_get_write_data().unwrap_or(0), ) { println!( @@ -747,9 +746,7 @@ impl M68K { } else if last_cycle.is_err() { self.stored_mem_cycles.pop(); } - self.use_stored_mem_cycles = true; - self.handling_bus_error = false; - } if format == 0 { + } else if format == 0 { // Nothing extra needed } else { self.trap(14)?; @@ -1760,10 +1757,7 @@ impl M68K { fn berr_trap( &mut self, - write: bool, - ins: bool, - byte_access: bool, - fault_addr: u32, + bus_error: DetailedBusError, write_data: u16, ) -> Result<(), InsExecError> { let orig_sr = self.sr; @@ -1792,11 +1786,12 @@ impl M68K { // Unused self.push(0, Size::Word)?; // Fault address - self.push(fault_addr, Size::Long)?; + self.push(bus_error.address, Size::Long)?; // Special status word - let special_status_word = (u16::from(write) << 8) - | (u16::from(byte_access) << 9) - | (((fault_addr & 0x1) as u16) << 10) + let ins = bus_error.cause == BusErrorCause::ReadingInstruction; + let special_status_word = (u16::from(bus_error.cause.is_write()) << 8) + | (u16::from(bus_error.cause.is_byte()) << 9) + | (((bus_error.address & 0x1) as u16) << 10) | u16::from(!ins) | u16::from(ins); self.push(u32::from(special_status_word), Size::Word)?; diff --git a/src/mmu.rs b/src/mmu.rs index 3ff43bc..9a9f46a 100644 --- a/src/mmu.rs +++ b/src/mmu.rs @@ -162,15 +162,13 @@ impl Card for MmuCard { if j_frame == frame { if range_one_page == Some(false) { break; - } else { - range_one_page = Some(true); - } + } + range_one_page = Some(true); } else if (j_frame - frame) == ((((j - i) as u32) + 1) * 0x1000) { if range_one_page == Some(true) { break; - } else { - range_one_page = Some(false); } + range_one_page = Some(false); } else { break; } @@ -246,15 +244,13 @@ impl Card for MmuCard { if j_frame == frame { if range_one_page == Some(false) { break; - } else { - range_one_page = Some(true); } + range_one_page = Some(true); } else if (j_frame - frame) == ((((j - i) as u32) + 1) * 0x1000) { if range_one_page == Some(true) { break; - } else { - range_one_page = Some(false); } + range_one_page = Some(false); } else { break; } diff --git a/src/symbol_table.rs b/src/symbol_table.rs index 26a34e7..1d65b42 100644 --- a/src/symbol_table.rs +++ b/src/symbol_table.rs @@ -26,10 +26,6 @@ impl Display for SymbolDisplayer<'_> { } } -#[derive(Debug, Copy, Clone, Error)] -#[error("Invalid symbol table")] -struct InvalidSymbolTable; - pub struct BreakpointDisplayer<'a>(&'a SymbolTable); impl Display for BreakpointDisplayer<'_> {