#include "cpu/cpu.h" #include "memory/mem_device.h" u8 Cpu::readPC8() { u8 data = bus->read8(state.PC); state.PC++; return data; } u16 Cpu::readPC16() { u16 data = bus->read16(state.PC); state.PC+=2; return data; } void Cpu::pushStack8(u8 data) { bus->write8(state.SP, data); state.SP--; } u8 Cpu::popStack8() { u8 data = bus->read8(state.SP); state.SP++; return data; } void Cpu::pushStack16(u16 data) { bus->write16(state.SP,data); state.SP-=2; } u16 Cpu::popStack16() { u16 data = bus->read16(state.SP); state.SP+=2; return data; } void Cpu::step() { opcode_t op = readPC8(); int mcycles = 1; if ((op & 0xC0 == 0x40) && op != 0x76) // Lots of LD (0x76 is HALT) { u9 tmp; switch(op & 0x07) { case 0x0: tmp = state.B; break; case 0x1: tmp = state.C; break; case 0x2: tmp = state.D; break; case 0x3: tmp = state.E; break; case 0x4: tmp = state.H; break; case 0x5: tmp = state.L; break; case 0x6: tmp = bus->read8(state.HL); break; case 0x7: tmp = state.A; break; }; switch(op & 0x38) { case 0x00: state.B = tmp; break; case 0x10: state.D = tmp; break; case 0x20: state.H = tmp; break; case 0x30: bus->write8(state.HL, tmp); break; case 0x08: state.C = tmp; break; case 0x18: state.E = tmp; break; case 0x28: state.L = tmp; break; case 0x38: state.A = tmp; break; } } else if(op & 0xC7 == 0x06) { } else { switch(op) { case 0x00: break; // NOP case 0x01: // LD BC, n16 state.BC = readPC16(); mcycles = 12; break; case 0x11: // LD DE, n16 state.DE = readPC16(); mcycles = 12; break; case 0x21: // LD HL, n16 state.HL = readPC16(); mcycles = 12; break; case 0x31: // LD SP, n16 state.SP = readPC16(); mcycles = 12; break; case 0x02: // LD [BC], A bus->write8(state.BC, state.A); mcycles = 8; break; case 0x12: // LD [DE], A bus->write8(state.DE, state.A); mcycles = 8; break; case 0x22: // LD [HL+], A bus->write8(state.HL, state.A); state.HL++; mcycles = 8; break; case 0x32: // LD [HL-], A bus->write8(state.HL, state.A); state.HL--; mcycles = 8; break; case 0x03: // INC BC state.BC++; mcycles = 2; break; case 0x13: // INC DE state.DE++; mcycles = 2; break; case 0x23: // INC HL state.HL++; mcycles = 2; break; case 0x33: // INC SP state.SP++; mcycles = 2; break; case 0x04: // INC B state.B++; state.zero = (state.B == 0); state.subtract = false; state.halfcarry = (state.B & 0x0F == 0); break; case 0x14: // INC D state.D++; state.zero = (state.D == 0); state.subtract = false; state.halfcarry = (state.D & 0x0F == 0); break; case 0x24: // INC H state.H++; state.zero = (state.H == 0); state.subtract = false; state.halfcarry = (state.H & 0x0F == 0); break; case 0x34: // INC [HL] { u8 data = bus->read8(state.HL); data++; bus->write8(state.HL, data); state.zero = (data == 0); state.subtract = false; state.halfcarry = (data & 0x0F == 0); mcycles = 3; } break; case 0x05: // INC B state.B--; state.zero = (state.B == 0); state.subtract = true; state.halfcarry = (state.B & 0x0F == 0x0F); break; case 0x15: // INC D state.D--; state.zero = (state.D == 0); state.subtract = true; state.halfcarry = (state.D & 0x0F == 0x0F); break; case 0x25: // INC H state.H--; state.zero = (state.H == 0); state.subtract = true; state.halfcarry = (state.H & 0x0F == 0x0F); break; case 0x35: // INC [HL] { u8 data = bus->read8(state.HL); data--; bus->write8(state.HL, data); state.zero = (data == 0); state.subtract = true; state.halfcarry = (data & 0x0F == 0x0F); mcycles = 3; } break; case 0x06: // LD B, n8 state.B = readPC8(); mcycles = 2; break; case 0x16: // LD D, n8 state.D = readPC8(); mcycles = 2; break; case 0x26: // LD H, n8 state.H = readPC8(); mcycles = 2; break; case 0x36: // LD [HL], n8 bus->write8(state.HL, readPC8()); mcycles = 3; break; case 0x07: // RLCA case 0x17: // RLA case 0x27: // DAA case 0x37: // SCF break; case 0x08: // LD [a16], SP { u16 addr = readPC16(); bus->write16(addr, state.SP); mcycles = 5; } break; case 0x18: // JR e8 { s8 rel = readPC8(); state.PC = state.PC + rel; mcycles = 3; } break; case 0x28: // JR Z, e8 { s8 rel = readPC8(); if (state.zero) { state.PC = state.PC + rel; mcycles = 3; } else { mcycles = 2; } } break; case 0x38: // JR C, e8 { s8 rel = readPC8(); if (state.carry) { state.PC = state.PC + rel; mcycles = 3; } else { mcycles = 2; } } break; case 0x09: // ADD HL, BC case 0x19: // ADD HL, DE case 0x29: // ADD HL, HL case 0x39: // ADD HL, SP // TODO break; case 0x0A: // LD A, [BC] state.A = bus->read8(state.BC); break; case 0x1A: // LD A, [DE] state.A = bus->read8(state.DE); break; case 0x2A: // LD A, [HL+] state.A = bus->read8(state.HL); state.HL++; break; case 0x3A: // LD A, [HL-] state.A = bus->read8(state.HL); state.HL--; break; case 0x0B: // DEC BC state.BC--; break; case 0x1B: // DEC DE state.DE--; break; case 0x2B: // DEC HL state.HL--; break; case 0x3B: // DEC SP state.SP--; break; case 0x0C: // INC C state.C++; state.zero = (state.C == 0); state.subtract = false; state.halfcarry = (state.C & 0x0F == 0); break; case 0x1C: // INC E state.E++; state.zero = (state.E == 0); state.subtract = false; state.halfcarry = (state.E & 0x0F == 0); break; case 0x2C: // INC L state.L++; state.zero = (state.L == 0); state.subtract = false; state.halfcarry = (state.L & 0x0F == 0); break; case 0x3C: // INC A state.A++; state.zero = (state.A == 0); state.subtract = false; state.halfcarry = (state.A & 0x0F == 0); break; case 0x0D: // DEC C state.C--; state.zero = (state.C == 0); state.subtract = true; state.halfcarry = (state.C & 0x0F == 0x0F); break; case 0x1D: // DEC E state.E--; state.zero = (state.E == 0); state.subtract = true; state.halfcarry = (state.E & 0x0F == 0x0F); break; case 0x2D: // DEC L state.L--; state.zero = (state.L == 0); state.subtract = true; state.halfcarry = (state.L & 0x0F == 0x0F); break; case 0x3D: // DEC A state.A--; state.zero = (state.A == 0); state.subtract = true; state.halfcarry = (state.A & 0x0F == 0x0F); break; case 0x0E: // LD C, n8 state.C = readPC8(); mcycles = 2; break; case 0x1E: // LD E, n8 state.E = readPC8(); mcycles = 2; break; case 0x2E: // LD L, n8 state.L = readPC8(); mcycles = 2; break; case 0x3E: // LD A, n8 state.A = readPC8(); mcycles = 2; break; case 0x0F: // RRCA case 0x1F: // RRA case 0x2F: // CPL case 0x3F: // CCF // TODO break; } } }