use crate::hw::cop0::{Cause, Excode, IntSrc};
use crate::hw::Register;
use core::fmt;
use core::fmt::{Debug, Formatter};
const EXCODE: usize = 2;
const BD: usize = 31;
impl Cause {
pub fn pending(&self, int_src: IntSrc) -> bool {
self.all_set(1 << (int_src as u32))
}
pub fn ack(&mut self, int_src: IntSrc) -> &mut Self {
self.clear_bits(1 << (int_src as u32))
}
pub fn branch_delay_slot(&self) -> bool {
self.all_set(1 << BD)
}
pub fn excode(&self) -> Excode {
match (self.to_bits() >> EXCODE) & 0x1F {
0x00 => Excode::Interrupt,
0x04 => Excode::AddressErrorLoad,
0x05 => Excode::AddressErrorStore,
0x08 => Excode::Syscall,
0x09 => Excode::Breakpoint,
0x0A => Excode::ReservedInstruction,
_ => Excode::Other,
}
}
}
impl Debug for Cause {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("cop0::Cause")
.field("bits", &self.to_bits())
.field("hw_interrupt_pending", &self.pending(IntSrc::Hardware))
.field("sw0_interrupt_pending", &self.pending(IntSrc::Software0))
.field("sw1_interrupt_pending", &self.pending(IntSrc::Software1))
.field("branch_delay_slot", &self.branch_delay_slot())
.field("exception_code", &self.excode())
.finish()
}
}