From 268b45b0620dfdc7a2934cd8a53cee0940693623 Mon Sep 17 00:00:00 2001 From: PalindromicBreadLoaf Date: Tue, 22 Jul 2025 11:31:10 -0400 Subject: [PATCH] Add some branching instructions --- src/cpu.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/cpu.h | 15 +++++++++++---- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/cpu.cpp b/src/cpu.cpp index 535ff09..1fbfbd5 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -100,9 +100,33 @@ void CPU::UpdateCompareFlags16(const uint16_t reg_value, const uint16_t compare_ } } +void CPU::DoBranch(const bool condition) { + int8_t displacement = static_cast(ReadByte(PC)); + PC++; + + if (condition) { + // Save the current PC for page boundary check + const uint32_t old_pc = PC; + + PC = static_cast(static_cast(PC) + displacement); + + cycles++; + + if ((old_pc & 0xFF00) != (PC & 0xFF00)) cycles++; // Add one cycle for crossing a page boundary + } +} + void CPU::ExecuteInstruction() { // TODO: Actual Opcode decoding switch (const uint8_t opcode = bus->Read(PC++)) { + // Branch Instructions + case 0xF0: BEQ_Relative(); break; // BEQ $nn + case 0xD0: BNE_Relative(); break; // BNE $nn + case 0x90: BCC_Relative(); break; // BCC $nn + case 0xB0: BCS_Relative(); break; // BCS $nn + case 0x30: BMI_Relative(); break; // BMI $nn + case 0x10: BPL_Relative(); break; // BPL $nn + // CMP - Compare Accumulator case 0xC9: CMP_Immediate(); break; // CMP #$nn or #$nnnn case 0xCD: CMP_Absolute(); break; // CMP $nnnn @@ -116,12 +140,12 @@ void CPU::ExecuteInstruction() { case 0xCF: CMP_Long(); break; // CMP $nnnnnn case 0xDF: CMP_LongX(); break; // CMP $nnnnnn,X - // CPX - Compare X Register + // CPX - Compare X Register case 0xE0: CPX_Immediate(); break; // CPX #$nn or #$nnnn case 0xEC: CPX_Absolute(); break; // CPX $nnnn case 0xE4: CPX_DirectPage(); break; // CPX $nn - // CPY - Compare Y Register + // CPY - Compare Y Register case 0xC0: CPY_Immediate(); break; // CPY #$nn or #$nnnn case 0xCC: CPY_Absolute(); break; // CPY $nnnn case 0xC4: CPY_DirectPage(); break; // CPY $nn @@ -1467,4 +1491,28 @@ void CPU::JMP_AbsoluteIndirectX() { PC = (static_cast(PB) << 16) | target_addr; cycles += 6; +} + +void CPU::BEQ_Relative() { + DoBranch(P & FLAG_Z); +} + +void CPU::BNE_Relative() { + DoBranch(!(P & FLAG_Z)); +} + +void CPU::BCC_Relative() { + DoBranch(!(P & FLAG_C)); +} + +void CPU::BCS_Relative() { + DoBranch(P & FLAG_C); +} + +void CPU::BMI_Relative() { + DoBranch(P & FLAG_N); +} + +void CPU::BPL_Relative() { + DoBranch(!(P & FLAG_N)); } \ No newline at end of file diff --git a/src/cpu.h b/src/cpu.h index 0b0bb42..52c3563 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -8,7 +8,6 @@ // 65816 CPU implementation class CPU { -private: // Registers uint16_t A; // Accumulator uint16_t X, Y; // Index registers @@ -37,7 +36,7 @@ private: }; public: - CPU(Bus* memory_bus) : bus(memory_bus) { + explicit CPU(Bus* memory_bus) : bus(memory_bus) { Reset(); } @@ -61,6 +60,9 @@ public: void UpdateCompareFlags8(uint8_t reg_value, uint8_t compare_value); void UpdateCompareFlags16(uint16_t reg_value, uint16_t compare_value); + // Branching helper method + void DoBranch(bool condition); + // Instruction implementations // TODO: Implement remaining instructions void CMP_Immediate(); @@ -83,8 +85,6 @@ public: void CPY_Absolute(); void CPY_DirectPage(); - void JMP(); - static void NOP(); void LDA_Immediate(); @@ -151,6 +151,13 @@ public: void JMP_AbsoluteIndirect(); void JMP_AbsoluteLong(); void JMP_AbsoluteIndirectX(); + + void BEQ_Relative(); + void BNE_Relative(); + void BCC_Relative(); + void BCS_Relative(); + void BMI_Relative(); + void BPL_Relative(); }; #endif //CPU_H