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:
parent
1bafb9238b
commit
a47cb18cda
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue