Most opcodes implemented, Prefix CB remains
This commit is contained in:
@@ -970,124 +970,124 @@ namespace MCEmuCore.GBMonolith
|
||||
#region OpCodes 0xA0-0xAF
|
||||
// 0xA0
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A & registers.B);
|
||||
registers.A = AndRegisters(registers.A, registers.B);
|
||||
return 4;
|
||||
},
|
||||
// 0xA1
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A & registers.C);
|
||||
registers.A = AndRegisters(registers.A, registers.C);
|
||||
return 4;
|
||||
},
|
||||
// 0xA2
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A & registers.D);
|
||||
registers.A = AndRegisters(registers.A, registers.D);
|
||||
return 4;
|
||||
},
|
||||
// 0xA3
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A & registers.E);
|
||||
registers.A = AndRegisters(registers.A, registers.E);
|
||||
return 4;
|
||||
},
|
||||
// 0xA4
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A & registers.H);
|
||||
registers.A = AndRegisters(registers.A, registers.H);
|
||||
return 4;
|
||||
},
|
||||
// 0xA5
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A & registers.L);
|
||||
registers.A = AndRegisters(registers.A, registers.L);
|
||||
return 4;
|
||||
},
|
||||
// 0xA6
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A & memory.ReadByte(registers.HL));
|
||||
registers.A = AndRegisters(registers.A, memory.ReadByte(registers.HL));
|
||||
return 8;
|
||||
},
|
||||
// 0xA7
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A & registers.A);
|
||||
registers.A = AndRegisters(registers.A, registers.A);
|
||||
return 4;
|
||||
},
|
||||
// 0xA8
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A ^ registers.B);
|
||||
registers.A = XorRegisters(registers.A, registers.B);
|
||||
return 4;
|
||||
},
|
||||
// 0xA9
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A ^ registers.C);
|
||||
registers.A = XorRegisters(registers.A, registers.C);
|
||||
return 4;
|
||||
},
|
||||
// 0xAA
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A ^ registers.D);
|
||||
registers.A = XorRegisters(registers.A, registers.D);
|
||||
return 4;
|
||||
},
|
||||
// 0xAB
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A ^ registers.E);
|
||||
registers.A = XorRegisters(registers.A, registers.E);
|
||||
return 4;
|
||||
},
|
||||
// 0xAC
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A ^ registers.H);
|
||||
registers.A = XorRegisters(registers.A, registers.H);
|
||||
return 4;
|
||||
},
|
||||
// 0xAD
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A ^ registers.L);
|
||||
registers.A = XorRegisters(registers.A, registers.L);
|
||||
return 4;
|
||||
},
|
||||
// 0xAE
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A ^ memory.ReadByte(registers.HL));
|
||||
registers.A = XorRegisters(registers.A, memory.ReadByte(registers.HL));
|
||||
return 8;
|
||||
},
|
||||
// 0xAF
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A ^ registers.A);
|
||||
registers.A = XorRegisters(registers.A, registers.A);
|
||||
return 4;
|
||||
},
|
||||
#endregion
|
||||
#region OpCodes 0xB0-0xBF
|
||||
// 0xB0
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A | registers.B);
|
||||
registers.A = OrRegisters(registers.A, registers.B);
|
||||
return 4;
|
||||
},
|
||||
// 0xB1
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A | registers.C);
|
||||
registers.A = OrRegisters(registers.A, registers.C);
|
||||
return 4;
|
||||
},
|
||||
// 0xB2
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A | registers.D);
|
||||
registers.A = OrRegisters(registers.A, registers.D);
|
||||
return 4;
|
||||
},
|
||||
// 0xB3
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A | registers.E);
|
||||
registers.A = OrRegisters(registers.A, registers.E);
|
||||
return 4;
|
||||
},
|
||||
// 0xB4
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A | registers.H);
|
||||
registers.A = OrRegisters(registers.A, registers.H);
|
||||
return 4;
|
||||
},
|
||||
// 0xB5
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A | registers.L);
|
||||
registers.A = OrRegisters(registers.A, registers.L);
|
||||
return 4;
|
||||
},
|
||||
// 0xB6
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A | memory.ReadByte(registers.HL));
|
||||
registers.A = OrRegisters(registers.A, memory.ReadByte(registers.HL));
|
||||
return 8;
|
||||
},
|
||||
// 0xB7
|
||||
(op) => {
|
||||
registers.A = (byte)(registers.A | registers.A);
|
||||
registers.A = OrRegisters(registers.A, registers.A);
|
||||
return 4;
|
||||
},
|
||||
// 0xB8
|
||||
@@ -1267,47 +1267,98 @@ namespace MCEmuCore.GBMonolith
|
||||
#region OpCodes 0xD0-0xDF
|
||||
// 0xD0
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xD0");
|
||||
if (!registers.Flags.Carry)
|
||||
{
|
||||
Jump(PopShort());
|
||||
return 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
},
|
||||
// 0xD1
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xD1");
|
||||
registers.DE = PopShort();
|
||||
return 12;
|
||||
},
|
||||
// 0xD2
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xD2");
|
||||
ushort jumpAddress = ReadShortFromInstruction();
|
||||
if (!registers.Flags.Carry)
|
||||
{
|
||||
Jump(jumpAddress);
|
||||
return 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
},
|
||||
// 0xD3
|
||||
(op) => {
|
||||
throw new IllegalInstructionException(op, "Instruction does not exist");
|
||||
throw new IllegalInstructionException(op, "Instruction does not exist: 0xD3");
|
||||
},
|
||||
// 0xD4
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xD4");
|
||||
ushort jumpAddress = ReadShortFromInstruction();
|
||||
if (!registers.Flags.Carry)
|
||||
{
|
||||
PushShort(registers.PC);
|
||||
Jump(jumpAddress);
|
||||
return 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
},
|
||||
// 0xD5
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xD5");
|
||||
PushShort(registers.DE);
|
||||
return 16;
|
||||
},
|
||||
// 0xD6
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xD6");
|
||||
registers.A = SubtractRegisters(registers.A, ReadInstruction());
|
||||
return 8;
|
||||
},
|
||||
// 0xD7
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xD7");
|
||||
PushShort(registers.PC);
|
||||
Jump(0x0010);
|
||||
return 16;
|
||||
},
|
||||
// 0xD8
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xD8");
|
||||
if (registers.Flags.Carry)
|
||||
{
|
||||
Jump(PopShort());
|
||||
return 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
},
|
||||
// 0xD9
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xD9");
|
||||
Jump(PopShort());
|
||||
interruptsEnabled = true;
|
||||
return 16;
|
||||
},
|
||||
// 0xDA
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xDA");
|
||||
ushort jumpAddress = ReadShortFromInstruction();
|
||||
if (registers.Flags.Carry)
|
||||
{
|
||||
Jump(jumpAddress);
|
||||
return 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
},
|
||||
// 0xDB
|
||||
(op) => {
|
||||
@@ -1315,7 +1366,17 @@ namespace MCEmuCore.GBMonolith
|
||||
},
|
||||
// 0xDC
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xDC");
|
||||
ushort jumpAddress = ReadShortFromInstruction();
|
||||
if (registers.Flags.Carry)
|
||||
{
|
||||
PushShort(registers.PC);
|
||||
Jump(jumpAddress);
|
||||
return 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
},
|
||||
// 0xDD
|
||||
(op) => {
|
||||
@@ -1323,25 +1384,31 @@ namespace MCEmuCore.GBMonolith
|
||||
},
|
||||
// 0xDE
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xDE");
|
||||
registers.A = SubtractRegisters(registers.A, ReadInstruction(), true);
|
||||
return 8;
|
||||
},
|
||||
// 0xDF
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xDF");
|
||||
PushShort(registers.PC);
|
||||
Jump(0x0018);
|
||||
return 16;
|
||||
},
|
||||
#endregion
|
||||
#region OpCodes 0xE0-0xEF
|
||||
// 0xE0
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xE0");
|
||||
memory.WriteByte(0xFF00 + ReadInstruction(), registers.A);
|
||||
return 12;
|
||||
},
|
||||
// 0xE1
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xE1");
|
||||
registers.HL = PopShort();
|
||||
return 12;
|
||||
},
|
||||
// 0xE2
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xE2");
|
||||
memory.WriteByte(0xFF00 + registers.C, registers.A);
|
||||
return 8;
|
||||
},
|
||||
// 0xE3
|
||||
(op) => {
|
||||
@@ -1353,27 +1420,35 @@ namespace MCEmuCore.GBMonolith
|
||||
},
|
||||
// 0xE5
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xE5");
|
||||
PushShort(registers.HL);
|
||||
return 16;
|
||||
},
|
||||
// 0xE6
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xE6");
|
||||
registers.A = AndRegisters(registers.A, ReadInstruction());
|
||||
return 8;
|
||||
},
|
||||
// 0xE7
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xE7");
|
||||
PushShort(registers.PC);
|
||||
Jump(0x0020);
|
||||
return 16;
|
||||
},
|
||||
// 0xE8
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xE8");
|
||||
registers.SP = AddWideRegisters(registers.SP, ReadInstruction());
|
||||
registers.Flags.Zero = false;
|
||||
return 16;
|
||||
},
|
||||
// 0xE9
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xE9");
|
||||
Jump(registers.HL);
|
||||
return 4;
|
||||
},
|
||||
// 0xEA
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xEA");
|
||||
memory.WriteByte(ReadShortFromInstruction(), registers.A);
|
||||
return 16;
|
||||
},
|
||||
// 0xEB
|
||||
(op) => {
|
||||
@@ -1389,61 +1464,78 @@ namespace MCEmuCore.GBMonolith
|
||||
},
|
||||
// 0xEE
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xEE");
|
||||
registers.A = XorRegisters(registers.A, ReadInstruction());
|
||||
return 8;
|
||||
},
|
||||
// 0xEF
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xEF");
|
||||
PushShort(registers.PC);
|
||||
Jump(0x0028);
|
||||
return 16;
|
||||
},
|
||||
#endregion
|
||||
#region OpCodes 0xF0-0xFF
|
||||
// 0xF0
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xF0");
|
||||
registers.A = memory.ReadByte(0xFF + ReadInstruction());
|
||||
return 12;
|
||||
},
|
||||
// 0xF1
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xF1");
|
||||
registers.AF = PopShort();
|
||||
return 12;
|
||||
},
|
||||
// 0xF2
|
||||
(op) => {
|
||||
registers.A = memory.ReadByte(0xFF + registers.C);
|
||||
return 8;
|
||||
throw new NotImplementedException("0xF2");
|
||||
},
|
||||
// 0xF3
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xF3");
|
||||
interruptsEnabled = false;
|
||||
return 4;
|
||||
},
|
||||
// 0xF4
|
||||
(op) => {
|
||||
throw new IllegalInstructionException(op, "Instruction does not exist");
|
||||
throw new IllegalInstructionException(op, "Instruction does not exist: 0xF4");
|
||||
},
|
||||
// 0xF5
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xF5");
|
||||
PushShort(registers.AF);
|
||||
return 16;
|
||||
},
|
||||
// 0xF6
|
||||
(op) => {
|
||||
registers.A = OrRegisters(registers.A, ReadInstruction());
|
||||
throw new NotImplementedException("0xF6");
|
||||
},
|
||||
// 0xF7
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xF7");
|
||||
PushShort(registers.PC);
|
||||
Jump(0x0030);
|
||||
return 16;
|
||||
},
|
||||
// 0xF8
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xF8");
|
||||
registers.HL = AddWideRegisters(registers.SP, ReadInstruction());
|
||||
registers.Flags.Zero = false;
|
||||
return 12;
|
||||
},
|
||||
// 0xF9
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xF9");
|
||||
registers.SP = registers.HL;
|
||||
return 4;
|
||||
},
|
||||
// 0xFA
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xFA");
|
||||
registers.A = memory.ReadByte(ReadShortFromInstruction());
|
||||
return 16;
|
||||
},
|
||||
// 0xFB
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xFB");
|
||||
interruptsEnabled = true;
|
||||
return 4;
|
||||
},
|
||||
// 0xFC
|
||||
(op) => {
|
||||
@@ -1455,11 +1547,14 @@ namespace MCEmuCore.GBMonolith
|
||||
},
|
||||
// 0xFE
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xFE");
|
||||
SubtractRegisters(registers.A, ReadInstruction());
|
||||
return 8;
|
||||
},
|
||||
// 0xFF
|
||||
(op) => {
|
||||
throw new NotImplementedException("0xFF");
|
||||
PushShort(registers.PC);
|
||||
Jump(0x0038);
|
||||
return 16;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
@@ -1549,6 +1644,42 @@ namespace MCEmuCore.GBMonolith
|
||||
return reg;
|
||||
}
|
||||
|
||||
private byte AndRegisters(byte register1, byte register2)
|
||||
{
|
||||
byte val = (byte)(register1 & register2);
|
||||
|
||||
registers.Flags.Carry = false;
|
||||
registers.Flags.HalfCarry = true;
|
||||
registers.Flags.N_Subtract = false;
|
||||
registers.Flags.Zero = val == 0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private byte OrRegisters(byte register1, byte register2)
|
||||
{
|
||||
byte val = (byte)(register1 | register2);
|
||||
|
||||
registers.Flags.Carry = false;
|
||||
registers.Flags.HalfCarry = false;
|
||||
registers.Flags.N_Subtract = false;
|
||||
registers.Flags.Zero = val == 0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private byte XorRegisters(byte register1, byte register2)
|
||||
{
|
||||
byte val = (byte)(register1 ^ register2);
|
||||
|
||||
registers.Flags.Carry = false;
|
||||
registers.Flags.HalfCarry = false;
|
||||
registers.Flags.N_Subtract = false;
|
||||
registers.Flags.Zero = val == 0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private ushort AddWideRegisters(ushort wideRegister1, ushort wideRegister2)
|
||||
{
|
||||
// ADD HL, BC
|
||||
|
||||
Reference in New Issue
Block a user