diff --git a/src/arm7tdmi/arm/display.rs b/src/arm7tdmi/arm/display.rs index f8f7005..b2db557 100644 --- a/src/arm7tdmi/arm/display.rs +++ b/src/arm7tdmi/arm/display.rs @@ -220,7 +220,7 @@ impl ArmInstruction { fn fmt_ldr_str(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "{mnem}{B}{cond}{T}\t{Rd}, ", + "{mnem}{B}{T}{cond}\t{Rd}, ", mnem = if self.load_flag() { "ldr" } else { "str" }, B = if self.transfer_size() == 1 { "b" } else { "" }, cond = self.cond, @@ -358,7 +358,7 @@ impl ArmInstruction { fn fmt_swi(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "swi{cond}\t#0x{comm:08x}", + "swi{cond}\t#{comm:#x}", cond = self.cond, comm = self.swi_comment() ) diff --git a/src/arm7tdmi/arm/exec.rs b/src/arm7tdmi/arm/exec.rs index aee099a..acdcba4 100644 --- a/src/arm7tdmi/arm/exec.rs +++ b/src/arm7tdmi/arm/exec.rs @@ -2,7 +2,8 @@ use crate::bit::BitIndex; use crate::arm7tdmi; use arm7tdmi::cpu::{ - Core, CpuError, CpuExecResult, CpuInstruction, CpuPipelineAction, CpuResult, CpuState, Exception + Core, CpuError, CpuExecResult, CpuInstruction, CpuPipelineAction, CpuResult, CpuState, + Exception, }; use super::super::sysbus::SysBus; diff --git a/src/arm7tdmi/arm/mod.rs b/src/arm7tdmi/arm/mod.rs index abae4eb..cff83e6 100644 --- a/src/arm7tdmi/arm/mod.rs +++ b/src/arm7tdmi/arm/mod.rs @@ -430,9 +430,8 @@ impl ArmInstruction { } } - - #[cfg(test)] +/// All instructions constants were generated using an ARM assembler. mod tests { use super::*; @@ -442,6 +441,7 @@ mod tests { let decoded = ArmInstruction::try_from(0xef001337).unwrap(); assert_eq!(decoded.fmt, ArmInstructionFormat::SWI); assert_eq!(decoded.swi_comment(), 0x1337); + assert_eq!(format!("{}", decoded), "swi\t#0x1337"); } #[test] @@ -450,7 +450,11 @@ mod tests { let decoded = ArmInstruction::try_from((0xea_00_00_02, 0x20)).unwrap(); assert_eq!(decoded.fmt, ArmInstructionFormat::B_BL); assert_eq!(decoded.link_flag(), false); - assert_eq!((decoded.pc as i32).wrapping_add(decoded.branch_offset()), 0x30); + assert_eq!( + (decoded.pc as i32).wrapping_add(decoded.branch_offset()), + 0x30 + ); + assert_eq!(format!("{}", decoded), "b\t0x30"); } #[test] @@ -459,6 +463,56 @@ mod tests { let decoded = ArmInstruction::try_from((0xeb_ff_ff_fa, 0x20)).unwrap(); assert_eq!(decoded.fmt, ArmInstructionFormat::B_BL); assert_eq!(decoded.link_flag(), true); - assert_eq!((decoded.pc as i32).wrapping_add(decoded.branch_offset()), 0x10); + assert_eq!( + (decoded.pc as i32).wrapping_add(decoded.branch_offset()), + 0x10 + ); + assert_eq!(format!("{}", decoded), "b\t0x10"); + } + + #[test] + fn test_decode_ldr_preindex() { + // ldreq r2, [r5, -r6, lsl #5] + let decoded = ArmInstruction::try_from(0x07_15_22_86).unwrap(); + assert_eq!(decoded.fmt, ArmInstructionFormat::LDR_STR); + assert_eq!(decoded.cond, ArmCond::Equal); + assert_eq!(decoded.load_flag(), true); + assert_eq!(decoded.pre_index_flag(), true); + assert_eq!(decoded.write_back_flag(), false); + assert_eq!(decoded.rd(), 2); + assert_eq!(decoded.rn(), 5); + assert_eq!( + decoded.ldr_str_offset(), + Ok(ArmShiftedValue::ShiftedRegister { + reg: 6, + shift: ArmRegisterShift::ShiftAmount(5, ArmShiftType::LSL), + added: Some(false) + }) + ); + + assert_eq!(format!("{}", decoded), "ldreq\tr2, [r5, -r6, lsl #5]"); + } + + #[test] + fn test_decode_str_postindex() { + // strteq r2, [r4], -r7, lsl #8 + let decoded = ArmInstruction::try_from(0x06_24_24_47).unwrap(); + assert_eq!(decoded.fmt, ArmInstructionFormat::LDR_STR); + assert_eq!(decoded.cond, ArmCond::Equal); + assert_eq!(decoded.load_flag(), false); + assert_eq!(decoded.pre_index_flag(), false); + assert_eq!(decoded.write_back_flag(), true); + assert_eq!(decoded.rd(), 2); + assert_eq!(decoded.rn(), 4); + assert_eq!( + decoded.ldr_str_offset(), + Ok(ArmShiftedValue::ShiftedRegister { + reg: 7, + shift: ArmRegisterShift::ShiftAmount(8, ArmShiftType::ASR), + added: Some(false) + }) + ); + + assert_eq!(format!("{}", decoded), "strteq\tr2, [r4], -r7, asr #8"); } }