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 Won't boot unless binary patched to remove a loop querying the flash chip
### Dragon Ball - Legacy of Goku 2 ### 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 ## Screenshots

View file

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

View file

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