Add some branching instructions

This commit is contained in:
2025-07-22 11:31:10 -04:00
parent afa00385db
commit 268b45b062
2 changed files with 61 additions and 6 deletions

View File

@@ -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<int8_t>(ReadByte(PC));
PC++;
if (condition) {
// Save the current PC for page boundary check
const uint32_t old_pc = PC;
PC = static_cast<uint32_t>(static_cast<int32_t>(PC) + displacement);
cycles++;
if ((old_pc & 0xFF00) != (PC & 0xFF00)) cycles++; // Add one cycle for crossing a page boundary
}
}
void CPU::ExecuteInstruction() { void CPU::ExecuteInstruction() {
// TODO: Actual Opcode decoding // TODO: Actual Opcode decoding
switch (const uint8_t opcode = bus->Read(PC++)) { 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 // CMP - Compare Accumulator
case 0xC9: CMP_Immediate(); break; // CMP #$nn or #$nnnn case 0xC9: CMP_Immediate(); break; // CMP #$nn or #$nnnn
case 0xCD: CMP_Absolute(); break; // CMP $nnnn case 0xCD: CMP_Absolute(); break; // CMP $nnnn
@@ -116,12 +140,12 @@ void CPU::ExecuteInstruction() {
case 0xCF: CMP_Long(); break; // CMP $nnnnnn case 0xCF: CMP_Long(); break; // CMP $nnnnnn
case 0xDF: CMP_LongX(); break; // CMP $nnnnnn,X 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 0xE0: CPX_Immediate(); break; // CPX #$nn or #$nnnn
case 0xEC: CPX_Absolute(); break; // CPX $nnnn case 0xEC: CPX_Absolute(); break; // CPX $nnnn
case 0xE4: CPX_DirectPage(); break; // CPX $nn 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 0xC0: CPY_Immediate(); break; // CPY #$nn or #$nnnn
case 0xCC: CPY_Absolute(); break; // CPY $nnnn case 0xCC: CPY_Absolute(); break; // CPY $nnnn
case 0xC4: CPY_DirectPage(); break; // CPY $nn case 0xC4: CPY_DirectPage(); break; // CPY $nn
@@ -1468,3 +1492,27 @@ void CPU::JMP_AbsoluteIndirectX() {
cycles += 6; 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));
}

View File

@@ -8,7 +8,6 @@
// 65816 CPU implementation // 65816 CPU implementation
class CPU { class CPU {
private:
// Registers // Registers
uint16_t A; // Accumulator uint16_t A; // Accumulator
uint16_t X, Y; // Index registers uint16_t X, Y; // Index registers
@@ -37,7 +36,7 @@ private:
}; };
public: public:
CPU(Bus* memory_bus) : bus(memory_bus) { explicit CPU(Bus* memory_bus) : bus(memory_bus) {
Reset(); Reset();
} }
@@ -61,6 +60,9 @@ public:
void UpdateCompareFlags8(uint8_t reg_value, uint8_t compare_value); void UpdateCompareFlags8(uint8_t reg_value, uint8_t compare_value);
void UpdateCompareFlags16(uint16_t reg_value, uint16_t compare_value); void UpdateCompareFlags16(uint16_t reg_value, uint16_t compare_value);
// Branching helper method
void DoBranch(bool condition);
// Instruction implementations // Instruction implementations
// TODO: Implement remaining instructions // TODO: Implement remaining instructions
void CMP_Immediate(); void CMP_Immediate();
@@ -83,8 +85,6 @@ public:
void CPY_Absolute(); void CPY_Absolute();
void CPY_DirectPage(); void CPY_DirectPage();
void JMP();
static void NOP(); static void NOP();
void LDA_Immediate(); void LDA_Immediate();
@@ -151,6 +151,13 @@ public:
void JMP_AbsoluteIndirect(); void JMP_AbsoluteIndirect();
void JMP_AbsoluteLong(); void JMP_AbsoluteLong();
void JMP_AbsoluteIndirectX(); void JMP_AbsoluteIndirectX();
void BEQ_Relative();
void BNE_Relative();
void BCC_Relative();
void BCS_Relative();
void BMI_Relative();
void BPL_Relative();
}; };
#endif //CPU_H #endif //CPU_H