Created
June 22, 2019 22:43
-
-
Save nico-abram/7939e22d69760a145c14835a1a973b67 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Data Processing or PSR transfer | |
pub fn PSR(cpu: &mut Cpu, opcode: u32) { | |
let immediate = as_extra_flag(opcode); | |
let set_condition_flags = (opcode & 0x0010_0000) != 0; | |
let (rn, rd, _, _, _) = as_usizes(opcode); | |
let (_, _, third_byte, second_byte, lowest_byte) = as_bytes(opcode); | |
let rn = *cpu.reg_mut(rn); | |
let psr_opcode = ((opcode & 0x01E0_0000) >> 25) as u8; | |
let op2: u32 = if immediate { | |
let ror_shift = second_byte & 0x0007; | |
(lowest_byte as u32).rotate_right(ror_shift as u32) // TODO: Im fairly sure this is wrong | |
} else { | |
let register_value: u32 = cpu.regs[lowest_byte as usize]; | |
let shift_by_register = (opcode & 0x0000_0010) != 0; | |
let shift_amount = if (shift_by_register) { | |
cpu.regs[third_byte as usize] | |
} else { | |
((third_byte as u32) * 2 + ((second_byte & 0x80) as u32)) | |
}; | |
let shift_type = ((opcode & 0x0000_0060) >> 6) as u8; | |
match shift_type { | |
0 => register_value.overflowing_shl(shift_amount).0, | |
1 => register_value.overflowing_shr(shift_amount).0, | |
1 => register_value.overflowing_shr(shift_amount).0, | |
2 => (register_value as i32).overflowing_shr(shift_amount).0 as u32, | |
3 => register_value.rotate_right(shift_amount), | |
_ => unimplemented!("Impossible"), | |
} | |
}; | |
let mut res = &mut cpu.regs[rd]; | |
let mut void = 0u32; // For use by tst and teq | |
match psr_opcode as u8 { | |
0 => { | |
*res = rn & op2; | |
} | |
1 => { | |
*res = rn ^ op2; | |
} | |
2 => { | |
*res = rn - op2; | |
} | |
3 => { | |
*res = op2 - rn; | |
} | |
4 => { | |
*res = rn + op2; | |
} | |
5 => { | |
*res = rn + op2 + (cpu.cpsr.C() as u32); | |
} | |
6 => { | |
*res = rn - op2 + (cpu.cpsr.C() as u32) - 1; | |
} | |
7 => { | |
*res = op2 - rn + (cpu.cpsr.C() as u32) - 1; | |
} | |
8 => { | |
res = &mut void; | |
//tst | |
unimplemented!(); | |
} | |
9 => { | |
res = &mut void; | |
//teq | |
unimplemented!(); | |
} | |
10 => { | |
//cmp | |
unimplemented!(); | |
} | |
11 => { | |
//cmn | |
unimplemented!(); | |
} | |
12 => { | |
*res = rn | op2; | |
} | |
13 => { | |
*res = op2; | |
} | |
14 => { | |
*res = rn & (!op2); | |
} | |
15 => { | |
*res = !op2; | |
} | |
_ => unimplemented!("Impossible"), | |
} | |
if set_condition_flags { | |
unimplemented!(); | |
// TODO: conditions | |
} | |
cpu.clocks += 0; // todo:clocks | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment