From 030ca2281206d0b8d48d3e590becd3932ef9051f Mon Sep 17 00:00:00 2001 From: pjht Date: Thu, 7 Dec 2023 13:56:41 -0600 Subject: [PATCH 1/2] Allow dissasembly errors to include abnormal traps --- src/m68k.rs | 26 +++++++++++++++++++------- src/main.rs | 3 ++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/m68k.rs b/src/m68k.rs index adbdd1d..8649612 100644 --- a/src/m68k.rs +++ b/src/m68k.rs @@ -144,8 +144,14 @@ impl From for InsExecError { } } - - +impl Display for InsExecError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InsExecError::BusError(err) => f.write_fmt(format_args!("{}", err)), + InsExecError::AbnormalTrap => f.write_str("Abnormal trap"), + } + } +} #[derive(Debug)] pub struct M68K { @@ -243,11 +249,14 @@ impl M68K { pub fn disassemble( &mut self, loc: u32, - ) -> Result<(Instruction, u32), DisassemblyError> { + ) -> Result<(Instruction, u32), DisassemblyError> { disas::disasm(loc, &mut |addr| { - self.read_word(addr).map_err(|err| DetailedBusError { - cause: BusErrorCause::ReadingInstruction, - ..err.try_into_bus_error().unwrap() + self.read_word(addr).map_err(|err| match err { + InsExecError::AbnormalTrap => InsExecError::AbnormalTrap, + InsExecError::BusError(err) => InsExecError::BusError(DetailedBusError { + cause: BusErrorCause::ReadingInstruction, + ..err + }), }) }) } @@ -316,7 +325,10 @@ impl M68K { } let (ins, new_pc) = match self.disassemble(self.pc) { Ok(ins) => ins, - Err(DisassemblyError::InvalidInstruction) => panic!("Invalid instruction"), + Err(DisassemblyError::InvalidInstruction) => { + self.trap(4)?; + return self.step_ret_berr(); + } Err(DisassemblyError::ReadError(e)) => return Err(e.into()), }; self.pc = new_pc; diff --git a/src/main.rs b/src/main.rs index 4960222..06bace2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ use clap::Parser; use disas::DisassemblyError; use indexmap::IndexSet; use itertools::Itertools; +use m68k::InsExecError; use parse_int::parse; use reedline_repl_rs::{ clap::{builder::BoolishValueParser, Arg, ArgAction, Command}, @@ -527,7 +528,7 @@ fn disas_fmt( cpu: &mut M68K, addr: u32, symbol_tables: &SymbolTables, -) -> (String, Result>) { +) -> (String, Result>) { let addr_fmt = if let Some((table, symbol, offset)) = symbol_tables.address_to_symbol(addr) { format!("{table}:{symbol} + {offset} (0x{addr:x})") } else { From 53b47f8410b4a81dcb5bddf984f9f667fa507630 Mon Sep 17 00:00:00 2001 From: pjht Date: Thu, 7 Dec 2023 13:56:56 -0600 Subject: [PATCH 2/2] Clean up code --- src/backplane.rs | 4 +- src/disas.rs | 13 +-- src/instruction.rs | 27 +++-- src/m68k.rs | 253 +++++++++++++++++++------------------------- src/main.rs | 22 ++-- src/mmu.rs | 13 +-- src/peek.rs | 4 +- src/rom.rs | 4 +- src/storage.rs | 18 ++-- src/symbol_table.rs | 2 +- 10 files changed, 159 insertions(+), 201 deletions(-) diff --git a/src/backplane.rs b/src/backplane.rs index 01021eb..576264c 100644 --- a/src/backplane.rs +++ b/src/backplane.rs @@ -95,7 +95,7 @@ impl Backplane { } let cards: Vec<_> = card_configs .into_iter() - .map(|cfg| cfg.into_card()) + .map(card::Config::into_card) .try_collect()?; let mmu = cards @@ -328,7 +328,7 @@ impl Backplane { fn read_byte_io(&self, address: u8) -> NullableResult { #[allow(clippy::single_match)] match address { - 0x1 => NullableResult::Ok(self.io_at_top_16mb.load(Ordering::Relaxed) as u8), + 0x1 => NullableResult::Ok(u8::from(self.io_at_top_16mb.load(Ordering::Relaxed))), _ => NullableResult::Ok(0), } } diff --git a/src/disas.rs b/src/disas.rs index 75c1edd..710edad 100644 --- a/src/disas.rs +++ b/src/disas.rs @@ -3,8 +3,8 @@ use std::fmt::Display; use bitvec::prelude::*; use crate::instruction::{ - BitInsType, Condition, EffectiveAddress, Instruction, MoveDirection, RegisterEffective, - Rotation, ShiftDirection, ShiftType, Size, ControlRegister, + BitInsType, Condition, ControlRegister, EffectiveAddress, Instruction, MoveDirection, + RegisterEffective, Rotation, ShiftDirection, ShiftType, Size, }; use derive_try_from_primitive::TryFromPrimitive; @@ -461,7 +461,7 @@ impl Disasm<'_, T> { } else if ins_word[4..13].load_be::() == 0b1_1100_1010 { let areg = ins_word[13..16].load_be::(); let displacement = self.read_immediate(Size::Word)? as i16; - Ok(Instruction::Link {areg, displacement}) + Ok(Instruction::Link { areg, displacement }) } else if ins_word[4..13].load_be::() == 0b1_1100_1011 { let dst = ins_word[13..16].load_be::(); Ok(Instruction::Unlk(dst)) @@ -502,7 +502,8 @@ impl Disasm<'_, T> { } else { EffectiveAddress::DataReg(reg_num) }; - let ctrl = ControlRegister::try_from(word2[4..16].load_be::()).map_err(|_| DisassemblyError::InvalidInstruction)?; + let ctrl = ControlRegister::try_from(word2[4..16].load_be::()) + .map_err(|_| DisassemblyError::InvalidInstruction)?; Ok(Instruction::Movec(dir, ea, ctrl)) } else if ins_word[4..10].load_be::() == 0b11_1010 { let dst_mode = @@ -616,9 +617,9 @@ impl Disasm<'_, T> { Size::Long => unreachable!(), }; let new_pc = if displacement >= 0 { - pc.wrapping_add(displacement as u16 as u32) + pc.wrapping_add(u32::from(displacement as u16)) } else { - pc.wrapping_sub(-displacement as u16 as u32) + pc.wrapping_sub(u32::from(-displacement as u16)) }; if condition == Condition::False { Ok(Instruction::Bsr(size, displacement, new_pc)) diff --git a/src/instruction.rs b/src/instruction.rs index 2e4f45f..850cc27 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -265,23 +265,22 @@ impl Display for ShiftDirection { } } - #[derive(Debug, Clone, TryFromPrimitive)] #[repr(u16)] pub enum ControlRegister { - SFC = 0x0, - DFC = 0x1, - USP = 0x800, - VBR = 0x801, + Sfc = 0x0, + Dfc = 0x1, + Usp = 0x800, + Vbr = 0x801, } impl Display for ControlRegister { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Self::SFC => f.write_str("SFC"), - Self::DFC => f.write_str("DFC"), - Self::USP => f.write_str("USP"), - Self::VBR => f.write_str("VBR"), + Self::Sfc => f.write_str("SFC"), + Self::Dfc => f.write_str("DFC"), + Self::Usp => f.write_str("USP"), + Self::Vbr => f.write_str("VBR"), } } } @@ -488,12 +487,10 @@ impl Display for Instruction { Self::Rts => write!(f, "RTS"), Self::Trapv => write!(f, "TRAPV"), Self::Rtr => write!(f, "RTR"), - Self::Movec(dir, ea, ctrl) => { - match dir { - MoveDirection::MemToReg => write!(f, "MOVEC {ctrl}, {ea}"), - MoveDirection::RegToMem => write!(f, "MOVEC {ea}, {ctrl}"), - } - } + Self::Movec(dir, ea, ctrl) => match dir { + MoveDirection::MemToReg => write!(f, "MOVEC {ctrl}, {ea}"), + MoveDirection::RegToMem => write!(f, "MOVEC {ea}, {ctrl}"), + }, Self::Jsr(ea) => write!(f, "JSR {ea}"), Self::Jmp(ea) => write!(f, "JMP {ea}"), Self::Movem(dir, size, dst, regs) => { diff --git a/src/m68k.rs b/src/m68k.rs index 8649612..803efe9 100644 --- a/src/m68k.rs +++ b/src/m68k.rs @@ -8,8 +8,8 @@ use crate::{ backplane::Backplane, disas::{self, DisassemblyError}, instruction::{ - ArithType, BitInsType, EffectiveAddress, Instruction, MoveDirection, ShiftDirection, - ShiftType, Size, ControlRegister, Rotation, + ArithType, BitInsType, ControlRegister, EffectiveAddress, Instruction, MoveDirection, + Rotation, ShiftDirection, ShiftType, Size, }, }; @@ -87,37 +87,37 @@ enum MemCycleInfo { impl MemCycleInfo { fn is_err(&self) -> bool { match self { - MemCycleInfo::ReadByte { result, .. } => result.is_err(), - MemCycleInfo::ReadWord { result, .. } => result.is_err(), - MemCycleInfo::WriteByte { result, .. } => result.is_err(), - MemCycleInfo::WriteWord { result, .. } => result.is_err(), + Self::ReadByte { result, .. } => result.is_err(), + Self::ReadWord { result, .. } => result.is_err(), + Self::WriteByte { result, .. } => result.is_err(), + Self::WriteWord { result, .. } => result.is_err(), } } fn unwrap_err(&self) -> DetailedBusError { match self { - MemCycleInfo::ReadByte { result, .. } => result.unwrap_err(), - MemCycleInfo::ReadWord { result, .. } => result.unwrap_err(), - MemCycleInfo::WriteByte { result, .. } => result.unwrap_err(), - MemCycleInfo::WriteWord { result, .. } => result.unwrap_err(), + Self::ReadByte { result, .. } => result.unwrap_err(), + Self::ReadWord { result, .. } => result.unwrap_err(), + Self::WriteByte { result, .. } => result.unwrap_err(), + Self::WriteWord { result, .. } => result.unwrap_err(), } } fn address(&self) -> u32 { *(match self { - MemCycleInfo::ReadByte { address, .. } => address, - MemCycleInfo::ReadWord { address, .. } => address, - MemCycleInfo::WriteByte { address, .. } => address, - MemCycleInfo::WriteWord { address, .. } => address, + Self::ReadByte { address, .. } => address, + Self::ReadWord { address, .. } => address, + Self::WriteByte { address, .. } => address, + Self::WriteWord { address, .. } => address, }) } fn try_get_write_data(&self) -> Option { match self { - MemCycleInfo::ReadByte { .. } => None, - MemCycleInfo::ReadWord { .. } => None, - MemCycleInfo::WriteByte { data, .. } => Some(*data as u16), - MemCycleInfo::WriteWord { data, .. } => Some(*data), + Self::ReadByte { .. } => None, + Self::ReadWord { .. } => None, + Self::WriteByte { data, .. } => Some(u16::from(*data)), + Self::WriteWord { data, .. } => Some(*data), } } } @@ -147,8 +147,8 @@ impl From for InsExecError { impl Display for InsExecError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - InsExecError::BusError(err) => f.write_fmt(format_args!("{}", err)), - InsExecError::AbnormalTrap => f.write_str("Abnormal trap"), + Self::BusError(err) => f.write_fmt(format_args!("{err}")), + Self::AbnormalTrap => f.write_str("Abnormal trap"), } } } @@ -231,7 +231,7 @@ impl M68K { self.read_word(4), self.read_word(6), ) { - self.ssp = ((ssp_high as u32) << 16) | (ssp_low as u32); + self.ssp = (u32::from(ssp_high) << 16) | u32::from(ssp_low); self.vbr = 0; self.pc = (u32::from(pc_high) << 16) | u32::from(pc_low); self.sr = 0x2700 | self.sr & 0xFF; @@ -263,22 +263,20 @@ impl M68K { pub fn step(&mut self) { let bus_error = match self.step_ret_berr() { - Ok(_) => { + Ok(()) => { self.stored_mem_cycles.clear(); return; - }, - Err(e) => { - match e { - InsExecError::BusError(e) => e, - InsExecError::AbnormalTrap => { - self.stored_mem_cycles.clear(); - return; - }, + } + Err(e) => match e { + InsExecError::BusError(e) => e, + InsExecError::AbnormalTrap => { + self.stored_mem_cycles.clear(); + return; } }, }; if self.handling_bus_error { - println!("{} while handling bus error, halting", bus_error); + println!("{bus_error} while handling bus error, halting"); self.stopped = true; self.stored_mem_cycles.clear(); self.use_stored_mem_cycles = false; @@ -297,22 +295,23 @@ impl M68K { }; 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, - last_cycle.try_get_write_data().unwrap_or(0), - ) - { - println!("{} while trapping to bus error handler for {}, halting", snd_bus_error.try_into_bus_error().unwrap(), bus_error); + if let Err(snd_bus_error) = self.berr_trap( + write, + ins, + byte_access, + bus_error.address, + last_cycle.try_get_write_data().unwrap_or(0), + ) { + println!( + "{} while trapping to bus error handler for {}, halting", + snd_bus_error.try_into_bus_error().unwrap(), + bus_error + ); self.stopped = true; self.stored_mem_cycles.clear(); self.use_stored_mem_cycles = false; self.handling_bus_error = false; self.store_mem_cycles = true; - return; } } @@ -329,12 +328,12 @@ impl M68K { self.trap(4)?; return self.step_ret_berr(); } - Err(DisassemblyError::ReadError(e)) => return Err(e.into()), + Err(DisassemblyError::ReadError(e)) => return Err(e), }; self.pc = new_pc; match ins { Instruction::OriCcr(val) => { - self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) | val as u16); + self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) | u16::from(val)); } Instruction::OriSr(val) => self.sr |= val, Instruction::Ori(size, dst, val) => { @@ -352,7 +351,7 @@ impl M68K { self.sr = (self.sr & 0xFFE0) | new_flags; } Instruction::AndiCcr(val) => { - self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) & val as u16); + self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) & u16::from(val)); } Instruction::AndiSr(val) => self.sr &= val, Instruction::Andi(size, dst, val) => { @@ -376,7 +375,7 @@ impl M68K { self.add(dst, EffectiveAddress::Immediate(val), size, ArithType::Reg)?; } Instruction::EoriCcr(val) => { - self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) ^ val as u16); + self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) ^ u16::from(val)); } Instruction::EoriSr(val) => self.sr ^= val, Instruction::Eori(size, dst, val) => { @@ -435,7 +434,7 @@ impl M68K { )? as u8; self.write_effective( EffectiveAddress::DataReg(dreg), - ((high as u32) << 8) | (low as u32), + (u32::from(high) << 8) | u32::from(low), Size::Word, )?; } @@ -458,10 +457,10 @@ impl M68K { )? as u8; self.write_effective( EffectiveAddress::DataReg(dreg), - ((high as u32) << 24) - | ((mid_high as u32) << 16) - | ((mid_low as u32) << 8) - | (low as u32), + (u32::from(high) << 24) + | (u32::from(mid_high) << 16) + | (u32::from(mid_low) << 8) + | u32::from(low), Size::Word, )?; } @@ -612,11 +611,7 @@ impl M68K { } else { sp.wrapping_sub(-displacement as u32) }; - self.write_effective( - EffectiveAddress::AddressReg(7), - new_sp, - Size::Long, - )?; + self.write_effective(EffectiveAddress::AddressReg(7), new_sp, Size::Long)?; } Instruction::Unlk(areg) => { let dst = EffectiveAddress::AddressReg(areg); @@ -669,14 +664,11 @@ impl M68K { let ssw_rerrun = (special_status_word >> 15) > 1; let stored_mem_cycles_len = self.stored_mem_cycles.len(); let last_cycle = &mut self.stored_mem_cycles[stored_mem_cycles_len - 1]; - if !ssw_rerrun { - if last_cycle.is_err() { - self.stored_mem_cycles.pop(); - } - } else { - if fault_address != last_cycle.address() { - panic!("Recorded fault address did not match cycle address"); - }; + if ssw_rerrun { + assert!( + fault_address == last_cycle.address(), + "Recorded fault address did not match cycle address" + ); let (expected_write, expected_ins, expected_byte_access) = match last_cycle.unwrap_err().cause { BusErrorCause::ReadingByte => (false, false, true), @@ -685,15 +677,9 @@ impl M68K { BusErrorCause::WritingWord => (true, false, false), BusErrorCause::ReadingInstruction => (false, true, false), }; - if ssw_write != expected_write { - panic!("Write flag in the SSW did not match kind of cycle when returning from handling bus error (got {}, expected {})", ssw_write, expected_write); - }; - if ssw_ins != expected_ins { - panic!("Instruction flag in the SSW did not match kind of cycle when returning from handling bus error (got {}, expected {})", ssw_ins, expected_ins); - }; - if ssw_byte_access != expected_byte_access { - panic!("Byte access flag in the SSW did not match kind of cycle when returning from handling bus error (got {}, expected {})", ssw_byte_access, expected_byte_access); - }; + assert!(ssw_write == expected_write, "Write flag in the SSW did not match kind of cycle when returning from handling bus error (got {ssw_write}, expected {expected_write})"); + assert!(ssw_ins == expected_ins, "Instruction flag in the SSW did not match kind of cycle when returning from handling bus error (got {ssw_ins}, expected {expected_ins})"); + assert!(ssw_byte_access == expected_byte_access, "Byte access flag in the SSW did not match kind of cycle when returning from handling bus error (got {ssw_byte_access}, expected {expected_byte_access})"); let input_buf = if ssw_ins { instruction_input_buf } else { @@ -717,6 +703,8 @@ impl M68K { *result = Ok(()); } } + } else if last_cycle.is_err() { + self.stored_mem_cycles.pop(); } } } @@ -731,34 +719,28 @@ impl M68K { self.sr = (self.sr & 0xFF00) | u16::from(self.pop(Size::Word)? as u8); self.pc = self.pop(Size::Long)?; } - Instruction::Movec(dir, ea, ctrl) => { - match dir { - MoveDirection::MemToReg => { - match ctrl { - ControlRegister::SFC => todo!(), - ControlRegister::DFC => todo!(), - ControlRegister::USP => { - self.write_effective(ea, self.usp, Size::Long)?; - }, - ControlRegister::VBR => { - self.write_effective(ea, self.vbr, Size::Long)?; - }, - } - }, - MoveDirection::RegToMem => { - match ctrl { - ControlRegister::SFC => todo!(), - ControlRegister::DFC => todo!(), - ControlRegister::USP => { - self.usp = self.read_effective(ea, Size::Long)?; - }, - ControlRegister::VBR => { - self.vbr = self.read_effective(ea, Size::Long)? &!(0x3FF); - }, - } - }, - } - } + Instruction::Movec(dir, ea, ctrl) => match dir { + MoveDirection::MemToReg => match ctrl { + ControlRegister::Sfc => todo!(), + ControlRegister::Dfc => todo!(), + ControlRegister::Usp => { + self.write_effective(ea, self.usp, Size::Long)?; + } + ControlRegister::Vbr => { + self.write_effective(ea, self.vbr, Size::Long)?; + } + }, + MoveDirection::RegToMem => match ctrl { + ControlRegister::Sfc => todo!(), + ControlRegister::Dfc => todo!(), + ControlRegister::Usp => { + self.usp = self.read_effective(ea, Size::Long)?; + } + ControlRegister::Vbr => { + self.vbr = self.read_effective(ea, Size::Long)? & !(0x3FF); + } + }, + }, Instruction::Jsr(ea) => { self.push(self.pc, Size::Long)?; self.pc = self.effective_address(ea)?; @@ -792,7 +774,7 @@ impl M68K { } Instruction::Addq(size, val, dst) => self.add( dst, - EffectiveAddress::Immediate(val as i32 as u32), + EffectiveAddress::Immediate(i32::from(val) as u32), size, if matches!(dst, EffectiveAddress::AddressReg(_)) { ArithType::Addr @@ -802,7 +784,7 @@ impl M68K { )?, Instruction::Subq(size, val, dst) => self.sub( dst, - EffectiveAddress::Immediate(val as i32 as u32), + EffectiveAddress::Immediate(i32::from(val) as u32), size, if matches!(dst, EffectiveAddress::AddressReg(_)) { ArithType::Addr @@ -839,7 +821,7 @@ impl M68K { } } Instruction::Moveq { dreg, imm } => { - let imm = imm as i32 as u32; + let imm = i32::from(imm) as u32; let neg = (imm & 0x8000_0000) > 0; let zero = imm == 0; let old_flags = self.sr & 0xFFE0; @@ -1373,7 +1355,7 @@ impl M68K { .wrapping_add(self.read_effective(EffectiveAddress::from(idx), idx_size)?); self.read_address(address, size) } - EffectiveAddress::AbsoluteShort(x) => self.read_address(x as u32, size), + EffectiveAddress::AbsoluteShort(x) => self.read_address(u32::from(x), size), EffectiveAddress::AbsoluteLong(x) => self.read_address(x, size), } } @@ -1452,7 +1434,7 @@ impl M68K { .wrapping_add(self.read_effective(EffectiveAddress::from(idx), idx_size)?); self.write_address(address, data, size)?; } - EffectiveAddress::AbsoluteShort(x) => self.write_address(x as u32, data, size)?, + EffectiveAddress::AbsoluteShort(x) => self.write_address(u32::from(x), data, size)?, EffectiveAddress::AbsoluteLong(x) => self.write_address(x, data, size)?, EffectiveAddress::PcDisplacement(..) | EffectiveAddress::PcIndex(..) @@ -1462,7 +1444,6 @@ impl M68K { } fn read_address(&mut self, address: u32, size: Size) -> Result { - // println!("READ {:x}, {:?}", address, size); let address = address & 0xFF_FFFF; match size { Size::Byte => Ok(u32::from(self.read_byte(address)?)), @@ -1474,13 +1455,7 @@ impl M68K { } } - fn write_address( - &mut self, - address: u32, - data: u32, - size: Size, - ) -> Result<(), InsExecError> { - // println!("WRITE {:x}, {:?}, data {:x}", address, size, data); + fn write_address(&mut self, address: u32, data: u32, size: Size) -> Result<(), InsExecError> { match size { Size::Byte => self.write_byte(address, data as u8)?, Size::Word => self.write_word(address, data as u16)?, @@ -1501,11 +1476,8 @@ impl M68K { result, } = cycle { - if stored_address == address { - return Ok(result?); - } else { - panic!("Stored bus cycle has wrong address when reading byte (reading {:#x}, stored {:#x})", address, stored_address); - } + assert!(stored_address == address, "Stored bus cycle has wrong address when reading byte (reading {address:#x}, stored {stored_address:#x})"); + return Ok(result?); } if self.stored_mem_cycles.is_empty() { self.store_mem_cycles = true; @@ -1516,10 +1488,8 @@ impl M68K { cause: BusErrorCause::ReadingByte, }); if self.store_mem_cycles { - self.stored_mem_cycles.push(MemCycleInfo::ReadByte { - address, - result: result.clone(), - }); + self.stored_mem_cycles + .push(MemCycleInfo::ReadByte { address, result }); }; Ok(result?) } @@ -1537,9 +1507,9 @@ impl M68K { if stored_address == address && stored_data == data { return Ok(result?); } else if stored_address != address { - panic!("Stored bus cycle has wrong address when writing byte (reading {:#x}, stored {:#x})", address, stored_address); + panic!("Stored bus cycle has wrong address when writing byte (reading {address:#x}, stored {stored_address:#x})"); } else if stored_data != data { - panic!("Stored bus cycle has wrong data when writing byte (writing {:#x}, stored {:#x})", data, stored_data); + panic!("Stored bus cycle has wrong data when writing byte (writing {data:#x}, stored {stored_data:#x})"); } } if self.stored_mem_cycles.is_empty() { @@ -1557,7 +1527,7 @@ impl M68K { self.stored_mem_cycles.push(MemCycleInfo::WriteByte { address, data, - result: result.clone(), + result, }); }; Ok(result?) @@ -1576,11 +1546,8 @@ impl M68K { result, } = cycle { - if stored_address == address { - return Ok(result?); - } else { - panic!("Stored bus cycle has wrong address when reading word (reading {:#x}, stored {:#x})", address, stored_address); - } + assert!(stored_address == address, "Stored bus cycle has wrong address when reading word (reading {address:#x}, stored {stored_address:#x})"); + return Ok(result?); } if self.stored_mem_cycles.is_empty() { self.store_mem_cycles = true; @@ -1591,10 +1558,8 @@ impl M68K { cause: BusErrorCause::ReadingWord, }); if self.store_mem_cycles { - self.stored_mem_cycles.push(MemCycleInfo::ReadWord { - address, - result: result.clone(), - }); + self.stored_mem_cycles + .push(MemCycleInfo::ReadWord { address, result }); }; Ok(result?) } @@ -1616,9 +1581,9 @@ impl M68K { if stored_address == address && stored_data == data { return Ok(result?); } else if stored_address != address { - panic!("Stored bus cycle has wrong address when writing word (reading {:#x}, stored {:#x})", address, stored_address); + panic!("Stored bus cycle has wrong address when writing word (reading {address:#x}, stored {stored_address:#x})"); } else if stored_data != data { - panic!("Stored bus cycle has wrong data when writing word (writing {:#x}, stored {:#x})", data, stored_data); + panic!("Stored bus cycle has wrong data when writing word (writing {data:#x}, stored {stored_data:#x})"); } } if self.stored_mem_cycles.is_empty() { @@ -1636,7 +1601,7 @@ impl M68K { self.stored_mem_cycles.push(MemCycleInfo::WriteWord { address, data, - result: result.clone(), + result, }); }; Ok(result?) @@ -1675,7 +1640,7 @@ impl M68K { } } EffectiveAddress::PcDisplacement(pc, d) => Ok(pc.wrapping_add(d.into())), - EffectiveAddress::AbsoluteShort(x) => Ok(x as u32), + EffectiveAddress::AbsoluteShort(x) => Ok(u32::from(x)), EffectiveAddress::AbsoluteLong(x) => Ok(x), EffectiveAddress::DataReg(_) | EffectiveAddress::AddressReg(_) @@ -1747,17 +1712,17 @@ impl M68K { // Unused self.push(0, Size::Word)?; // Data output buffer - self.push(write_data as u32, Size::Word)?; + self.push(u32::from(write_data), Size::Word)?; // Unused self.push(0, Size::Word)?; // Fault address self.push(fault_addr, Size::Long)?; // Special status word - let special_status_word = ((write as u16) << 8) - | ((byte_access as u16) << 9) + let special_status_word = (u16::from(write) << 8) + | (u16::from(byte_access) << 9) | (((fault_addr & 0x1) as u16) << 10) - | (!ins as u16) - | (ins as u16); + | u16::from(!ins) + | u16::from(ins); self.push(u32::from(special_status_word), Size::Word)?; // Format & vector self.push(0x8002, Size::Word)?; diff --git a/src/main.rs b/src/main.rs index 06bace2..32786df 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,11 +15,7 @@ mod symbol; mod symbol_table; mod symbol_tables; mod term; -use crate::{ - backplane::Backplane, - location::Location, - m68k::{DetailedBusError, M68K}, -}; +use crate::{backplane::Backplane, location::Location, m68k::M68K}; use anyhow::anyhow; use clap::Parser; use disas::DisassemblyError; @@ -287,22 +283,22 @@ fn main() -> Result<(), anyhow::Error> { if args.get_flag("phys") { for i in 0..count { match size { - peek::Size::Byte => data.push(bus.read_byte_phys(addr + i)? as u32), - peek::Size::Word => data.push(bus.read_word_phys(addr + (i * 2))? as u32), + peek::Size::Byte => data.push(u32::from(bus.read_byte_phys(addr + i)?)), + peek::Size::Word => data.push(u32::from(bus.read_word_phys(addr + (i * 2))?)), peek::Size::LongWord => data.push( - (bus.read_word_phys(addr + (i * 4))? as u32) << 16 - | (bus.read_word_phys(addr + (i * 4) + 2)? as u32), + u32::from(bus.read_word_phys(addr + (i * 4))?) << 16 + | u32::from(bus.read_word_phys(addr + (i * 4) + 2)?), ), } } } else { for i in 0..count { match size { - peek::Size::Byte => data.push(bus.read_byte(addr + i)? as u32), - peek::Size::Word => data.push(bus.read_word(addr + (i * 2))? as u32), + peek::Size::Byte => data.push(u32::from(bus.read_byte(addr + i)?)), + peek::Size::Word => data.push(u32::from(bus.read_word(addr + (i * 2))?)), peek::Size::LongWord => data.push( - (bus.read_word(addr + (i * 4))? as u32) << 16 - | (bus.read_word(addr + (i * 4) + 2)? as u32), + u32::from(bus.read_word(addr + (i * 4))?) << 16 + | u32::from(bus.read_word(addr + (i * 4) + 2)?), ), } } diff --git a/src/mmu.rs b/src/mmu.rs index cd43b78..187b232 100644 --- a/src/mmu.rs +++ b/src/mmu.rs @@ -49,7 +49,7 @@ impl Card for MmuCard { let offset = address % 4; match offset { (0..=2) => NullableResult::Ok(u32_get_be_byte(self.map_frames[map_no], offset)), - 3 => NullableResult::Ok(self.map_frames_enabled[map_no] as u8), + 3 => NullableResult::Ok(u8::from(self.map_frames_enabled[map_no])), _ => unreachable!(), } } @@ -86,18 +86,19 @@ impl Card for MmuCard { match offset { 0 => (), 1 => { - self.tlb_clear_entry = (self.tlb_clear_entry & 0xF) | ((data as u16) << 4); + self.tlb_clear_entry = + (self.tlb_clear_entry & 0xF) | (u16::from(data) << 4); } 2 => { self.tlb_clear_entry = - (self.tlb_clear_entry & 0xFF0) | (((data as u16) & 0xF0) >> 4); + (self.tlb_clear_entry & 0xFF0) | ((u16::from(data) & 0xF0) >> 4); } 3 => { if self.print_debug { println!( "Clearing TLB entry {:#x} ( page start {:#x} )", self.tlb_clear_entry, - (self.tlb_clear_entry as u32) << 12 + u32::from(self.tlb_clear_entry) << 12 ); } self.tlb[self.tlb_clear_entry as usize] = 0x0; @@ -164,7 +165,7 @@ impl Mmu for MmuCard { let print_debug = self.print_debug; if self.enabled { if print_debug { - println!("Translating {:#x}", address); + println!("Translating {address:#x}"); } let page = address >> 12; let offset = address & 0xFFF; @@ -192,7 +193,7 @@ impl Mmu for MmuCard { let mapping_hi = backplane.read_word_phys(mapping_address)?; let mapping_lo = backplane.read_word_phys(mapping_address + 2)?; let mapping = - ((mapping_hi as u32) << 16 | mapping_lo as u32) | TLB_MAPPING_FLAG_VALID; + (u32::from(mapping_hi) << 16 | u32::from(mapping_lo)) | TLB_MAPPING_FLAG_VALID; self.tlb[page as usize] = mapping; mapping }; diff --git a/src/peek.rs b/src/peek.rs index f637a2d..48a7860 100644 --- a/src/peek.rs +++ b/src/peek.rs @@ -16,8 +16,8 @@ impl Format { Self::Hex => format!("0x{:0>width$x}", num, width = size.byte_count() * 2), Self::Decimal => { let num = match size { - Size::Byte => num as u8 as i8 as i32, - Size::Word => num as u16 as i16 as i32, + Size::Byte => i32::from(num as u8 as i8), + Size::Word => i32::from(num as u16 as i16), Size::LongWord => num as i32, }; format!("{num}") diff --git a/src/rom.rs b/src/rom.rs index 6ff95ed..ee739ea 100644 --- a/src/rom.rs +++ b/src/rom.rs @@ -77,7 +77,7 @@ impl Card for Rom { match address { (0..=0xEF) => NullableResult::Ok(self.ram[address as usize]), (0xF0..=0xF1) => NullableResult::Ok(u16_get_be_byte(self.start, address - 0xF0)), - 0xF3 => NullableResult::Ok(self.enabled as u8), + 0xF3 => NullableResult::Ok(u8::from(self.enabled)), (0xFE..=0xFF) => NullableResult::Ok(u16_get_be_byte(ID, address - 0xFE)), _ => NullableResult::Null, } @@ -144,7 +144,7 @@ impl Display for Rom { if self.enabled { f.write_fmt(format_args!( ", enabled at base address {:#x}", - (self.start as u32) << 16 + u32::from(self.start) << 16 ))?; }; Ok(()) diff --git a/src/storage.rs b/src/storage.rs index b09b329..e415408 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -102,14 +102,13 @@ impl Card for Storage { 0x9 => match data { 0x0 => { if let Some((file, _)) = &mut self.file { - file.seek(SeekFrom::Start(self.sector as u64 * SECTOR_SIZE)) + file.seek(SeekFrom::Start(u64::from(self.sector) * SECTOR_SIZE)) .unwrap(); - let mut buf = Vec::new(); - buf.resize(self.count as usize * SECTOR_SIZE as usize, 0); + let mut buf = vec![0; self.count as usize * SECTOR_SIZE as usize]; match file.read_exact(&mut buf) { - Ok(_) => (), + Ok(()) => (), Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => (), - Err(e) => Err(e).unwrap(), + Err(e) => panic!("{e:?}"), } self.read_data.extend(buf); self.status.set(Status::DATA_READY, true); @@ -117,14 +116,13 @@ impl Card for Storage { } 0x1 => { if let Some((file, _)) = &mut self.file { - file.seek(SeekFrom::Start(self.sector as u64 * SECTOR_SIZE)) + file.seek(SeekFrom::Start(u64::from(self.sector) * SECTOR_SIZE)) .unwrap(); - let mut buf = Vec::new(); - buf.resize(self.count as usize * SECTOR_SIZE as usize, 0); + let mut buf = vec![0; self.count as usize * SECTOR_SIZE as usize]; match file.read_exact(&mut buf) { - Ok(_) => (), + Ok(()) => (), Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => (), - Err(e) => Err(e).unwrap(), + Err(e) => panic!("{e:?}"), } self.read_data.extend(buf); self.status.set(Status::BUSY, true); diff --git a/src/symbol_table.rs b/src/symbol_table.rs index d78cef7..57ed6ed 100644 --- a/src/symbol_table.rs +++ b/src/symbol_table.rs @@ -81,8 +81,8 @@ impl SymbolTable { self.breakpoints = self .breakpoints .iter() + .filter(|&sym| table.symbols.contains_key(sym)) .cloned() - .filter(|sym| table.symbols.contains_key(sym)) .collect::>(); self.symbols = table.symbols; }