nes/src/Cpu.h

159 lines
4.5 KiB
C++

//
// Created by Selim Mustafaev on 11.08.2023.
//
#ifndef NES_CPU_H
#define NES_CPU_H
#include <cstdint>
#include <vector>
#include <memory>
namespace nes {
class System;
enum CpuFlags: uint8_t {
Carry = (1 << 0),
Zero = (1 << 1),
InterruptDisable = (1 << 2),
DecimalMode = (1 << 3),
Break = (1 << 4),
Unused = (1 << 5),
Overflow = (1 << 6),
Negative = (1 << 7)
};
class Cpu {
public:
struct InstructionArgs {
uint16_t address;
uint8_t cycles;
};
struct Instruction {
char name[4];
void(Cpu::*process)(InstructionArgs);
InstructionArgs(Cpu::*getAddress)();
uint8_t cycles;
bool variableCycles;
};
static constexpr uint16_t STACK_BASE = 0x0100;
public:
explicit Cpu(System* system);
void reset();
bool tick();
void setFlag(CpuFlags flag, bool value);
bool getFlag(CpuFlags flag) const;
void setStartAddress(uint16_t address);
void nmi();
#ifdef NES_LOGGING
std::string state() const;
#endif
private:
size_t _ticks;
System* _system;
std::vector<Instruction> _instructions;
private:
// Registers
uint8_t A; // Accumulator
uint8_t X; // - Index registers
uint8_t Y; // /
uint16_t PC; // Program Counter
uint8_t SP; // Stack Pointer
uint8_t flags;
private:
// Debug info
uint8_t _currentOpcode;
private:
void branch(InstructionArgs args);
private:
InstructionArgs IMM();
InstructionArgs ABSL();
InstructionArgs IMPL();
InstructionArgs REL();
InstructionArgs ZP0();
InstructionArgs IZX();
InstructionArgs IZY();
InstructionArgs IND();
InstructionArgs ABX();
InstructionArgs ABY();
InstructionArgs ZPX();
InstructionArgs ZPY();
private:
void LDA(InstructionArgs args);
void LDX(InstructionArgs args);
void LDY(InstructionArgs args);
void STA(InstructionArgs args);
void STX(InstructionArgs args);
void CLC(InstructionArgs args);
void ADC(InstructionArgs args);
void SBC(InstructionArgs args);
void DEY(InstructionArgs args);
void BNE(InstructionArgs args);
void NOP(InstructionArgs args);
void SEI(InstructionArgs args);
void CLD(InstructionArgs args);
void TXS(InstructionArgs args);
void BPL(InstructionArgs args);
void JMP(InstructionArgs args);
void JSR(InstructionArgs args);
void SEC(InstructionArgs args);
void BCS(InstructionArgs args);
void BCC(InstructionArgs args);
void BEQ(InstructionArgs args);
void BIT(InstructionArgs args);
void BVS(InstructionArgs args);
void BVC(InstructionArgs args);
void RTS(InstructionArgs args);
void SED(InstructionArgs args);
void PHP(InstructionArgs args);
void PLA(InstructionArgs args);
void AND(InstructionArgs args);
void CMP(InstructionArgs args);
void BMI(InstructionArgs args);
void PHA(InstructionArgs args);
void PLP(InstructionArgs args);
void ORA(InstructionArgs args);
void CLV(InstructionArgs args);
void EOR(InstructionArgs args);
void CPY(InstructionArgs args);
void CPX(InstructionArgs args);
void STY(InstructionArgs args);
void INY(InstructionArgs args);
void INX(InstructionArgs args);
void DEX(InstructionArgs args);
void TAY(InstructionArgs args);
void TAX(InstructionArgs args);
void TYA(InstructionArgs args);
void TXA(InstructionArgs args);
void TSX(InstructionArgs args);
void BRK(InstructionArgs args);
void RTI(InstructionArgs args);
void LSR_ACC(InstructionArgs args);
void LSR(InstructionArgs args);
void ASL_ACC(InstructionArgs args);
void ASL(InstructionArgs args);
void ROR_ACC(InstructionArgs args);
void ROR(InstructionArgs args);
void ROL_ACC(InstructionArgs args);
void ROL(InstructionArgs args);
void INC(InstructionArgs args);
void DEC(InstructionArgs args);
};
}
#endif //NES_CPU_H