diff --git a/MCEmuCore.GBMonolith/Cpu.cs b/MCEmuCore.GBMonolith/Cpu.cs index 4433798..c37d83e 100644 --- a/MCEmuCore.GBMonolith/Cpu.cs +++ b/MCEmuCore.GBMonolith/Cpu.cs @@ -27,7 +27,8 @@ namespace MCEmuCore.GBMonolith OpCodeTable = new Dictionary>() { - {0x00, (op) => { + #region OpCodes 0x00-0x0F + {0x00, (op) =>{ registers.PC += 1; return true; } }, @@ -65,11 +66,188 @@ namespace MCEmuCore.GBMonolith registers.Flags.Subtract = false; registers.Flags.Zero = reg == 0; + // This logic only works for the increment operation registers.Flags.HalfCarry = reg == 16; registers.PC += 1; return true; + } }, + {0x05, (op) => + { + // DEC B + byte reg = (byte)((uint)registers.B - 1); + registers.B = reg; + + registers.Flags.Subtract = true; + registers.Flags.Zero = reg == 0; + // This logic only works for the decrement operation + registers.Flags.HalfCarry = reg == 15; + + registers.PC += 1; + return true; + } }, + {0x06, (op) => + { + // LD B,d8 + if (op.Arg1.HasValue) + { + registers.B = op.Arg1.Value; + registers.PC += 2; + return true; + } + else + { + throw new InvalidOperationException(op, "Missing arguments for LD B"); + } + } }, + {0x07, (op) => + { + // RLCA + registers.Flags.Zero = false; + registers.Flags.Subtract = false; + registers.Flags.HalfCarry = false; + registers.Flags.Carry = (registers.A & 0b1000_0000) != 0; + + registers.A = (byte)((registers.A << 1) + (registers.A >> 7)); + registers.PC += 1; + return true; + } }, + {0x08, (op) => + { + // LD (a16), SP + // Load SP into address + throw new NotImplementedException("LD (a16), SP"); + } }, + {0x09, (op) => + { + // ADD HL, BC + registers.Flags.Subtract = false; + registers.Flags.HalfCarry = (((registers.HL & 0x0FFF) + (registers.BC & 0x0FFF) & 0x1000) == 0x1000); + registers.Flags.Carry = (((registers.HL + registers.BC) & 0x10000) == 0x10000); + + registers.HL += registers.BC; + registers.PC += 1; + + return true; + } }, + {0x0A, (op) => + { + // LD A, (BC) + // Load byte at address stored in BC into A + throw new NotImplementedException("LD A, (BC)"); + } }, + {0x0B, (op) => + { + // DEC BC + registers.BC -= 1; + registers.PC += 1; + return true; + } }, + {0x0C, (op) => + { + // INC C + byte reg = (byte)(registers.C + 1); + registers.C = reg; + + registers.Flags.Subtract = false; + registers.Flags.Zero = reg == 0; + // This logic only works for the increment operation + registers.Flags.HalfCarry = reg == 16; + + registers.PC += 1; + return true; + } }, + {0x0D, (op) => + { + // DEC C + byte reg = (byte)((uint)registers.C - 1); + registers.C = reg; + + registers.Flags.Subtract = true; + registers.Flags.Zero = reg == 0; + // This logic only works for the decrement operation + registers.Flags.HalfCarry = reg == 15; + + registers.PC += 1; + return true; + } }, + {0x0E, (op) => + { + // LD C,d8 + if (op.Arg1.HasValue) + { + registers.C = op.Arg1.Value; + registers.PC += 2; + return true; + } + else + { + throw new InvalidOperationException(op, "Missing argument for LD B"); + } + } }, + {0x0F, (op) => + { + // RRCA + registers.Flags.Zero = false; + registers.Flags.Subtract = false; + registers.Flags.HalfCarry = false; + registers.Flags.Carry = (registers.A & 0b0000_0001) != 0; + + registers.A = (byte)((registers.A >> 1) + (registers.A << 7)); + registers.PC += 1; + return true; + } }, + #endregion + #region OpCodes 0x10-0x1F + {0x10, (op) => + { + // STOP 0 + // Halts CPU & LCD until button pressed + throw new NotImplementedException("STOP"); } } + #endregion + #region OpCodes 0x20-0x2F + + #endregion + #region OpCodes 0x30-0x3F + + #endregion + #region OpCodes 0x40-0x4F + + #endregion + #region OpCodes 0x50-0x5F + + #endregion + #region OpCodes 0x60-0x6F + + #endregion + #region OpCodes 0x70-0x7F + + #endregion + #region OpCodes 0x80-0x8F + + #endregion + #region OpCodes 0x90-0x9F + + #endregion + #region OpCodes 0xA0-0xAF + + #endregion + #region OpCodes 0xB0-0xBF + + #endregion + #region OpCodes 0xC0-0xCF + + #endregion + #region OpCodes 0xD0-0xDF + + #endregion + #region OpCodes 0xE0-0xEF + + #endregion + #region OpCodes 0xF0-0xFF + + #endregion }; } } diff --git a/MCEmuCore.GBMonolith/CpuRegisters.cs b/MCEmuCore.GBMonolith/CpuRegisters.cs index 86d3aa5..31f7b89 100644 --- a/MCEmuCore.GBMonolith/CpuRegisters.cs +++ b/MCEmuCore.GBMonolith/CpuRegisters.cs @@ -252,7 +252,13 @@ namespace MCEmuCore.GBMonolith public class FlagRegister { - protected internal byte Value { get; set; } + private byte register; + public byte Value { + get => register; + set { + register = (byte)(value & 0b1111_0000); + } + } #region Boolean Flag Properties public bool Zero { diff --git a/MCEmuCore.GBMonolith/Program.cs b/MCEmuCore.GBMonolith/Program.cs index c533403..55c5f46 100644 --- a/MCEmuCore.GBMonolith/Program.cs +++ b/MCEmuCore.GBMonolith/Program.cs @@ -11,7 +11,7 @@ namespace MCEmuCore.GBMonolith static void TestRegisters() { - CpuRegisters cpuRegisters = new CpuRegisters(true); + CpuRegisters cpuRegisters = new CpuRegisters(0); Console.WriteLine("Initializing registers:"); Console.WriteLine("A:\t1\tF:\t16"); Console.WriteLine("B:\t2\tC:\t100");