mirror of
https://github.com/tdinucci/6502-emulator.git
synced 2024-11-27 02:49:50 +00:00
Rest of maths opcodes
This commit is contained in:
parent
90e33ad6cb
commit
e6abdd2dd8
@ -12,6 +12,15 @@ namespace emu_6502 {
|
||||
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::SBC_IMM, [this](Machine& machine) { sbc_imm(machine); }});
|
||||
handlers.insert({Op::SBC_ZPG, [this](Machine& machine) { sbc_zpg(machine); }});
|
||||
handlers.insert({Op::SBC_ZPG_X, [this](Machine& machine) { sbc_zpg_x(machine); }});
|
||||
handlers.insert({Op::SBC_ABS, [this](Machine& machine) { sbc_abs(machine); }});
|
||||
handlers.insert({Op::SBC_ABS_X, [this](Machine& machine) { sbc_abs_x(machine); }});
|
||||
handlers.insert({Op::SBC_ABS_Y, [this](Machine& machine) { sbc_abs_y(machine); }});
|
||||
handlers.insert({Op::SBC_IND_X, [this](Machine& machine) { sbc_ind_x(machine); }});
|
||||
handlers.insert({Op::SBC_IND_Y, [this](Machine& machine) { sbc_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); }});
|
||||
@ -85,6 +94,43 @@ namespace emu_6502 {
|
||||
adc(machine, machine.get_memory().get_at(get_ind_y_address(machine)));
|
||||
}
|
||||
|
||||
void MathsOpcodeHandlerContainer::sbc(Machine& machine, uint8_t value) {
|
||||
// subtract is same as add negative value (i.e. add accumulator to the twos compliment of 'value')
|
||||
adc(machine, (0xFF ^ value) + 1);
|
||||
}
|
||||
|
||||
void MathsOpcodeHandlerContainer::sbc_imm(Machine& machine) {
|
||||
sbc(machine, machine.read_program_byte());
|
||||
}
|
||||
|
||||
void MathsOpcodeHandlerContainer::sbc_zpg(Machine& machine) {
|
||||
sbc(machine, machine.get_memory().get_at(get_zpg_address(machine)));
|
||||
}
|
||||
|
||||
void MathsOpcodeHandlerContainer::sbc_zpg_x(Machine& machine) {
|
||||
sbc(machine, machine.get_memory().get_at(get_zpg_x_address(machine)));
|
||||
}
|
||||
|
||||
void MathsOpcodeHandlerContainer::sbc_abs(Machine& machine) {
|
||||
sbc(machine, machine.get_memory().get_at(get_abs_address(machine)));
|
||||
}
|
||||
|
||||
void MathsOpcodeHandlerContainer::sbc_abs_x(Machine& machine) {
|
||||
sbc(machine, machine.get_memory().get_at(get_abs_x_address(machine)));
|
||||
}
|
||||
|
||||
void MathsOpcodeHandlerContainer::sbc_abs_y(Machine& machine) {
|
||||
sbc(machine, machine.get_memory().get_at(get_abs_y_address(machine)));
|
||||
}
|
||||
|
||||
void MathsOpcodeHandlerContainer::sbc_ind_x(Machine& machine) {
|
||||
sbc(machine, machine.get_memory().get_at(get_ind_x_address(machine)));
|
||||
}
|
||||
|
||||
void MathsOpcodeHandlerContainer::sbc_ind_y(Machine& machine) {
|
||||
sbc(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);
|
||||
@ -160,28 +206,4 @@ namespace emu_6502 {
|
||||
void MathsOpcodeHandlerContainer::iny(Machine& machine) {
|
||||
in(machine, machine.get_cpu().get_y());
|
||||
}
|
||||
|
||||
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) {
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,15 @@ namespace emu_6502 {
|
||||
ADC_IND_X = 0x61,
|
||||
ADC_IND_Y = 0x71,
|
||||
|
||||
SBC_IMM = 0xE9,
|
||||
SBC_ZPG = 0xE5,
|
||||
SBC_ZPG_X = 0xF5,
|
||||
SBC_ABS = 0xED,
|
||||
SBC_ABS_X = 0xFD,
|
||||
SBC_ABS_Y = 0xF9,
|
||||
SBC_IND_X = 0xE1,
|
||||
SBC_IND_Y = 0xF1,
|
||||
|
||||
DEC_ZPG = 0xC6,
|
||||
DEC_ZPG_X = 0xD6,
|
||||
DEC_ABS = 0xCE,
|
||||
@ -29,16 +38,7 @@ namespace emu_6502 {
|
||||
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
|
||||
INY = 0xC8
|
||||
};
|
||||
|
||||
void set_zero_neg(StatusRegister& ps, uint8_t value);
|
||||
@ -53,6 +53,16 @@ namespace emu_6502 {
|
||||
void adc_ind_x(Machine& machine);
|
||||
void adc_ind_y(Machine& machine);
|
||||
|
||||
void sbc(Machine& machine, uint8_t value);
|
||||
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);
|
||||
|
||||
void dec(Machine& machine, uint16_t address);
|
||||
void dec_zpg(Machine& machine);
|
||||
void dec_zpg_x(Machine& machine);
|
||||
@ -73,15 +83,6 @@ namespace emu_6502 {
|
||||
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;
|
||||
|
@ -13,6 +13,15 @@ const uint8_t ADC_ABS_Y = 0x79;
|
||||
const uint8_t ADC_IND_X = 0x61;
|
||||
const uint8_t ADC_IND_Y = 0x71;
|
||||
|
||||
const uint8_t SBC_IMM = 0xE9;
|
||||
const uint8_t SBC_ZPG = 0xE5;
|
||||
const uint8_t SBC_ZPG_X = 0xF5;
|
||||
const uint8_t SBC_ABS = 0xED;
|
||||
const uint8_t SBC_ABS_X = 0xFD;
|
||||
const uint8_t SBC_ABS_Y = 0xF9;
|
||||
const uint8_t SBC_IND_X = 0xE1;
|
||||
const uint8_t SBC_IND_Y = 0xF1;
|
||||
|
||||
const uint8_t DEC_ZPG = 0xC6;
|
||||
const uint8_t DEC_ZPG_X = 0xD6;
|
||||
const uint8_t DEC_ABS = 0xCE;
|
||||
@ -191,6 +200,148 @@ TEST(MathsOpcodeHandlerContainer, ADC_IND_Y) {
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, SBC_IMM) {
|
||||
auto machine = create_machine({SBC_IMM, 0x20});
|
||||
machine->get_cpu().get_a().set_value(0x50);
|
||||
machine->execute();
|
||||
|
||||
ASSERT_EQ(0x30, machine->get_cpu().get_a().get_value());
|
||||
RegisterFlagSet flags{};
|
||||
flags.carry = true; // indicates no borrow
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, SBC_IMM_WithBorrow) {
|
||||
auto machine = create_machine({SBC_IMM, 0xf0});
|
||||
machine->get_cpu().get_a().set_value(0xd0);
|
||||
machine->execute();
|
||||
|
||||
ASSERT_EQ(0xe0, machine->get_cpu().get_a().get_value());
|
||||
RegisterFlagSet flags{};
|
||||
flags.carry = false; // indicates there was a borrow
|
||||
flags.negative = true;
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, SBC_IMM_WithOverflow) {
|
||||
auto machine = create_machine({SBC_IMM, 0xb0});
|
||||
machine->get_cpu().get_a().set_value(0x50);
|
||||
machine->execute();
|
||||
|
||||
ASSERT_EQ(0xa0, machine->get_cpu().get_a().get_value());
|
||||
RegisterFlagSet flags{};
|
||||
flags.carry = false; // was a borrow
|
||||
flags.negative = true;
|
||||
flags.overflow = true;
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, SBC_IMM_ZeroFlag) {
|
||||
auto machine = create_machine({SBC_IMM, 50});
|
||||
machine->get_cpu().get_a().set_value(50);
|
||||
machine->execute();
|
||||
|
||||
ASSERT_EQ(0, machine->get_cpu().get_a().get_value());
|
||||
|
||||
RegisterFlagSet flags{};
|
||||
flags.zero = true;
|
||||
flags.carry = true; // no borrow
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, SBC_ZPG) {
|
||||
auto machine = create_machine({SBC_ZPG, 0xf1});
|
||||
machine->get_cpu().get_a().set_value(36);
|
||||
machine->get_memory().set_at(0xf1, 20);
|
||||
machine->execute();
|
||||
|
||||
ASSERT_EQ(16, machine->get_cpu().get_a().get_value());
|
||||
RegisterFlagSet flags{};
|
||||
flags.carry = true; // no borrow
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, SBC_ZPG_X) {
|
||||
auto machine = create_machine({SBC_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(16, machine->get_cpu().get_a().get_value());
|
||||
RegisterFlagSet flags{};
|
||||
flags.carry = true; // no borrow
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, SBC_ABS) {
|
||||
auto machine = create_machine({SBC_ABS, 0xf1, 0x36});
|
||||
machine->get_cpu().get_a().set_value(36);
|
||||
machine->get_memory().set_at(0x36f1, 20);
|
||||
machine->execute();
|
||||
|
||||
ASSERT_EQ(16, machine->get_cpu().get_a().get_value());
|
||||
RegisterFlagSet flags{};
|
||||
flags.carry = true; // no borrow
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, SBC_ABS_X) {
|
||||
auto machine = create_machine({SBC_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(16, machine->get_cpu().get_a().get_value());
|
||||
RegisterFlagSet flags{};
|
||||
flags.carry = true; // no borrow
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, SBC_ABS_Y) {
|
||||
auto machine = create_machine({SBC_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(16, machine->get_cpu().get_a().get_value());
|
||||
RegisterFlagSet flags{};
|
||||
flags.carry = true; // no borrow
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, SBC_IND_X) {
|
||||
auto machine = create_machine({SBC_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(16, machine->get_cpu().get_a().get_value());
|
||||
RegisterFlagSet flags{};
|
||||
flags.carry = true; // no borrow
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, SBC_IND_Y) {
|
||||
auto machine = create_machine({SBC_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(16, machine->get_cpu().get_a().get_value());
|
||||
RegisterFlagSet flags{};
|
||||
flags.carry = true; // no borrow
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(MathsOpcodeHandlerContainer, DEC_ZPG) {
|
||||
auto machine = create_machine({DEC_ZPG, 0xf1});
|
||||
machine->get_memory().set_at(0xf1, 20);
|
||||
|
Loading…
Reference in New Issue
Block a user