#pragma once #include "types.h" class Cpu; class Mem_device; enum Flags { F_ZERO = 0x8, F_SUB = 0x4, F_HALF = 0x2, F_CARRY = 0x1, }; enum AluOp : int { ADD = 0, ADC = 1, SUB = 2, SBC = 3, AND = 4, XOR = 5, OR = 6, CP = 7, }; enum CC { COND_NZ = 0, COND_Z = 1, COND_NC = 2, COND_C = 3, }; struct Cpu_state { // Registers union { u16 BC; struct { u8 B; u8 C; }; }; union { u16 DE; struct { u8 D; u8 E; }; }; union { u16 HL; struct { u8 H; u8 L; }; }; u8 A; u16 SP; u16 PC; bool zero; bool subtract; bool halfcarry; bool carry; bool IME; // interrupts enabled/disabled bool IME_scheduled; // interrupts about to be enabled bool bootRomEnabled; // Whether boot ROM is visible void setAF(u16 v); u16 getAF(); }; class Cpu { private: Cpu_state state; Mem_device* bus; typedef u8 opcode_t; private: u8 readPC8(); u16 readPC16(); void pushStack8(u8 data); u8 popStack8(); void pushStack16(u16 data); u16 popStack16(); void aluop8(AluOp op, u8 lhs, u8 rhs, u8& out, bool update_carry = true); inline void aluop8(AluOp op, u8 rhs, bool update_carry = true) { aluop8(op, state.A, rhs, state.A, update_carry); } void doCall(u16 target); void doRet(); bool decodeCond(u8 cc); public: Cpu(); void step(); };