From 2548267d6dae6ed962a9bd64b1d296804703e1fc Mon Sep 17 00:00:00 2001 From: matheusgomes28 Date: Mon, 14 Oct 2024 22:19:44 +0100 Subject: [PATCH] Support for DEC zp, zp+x, abs, abs+x --- README.md | 6 ++--- emulator/emulator.cpp | 61 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e02dffe..8a9c378 100644 --- a/README.md +++ b/README.md @@ -204,9 +204,9 @@ Total number of stack instructions: `4`. | **Opcode** | **Addressing Mode** | **Opcode (Hex)** | **Bytes** | **Cycles** | **Supported** | |------------|---------------------|------------------|-----------|------------|--------------------| | DEC | Zero Page | 0xC6 | 2 | 5 | :white_check_mark: | -| DEC | Zero Page, X | 0xD6 | 2 | 6 | :x: | -| DEC | Absolute | 0xCE | 3 | 6 | :x: | -| DEC | Absolute, X | 0xDE | 3 | 7 | :x: | +| DEC | Zero Page, X | 0xD6 | 2 | 6 | :ok: | +| DEC | Absolute | 0xCE | 3 | 6 | :ok: | +| DEC | Absolute, X | 0xDE | 3 | 7 | :ok: | | DEX | Implied | 0xCA | 1 | 2 | :white_check_mark: | | DEY | Implied | 0x88 | 1 | 2 | :white_check_mark: | | INC | Zero Page | 0xE6 | 2 | 5 | :white_check_mark: | diff --git a/emulator/emulator.cpp b/emulator/emulator.cpp index d4d85d6..9b28c3c 100644 --- a/emulator/emulator.cpp +++ b/emulator/emulator.cpp @@ -863,6 +863,14 @@ std::optional inc_absolute_plus_x(emulator::Cpu& cpu, std::sp return std::make_optional(3, 7); } +/* Decrement operations */ +void decrement_operation(emulator::Cpu& cpu, std::uint16_t pos) +{ + cpu.mem[pos]--; + cpu.flags.z = cpu.mem[pos] == 0; + cpu.flags.n = cpu.mem[pos] & 0b1000'0000; +} + std::optional dec_zeropage(emulator::Cpu& cpu, std::span program) { ENABLE_PROFILER(cpu); @@ -872,13 +880,53 @@ std::optional dec_zeropage(emulator::Cpu& cpu, std::span(2, 5); +} - return std::make_optional(2); +std::optional dec_zp_indexed(emulator::Cpu& cpu, std::span program) +{ + ENABLE_PROFILER(cpu); + if ((cpu.reg.pc + 1) >= program.size()) + { + return std::nullopt; + } + + auto const pos = zeropage_indexed(cpu, program[cpu.reg.pc + 1], &emulator::Registers::x); + decrement_operation(cpu, pos); + return std::make_optional(2, 5); } +std::optional dec_abs(emulator::Cpu& cpu, std::span program) +{ + ENABLE_PROFILER(cpu); + if ((cpu.reg.pc + 2) >= program.size()) + { + return std::nullopt; + } + + // (hsb << 8) + lsb convert little endian to the address + auto const lsb = program[cpu.reg.pc + 1]; + auto const hsb = program[cpu.reg.pc + 2]; + decrement_operation(cpu, (hsb << 8) | lsb); + return std::make_optional(3, 6); +} + +std::optional dec_abs_indexed(emulator::Cpu& cpu, std::span program) +{ + ENABLE_PROFILER(cpu); + if ((cpu.reg.pc + 2) >= program.size()) + { + return std::nullopt; + } + + // (hsb << 8) + lsb convert little endian to the address + auto const pos = absolute_indexed(cpu, program[cpu.reg.pc + 1], program[cpu.reg.pc + 2], &emulator::Registers::x); + decrement_operation(cpu, pos); + return std::make_optional(3, 7); +} +/* End Decrement operations */ + Instruction inc_reg(std::uint8_t emulator::Registers::*reg) { return [=](emulator::Cpu& cpu, std::span /* program */) @@ -1525,7 +1573,12 @@ std::array get_instructions() supported_instructions[0xc8] = inc_reg(&emulator::Registers::y); supported_instructions[0xe8] = inc_reg(&emulator::Registers::x); + // DEC opcodes supported_instructions[0xc6] = dec_zeropage; + supported_instructions[0xd6] = dec_zp_indexed; + supported_instructions[0xce] = dec_abs; + supported_instructions[0xde] = dec_abs_indexed; + supported_instructions[0x88] = dec_reg(&emulator::Registers::y); supported_instructions[0xca] = dec_reg(&emulator::Registers::x);