Implemented many more OpCodes
This commit is contained in:
@@ -50,13 +50,33 @@ namespace Core.Cpu
|
||||
public void Reset()
|
||||
{
|
||||
PC = 0x0000;
|
||||
// The Z80 initializes SP to 0xFFFF on boot
|
||||
SP = 0xFFFF;
|
||||
SP = 0xFFFF; // The Z80 initializes SP to 0xFFFF on boot
|
||||
|
||||
// Main Registers
|
||||
AF.Word = 0;
|
||||
BC.Word = 0;
|
||||
DE.Word = 0;
|
||||
HL.Word = 0;
|
||||
|
||||
// Alternate Registers
|
||||
AF_Prime.Word = 0;
|
||||
BC_Prime.Word = 0;
|
||||
DE_Prime.Word = 0;
|
||||
HL_Prime.Word = 0;
|
||||
|
||||
// Index Registers
|
||||
IX.Word = 0;
|
||||
IY.Word = 0;
|
||||
|
||||
// Internal Registers
|
||||
I = 0;
|
||||
R = 0;
|
||||
|
||||
// Hardware State
|
||||
IFF1 = false;
|
||||
IFF2 = false;
|
||||
InterruptMode = 0;
|
||||
TotalTStates = 0; // Reset the system clock!
|
||||
}
|
||||
|
||||
public int Step()
|
||||
@@ -96,6 +116,36 @@ namespace Core.Cpu
|
||||
$"C:{f & 1}";
|
||||
}
|
||||
|
||||
private void Sub(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
|
||||
|
||||
// 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 borrow from bit 4
|
||||
if (((a & 0x0F) - (value & 0x0F)) < 0) AF.Low |= 0x10;
|
||||
|
||||
// Overflow Flag (Bit 2) - Set if operands have different signs and result sign changes
|
||||
if ((((a ^ value) & 0x80) != 0) && (((a ^ result) & 0x80) != 0)) AF.Low |= 0x04;
|
||||
|
||||
// Subtract Flag (Bit 1) - ALWAYS set for CP/SUB
|
||||
AF.Low |= 0x02;
|
||||
|
||||
// Carry Flag (Bit 0) - Set if the overall result dropped below 0
|
||||
if (result < 0) AF.Low |= 0x01;
|
||||
}
|
||||
|
||||
private void Sbc(byte value)
|
||||
{
|
||||
byte a = AF.High;
|
||||
@@ -309,6 +359,17 @@ namespace Core.Cpu
|
||||
_memory.Write(SP, (byte)(value & 0xFF));
|
||||
}
|
||||
|
||||
private ushort Pop()
|
||||
{
|
||||
// The Z80 is Little-Endian. Low byte comes off the stack first.
|
||||
byte low = _memory.Read(SP++);
|
||||
|
||||
// High byte comes off second.
|
||||
byte high = _memory.Read(SP++);
|
||||
|
||||
return (ushort)((high << 8) | low);
|
||||
}
|
||||
|
||||
private int ExecuteOpcode(byte opcode)
|
||||
{
|
||||
sbyte offset = 0;
|
||||
@@ -340,6 +401,9 @@ namespace Core.Cpu
|
||||
case 0x11: //LD DE, nn
|
||||
DE.Word = FetchWord();
|
||||
return 10;
|
||||
case 0x16: // LD D, n
|
||||
DE.High = FetchByte();
|
||||
return 7;
|
||||
case 0x19: // ADD HL, DE
|
||||
Add16(DE.Word);
|
||||
return 11;
|
||||
@@ -429,9 +493,15 @@ namespace Core.Cpu
|
||||
case 0x77: // LD (HL), A
|
||||
_memory.Write(HL.Word, AF.High);
|
||||
return 7;
|
||||
case 0x91: // SUB C
|
||||
Sub(BC.Low);
|
||||
return 4; // Takes 4 T-States
|
||||
case 0xA7: // AND A
|
||||
And(AF.High);
|
||||
return 4;
|
||||
case 0x5F: // LD E, A
|
||||
DE.Low = AF.High;
|
||||
return 4;
|
||||
case 0xAF: // XOR A
|
||||
AF.High = 0;
|
||||
AF.Low = 0x44;
|
||||
@@ -442,6 +512,9 @@ namespace Core.Cpu
|
||||
case 0xC3:
|
||||
PC = FetchWord();
|
||||
return 10;
|
||||
case 0xC9: // RET
|
||||
PC = Pop();
|
||||
return 10;
|
||||
case 0xCD: // CALL nn
|
||||
ushort callAddress = FetchWord();
|
||||
Push(PC);
|
||||
@@ -604,6 +677,24 @@ namespace Core.Cpu
|
||||
byte decVal = Dec8(memVal);
|
||||
_memory.Write(targetAddress, decVal);
|
||||
return 23;
|
||||
case 0x36: // LD (IY+d), n
|
||||
{
|
||||
sbyte offset36 = (sbyte)FetchByte();
|
||||
byte nValue = FetchByte();
|
||||
targetAddress = (ushort)(IY.Word + offset36);
|
||||
|
||||
_memory.Write(targetAddress, nValue);
|
||||
return 19; // Takes 19 T-States
|
||||
}
|
||||
case 0x71: // LD (IY+d), C
|
||||
{
|
||||
sbyte offset71 = (sbyte)FetchByte();
|
||||
targetAddress = (ushort)(IY.Word + offset71);
|
||||
|
||||
// Write the C register (low byte of BC) to memory
|
||||
_memory.Write(targetAddress, BC.Low);
|
||||
return 19; // Takes 19 T-States
|
||||
}
|
||||
case 0x75: // LD (IY+d), L
|
||||
sbyte offset75 = (sbyte)FetchByte();
|
||||
targetAddress = (ushort)(IY.Word + offset75);
|
||||
|
||||
@@ -42,5 +42,10 @@ namespace Core.Memory
|
||||
// Copy the ROM
|
||||
Array.Copy(romData, 0, _memory, 0, romData.Length);
|
||||
}
|
||||
|
||||
public void ClearRam()
|
||||
{
|
||||
//To Do
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user