Implemented many more OpCodes - 11_04_2026__02_23

This commit is contained in:
2026-04-11 02:23:38 +01:00
parent 0ef8b9f3eb
commit d953eb4ec7
2 changed files with 160 additions and 13 deletions

View File

@@ -8,6 +8,8 @@ namespace Core.Cpu
//T-State counter
public long TotalTStates { get; set; }
public int InterruptMode { get; private set; } = 0; // Defaults to 0 on power-up
// Interrupt Flip-Flops
public bool IFF1;
public bool IFF2;
@@ -191,6 +193,36 @@ namespace Core.Cpu
return result;
}
private byte Inc8(byte value)
{
byte result = (byte)(value + 1);
// Store the existing Carry flag so we can preserve it
byte carry = (byte)(AF.Low & 0x01);
// Clear all flags
AF.Low = 0;
// Sign Flag (Bit 7)
if ((result & 0x80) != 0) AF.Low |= 0x80;
// Zero Flag (Bit 6)
if (result == 0) AF.Low |= 0x40;
// Half-Carry Flag (Bit 4) - Set if carry from bit 3 (happens if lower nibble was 0x0F)
if ((value & 0x0F) == 0x0F) AF.Low |= 0x10;
// Parity/Overflow Flag (Bit 2) - Set if the original value was 0x7F (maximum positive)
if (value == 0x7F) AF.Low |= 0x04;
// Subtract Flag (Bit 1) - ALWAYS 0 for increments (already 0 because we cleared AF.Low)
// Restore the original Carry Flag (Bit 0)
AF.Low |= carry;
return result;
}
private void Cp(byte value)
{
byte a = AF.High;
@@ -247,10 +279,6 @@ namespace Core.Cpu
// Update the HL register
HL.Word = (ushort)result;
// --- Update Flags (F Register) ---
// 16-bit ADD preserves S, Z, P/V (and the undocumented X/Y flags).
// We clear H (Bit 4), N (Bit 1), and C (Bit 0) using a bitwise AND mask (0xEC = 1110 1100)
AF.Low &= 0xEC;
// Half-Carry Flag (Bit 4) - Set if there is a carry from bit 11
@@ -277,6 +305,12 @@ namespace Core.Cpu
{
case 0x00: // NOP
return 4;
case 0x01: // LD BC, nn
BC.Word = FetchWord();
return 10; // Takes 10 T-States
case 0x04: // INC B
BC.High = Inc8(BC.High);
return 4;
case 0x11: //LD DE, nn
DE.Word = FetchWord();
return 10;
@@ -291,6 +325,14 @@ namespace Core.Cpu
return 12;
}
return 7;
case 0x21: // LD HL, nn
HL.Word = FetchWord();
return 10;
case 0x22: // LD (nn), HL
ushort dest22 = FetchWord();
_memory.Write(dest22, HL.Low);
_memory.Write((ushort)(dest22 + 1), HL.High);
return 16;
case 0x23: // INC HL
HL.Word++;
return 6;
@@ -304,6 +346,13 @@ namespace Core.Cpu
return 12; // Jump taken
}
return 7; // Jump not taken
case 0x2A: // LD HL, (nn)
{
ushort srcAddress = FetchWord();
HL.Low = _memory.Read(srcAddress);
HL.High = _memory.Read((ushort)(srcAddress + 1));
return 16; // Takes 16 T-States
}
case 0x2B: // DEC HL
HL.Word--;
return 6;
@@ -334,10 +383,11 @@ namespace Core.Cpu
return 10;
case 0x3E: //LD A, n
AF.High = FetchByte();
return 7;
return 7;
case 0x47: // LD B, A
BC.High = AF.High;
return 4;
case 0x62: // LD H, D
HL.High = DE.High;
return 4;
@@ -347,6 +397,10 @@ namespace Core.Cpu
case 0xA7: // AND A
And(AF.High);
return 4;
case 0xAF: // XOR A
AF.High = 0;
AF.Low = 0x44;
return 4;
case 0xBC: // CP H
Cp(HL.High);
return 4;
@@ -379,17 +433,20 @@ namespace Core.Cpu
case 0xDE: // SBC A, n
Sbc(FetchByte());
return 7;
case 0xEB: // EX DE, HL
ushort tempEx = DE.Word;
DE.Word = HL.Word;
HL.Word = tempEx;
return 4; // Takes 4 T-States
case 0xED:
return ExecuteExtendedPrefix();
case 0xF3: // DI (Disable Interrupts)
IFF1 = false;
IFF2 = false;
return 4;
case 0xAF: // XOR A
AF.High = 0;
AF.Low = 0x44;
return 4;
case 0xF9: // LD SP, HL
SP = HL.Word; // (Use SP.Word = HL.Word if you made SP a RegisterPair)
return 6;
default:
throw new NotImplementedException($"Opcode 0x{opcode:X2} at PC 0x{(PC - 1):X4} is not implemented.");
}
@@ -401,12 +458,53 @@ namespace Core.Cpu
switch (extendedOpcode)
{
case 0x43: // LD (nn), BC
ushort dest43 = FetchWord();
_memory.Write(dest43, BC.Low);
_memory.Write((ushort)(dest43 + 1), BC.High);
return 20;
case 0x47: // LD I, A
I = AF.High;
return 9;
case 0x52: // SBC HL, DE
Sbc16(DE.Word);
return 15; // Takes 15 T-States
return 15;
case 0x53: // LD (nn), DE
ushort dest53 = FetchWord();
_memory.Write(dest53, DE.Low);
_memory.Write((ushort)(dest53 + 1), DE.High);
return 20;
case 0x56: // IM 1
InterruptMode = 1;
return 8; // Takes 8 T-States
case 0xB8: // LDDR
// 1. Read byte from (HL)
byte val = _memory.Read(HL.Word);
// 2. Write byte to (DE)
_memory.Write(DE.Word, val);
// 3. Decrement all three pointers
HL.Word--;
DE.Word--;
BC.Word--;
// 4. Update Flags
// Preserve S (0x80), Z (0x40), and C (0x01).
// H (0x10) and N (0x02) are always reset to 0.
AF.Low &= 0xC1;
// P/V Flag (Bit 2) is set to 1 if BC is not 0
if (BC.Word != 0)
{
AF.Low |= 0x04;
// Rewind the PC so the CPU executes this instruction again!
PC -= 2;
return 21; // Looping
}
return 16; // Finished!
default:
throw new NotImplementedException($"Extended ED Opcode 0x{extendedOpcode:X2} at PC 0x{(PC - 1):X4} is not implemented.");
}