Skip to content

Commit

Permalink
Merge pull request #56 from matheusgomes28/add-rol-support
Browse files Browse the repository at this point in the history
Add support for all ROL opcodes
  • Loading branch information
matheusgomes28 authored Oct 5, 2024
2 parents 9f08d5d + 0081989 commit 2695939
Show file tree
Hide file tree
Showing 3 changed files with 527 additions and 3 deletions.
91 changes: 88 additions & 3 deletions emulator/emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,15 @@ std::optional<InstructionConfig> pull_stack_to_status_reg(emulator::Cpu& cpu, st
return new_value;
}

[[nodiscard]] std::uint8_t rol_operation(emulator::Cpu& cpu, std::uint8_t value)
{
std::uint8_t const new_value = (value << 1) | (static_cast<std::uint8_t>(cpu.flags.c));
cpu.flags.n = new_value & 0b1000'0000;
cpu.flags.z = new_value == 0;
cpu.flags.c = value & (0b1000'0000);
return new_value;
}

std::optional<InstructionConfig> ror_accumulator(emulator::Cpu& cpu, std::span<const std::uint8_t> program)
{
ENABLE_PROFILER(cpu);
Expand All @@ -319,7 +328,7 @@ std::optional<InstructionConfig> ror_zeropage(emulator::Cpu& cpu, std::span<cons
}
auto const zp = program[cpu.reg.pc + 1];
auto const value = cpu.mem[zp];
cpu.mem[zp] = ror_operation(cpu, value);
cpu.mem[zp] = ror_operation(cpu, value);
return std::make_optional<InstructionConfig>(2);
}

Expand Down Expand Up @@ -349,9 +358,9 @@ std::optional<InstructionConfig> ror_absolute(emulator::Cpu& cpu, std::span<cons

auto const lsb = program[cpu.reg.pc + 1];
auto const hsb = program[cpu.reg.pc + 2];
auto const pos = (hsb << 8) | lsb;
auto const pos = (hsb << 8) | lsb;
auto const value = cpu.mem[pos];
cpu.mem[pos] = ror_operation(cpu, value);
cpu.mem[pos] = ror_operation(cpu, value);
return std::make_optional<InstructionConfig>(3);
}

Expand All @@ -371,6 +380,75 @@ std::optional<InstructionConfig> ror_absolute_indexed(emulator::Cpu& cpu, std::s
cpu.mem[pos] = ror_operation(cpu, value);
return std::make_optional<InstructionConfig>(3);
}

std::optional<InstructionConfig> rol_accumulator(emulator::Cpu& cpu, std::span<const std::uint8_t> program)
{
ENABLE_PROFILER(cpu);
cpu.reg.a = rol_operation(cpu, cpu.reg.a);
return std::make_optional<InstructionConfig>(1);
}

std::optional<InstructionConfig> rol_zeropage(emulator::Cpu& cpu, std::span<const std::uint8_t> program)
{
ENABLE_PROFILER(cpu);
if ((cpu.reg.pc + 1) >= program.size())
{
return std::nullopt;
}
auto const zp = program[cpu.reg.pc + 1];
auto const value = cpu.mem[zp];
cpu.mem[zp] = rol_operation(cpu, value);
return std::make_optional<InstructionConfig>(2);
}

std::optional<InstructionConfig> rol_zeropage_indexed(emulator::Cpu& cpu, std::span<const std::uint8_t> program)
{
ENABLE_PROFILER(cpu);
if ((cpu.reg.pc + 1) >= program.size())
{
return std::nullopt;
}

auto const zp = program[cpu.reg.pc + 1];
auto const pos = zeropage_indexed(cpu, zp, &emulator::Registers::x);
auto const value = cpu.mem[pos];

cpu.mem[pos] = rol_operation(cpu, value);
return std::make_optional<InstructionConfig>(2);
}

std::optional<InstructionConfig> rol_absolute(emulator::Cpu& cpu, std::span<const std::uint8_t> program)
{
ENABLE_PROFILER(cpu);
if ((cpu.reg.pc + 2) >= program.size())
{
return std::nullopt;
}

auto const lsb = program[cpu.reg.pc + 1];
auto const hsb = program[cpu.reg.pc + 2];
auto const pos = (hsb << 8) | lsb;
auto const value = cpu.mem[pos];
cpu.mem[pos] = rol_operation(cpu, value);
return std::make_optional<InstructionConfig>(3);
}

std::optional<InstructionConfig> rol_absolute_indexed(emulator::Cpu& cpu, std::span<const std::uint8_t> program)
{
ENABLE_PROFILER(cpu);
if ((cpu.reg.pc + 2) >= program.size())
{
return std::nullopt;
}

auto const lsb = program[cpu.reg.pc + 1];
auto const hsb = program[cpu.reg.pc + 2];
auto const pos = absolute_indexed(cpu, lsb, hsb, &emulator::Registers::x);
auto const value = cpu.mem[pos];

cpu.mem[pos] = rol_operation(cpu, value);
return std::make_optional<InstructionConfig>(3);
}
/* End bit rotation functions */

/* Flag setting opcodes */
Expand Down Expand Up @@ -1298,6 +1376,13 @@ std::array<Instruction, 256> get_instructions()
supported_instructions[0x6e] = ror_absolute;
supported_instructions[0x7e] = ror_absolute_indexed;

// ROL opcodes
supported_instructions[0x2a] = rol_accumulator;
supported_instructions[0x26] = rol_zeropage;
supported_instructions[0x36] = rol_zeropage_indexed;
supported_instructions[0x2e] = rol_absolute;
supported_instructions[0x3e] = rol_absolute_indexed;

// Stack-related opcodes
supported_instructions[0x48] = push_accumulator_to_stack;
supported_instructions[0x08] = push_status_reg_to_stack;
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,6 @@ create_tests(pha_tests)
create_tests(php_tests)
create_tests(pla_tests)
create_tests(plp_tests)
create_tests(rol_tests)
create_tests(ror_tests)
create_tests(tx_tests)
Loading

0 comments on commit 2695939

Please sign in to comment.