Stack opcodes

This commit is contained in:
Tony Di Nucci 2019-04-21 21:53:00 +01:00
parent 51812ebd71
commit 248be24ef8
4 changed files with 152 additions and 0 deletions

View File

@ -0,0 +1,30 @@
#include "stack-opcode-handler-container.h"
#include "../../utils.h"
namespace emu_6502 {
StackOpcodeHandlerContainer::StackOpcodeHandlerContainer() {
handlers.insert({Op::PHA, [this](Machine& machine) { pha(machine); }});
handlers.insert({Op::PHP, [this](Machine& machine) { php(machine); }});
handlers.insert({Op::PLA, [this](Machine& machine) { pla(machine); }});
handlers.insert({Op::PLP, [this](Machine& machine) { plp(machine); }});
}
void StackOpcodeHandlerContainer::pha(Machine& machine) {
machine.get_stack().push(machine.get_cpu().get_a().get_value());
}
void StackOpcodeHandlerContainer::php(Machine& machine) {
machine.get_stack().push(machine.get_cpu().get_ps().get_value().to_ulong());
}
void StackOpcodeHandlerContainer::pla(Machine& machine) {
auto value = machine.get_stack().pop();
machine.get_cpu().get_a().set_value(value);
set_zero_and_neg_flags(machine.get_cpu().get_ps(), value);
}
void StackOpcodeHandlerContainer::plp(Machine& machine) {
machine.get_cpu().get_ps().set_value(machine.get_stack().pop());
}
}

View File

@ -0,0 +1,30 @@
#ifndef INC_6502_EMULATOR_STACK_OPCODE_HANDLER_CONTAINER_H
#define INC_6502_EMULATOR_STACK_OPCODE_HANDLER_CONTAINER_H
#include "opcode-handler-container.h"
namespace emu_6502 {
class StackOpcodeHandlerContainer : public OpcodeHandlerContainer {
private:
enum Op {
PHA = 0x48,
PHP = 0x08,
PLA = 0x68,
PLP = 0x28,
};
void pha(Machine& machine);
void php(Machine& machine);
void pla(Machine& machine);
void plp(Machine& machine);
public:
StackOpcodeHandlerContainer();
StackOpcodeHandlerContainer(const StackOpcodeHandlerContainer&) = delete;
StackOpcodeHandlerContainer& operator=(const StackOpcodeHandlerContainer&) = delete;
};
}
#endif //INC_6502_EMULATOR_STACK_OPCODE_HANDLER_CONTAINER_H

View File

@ -6,6 +6,7 @@
#include "handler/bitwise-opcode-handler-container.h"
#include "handler/status-opcode-handler-container.h"
#include "handler/compare-opcode-handler-container.h"
#include "handler/stack-opcode-handler-container.h"
#include "../utils.h"
namespace emu_6502 {
@ -18,6 +19,7 @@ namespace emu_6502 {
handler_containers.push_back(make_unique<BitwiseOpcodeHandlerContainer>());
handler_containers.push_back(make_unique<StatusOpcodeHandlerContainer>());
handler_containers.push_back(make_unique<CompareOpcodeHandlerContainer>());
handler_containers.push_back(make_unique<StackOpcodeHandlerContainer>());
init_handlers();
}

View File

@ -0,0 +1,90 @@
#include "gtest/gtest.h"
#include "test-utils.h"
using namespace std;
using namespace emu_6502;
const uint8_t PHA = 0x48;
const uint8_t PHP = 0x08;
const uint8_t PLA = 0x68;
const uint8_t PLP = 0x28;
const uint8_t CLC = 0x18;
const uint8_t CLD = 0xD8;
const uint8_t CLI = 0x58;
const uint8_t CLV = 0xB8;
TEST(StackOpcodeHandlerContainer, PHA) {
auto machine = create_machine({PHA});
machine->get_cpu().get_a().set_value(0x13);
machine->execute();
ASSERT_EQ(0x13, machine->get_cpu().get_a().get_value());
ASSERT_EQ(0x13, machine->get_stack().pop());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(StackOpcodeHandlerContainer, PHP) {
auto machine = create_machine({PHP});
machine->get_cpu().get_ps().set_value(0xFF);
machine->execute();
ASSERT_EQ(0xFF, machine->get_cpu().get_ps().get_value().to_ulong());
ASSERT_EQ(0xFF, machine->get_stack().pop());
}
TEST(StackOpcodeHandlerContainer, PLA) {
auto machine = create_machine({PLA});
machine->get_stack().push(0x05);
machine->execute();
ASSERT_EQ(0x05, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(StackOpcodeHandlerContainer, PLA_NegativeFlag) {
auto machine = create_machine({PLA});
machine->get_stack().push(0xf5);
machine->execute();
ASSERT_EQ(0xf5, machine->get_cpu().get_a().get_value());
RegisterFlagSet flags{};
flags.negative = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(StackOpcodeHandlerContainer, PLA_ZeroFlag) {
auto machine = create_machine({PLA});
machine->get_stack().push(0x0);
machine->execute();
ASSERT_EQ(0x0, machine->get_cpu().get_a().get_value());
RegisterFlagSet flags{};
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(StackOpcodeHandlerContainer, PLP) {
auto machine = create_machine({PHP, CLC, CLD, CLI, CLV, PLP});
auto& ps = machine->get_cpu().get_ps();
ps.set_zero(true);
ps.set_negative(true);
ps.set_carry(true);
ps.set_overflow(true);
ps.set_interupt_disable(true);
ps.set_decimal(true);
ps.set_break(true);
machine->execute();
RegisterFlagSet flags{};
flags.zero = true;
flags.negative = true;
flags.carry = true;
flags.overflow = true;
flags.interupt_disable = true;
flags.decimal = true;
flags.brk = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}