Implemented a shit load of OpCodes

This commit is contained in:
2026-04-15 00:27:15 +01:00
parent 695db41f60
commit 7e7453691f
2 changed files with 388 additions and 135 deletions

View File

@@ -401,6 +401,34 @@ namespace Core.Cpu
if (result > 0xFF) AF.Low |= 0x01;
}
private void AddA(byte operand)
{
byte a = AF.High;
int result = a + operand;
AF.High = (byte)result;
// --- Update Flags ---
AF.Low = 0; // Clear all flags initially (Forces N to 0)
// Sign Flag (Bit 7)
if ((AF.High & 0x80) != 0) AF.Low |= 0x80;
// Zero Flag (Bit 6)
if (AF.High == 0) AF.Low |= 0x40;
// Half-Carry Flag (Bit 4) - Check if bits 0-3 overflowed
if (((a & 0x0F) + (operand & 0x0F)) > 0x0F) AF.Low |= 0x10;
// Parity/Overflow Flag (Bit 2)
bool sameSign = ((a ^ operand) & 0x80) == 0; // Did inputs have the same sign?
bool changedSign = ((a ^ AF.High) & 0x80) != 0; // Did the result's sign flip?
if (sameSign && changedSign) AF.Low |= 0x04;
// Carry Flag (Bit 0) - Check if the whole 8-bit addition overflowed
if (result > 0xFF) AF.Low |= 0x01;
}
private bool HasEvenParity(byte value)
{
int bits = 0;
@@ -443,9 +471,15 @@ namespace Core.Cpu
case 0x01: // LD BC, nn
BC.Word = FetchWord();
return 10; // Takes 10 T-States
case 0x03: // INC BC
BC.Word++;
return 6;
case 0x04: // INC B
BC.High = Inc8(BC.High);
return 4;
case 0x0B: // DEC BC
BC.Word--;
return 6;
case 0x0E: // LD C, n
BC.Low = FetchByte();
return 7; // Takes 7 T-States
@@ -464,6 +498,9 @@ namespace Core.Cpu
case 0x11: //LD DE, nn
DE.Word = FetchWord();
return 10;
case 0x13: // INC DE
DE.Word++;
return 6;
case 0x16: // LD D, n
DE.High = FetchByte();
return 7;
@@ -539,6 +576,9 @@ namespace Core.Cpu
_memory.Write(destAddress, AF.High);
return 13;
}
case 0x33: // INC SP
SP++;
return 6;
case 0x35: // DEC (HL)
// Read the current byte from memory
byte memValue = _memory.Read(HL.Word);
@@ -567,6 +607,9 @@ namespace Core.Cpu
return 12;
}
return 7;
case 0x3B: // DEC SP
SP--;
return 6;
case 0x3E: //LD A, n
AF.High = FetchByte();
return 7;
@@ -580,76 +623,144 @@ namespace Core.Cpu
else
AF.Low &= 0xEF;
return 4;
case 0x47: // LD B, A
BC.High = AF.High;
return 4;
case 0x4E: // LD C, (HL)
BC.Low = _memory.Read(HL.Word);
return 7;
case 0x56: // LD D, (HL)
DE.High = _memory.Read(HL.Word);
return 7; // Takes 7 T-States
case 0x5E: // LD E, (HL)
DE.Low = _memory.Read(HL.Word);
return 7; // Takes 7 T-States
case 0x62: // LD H, D
HL.High = DE.High;
return 4;
case 0x67: // LD H, A
HL.High = AF.High;
return 4;
case 0x6B: // LD L, E
HL.Low = DE.Low;
return 4;
case 0x72: // LD (HL), D
_memory.Write(HL.Word, DE.High);
return 7;
case 0x73: // LD (HL), E
_memory.Write(HL.Word, DE.Low);
return 7;
case 0x77: // LD (HL), A
_memory.Write(HL.Word, AF.High);
return 7;
case 0x7A: // LD A, D
AF.High = DE.High;
return 4;
case 0x7E: // LD A, (HL)
AF.High = _memory.Read(HL.Word);
return 7; // Takes 7 T-States
case 0x87: // ADD A, A
Add(AF.High);
return 4;
case 0x91: // SUB C
Sub(BC.Low);
return 4;
case 0xA7: // AND A
And(AF.High);
return 4;
case 0x5F: // LD E, A
DE.Low = AF.High;
return 4;
case 0x6F: // LD L, A
HL.Low = AF.High;
return 4;
case 0xAE: // XOR (HL)
Xor(_memory.Read(HL.Word));
return 7;
case 0xAF: // XOR A
AF.High = 0;
AF.Low = 0x44;
return 4;
case 0xB3: // OR E
Or(DE.Low);
return 4;
case 0xB9: // CP C
Cp(BC.Low);
return 4; // Takes 4 T-States
case 0xBC: // CP H
Cp(HL.High);
return 4;
case 0x40: BC.High = BC.High; return 4;
case 0x41: BC.High = BC.Low; return 4;
case 0x42: BC.High = DE.High; return 4;
case 0x43: BC.High = DE.Low; return 4;
case 0x44: BC.High = HL.High; return 4;
case 0x45: BC.High = HL.Low; return 4;
case 0x46: BC.High = _memory.Read(HL.Word); return 7;
case 0x47: BC.High = AF.High; return 4;
// --- LD C, r ---
case 0x48: BC.Low = BC.High; return 4;
case 0x49: BC.Low = BC.Low; return 4;
case 0x4A: BC.Low = DE.High; return 4;
case 0x4B: BC.Low = DE.Low; return 4;
case 0x4C: BC.Low = HL.High; return 4;
case 0x4D: BC.Low = HL.Low; return 4;
case 0x4E: BC.Low = _memory.Read(HL.Word); return 7;
case 0x4F: BC.Low = AF.High; return 4;
// --- LD D, r ---
case 0x50: DE.High = BC.High; return 4;
case 0x51: DE.High = BC.Low; return 4;
case 0x52: DE.High = DE.High; return 4;
case 0x53: DE.High = DE.Low; return 4;
case 0x54: DE.High = HL.High; return 4;
case 0x55: DE.High = HL.Low; return 4;
case 0x56: DE.High = _memory.Read(HL.Word); return 7;
case 0x57: DE.High = AF.High; return 4;
// --- LD E, r ---
case 0x58: DE.Low = BC.High; return 4;
case 0x59: DE.Low = BC.Low; return 4;
case 0x5A: DE.Low = DE.High; return 4;
case 0x5B: DE.Low = DE.Low; return 4;
case 0x5C: DE.Low = HL.High; return 4;
case 0x5D: DE.Low = HL.Low; return 4;
case 0x5E: DE.Low = _memory.Read(HL.Word); return 7;
case 0x5F: DE.Low = AF.High; return 4;
// --- LD H, r ---
case 0x60: HL.High = BC.High; return 4;
case 0x61: HL.High = BC.Low; return 4;
case 0x62: HL.High = DE.High; return 4;
case 0x63: HL.High = DE.Low; return 4;
case 0x64: HL.High = HL.High; return 4;
case 0x65: HL.High = HL.Low; return 4;
case 0x66: HL.High = _memory.Read(HL.Word); return 7;
case 0x67: HL.High = AF.High; return 4;
// --- LD L, r ---
case 0x68: HL.Low = BC.High; return 4;
case 0x69: HL.Low = BC.Low; return 4;
case 0x6A: HL.Low = DE.High; return 4;
case 0x6B: HL.Low = DE.Low; return 4;
case 0x6C: HL.Low = HL.High; return 4;
case 0x6D: HL.Low = HL.Low; return 4;
case 0x6E: HL.Low = _memory.Read(HL.Word); return 7;
case 0x6F: HL.Low = AF.High; return 4;
// --- LD (HL), r --- (Note: 0x76 is HALT, so it is skipped here)
case 0x70: _memory.Write(HL.Word, BC.High); return 7;
case 0x71: _memory.Write(HL.Word, BC.Low); return 7;
case 0x72: _memory.Write(HL.Word, DE.High); return 7;
case 0x73: _memory.Write(HL.Word, DE.Low); return 7;
case 0x74: _memory.Write(HL.Word, HL.High); return 7;
case 0x75: _memory.Write(HL.Word, HL.Low); return 7;
case 0x77: _memory.Write(HL.Word, AF.High); return 7;
// --- LD A, r ---
case 0x78: AF.High = BC.High; return 4;
case 0x79: AF.High = BC.Low; return 4;
case 0x7A: AF.High = DE.High; return 4;
case 0x7B: AF.High = DE.Low; return 4;
case 0x7C: AF.High = HL.High; return 4;
case 0x7D: AF.High = HL.Low; return 4;
case 0x7E: AF.High = _memory.Read(HL.Word); return 7;
case 0x7F: AF.High = AF.High; return 4;
case 0x80: Add(BC.High); return 4; // ADD A, B
case 0x81: Add(BC.Low); return 4; // ADD A, C
case 0x82: Add(DE.High); return 4; // ADD A, D
case 0x83: Add(DE.Low); return 4; // ADD A, E
case 0x84: Add(HL.High); return 4; // ADD A, H
case 0x85: Add(HL.Low); return 4; // ADD A, L
case 0x86: Add(_memory.Read(HL.Word)); return 7; // ADD A, (HL)
case 0x87: Add(AF.High); return 4; // ADD A, A
case 0x90: Sub(BC.High); return 4; // SUB B
case 0x91: Sub(BC.Low); return 4; // SUB C
case 0x92: Sub(DE.High); return 4; // SUB D
case 0x93: Sub(DE.Low); return 4; // SUB E
case 0x94: Sub(HL.High); return 4; // SUB H
case 0x95: Sub(HL.Low); return 4; // SUB L
case 0x96: Sub(_memory.Read(HL.Word)); return 7; // SUB (HL)
case 0x97: Sub(AF.High); return 4; // SUB A
case 0xA0: And(BC.High); return 4; // AND B
case 0xA1: And(BC.Low); return 4; // AND C
case 0xA2: And(DE.High); return 4; // AND D
case 0xA3: And(DE.Low); return 4; // AND E
case 0xA4: And(HL.High); return 4; // AND H
case 0xA5: And(HL.Low); return 4; // AND L
case 0xA6: And(_memory.Read(HL.Word)); return 7; // AND (HL)
case 0xA7: And(AF.High); return 4; // AND A
case 0xA8: Xor(BC.High); return 4; // XOR B
case 0xA9: Xor(BC.Low); return 4; // XOR C
case 0xAA: Xor(DE.High); return 4; // XOR D
case 0xAB: Xor(DE.Low); return 4; // XOR E
case 0xAC: Xor(HL.High); return 4; // XOR H
case 0xAD: Xor(HL.Low); return 4; // XOR L
case 0xAE: Xor(_memory.Read(HL.Word)); return 7; // XOR (HL)
case 0xAF: Xor(AF.High); return 4; // XOR A
// --- OR r ---
case 0xB0: Or(BC.High); return 4; // OR B
case 0xB1: Or(BC.Low); return 4; // OR C
case 0xB2: Or(DE.High); return 4; // OR D
case 0xB3: Or(DE.Low); return 4; // OR E
case 0xB4: Or(HL.High); return 4; // OR H
case 0xB5: Or(HL.Low); return 4; // OR L
case 0xB6: Or(_memory.Read(HL.Word)); return 7; // OR (HL)
case 0xB7: Or(AF.High); return 4; // OR A
// --- CP r ---
case 0xB8: Cp(BC.High); return 4; // CP B
case 0xB9: Cp(BC.Low); return 4; // CP C
case 0xBA: Cp(DE.High); return 4; // CP D
case 0xBB: Cp(DE.Low); return 4; // CP E
case 0xBC: Cp(HL.High); return 4; // CP H
case 0xBD: Cp(HL.Low); return 4; // CP L
case 0xBE: Cp(_memory.Read(HL.Word)); return 7; // CP (HL)
case 0xBF: Cp(AF.High); return 4; // CP A
case 0xC1: // POP BC
BC.Word = Pop();
return 10;
case 0xC3:
PC = FetchWord();
return 10;
case 0xc5: //push bc
Push(BC.Word);
return 11;
case 0xC6: // ADD A, n
Add(FetchByte());
return 7;
@@ -677,6 +788,9 @@ namespace Core.Cpu
return 11; // Condition met, took the return
}
return 5; // Condition not met, skipped
case 0xD1: // POP DE
DE.Word = Pop();
return 10;
case 0xD3: // OUT (n), A
byte portOffset = FetchByte();
@@ -685,7 +799,13 @@ namespace Core.Cpu
_ioBus.Write(portAddress, AF.High);
return 11; // Takes 11 T-States
return 11;
case 0xd5: //push bc
Push(DE.Word);
return 11;
case 0xD6: // SUB n
Sub(FetchByte());
return 7;
case 0xD9: // EXX
ushort tempBC = BC.Word;
BC.Word = BC_Prime.Word;
@@ -703,6 +823,12 @@ namespace Core.Cpu
case 0xDE: // SBC A, n
Sbc(FetchByte());
return 7;
case 0xE1: // POP HL
HL.Word = Pop();
return 10;
case 0xe5: //push bc
Push(HL.Word);
return 11;
case 0xE6: // AND n
And(FetchByte());
return 7;
@@ -716,10 +842,16 @@ namespace Core.Cpu
return 4; // Takes 4 T-States
case 0xED:
return ExecuteExtendedPrefix();
case 0xF1: // POP AF
AF.Word = Pop();
return 10;
case 0xF3: // DI (Disable Interrupts)
IFF1 = false;
IFF2 = false;
return 4;
case 0xf5: //push bc
Push(AF.Word);
return 11;
case 0xF9: // LD SP, HL
SP = HL.Word; // (Use SP.Word = HL.Word if you made SP a RegisterPair)
return 6;
@@ -869,7 +1001,17 @@ namespace Core.Cpu
targetAddress = (ushort)(IY.Word + offset75);
// Write the low byte of HL to memory
_memory.Write(targetAddress, HL.Low);
return 19;
return 19;
case 0x86: // ADD A, (IY+d)
{
sbyte displacementAdd = (sbyte)FetchByte();
ushort targetAddressAdd = (ushort)(IY.Word + displacementAdd);
byte valueToAdd = _memory.Read(targetAddressAdd);
AddA(valueToAdd);
return 19;
}
case 0xCB: // The FD CB nested prefix
{
sbyte offsetCB = (sbyte)FetchByte(); // This is the '01'