diff --git a/emulator/cpus/m68k/src/decode.rs b/emulator/cpus/m68k/src/decode.rs index 0d087fd..e7c9bbc 100644 --- a/emulator/cpus/m68k/src/decode.rs +++ b/emulator/cpus/m68k/src/decode.rs @@ -1,7 +1,7 @@ -use moa_core::{Error, Address, Addressable}; +use moa_core::{Address, Addressable}; -use crate::state::{M68kType, Exceptions}; +use crate::state::{M68kType, M68kError, Exceptions}; use crate::memory::M68kBusPort; use crate::instructions::{ Size, @@ -66,13 +66,13 @@ impl M68kDecoder { self.end = start; } - pub fn decode_at(&mut self, memory: &mut M68kBusPort, is_supervisor: bool, start: u32) -> Result<(), Error> { + pub fn decode_at(&mut self, memory: &mut M68kBusPort, is_supervisor: bool, start: u32) -> Result<(), M68kError> { self.init(is_supervisor, start); self.instruction = self.decode_next(memory)?; Ok(()) } - pub fn decode_next(&mut self, memory: &mut M68kBusPort) -> Result { + pub fn decode_next(&mut self, memory: &mut M68kBusPort) -> Result { let ins = self.read_instruction_word(memory)?; self.instruction_word = ins; @@ -93,12 +93,12 @@ impl M68kDecoder { OPCG_ADD => self.decode_group_add(memory, ins), OPCG_SHIFT => self.decode_group_shift(memory, ins), OPCG_FLINE => Ok(Instruction::UnimplementedF(ins)), - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } #[inline] - fn decode_group_bit_ops(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_bit_ops(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { let optype = (ins & 0x0F00) >> 8; if (ins & 0x13F) == 0x03C { @@ -109,7 +109,7 @@ impl M68kDecoder { 0b0000 => Ok(Instruction::ORtoCCR(data as u8)), 0b0010 => Ok(Instruction::ANDtoCCR(data as u8)), 0b1010 => Ok(Instruction::EORtoCCR(data as u8)), - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } }, 0b01 => { @@ -118,10 +118,10 @@ impl M68kDecoder { 0b0000 => Ok(Instruction::ORtoSR(data)), 0b0010 => Ok(Instruction::ANDtoSR(data)), 0b1010 => Ok(Instruction::EORtoSR(data)), - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } }, - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } else if (ins & 0x138) == 0x108 { let dreg = get_high_reg(ins); @@ -148,7 +148,7 @@ impl M68kDecoder { 0b01 => Ok(Instruction::BCHG(bitnum, target, size)), 0b10 => Ok(Instruction::BCLR(bitnum, target, size)), 0b11 => Ok(Instruction::BSET(bitnum, target, size)), - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } else { let size = get_size(ins); @@ -156,7 +156,7 @@ impl M68kDecoder { Some(Size::Byte) => self.read_instruction_word(memory)? as u32 & 0xFF, Some(Size::Word) => self.read_instruction_word(memory)? as u32, Some(Size::Long) => self.read_instruction_long(memory)?, - None => return Err(Error::processor(Exceptions::IllegalInstruction as u32)), + None => return Err(M68kError::Exception(Exceptions::IllegalInstruction)), }; let target = self.decode_lower_effective_address(memory, ins, size)?; @@ -167,20 +167,20 @@ impl M68kDecoder { 0b0110 => Ok(Instruction::ADD(Target::Immediate(data), target, size.unwrap())), 0b1010 => Ok(Instruction::EOR(Target::Immediate(data), target, size.unwrap())), 0b1100 => Ok(Instruction::CMP(Target::Immediate(data), target, size.unwrap())), - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } } #[inline] - fn decode_group_move_byte(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_move_byte(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { let src = self.decode_lower_effective_address(memory, ins, Some(Size::Byte))?; let dest = self.decode_upper_effective_address(memory, ins, Some(Size::Byte))?; Ok(Instruction::MOVE(src, dest, Size::Byte)) } #[inline] - fn decode_group_move_long(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_move_long(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { let src = self.decode_lower_effective_address(memory, ins, Some(Size::Long))?; let dest = self.decode_upper_effective_address(memory, ins, Some(Size::Long))?; if let Target::DirectAReg(reg) = dest { @@ -191,7 +191,7 @@ impl M68kDecoder { } #[inline] - fn decode_group_move_word(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_move_word(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { let src = self.decode_lower_effective_address(memory, ins, Some(Size::Word))?; let dest = self.decode_upper_effective_address(memory, ins, Some(Size::Word))?; if let Target::DirectAReg(reg) = dest { @@ -202,7 +202,7 @@ impl M68kDecoder { } #[inline] - fn decode_group_misc(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_misc(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { let ins_0f00 = ins & 0xF00; let ins_00f0 = ins & 0x0F0; @@ -213,7 +213,7 @@ impl M68kDecoder { Some(Size::Long) if self.cputype >= M68kType::MC68020 => Size::Long, // On the 68000, long words in CHK are not supported, but the opcode maps to the word size instruction Some(Size::Long) => Size::Word, - _ => return Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => return Err(M68kError::Exception(Exceptions::IllegalInstruction)), }; let reg = get_high_reg(ins); @@ -253,7 +253,7 @@ impl M68kDecoder { match get_size(ins) { Some(size) => Ok(Instruction::CLR(target, size)), None if self.cputype >= M68kType::MC68010 => Ok(Instruction::MOVEfromCCR(target)), - None => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + None => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } }, 0b100 => { @@ -268,7 +268,7 @@ impl M68kDecoder { None => Ok(Instruction::MOVEtoSR(target)), } }, - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } else if ins_0f00 == 0x800 || ins_0f00 == 0x900 { let opmode = (ins & 0x01C0) >> 6; @@ -301,7 +301,7 @@ impl M68kDecoder { (0b111, 0b000) => { Ok(Instruction::EXT(get_low_reg(ins), Size::Byte, Size::Long)) }, - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } else if ins_0f00 == 0xA00 { if (ins & 0x0FF) == 0xFC { @@ -360,20 +360,20 @@ impl M68kDecoder { }; let creg = match ins2 & 0xFFF { 0x801 => ControlRegister::VBR, - _ => return Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => return Err(M68kError::Exception(Exceptions::IllegalInstruction)), }; Ok(Instruction::MOVEC(target, creg, dir)) }, - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } } else { - Err(Error::processor(Exceptions::IllegalInstruction as u32)) + Err(M68kError::Exception(Exceptions::IllegalInstruction)) } } #[inline] - fn decode_group_addq_subq(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_addq_subq(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { match get_size(ins) { Some(size) => { let target = self.decode_lower_effective_address(memory, ins, Some(size))?; @@ -411,7 +411,7 @@ impl M68kDecoder { } #[inline] - fn decode_group_branch(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_branch(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { let mut disp = ((ins & 0xFF) as i8) as i32; if disp == 0 { disp = (self.read_instruction_word(memory)? as i16) as i32; @@ -427,9 +427,9 @@ impl M68kDecoder { } #[inline] - fn decode_group_moveq(&mut self, _memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_moveq(&mut self, _memory: &mut M68kBusPort, ins: u16) -> Result { if (ins & 0x0100) != 0 { - return Err(Error::processor(Exceptions::IllegalInstruction as u32)); + return Err(M68kError::Exception(Exceptions::IllegalInstruction)); } let reg = get_high_reg(ins); let data = (ins & 0xFF) as u8; @@ -437,7 +437,7 @@ impl M68kDecoder { } #[inline] - fn decode_group_div_or(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_div_or(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { let size = get_size(ins); if (ins & 0x1F0) == 0x100 { @@ -461,7 +461,7 @@ impl M68kDecoder { } #[inline] - fn decode_group_sub(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_sub(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { let reg = get_high_reg(ins); let dir = (ins & 0x0100) >> 8; let size = get_size(ins); @@ -492,7 +492,7 @@ impl M68kDecoder { } #[inline] - fn decode_group_cmp_eor(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_cmp_eor(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { let reg = get_high_reg(ins); let optype = (ins & 0x0100) >> 8; let size = get_size(ins); @@ -514,12 +514,12 @@ impl M68kDecoder { let target = self.decode_lower_effective_address(memory, ins, Some(size))?; Ok(Instruction::CMPA(target, reg, size)) }, - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } #[inline] - fn decode_group_mul_and(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_mul_and(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { let size = get_size(ins); if (ins & 0b0001_1111_0000) == 0b0001_0000_0000 { @@ -537,7 +537,7 @@ impl M68kDecoder { 0b01000 => Ok(Instruction::EXG(Target::DirectDReg(regx), Target::DirectDReg(regy))), 0b01001 => Ok(Instruction::EXG(Target::DirectAReg(regx), Target::DirectAReg(regy))), 0b10001 => Ok(Instruction::EXG(Target::DirectDReg(regx), Target::DirectAReg(regy))), - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } else if let Some(size) = size { let data_reg = Target::DirectDReg(get_high_reg(ins)); @@ -552,7 +552,7 @@ impl M68kDecoder { } #[inline] - fn decode_group_add(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_add(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { let reg = get_high_reg(ins); let dir = (ins & 0x0100) >> 8; let size = get_size(ins); @@ -582,7 +582,7 @@ impl M68kDecoder { } } - fn decode_group_shift(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { + fn decode_group_shift(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result { match get_size(ins) { Some(size) => { let target = Target::DirectDReg(get_low_reg(ins)); @@ -599,7 +599,7 @@ impl M68kDecoder { 0b01 => Ok(Instruction::LSR(count, target, size)), 0b10 => Ok(Instruction::ROXR(count, target, size)), 0b11 => Ok(Instruction::ROR(count, target, size)), - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } else { match (ins & 0x0018) >> 3 { @@ -607,7 +607,7 @@ impl M68kDecoder { 0b01 => Ok(Instruction::LSL(count, target, size)), 0b10 => Ok(Instruction::ROXL(count, target, size)), 0b11 => Ok(Instruction::ROL(count, target, size)), - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } }, @@ -623,7 +623,7 @@ impl M68kDecoder { 0b01 => Ok(Instruction::LSR(count, target, size)), 0b10 => Ok(Instruction::ROXR(count, target, size)), 0b11 => Ok(Instruction::ROR(count, target, size)), - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } else { match (ins & 0x0600) >> 9 { @@ -631,7 +631,7 @@ impl M68kDecoder { 0b01 => Ok(Instruction::LSL(count, target, size)), 0b10 => Ok(Instruction::ROXL(count, target, size)), 0b11 => Ok(Instruction::ROL(count, target, size)), - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } } else if self.cputype > M68kType::MC68020 { @@ -659,50 +659,50 @@ impl M68kDecoder { 0b111 => Ok(Instruction::BFINS(reg, target, offset, width)), 0b110 => Ok(Instruction::BFSET(target, offset, width)), 0b000 => Ok(Instruction::BFTST(target, offset, width)), - _ => Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => Err(M68kError::Exception(Exceptions::IllegalInstruction)), } } else { - Err(Error::processor(Exceptions::IllegalInstruction as u32)) + Err(M68kError::Exception(Exceptions::IllegalInstruction)) } }, } } - fn read_instruction_word(&mut self, memory: &mut M68kBusPort) -> Result { + fn read_instruction_word(&mut self, memory: &mut M68kBusPort) -> Result { let word = memory.read_instruction_word(self.is_supervisor, self.end)?; self.end += 2; Ok(word) } - fn read_instruction_long(&mut self, memory: &mut M68kBusPort) -> Result { + fn read_instruction_long(&mut self, memory: &mut M68kBusPort) -> Result { let word = memory.read_instruction_long(self.is_supervisor, self.end)?; self.end += 4; Ok(word) } - fn decode_lower_effective_address(&mut self, memory: &mut M68kBusPort, ins: u16, size: Option) -> Result { + fn decode_lower_effective_address(&mut self, memory: &mut M68kBusPort, ins: u16, size: Option) -> Result { let reg = get_low_reg(ins); let mode = get_low_mode(ins); self.get_mode_as_target(memory, mode, reg, size) } - fn decode_upper_effective_address(&mut self, memory: &mut M68kBusPort, ins: u16, size: Option) -> Result { + fn decode_upper_effective_address(&mut self, memory: &mut M68kBusPort, ins: u16, size: Option) -> Result { let reg = get_high_reg(ins); let mode = get_high_mode(ins); self.get_mode_as_target(memory, mode, reg, size) } - fn get_extension_displacement(&mut self, memory: &mut M68kBusPort, select: u16) -> Result { + fn get_extension_displacement(&mut self, memory: &mut M68kBusPort, select: u16) -> Result { let result = match select { 0b00 | 0b01 => 0, 0b10 => sign_extend_to_long(self.read_instruction_word(memory)? as u32, Size::Word), 0b11 => self.read_instruction_long(memory)? as i32, - _ => return Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => return Err(M68kError::Exception(Exceptions::IllegalInstruction)), }; Ok(result) } - fn decode_extension_word(&mut self, memory: &mut M68kBusPort, areg: Option) -> Result { + fn decode_extension_word(&mut self, memory: &mut M68kBusPort, areg: Option) -> Result { let brief_extension = self.read_instruction_word(memory)?; let use_brief = (brief_extension & 0x0100) == 0; @@ -755,7 +755,7 @@ impl M68kDecoder { } } - pub(super) fn get_mode_as_target(&mut self, memory: &mut M68kBusPort, mode: u8, reg: u8, size: Option) -> Result { + pub(super) fn get_mode_as_target(&mut self, memory: &mut M68kBusPort, mode: u8, reg: u8, size: Option) -> Result { let value = match mode { 0b000 => Target::DirectDReg(reg), 0b001 => Target::DirectAReg(reg), @@ -790,14 +790,14 @@ impl M68kDecoder { let data = match size { Some(Size::Byte) | Some(Size::Word) => self.read_instruction_word(memory)? as u32, Some(Size::Long) => self.read_instruction_long(memory)?, - None => return Err(Error::processor(Exceptions::IllegalInstruction as u32)), + None => return Err(M68kError::Exception(Exceptions::IllegalInstruction)), }; Target::Immediate(data) }, - _ => return Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => return Err(M68kError::Exception(Exceptions::IllegalInstruction)), } }, - _ => return Err(Error::processor(Exceptions::IllegalInstruction as u32)), + _ => return Err(M68kError::Exception(Exceptions::IllegalInstruction)), }; Ok(value) } @@ -813,7 +813,7 @@ impl M68kDecoder { Err(err) => { println!("{:?}", err); match err { - Error::Processor(native) if native == Exceptions::IllegalInstruction as u32 => { + M68kError::Exception(ex) if ex == Exceptions::IllegalInstruction => { println!(" at {:08x}: {:04x}", self.start, memory.port.read_beu16(memory.current_clock, self.start as Address).unwrap()); }, _ => { }, @@ -825,7 +825,7 @@ impl M68kDecoder { } pub fn dump_decoded(&mut self, memory: &mut M68kBusPort) { - let ins_data: Result = + let ins_data: Result = (0..((self.end - self.start) / 2)).map(|offset| Ok(format!("{:04x} ", memory.port.read_beu16(memory.current_clock, (self.start + (offset * 2)) as Address).unwrap())) ).collect(); diff --git a/emulator/cpus/m68k/src/execute.rs b/emulator/cpus/m68k/src/execute.rs index 6e54d40..76d5db2 100644 --- a/emulator/cpus/m68k/src/execute.rs +++ b/emulator/cpus/m68k/src/execute.rs @@ -3,7 +3,7 @@ use femtos::{Instant, Duration}; use moa_core::{System, Error, Address, Steppable, Interruptable, Addressable, Debuggable, Transmutable}; -use crate::state::{M68k, M68kType, ClockCycles, Status, Flags, Exceptions, InterruptPriority}; +use crate::state::{M68k, M68kType, M68kError, ClockCycles, Status, Flags, Exceptions, InterruptPriority}; use crate::memory::{MemType, MemAccess}; use crate::decode::M68kDecoder; use crate::timing::M68kInstructionTiming; @@ -59,18 +59,44 @@ impl Transmutable for M68k { } } +impl From for Error { + fn from(err: M68kError) -> Self { + match err { + M68kError::Halted => Self::Other("cpu halted".to_string()), + M68kError::Exception(ex) => Self::Processor(ex as u32), + M68kError::Interrupt(num) => Self::Processor(num as u32), + M68kError::Breakpoint => Self::Breakpoint("breakpoint".to_string()), + M68kError::InvalidTarget(target) => Self::new(target.to_string()), + M68kError::Other(msg) => Self::Other(msg), + } + } +} + +impl From for M68kError { + fn from(err: Error) -> Self { + match err { + Error::Processor(ex) => M68kError::Interrupt(ex as u8), + Error::Breakpoint(msg) => M68kError::Breakpoint, + Error::Other(msg) | Error::Assertion(msg) | Error::Emulator(_, msg) => M68kError::Other(format!("{}", msg)), + } + } +} impl M68k { - pub fn step_internal(&mut self, system: &System) -> Result { + pub fn step_internal(&mut self, system: &System) -> Result { self.init_cycle(system.clock); match self.state.status { Status::Init => self.reset_cpu(), - Status::Stopped => Err(Error::new("CPU stopped")), + Status::Stopped => Err(M68kError::Halted), Status::Running => { match self.cycle_one(system) { Ok(diff) => Ok(diff), - Err(Error::Processor(native)) => { - self.exception(native as u8, false)?; + Err(M68kError::Exception(ex)) => { + self.exception(ex as u8, false)?; + Ok(4) + }, + Err(M68kError::Interrupt(ex)) => { + self.exception(ex as u8, false)?; Ok(4) }, Err(err) => Err(err), @@ -87,14 +113,14 @@ impl M68k { self.timing.reset(); } - pub fn reset_cpu(&mut self) -> Result { + pub fn reset_cpu(&mut self) -> Result { self.state.ssp = self.get_address_sized(0, Size::Long)?; self.state.pc = self.get_address_sized(4, Size::Long)?; self.state.status = Status::Running; Ok(16) } - pub fn cycle_one(&mut self, system: &System) -> Result { + pub fn cycle_one(&mut self, system: &System) -> Result { self.check_breakpoints()?; self.decode_next()?; @@ -104,7 +130,7 @@ impl M68k { Ok(self.timing.calculate_clocks(false, 1)) } - pub fn check_pending_interrupts(&mut self, system: &System) -> Result<(), Error> { + pub fn check_pending_interrupts(&mut self, system: &System) -> Result<(), M68kError> { self.state.pending_ipl = match system.get_interrupt_controller().check() { (true, priority) => InterruptPriority::from_u8(priority), (false, _) => InterruptPriority::NoInterrupt, @@ -132,7 +158,7 @@ impl M68k { Ok(()) } - pub fn exception(&mut self, number: u8, is_interrupt: bool) -> Result<(), Error> { + pub fn exception(&mut self, number: u8, is_interrupt: bool) -> Result<(), M68kError> { log::debug!("{}: raising exception {}", DEV_NAME, number); if number == Exceptions::BusError as u8 || number == Exceptions::AddressError as u8 { @@ -148,7 +174,7 @@ impl M68k { Ok(()) } - pub fn setup_group0_exception(&mut self, number: u8) -> Result<(), Error> { + pub fn setup_group0_exception(&mut self, number: u8) -> Result<(), M68kError> { let sr = self.state.sr; let ins_word = self.decoder.instruction_word; let extra_code = self.port.request.get_type_code(); @@ -177,7 +203,7 @@ impl M68k { Ok(()) } - pub fn setup_normal_exception(&mut self, number: u8, is_interrupt: bool) -> Result<(), Error> { + pub fn setup_normal_exception(&mut self, number: u8, is_interrupt: bool) -> Result<(), M68kError> { let sr = self.state.sr; self.port.request.i_n_bit = true; @@ -202,7 +228,7 @@ impl M68k { Ok(()) } - pub fn decode_next(&mut self) -> Result<(), Error> { + pub fn decode_next(&mut self) -> Result<(), M68kError> { let is_supervisor = self.is_supervisor(); self.decoder.decode_at(&mut self.port, is_supervisor, self.state.pc)?; @@ -213,7 +239,7 @@ impl M68k { Ok(()) } - pub fn execute_current(&mut self) -> Result<(), Error> { + pub fn execute_current(&mut self) -> Result<(), M68kError> { match self.decoder.instruction { Instruction::ABCD(src, dest) => self.execute_abcd(src, dest), Instruction::ADD(src, dest, size) => self.execute_add(src, dest, size), @@ -303,13 +329,13 @@ impl M68k { Instruction::UNLK(reg) => self.execute_unlk(reg), Instruction::UnimplementedA(value) => self.execute_unimplemented_a(value), Instruction::UnimplementedF(value) => self.execute_unimplemented_f(value), - _ => { return Err(Error::new("Unsupported instruction")); }, + _ => { return Err(M68kError::Other("Unsupported instruction".to_string())); }, }?; Ok(()) } - fn execute_abcd(&mut self, src: Target, dest: Target) -> Result<(), Error> { + fn execute_abcd(&mut self, src: Target, dest: Target) -> Result<(), M68kError> { let src_val = self.get_target_value(src, Size::Byte, Used::Once)?; let dest_val = self.get_target_value(dest, Size::Byte, Used::Twice)?; @@ -333,7 +359,7 @@ impl M68k { Ok(()) } - fn execute_add(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> { + fn execute_add(&mut self, src: Target, dest: Target, size: Size) -> Result<(), M68kError> { let src_val = self.get_target_value(src, size, Used::Once)?; let dest_val = self.get_target_value(dest, size, Used::Twice)?; let (result, carry) = overflowing_add_sized(dest_val, src_val, size); @@ -344,7 +370,7 @@ impl M68k { Ok(()) } - fn execute_adda(&mut self, src: Target, dest: Register, size: Size) -> Result<(), Error> { + fn execute_adda(&mut self, src: Target, dest: Register, size: Size) -> Result<(), M68kError> { let src_val = sign_extend_to_long(self.get_target_value(src, size, Used::Once)?, size) as u32; let dest_val = *self.get_a_reg_mut(dest); let (result, _) = overflowing_add_sized(dest_val, src_val, Size::Long); @@ -352,7 +378,7 @@ impl M68k { Ok(()) } - fn execute_addx(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> { + fn execute_addx(&mut self, src: Target, dest: Target, size: Size) -> Result<(), M68kError> { let src_val = self.get_target_value(src, size, Used::Once)?; let dest_val = self.get_target_value(dest, size, Used::Twice)?; let extend = self.get_flag(Flags::Extend) as u32; @@ -373,7 +399,7 @@ impl M68k { Ok(()) } - fn execute_and(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> { + fn execute_and(&mut self, src: Target, dest: Target, size: Size) -> Result<(), M68kError> { let src_val = self.get_target_value(src, size, Used::Once)?; let dest_val = self.get_target_value(dest, size, Used::Twice)?; let result = get_value_sized(dest_val & src_val, size); @@ -382,18 +408,18 @@ impl M68k { Ok(()) } - fn execute_and_to_ccr(&mut self, value: u8) -> Result<(), Error> { + fn execute_and_to_ccr(&mut self, value: u8) -> Result<(), M68kError> { self.state.sr = (self.state.sr & 0xFF00) | ((self.state.sr & 0x00FF) & (value as u16)); Ok(()) } - fn execute_and_to_sr(&mut self, value: u16) -> Result<(), Error> { + fn execute_and_to_sr(&mut self, value: u16) -> Result<(), M68kError> { self.require_supervisor()?; self.set_sr(self.state.sr & value); Ok(()) } - fn execute_asl(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_asl(&mut self, count: Target, target: Target, size: Size) -> Result<(), M68kError> { let count = self.get_target_value(count, size, Used::Once)? % 64; let value = self.get_target_value(target, size, Used::Twice)?; @@ -413,7 +439,7 @@ impl M68k { Ok(()) } - fn execute_asr(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_asr(&mut self, count: Target, target: Target, size: Size) -> Result<(), M68kError> { let count = self.get_target_value(count, size, Used::Once)? % 64; let value = self.get_target_value(target, size, Used::Twice)?; @@ -446,7 +472,7 @@ impl M68k { } } - fn execute_bcc(&mut self, cond: Condition, offset: i32) -> Result<(), Error> { + fn execute_bcc(&mut self, cond: Condition, offset: i32) -> Result<(), M68kError> { let should_branch = self.get_current_condition(cond); if should_branch { if let Err(err) = self.set_pc(self.decoder.start.wrapping_add(2).wrapping_add(offset as u32)) { @@ -457,7 +483,7 @@ impl M68k { Ok(()) } - fn execute_bra(&mut self, offset: i32) -> Result<(), Error> { + fn execute_bra(&mut self, offset: i32) -> Result<(), M68kError> { if let Err(err) = self.set_pc(self.decoder.start.wrapping_add(2).wrapping_add(offset as u32)) { self.state.pc -= 2; return Err(err); @@ -465,7 +491,7 @@ impl M68k { Ok(()) } - fn execute_bsr(&mut self, offset: i32) -> Result<(), Error> { + fn execute_bsr(&mut self, offset: i32) -> Result<(), M68kError> { self.push_long(self.state.pc)?; let sp = *self.get_stack_pointer_mut(); self.debugger.stack_tracer.push_return(sp); @@ -476,7 +502,7 @@ impl M68k { Ok(()) } - fn execute_bchg(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_bchg(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), M68kError> { let bitnum = self.get_target_value(bitnum, Size::Byte, Used::Once)?; let mut src_val = self.get_target_value(target, size, Used::Twice)?; let mask = self.set_bit_test_flags(src_val, bitnum, size); @@ -485,7 +511,7 @@ impl M68k { Ok(()) } - fn execute_bclr(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_bclr(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), M68kError> { let bitnum = self.get_target_value(bitnum, Size::Byte, Used::Once)?; let mut src_val = self.get_target_value(target, size, Used::Twice)?; let mask = self.set_bit_test_flags(src_val, bitnum, size); @@ -494,7 +520,7 @@ impl M68k { Ok(()) } - fn execute_bset(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_bset(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), M68kError> { let bitnum = self.get_target_value(bitnum, Size::Byte, Used::Once)?; let mut value = self.get_target_value(target, size, Used::Twice)?; let mask = self.set_bit_test_flags(value, bitnum, size); @@ -503,14 +529,14 @@ impl M68k { Ok(()) } - fn execute_btst(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_btst(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), M68kError> { let bitnum = self.get_target_value(bitnum, Size::Byte, Used::Once)?; let value = self.get_target_value(target, size, Used::Once)?; self.set_bit_test_flags(value, bitnum, size); Ok(()) } - fn execute_bfchg(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), Error> { + fn execute_bfchg(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), M68kError> { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); let value = self.get_target_value(target, Size::Long, Used::Twice)?; @@ -520,7 +546,7 @@ impl M68k { Ok(()) } - fn execute_bfclr(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), Error> { + fn execute_bfclr(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), M68kError> { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); let value = self.get_target_value(target, Size::Long, Used::Twice)?; @@ -530,7 +556,7 @@ impl M68k { Ok(()) } - fn execute_bfexts(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate, reg: Register) -> Result<(), Error> { + fn execute_bfexts(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate, reg: Register) -> Result<(), M68kError> { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); let value = self.get_target_value(target, Size::Long, Used::Once)?; @@ -546,7 +572,7 @@ impl M68k { Ok(()) } - fn execute_bfextu(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate, reg: Register) -> Result<(), Error> { + fn execute_bfextu(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate, reg: Register) -> Result<(), M68kError> { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); let value = self.get_target_value(target, Size::Long, Used::Once)?; @@ -556,7 +582,7 @@ impl M68k { Ok(()) } - fn execute_bfset(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), Error> { + fn execute_bfset(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), M68kError> { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); let value = self.get_target_value(target, Size::Long, Used::Twice)?; @@ -566,7 +592,7 @@ impl M68k { Ok(()) } - fn execute_bftst(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), Error> { + fn execute_bftst(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), M68kError> { let (offset, width) = self.get_bit_field_args(offset, width); let mask = get_bit_field_mask(offset, width); let value = self.get_target_value(target, Size::Long, Used::Once)?; @@ -575,7 +601,7 @@ impl M68k { Ok(()) } - fn execute_chk(&mut self, target: Target, reg: Register, size: Size) -> Result<(), Error> { + fn execute_chk(&mut self, target: Target, reg: Register, size: Size) -> Result<(), M68kError> { let upper_bound = sign_extend_to_long(self.get_target_value(target, size, Used::Once)?, size); let dreg = sign_extend_to_long(self.state.d_reg[reg as usize], size); @@ -591,7 +617,7 @@ impl M68k { Ok(()) } - fn execute_clr(&mut self, target: Target, size: Size) -> Result<(), Error> { + fn execute_clr(&mut self, target: Target, size: Size) -> Result<(), M68kError> { if self.cputype == M68kType::MC68000 { self.get_target_value(target, size, Used::Twice)?; self.set_target_value(target, 0, size, Used::Twice)?; @@ -603,7 +629,7 @@ impl M68k { Ok(()) } - fn execute_cmp(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> { + fn execute_cmp(&mut self, src: Target, dest: Target, size: Size) -> Result<(), M68kError> { let src_val = self.get_target_value(src, size, Used::Once)?; let dest_val = self.get_target_value(dest, size, Used::Once)?; let (result, carry) = overflowing_sub_sized(dest_val, src_val, size); @@ -612,7 +638,7 @@ impl M68k { Ok(()) } - fn execute_cmpa(&mut self, src: Target, reg: Register, size: Size) -> Result<(), Error> { + fn execute_cmpa(&mut self, src: Target, reg: Register, size: Size) -> Result<(), M68kError> { let src_val = sign_extend_to_long(self.get_target_value(src, size, Used::Once)?, size) as u32; let dest_val = *self.get_a_reg_mut(reg); let (result, carry) = overflowing_sub_sized(dest_val, src_val, Size::Long); @@ -621,7 +647,7 @@ impl M68k { Ok(()) } - fn execute_dbcc(&mut self, cond: Condition, reg: Register, offset: i16) -> Result<(), Error> { + fn execute_dbcc(&mut self, cond: Condition, reg: Register, offset: i16) -> Result<(), M68kError> { let condition_true = self.get_current_condition(cond); if !condition_true { let next = ((get_value_sized(self.state.d_reg[reg as usize], Size::Word) as u16) as i16).wrapping_sub(1); @@ -636,7 +662,7 @@ impl M68k { Ok(()) } - fn execute_divw(&mut self, src: Target, dest: Register, sign: Sign) -> Result<(), Error> { + fn execute_divw(&mut self, src: Target, dest: Register, sign: Sign) -> Result<(), M68kError> { let src_val = self.get_target_value(src, Size::Word, Used::Once)?; if src_val == 0 { self.exception(Exceptions::ZeroDivide as u8, false)?; @@ -676,7 +702,7 @@ impl M68k { Ok(()) } - fn execute_divl(&mut self, src: Target, dest_h: Option, dest_l: Register, sign: Sign) -> Result<(), Error> { + fn execute_divl(&mut self, src: Target, dest_h: Option, dest_l: Register, sign: Sign) -> Result<(), M68kError> { let src_val = self.get_target_value(src, Size::Long, Used::Once)?; if src_val == 0 { self.exception(Exceptions::ZeroDivide as u8, false)?; @@ -709,7 +735,7 @@ impl M68k { Ok(()) } - fn execute_eor(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> { + fn execute_eor(&mut self, src: Target, dest: Target, size: Size) -> Result<(), M68kError> { let src_val = self.get_target_value(src, size, Used::Once)?; let dest_val = self.get_target_value(dest, size, Used::Twice)?; let result = get_value_sized(dest_val ^ src_val, size); @@ -718,18 +744,18 @@ impl M68k { Ok(()) } - fn execute_eor_to_ccr(&mut self, value: u8) -> Result<(), Error> { + fn execute_eor_to_ccr(&mut self, value: u8) -> Result<(), M68kError> { self.set_sr((self.state.sr & 0xFF00) | ((self.state.sr & 0x00FF) ^ (value as u16))); Ok(()) } - fn execute_eor_to_sr(&mut self, value: u16) -> Result<(), Error> { + fn execute_eor_to_sr(&mut self, value: u16) -> Result<(), M68kError> { self.require_supervisor()?; self.set_sr(self.state.sr ^ value); Ok(()) } - fn execute_exg(&mut self, target1: Target, target2: Target) -> Result<(), Error> { + fn execute_exg(&mut self, target1: Target, target2: Target) -> Result<(), M68kError> { let value1 = self.get_target_value(target1, Size::Long, Used::Twice)?; let value2 = self.get_target_value(target2, Size::Long, Used::Twice)?; self.set_target_value(target1, value2, Size::Long, Used::Twice)?; @@ -737,7 +763,7 @@ impl M68k { Ok(()) } - fn execute_ext(&mut self, reg: Register, from_size: Size, to_size: Size) -> Result<(), Error> { + fn execute_ext(&mut self, reg: Register, from_size: Size, to_size: Size) -> Result<(), M68kError> { let input = get_value_sized(self.state.d_reg[reg as usize], from_size); let result = match (from_size, to_size) { (Size::Byte, Size::Word) => ((((input as u8) as i8) as i16) as u16) as u32, @@ -750,12 +776,12 @@ impl M68k { Ok(()) } - fn execute_illegal(&mut self) -> Result<(), Error> { + fn execute_illegal(&mut self) -> Result<(), M68kError> { self.exception(Exceptions::IllegalInstruction as u8, false)?; Ok(()) } - fn execute_jmp(&mut self, target: Target) -> Result<(), Error> { + fn execute_jmp(&mut self, target: Target) -> Result<(), M68kError> { let addr = self.get_target_address(target)?; if let Err(err) = self.set_pc(addr) { self.state.pc -= 2; @@ -764,7 +790,7 @@ impl M68k { Ok(()) } - fn execute_jsr(&mut self, target: Target) -> Result<(), Error> { + fn execute_jsr(&mut self, target: Target) -> Result<(), M68kError> { let previous_pc = self.state.pc; let addr = self.get_target_address(target)?; if let Err(err) = self.set_pc(addr) { @@ -779,14 +805,14 @@ impl M68k { Ok(()) } - fn execute_lea(&mut self, target: Target, reg: Register) -> Result<(), Error> { + fn execute_lea(&mut self, target: Target, reg: Register) -> Result<(), M68kError> { let value = self.get_target_address(target)?; let addr = self.get_a_reg_mut(reg); *addr = value; Ok(()) } - fn execute_link(&mut self, reg: Register, offset: i32) -> Result<(), Error> { + fn execute_link(&mut self, reg: Register, offset: i32) -> Result<(), M68kError> { *self.get_stack_pointer_mut() -= 4; let sp = *self.get_stack_pointer_mut(); let value = *self.get_a_reg_mut(reg); @@ -796,7 +822,7 @@ impl M68k { Ok(()) } - fn execute_lsl(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_lsl(&mut self, count: Target, target: Target, size: Size) -> Result<(), M68kError> { let count = self.get_target_value(count, size, Used::Once)? % 64; let mut pair = (self.get_target_value(target, size, Used::Twice)?, false); for _ in 0..count { @@ -808,7 +834,7 @@ impl M68k { Ok(()) } - fn execute_lsr(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_lsr(&mut self, count: Target, target: Target, size: Size) -> Result<(), M68kError> { let count = self.get_target_value(count, size, Used::Once)? % 64; let mut pair = (self.get_target_value(target, size, Used::Twice)?, false); for _ in 0..count { @@ -831,14 +857,14 @@ impl M68k { } } - fn execute_move(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> { + fn execute_move(&mut self, src: Target, dest: Target, size: Size) -> Result<(), M68kError> { let src_val = self.get_target_value(src, size, Used::Once)?; self.set_logic_flags(src_val, size); self.set_target_value(dest, src_val, size, Used::Once)?; Ok(()) } - fn execute_movea(&mut self, src: Target, reg: Register, size: Size) -> Result<(), Error> { + fn execute_movea(&mut self, src: Target, reg: Register, size: Size) -> Result<(), M68kError> { let src_val = self.get_target_value(src, size, Used::Once)?; let src_val = sign_extend_to_long(src_val, size) as u32; let addr = self.get_a_reg_mut(reg); @@ -846,26 +872,26 @@ impl M68k { Ok(()) } - fn execute_move_from_sr(&mut self, target: Target) -> Result<(), Error> { + fn execute_move_from_sr(&mut self, target: Target) -> Result<(), M68kError> { self.require_supervisor()?; self.set_target_value(target, self.state.sr as u32, Size::Word, Used::Once)?; Ok(()) } - fn execute_move_to_sr(&mut self, target: Target) -> Result<(), Error> { + fn execute_move_to_sr(&mut self, target: Target) -> Result<(), M68kError> { self.require_supervisor()?; let value = self.get_target_value(target, Size::Word, Used::Once)? as u16; self.set_sr(value); Ok(()) } - fn execute_move_to_ccr(&mut self, target: Target) -> Result<(), Error> { + fn execute_move_to_ccr(&mut self, target: Target) -> Result<(), M68kError> { let value = self.get_target_value(target, Size::Word, Used::Once)? as u16; self.set_sr((self.state.sr & 0xFF00) | (value & 0x00FF)); Ok(()) } - fn execute_movec(&mut self, target: Target, control_reg: ControlRegister, dir: Direction) -> Result<(), Error> { + fn execute_movec(&mut self, target: Target, control_reg: ControlRegister, dir: Direction) -> Result<(), M68kError> { self.require_supervisor()?; match dir { Direction::FromTarget => { @@ -882,7 +908,7 @@ impl M68k { Ok(()) } - fn execute_movem(&mut self, target: Target, size: Size, dir: Direction, mask: u16) -> Result<(), Error> { + fn execute_movem(&mut self, target: Target, size: Size, dir: Direction, mask: u16) -> Result<(), M68kError> { let addr = self.get_target_address(target)?; // If we're using a MC68020 or higher, and it was Post-Inc/Pre-Dec target, then update the value before it's stored @@ -899,13 +925,13 @@ impl M68k { let post_addr = match target { Target::IndirectARegInc(_) => { if dir != Direction::FromTarget { - return Err(Error::new(format!("Cannot use {:?} with {:?}", target, dir))); + return Err(M68kError::Other(format!("Cannot use {:?} with {:?}", target, dir))); } self.move_memory_to_registers(addr, size, mask)? }, Target::IndirectARegDec(_) => { if dir != Direction::ToTarget { - return Err(Error::new(format!("Cannot use {:?} with {:?}", target, dir))); + return Err(M68kError::Other(format!("Cannot use {:?} with {:?}", target, dir))); } self.move_registers_to_memory_reverse(addr, size, mask)? }, @@ -929,7 +955,7 @@ impl M68k { Ok(()) } - fn move_memory_to_registers(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result { + fn move_memory_to_registers(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result { for i in 0..8 { if (mask & 0x01) != 0 { self.state.d_reg[i] = sign_extend_to_long(self.get_address_sized(addr as Address, size)?, size) as u32; @@ -947,7 +973,7 @@ impl M68k { Ok(addr) } - fn move_registers_to_memory(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result { + fn move_registers_to_memory(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result { for i in 0..8 { if (mask & 0x01) != 0 { self.set_address_sized(addr as Address, self.state.d_reg[i], size)?; @@ -966,7 +992,7 @@ impl M68k { Ok(addr) } - fn move_registers_to_memory_reverse(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result { + fn move_registers_to_memory_reverse(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result { for i in (0..8).rev() { if (mask & 0x01) != 0 { let value = *self.get_a_reg_mut(i); @@ -985,7 +1011,7 @@ impl M68k { Ok(addr) } - fn execute_movep(&mut self, dreg: Register, areg: Register, offset: i16, size: Size, dir: Direction) -> Result<(), Error> { + fn execute_movep(&mut self, dreg: Register, areg: Register, offset: i16, size: Size, dir: Direction) -> Result<(), M68kError> { match dir { Direction::ToTarget => { let mut shift = (size.in_bits() as i32) - 8; @@ -1011,14 +1037,14 @@ impl M68k { Ok(()) } - fn execute_moveq(&mut self, data: u8, reg: Register) -> Result<(), Error> { + fn execute_moveq(&mut self, data: u8, reg: Register) -> Result<(), M68kError> { let value = sign_extend_to_long(data as u32, Size::Byte) as u32; self.state.d_reg[reg as usize] = value; self.set_logic_flags(value, Size::Long); Ok(()) } - fn execute_moveusp(&mut self, target: Target, dir: Direction) -> Result<(), Error> { + fn execute_moveusp(&mut self, target: Target, dir: Direction) -> Result<(), M68kError> { self.require_supervisor()?; match dir { Direction::ToTarget => self.set_target_value(target, self.state.usp, Size::Long, Used::Once)?, @@ -1027,7 +1053,7 @@ impl M68k { Ok(()) } - fn execute_mulw(&mut self, src: Target, dest: Register, sign: Sign) -> Result<(), Error> { + fn execute_mulw(&mut self, src: Target, dest: Register, sign: Sign) -> Result<(), M68kError> { let src_val = self.get_target_value(src, Size::Word, Used::Once)?; let dest_val = get_value_sized(self.state.d_reg[dest as usize], Size::Word); let result = match sign { @@ -1040,7 +1066,7 @@ impl M68k { Ok(()) } - fn execute_mull(&mut self, src: Target, dest_h: Option, dest_l: Register, sign: Sign) -> Result<(), Error> { + fn execute_mull(&mut self, src: Target, dest_h: Option, dest_l: Register, sign: Sign) -> Result<(), M68kError> { let src_val = self.get_target_value(src, Size::Long, Used::Once)?; let dest_val = get_value_sized(self.state.d_reg[dest_l as usize], Size::Long); let result = match sign { @@ -1056,14 +1082,14 @@ impl M68k { Ok(()) } - fn execute_nbcd(&mut self, dest: Target) -> Result<(), Error> { + fn execute_nbcd(&mut self, dest: Target) -> Result<(), M68kError> { let dest_val = self.get_target_value(dest, Size::Byte, Used::Twice)?; let result = self.execute_sbcd_val(dest_val, 0)?; self.set_target_value(dest, result, Size::Byte, Used::Twice)?; Ok(()) } - fn execute_neg(&mut self, target: Target, size: Size) -> Result<(), Error> { + fn execute_neg(&mut self, target: Target, size: Size) -> Result<(), M68kError> { let original = self.get_target_value(target, size, Used::Twice)?; let (result, overflow) = overflowing_sub_signed_sized(0, original, size); let carry = result != 0; @@ -1073,7 +1099,7 @@ impl M68k { Ok(()) } - fn execute_negx(&mut self, dest: Target, size: Size) -> Result<(), Error> { + fn execute_negx(&mut self, dest: Target, size: Size) -> Result<(), M68kError> { let dest_val = self.get_target_value(dest, size, Used::Twice)?; let extend = self.get_flag(Flags::Extend) as u32; let (result1, carry1) = overflowing_sub_sized(0, dest_val, size); @@ -1093,7 +1119,7 @@ impl M68k { Ok(()) } - fn execute_not(&mut self, target: Target, size: Size) -> Result<(), Error> { + fn execute_not(&mut self, target: Target, size: Size) -> Result<(), M68kError> { let mut value = self.get_target_value(target, size, Used::Twice)?; value = get_value_sized(!value, size); self.set_target_value(target, value, size, Used::Twice)?; @@ -1101,7 +1127,7 @@ impl M68k { Ok(()) } - fn execute_or(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> { + fn execute_or(&mut self, src: Target, dest: Target, size: Size) -> Result<(), M68kError> { let src_val = self.get_target_value(src, size, Used::Once)?; let dest_val = self.get_target_value(dest, size, Used::Twice)?; let result = get_value_sized(dest_val | src_val, size); @@ -1110,30 +1136,30 @@ impl M68k { Ok(()) } - fn execute_or_to_ccr(&mut self, value: u8) -> Result<(), Error> { + fn execute_or_to_ccr(&mut self, value: u8) -> Result<(), M68kError> { self.set_sr((self.state.sr & 0xFF00) | ((self.state.sr & 0x00FF) | (value as u16))); Ok(()) } - fn execute_or_to_sr(&mut self, value: u16) -> Result<(), Error> { + fn execute_or_to_sr(&mut self, value: u16) -> Result<(), M68kError> { self.require_supervisor()?; self.set_sr(self.state.sr | value); Ok(()) } - fn execute_pea(&mut self, target: Target) -> Result<(), Error> { + fn execute_pea(&mut self, target: Target) -> Result<(), M68kError> { let value = self.get_target_address(target)?; self.push_long(value)?; Ok(()) } - fn execute_reset(&mut self) -> Result<(), Error> { + fn execute_reset(&mut self) -> Result<(), M68kError> { self.require_supervisor()?; // TODO this only resets external devices and not internal ones Ok(()) } - fn execute_rol(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_rol(&mut self, count: Target, target: Target, size: Size) -> Result<(), M68kError> { let count = self.get_target_value(count, size, Used::Once)? % 64; let mut pair = (self.get_target_value(target, size, Used::Twice)?, false); for _ in 0..count { @@ -1144,7 +1170,7 @@ impl M68k { Ok(()) } - fn execute_ror(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_ror(&mut self, count: Target, target: Target, size: Size) -> Result<(), M68kError> { let count = self.get_target_value(count, size, Used::Once)? % 64; let mut pair = (self.get_target_value(target, size, Used::Twice)?, false); for _ in 0..count { @@ -1155,7 +1181,7 @@ impl M68k { Ok(()) } - fn execute_roxl(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_roxl(&mut self, count: Target, target: Target, size: Size) -> Result<(), M68kError> { let count = self.get_target_value(count, size, Used::Once)? % 64; let mut pair = (self.get_target_value(target, size, Used::Twice)?, false); for _ in 0..count { @@ -1167,7 +1193,7 @@ impl M68k { Ok(()) } - fn execute_roxr(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> { + fn execute_roxr(&mut self, count: Target, target: Target, size: Size) -> Result<(), M68kError> { let count = self.get_target_value(count, size, Used::Once)? % 64; let mut pair = (self.get_target_value(target, size, Used::Twice)?, false); for _ in 0..count { @@ -1186,7 +1212,7 @@ impl M68k { } } - fn execute_rte(&mut self) -> Result<(), Error> { + fn execute_rte(&mut self) -> Result<(), M68kError> { self.require_supervisor()?; let sr = self.pop_word()?; let addr = self.pop_long()?; @@ -1203,7 +1229,7 @@ impl M68k { Ok(()) } - fn execute_rtr(&mut self) -> Result<(), Error> { + fn execute_rtr(&mut self) -> Result<(), M68kError> { let ccr = self.pop_word()?; let addr = self.pop_long()?; self.set_sr((self.state.sr & 0xFF00) | (ccr & 0x00FF)); @@ -1214,7 +1240,7 @@ impl M68k { Ok(()) } - fn execute_rts(&mut self) -> Result<(), Error> { + fn execute_rts(&mut self) -> Result<(), M68kError> { self.debugger.stack_tracer.pop_return(); let addr = self.pop_long()?; if let Err(err) = self.set_pc(addr) { @@ -1224,7 +1250,7 @@ impl M68k { Ok(()) } - fn execute_scc(&mut self, cond: Condition, target: Target) -> Result<(), Error> { + fn execute_scc(&mut self, cond: Condition, target: Target) -> Result<(), M68kError> { let condition_true = self.get_current_condition(cond); if condition_true { self.set_target_value(target, 0xFF, Size::Byte, Used::Once)?; @@ -1234,14 +1260,14 @@ impl M68k { Ok(()) } - fn execute_stop(&mut self, flags: u16) -> Result<(), Error> { + fn execute_stop(&mut self, flags: u16) -> Result<(), M68kError> { self.require_supervisor()?; self.set_sr(flags); self.state.status = Status::Stopped; Ok(()) } - fn execute_sbcd(&mut self, src: Target, dest: Target) -> Result<(), Error> { + fn execute_sbcd(&mut self, src: Target, dest: Target) -> Result<(), M68kError> { let src_val = self.get_target_value(src, Size::Byte, Used::Once)?; let dest_val = self.get_target_value(dest, Size::Byte, Used::Twice)?; let result = self.execute_sbcd_val(src_val, dest_val)?; @@ -1249,7 +1275,7 @@ impl M68k { Ok(()) } - fn execute_sbcd_val(&mut self, src_val: u32, dest_val: u32) -> Result { + fn execute_sbcd_val(&mut self, src_val: u32, dest_val: u32) -> Result { let extend_flag = self.get_flag(Flags::Extend) as u32; let src_parts = get_nibbles_from_byte(src_val); let dest_parts = get_nibbles_from_byte(dest_val); @@ -1270,7 +1296,7 @@ impl M68k { Ok(result) } - fn execute_sub(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> { + fn execute_sub(&mut self, src: Target, dest: Target, size: Size) -> Result<(), M68kError> { let src_val = self.get_target_value(src, size, Used::Once)?; let dest_val = self.get_target_value(dest, size, Used::Twice)?; let (result, carry) = overflowing_sub_sized(dest_val, src_val, size); @@ -1281,7 +1307,7 @@ impl M68k { Ok(()) } - fn execute_suba(&mut self, src: Target, dest: Register, size: Size) -> Result<(), Error> { + fn execute_suba(&mut self, src: Target, dest: Register, size: Size) -> Result<(), M68kError> { let src_val = sign_extend_to_long(self.get_target_value(src, size, Used::Once)?, size) as u32; let dest_val = *self.get_a_reg_mut(dest); let (result, _) = overflowing_sub_sized(dest_val, src_val, Size::Long); @@ -1289,7 +1315,7 @@ impl M68k { Ok(()) } - fn execute_subx(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> { + fn execute_subx(&mut self, src: Target, dest: Target, size: Size) -> Result<(), M68kError> { let src_val = self.get_target_value(src, size, Used::Once)?; let dest_val = self.get_target_value(dest, size, Used::Twice)?; let extend = self.get_flag(Flags::Extend) as u32; @@ -1310,14 +1336,14 @@ impl M68k { Ok(()) } - fn execute_swap(&mut self, reg: Register) -> Result<(), Error> { + fn execute_swap(&mut self, reg: Register) -> Result<(), M68kError> { let value = self.state.d_reg[reg as usize]; self.state.d_reg[reg as usize] = ((value & 0x0000FFFF) << 16) | ((value & 0xFFFF0000) >> 16); self.set_logic_flags(self.state.d_reg[reg as usize], Size::Long); Ok(()) } - fn execute_tas(&mut self, target: Target) -> Result<(), Error> { + fn execute_tas(&mut self, target: Target) -> Result<(), M68kError> { let value = self.get_target_value(target, Size::Byte, Used::Twice)?; self.set_flag(Flags::Negative, (value & 0x80) != 0); self.set_flag(Flags::Zero, value == 0); @@ -1327,25 +1353,25 @@ impl M68k { Ok(()) } - fn execute_tst(&mut self, target: Target, size: Size) -> Result<(), Error> { + fn execute_tst(&mut self, target: Target, size: Size) -> Result<(), M68kError> { let value = self.get_target_value(target, size, Used::Once)?; self.set_logic_flags(value, size); Ok(()) } - fn execute_trap(&mut self, number: u8) -> Result<(), Error> { + fn execute_trap(&mut self, number: u8) -> Result<(), M68kError> { self.exception(32 + number, false)?; Ok(()) } - fn execute_trapv(&mut self) -> Result<(), Error> { + fn execute_trapv(&mut self) -> Result<(), M68kError> { if self.get_flag(Flags::Overflow) { self.exception(Exceptions::TrapvInstruction as u8, false)?; } Ok(()) } - fn execute_unlk(&mut self, reg: Register) -> Result<(), Error> { + fn execute_unlk(&mut self, reg: Register) -> Result<(), M68kError> { let value = *self.get_a_reg_mut(reg); *self.get_stack_pointer_mut() = value; let new_value = self.pop_long()?; @@ -1354,20 +1380,20 @@ impl M68k { Ok(()) } - fn execute_unimplemented_a(&mut self, _: u16) -> Result<(), Error> { + fn execute_unimplemented_a(&mut self, _: u16) -> Result<(), M68kError> { self.state.pc -= 2; self.exception(Exceptions::LineAEmulator as u8, false)?; Ok(()) } - fn execute_unimplemented_f(&mut self, _: u16) -> Result<(), Error> { + fn execute_unimplemented_f(&mut self, _: u16) -> Result<(), M68kError> { self.state.pc -= 2; self.exception(Exceptions::LineFEmulator as u8, false)?; Ok(()) } - pub(super) fn get_target_value(&mut self, target: Target, size: Size, used: Used) -> Result { + pub(super) fn get_target_value(&mut self, target: Target, size: Size, used: Used) -> Result { match target { Target::Immediate(value) => Ok(value), Target::DirectDReg(reg) => Ok(get_value_sized(self.state.d_reg[reg as usize], size)), @@ -1407,7 +1433,7 @@ impl M68k { } } - pub(super) fn set_target_value(&mut self, target: Target, value: u32, size: Size, used: Used) -> Result<(), Error> { + pub(super) fn set_target_value(&mut self, target: Target, value: u32, size: Size, used: Used) -> Result<(), M68kError> { match target { Target::DirectDReg(reg) => { set_value_sized(&mut self.state.d_reg[reg as usize], value, size); @@ -1447,12 +1473,12 @@ impl M68k { Target::IndirectMemory(addr, _) => { self.set_address_sized(addr as Address, value, size)?; }, - _ => return Err(Error::new(format!("Unimplemented addressing target: {:?}", target))), + Target::Immediate(_) => return Err(M68kError::InvalidTarget(target)), } Ok(()) } - fn get_target_address(&mut self, target: Target) -> Result { + fn get_target_address(&mut self, target: Target) -> Result { let addr = match target { Target::IndirectAReg(reg) | Target::IndirectARegInc(reg) | Target::IndirectARegDec(reg) => *self.get_a_reg_mut(reg), Target::IndirectRegOffset(base_reg, index_reg, displacement) => { @@ -1475,7 +1501,7 @@ impl M68k { Target::IndirectMemory(addr, _) => { addr }, - _ => return Err(Error::new(format!("Invalid addressing target: {:?}", target))), + _ => return Err(M68kError::InvalidTarget(target)), }; Ok(addr) } @@ -1507,22 +1533,23 @@ impl M68k { *reg_addr } - fn get_address_sized(&mut self, addr: Address, size: Size) -> Result { + fn get_address_sized(&mut self, addr: Address, size: Size) -> Result { self.port.read_data_sized(self.is_supervisor(), addr, size) } - fn set_address_sized(&mut self, addr: Address, value: u32, size: Size) -> Result<(), Error> { + fn set_address_sized(&mut self, addr: Address, value: u32, size: Size) -> Result<(), M68kError> { self.port.write_data_sized(self.is_supervisor(), addr, value, size) } - fn push_word(&mut self, value: u16) -> Result<(), Error> { + fn push_word(&mut self, value: u16) -> Result<(), M68kError> { *self.get_stack_pointer_mut() -= 2; let addr = *self.get_stack_pointer_mut(); self.port.start_request(self.is_supervisor(), addr, Size::Word, MemAccess::Write, MemType::Data, false)?; - self.port.port.write_beu16(self.current_clock, addr as Address, value) + self.port.port.write_beu16(self.current_clock, addr as Address, value)?; + Ok(()) } - fn pop_word(&mut self) -> Result { + fn pop_word(&mut self) -> Result { let addr = *self.get_stack_pointer_mut(); self.port.start_request(self.is_supervisor(), addr, Size::Word, MemAccess::Read, MemType::Data, false)?; let value = self.port.port.read_beu16(self.current_clock, addr as Address)?; @@ -1530,14 +1557,15 @@ impl M68k { Ok(value) } - fn push_long(&mut self, value: u32) -> Result<(), Error> { + fn push_long(&mut self, value: u32) -> Result<(), M68kError> { *self.get_stack_pointer_mut() -= 4; let addr = *self.get_stack_pointer_mut(); self.port.start_request(self.is_supervisor(), addr, Size::Long, MemAccess::Write, MemType::Data, false)?; - self.port.port.write_beu32(self.current_clock, addr as Address, value) + self.port.port.write_beu32(self.current_clock, addr as Address, value)?; + Ok(()) } - fn pop_long(&mut self) -> Result { + fn pop_long(&mut self) -> Result { let addr = *self.get_stack_pointer_mut(); self.port.start_request(self.is_supervisor(), addr, Size::Long, MemAccess::Read, MemType::Data, false)?; let value = self.port.port.read_beu32(self.current_clock, addr as Address)?; @@ -1545,7 +1573,7 @@ impl M68k { Ok(value) } - fn set_pc(&mut self, value: u32) -> Result<(), Error> { + fn set_pc(&mut self, value: u32) -> Result<(), M68kError> { self.state.pc = value; self.port.start_request(self.is_supervisor(), self.state.pc, Size::Word, MemAccess::Read, MemType::Program, true)?; Ok(()) @@ -1622,11 +1650,11 @@ impl M68k { self.state.sr & (Flags:: Supervisor as u16) != 0 } - fn require_supervisor(&self) -> Result<(), Error> { + fn require_supervisor(&self) -> Result<(), M68kError> { if self.is_supervisor() { Ok(()) } else { - Err(Error::processor(Exceptions::PrivilegeViolation as u32)) + Err(M68kError::Exception(Exceptions::PrivilegeViolation)) } } diff --git a/emulator/cpus/m68k/src/memory.rs b/emulator/cpus/m68k/src/memory.rs index ae21e39..c4eff72 100644 --- a/emulator/cpus/m68k/src/memory.rs +++ b/emulator/cpus/m68k/src/memory.rs @@ -3,7 +3,7 @@ use femtos::Instant; use moa_core::{Error, Address, Addressable, BusPort}; -use crate::state::{M68k, Exceptions}; +use crate::state::{M68k, M68kError, Exceptions}; use crate::instructions::Size; #[repr(u8)] @@ -120,35 +120,35 @@ impl M68kBusPort { self.current_clock = clock; } - pub(crate) fn read_instruction_word(&mut self, is_supervisor: bool, addr: u32) -> Result { + pub(crate) fn read_instruction_word(&mut self, is_supervisor: bool, addr: u32) -> Result { self.start_instruction_request(is_supervisor, addr)?; - self.port.read_beu16(self.current_clock, addr as Address) + Ok(self.port.read_beu16(self.current_clock, addr as Address)?) } - pub(crate) fn read_instruction_long(&mut self, is_supervisor: bool, addr: u32) -> Result { + pub(crate) fn read_instruction_long(&mut self, is_supervisor: bool, addr: u32) -> Result { self.start_instruction_request(is_supervisor, addr)?; - self.port.read_beu32(self.current_clock, addr as Address) + Ok(self.port.read_beu32(self.current_clock, addr as Address)?) } - pub(crate) fn read_data_sized(&mut self, is_supervisor: bool, addr: Address, size: Size) -> Result { + pub(crate) fn read_data_sized(&mut self, is_supervisor: bool, addr: Address, size: Size) -> Result { self.start_request(is_supervisor, addr as u32, size, MemAccess::Read, MemType::Data, false)?; - match size { + Ok(match size { Size::Byte => self.port.read_u8(self.current_clock, addr).map(|value| value as u32), Size::Word => self.port.read_beu16(self.current_clock, addr).map(|value| value as u32), Size::Long => self.port.read_beu32(self.current_clock, addr), - } + }?) } - pub(crate) fn write_data_sized(&mut self, is_supervisor: bool, addr: Address, value: u32, size: Size) -> Result<(), Error> { + pub(crate) fn write_data_sized(&mut self, is_supervisor: bool, addr: Address, value: u32, size: Size) -> Result<(), M68kError> { self.start_request(is_supervisor, addr as u32, size, MemAccess::Write, MemType::Data, false)?; - match size { + Ok(match size { Size::Byte => self.port.write_u8(self.current_clock, addr, value as u8), Size::Word => self.port.write_beu16(self.current_clock, addr, value as u16), Size::Long => self.port.write_beu32(self.current_clock, addr, value), - } + }?) } - pub(crate) fn start_instruction_request(&mut self, is_supervisor: bool, addr: u32) -> Result { + pub(crate) fn start_instruction_request(&mut self, is_supervisor: bool, addr: u32) -> Result { self.request.i_n_bit = false; self.request.code = FunctionCode::program(is_supervisor); self.request.access = MemAccess::Read; @@ -157,7 +157,7 @@ impl M68kBusPort { validate_address(addr) } - pub(crate) fn start_request(&mut self, is_supervisor: bool, addr: u32, size: Size, access: MemAccess, mtype: MemType, i_n_bit: bool) -> Result { + pub(crate) fn start_request(&mut self, is_supervisor: bool, addr: u32, size: Size, access: MemAccess, mtype: MemType, i_n_bit: bool) -> Result { self.request.i_n_bit = i_n_bit; self.request.code = match mtype { MemType::Program => FunctionCode::program(is_supervisor), @@ -179,11 +179,11 @@ impl M68kBusPort { } } -fn validate_address(addr: u32) -> Result { +fn validate_address(addr: u32) -> Result { if addr & 0x1 == 0 { Ok(addr) } else { - Err(Error::processor(Exceptions::AddressError as u32)) + Err(M68kError::Exception(Exceptions::AddressError)) } } @@ -210,15 +210,15 @@ impl TargetAccess { } - pub(crate) fn get(&mut self, cpu: &M68k) -> Result { + pub(crate) fn get(&mut self, cpu: &M68k) -> Result { } - pub(crate) fn set(&mut self, cpu: &M68k, value: u32) -> Result<(), Error> { + pub(crate) fn set(&mut self, cpu: &M68k, value: u32) -> Result<(), M68kError> { } - pub(crate) fn complete(&self) -> Result { + pub(crate) fn complete(&self) -> Result { } } @@ -257,11 +257,11 @@ pub(crate) struct ReadOnceAccess { } impl ReadOnceAccess { - pub(crate) fn get(&mut self, cpu: &M68k) -> Result { + pub(crate) fn get(&mut self, cpu: &M68k) -> Result { } - pub(crate) fn complete(&self) -> Result { + pub(crate) fn complete(&self) -> Result { } } @@ -272,15 +272,15 @@ pub(crate) struct ReadUpdateAccess { } impl ReadUpdateAccess { - pub(crate) fn get(&mut self, cpu: &M68k) -> Result { + pub(crate) fn get(&mut self, cpu: &M68k) -> Result { } - pub(crate) fn set(&mut self, cpu: &M68k, value: u32) -> Result<(), Error> { + pub(crate) fn set(&mut self, cpu: &M68k, value: u32) -> Result<(), M68kError> { } - pub(crate) fn complete(&self) -> Result { + pub(crate) fn complete(&self) -> Result { } } @@ -291,11 +291,11 @@ pub(crate) struct WriteOnceAccess { } impl WriteOnceAccess { - pub(crate) fn set(&mut self, cpu: &M68k, value: u32) -> Result<(), Error> { + pub(crate) fn set(&mut self, cpu: &M68k, value: u32) -> Result<(), M68kError> { } - pub(crate) fn complete(&self) -> Result { + pub(crate) fn complete(&self) -> Result { } } diff --git a/emulator/cpus/m68k/src/state.rs b/emulator/cpus/m68k/src/state.rs index c92b6da..fc6dcdf 100644 --- a/emulator/cpus/m68k/src/state.rs +++ b/emulator/cpus/m68k/src/state.rs @@ -9,6 +9,7 @@ use crate::decode::M68kDecoder; use crate::debugger::M68kDebugger; use crate::memory::M68kBusPort; use crate::timing::M68kInstructionTiming; +use crate::instructions::Target; pub type ClockCycles = u16; @@ -91,6 +92,22 @@ pub struct M68kState { pub vbr: u32, } +#[derive(Clone, Debug, thiserror::Error)] +pub enum M68kError { + #[error("cpu halted")] + Halted, + #[error("processor exception {0:?}")] + Exception(Exceptions), + #[error("interrupt vector {0} occurred")] + Interrupt(u8), + #[error("breakpoint reached")] + Breakpoint, + #[error("invalid instruction target, direct value used as a pointer: {0:?}")] + InvalidTarget(Target), + #[error("error: {0}")] + Other(String), +} + #[derive(Clone)] pub struct M68k { pub cputype: M68kType, diff --git a/emulator/cpus/m68k/src/tests.rs b/emulator/cpus/m68k/src/tests.rs index 104497c..d694287 100644 --- a/emulator/cpus/m68k/src/tests.rs +++ b/emulator/cpus/m68k/src/tests.rs @@ -251,7 +251,8 @@ mod decode_unit_tests { #[cfg(test)] mod execute_unit_tests { - use moa_core::{System, MemoryBlock, BusPort, Instant, Frequency, Address, Addressable, Steppable, Device}; + use femtos::{Instant, Frequency}; + use moa_core::{System, MemoryBlock, BusPort, Address, Addressable, Steppable, Device}; use crate::{M68k, M68kType}; use crate::execute::Used;