using System; using System.Globalization; using System.IO; // This Z80-Gameboy emulator is a modified version of Ben Ryves 'Brazil' emulator. // It is MIT licensed (not public domain). (See Licenses) namespace BizHawk.Emulation.CPUs.Z80GB { public sealed partial class Z80 { private static bool logging = false; private static StreamWriter log; static Z80() { if (logging) log = new StreamWriter("log_Z80.txt"); } public Z80() { InitializeTables(); Reset(); } public void Reset() { ResetRegisters(); ResetInterrupts(); PendingCycles = 0; TotalExecutedCycles = 0; } // Memory Access public Func ReadMemory; public Action WriteMemory; public void UnregisterMemoryMapper() { ReadMemory = null; WriteMemory = null; } // State Save/Load public void SaveStateText(TextWriter writer) { writer.WriteLine("[Z80]"); writer.WriteLine("AF {0:X4}", RegAF.Word); writer.WriteLine("BC {0:X4}", RegBC.Word); writer.WriteLine("DE {0:X4}", RegDE.Word); writer.WriteLine("HL {0:X4}", RegHL.Word); writer.WriteLine("I {0:X2}", RegI); writer.WriteLine("SP {0:X4}", RegSP.Word); writer.WriteLine("PC {0:X4}", RegPC.Word); writer.WriteLine("IRQ {0}", interrupt); writer.WriteLine("NMI {0}", nonMaskableInterrupt); writer.WriteLine("NMIPending {0}", nonMaskableInterruptPending); writer.WriteLine("IM {0}", InterruptMode); writer.WriteLine("IFF1 {0}", IFF1); writer.WriteLine("IFF2 {0}", IFF2); writer.WriteLine("Halted {0}", Halted); writer.WriteLine("ExecutedCycles {0}", TotalExecutedCycles); writer.WriteLine("PendingCycles {0}", PendingCycles); writer.WriteLine("[/Z80]"); writer.WriteLine(); } public void LoadStateText(TextReader reader) { while (true) { string[] args = reader.ReadLine().Split(' '); if (args[0].Trim() == "") continue; if (args[0] == "[/Z80]") break; if (args[0] == "AF") RegAF.Word = ushort.Parse(args[1], NumberStyles.HexNumber); else if (args[0] == "BC") RegBC.Word = ushort.Parse(args[1], NumberStyles.HexNumber); else if (args[0] == "DE") RegDE.Word = ushort.Parse(args[1], NumberStyles.HexNumber); else if (args[0] == "HL") RegHL.Word = ushort.Parse(args[1], NumberStyles.HexNumber); else if (args[0] == "I") RegI = byte.Parse(args[1], NumberStyles.HexNumber); else if (args[0] == "SP") RegSP.Word = ushort.Parse(args[1], NumberStyles.HexNumber); else if (args[0] == "PC") RegPC.Word = ushort.Parse(args[1], NumberStyles.HexNumber); else if (args[0] == "IRQ") interrupt = bool.Parse(args[1]); else if (args[0] == "NMI") nonMaskableInterrupt = bool.Parse(args[1]); else if (args[0] == "NMIPending") nonMaskableInterruptPending = bool.Parse(args[1]); else if (args[0] == "IM") InterruptMode = int.Parse(args[1]); else if (args[0] == "IFF1") IFF1 = bool.Parse(args[1]); else if (args[0] == "IFF2") IFF2 = bool.Parse(args[1]); else if (args[0] == "Halted") Halted = bool.Parse(args[1]); else if (args[0] == "ExecutedCycles") TotalExecutedCycles = int.Parse(args[1]); else if (args[0] == "PendingCycles") PendingCycles = int.Parse(args[1]); else Console.WriteLine("Skipping unrecognized identifier " + args[0]); } } public void SaveStateBinary(BinaryWriter writer) { writer.Write(RegAF.Word); writer.Write(RegBC.Word); writer.Write(RegDE.Word); writer.Write(RegHL.Word); writer.Write(RegI); writer.Write(RegSP.Word); writer.Write(RegPC.Word); writer.Write(interrupt); writer.Write(nonMaskableInterrupt); writer.Write(nonMaskableInterruptPending); writer.Write(InterruptMode); writer.Write(IFF1); writer.Write(IFF2); writer.Write(Halted); writer.Write(TotalExecutedCycles); writer.Write(PendingCycles); } public void LoadStateBinary(BinaryReader reader) { RegAF.Word = reader.ReadUInt16(); RegBC.Word = reader.ReadUInt16(); RegDE.Word = reader.ReadUInt16(); RegHL.Word = reader.ReadUInt16(); RegI = reader.ReadByte(); RegSP.Word = reader.ReadUInt16(); RegPC.Word = reader.ReadUInt16(); interrupt = reader.ReadBoolean(); nonMaskableInterrupt = reader.ReadBoolean(); nonMaskableInterruptPending = reader.ReadBoolean(); InterruptMode = reader.ReadInt32(); IFF1 = reader.ReadBoolean(); IFF2 = reader.ReadBoolean(); Halted = reader.ReadBoolean(); TotalExecutedCycles = reader.ReadInt32(); PendingCycles = reader.ReadInt32(); } public void LogData() { if (!logging) return; log.WriteLine("AF {0:X4}", RegAF.Word); log.WriteLine("BC {0:X4}", RegBC.Word); log.WriteLine("DE {0:X4}", RegDE.Word); log.WriteLine("HL {0:X4}", RegHL.Word); log.WriteLine("SP {0:X4}", RegSP.Word); log.WriteLine("PC {0:X4}", RegPC.Word); log.WriteLine("------"); log.WriteLine(); log.Flush(); } } }