// // Created by Palindromic Bread Loaf on 7/21/25. // #ifndef CPU_H #define CPU_H #include "bus.h" // 65816 CPU implementation class CPU { // Registers uint16_t A; // Accumulator uint16_t X, Y; // Index registers uint16_t SP; // Stack pointer uint32_t PC; // Program counter (24-bit) uint8_t P; // Processor status uint8_t DB; // Data bank uint8_t PB; // Program bank uint16_t D; // Direct page Bus* bus; uint64_t cycles; bool emulation_mode = false; // Status flags enum Flags { FLAG_C = 0x01, // Carry FLAG_Z = 0x02, // Zero FLAG_I = 0x04, // IRQ disable FLAG_D = 0x08, // Decimal mode FLAG_X = 0x10, // Index register size (0=16-bit, 1=8-bit) FLAG_M = 0x20, // Memory/Accumulator size (0=16-bit, 1=8-bit) FLAG_V = 0x40, // Overflow FLAG_N = 0x80 // Negative // FLAG_E = ??? // 6502 Emulation Mode // FLAG_B = 0x10 //Break }; public: explicit CPU(Bus* memory_bus) : bus(memory_bus) { Reset(); } void Reset(); void Step(); void ExecuteInstruction(); [[nodiscard]] uint64_t GetCycles() const { return cycles; } // Addressing mode helpers //uint32_t GetEffectiveAddress(uint8_t mode); uint8_t ReadByte(uint32_t address); uint16_t ReadWord(uint32_t address); void UpdateNZ8(uint8_t value); void UpdateNZ16(uint16_t value); // Memory write helpers void WriteByte(uint32_t address, uint8_t value) const; void WriteWord(uint32_t address, uint16_t value) const; // Helper methods for compare operations 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); // Helper methods for stack operations void PushByte(uint8_t value); void PushWord(uint16_t value); uint8_t PopByte(); uint16_t PopWord(); // Helper method for ADC instructions void DoADC(uint16_t value); // Helper method to check for decimal mode adjustment static uint16_t AdjustDecimal(uint16_t binary_result, bool is_16bit); // Helper methods for ASL stuff void UpdateASLFlags8(uint8_t original_value, uint8_t result); void UpdateASLFlags16(uint16_t original_value, uint16_t result); // Helper methods for BIT void UpdateBITFlags8(uint8_t memory_value, uint8_t acc_value); void UpdateBITFlags16(uint16_t memory_value, uint16_t acc_value); void UpdateBITImmediateFlags8(uint8_t memory_value, uint8_t acc_value); void UpdateBITImmediateFlags16(uint16_t memory_value, uint16_t acc_value); // Instruction implementations // TODO: Implement remaining instructions void CMP_Immediate(); void CMP_Absolute(); void CMP_AbsoluteX(); void CMP_AbsoluteY(); void CMP_DirectPage(); void CMP_DirectPageX(); void CMP_IndirectDirectPage(); void CMP_IndirectDirectPageY(); void CMP_DirectPageIndirectX(); void CMP_Long(); void CMP_LongX(); void CPX_Immediate(); void CPX_Absolute(); void CPX_DirectPage(); void CPY_Immediate(); void CPY_Absolute(); void CPY_DirectPage(); static void NOP(); void LDA_Immediate(); void LDA_Absolute(); void LDA_AbsoluteX(); void LDA_AbsoluteY(); void LDA_DirectPage(); void LDA_DirectPageX(); void LDA_IndirectDirectPage(); void LDA_IndirectDirectPageY(); void LDA_DirectPageIndirectX(); void LDA_Long(); void LDA_LongX(); void LDX_Immediate(); void LDX_Absolute(); void LDX_AbsoluteY(); void LDX_DirectPage(); void LDX_DirectPageY(); void LDY_Immediate(); void LDY_Absolute(); void LDY_AbsoluteX(); void LDY_DirectPage(); void LDY_DirectPageX(); void STA_Absolute(); void STA_AbsoluteX(); void STA_AbsoluteY(); void STA_DirectPage(); void STA_DirectPageX(); void STA_IndirectDirectPage(); void STA_IndirectDirectPageY(); void STA_DirectPageIndirectX(); void STA_Long(); void STA_LongX(); void STX_Absolute(); void STX_DirectPage(); void STX_DirectPageY(); void STY_Absolute(); void STY_DirectPage(); void STY_DirectPageX(); void INC_Accumulator(); void INC_Absolute(); void INC_AbsoluteX(); void INC_DirectPage(); void INC_DirectPageX(); void DEC_Accumulator(); void DEC_Absolute(); void DEC_AbsoluteX(); void DEC_DirectPage(); void DEC_DirectPageX(); void INX(); void INY(); void DEX(); void DEY(); void JMP_Absolute(); 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(); void JSR_Absolute(); void JSR_AbsoluteLong(); void JSR_AbsoluteIndirectX(); void RTS(); void RTL(); void PHA(); void PLA(); void PHX(); void PLX(); void PHY(); void PLY(); void PHP(); void PLP(); void PHB(); void PLB(); void PHD(); void PLD(); void PHK(); void ADC_Immediate(); void ADC_Absolute(); void ADC_AbsoluteX(); void ADC_AbsoluteY(); void ADC_DirectPage(); void ADC_DirectPageX(); void ADC_IndirectDirectPage(); void ADC_IndirectDirectPageY(); void ADC_DirectPageIndirectX(); void ADC_AbsoluteLong(); void ADC_AbsoluteLongX(); void ADC_DirectPageIndirectLong(); void ADC_DirectPageIndirectLongY(); void ADC_StackRelative(); void ADC_StackRelativeIndirectY(); void AND_Immediate(); void AND_Absolute(); void AND_AbsoluteX(); void AND_AbsoluteY(); void AND_DirectPage(); void AND_DirectPageX(); void AND_IndirectDirectPage(); void AND_IndirectDirectPageLong(); void AND_IndexedIndirectDirectPageX(); void AND_IndirectDirectPageY(); void AND_IndirectDirectPageLongY(); void AND_AbsoluteLong(); void AND_AbsoluteLongX(); void AND_StackRelative(); void AND_StackRelativeIndirectY(); void ASL_Accumulator(); void ASL_Absolute(); void ASL_AbsoluteX(); void ASL_DirectPage(); void ASL_DirectPageX(); void BIT_Immediate(); void BIT_Absolute(); void BIT_AbsoluteX(); void BIT_DirectPage(); void BIT_DirectPageX(); void BRA_Relative(); void BRL_RelativeLong(); void BVC_Relative(); void BVS_Relative(); void BRK(); void CLC(); void CLD(); void CLI(); void CLV(); }; #endif //CPU_H