Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Game Boy (DMG-01) emulator project focused on building an accurate LR35902 CPU c

```bash
❯ ./utility_scripts/opcode_progress.py
- Base Opcodes: [██████████████████░░] 92.2% (236/256)
- Base Opcodes: [██████████████████░░] 93.8% (240/256)
- CB Opcodes: [████████████████████] 100.0% (256/256)
- Combined: [███████████████████░] 96.1% (492/512)
- Combined: [███████████████████░] 96.9% (496/512)
```

## Current Focus
Expand Down
2 changes: 1 addition & 1 deletion include/ProcessingUnit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class ProcessingUnit{
}
void normalizeFlags()
{
F &= 0xF0;
F = 0xF0;
}
void setFlag(Flag flag, bool value)
{
Expand Down
72 changes: 68 additions & 4 deletions src/core/cpu/instructions/opcodes/op_0C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,71 @@ int op_cb_prefix(ProcessingUnit& cpu , MMU& mmu) // 0xCB
return cbInstructionTable[cb_opcode](cpu, mmu);
}

DUMMY(op_call_z) // 0xCC
DUMMY(op_call) // 0xCD
DUMMY(op_adc_a_d8) // 0xCE
DUMMY(op_rst_08) // 0xCF
int op_call_z(ProcessingUnit& cpu, MMU& mmu) // 0xCC
{
const u8 lo = mmu.read(cpu.inc_pc());
const u8 hi = mmu.read(cpu.inc_pc());
const u16 addr = static_cast<u16>((hi << 8) | lo);

if (cpu.get_flag_z())
{
const u16 pc = cpu.get_pc();
const u16 sp = cpu.get_sp();

mmu.write(sp - 1, static_cast<u8>(pc >> 8));
mmu.write(sp - 2, static_cast<u8>(pc & 0xFF));
cpu.set_sp(sp - 2);
cpu.set_pc(addr);

return totalMachineCycles(6);
}
return totalMachineCycles(3);
}

int op_call(ProcessingUnit& cpu, MMU& mmu) // 0xCD
{
const u8 lo = mmu.read(cpu.inc_pc());
const u8 hi = mmu.read(cpu.inc_pc());
const u16 addr = static_cast<u16>((hi << 8) | lo);

const u16 pc = cpu.get_pc();
const u16 sp = cpu.get_sp();

mmu.write(sp - 1, static_cast<u8>(pc >> 8));
mmu.write(sp - 2, static_cast<u8>(pc & 0xFF));

cpu.set_sp(sp - 2);
cpu.set_pc(addr);

return totalMachineCycles(6);
}

int op_adc_a_d8(ProcessingUnit& cpu, MMU& mmu) // 0xCE
{
const u8 d8 = mmu.read(cpu.inc_pc());
const u8 a = cpu.reg(ProcessingUnit::Register::A);
const u8 c = cpu.get_flag_c() ? 1 : 0;
const u16 result = a + d8 + c;

cpu.setFlag(ProcessingUnit::Flag::Z, (result & 0xFF) == 0);
cpu.setFlag(ProcessingUnit::Flag::N, false);
cpu.setFlag(ProcessingUnit::Flag::H, ((a & 0xF) + (d8 & 0xF) + c) > 0xF);
cpu.setFlag(ProcessingUnit::Flag::C, result > 0xFF);

cpu.reg(ProcessingUnit::Register::A) = static_cast<u8>(result);
return totalMachineCycles(2);
}

