diff --git a/emulator/cpus/z80/src/execute.rs b/emulator/cpus/z80/src/execute.rs index 8a6a81a..f921287 100644 --- a/emulator/cpus/z80/src/execute.rs +++ b/emulator/cpus/z80/src/execute.rs @@ -193,8 +193,49 @@ impl Z80 { self.set_flag(Flags::HalfCarry, true); self.set_flag(Flags::AddSubtract, true); }, - //Instruction::DAA => { - //}, + Instruction::DAA => { + // From + // if the least significant four bits of A contain a non-BCD digit (i. e. it is + // greater than 9) or the H flag is set, then $06 is added to the register. Then + // the four most significant bits are checked. If this more significant digit + // also happens to be greater than 9 or the C flag is set, then $60 is added. + + // From + // + // CF | high | HF | low | diff + // | nibble | | nibble | + //---------------------------------- + // 0 | 0-9 | 0 | 0-9 | 00 + // 0 | 0-9 | 1 | 0-9 | 06 + // 0 | 0-8 | * | a-f | 06 + // 0 | a-f | 0 | 0-9 | 60 + // 1 | * | 0 | 0-9 | 60 + // 1 | * | 1 | 0-9 | 66 + // 1 | * | * | a-f | 66 + // 0 | 9-f | * | a-f | 66 + // 0 | a-f | 1 | 0-9 | 66 + + let mut value = self.get_register_value(Register::A); + let mut carry = false; + let mut half_carry = false; + if (value & 0x0F) > 9 || self.get_flag(Flags::HalfCarry) { + let (result, _, _, half_carry1) = add_bytes(value, 6); + value = result; + half_carry = half_carry1; + } + if (value & 0xF0) > 0x90 || self.get_flag(Flags::Carry) { + let (result, _, _, half_carry2) = add_bytes(value, 0x60); + value = result; + half_carry |= half_carry2; + carry = true; + } + self.set_register_value(Register::A, value); + + self.set_numeric_flags(value as u16, Size::Byte); + self.set_parity_flags(value); + self.set_flag(Flags::HalfCarry, half_carry); + self.set_flag(Flags::Carry, carry); + }, Instruction::DEC16(regpair) => { let value = self.get_register_pair_value(regpair); @@ -910,9 +951,8 @@ impl Z80 { } fn set_parity_flags(&mut self, value: u8) { - let mask = (Flags::Parity as u8) | (Flags::AddSubtract as u8); let parity = if (value.count_ones() & 0x01) == 0 { Flags::Parity as u8 } else { 0 }; - self.set_flags(mask, parity); + self.set_flags(Flags::Parity as u8, parity); } fn set_arithmetic_op_flags(&mut self, value: u16, size: Size, addsub: bool, carry: bool, overflow: bool, half_carry: bool) { diff --git a/tests/rad_tests/latest.txt b/tests/rad_tests/latest.txt index 0342946..80b6239 100644 --- a/tests/rad_tests/latest.txt +++ b/tests/rad_tests/latest.txt @@ -1,4 +1,4 @@ -Last run on 2023-05-13 at commit f3d1fd0ae2410a164c92150cc3caa0f525cbb4b7 +Last run on 2023-05-13 at commit 5ec2fe41578e06279419b35826bb4b575bc14c09 00.json completed, all passed! 01.json completed, all passed! @@ -41,7 +41,7 @@ Last run on 2023-05-13 at commit f3d1fd0ae2410a164c92150cc3caa0f525cbb4b7 24.json completed, all passed! 25.json completed, all passed! 26.json completed, all passed! -27.json completed: 0 passed, 1000 FAILED +27.json completed: 396 passed, 604 FAILED 28.json completed, all passed! 29.json completed, all passed! 2a.json completed, all passed! @@ -643,5 +643,5 @@ fd f9.json completed, all passed! fe.json completed, all passed! ff.json completed, all passed! -passed: 628998, failed: 13002, total 98% -completed in 0m 31s +passed: 629394, failed: 12606, total 98% +completed in 0m 32s