Add opcodes
This commit is contained in:
@@ -27,7 +27,8 @@ namespace MCEmuCore.GBMonolith
|
|||||||
|
|
||||||
OpCodeTable = new Dictionary<byte, Func<OpCode, bool>>()
|
OpCodeTable = new Dictionary<byte, Func<OpCode, bool>>()
|
||||||
{
|
{
|
||||||
{0x00, (op) => {
|
#region OpCodes 0x00-0x0F
|
||||||
|
{0x00, (op) =>{
|
||||||
registers.PC += 1;
|
registers.PC += 1;
|
||||||
return true;
|
return true;
|
||||||
} },
|
} },
|
||||||
@@ -65,11 +66,188 @@ namespace MCEmuCore.GBMonolith
|
|||||||
|
|
||||||
registers.Flags.Subtract = false;
|
registers.Flags.Subtract = false;
|
||||||
registers.Flags.Zero = reg == 0;
|
registers.Flags.Zero = reg == 0;
|
||||||
|
// This logic only works for the increment operation
|
||||||
registers.Flags.HalfCarry = reg == 16;
|
registers.Flags.HalfCarry = reg == 16;
|
||||||
|
|
||||||
registers.PC += 1;
|
registers.PC += 1;
|
||||||
return true;
|
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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -252,7 +252,13 @@ namespace MCEmuCore.GBMonolith
|
|||||||
|
|
||||||
public class FlagRegister
|
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
|
#region Boolean Flag Properties
|
||||||
public bool Zero
|
public bool Zero
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace MCEmuCore.GBMonolith
|
|||||||
|
|
||||||
static void TestRegisters()
|
static void TestRegisters()
|
||||||
{
|
{
|
||||||
CpuRegisters cpuRegisters = new CpuRegisters(true);
|
CpuRegisters cpuRegisters = new CpuRegisters(0);
|
||||||
Console.WriteLine("Initializing registers:");
|
Console.WriteLine("Initializing registers:");
|
||||||
Console.WriteLine("A:\t1\tF:\t16");
|
Console.WriteLine("A:\t1\tF:\t16");
|
||||||
Console.WriteLine("B:\t2\tC:\t100");
|
Console.WriteLine("B:\t2\tC:\t100");
|
||||||
|
|||||||
Reference in New Issue
Block a user