diff --git a/src/cpu.rs b/src/cpu.rs index e4d6f56..0aaf7ea 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -754,6 +754,17 @@ impl CPU { self.registers.set_flag(FlagRegister::Substract, false); self.registers.set_flag(FlagRegister::HalfCarry, false); }, + Opcode::RR(register) => { + let val = self.registers.get_8bit(register); + let old_carry = self.registers.get_flag(FlagRegister::Carry); + let new_carry = get_bit(val, BitIndex::I6); + let val = val << 2 | ((old_carry as u8) << 1) | (val >> 7); + self.registers.set(register, val as u16); + self.registers.set_flag(FlagRegister::Carry, new_carry); + self.registers.set_flag(FlagRegister::Zero, val == 0); + self.registers.set_flag(FlagRegister::Substract, false); + self.registers.set_flag(FlagRegister::HalfCarry, false); + }, _ => {}, }; }, @@ -2303,6 +2314,43 @@ mod tests { assert_eq!(cpu.registers.get(Register::PC), 0x102); } + #[test] + fn test_prefix_cb_rr_instruction() { + let mut bus = Bus::new(); + let mut cpu = CPU::new(); + cpu.registers.set(Register::A, 0b00000001); + cpu.registers.set_flag(FlagRegister::Carry, true); + cpu.exec(Opcode::PrefixCB(Box::new(Opcode::RR(Register::A))), &mut bus); + assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false); + assert_eq!(cpu.registers.get_flag(FlagRegister::Substract), false); + assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), false); + assert_eq!(cpu.registers.get_flag(FlagRegister::Carry), false); + assert_eq!(cpu.registers.get(Register::A), 0b00000110); + assert_eq!(cpu.registers.get(Register::PC), 0x102); + + let mut cpu = CPU::new(); + cpu.registers.set(Register::A, 0b10000000); + cpu.registers.set_flag(FlagRegister::Carry, false); + cpu.exec(Opcode::PrefixCB(Box::new(Opcode::RR(Register::A))), &mut bus); + assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false); + assert_eq!(cpu.registers.get_flag(FlagRegister::Substract), false); + assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), false); + assert_eq!(cpu.registers.get_flag(FlagRegister::Carry), false); + assert_eq!(cpu.registers.get(Register::A), 0b00000001); + assert_eq!(cpu.registers.get(Register::PC), 0x102); + + let mut cpu = CPU::new(); + cpu.registers.set(Register::A, 0b01000000); + cpu.registers.set_flag(FlagRegister::Carry, false); + cpu.exec(Opcode::PrefixCB(Box::new(Opcode::RR(Register::A))), &mut bus); + assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), true); + assert_eq!(cpu.registers.get_flag(FlagRegister::Substract), false); + assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), false); + assert_eq!(cpu.registers.get_flag(FlagRegister::Carry), true); + assert_eq!(cpu.registers.get(Register::A), 0b00000000); + assert_eq!(cpu.registers.get(Register::PC), 0x102); + } + #[test] fn test_nop_instructions() { let mut cpu = CPU::new();