Files
ZXSpectrum48K/Core/Cpu/Z80.cs
2026-04-08 22:36:26 +01:00

92 lines
2.4 KiB
C#

using System;
using Core.Interfaces;
namespace Core.Cpu
{
public partial class Z80
{
//T-State counter
public long TotalTStates { get; set; }
// Main Register Set
public RegisterPair AF;
public RegisterPair BC;
public RegisterPair DE;
public RegisterPair HL;
// Alternate Register Set
public RegisterPair AF_Prime;
public RegisterPair BC_Prime;
public RegisterPair DE_Prime;
public RegisterPair HL_Prime;
// Index Registers
public RegisterPair IX;
public RegisterPair IY;
// Special Purpose Registers
public ushort PC; // Program Counter
public ushort SP; // Stack Pointer
public byte I; // Interrupt Vector
public byte R; // Memory Refresh
// The Memory Bus
private readonly IMemory _memory;
public Z80(IMemory memory)
{
_memory = memory;
Reset();
}
public void Reset()
{
PC = 0x0000;
// The Z80 initializes SP to 0xFFFF on boot
SP = 0xFFFF;
AF.Word = 0;
BC.Word = 0;
DE.Word = 0;
HL.Word = 0;
}
public int Step()
{
// Fetch the next opcode and increment the Program Counter
byte opcode = _memory.Read(PC++);
int tStates = ExecuteOpcode(opcode);
TotalTStates += tStates;
// Decode and execute
return tStates;
}
public string GetFlagsString()
{
byte f = AF.Low;
return $"S:{(f >> 7) & 1} " +
$"Z:{(f >> 6) & 1} " +
$"Y:{(f >> 5) & 1} " + // Undocumented flag
$"H:{(f >> 4) & 1} " +
$"X:{(f >> 3) & 1} " + // Undocumented flag
$"P/V:{(f >> 2) & 1} " +
$"N:{(f >> 1) & 1} " +
$"C:{f & 1}";
}
private int ExecuteOpcode(byte opcode)
{
switch (opcode)
{
case 0x00: // NOP (No Operation)
return 4; // Takes 4 T-states
// We will expand this massive list soon!
default:
throw new NotImplementedException($"Opcode 0x{opcode:X2} at PC 0x{(PC - 1):X4} is not implemented.");
}
}
}
}