mirror of
https://github.com/tdinucci/6502-emulator.git
synced 2024-09-27 13:55:49 +00:00
Add "adc" instructions
This commit is contained in:
parent
534c5576f8
commit
cab2cec9ff
@ -92,7 +92,7 @@ namespace emu_6502 {
|
|||||||
pimpl->load(program, load_at);
|
pimpl->load(program, load_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Machine::is_eop() {
|
bool Machine::is_eop() const {
|
||||||
return pimpl->is_eop();
|
return pimpl->is_eop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ namespace emu_6502 {
|
|||||||
Memory& get_memory();
|
Memory& get_memory();
|
||||||
Stack& get_stack();
|
Stack& get_stack();
|
||||||
|
|
||||||
bool is_eop();
|
bool is_eop() const;
|
||||||
uint8_t read_program_byte();
|
uint8_t read_program_byte();
|
||||||
void load(const vector<uint8_t>& program, uint16_t load_at);
|
void load(const vector<uint8_t>& program, uint16_t load_at);
|
||||||
void execute();
|
void execute();
|
||||||
|
@ -16,9 +16,9 @@ namespace emu_6502 {
|
|||||||
T value;
|
T value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Register<T>(string name);
|
explicit Register<T>(string name);
|
||||||
Register<T>(const Register<T>&) = delete;
|
Register<T>(const Register<T>&) = delete;
|
||||||
Register<T>& operator=(const Register<T>&) = delete;
|
virtual Register<T>& operator=(const Register<T>&) = delete;
|
||||||
|
|
||||||
const string& get_name() const;
|
const string& get_name() const;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ namespace emu_6502 {
|
|||||||
StatusRegister() : Register<bitset<8>>("PS") {}
|
StatusRegister() : Register<bitset<8>>("PS") {}
|
||||||
|
|
||||||
StatusRegister(const StatusRegister&) = delete;
|
StatusRegister(const StatusRegister&) = delete;
|
||||||
StatusRegister& operator=(const StatusRegister&) = delete;
|
virtual StatusRegister& operator=(const StatusRegister&) = delete;
|
||||||
|
|
||||||
bool is_carry_set() const;
|
bool is_carry_set() const;
|
||||||
bool is_zero_set() const;
|
bool is_zero_set() const;
|
||||||
|
124
src/opcode/handler/maths-opcode-handler-container.cpp
Normal file
124
src/opcode/handler/maths-opcode-handler-container.cpp
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
#include "maths-opcode-handler-container.h"
|
||||||
|
#include "../../utils.h"
|
||||||
|
|
||||||
|
namespace emu_6502 {
|
||||||
|
MathsOpcodeHandlerContainer::MathsOpcodeHandlerContainer() : OpcodeHandlerContainer() {
|
||||||
|
handlers.insert({Op::ADC_IMM, [this](Machine& machine) { adc_imm(machine); }});
|
||||||
|
handlers.insert({Op::ADC_ZPG, [this](Machine& machine) { adc_zpg(machine); }});
|
||||||
|
handlers.insert({Op::ADC_ZPG_X, [this](Machine& machine) { adc_zpg_x(machine); }});
|
||||||
|
handlers.insert({Op::ADC_ABS, [this](Machine& machine) { adc_abs(machine); }});
|
||||||
|
handlers.insert({Op::ADC_ABS_X, [this](Machine& machine) { adc_abs_x(machine); }});
|
||||||
|
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); }});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::adc(Machine& machine, uint8_t value){
|
||||||
|
auto& cpu = machine.get_cpu();
|
||||||
|
auto init_a = cpu.get_a().get_value();
|
||||||
|
|
||||||
|
uint16_t result = value + init_a;
|
||||||
|
if (cpu.get_ps().is_carry_set())
|
||||||
|
result += 1;
|
||||||
|
|
||||||
|
cpu.get_a().set_value(result); // will chop off bit 8 if set
|
||||||
|
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);
|
||||||
|
cpu.get_ps().set_carry(result > 0xFF);
|
||||||
|
cpu.get_ps().set_overflow(
|
||||||
|
(value < 0x7F && init_a < 0x7F && a > 0x7F) ||
|
||||||
|
(value > 0x7F && init_a > 0x7F && a < 0x7F));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::adc_imm(Machine& machine) {
|
||||||
|
adc(machine, machine.read_program_byte());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::adc_zpg(Machine& machine) {
|
||||||
|
auto addr = get_zpg_address(machine.read_program_byte());
|
||||||
|
adc(machine, machine.get_memory().get_at(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::dec_zpg(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::dec_zpg_x(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::dec_abs(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::dec_abs_x(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::dex(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::dey(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::inx(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::iny(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::sbc_imm(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::sbc_zpg(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::sbc_zpg_x(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::sbc_abs(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::sbc_abs_x(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::sbc_abs_y(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::sbc_ind_x(Machine& machine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathsOpcodeHandlerContainer::sbc_ind_y(Machine& machine) {
|
||||||
|
}
|
||||||
|
}
|
81
src/opcode/handler/maths-opcode-handler-container.h
Normal file
81
src/opcode/handler/maths-opcode-handler-container.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#ifndef INC_6502_EMULATOR_MATHS_OPCODE_HANDLER_CONTAINER_H
|
||||||
|
#define INC_6502_EMULATOR_MATHS_OPCODE_HANDLER_CONTAINER_H
|
||||||
|
|
||||||
|
#include "opcode-handler-container.h"
|
||||||
|
|
||||||
|
namespace emu_6502 {
|
||||||
|
class MathsOpcodeHandlerContainer : public OpcodeHandlerContainer {
|
||||||
|
private:
|
||||||
|
enum Op {
|
||||||
|
ADC_IMM = 0x69,
|
||||||
|
ADC_ZPG = 0x65,
|
||||||
|
ADC_ZPG_X = 0x75,
|
||||||
|
ADC_ABS = 0x6D,
|
||||||
|
ADC_ABS_X = 0x7D,
|
||||||
|
ADC_ABS_Y = 0x79,
|
||||||
|
ADC_IND_X = 0x61,
|
||||||
|
ADC_IND_Y = 0x71,
|
||||||
|
|
||||||
|
DEC_ZPG = 0xC6,
|
||||||
|
DEC_ZPG_X = 0xD6,
|
||||||
|
DEC_ABS = 0xCE,
|
||||||
|
DEC_ABS_X = 0xDE,
|
||||||
|
|
||||||
|
INC_ZPG = 0xE6,
|
||||||
|
INC_ZPG_X = 0xF6,
|
||||||
|
INC_ABS = 0xEE,
|
||||||
|
INC_ABS_X = 0xFE,
|
||||||
|
|
||||||
|
DEX = 0xCA,
|
||||||
|
DEY = 0x88,
|
||||||
|
INX = 0xE8,
|
||||||
|
INY = 0xC8,
|
||||||
|
|
||||||
|
SBC_IMM = 0x0,
|
||||||
|
SBC_ZPG = 0x0,
|
||||||
|
SBC_ZPG_X = 0x0,
|
||||||
|
SBC_ABS = 0x0,
|
||||||
|
SBC_ABS_X = 0x0,
|
||||||
|
SBC_ABS_Y = 0x0,
|
||||||
|
SBC_IND_X = 0x0,
|
||||||
|
SBC_IND_Y = 0x0
|
||||||
|
};
|
||||||
|
|
||||||
|
void adc(Machine& machine, uint8_t value);
|
||||||
|
void adc_imm(Machine& machine);
|
||||||
|
void adc_zpg(Machine& machine);
|
||||||
|
void adc_zpg_x(Machine& machine);
|
||||||
|
void adc_abs(Machine& machine);
|
||||||
|
void adc_abs_x(Machine& machine);
|
||||||
|
void adc_abs_y(Machine& machine);
|
||||||
|
void adc_ind_x(Machine& machine);
|
||||||
|
void adc_ind_y(Machine& machine);
|
||||||
|
|
||||||
|
void dec_zpg(Machine& machine);
|
||||||
|
void dec_zpg_x(Machine& machine);
|
||||||
|
void dec_abs(Machine& machine);
|
||||||
|
void dec_abs_x(Machine& machine);
|
||||||
|
|
||||||
|
void dex(Machine& machine);
|
||||||
|
void dey(Machine& machine);
|
||||||
|
void inx(Machine& machine);
|
||||||
|
void iny(Machine& machine);
|
||||||
|
|
||||||
|
void sbc_imm(Machine& machine);
|
||||||
|
void sbc_zpg(Machine& machine);
|
||||||
|
void sbc_zpg_x(Machine& machine);
|
||||||
|
void sbc_abs(Machine& machine);
|
||||||
|
void sbc_abs_x(Machine& machine);
|
||||||
|
void sbc_abs_y(Machine& machine);
|
||||||
|
void sbc_ind_x(Machine& machine);
|
||||||
|
void sbc_ind_y(Machine& machine);
|
||||||
|
|
||||||
|
public:
|
||||||
|
MathsOpcodeHandlerContainer();
|
||||||
|
MathsOpcodeHandlerContainer(const MathsOpcodeHandlerContainer&) = delete;
|
||||||
|
MathsOpcodeHandlerContainer& operator=(const MathsOpcodeHandlerContainer&) = delete;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //INC_6502_EMULATOR_MATHS_OPCODE_HANDLER_CONTAINER_H
|
@ -2,6 +2,7 @@
|
|||||||
#include "handler/load-opcode-handler-container.h"
|
#include "handler/load-opcode-handler-container.h"
|
||||||
#include "handler/store-opcode-handler-container.h"
|
#include "handler/store-opcode-handler-container.h"
|
||||||
#include "handler/transfer-opcode-handler-container.h"
|
#include "handler/transfer-opcode-handler-container.h"
|
||||||
|
#include "handler/maths-opcode-handler-container.h"
|
||||||
#include "../utils.h"
|
#include "../utils.h"
|
||||||
|
|
||||||
namespace emu_6502 {
|
namespace emu_6502 {
|
||||||
@ -10,6 +11,7 @@ namespace emu_6502 {
|
|||||||
handler_containers.push_back(make_unique<LoadOpcodeHandlerContainer>());
|
handler_containers.push_back(make_unique<LoadOpcodeHandlerContainer>());
|
||||||
handler_containers.push_back(make_unique<StoreOpcodeHandlerContainer>());
|
handler_containers.push_back(make_unique<StoreOpcodeHandlerContainer>());
|
||||||
handler_containers.push_back(make_unique<TransferOpcodeHandlerContainer>());
|
handler_containers.push_back(make_unique<TransferOpcodeHandlerContainer>());
|
||||||
|
handler_containers.push_back(make_unique<MathsOpcodeHandlerContainer>());
|
||||||
|
|
||||||
init_handlers();
|
init_handlers();
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,18 @@ namespace emu_6502 {
|
|||||||
return address;
|
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) {
|
uint16_t get_ind_x_address(uint8_t offset, Machine& machine) {
|
||||||
uint8_t paddress = machine.get_cpu().get_x().get_value() + offset;
|
uint8_t paddress = machine.get_cpu().get_x().get_value() + offset;
|
||||||
auto low = machine.get_memory().get_at(paddress);
|
auto low = machine.get_memory().get_at(paddress);
|
||||||
|
@ -15,6 +15,8 @@ namespace emu_6502 {
|
|||||||
uint16_t get_abs_address(uint8_t low_byte, uint8_t high_byte);
|
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_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_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_x_address(uint8_t offset, Machine& machine);
|
||||||
uint16_t get_ind_y_address(uint8_t offset, Machine& machine);
|
uint16_t get_ind_y_address(uint8_t offset, Machine& machine);
|
||||||
}
|
}
|
||||||
|
177
test/maths-opcode-handler-test.cpp
Normal file
177
test/maths-opcode-handler-test.cpp
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "test-utils.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace emu_6502;
|
||||||
|
|
||||||
|
const uint8_t ADC_IMM = 0x69;
|
||||||
|
const uint8_t ADC_ZPG = 0x65;
|
||||||
|
const uint8_t ADC_ZPG_X = 0x75;
|
||||||
|
const uint8_t ADC_ABS = 0x6D;
|
||||||
|
const uint8_t ADC_ABS_X = 0x7D;
|
||||||
|
const uint8_t ADC_ABS_Y = 0x79;
|
||||||
|
const uint8_t ADC_IND_X = 0x61;
|
||||||
|
const uint8_t ADC_IND_Y = 0x71;
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_IMM) {
|
||||||
|
auto machine = create_machine({ADC_IMM, 36});
|
||||||
|
machine->get_cpu().get_a().set_value(36);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(72, machine->get_cpu().get_a().get_value());
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_IMM_ZeroFlag) {
|
||||||
|
auto machine = create_machine({ADC_IMM, 0});
|
||||||
|
machine->get_cpu().get_a().set_value(0);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(0, machine->get_cpu().get_a().get_value());
|
||||||
|
|
||||||
|
RegisterFlagSet flags{};
|
||||||
|
flags.zero = true;
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_IMM_CarryFlag) {
|
||||||
|
auto machine = create_machine({ADC_IMM, 200});
|
||||||
|
machine->get_cpu().get_a().set_value(72);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(16, machine->get_cpu().get_a().get_value());
|
||||||
|
|
||||||
|
RegisterFlagSet flags{};
|
||||||
|
flags.carry = true;
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_IMM_ZeroAndCarryFlags) {
|
||||||
|
auto machine = create_machine({ADC_IMM, 0xFF});
|
||||||
|
machine->get_cpu().get_a().set_value(1);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(0, 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(MathsOpcodeHandlerContainer, ADC_IMM_NegativeFlag) {
|
||||||
|
auto machine = create_machine({ADC_IMM, 200});
|
||||||
|
machine->get_cpu().get_a().set_value(32);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(232, machine->get_cpu().get_a().get_value());
|
||||||
|
|
||||||
|
RegisterFlagSet flags{};
|
||||||
|
flags.negative = true;
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_IMM_OverflowFlag_Postive) {
|
||||||
|
auto machine = create_machine({ADC_IMM, 120});
|
||||||
|
machine->get_cpu().get_a().set_value(32);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(152, machine->get_cpu().get_a().get_value());
|
||||||
|
|
||||||
|
RegisterFlagSet flags{};
|
||||||
|
flags.negative = true;
|
||||||
|
flags.overflow = true;
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_IMM_OverflowFlag_Negative) {
|
||||||
|
auto machine = create_machine({ADC_IMM, 208});
|
||||||
|
machine->get_cpu().get_a().set_value(144);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(96, machine->get_cpu().get_a().get_value());
|
||||||
|
|
||||||
|
RegisterFlagSet flags{};
|
||||||
|
flags.carry = true;
|
||||||
|
flags.overflow = true;
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_ZPG) {
|
||||||
|
auto machine = create_machine({ADC_ZPG, 0xf1});
|
||||||
|
machine->get_cpu().get_a().set_value(36);
|
||||||
|
machine->get_memory().set_at(0xf1, 20);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(56, machine->get_cpu().get_a().get_value());
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_ZPG_X) {
|
||||||
|
auto machine = create_machine({ADC_ZPG_X, 0xf1});
|
||||||
|
machine->get_cpu().get_a().set_value(36);
|
||||||
|
machine->get_cpu().get_x().set_value(5);
|
||||||
|
machine->get_memory().set_at(0xf6, 20);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(56, machine->get_cpu().get_a().get_value());
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_ABS) {
|
||||||
|
auto machine = create_machine({ADC_ABS, 0xf1, 0x36});
|
||||||
|
machine->get_cpu().get_a().set_value(36);
|
||||||
|
machine->get_memory().set_at(0x36f1, 20);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(56, machine->get_cpu().get_a().get_value());
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_ABS_X) {
|
||||||
|
auto machine = create_machine({ADC_ABS_X, 0xf1, 0x36});
|
||||||
|
machine->get_cpu().get_a().set_value(36);
|
||||||
|
machine->get_cpu().get_x().set_value(8);
|
||||||
|
machine->get_memory().set_at(0x36f9, 20);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(56, machine->get_cpu().get_a().get_value());
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_ABS_Y) {
|
||||||
|
auto machine = create_machine({ADC_ABS_Y, 0xf1, 0x36});
|
||||||
|
machine->get_cpu().get_a().set_value(36);
|
||||||
|
machine->get_cpu().get_y().set_value(8);
|
||||||
|
machine->get_memory().set_at(0x36f9, 20);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(56, machine->get_cpu().get_a().get_value());
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_IND_X) {
|
||||||
|
auto machine = create_machine({ADC_IND_X, 0x41});
|
||||||
|
machine->get_cpu().get_x().set_value(0x22);
|
||||||
|
machine->get_cpu().get_a().set_value(36);
|
||||||
|
machine->get_memory().set_at(0x63, 0x34);
|
||||||
|
machine->get_memory().set_at(0x64, 0x12);
|
||||||
|
machine->get_memory().set_at(0x1234, 20);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(56, machine->get_cpu().get_a().get_value());
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MathsOpcodeHandlerContainer, ADC_IND_Y) {
|
||||||
|
auto machine = create_machine({ADC_IND_Y, 0x41});
|
||||||
|
machine->get_cpu().get_y().set_value(0x22);
|
||||||
|
machine->get_cpu().get_a().set_value(36);
|
||||||
|
machine->get_memory().set_at(0x41, 0x34);
|
||||||
|
machine->get_memory().set_at(0x42, 0x12);
|
||||||
|
machine->get_memory().set_at(0x1256, 20);
|
||||||
|
machine->execute();
|
||||||
|
|
||||||
|
ASSERT_EQ(56, machine->get_cpu().get_a().get_value());
|
||||||
|
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user