diff --git a/src/cpu.cpp b/src/cpu.cpp index f9bee6c..5fa09a3 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -527,35 +527,44 @@ void CPU::daa() // bits) of a byte (a byte, since it is 8 bits has two nibbles) to store // a decimal digit. // Example: 64 split on each number gives a 6 and a 4, so 0110 0100 as a BCD - uint8_t higher_nibble = m_a & 0xf0; - uint8_t lower_nibble = m_a & 0xf; - // Step 1: Check lower nibble of the BCD stored in A. + // Step 1: Check upper nibble of the BCD stored in A. + // If it is greater than decimal 9 or the carry flag is set + // (meaning that the upper nibble value is > 15), + // add decimal 6 to the upper nibble to make it wrap around and set carry flag to 1 + + // Step 2: Check lower nibble of the BCD stored in A. // If it is greater than decimal 9 or half carry flag is set // (meaning that the lower nibble value is > 15), // add decimal 6 to the lower nibble to make it wrap around - if (lower_nibble > 9 || m_hf) { - lower_nibble += 6; - higher_nibble += isCarry(m_a, 6, 0x10); - } - // Step 2: Check higher nibble (after addition of the carry from the lower nibble). - // If it is greater than decimal 9 or the carry flag is set - // (meaning that the upper nibble value is > 15), - // add decimal 6 to the upper nibble to make it wrap around and set carry flag to 1 - uint32_t new_carry = 0; - if (higher_nibble > 9 || m_cf) { - higher_nibble += 6; - new_carry = 1; + if (!m_nf) { + if (m_cf || m_a > 0x99) { + m_a += 0x60; + } + + if (m_hf || (m_a & 0xf) > 0x9) { + m_a += 0x6; + } } + else { + if (m_cf) { + m_a -= 0x60; + } + + if (m_hf) { + m_a -= 0x6; + } + } + + // Carry flag + m_cf = (m_a & 0x100) == 0x100; - // Set Accumulator to the correct BCD representation - m_a = higher_nibble | lower_nibble; + m_a = m_a & 0xff; // Set flags - m_zf = m_a == 0; + m_zf = (m_a == 0); m_hf = 0; - m_cf = new_carry; break; } default: diff --git a/src/cpu.h b/src/cpu.h index fcd3ec3..700b57f 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -32,6 +32,7 @@ public: void add8(); void and8(); void cp(); + void daa(); void dec8(); void inc8(); void or8();