From afa00385dbed313f6234056e8109ecd35e7ab755 Mon Sep 17 00:00:00 2001 From: PalindromicBreadLoaf Date: Tue, 22 Jul 2025 11:12:24 -0400 Subject: [PATCH] Implement JMP instructions --- src/cpu.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++-- src/cpu.h | 5 +++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/cpu.cpp b/src/cpu.cpp index 2921351..535ff09 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -28,8 +28,8 @@ uint8_t CPU::ReadByte(const uint32_t address) { } uint16_t CPU::ReadWord(const uint32_t address) { - uint8_t low = ReadByte(address); - uint8_t high = ReadByte(address + 1); + const uint8_t low = ReadByte(address); + const uint8_t high = ReadByte(address + 1); return (high << 8) | low; } @@ -133,6 +133,12 @@ void CPU::ExecuteInstruction() { case 0xC6: DEC_DirectPage(); break; // DEC $nn case 0xD6: DEC_DirectPageX(); break; // DEC $nn,X + // JMP - Jump to an Address + case 0x4C: JMP_Absolute(); break; // JMP $nnnn + case 0x6C: JMP_AbsoluteIndirect(); break; // JMP ($nnnn) + case 0x5C: JMP_AbsoluteLong(); break; // JMP $nnnnnn + case 0x7C: JMP_AbsoluteIndirectX(); break; // JMP ($nnnn,X) + // Single Register Decrement case 0xCA: DEX(); break; // DEX - Decrement X Register case 0x88: DEY(); break; // DEY - Decrement Y Register @@ -1413,4 +1419,52 @@ void CPU::CPY_DirectPage() { cycles += 4; if (D & 0xFF) cycles++; // Extra cycle if D register low byte != 0 } +} + +void CPU::JMP_Absolute() { + const uint16_t address = ReadWord(PC); + PC += 2; + + PC = (static_cast(PB) << 16) | address; + + cycles += 3; +} + +void CPU::JMP_AbsoluteIndirect() { + const uint16_t indirect_addr = ReadWord(PC); + PC += 2; + + const uint32_t full_indirect_addr = (static_cast(DB) << 16) | indirect_addr; + const uint16_t target_addr = ReadWord(full_indirect_addr); + + PC = (static_cast(PB) << 16) | target_addr; + + cycles += 5; +} + +void CPU::JMP_AbsoluteLong() { + const uint16_t addr_low = ReadWord(PC); + PC += 2; + const uint8_t addr_high = ReadByte(PC); + PC++; + + const uint32_t target_addr = (static_cast(addr_high) << 16) | addr_low; + + PB = addr_high; + PC = target_addr; + + cycles += 4; +} + +void CPU::JMP_AbsoluteIndirectX() { + const uint16_t base_addr = ReadWord(PC); + PC += 2; + + const uint32_t indirect_addr = (static_cast(PB) << 16) | (base_addr + X); + + const uint16_t target_addr = ReadWord(indirect_addr); + + PC = (static_cast(PB) << 16) | target_addr; + + cycles += 6; } \ No newline at end of file diff --git a/src/cpu.h b/src/cpu.h index c4a0b03..0b0bb42 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -146,6 +146,11 @@ public: void INY(); void DEX(); void DEY(); + + void JMP_Absolute(); + void JMP_AbsoluteIndirect(); + void JMP_AbsoluteLong(); + void JMP_AbsoluteIndirectX(); }; #endif //CPU_H