Implemented many more OpCodes - again!
This commit is contained in:
124
Core/Cpu/Z80.cs
124
Core/Cpu/Z80.cs
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user