diff --git a/src/opcode/handler/load-opcode-handler-container.cpp b/src/opcode/handler/load-opcode-handler-container.cpp index 641adc1..5b75b8a 100644 --- a/src/opcode/handler/load-opcode-handler-container.cpp +++ b/src/opcode/handler/load-opcode-handler-container.cpp @@ -45,48 +45,34 @@ namespace emu_6502 { } void LoadOpcodeHandlerContainer::ld_zpg(Machine& machine, Register& reg) { - auto addr = get_zpg_address(machine.read_program_byte()); - set_from(machine, reg, addr); + set_from(machine, reg, get_zpg_address(machine)); } void LoadOpcodeHandlerContainer::ld_zpg_x(Machine& machine, Register& reg) { - auto addr = get_zpg_x_address(machine.read_program_byte(), machine.get_cpu()); - set_from(machine, reg, addr); + set_from(machine, reg, get_zpg_x_address(machine)); } void LoadOpcodeHandlerContainer::ld_zpg_y(Machine& machine, Register& reg) { - auto addr = get_zpg_y_address(machine.read_program_byte(), machine.get_cpu()); - set_from(machine, reg, addr); + set_from(machine, reg, get_zpg_y_address(machine)); } void LoadOpcodeHandlerContainer::ld_abs(Machine& machine, Register& reg) { - auto low = machine.read_program_byte(); - auto high = machine.read_program_byte(); - auto addr = get_abs_address(low, high); - set_from(machine, reg, addr); + set_from(machine, reg, get_abs_address(machine)); } void LoadOpcodeHandlerContainer::ld_abs_x(Machine& machine, Register& reg) { - auto low = machine.read_program_byte(); - auto high = machine.read_program_byte(); - auto addr = get_abs_x_address(low, high, machine.get_cpu()); - set_from(machine, reg, addr); + set_from(machine, reg, get_abs_x_address(machine)); } void LoadOpcodeHandlerContainer::ld_abs_y(Machine& machine, Register& reg) { - auto low = machine.read_program_byte(); - auto high = machine.read_program_byte(); - auto addr = get_abs_y_address(low, high, machine.get_cpu()); - set_from(machine, reg, addr); + set_from(machine, reg, get_abs_y_address(machine)); } void LoadOpcodeHandlerContainer::ld_ind_x(Machine& machine, Register& reg) { - auto addr = get_ind_x_address(machine.read_program_byte(), machine); - set_from(machine, reg, addr); + set_from(machine, reg, get_ind_x_address(machine)); } void LoadOpcodeHandlerContainer::ld_ind_y(Machine& machine, Register& reg) { - auto addr = get_ind_y_address(machine.read_program_byte(), machine); - set_from(machine, reg, addr); + set_from(machine, reg, get_ind_y_address(machine)); } } \ No newline at end of file diff --git a/src/opcode/handler/maths-opcode-handler-container.cpp b/src/opcode/handler/maths-opcode-handler-container.cpp index e2cec86..d3d2db7 100644 --- a/src/opcode/handler/maths-opcode-handler-container.cpp +++ b/src/opcode/handler/maths-opcode-handler-container.cpp @@ -11,12 +11,33 @@ namespace emu_6502 { handlers.insert({Op::ADC_ABS_Y, [this](Machine& machine) { adc_abs_y(machine); }}); handlers.insert({Op::ADC_IND_X, [this](Machine& machine) { adc_ind_x(machine); }}); handlers.insert({Op::ADC_IND_Y, [this](Machine& machine) { adc_ind_y(machine); }}); + + handlers.insert({Op::DEC_ZPG, [this](Machine& machine) { dec_zpg(machine); }}); + handlers.insert({Op::DEC_ZPG_X, [this](Machine& machine) { dec_zpg_x(machine); }}); + handlers.insert({Op::DEC_ABS, [this](Machine& machine) { dec_abs(machine); }}); + handlers.insert({Op::DEC_ABS_X, [this](Machine& machine) { dec_abs_x(machine); }}); + + handlers.insert({Op::INC_ZPG, [this](Machine& machine) { inc_zpg(machine); }}); + handlers.insert({Op::INC_ZPG_X, [this](Machine& machine) { inc_zpg_x(machine); }}); + handlers.insert({Op::INC_ABS, [this](Machine& machine) { inc_abs(machine); }}); + handlers.insert({Op::INC_ABS_X, [this](Machine& machine) { inc_abs_x(machine); }}); + + handlers.insert({Op::INX, [this](Machine& machine) { inx(machine); }}); + handlers.insert({Op::INY, [this](Machine& machine) { iny(machine); }}); + handlers.insert({Op::DEX, [this](Machine& machine) { dex(machine); }}); + handlers.insert({Op::DEY, [this](Machine& machine) { dey(machine); }}); } - void MathsOpcodeHandlerContainer::adc(Machine& machine, uint8_t value){ + void MathsOpcodeHandlerContainer::set_zero_neg(StatusRegister& ps, uint8_t value) { + ps.set_zero(value == 0); + ps.set_negative((value & 0x80) == 0x80); + } + + void MathsOpcodeHandlerContainer::adc(Machine& machine, uint8_t value) { auto& cpu = machine.get_cpu(); auto init_a = cpu.get_a().get_value(); + // allow for operation to breach 8 bits uint16_t result = value + init_a; if (cpu.get_ps().is_carry_set()) result += 1; @@ -25,8 +46,7 @@ namespace emu_6502 { auto a = cpu.get_a().get_value(); // 'a' may be 0 if the result wasn't 0, i.e. the cary bit is set - cpu.get_ps().set_zero(a == 0); - cpu.get_ps().set_negative((a & 0x80) == 0x80); + set_zero_neg(cpu.get_ps(), a); cpu.get_ps().set_carry(result > 0xFF); cpu.get_ps().set_overflow( (value < 0x7F && init_a < 0x7F && a > 0x7F) || @@ -38,64 +58,107 @@ namespace emu_6502 { } void MathsOpcodeHandlerContainer::adc_zpg(Machine& machine) { - auto addr = get_zpg_address(machine.read_program_byte()); - adc(machine, machine.get_memory().get_at(addr)); + adc(machine, machine.get_memory().get_at(get_zpg_address(machine))); } void MathsOpcodeHandlerContainer::adc_zpg_x(Machine& machine) { - auto addr = get_zpg_x_address(machine.read_program_byte(), machine.get_cpu()); - adc(machine, machine.get_memory().get_at(addr)); + adc(machine, machine.get_memory().get_at(get_zpg_x_address(machine))); } void MathsOpcodeHandlerContainer::adc_abs(Machine& machine) { - auto low = machine.read_program_byte(); - auto high = machine.read_program_byte(); - auto addr = get_abs_address(low, high); - adc(machine, machine.get_memory().get_at(addr)); + adc(machine, machine.get_memory().get_at(get_abs_address(machine))); } void MathsOpcodeHandlerContainer::adc_abs_x(Machine& machine) { - auto addr = get_abs_x_address(machine, machine.get_cpu()); - adc(machine, machine.get_memory().get_at(addr)); + adc(machine, machine.get_memory().get_at(get_abs_x_address(machine))); } void MathsOpcodeHandlerContainer::adc_abs_y(Machine& machine) { - auto addr = get_abs_y_address(machine, machine.get_cpu()); - adc(machine, machine.get_memory().get_at(addr)); + adc(machine, machine.get_memory().get_at(get_abs_y_address(machine))); } void MathsOpcodeHandlerContainer::adc_ind_x(Machine& machine) { - auto addr = get_ind_x_address(machine.read_program_byte(), machine); - adc(machine, machine.get_memory().get_at(addr)); + adc(machine, machine.get_memory().get_at(get_ind_x_address(machine))); } void MathsOpcodeHandlerContainer::adc_ind_y(Machine& machine) { - auto addr = get_ind_y_address(machine.read_program_byte(), machine); - adc(machine, machine.get_memory().get_at(addr)); + adc(machine, machine.get_memory().get_at(get_ind_y_address(machine))); + } + + void MathsOpcodeHandlerContainer::dec(Machine& machine, uint16_t address) { + uint8_t value = machine.get_memory().get_at(address) - 1; + machine.get_memory().set_at(address, value); + + set_zero_neg(machine.get_cpu().get_ps(), value); } void MathsOpcodeHandlerContainer::dec_zpg(Machine& machine) { + dec(machine, get_zpg_address(machine)); } void MathsOpcodeHandlerContainer::dec_zpg_x(Machine& machine) { + dec(machine, get_zpg_x_address(machine)); } void MathsOpcodeHandlerContainer::dec_abs(Machine& machine) { + dec(machine, get_abs_address(machine)); } void MathsOpcodeHandlerContainer::dec_abs_x(Machine& machine) { + dec(machine, get_abs_x_address(machine)); + } + + void MathsOpcodeHandlerContainer::inc(Machine& machine, uint16_t address) { + uint8_t value = machine.get_memory().get_at(address) + 1; + machine.get_memory().set_at(address, value); + + set_zero_neg(machine.get_cpu().get_ps(), value); + } + + void MathsOpcodeHandlerContainer::inc_zpg(Machine& machine) { + inc(machine, get_zpg_address(machine)); + } + + void MathsOpcodeHandlerContainer::inc_zpg_x(Machine& machine) { + inc(machine, get_zpg_x_address(machine)); + } + + void MathsOpcodeHandlerContainer::inc_abs(Machine& machine) { + inc(machine, get_abs_address(machine)); + } + + void MathsOpcodeHandlerContainer::inc_abs_x(Machine& machine) { + inc(machine, get_abs_x_address(machine)); + } + + void MathsOpcodeHandlerContainer::de(Machine& machine, Register& reg) { + uint8_t value = reg.get_value() - 1; + reg.set_value(value); + + set_zero_neg(machine.get_cpu().get_ps(), value); } void MathsOpcodeHandlerContainer::dex(Machine& machine) { + de(machine, machine.get_cpu().get_x()); } void MathsOpcodeHandlerContainer::dey(Machine& machine) { + de(machine, machine.get_cpu().get_y()); + } + + void MathsOpcodeHandlerContainer::in(Machine& machine, Register& reg) { + uint8_t value = reg.get_value() + 1; + reg.set_value(value); + + set_zero_neg(machine.get_cpu().get_ps(), value); } void MathsOpcodeHandlerContainer::inx(Machine& machine) { + in(machine, machine.get_cpu().get_x()); } void MathsOpcodeHandlerContainer::iny(Machine& machine) { + in(machine, machine.get_cpu().get_y()); } void MathsOpcodeHandlerContainer::sbc_imm(Machine& machine) { diff --git a/src/opcode/handler/maths-opcode-handler-container.h b/src/opcode/handler/maths-opcode-handler-container.h index 6dd124e..7e047e4 100644 --- a/src/opcode/handler/maths-opcode-handler-container.h +++ b/src/opcode/handler/maths-opcode-handler-container.h @@ -41,6 +41,8 @@ namespace emu_6502 { SBC_IND_Y = 0x0 }; + void set_zero_neg(StatusRegister& ps, uint8_t value); + void adc(Machine& machine, uint8_t value); void adc_imm(Machine& machine); void adc_zpg(Machine& machine); @@ -51,13 +53,23 @@ namespace emu_6502 { void adc_ind_x(Machine& machine); void adc_ind_y(Machine& machine); + void dec(Machine& machine, uint16_t address); void dec_zpg(Machine& machine); void dec_zpg_x(Machine& machine); void dec_abs(Machine& machine); void dec_abs_x(Machine& machine); + void inc(Machine& machine, uint16_t address); + void inc_zpg(Machine& machine); + void inc_zpg_x(Machine& machine); + void inc_abs(Machine& machine); + void inc_abs_x(Machine& machine); + + void de(Machine& machine, Register& reg); void dex(Machine& machine); void dey(Machine& machine); + + void in(Machine& machine, Register& reg); void inx(Machine& machine); void iny(Machine& machine); diff --git a/src/opcode/handler/store-opcode-handler-container.cpp b/src/opcode/handler/store-opcode-handler-container.cpp index 7ccb832..43f9ba2 100644 --- a/src/opcode/handler/store-opcode-handler-container.cpp +++ b/src/opcode/handler/store-opcode-handler-container.cpp @@ -25,48 +25,34 @@ namespace emu_6502 { } void StoreOpcodeHandlerContainer::st_zpg(Machine& machine, Register& reg) { - auto addr = get_zpg_address(machine.read_program_byte()); - store_to(machine, reg, addr); + store_to(machine, reg, get_zpg_address(machine)); } void StoreOpcodeHandlerContainer::st_zpg_x(Machine& machine, Register& reg) { - auto addr = get_zpg_x_address(machine.read_program_byte(), machine.get_cpu()); - store_to(machine, reg, addr); + store_to(machine, reg, get_zpg_x_address(machine)); } void StoreOpcodeHandlerContainer::st_zpg_y(Machine& machine, Register& reg) { - auto addr = get_zpg_y_address(machine.read_program_byte(), machine.get_cpu()); - store_to(machine, reg, addr); + store_to(machine, reg, get_zpg_y_address(machine)); } void StoreOpcodeHandlerContainer::st_abs(Machine& machine, Register& reg) { - auto low = machine.read_program_byte(); - auto high = machine.read_program_byte(); - auto addr = get_abs_address(low, high); - store_to(machine, reg, addr); + store_to(machine, reg, get_abs_address(machine)); } void StoreOpcodeHandlerContainer::st_abs_x(Machine& machine, Register& reg) { - auto low = machine.read_program_byte(); - auto high = machine.read_program_byte(); - auto addr = get_abs_x_address(low, high, machine.get_cpu()); - store_to(machine, reg, addr); + store_to(machine, reg, get_abs_x_address(machine)); } void StoreOpcodeHandlerContainer::st_abs_y(Machine& machine, Register& reg) { - auto low = machine.read_program_byte(); - auto high = machine.read_program_byte(); - auto addr = get_abs_y_address(low, high, machine.get_cpu()); - store_to(machine, reg, addr); + store_to(machine, reg, get_abs_y_address(machine)); } void StoreOpcodeHandlerContainer::st_ind_x(Machine& machine, Register& reg) { - auto addr = get_ind_x_address(machine.read_program_byte(), machine); - store_to(machine, reg, addr); + store_to(machine, reg, get_ind_x_address(machine)); } void StoreOpcodeHandlerContainer::st_ind_y(Machine& machine, Register& reg) { - auto addr = get_ind_y_address(machine.read_program_byte(), machine); - store_to(machine, reg, addr); + store_to(machine, reg, get_ind_y_address(machine)); } } \ No newline at end of file diff --git a/src/utils.cpp b/src/utils.cpp index 29f56c0..32b91fb 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -8,49 +8,43 @@ namespace emu_6502 { return ss.str(); } - uint8_t get_zpg_address(uint8_t offset) { - return offset; + uint8_t get_zpg_address(Machine& machine) { + return machine.read_program_byte(); } - uint8_t get_zpg_x_address(uint8_t offset, Cpu& cpu) { + uint8_t get_zpg_x_address(Machine& machine) { // expect wrap around - return offset + cpu.get_x().get_value(); + return machine.read_program_byte() + machine.get_cpu().get_x().get_value(); } - uint8_t get_zpg_y_address(uint8_t offset, Cpu& cpu) { + uint8_t get_zpg_y_address(Machine& machine) { // expect wrap around - return offset + cpu.get_y().get_value(); + return machine.read_program_byte() + machine.get_cpu().get_y().get_value(); } - uint16_t get_abs_address(uint8_t low_byte, uint8_t high_byte) { + uint16_t get_abs_address(Machine& machine) { + auto low_byte = machine.read_program_byte(); + auto high_byte = machine.read_program_byte(); uint16_t address = (high_byte << 8) + low_byte; return address; } - uint16_t get_abs_x_address(uint8_t low_byte, uint8_t high_byte, Cpu& cpu) { - uint16_t address = (high_byte << 8) + low_byte + cpu.get_x().get_value(); + uint16_t get_abs_x_address(Machine& machine) { + auto low_byte = machine.read_program_byte(); + auto high_byte = machine.read_program_byte(); + uint16_t address = (high_byte << 8) + low_byte + machine.get_cpu().get_x().get_value(); return address; } - uint16_t get_abs_y_address(uint8_t low_byte, uint8_t high_byte, Cpu& cpu) { - uint16_t address = (high_byte << 8) + low_byte + cpu.get_y().get_value(); + uint16_t get_abs_y_address(Machine& machine) { + auto low_byte = machine.read_program_byte(); + auto high_byte = machine.read_program_byte(); + uint16_t address = (high_byte << 8) + low_byte + machine.get_cpu().get_y().get_value(); return address; } - uint16_t get_abs_x_address(Machine& machine, Cpu& cpu) { - auto low = machine.read_program_byte(); - auto high = machine.read_program_byte(); - return get_abs_x_address(low, high, machine.get_cpu()); - } - - uint16_t get_abs_y_address(Machine& machine, Cpu& cpu) { - auto low = machine.read_program_byte(); - auto high = machine.read_program_byte(); - return get_abs_y_address(low, high, machine.get_cpu()); - } - - uint16_t get_ind_x_address(uint8_t offset, Machine& machine) { - uint8_t paddress = machine.get_cpu().get_x().get_value() + offset; + uint16_t get_ind_x_address(Machine& machine) { + uint8_t paddress = machine.get_cpu().get_x().get_value() + machine.read_program_byte(); auto low = machine.get_memory().get_at(paddress); auto high = machine.get_memory().get_at(paddress + 1); uint16_t address = (high << 8) + low; @@ -58,7 +52,8 @@ namespace emu_6502 { return address; } - uint16_t get_ind_y_address(uint8_t offset, Machine& machine) { + uint16_t get_ind_y_address(Machine& machine) { + auto offset = machine.read_program_byte(); auto low = machine.get_memory().get_at(offset); auto high = machine.get_memory().get_at(offset + 1); auto y = machine.get_cpu().get_y().get_value(); diff --git a/src/utils.h b/src/utils.h index f5e1d28..43659f0 100644 --- a/src/utils.h +++ b/src/utils.h @@ -9,16 +9,16 @@ using namespace std; namespace emu_6502 { string uint_to_hex(uint64_t value); - uint8_t get_zpg_address(uint8_t offset); - uint8_t get_zpg_x_address(uint8_t offset, Cpu& cpu); - uint8_t get_zpg_y_address(uint8_t offset, Cpu& cpu); - uint16_t get_abs_address(uint8_t low_byte, uint8_t high_byte); - uint16_t get_abs_x_address(uint8_t low_byte, uint8_t high_byte, Cpu& cpu); - uint16_t get_abs_y_address(uint8_t low_byte, uint8_t high_byte, Cpu& cpu); - uint16_t get_abs_x_address(Machine& machine, Cpu& cpu); - uint16_t get_abs_y_address(Machine& machine, Cpu& cpu); - uint16_t get_ind_x_address(uint8_t offset, Machine& machine); - uint16_t get_ind_y_address(uint8_t offset, Machine& machine); + uint8_t get_zpg_address(Machine& machine); + uint8_t get_zpg_x_address(Machine& machine); + uint8_t get_zpg_y_address(Machine& machine); + uint16_t get_abs_address(Machine& machine); + uint16_t get_abs_x_address(Machine& machine); + uint16_t get_abs_y_address(Machine& machine); + uint16_t get_abs_x_address(Machine& machine); + uint16_t get_abs_y_address(Machine& machine); + uint16_t get_ind_x_address(Machine& machine); + uint16_t get_ind_y_address(Machine& machine); } #endif // INC_6502_EMULATOR_UTILS_H \ No newline at end of file diff --git a/test/maths-opcode-handler-test.cpp b/test/maths-opcode-handler-test.cpp index 1bdcc3a..a18b197 100644 --- a/test/maths-opcode-handler-test.cpp +++ b/test/maths-opcode-handler-test.cpp @@ -13,6 +13,21 @@ const uint8_t ADC_ABS_Y = 0x79; const uint8_t ADC_IND_X = 0x61; const uint8_t ADC_IND_Y = 0x71; +const uint8_t DEC_ZPG = 0xC6; +const uint8_t DEC_ZPG_X = 0xD6; +const uint8_t DEC_ABS = 0xCE; +const uint8_t DEC_ABS_X = 0xDE; + +const uint8_t INC_ZPG = 0xE6; +const uint8_t INC_ZPG_X = 0xF6; +const uint8_t INC_ABS = 0xEE; +const uint8_t INC_ABS_X = 0xFE; + +const uint8_t DEX = 0xCA; +const uint8_t DEY = 0x88; +const uint8_t INX = 0xE8; +const uint8_t INY = 0xC8; + TEST(MathsOpcodeHandlerContainer, ADC_IMM) { auto machine = create_machine({ADC_IMM, 36}); machine->get_cpu().get_a().set_value(36); @@ -175,3 +190,211 @@ TEST(MathsOpcodeHandlerContainer, ADC_IND_Y) { ASSERT_EQ(56, machine->get_cpu().get_a().get_value()); ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); } + +TEST(MathsOpcodeHandlerContainer, DEC_ZPG) { + auto machine = create_machine({DEC_ZPG, 0xf1}); + machine->get_memory().set_at(0xf1, 20); + machine->execute(); + + ASSERT_EQ(19, machine->get_memory().get_at(0xf1)); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +} + +TEST(MathsOpcodeHandlerContainer, DEC_ZPG_ZeroFlag) { + auto machine = create_machine({DEC_ZPG, 0xf1}); + machine->get_memory().set_at(0xf1, 1); + machine->execute(); + + ASSERT_EQ(0, machine->get_memory().get_at(0xf1)); + + RegisterFlagSet flags{}; + flags.zero = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(MathsOpcodeHandlerContainer, DEC_ZPG_NegativeFlag) { + auto machine = create_machine({DEC_ZPG, 0xf1}); + machine->get_memory().set_at(0xf1, 0); + machine->execute(); + + ASSERT_EQ(0xFF, machine->get_memory().get_at(0xf1)); + + RegisterFlagSet flags{}; + flags.negative = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(MathsOpcodeHandlerContainer, DEC_ZPG_X) { + auto machine = create_machine({DEC_ZPG_X, 0x45}); + machine->get_cpu().get_x().set_value(0x10); + machine->get_memory().set_at(0x55, 20); + machine->execute(); + + ASSERT_EQ(19, machine->get_memory().get_at(0x55)); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +} + +TEST(MathsOpcodeHandlerContainer, DEC_ABS) { + auto machine = create_machine({DEC_ABS, 0x45, 0x1a}); + machine->get_memory().set_at(0x1a45, 20); + machine->execute(); + + ASSERT_EQ(19, machine->get_memory().get_at(0x1a45)); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +} + +TEST(MathsOpcodeHandlerContainer, DEC_ABS_X) { + auto machine = create_machine({DEC_ABS_X, 0x45, 0x1a}); + machine->get_cpu().get_x().set_value(0x10); + machine->get_memory().set_at(0x1a55, 20); + machine->execute(); + + ASSERT_EQ(19, machine->get_memory().get_at(0x1a55)); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +} + +TEST(MathsOpcodeHandlerContainer, INC_ZPG) { + auto machine = create_machine({INC_ZPG, 0xf1}); + machine->get_memory().set_at(0xf1, 20); + machine->execute(); + + ASSERT_EQ(21, machine->get_memory().get_at(0xf1)); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +} + +TEST(MathsOpcodeHandlerContainer, INC_ZPG_ZeroFlag) { + auto machine = create_machine({INC_ZPG, 0xf1}); + machine->get_memory().set_at(0xf1, 0xff); + machine->execute(); + + ASSERT_EQ(0, machine->get_memory().get_at(0xf1)); + + RegisterFlagSet flags{}; + flags.zero = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(MathsOpcodeHandlerContainer, INC_ZPG_NegativeFlag) { + auto machine = create_machine({INC_ZPG, 0xf1}); + machine->get_memory().set_at(0xf1, 0x7f); + machine->execute(); + + ASSERT_EQ(0x80, machine->get_memory().get_at(0xf1)); + + RegisterFlagSet flags{}; + flags.negative = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(MathsOpcodeHandlerContainer, INC_ZPG_X) { + auto machine = create_machine({INC_ZPG_X, 0x45}); + machine->get_cpu().get_x().set_value(0x10); + machine->get_memory().set_at(0x55, 20); + machine->execute(); + + ASSERT_EQ(21, machine->get_memory().get_at(0x55)); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +} + +TEST(MathsOpcodeHandlerContainer, INC_ABS) { + auto machine = create_machine({INC_ABS, 0x45, 0x1a}); + machine->get_memory().set_at(0x1a45, 20); + machine->execute(); + + ASSERT_EQ(21, machine->get_memory().get_at(0x1a45)); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +} + +TEST(MathsOpcodeHandlerContainer, INC_ABS_X) { + auto machine = create_machine({INC_ABS_X, 0x45, 0x1a}); + machine->get_cpu().get_x().set_value(0x10); + machine->get_memory().set_at(0x1a55, 20); + machine->execute(); + + ASSERT_EQ(21, machine->get_memory().get_at(0x1a55)); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +} + +TEST(MathsOpcodeHandlerContainer, INX) { + auto machine = create_machine({INX}); + machine->get_cpu().get_x().set_value(5); + machine->execute(); + + ASSERT_EQ(6, machine->get_cpu().get_x().get_value()); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +} + +TEST(MathsOpcodeHandlerContainer, INX_ZeroFlag) { + auto machine = create_machine({INX}); + machine->get_cpu().get_x().set_value(0xff); + machine->execute(); + + ASSERT_EQ(0, machine->get_cpu().get_x().get_value()); + + RegisterFlagSet flags{}; + flags.zero = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(MathsOpcodeHandlerContainer, INX_NegativeFlag) { + auto machine = create_machine({INX}); + machine->get_cpu().get_x().set_value(0x7f); + machine->execute(); + + ASSERT_EQ(0x80, machine->get_cpu().get_x().get_value()); + + RegisterFlagSet flags{}; + flags.negative = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(MathsOpcodeHandlerContainer, INY) { + auto machine = create_machine({INY}); + machine->get_cpu().get_y().set_value(5); + machine->execute(); + + ASSERT_EQ(6, machine->get_cpu().get_y().get_value()); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +} + +TEST(MathsOpcodeHandlerContainer, DEX) { + auto machine = create_machine({DEX}); + machine->get_cpu().get_x().set_value(5); + machine->execute(); + + ASSERT_EQ(4, machine->get_cpu().get_x().get_value()); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +} + +TEST(MathsOpcodeHandlerContainer, DEX_ZeroFlag) { + auto machine = create_machine({DEX}); + machine->get_cpu().get_x().set_value(1); + machine->execute(); + + ASSERT_EQ(0, machine->get_cpu().get_x().get_value()); + + RegisterFlagSet flags{}; + flags.zero = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(MathsOpcodeHandlerContainer, DEX_NegativeFlag) { + auto machine = create_machine({DEX}); + machine->get_cpu().get_x().set_value(0); + machine->execute(); + + ASSERT_EQ(0xff, machine->get_cpu().get_x().get_value()); + + RegisterFlagSet flags{}; + flags.negative = true; + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags)); +} + +TEST(MathsOpcodeHandlerContainer, DEY) { + auto machine = create_machine({DEY}); + machine->get_cpu().get_y().set_value(5); + machine->execute(); + + ASSERT_EQ(4, machine->get_cpu().get_y().get_value()); + ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{})); +}