#pragma once #include #include "Processor.h" #include "Bus.h" class LR35902 : public EightBit::Processor { public: enum StatusBits { ZF = Bit7, NF = Bit6, HC = Bit5, CF = Bit4, }; LR35902(Bus& memory); EightBit::Signal ExecutingInstruction; void stop() { m_stopped = true; } void start() { m_stopped = false; } bool stopped() const { return m_stopped; } bool& IME() { return m_ime; } void di(); void ei(); int interrupt(uint8_t value); int execute(uint8_t opcode); int step(); // Mutable access to processor!! EightBit::register16_t& AF() { m_accumulatorFlag.low &= 0xf0; return m_accumulatorFlag; } uint8_t& A() { return AF().high; } uint8_t& F() { return AF().low; } EightBit::register16_t& BC() { return m_registers[BC_IDX]; } uint8_t& B() { return BC().high; } uint8_t& C() { return BC().low; } EightBit::register16_t& DE() { return m_registers[DE_IDX]; } uint8_t& D() { return DE().high; } uint8_t& E() { return DE().low; } EightBit::register16_t& HL() { return m_registers[HL_IDX]; } uint8_t& H() { return HL().high; } uint8_t& L() { return HL().low; } virtual void reset(); virtual void initialise(); private: enum { BC_IDX, DE_IDX, HL_IDX }; std::array m_registers; EightBit::register16_t m_accumulatorFlag; bool m_ime; bool m_prefixCB; bool m_stopped; std::array m_halfCarryTableAdd = { { false, false, true, false, true, false, true, true } }; std::array m_halfCarryTableSub = { { false, true, true, true, false, false, false, true } }; EightBit::register16_t fetchWord() { EightBit::register16_t returned; Processor::fetchWord(returned); return returned; } int fetchExecute() { return execute(fetchByte()); } void clearFlag(int flag) { F() &= ~flag; } void setFlag(int flag) { F() |= flag; } void setFlag(int flag, int condition) { setFlag(flag, condition != 0); } void setFlag(int flag, uint32_t condition) { setFlag(flag, condition != 0); } void setFlag(int flag, bool condition) { condition ? setFlag(flag) : clearFlag(flag); } void clearFlag(int flag, int condition) { clearFlag(flag, condition != 0); } void clearFlag(int flag, uint32_t condition) { clearFlag(flag, condition != 0); } void clearFlag(int flag, bool condition) { condition ? clearFlag(flag) : setFlag(flag); } uint8_t& R(int r) { switch (r) { case 0: return B(); case 1: return C(); case 2: return D(); case 3: return E(); case 4: return H(); case 5: return L(); case 6: m_memory.ADDRESS() = HL(); return m_memory.reference(); case 7: return A(); } throw std::logic_error("Unhandled registry mechanism"); } EightBit::register16_t& RP(int rp) { switch (rp) { case 3: return sp; default: return m_registers[rp]; } } EightBit::register16_t& RP2(int rp) { switch (rp) { case 3: return AF(); default: return m_registers[rp]; } } int buildHalfCarryIndex(uint8_t before, uint8_t value, int calculation) { return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3); } void adjustHalfCarryAdd(uint8_t before, uint8_t value, int calculation) { auto index = buildHalfCarryIndex(before, value, calculation); setFlag(HC, m_halfCarryTableAdd[index & 0x7]); } void adjustHalfCarrySub(uint8_t before, uint8_t value, int calculation) { auto index = buildHalfCarryIndex(before, value, calculation); setFlag(HC, m_halfCarryTableSub[index & 0x7]); } void executeCB(int x, int y, int z, int p, int q); void executeOther(int x, int y, int z, int p, int q); void adjustZero(uint8_t value); void postIncrement(uint8_t value); void postDecrement(uint8_t value); void restart(uint8_t address); void jrConditional(int conditional); void jrConditionalFlag(int flag); void ret(); void reti(); void returnConditional(int condition); void returnConditionalFlag(int flag); void jumpConditional(int condition); void jumpConditionalFlag(int flag); void call(uint16_t address); void callConditional(uint16_t address, int condition); void callConditionalFlag(uint16_t address, int flag); uint16_t sbc(uint16_t value); uint16_t adc(uint16_t value); uint16_t add(uint16_t value); void sub(uint8_t& operand, uint8_t value, bool carry); void sub(uint8_t& operand, uint8_t value); void sbc(uint8_t& operand, uint8_t value); void add(uint8_t& operand, uint8_t value, bool carry); void add(uint8_t& operand, uint8_t value); void adc(uint8_t& operand, uint8_t value); void andr(uint8_t& operand, uint8_t value); void anda(uint8_t value); void xora(uint8_t value); void ora(uint8_t value); void compare(uint8_t value); void rlca(); void rrca(); void rla(); void rra(); void rlc(uint8_t& operand); void rrc(uint8_t& operand); void rl(uint8_t& operand); void rr(uint8_t& operand); void sla(uint8_t& operand); void sra(uint8_t& operand); void srl(uint8_t& operand); void bit(int n, uint8_t& operand); void res(int n, uint8_t& operand); void set(int nit, uint8_t& operand); void daa(); void scf(); void ccf(); void cpl(); void swap(uint8_t& operand); };