diff --git a/src/opcode/handler/bitwise-opcode-handler-container.cpp b/src/opcode/handler/bitwise-opcode-handler-container.cpp index dcdee18..c2bec09 100644 --- a/src/opcode/handler/bitwise-opcode-handler-container.cpp +++ b/src/opcode/handler/bitwise-opcode-handler-container.cpp @@ -208,22 +208,26 @@ namespace emu_6502 { bit(machine, get_abs_address(machine)); } - void BitwiseOpcodeHandlerContainer::asl_at(Machine& machine, uint16_t address) { - uint16_t result = machine.get_memory().get_at(address) << 1; - machine.get_memory().set_at(address, result); + void BitwiseOpcodeHandlerContainer::asl(emu_6502::Machine& machine, function get_value, + function set_value) { + uint16_t result = get_value() << 1; + set_value(result); auto& ps = machine.get_cpu().get_ps(); ps.set_carry((result & 0x100) == 0x100); set_zero_and_neg_flags(ps, result); } - void BitwiseOpcodeHandlerContainer::asl_acc(Machine& machine) { - uint16_t result = machine.get_cpu().get_a().get_value() << 1; - machine.get_cpu().get_a().set_value(result); + void BitwiseOpcodeHandlerContainer::asl_at(Machine& machine, uint16_t address) { + asl(machine, + [&]() { return machine.get_memory().get_at(address); }, + [&](uint8_t value) { machine.get_memory().set_at(address, value); }); + } - auto& ps = machine.get_cpu().get_ps(); - ps.set_carry((result & 0x100) == 0x100); - set_zero_and_neg_flags(ps, result); + void BitwiseOpcodeHandlerContainer::asl_acc(Machine& machine) { + asl(machine, + [&]() { return machine.get_cpu().get_a().get_value(); }, + [&](uint8_t value) { machine.get_cpu().get_a().set_value(value); }); } void BitwiseOpcodeHandlerContainer::asl_zpg(Machine& machine) { @@ -242,24 +246,27 @@ namespace emu_6502 { asl_at(machine, get_abs_x_address(machine)); } - void BitwiseOpcodeHandlerContainer::lsr_at(Machine& machine, uint16_t address) { - auto orig = machine.get_memory().get_at(address); + void BitwiseOpcodeHandlerContainer::lsr(emu_6502::Machine& machine, function get_value, + function set_value) { + auto orig = get_value(); auto result = orig >> 1; - machine.get_memory().set_at(address, result); + set_value(result); auto& ps = machine.get_cpu().get_ps(); ps.set_carry((orig & 1) == 1); ps.set_zero(result == 0); } - void BitwiseOpcodeHandlerContainer::lsr_acc(Machine& machine) { - auto orig = machine.get_cpu().get_a().get_value(); - auto result = orig >> 1; - machine.get_cpu().get_a().set_value(result); + void BitwiseOpcodeHandlerContainer::lsr_at(Machine& machine, uint16_t address) { + lsr(machine, + [&]() { return machine.get_memory().get_at(address); }, + [&](uint8_t value) { machine.get_memory().set_at(address, value); }); + } - auto& ps = machine.get_cpu().get_ps(); - ps.set_carry((orig & 1) == 1); - ps.set_zero(result == 0); + void BitwiseOpcodeHandlerContainer::lsr_acc(Machine& machine) { + lsr(machine, + [&]() { return machine.get_cpu().get_a().get_value(); }, + [&](uint8_t value) { machine.get_cpu().get_a().set_value(value); }); } void BitwiseOpcodeHandlerContainer::lsr_zpg(Machine& machine) { @@ -278,28 +285,28 @@ namespace emu_6502 { lsr_at(machine, get_abs_x_address(machine)); } - void BitwiseOpcodeHandlerContainer::rol_at(Machine& machine, uint16_t address) { - uint16_t result = machine.get_memory().get_at(address) << 1; - + void BitwiseOpcodeHandlerContainer::rol(emu_6502::Machine& machine, function get_value, + function set_value) { + uint16_t result = get_value() << 1; auto& ps = machine.get_cpu().get_ps(); if (ps.is_carry_set()) result += 1; - machine.get_memory().set_at(address, result); + set_value(result); ps.set_carry((result & 0x100) == 0x100); set_zero_and_neg_flags(ps, result); } + void BitwiseOpcodeHandlerContainer::rol_at(Machine& machine, uint16_t address) { + rol(machine, + [&]() { return machine.get_memory().get_at(address); }, + [&](uint8_t value) { machine.get_memory().set_at(address, value); }); + } + void BitwiseOpcodeHandlerContainer::rol_acc(Machine& machine) { - uint16_t result = machine.get_cpu().get_a().get_value() << 1; - - auto& ps = machine.get_cpu().get_ps(); - if (ps.is_carry_set()) - result += 1; - - machine.get_cpu().get_a().set_value(result); - ps.set_carry((result & 0x100) == 0x100); - set_zero_and_neg_flags(ps, result); + rol(machine, + [&]() { return machine.get_cpu().get_a().get_value(); }, + [&](uint8_t value) { machine.get_cpu().get_a().set_value(value); }); } void BitwiseOpcodeHandlerContainer::rol_zpg(Machine& machine) { @@ -318,30 +325,30 @@ namespace emu_6502 { rol_at(machine, get_abs_x_address(machine)); } - void BitwiseOpcodeHandlerContainer::ror_at(Machine& machine, uint16_t address) { - auto orig = machine.get_memory().get_at(address); + void BitwiseOpcodeHandlerContainer::ror(Machine& machine, function get_value, + function set_value) { + auto orig = get_value(); auto result = orig >> 1; auto& ps = machine.get_cpu().get_ps(); if (ps.is_carry_set()) result += 0x80; - machine.get_memory().set_at(address, result); + set_value(result); ps.set_carry((orig & 1) == 1); set_zero_and_neg_flags(ps, result); } + void BitwiseOpcodeHandlerContainer::ror_at(Machine& machine, uint16_t address) { + ror(machine, + [&]() { return machine.get_memory().get_at(address); }, + [&](uint8_t value) { machine.get_memory().set_at(address, value); }); + } + void BitwiseOpcodeHandlerContainer::ror_acc(Machine& machine) { - auto orig = machine.get_cpu().get_a().get_value(); - auto result = orig >> 1; - - auto& ps = machine.get_cpu().get_ps(); - if (ps.is_carry_set()) - result += 0x80; - - machine.get_cpu().get_a().set_value(result); - ps.set_carry((orig & 1) == 1); - set_zero_and_neg_flags(ps, result); + ror(machine, + [&]() { return machine.get_cpu().get_a().get_value(); }, + [&](uint8_t value) { machine.get_cpu().get_a().set_value(value); }); } void BitwiseOpcodeHandlerContainer::ror_zpg(Machine& machine) { diff --git a/src/opcode/handler/bitwise-opcode-handler-container.h b/src/opcode/handler/bitwise-opcode-handler-container.h index cbab570..39d76a5 100644 --- a/src/opcode/handler/bitwise-opcode-handler-container.h +++ b/src/opcode/handler/bitwise-opcode-handler-container.h @@ -3,6 +3,7 @@ #include "opcode-handler-container.h" + namespace emu_6502 { class BitwiseOpcodeHandlerContainer : public OpcodeHandlerContainer { private: @@ -99,6 +100,7 @@ namespace emu_6502 { void bit_zpg(Machine& machine); void bit_abs(Machine& machine); + void asl(Machine& machine, function get_value, function set_value); void asl_at(Machine& machine, uint16_t address); void asl_acc(Machine& machine); void asl_zpg(Machine& machine); @@ -106,6 +108,7 @@ namespace emu_6502 { void asl_abs(Machine& machine); void asl_abs_x(Machine& machine); + void lsr(Machine& machine, function get_value, function set_value); void lsr_at(Machine& machine, uint16_t address); void lsr_acc(Machine& machine); void lsr_zpg(Machine& machine); @@ -113,6 +116,7 @@ namespace emu_6502 { void lsr_abs(Machine& machine); void lsr_abs_x(Machine& machine); + void rol(Machine& machine, function get_value, function set_value); void rol_at(Machine& machine, uint16_t address); void rol_acc(Machine& machine); void rol_zpg(Machine& machine); @@ -120,6 +124,7 @@ namespace emu_6502 { void rol_abs(Machine& machine); void rol_abs_x(Machine& machine); + void ror(Machine& machine, function get_value, function set_value); void ror_at(Machine& machine, uint16_t address); void ror_acc(Machine& machine); void ror_zpg(Machine& machine); diff --git a/src/opcode/handler/compare-opcode-handler-container.cpp b/src/opcode/handler/compare-opcode-handler-container.cpp index f7d1ed8..27f5839 100644 --- a/src/opcode/handler/compare-opcode-handler-container.cpp +++ b/src/opcode/handler/compare-opcode-handler-container.cpp @@ -1,6 +1,95 @@ #include "compare-opcode-handler-container.h" +#include "../../utils.h" namespace emu_6502 { CompareOpcodeHandlerContainer::CompareOpcodeHandlerContainer() { + handlers.insert({Op::CMP_IMM, [this](Machine& machine) { cmp_imm(machine); }}); + handlers.insert({Op::CMP_ZPG, [this](Machine& machine) { cmp_zpg(machine); }}); + handlers.insert({Op::CMP_ZPG_X, [this](Machine& machine) { cmp_zpg_x(machine); }}); + handlers.insert({Op::CMP_ABS, [this](Machine& machine) { cmp_abs(machine); }}); + handlers.insert({Op::CMP_ABS_X, [this](Machine& machine) { cmp_abs_x(machine); }}); + handlers.insert({Op::CMP_ABS_Y, [this](Machine& machine) { cmp_abs_y(machine); }}); + handlers.insert({Op::CMP_IND_X, [this](Machine& machine) { cmp_ind_x(machine); }}); + handlers.insert({Op::CMP_IND_Y, [this](Machine& machine) { cmp_ind_y(machine); }}); + + handlers.insert({Op::CPX_IMM, [this](Machine& machine) { cpx_imm(machine); }}); + handlers.insert({Op::CPX_ZPG, [this](Machine& machine) { cpx_zpg(machine); }}); + handlers.insert({Op::CPX_ABS, [this](Machine& machine) { cpx_abs(machine); }}); + + handlers.insert({Op::CPY_IMM, [this](Machine& machine) { cpy_imm(machine); }}); + handlers.insert({Op::CPY_ZPG, [this](Machine& machine) { cpy_zpg(machine); }}); + handlers.insert({Op::CPY_ABS, [this](Machine& machine) { cpy_abs(machine); }}); } -} \ No newline at end of file + + void CompareOpcodeHandlerContainer::cmp(Machine& machine, Register& reg, uint8_t value) { + auto reg_val = reg.get_value(); + uint8_t result = reg_val - value; + auto& ps = machine.get_cpu().get_ps(); + + ps.set_carry(false); + ps.set_zero(false); + + if (reg_val >= value) + ps.set_carry(true); + if (reg_val == value) + ps.set_zero(true); + if ((result & 0x80) == 0x80) + ps.set_negative(true); + } + + void CompareOpcodeHandlerContainer::cmp_imm(Machine& machine) { + cmp(machine, machine.get_cpu().get_a(), machine.read_program_byte()); + } + + void CompareOpcodeHandlerContainer::cmp_zpg(Machine& machine) { + cmp(machine, machine.get_cpu().get_a(), machine.get_memory().get_at(get_zpg_address(machine))); + } + + void CompareOpcodeHandlerContainer::cmp_zpg_x(Machine& machine) { + cmp(machine, machine.get_cpu().get_a(), machine.get_memory().get_at(get_zpg_x_address(machine))); + } + + void CompareOpcodeHandlerContainer::cmp_abs(Machine& machine) { + cmp(machine, machine.get_cpu().get_a(), machine.get_memory().get_at(get_abs_address(machine))); + } + + void CompareOpcodeHandlerContainer::cmp_abs_x(Machine& machine) { + cmp(machine, machine.get_cpu().get_a(), machine.get_memory().get_at(get_abs_x_address(machine))); + } + + void CompareOpcodeHandlerContainer::cmp_abs_y(Machine& machine) { + cmp(machine, machine.get_cpu().get_a(), machine.get_memory().get_at(get_abs_y_address(machine))); + } + + void CompareOpcodeHandlerContainer::cmp_ind_x(Machine& machine) { + cmp(machine, machine.get_cpu().get_a(), machine.get_memory().get_at(get_ind_x_address(machine))); + } + + void CompareOpcodeHandlerContainer::cmp_ind_y(Machine& machine) { + cmp(machine, machine.get_cpu().get_a(), machine.get_memory().get_at(get_ind_y_address(machine))); + } + + void CompareOpcodeHandlerContainer::cpx_imm(Machine& machine) { + cmp(machine, machine.get_cpu().get_x(), machine.read_program_byte()); + } + + void CompareOpcodeHandlerContainer::cpx_zpg(Machine& machine) { + cmp(machine, machine.get_cpu().get_x(), machine.get_memory().get_at(get_zpg_address(machine))); + } + + void CompareOpcodeHandlerContainer::cpx_abs(Machine& machine) { + cmp(machine, machine.get_cpu().get_x(), machine.get_memory().get_at(get_abs_address(machine))); + } + + void CompareOpcodeHandlerContainer::cpy_imm(Machine& machine) { + cmp(machine, machine.get_cpu().get_y(), machine.read_program_byte()); + } + + void CompareOpcodeHandlerContainer::cpy_zpg(Machine& machine) { + cmp(machine, machine.get_cpu().get_y(), machine.get_memory().get_at(get_zpg_address(machine))); + } + + void CompareOpcodeHandlerContainer::cpy_abs(Machine& machine) { + cmp(machine, machine.get_cpu().get_y(), machine.get_memory().get_at(get_abs_address(machine))); + } +} diff --git a/src/opcode/handler/compare-opcode-handler-container.h b/src/opcode/handler/compare-opcode-handler-container.h index cb65adc..fbde2f5 100644 --- a/src/opcode/handler/compare-opcode-handler-container.h +++ b/src/opcode/handler/compare-opcode-handler-container.h @@ -2,6 +2,7 @@ #define INC_6502_EMULATOR_COMPARE_OPCODE_HANDLER_CONTAINER_H #include "opcode-handler-container.h" +#include "../../machine/register.h" namespace emu_6502 { class CompareOpcodeHandlerContainer : public OpcodeHandlerContainer { @@ -9,7 +10,7 @@ namespace emu_6502 { enum Op { CMP_IMM = 0xC9, CMP_ZPG = 0xC5, - CMP_ZPX_X = 0xD5, + CMP_ZPG_X = 0xD5, CMP_ABS = 0xCD, CMP_ABS_X = 0xDD, CMP_ABS_Y = 0xD9, @@ -20,11 +21,30 @@ namespace emu_6502 { CPX_ZPG = 0xE4, CPX_ABS = 0xEC, - CPY_IMM = 0x0, - CPY_ZPG = 0x0, - CPY_ABS = 0x0, + CPY_IMM = 0xC0, + CPY_ZPG = 0xC4, + CPY_ABS = 0xCC, }; + void cmp(Machine& machine, Register& reg, uint8_t value); + + void cmp_imm(Machine& machine); + void cmp_zpg(Machine& machine); + void cmp_zpg_x(Machine& machine); + void cmp_abs(Machine& machine); + void cmp_abs_x(Machine& machine); + void cmp_abs_y(Machine& machine); + void cmp_ind_x(Machine& machine); + void cmp_ind_y(Machine& machine); + + void cpx_imm(Machine& machine); + void cpx_zpg(Machine& machine); + void cpx_abs(Machine& machine); + + void cpy_imm(Machine& machine); + void cpy_zpg(Machine& machine); + void cpy_abs(Machine& machine); + public: CompareOpcodeHandlerContainer(); CompareOpcodeHandlerContainer(const CompareOpcodeHandlerContainer&) = delete; diff --git a/src/opcode/opcode-handler-directory.cpp b/src/opcode/opcode-handler-directory.cpp index 7c363b3..a4578c5 100644 --- a/src/opcode/opcode-handler-directory.cpp +++ b/src/opcode/opcode-handler-directory.cpp @@ -5,6 +5,7 @@ #include "handler/maths-opcode-handler-container.h" #include "handler/bitwise-opcode-handler-container.h" #include "handler/status-opcode-handler-container.h" +#include "handler/compare-opcode-handler-container.h" #include "../utils.h" namespace emu_6502 { @@ -16,6 +17,7 @@ namespace emu_6502 { handler_containers.push_back(make_unique()); handler_containers.push_back(make_unique()); handler_containers.push_back(make_unique()); + handler_containers.push_back(make_unique()); init_handlers(); } diff --git a/test/compare-opcode-handler-test.cpp b/test/compare-opcode-handler-test.cpp new file mode 100644 index 0000000..c85db49 --- /dev/null +++ b/test/compare-opcode-handler-test.cpp @@ -0,0 +1,259 @@ +#include "gtest/gtest.h" +#include "test-utils.h" + +using namespace std; +using namespace emu_6502; + +const uint8_t CMP_IMM = 0xC9; +const uint8_t CMP_ZPG = 0xC5; +const uint8_t CMP_ZPG_X = 0xD5; +const uint8_t CMP_ABS = 0xCD; +const uint8_t CMP_ABS_X = 0xDD; +const uint8_t CMP_ABS_Y = 0xD9; +const uint8_t CMP_IND_X = 0xC1; +const uint8_t CMP_IND_Y = 0xD1; + +const uint8_t CPX_IMM = 0xE0; +const uint8_t CPX_ZPG = 0xE4; +const uint8_t CPX_ABS = 0xEC; + +const uint8_t CPY_IMM = 0xC0; +const uint8_t CPY_ZPG = 0xC4; +const uint8_t CPY_ABS = 0xCC; + +TEST(CompareOpcodeHandlerContainer, CMP_IMM_Equal) { + auto machine = create_machine({CMP_IMM, 100}); + machine->get_cpu().get_a().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_a().get_value()); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CMP_IMM_LessThan) { + auto machine = create_machine({CMP_IMM, 100}); + machine->get_cpu().get_a().set_value(99); + machine->execute(); + + ASSERT_EQ(99, machine->get_cpu().get_a().get_value()); + + RegisterFlagSet flags{}; + flags.negative = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CMP_IMM_GreaterThan) { + auto machine = create_machine({CMP_IMM, 100}); + machine->get_cpu().get_a().set_value(101); + machine->execute(); + + ASSERT_EQ(101, machine->get_cpu().get_a().get_value()); + + RegisterFlagSet flags{}; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CMP_ZPG) { + auto machine = create_machine({CMP_ZPG, 0x10}); + machine->get_memory().set_at(0x10, 100); + machine->get_cpu().get_a().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_a().get_value()); + ASSERT_EQ(100, machine->get_memory().get_at(0x10)); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CMP_ZPG_X) { + auto machine = create_machine({CMP_ZPG_X, 0x10}); + machine->get_cpu().get_x().set_value(0x5); + machine->get_memory().set_at(0x15, 100); + machine->get_cpu().get_a().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_a().get_value()); + ASSERT_EQ(100, machine->get_memory().get_at(0x15)); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CMP_ABS) { + auto machine = create_machine({CMP_ABS, 0x10, 0x2a}); + machine->get_memory().set_at(0x2a10, 100); + machine->get_cpu().get_a().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_a().get_value()); + ASSERT_EQ(100, machine->get_memory().get_at(0x2a10)); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CMP_ABS_X) { + auto machine = create_machine({CMP_ABS_X, 0x10, 0x2a}); + machine->get_cpu().get_x().set_value(0x5); + machine->get_memory().set_at(0x2a15, 100); + machine->get_cpu().get_a().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_a().get_value()); + ASSERT_EQ(100, machine->get_memory().get_at(0x2a15)); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CMP_ABS_Y) { + auto machine = create_machine({CMP_ABS_Y, 0x10, 0x2a}); + machine->get_cpu().get_y().set_value(0x7); + machine->get_memory().set_at(0x2a17, 100); + machine->get_cpu().get_a().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_a().get_value()); + ASSERT_EQ(100, machine->get_memory().get_at(0x2a17)); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CMP_IND_X) { + auto machine = create_machine({CMP_IND_X, 0x55}); + machine->get_cpu().get_x().set_value(0x22); + machine->get_cpu().get_a().set_value(100); + machine->get_memory().set_at(0x77, 0x34); + machine->get_memory().set_at(0x78, 0x12); + machine->get_memory().set_at(0x1234, 100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_a().get_value()); + ASSERT_EQ(100, machine->get_memory().get_at(0x1234)); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CMP_IND_Y) { + auto machine = create_machine({CMP_IND_Y, 0x41}); + machine->get_cpu().get_y().set_value(0x22); + machine->get_cpu().get_a().set_value(100); + machine->get_memory().set_at(0x41, 0x34); + machine->get_memory().set_at(0x42, 0x12); + machine->get_memory().set_at(0x1256, 100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_a().get_value()); + ASSERT_EQ(100, machine->get_memory().get_at(0x1256)); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CPX_IMM) { + auto machine = create_machine({CPX_IMM, 100}); + machine->get_cpu().get_x().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_x().get_value()); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CPX_ZPG) { + auto machine = create_machine({CPX_ZPG, 0x10}); + machine->get_memory().set_at(0x10, 100); + machine->get_cpu().get_x().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_x().get_value()); + ASSERT_EQ(100, machine->get_memory().get_at(0x10)); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CPX_ABS) { + auto machine = create_machine({CPX_ABS, 0x10, 0x2a}); + machine->get_memory().set_at(0x2a10, 100); + machine->get_cpu().get_x().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_x().get_value()); + ASSERT_EQ(100, machine->get_memory().get_at(0x2a10)); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CPY_IMM) { + auto machine = create_machine({CPY_IMM, 100}); + machine->get_cpu().get_y().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_y().get_value()); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CPY_ZPG) { + auto machine = create_machine({CPY_ZPG, 0x10}); + machine->get_memory().set_at(0x10, 100); + machine->get_cpu().get_y().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_y().get_value()); + ASSERT_EQ(100, machine->get_memory().get_at(0x10)); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(CompareOpcodeHandlerContainer, CPY_ABS) { + auto machine = create_machine({CPY_ABS, 0x10, 0x2a}); + machine->get_memory().set_at(0x2a10, 100); + machine->get_cpu().get_y().set_value(100); + machine->execute(); + + ASSERT_EQ(100, machine->get_cpu().get_y().get_value()); + ASSERT_EQ(100, machine->get_memory().get_at(0x2a10)); + + RegisterFlagSet flags{}; + flags.zero = true; + flags.carry = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +}