use crate::arm7tdmi::arm::*;
use crate::arm7tdmi::bus::{Bus, MemoryAccessType::*, MemoryAccessWidth::*};
use crate::arm7tdmi::cpu::{Core, CpuExecResult, CpuPipelineAction};
use crate::arm7tdmi::{Addr, REG_PC};
use super::{ThumbFormat, ThumbInstruction};
impl Core {
fn exec_thumb_data_process_imm(
&mut self,
bus: &mut Bus,
insn: ThumbInstruction,
) -> CpuExecResult {
let arm_alu_op: ArmOpCode = insn.format3_op().into();
let op1 = self.get_reg(insn.rd()) as i32;
let op2 = insn.offset8() as i32;
let result = self.alu(arm_alu_op, op1, op2, true);
if let Some(result) = result {
self.set_reg(insn.rd(), result as u32);
}
// +1S
self.add_cycles(
self.pc + (self.word_size() as u32),
bus,
Seq + MemoryAccess32,
);
Ok(CpuPipelineAction::IncPC)
fn exec_thumb_ldr_pc(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
let addr = (insn.pc & !0b10) + 4 + (insn.word8() as Addr);
let data = bus.read_32(addr);
// +1N
self.add_cycles(addr, bus, NonSeq + MemoryAccess32);
self.set_reg(insn.rd(), data);
// +1I
self.add_cycle();
pub fn exec_thumb(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
match insn.fmt {
ThumbFormat::DataProcessImm => self.exec_thumb_data_process_imm(bus, insn),
ThumbFormat::LdrPc => self.exec_thumb_ldr_pc(bus, insn),
_ => unimplemented!("thumb not implemented {:#}", insn),