Add some branching instructions
This commit is contained in:
48
src/cpu.cpp
48
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<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
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
15
src/cpu.h
15
src/cpu.h
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user