Browse Source

Emulator: Add isCarry() function to CPU

master
Riyyi 2 years ago
parent
commit
cc120891ca
  1. 64
      src/cpu.cpp
  2. 4
      src/cpu.h

64
src/cpu.cpp

@ -5,7 +5,7 @@
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#include <cstdint> // int32_t, uint8_t, uint32_t #include <cstdint> // uint8_t, uint32_t
#include "cpu.h" #include "cpu.h"
#include "emu.h" #include "emu.h"
@ -113,13 +113,15 @@ void CPU::add()
m_wait_cycles += 8; m_wait_cycles += 8;
// Set flags // Set flags
m_zf = m_a + immediate == 0;
m_nf = 0; m_nf = 0;
m_hf = m_a + immediate > 16; m_hf = isCarry(m_a, immediate, 0x10);
m_cf = m_a + immediate > 255; m_cf = isCarry(m_a, immediate, 0x100);
// A = A + r // A = A + r
m_a = (m_a + immediate) & 0x00ff; m_a = (m_a + immediate) & 0xff;
// Zero flag
m_zf = m_a == 0;
break; break;
default: default:
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
@ -134,13 +136,15 @@ void CPU::dec8()
// DEC C, flags: Z 1 H - // DEC C, flags: Z 1 H -
m_wait_cycles += 4; m_wait_cycles += 4;
m_c = (m_c - 1) & 0x00ff;
// Set flags // Set flags
// TODO
// m_zf = ?
m_nf = 1; m_nf = 1;
// m_hf = ? m_hf = isCarry(m_c, -1, 0x10);
// C = C - 1
m_c = (m_c - 1) & 0xff;
// Zero flag
m_zf = m_c == 0;
break; break;
} }
default: default:
@ -355,10 +359,16 @@ void CPU::ld16()
m_wait_cycles += 12; m_wait_cycles += 12;
// Put SP + next (signed) byte in memory into HL // Put SP + next (signed) byte in memory into HL
// TODO uint32_t signed_data = (pcRead() ^ 0x80) - 0x80;
uint32_t sum = m_sp + signed_data;
m_h = sum >> 8;
m_l = sum & 0xff;
// Unsets ZF and NF, may enable HF and CF // Set flags
// TODO flags m_zf = 0;
m_nf = 0;
m_hf = isCarry(m_sp, signed_data, 0x10);
m_cf = isCarry(m_sp, signed_data, 0x100);
break; break;
} }
case 0xf9: { case 0xf9: {
@ -479,6 +489,34 @@ uint32_t CPU::ffRead(uint32_t address)
return Emu::the().readMemory(address | (0xff << 8)) & 0x00ff; return Emu::the().readMemory(address | (0xff << 8)) & 0x00ff;
} }
bool CPU::isCarry(uint32_t lhs, uint32_t rhs, uint32_t limit_bit)
{
// limit_bit values:
// 8-bit half-carry = 0x10 or 16
// 8-bit carry = 0x100 or 256
// 16-bit half-carry = 0x1000 or 4096
// 16-bit carry = 0x10000 or 65536
// Example for 8-bit half-carry:
// 0b00111110 62 | 0b00111000 56
// 0b00100010 34 + | 0b00010001 17 +
// --------------- | ---------------
// 0b01100000 96 | 0b01001001 73
// |
// 0b00111110 62 | 0b00111000 56
// 0b00100010 34 ^ | 0b00010001 17 ^
// --------------- | ---------------
// 0b00011100 | 0b00101001
// 0b01100000 96 ^ | 0b01001001 73 ^
// --------------- | ---------------
// 0b01111100 | 0b01100000
// 0b00010000 16 & | 0b00010000 16 &
// --------------- | ---------------
// 0b00010000 = true! | 0b00000000 = false!
return (lhs ^ rhs ^ (lhs + rhs)) & limit_bit;
}
// ----------------------------------------- // -----------------------------------------
void Formatter<CPU>::parse(Parser& parser) void Formatter<CPU>::parse(Parser& parser)

4
src/cpu.h

@ -7,7 +7,7 @@
#pragma once #pragma once
#include <cstdint> // int8_t, int32_t, uint8_t, uint32_t #include <cstdint> // int8_t, uint8_t, uint32_t
#include <functional> // std::function #include <functional> // std::function
#include <unordered_map> #include <unordered_map>
@ -81,6 +81,8 @@ private:
void ffWrite(uint32_t address, uint32_t value); void ffWrite(uint32_t address, uint32_t value);
uint32_t ffRead(uint32_t address); uint32_t ffRead(uint32_t address);
bool isCarry(uint32_t lhs, uint32_t rhs, uint32_t limit_bit);
// Registers // Registers
uint32_t m_a { 0 }; // Accumulator uint32_t m_a { 0 }; // Accumulator
uint32_t m_b { 0 }; // B uint32_t m_b { 0 }; // B

Loading…
Cancel
Save