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."); } } } }