From 11d53755f5fcb9158f4fe3abaa3c0b480a461fe7 Mon Sep 17 00:00:00 2001 From: Ian C Date: Sat, 23 Jun 2012 22:59:38 +0000 Subject: Added classes for save/load of emulation state. Added to Z80 CPU. --- src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs | 72 +++++++++++++++++++- src/Noddybox.Emulation/EmulationStateException.cs | 61 +++++++++++++++++ .../EmulationStateLoadManager.cs | 79 ++++++++++++++++++++++ .../EmulationStateSaveManager.cs | 69 +++++++++++++++++++ src/Noddybox.Emulation/IEmulationState.cs | 45 ++++++++++++ 5 files changed, 325 insertions(+), 1 deletion(-) create mode 100644 src/Noddybox.Emulation/EmulationStateException.cs create mode 100644 src/Noddybox.Emulation/EmulationStateLoadManager.cs create mode 100644 src/Noddybox.Emulation/EmulationStateSaveManager.cs create mode 100644 src/Noddybox.Emulation/IEmulationState.cs (limited to 'src') diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs index d575476..a802142 100644 --- a/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs +++ b/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs @@ -22,13 +22,14 @@ // Any introduced bugs in that code are mine, and not the original authors. // using System; +using System.IO; namespace Noddybox.Emulation.EightBit.Z80 { /// /// Provides an implementation of a Zilog Z80 processor. /// - public partial class Z80Cpu : ICpu + public partial class Z80Cpu : ICpu, IEmulationState { #region Private types @@ -608,5 +609,74 @@ namespace Noddybox.Emulation.EightBit.Z80 } #endregion + + #region IEmulationState Members + + public int Version + { + get { return 1; } + } + + public void SaveState(EmulationStateSaveManager manager) + { + BinaryWriter str = manager.Stream; + + str.Write(A); + str.Write((int)F); + str.Write(BC.reg); + str.Write(DE.reg); + str.Write(HL.reg); + str.Write(IX.reg); + str.Write(IY.reg); + str.Write(PC); + str.Write(SP); + str.Write(AF_.reg); + str.Write(BC_.reg); + str.Write(DE_.reg); + str.Write(HL_.reg); + str.Write(I); + str.Write(R); + str.Write(IFF1); + str.Write(IFF2); + str.Write(raise); + str.Write(nmi); + str.Write(devbyte); + str.Write(IM); + str.Write(HALT); + str.Write(shift); + str.Write(executedInstructions); + } + + public void LoadState(EmulationStateLoadManager manager) + { + BinaryReader str = manager.Stream; + + A = str.ReadByte(); + F = (Z80Flags)str.ReadInt32(); + BC.reg = str.ReadUInt16(); + DE.reg = str.ReadUInt16(); + HL.reg = str.ReadUInt16(); + IX.reg = str.ReadUInt16(); + IY.reg = str.ReadUInt16(); + PC = str.ReadUInt16(); + SP = str.ReadUInt16(); + AF_.reg = str.ReadUInt16(); + BC_.reg = str.ReadUInt16(); + DE_.reg = str.ReadUInt16(); + HL_.reg = str.ReadUInt16(); + I = str.ReadByte(); + R = str.ReadByte(); + IFF1 = str.ReadBoolean(); + IFF2 = str.ReadBoolean(); + raise = str.ReadBoolean(); + nmi = str.ReadBoolean(); + devbyte = str.ReadByte(); + IM = str.ReadByte(); + HALT = str.ReadBoolean(); + shift = str.ReadInt32(); + executedInstructions = str.ReadUInt32(); + } + + #endregion } } diff --git a/src/Noddybox.Emulation/EmulationStateException.cs b/src/Noddybox.Emulation/EmulationStateException.cs new file mode 100644 index 0000000..c15bc57 --- /dev/null +++ b/src/Noddybox.Emulation/EmulationStateException.cs @@ -0,0 +1,61 @@ +// This file is part of the Noddybox.Emulation C# suite. +// +// Noddybox.Emulation is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Noddybox.Emulation is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Noddybox.Emulation. If not, see . +// +// Copyright (c) 2012 Ian Cowburn +// +using System; +using System.IO; + +namespace Noddybox.Emulation +{ + /// + /// Errors from loading/saving emulation state. + /// + public class EmulationStateException : Exception + { + /// + /// Possible reasons that saving/loading failed. + /// + public enum Reason + { + InvalidVersion, + StreamException, + InvalidFieldType + } + + /// + /// The reason that saving/loading failed. + /// + public Reason Cause {get; private set;} + + /// + /// Exception caused by something other than a stream error. + /// + /// + public EmulationStateException(string message, Reason reason) : base(message) + { + Cause = reason; + } + + /// + /// Exceptions caused by a stream error. + /// + /// + public EmulationStateException(string message, IOException exception) : base(message, exception) + { + Cause = Reason.StreamException; + } + } +} diff --git a/src/Noddybox.Emulation/EmulationStateLoadManager.cs b/src/Noddybox.Emulation/EmulationStateLoadManager.cs new file mode 100644 index 0000000..bf131d9 --- /dev/null +++ b/src/Noddybox.Emulation/EmulationStateLoadManager.cs @@ -0,0 +1,79 @@ +// This file is part of the Noddybox.Emulation C# suite. +// +// Noddybox.Emulation is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Noddybox.Emulation is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Noddybox.Emulation. If not, see . +// +// Copyright (c) 2012 Ian Cowburn +// +using System; +using System.IO; + +namespace Noddybox.Emulation +{ + /// + /// Implements the state loading for emulators. + /// + public class EmulationStateLoadManager + { + #region Public members + + /// + /// Load an emulation state into a number of objects. + /// The objects must be in the same order they were saved. + /// + /// The stream to load from. + /// The objects to load. + public static void Load(BinaryReader stream, params IEmulationState[] objects) + { + EmulationStateLoadManager manager = new EmulationStateLoadManager(stream); + + try + { + foreach (IEmulationState obj in objects) + { + int version = stream.ReadInt32(); + + if (version != obj.Version) + { + throw new EmulationStateException(String.Format("Object {0} expected version {1}; got {2}", + obj.GetType(), version, obj.Version), + EmulationStateException.Reason.InvalidVersion); + } + + obj.LoadState(manager); + } + } + catch (IOException ex) + { + throw new EmulationStateException(String.Format("Got {0}", ex.GetType()), ex); + } + } + + + /// + /// The stream the objects use for loading. + /// + public BinaryReader Stream {get; private set;} + + #endregion + + #region Constructors + + private EmulationStateLoadManager(BinaryReader stream) + { + Stream = stream; + } + + #endregion + } +} diff --git a/src/Noddybox.Emulation/EmulationStateSaveManager.cs b/src/Noddybox.Emulation/EmulationStateSaveManager.cs new file mode 100644 index 0000000..1d5cea8 --- /dev/null +++ b/src/Noddybox.Emulation/EmulationStateSaveManager.cs @@ -0,0 +1,69 @@ +// This file is part of the Noddybox.Emulation C# suite. +// +// Noddybox.Emulation is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Noddybox.Emulation is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Noddybox.Emulation. If not, see . +// +// Copyright (c) 2012 Ian Cowburn +// +using System; +using System.IO; + +namespace Noddybox.Emulation +{ + /// + /// Implements the state saving for emulators. + /// + public class EmulationStateSaveManager + { + #region Public members + + /// + /// Save an emulation state from a number of objects. + /// + /// The stream to save to. + /// The objects to save. + public static void Save(BinaryWriter stream, params IEmulationState[] objects) + { + EmulationStateSaveManager manager = new EmulationStateSaveManager(stream); + + try + { + foreach (IEmulationState obj in objects) + { + stream.Write(obj.Version); + obj.SaveState(manager); + } + } + catch (IOException ex) + { + throw new EmulationStateException(String.Format("Got {0}", ex.GetType()), ex); + } + } + + /// + /// The stream the objects use for saving. + /// + public BinaryWriter Stream {get; private set;} + + #endregion + + #region Constructors + + private EmulationStateSaveManager(BinaryWriter stream) + { + Stream = stream; + } + + #endregion + } +} diff --git a/src/Noddybox.Emulation/IEmulationState.cs b/src/Noddybox.Emulation/IEmulationState.cs new file mode 100644 index 0000000..deac167 --- /dev/null +++ b/src/Noddybox.Emulation/IEmulationState.cs @@ -0,0 +1,45 @@ +// This file is part of the Noddybox.Emulation C# suite. +// +// Noddybox.Emulation is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Noddybox.Emulation is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Noddybox.Emulation. If not, see . +// +// Copyright (c) 2012 Ian Cowburn +// +using System; +using System.IO; + +namespace Noddybox.Emulation +{ + /// + /// Provides an interface that object implement to support the saving and loading of emulation state. + /// + public interface IEmulationState + { + /// + /// Gets the version of the objects state. + /// + int Version {get;} + + /// + /// Save the object's state. + /// + /// The manager that is saving. + void SaveState(EmulationStateSaveManager manager); + + /// + /// Load the object's state. + /// + /// The manager that is loading. + void LoadState(EmulationStateLoadManager manager); + } +} -- cgit v1.2.3