Files
MCEmuCore/MCEmuCore.GBMonolith/Cpu.cs
2019-02-07 15:56:39 -07:00

94 lines
2.9 KiB
C#

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<byte, Func<OpCode, bool>> OpCodeTable;
#endregion
public Cpu()
{
registers = new CpuRegisters();
OpCodeTable = new Dictionary<byte, Func<OpCode, bool>>()
{
{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) { }
}
}