summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--WindowsPhone/Noddybox.Emulation/EmulationStateSettings.cs38
-rw-r--r--WindowsPhone/Noddybox.Emulation/Noddybox.Emulation.csproj1
-rw-r--r--src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs10
-rw-r--r--src/Noddybox.Emulation.EightBit/ICpu.cs18
-rw-r--r--src/Noddybox.Emulation/EmulationStateException.cs1
-rw-r--r--src/Noddybox.Emulation/EmulationStateLoadManager.cs25
-rw-r--r--src/Noddybox.Emulation/EmulationStateSaveManager.cs1
7 files changed, 93 insertions, 1 deletions
diff --git a/WindowsPhone/Noddybox.Emulation/EmulationStateSettings.cs b/WindowsPhone/Noddybox.Emulation/EmulationStateSettings.cs
new file mode 100644
index 0000000..7b239c9
--- /dev/null
+++ b/WindowsPhone/Noddybox.Emulation/EmulationStateSettings.cs
@@ -0,0 +1,38 @@
+// 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 <http://www.gnu.org/licenses/>.
+//
+// Copyright (c) 2012 Ian Cowburn
+//
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+namespace Noddybox.Emulation
+{
+ /// <summary>
+ /// Contains internal settings for the state management.
+ /// </summary>
+ internal static class EmulationStateSettings
+ {
+ public static uint MAGIC = 0xf5ed54ef;
+ }
+}
diff --git a/WindowsPhone/Noddybox.Emulation/Noddybox.Emulation.csproj b/WindowsPhone/Noddybox.Emulation/Noddybox.Emulation.csproj
index 3b75fc7..b3cccab 100644
--- a/WindowsPhone/Noddybox.Emulation/Noddybox.Emulation.csproj
+++ b/WindowsPhone/Noddybox.Emulation/Noddybox.Emulation.csproj
@@ -70,6 +70,7 @@
<Compile Include="..\..\src\Noddybox.Emulation\ReadOnlyArray.cs">
<Link>ReadOnlyArray.cs</Link>
</Compile>
+ <Compile Include="EmulationStateSettings.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs
index a802142..854cc9d 100644
--- a/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs
+++ b/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs
@@ -256,6 +256,16 @@ namespace Noddybox.Emulation.EightBit.Z80
}
}
+ public void Run(CpuCallback callback)
+ {
+ VBL = false;
+
+ do
+ {
+ Step();
+ } while (callback(this));
+ }
+
public void MaskableInterrupt(byte value)
{
raise = true;
diff --git a/src/Noddybox.Emulation.EightBit/ICpu.cs b/src/Noddybox.Emulation.EightBit/ICpu.cs
index 9d1909c..1ee7781 100644
--- a/src/Noddybox.Emulation.EightBit/ICpu.cs
+++ b/src/Noddybox.Emulation.EightBit/ICpu.cs
@@ -20,6 +20,15 @@ using System;
namespace Noddybox.Emulation.EightBit
{
/// <summary>
+ /// Defines a delegate that will be called after an instruction.
+ /// </summary>
+ /// <param name="sender">The CPU being used. All state will be upto date prior to invoking
+ /// the callback.</param>
+ /// <returns>True if the CPU should continue executing, or false if not. Users should simply
+ /// return Clock.VBL if they need no other than clock control.</returns>
+ public delegate bool CpuCallback(object sender);
+
+ /// <summary>
/// Defines an 8-bit CPU.
/// </summary>
public interface ICpu
@@ -48,6 +57,15 @@ namespace Noddybox.Emulation.EightBit
void Run();
/// <summary>
+ /// Runs the CPU until the callback tells it to stop.
+ /// </summary>
+ /// <param name="callback">A delegate that is called after every completed instruction
+ /// cycle and tells the CPU when to stop running. Note that at least one instruction
+ /// is always executed as the callback is made after the cycle has completed.
+ /// </param>
+ void Run(CpuCallback callback);
+
+ /// <summary>
/// Generates a maskable interrupt to the CPU.
/// </summary>
/// <param name="value">Optional value from an interrupting device. May be ignored depending on the CPU type.</param>
diff --git a/src/Noddybox.Emulation/EmulationStateException.cs b/src/Noddybox.Emulation/EmulationStateException.cs
index c15bc57..84df165 100644
--- a/src/Noddybox.Emulation/EmulationStateException.cs
+++ b/src/Noddybox.Emulation/EmulationStateException.cs
@@ -30,6 +30,7 @@ namespace Noddybox.Emulation
/// </summary>
public enum Reason
{
+ InvalidStream,
InvalidVersion,
StreamException,
InvalidFieldType
diff --git a/src/Noddybox.Emulation/EmulationStateLoadManager.cs b/src/Noddybox.Emulation/EmulationStateLoadManager.cs
index bf131d9..cf9aa52 100644
--- a/src/Noddybox.Emulation/EmulationStateLoadManager.cs
+++ b/src/Noddybox.Emulation/EmulationStateLoadManager.cs
@@ -39,18 +39,41 @@ namespace Noddybox.Emulation
try
{
+ IEmulationState last = null;
+
foreach (IEmulationState obj in objects)
{
+ uint magic = stream.ReadUInt32();
+
+ if (magic != EmulationStateSettings.MAGIC)
+ {
+ string message;
+
+ if (last != null)
+ {
+ message = String.Format("Corrupted stream; {0} may have read too much or little", last.GetType());
+ }
+ else
+ {
+ message = "Invalid stream - not an emulation state file.";
+ }
+
+ throw new EmulationStateException(message,
+ EmulationStateException.Reason.InvalidStream);
+ }
+
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),
+ obj.GetType(), obj.Version, version),
EmulationStateException.Reason.InvalidVersion);
}
obj.LoadState(manager);
+
+ last = obj;
}
}
catch (IOException ex)
diff --git a/src/Noddybox.Emulation/EmulationStateSaveManager.cs b/src/Noddybox.Emulation/EmulationStateSaveManager.cs
index 1d5cea8..94716db 100644
--- a/src/Noddybox.Emulation/EmulationStateSaveManager.cs
+++ b/src/Noddybox.Emulation/EmulationStateSaveManager.cs
@@ -40,6 +40,7 @@ namespace Noddybox.Emulation
{
foreach (IEmulationState obj in objects)
{
+ stream.Write(EmulationStateSettings.MAGIC);
stream.Write(obj.Version);
obj.SaveState(manager);
}