core/arm7tdmi/arm/: Fix wrong calculation of op1 in DATA_PROCESSING instruction when RN==R15

The docs state: "If a register is used to specify the shift amount the PC will be 12 bytes ahead"
I probably misread that when implementing DataProcessing instructions,
and because of that added 4 bytes to (op1+8) when shift amount was specified by a rotated immediate.

Fixes #6 (and probably tons of other bugs too!)


Former-commit-id: 129f0951a6381221314c23a468c3da8b31435a30
This commit is contained in:
Michel Heily 2020-01-18 22:47:31 +02:00
parent 1bafb9238b
commit a47cb18cda
3 changed files with 16 additions and 7 deletions

View file

@ -52,7 +52,7 @@ No issues so far
Won't boot unless binary patched to remove a loop querying the flash chip
### Dragon Ball - Legacy of Goku 2
crashes when entering in-game menu, other than that works fine.
~~crashes when entering in-game menu, other than that works fine.~~
## Screenshots

View file

@ -47,7 +47,7 @@ impl AluOpCode {
}
}
#[derive(Debug, PartialEq, Primitive)]
#[derive(Debug, PartialEq, Primitive, Copy, Clone)]
pub enum BarrelShiftOpCode {
LSL = 0,
LSR = 1,
@ -55,13 +55,13 @@ pub enum BarrelShiftOpCode {
ROR = 3,
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum ShiftRegisterBy {
ByAmount(u32),
ByRegister(usize),
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub struct ShiftedRegister {
pub reg: usize,
pub shift_by: ShiftRegisterBy,
@ -69,7 +69,16 @@ pub struct ShiftedRegister {
pub added: Option<bool>,
}
#[derive(Debug, PartialEq)]
impl ShiftedRegister {
pub fn is_shifted_by_reg(&self) -> bool {
match self.shift_by {
ShiftRegisterBy::ByRegister(_) => true,
_ => false
}
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum BarrelShifterValue {
ImmediateValue(u32),
RotatedImmediate(u32, u32),

View file

@ -183,8 +183,8 @@ impl Core {
let op2 = insn.operand2()?;
match op2 {
BarrelShifterValue::ShiftedRegister(_) => {
if insn.rn() == REG_PC {
BarrelShifterValue::ShiftedRegister(shifted_reg) => {
if insn.rn() == REG_PC && shifted_reg.is_shifted_by_reg() {
op1 += 4;
}
}