int op_rst_08(ProcessingUnit& cpu, MMU& mmu) // 0xCF
{
const u16 pc = cpu.get_pc();
const u16 sp = cpu.get_sp();

mmu.write(sp - 1, static_cast<u8>(pc >> 8));
mmu.write(sp - 2, static_cast<u8>(pc & 0xFF));
cpu.set_sp(sp - 2);

cpu.set_pc(0x0008);

return totalMachineCycles(4);
}
32 changes: 16 additions & 16 deletions tests/op_tests/cb_op_08_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class CB_OpcodesCPUTest : public testing::Test {
// --- RES 0 ---
TEST_F(CB_OpcodesCPUTest, RES_0_B) {
cpu.reg(ProcessingUnit::Register::B) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0; // Set flags to ensure they aren't cleared
cpu.normalizeFlags(); // Set flags to ensure they aren't cleared
int cycles = op_res_0_b(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::B), 0xFE);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0); // Flags unchanged
Expand All @@ -26,7 +26,7 @@ TEST_F(CB_OpcodesCPUTest, RES_0_B) {

TEST_F(CB_OpcodesCPUTest, RES_0_C) {
cpu.reg(ProcessingUnit::Register::C) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_0_c(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::C), 0xFE);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -35,7 +35,7 @@ TEST_F(CB_OpcodesCPUTest, RES_0_C) {

TEST_F(CB_OpcodesCPUTest, RES_0_D) {
cpu.reg(ProcessingUnit::Register::D) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_0_d(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::D), 0xFE);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -44,7 +44,7 @@ TEST_F(CB_OpcodesCPUTest, RES_0_D) {

TEST_F(CB_OpcodesCPUTest, RES_0_E) {
cpu.reg(ProcessingUnit::Register::E) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_0_e(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::E), 0xFE);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -53,7 +53,7 @@ TEST_F(CB_OpcodesCPUTest, RES_0_E) {

TEST_F(CB_OpcodesCPUTest, RES_0_H) {
cpu.reg(ProcessingUnit::Register::H) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_0_h(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::H), 0xFE);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -62,7 +62,7 @@ TEST_F(CB_OpcodesCPUTest, RES_0_H) {

TEST_F(CB_OpcodesCPUTest, RES_0_L) {
cpu.reg(ProcessingUnit::Register::L) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_0_l(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::L), 0xFE);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -74,7 +74,7 @@ TEST_F(CB_OpcodesCPUTest, RES_0_HL) {
cpu.reg(ProcessingUnit::Register::H) = 0xC0;
cpu.reg(ProcessingUnit::Register::L) = 0x00;
mmu.write(addr, 0xFF);
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_0_hl(cpu, mmu);
EXPECT_EQ(mmu.read(addr), 0xFE);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -83,7 +83,7 @@ TEST_F(CB_OpcodesCPUTest, RES_0_HL) {

TEST_F(CB_OpcodesCPUTest, RES_0_A) {
cpu.reg(ProcessingUnit::Register::A) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_0_a(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::A), 0xFE);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -93,7 +93,7 @@ TEST_F(CB_OpcodesCPUTest, RES_0_A) {
// --- RES 1 ---
TEST_F(CB_OpcodesCPUTest, RES_1_B) {
cpu.reg(ProcessingUnit::Register::B) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_1_b(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::B), 0xFD);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -102,7 +102,7 @@ TEST_F(CB_OpcodesCPUTest, RES_1_B) {

TEST_F(CB_OpcodesCPUTest, RES_1_C) {
cpu.reg(ProcessingUnit::Register::C) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_1_c(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::C), 0xFD);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -111,7 +111,7 @@ TEST_F(CB_OpcodesCPUTest, RES_1_C) {

TEST_F(CB_OpcodesCPUTest, RES_1_D) {
cpu.reg(ProcessingUnit::Register::D) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_1_d(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::D), 0xFD);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -120,7 +120,7 @@ TEST_F(CB_OpcodesCPUTest, RES_1_D) {

TEST_F(CB_OpcodesCPUTest, RES_1_E) {
cpu.reg(ProcessingUnit::Register::E) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_1_e(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::E), 0xFD);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -129,7 +129,7 @@ TEST_F(CB_OpcodesCPUTest, RES_1_E) {

TEST_F(CB_OpcodesCPUTest, RES_1_H) {
cpu.reg(ProcessingUnit::Register::H) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_1_h(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::H), 0xFD);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -138,7 +138,7 @@ TEST_F(CB_OpcodesCPUTest, RES_1_H) {

TEST_F(CB_OpcodesCPUTest, RES_1_L) {
cpu.reg(ProcessingUnit::Register::L) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_1_l(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::L), 0xFD);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -150,7 +150,7 @@ TEST_F(CB_OpcodesCPUTest, RES_1_HL) {
cpu.reg(ProcessingUnit::Register::H) = 0xC0;
cpu.reg(ProcessingUnit::Register::L) = 0x00;
mmu.write(addr, 0xFF);
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_1_hl(cpu, mmu);
EXPECT_EQ(mmu.read(addr), 0xFD);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -159,7 +159,7 @@ TEST_F(CB_OpcodesCPUTest, RES_1_HL) {

TEST_F(CB_OpcodesCPUTest, RES_1_A) {
cpu.reg(ProcessingUnit::Register::A) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_1_a(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::A), 0xFD);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand Down
32 changes: 16 additions & 16 deletions tests/op_tests/cb_op_09_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class CB_OpcodesCPUTest : public testing::Test {
// --- RES 2 ---
TEST_F(CB_OpcodesCPUTest, RES_2_B) {
cpu.reg(ProcessingUnit::Register::B) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_2_b(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::B), 0xFB);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -22,7 +22,7 @@ TEST_F(CB_OpcodesCPUTest, RES_2_B) {

TEST_F(CB_OpcodesCPUTest, RES_2_C) {
cpu.reg(ProcessingUnit::Register::C) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_2_c(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::C), 0xFB);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -31,7 +31,7 @@ TEST_F(CB_OpcodesCPUTest, RES_2_C) {

TEST_F(CB_OpcodesCPUTest, RES_2_D) {
cpu.reg(ProcessingUnit::Register::D) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_2_d(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::D), 0xFB);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -40,7 +40,7 @@ TEST_F(CB_OpcodesCPUTest, RES_2_D) {

TEST_F(CB_OpcodesCPUTest, RES_2_E) {
cpu.reg(ProcessingUnit::Register::E) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_2_e(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::E), 0xFB);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -49,7 +49,7 @@ TEST_F(CB_OpcodesCPUTest, RES_2_E) {

TEST_F(CB_OpcodesCPUTest, RES_2_H) {
cpu.reg(ProcessingUnit::Register::H) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_2_h(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::H), 0xFB);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -58,7 +58,7 @@ TEST_F(CB_OpcodesCPUTest, RES_2_H) {

TEST_F(CB_OpcodesCPUTest, RES_2_L) {
cpu.reg(ProcessingUnit::Register::L) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_2_l(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::L), 0xFB);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -70,7 +70,7 @@ TEST_F(CB_OpcodesCPUTest, RES_2_HL) {
cpu.reg(ProcessingUnit::Register::H) = 0xC0;
cpu.reg(ProcessingUnit::Register::L) = 0x00;
mmu.write(addr, 0xFF);
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_2_hl(cpu, mmu);
EXPECT_EQ(mmu.read(addr), 0xFB);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -79,7 +79,7 @@ TEST_F(CB_OpcodesCPUTest, RES_2_HL) {

TEST_F(CB_OpcodesCPUTest, RES_2_A) {
cpu.reg(ProcessingUnit::Register::A) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_2_a(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::A), 0xFB);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -89,7 +89,7 @@ TEST_F(CB_OpcodesCPUTest, RES_2_A) {
// --- RES 3 ---
TEST_F(CB_OpcodesCPUTest, RES_3_B) {
cpu.reg(ProcessingUnit::Register::B) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_3_b(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::B), 0xF7);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -98,7 +98,7 @@ TEST_F(CB_OpcodesCPUTest, RES_3_B) {

TEST_F(CB_OpcodesCPUTest, RES_3_C) {
cpu.reg(ProcessingUnit::Register::C) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_3_c(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::C), 0xF7);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -107,7 +107,7 @@ TEST_F(CB_OpcodesCPUTest, RES_3_C) {

TEST_F(CB_OpcodesCPUTest, RES_3_D) {
cpu.reg(ProcessingUnit::Register::D) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_3_d(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::D), 0xF7);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -116,7 +116,7 @@ TEST_F(CB_OpcodesCPUTest, RES_3_D) {

TEST_F(CB_OpcodesCPUTest, RES_3_E) {
cpu.reg(ProcessingUnit::Register::E) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_3_e(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::E), 0xF7);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -125,7 +125,7 @@ TEST_F(CB_OpcodesCPUTest, RES_3_E) {

TEST_F(CB_OpcodesCPUTest, RES_3_H) {
cpu.reg(ProcessingUnit::Register::H) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_3_h(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::H), 0xF7);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -134,7 +134,7 @@ TEST_F(CB_OpcodesCPUTest, RES_3_H) {

TEST_F(CB_OpcodesCPUTest, RES_3_L) {
cpu.reg(ProcessingUnit::Register::L) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_3_l(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::L), 0xF7);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -146,7 +146,7 @@ TEST_F(CB_OpcodesCPUTest, RES_3_HL) {
cpu.reg(ProcessingUnit::Register::H) = 0xC0;
cpu.reg(ProcessingUnit::Register::L) = 0x00;
mmu.write(addr, 0xFF);
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_3_hl(cpu, mmu);
EXPECT_EQ(mmu.read(addr), 0xF7);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand All @@ -155,7 +155,7 @@ TEST_F(CB_OpcodesCPUTest, RES_3_HL) {

TEST_F(CB_OpcodesCPUTest, RES_3_A) {
cpu.reg(ProcessingUnit::Register::A) = 0xFF;
cpu.reg(ProcessingUnit::Register::F) = 0xF0;
cpu.normalizeFlags();
int cycles = op_res_3_a(cpu, mmu);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::A), 0xF7);
EXPECT_EQ(cpu.reg(ProcessingUnit::Register::F), 0xF0);
Expand Down
Loading
Loading