diff --git a/src/arm7tdmi/arm/exec.rs b/src/arm7tdmi/arm/exec.rs index 5020178..b7eff45 100644 --- a/src/arm7tdmi/arm/exec.rs +++ b/src/arm7tdmi/arm/exec.rs @@ -44,20 +44,25 @@ impl Core { Ok(CpuPipelineAction::Flush) } - /// Cycles 2S+1N - fn exec_bx(&mut self, _bus: &mut Bus, insn: ArmInstruction) -> CpuResult { - let rn = self.get_reg(insn.rn()); - if rn.bit(0) { + pub fn branch_exchange(&mut self, mut addr: Addr) -> CpuResult { + if addr.bit(0) { + addr = addr & !0x1; self.cpsr.set_state(CpuState::THUMB); } else { + addr = addr & !0x3; self.cpsr.set_state(CpuState::ARM); } - self.pc = rn & !1; + self.pc = addr; Ok(CpuPipelineAction::Flush) } + /// Cycles 2S+1N + fn exec_bx(&mut self, _bus: &mut Bus, insn: ArmInstruction) -> CpuResult { + self.branch_exchange(self.get_reg(insn.rn())) + } + fn exec_swi(&mut self, _bus: &mut Bus, _insn: ArmInstruction) -> CpuResult { self.exception(Exception::SoftwareInterrupt); Ok(CpuPipelineAction::Flush) diff --git a/src/arm7tdmi/thumb/exec.rs b/src/arm7tdmi/thumb/exec.rs index 9dd6c55..b0ec658 100644 --- a/src/arm7tdmi/thumb/exec.rs +++ b/src/arm7tdmi/thumb/exec.rs @@ -112,19 +112,7 @@ impl Core { } else { insn.rs() }; - - let mut addr = self.get_reg(src_reg); - if addr.bit(0) { - self.cpsr.set_state(CpuState::THUMB); - } else { - // word align when switching to arm state - addr = addr & !0x3; - self.cpsr.set_state(CpuState::ARM); - } - - self.pc = addr & !1; - - Ok(CpuPipelineAction::Flush) + self.branch_exchange(self.get_reg(src_reg)) } fn exec_thumb_hi_reg_op_or_bx(