Implemented many more OpCodes - again!

This commit is contained in:
2026-04-13 22:32:05 +01:00
parent 2b40960496
commit 9496c26004
2 changed files with 180 additions and 3 deletions

View File

@@ -322,6 +322,23 @@ namespace Core.Cpu
// Subtract Flag (N) and Carry Flag (C) are ALWAYS 0
}
private void Or(byte value)
{
AF.High = (byte)(AF.High | value);
// --- Update Flags ---
AF.Low = 0; // Clear all flags (H, N, and C are always 0 for OR)
// Sign Flag (Bit 7) - Set if the highest bit is 1
if ((AF.High & 0x80) != 0) AF.Low |= 0x80;
// Zero Flag (Bit 6) - Set if the result is 0
if (AF.High == 0) AF.Low |= 0x40;
// Parity Flag (Bit 2) - Set if the result has an even number of 1 bits
if (HasEvenParity(AF.High)) AF.Low |= 0x04;
}
private void Add16(ushort value)
{
int hl = HL.Word;
@@ -338,6 +355,34 @@ namespace Core.Cpu
if (result > 0xFFFF) AF.Low |= 0x01;
}
private void Add(byte value)
{
byte a = AF.High;
int result = a + value;
// Save the result back to the Accumulator
AF.High = (byte)result;
// --- Update Flags (F Register) ---
AF.Low = 0; // Clear all flags (This also correctly resets the N flag to 0)
// Sign Flag (Bit 7)
if ((result & 0x80) != 0) AF.Low |= 0x80;
// Zero Flag (Bit 6)
if ((byte)result == 0) AF.Low |= 0x40;
// Half-Carry Flag (Bit 4) - Set if carry from bit 3
if (((a & 0x0F) + (value & 0x0F)) > 0x0F) AF.Low |= 0x10;
// Overflow/Parity Flag (Bit 2) - For addition, overflow happens if two numbers
// with the SAME sign are added and produce a result with a DIFFERENT sign.
if ((((a ^ ~value) & 0x80) != 0) && (((a ^ result) & 0x80) != 0)) AF.Low |= 0x04;
// Carry Flag (Bit 0) - Set if the result is greater than 255
if (result > 0xFF) AF.Low |= 0x01;
}
private bool HasEvenParity(byte value)
{
int bits = 0;
@@ -406,7 +451,10 @@ namespace Core.Cpu
return 7;
case 0x19: // ADD HL, DE
Add16(DE.Word);
return 11;
return 11;
case 0x1B: // DEC DE
DE.Word--;
return 6;
case 0x20: // JR NZ, e
offset = (sbyte)FetchByte();
if ((AF.Low & 0x40) == 0)
@@ -426,6 +474,9 @@ namespace Core.Cpu
case 0x23: // INC HL
HL.Word++;
return 6;
case 0x26: // LD H, n
HL.High = FetchByte();
return 7;
case 0x28: // JR Z, e
offset = (sbyte)FetchByte();
@@ -477,13 +528,25 @@ namespace Core.Cpu
byte nValue = FetchByte();
_memory.Write(HL.Word, nValue);
return 10;
case 0x37: // SCF
AF.Low |= 0x01; // Force Carry Flag (Bit 0) to 1
AF.Low &= 0xED;
return 4; // Takes 4 T-States
case 0x3E: //LD A, n
AF.High = FetchByte();
return 7;
case 0x47: // LD B, A
BC.High = AF.High;
return 4;
case 0x4E: // LD C, (HL)
BC.Low = _memory.Read(HL.Word);
return 7; // Takes 7 T-States
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;
@@ -493,25 +556,54 @@ namespace Core.Cpu
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; // Takes 4 T-States
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 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 0xC3:
PC = FetchWord();
return 10;
case 0xC6: // ADD A, n
Add(FetchByte());
return 7;
case 0xC8: // RET Z
// Check if the Zero Flag (Bit 6) IS set
if ((AF.Low & 0x40) != 0)
{
PC = Pop();
return 11; // Condition met, took the return
}
return 5; // Condition not met, skipped
case 0xC9: // RET
PC = Pop();
return 10;
@@ -520,6 +612,14 @@ namespace Core.Cpu
Push(PC);
PC = callAddress;
return 17;
case 0xD0: // RET NC
// Check if the Carry Flag (Bit 0) is NOT set (0)
if ((AF.Low & 0x01) == 0)
{
PC = Pop();
return 11; // Condition met, took the return
}
return 5; // Condition not met, skipped
case 0xD3: // OUT (n), A
byte portOffset = FetchByte();
@@ -730,6 +830,15 @@ namespace Core.Cpu
return 20; // Takes 20 T-States
}
case 0x86: // RES 0, (IY+d)
byte memValRes0 = _memory.Read(targetAddress);
// 0xFE is Binary 1111 1110.
// ANDing preserves all bits except Bit 0, which becomes 0.
memValRes0 &= 0xFE;
_memory.Write(targetAddress, memValRes0);
return 23; // Takes 23 T-States
case 0x8E: // RES 1, (IY+d)
byte memValRes = _memory.Read(targetAddress);
@@ -738,6 +847,15 @@ namespace Core.Cpu
memValRes &= 0xFD;
_memory.Write(targetAddress, memValRes);
return 23;
case 0xA6: // RES 4, (IY+d)
byte memValRes4 = _memory.Read(targetAddress);
// 0xEF is Binary 1110 1111
// ANDing preserves all bits except Bit 4, which becomes 0.
memValRes4 &= 0xEF;
_memory.Write(targetAddress, memValRes4);
return 23;
case 0xCE: // SET 1, (IY+d)
memVal = _memory.Read(targetAddress);
memVal |= 0x02; // 0x02 is Binary 0000 0010 (Bit 1)