Added custom error type

This commit is contained in:
transistor 2024-03-01 23:08:28 -08:00
parent 55efc4f406
commit e13c172364
5 changed files with 245 additions and 199 deletions

View File

@ -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<Instruction, Error> {
pub fn decode_next(&mut self, memory: &mut M68kBusPort) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_bit_ops(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_move_byte(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_move_long(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_move_word(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_misc(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_addq_subq(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_branch(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_moveq(&mut self, _memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_div_or(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_sub(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_cmp_eor(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_mul_and(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_add(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<Instruction, Error> {
fn decode_group_shift(&mut self, memory: &mut M68kBusPort, ins: u16) -> Result<Instruction, M68kError> {
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<u16, Error> {
fn read_instruction_word(&mut self, memory: &mut M68kBusPort) -> Result<u16, M68kError> {
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<u32, Error> {
fn read_instruction_long(&mut self, memory: &mut M68kBusPort) -> Result<u32, M68kError> {
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<Size>) -> Result<Target, Error> {
fn decode_lower_effective_address(&mut self, memory: &mut M68kBusPort, ins: u16, size: Option<Size>) -> Result<Target, M68kError> {
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<Size>) -> Result<Target, Error> {
fn decode_upper_effective_address(&mut self, memory: &mut M68kBusPort, ins: u16, size: Option<Size>) -> Result<Target, M68kError> {
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<i32, Error> {
fn get_extension_displacement(&mut self, memory: &mut M68kBusPort, select: u16) -> Result<i32, M68kError> {
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<u8>) -> Result<Target, Error> {
fn decode_extension_word(&mut self, memory: &mut M68kBusPort, areg: Option<u8>) -> Result<Target, M68kError> {
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<Size>) -> Result<Target, Error> {
pub(super) fn get_mode_as_target(&mut self, memory: &mut M68kBusPort, mode: u8, reg: u8, size: Option<Size>) -> Result<Target, M68kError> {
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<String, Error> =
let ins_data: Result<String, M68kError> =
(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();

View File

@ -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<M68kError> 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<Error> 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<ClockCycles, Error> {
pub fn step_internal(&mut self, system: &System) -> Result<ClockCycles, M68kError> {
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<ClockCycles, Error> {
pub fn reset_cpu(&mut self) -> Result<ClockCycles, M68kError> {
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<ClockCycles, Error> {
pub fn cycle_one(&mut self, system: &System) -> Result<ClockCycles, M68kError> {
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<Register>, dest_l: Register, sign: Sign) -> Result<(), Error> {
fn execute_divl(&mut self, src: Target, dest_h: Option<Register>, 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<u32, Error> {
fn move_memory_to_registers(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result<u32, M68kError> {
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<u32, Error> {
fn move_registers_to_memory(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result<u32, M68kError> {
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<u32, Error> {
fn move_registers_to_memory_reverse(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result<u32, M68kError> {
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<Register>, dest_l: Register, sign: Sign) -> Result<(), Error> {
fn execute_mull(&mut self, src: Target, dest_h: Option<Register>, 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<u32, Error> {
fn execute_sbcd_val(&mut self, src_val: u32, dest_val: u32) -> Result<u32, M68kError> {
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<u32, Error> {
pub(super) fn get_target_value(&mut self, target: Target, size: Size, used: Used) -> Result<u32, M68kError> {
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<u32, Error> {
fn get_target_address(&mut self, target: Target) -> Result<u32, M68kError> {
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<u32, Error> {
fn get_address_sized(&mut self, addr: Address, size: Size) -> Result<u32, M68kError> {
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<u16, Error> {
fn pop_word(&mut self) -> Result<u16, M68kError> {
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<u32, Error> {
fn pop_long(&mut self) -> Result<u32, M68kError> {
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))
}
}

View File

@ -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<u16, Error> {
pub(crate) fn read_instruction_word(&mut self, is_supervisor: bool, addr: u32) -> Result<u16, M68kError> {
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<u32, Error> {
pub(crate) fn read_instruction_long(&mut self, is_supervisor: bool, addr: u32) -> Result<u32, M68kError> {
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<u32, Error> {
pub(crate) fn read_data_sized(&mut self, is_supervisor: bool, addr: Address, size: Size) -> Result<u32, M68kError> {
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<u32, Error> {
pub(crate) fn start_instruction_request(&mut self, is_supervisor: bool, addr: u32) -> Result<u32, M68kError> {
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<u32, Error> {
pub(crate) fn start_request(&mut self, is_supervisor: bool, addr: u32, size: Size, access: MemAccess, mtype: MemType, i_n_bit: bool) -> Result<u32, M68kError> {
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<u32, Error> {
fn validate_address(addr: u32) -> Result<u32, M68kError> {
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<u32, Error> {
pub(crate) fn get(&mut self, cpu: &M68k) -> Result<u32, M68kError> {
}
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<Self, Error> {
pub(crate) fn complete(&self) -> Result<Self, M68kError> {
}
}
@ -257,11 +257,11 @@ pub(crate) struct ReadOnceAccess {
}
impl ReadOnceAccess {
pub(crate) fn get(&mut self, cpu: &M68k) -> Result<u32, Error> {
pub(crate) fn get(&mut self, cpu: &M68k) -> Result<u32, M68kError> {
}
pub(crate) fn complete(&self) -> Result<Self, Error> {
pub(crate) fn complete(&self) -> Result<Self, M68kError> {
}
}
@ -272,15 +272,15 @@ pub(crate) struct ReadUpdateAccess {
}
impl ReadUpdateAccess {
pub(crate) fn get(&mut self, cpu: &M68k) -> Result<u32, Error> {
pub(crate) fn get(&mut self, cpu: &M68k) -> Result<u32, M68kError> {
}
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<Self, Error> {
pub(crate) fn complete(&self) -> Result<Self, M68kError> {
}
}
@ -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<Self, Error> {
pub(crate) fn complete(&self) -> Result<Self, M68kError> {
}
}

View File

@ -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,

View File

@ -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;