using System; using System.Collections.Generic; namespace MCEmuCore.GBMonolith { public struct OpCode { public readonly byte Instruction; public byte? Arg1; public byte? Arg2; } class Cpu { const byte ZERO_FLAG = 0b10000000; const byte SUB_FLAG = 0b01000000; const byte HALF_CARRY = 0b00100000; const byte FULL_CARRY = 0b00010000; private readonly CpuRegisters registers; #region OpCodes private readonly Dictionary> OpCodeTable; #endregion public Cpu() { registers = new CpuRegisters(); OpCodeTable = new Dictionary>() { {0x00, (op) => { registers.PC += 1; return true; } }, {0x01, (op) => { // LD BC,d16 if (op.Arg1.HasValue && op.Arg2.HasValue) { ushort operand = (ushort)(op.Arg2 + (op.Arg1 << 8)); registers.BC = operand; registers.PC += 3; return true; } else { throw new InvalidOperationException(op, "Missing arguments for LD BC"); } } }, {0x02, (op) => { // LD (BC), A throw new NotImplementedException("LD (BC), A"); } }, {0x03, (op) => { registers.BC += 1; registers.PC += 1; return true; } }, {0x04, (op) => { // INC B byte reg = (byte)(registers.B + 1); registers.B = reg; registers.Flags.Subtract = false; registers.Flags.Zero = reg == 0; registers.Flags.HalfCarry = reg == 16; registers.PC += 1; return true; } } }; } } [Serializable] public class InvalidOperationException : Exception { public OpCode OpCode { get; set; } public InvalidOperationException() { } public InvalidOperationException(OpCode opCode, string message) : base(message) { OpCode = opCode; } public InvalidOperationException(string message) : base(message) { } public InvalidOperationException(string message, Exception inner) : base(message, inner) { } protected InvalidOperationException( System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } } }