Return bus errors from cpu.step() instead of panicking

This commit is contained in:
pjht 2023-01-24 10:23:46 -06:00
parent 5ce4dcc894
commit a52442493a
Signed by: pjht
GPG Key ID: E911DEB42C25F8E1
3 changed files with 331 additions and 241 deletions

View File

@ -62,14 +62,14 @@ pub fn disasm<T>(
#[derive(Debug)] #[derive(Debug)]
pub enum DisassemblyError<T> { pub enum DisassemblyError<T> {
InvalidInstruction, InvalidInstruction,
ReadError(u32, T), ReadError(T),
} }
impl<T: Display> Display for DisassemblyError<T> { impl<T: Display> Display for DisassemblyError<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::InvalidInstruction => f.write_str("Invalid instruction"), Self::InvalidInstruction => f.write_str("Invalid instruction"),
Self::ReadError(addr, e) => f.write_fmt(format_args!("Read error at {} ({})", addr, e)), Self::ReadError(e) => f.write_fmt(format_args!("{}", e)),
} }
} }
} }
@ -926,11 +926,9 @@ impl<T> Disasm<'_, T> {
} }
fn read_prog_word(&mut self) -> Result<u16, DisassemblyError<T>> { fn read_prog_word(&mut self) -> Result<u16, DisassemblyError<T>> {
let word = ((self.byte_read)(self.pc) let word = ((self.byte_read)(self.pc).map_err(|e| DisassemblyError::ReadError(e))? as u16)
.map_err(|e| DisassemblyError::ReadError(self.pc, e))? as u16)
<< 8 << 8
| ((self.byte_read)(self.pc + 1) | ((self.byte_read)(self.pc + 1).map_err(|e| DisassemblyError::ReadError(e))? as u16);
.map_err(|e| DisassemblyError::ReadError(self.pc + 1, e))? as u16);
self.pc += 2; self.pc += 2;
Ok(word) Ok(word)
} }

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ mod term;
use crate::{ use crate::{
backplane::Backplane, backplane::Backplane,
location::Location, location::Location,
m68k::{BusError, M68K}, m68k::{DetailedBusError, M68K},
}; };
use anyhow::anyhow; use anyhow::anyhow;
use clap::Parser; use clap::Parser;
@ -79,7 +79,13 @@ fn main() -> Result<(), anyhow::Error> {
if args.run { if args.run {
let mut out = String::new(); let mut out = String::new();
while !state.cpu.stopped { while !state.cpu.stopped {
state.cpu.step(); match state.cpu.step() {
Ok(()) => (),
Err(e) => {
println!("{}", e);
state.cpu.stopped = true;
}
}
} }
out += &format!("{}\n", state.cpu); out += &format!("{}\n", state.cpu);
let pc = state.cpu.pc(); let pc = state.cpu.pc();
@ -458,7 +464,7 @@ fn disas_fmt(
cpu: &mut M68K, cpu: &mut M68K,
addr: u32, addr: u32,
symbol_tables: &SymbolTables, symbol_tables: &SymbolTables,
) -> (String, Result<u32, DisassemblyError<BusError>>) { ) -> (String, Result<u32, DisassemblyError<DetailedBusError>>) {
let addr_fmt = if let Some((table, symbol, offset)) = symbol_tables.address_to_symbol(addr) { let addr_fmt = if let Some((table, symbol, offset)) = symbol_tables.address_to_symbol(addr) {
format!("{}:{} + {} (0x{:x})", table, symbol, offset, addr) format!("{}:{} + {} (0x{:x})", table, symbol, offset, addr)
} else { } else {