From 2e3102879b2d3059f4ce0efc1a0ecd4bc3142a99 Mon Sep 17 00:00:00 2001 From: Ian C <ianc@noddybox.co.uk> Date: Wed, 28 Dec 2011 00:11:12 +0000 Subject: Added some more base classes and started on the Z80 implementation. --- .../Noddybox.Emulation.EightBit.Z80.csproj | 75 +++++++++ .../Properties/AssemblyInfo.cs | 37 +++++ Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs | 167 +++++++++++++++++++++ Noddybox.Emulation.EightBit/ICpu.cs | 54 +++++++ Noddybox.Emulation.EightBit/IDevice.cs | 4 +- Noddybox.Emulation.EightBit/IMemory.cs | 4 +- Noddybox.Emulation.EightBit/IRegister16.cs | 34 +++++ .../Noddybox.Emulation.EightBit.csproj | 11 ++ Noddybox.Emulation.EightBit/Register16BigEndian.cs | 53 +++++++ Noddybox.Emulation.EightBit/Register16Factory.cs | 31 ++++ .../Register16LittleEndian.cs | 53 +++++++ Noddybox.Emulation.sln | 6 + Noddybox.Emulation.suo | Bin 0 -> 37376 bytes Noddybox.Emulation/Clock.cs | 9 ++ 14 files changed, 534 insertions(+), 4 deletions(-) create mode 100644 Noddybox.Emulation.EightBit.Z80/Noddybox.Emulation.EightBit.Z80.csproj create mode 100644 Noddybox.Emulation.EightBit.Z80/Properties/AssemblyInfo.cs create mode 100644 Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs create mode 100644 Noddybox.Emulation.EightBit/ICpu.cs create mode 100644 Noddybox.Emulation.EightBit/IRegister16.cs create mode 100644 Noddybox.Emulation.EightBit/Register16BigEndian.cs create mode 100644 Noddybox.Emulation.EightBit/Register16Factory.cs create mode 100644 Noddybox.Emulation.EightBit/Register16LittleEndian.cs create mode 100644 Noddybox.Emulation.suo diff --git a/Noddybox.Emulation.EightBit.Z80/Noddybox.Emulation.EightBit.Z80.csproj b/Noddybox.Emulation.EightBit.Z80/Noddybox.Emulation.EightBit.Z80.csproj new file mode 100644 index 0000000..60cb7ff --- /dev/null +++ b/Noddybox.Emulation.EightBit.Z80/Noddybox.Emulation.EightBit.Z80.csproj @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>10.0.20506</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{7F257886-40D3-4E2A-BA9C-C5FEE93C08E9}</ProjectGuid> + <ProjectTypeGuids>{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Noddybox.Emulation.EightBit.Z80</RootNamespace> + <AssemblyName>Noddybox.Emulation.EightBit.Z80</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion> + <TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile> + <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier> + <SilverlightApplication>false</SilverlightApplication> + <ValidateXaml>true</ValidateXaml> + <ThrowErrorsInValidation>true</ThrowErrorsInValidation> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>Bin\Debug</OutputPath> + <DefineConstants>DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants> + <NoStdLib>true</NoStdLib> + <NoConfig>true</NoConfig> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>Bin\Release</OutputPath> + <DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants> + <NoStdLib>true</NoStdLib> + <NoConfig>true</NoConfig> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System.Windows" /> + <Reference Include="system" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml" /> + <Reference Include="System.Net" /> + <Reference Include="mscorlib.extensions" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Z80Cpu.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Noddybox.Emulation.EightBit\Noddybox.Emulation.EightBit.csproj"> + <Project>{ADC7A871-4DED-4A92-A447-2D784AB60FAF}</Project> + <Name>Noddybox.Emulation.EightBit</Name> + </ProjectReference> + <ProjectReference Include="..\Noddybox.Emulation\Noddybox.Emulation.csproj"> + <Project>{A2478066-4DFD-4042-BF98-963922DC97F8}</Project> + <Name>Noddybox.Emulation</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" /> + <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" /> + <ProjectExtensions /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file diff --git a/Noddybox.Emulation.EightBit.Z80/Properties/AssemblyInfo.cs b/Noddybox.Emulation.EightBit.Z80/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..52b6054 --- /dev/null +++ b/Noddybox.Emulation.EightBit.Z80/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Resources; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Noddybox.Emulation.EightBit.Z80")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Noddybox.Emulation.EightBit.Z80")] +[assembly: AssemblyCopyright("Copyright © 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3b53cbb7-adc4-4405-ba85-4b345a46ed11")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: NeutralResourcesLanguageAttribute("en-US")] diff --git a/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs b/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs new file mode 100644 index 0000000..d967bb9 --- /dev/null +++ b/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs @@ -0,0 +1,167 @@ +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.EightBit.Z80 +{ + /// <summary> + /// Provides an implementation of a Zilog Z80 processor. + /// </summary> + public partial class Z80Cpu : ICpu + { + #region Private types + + [Flags] + private enum Z80Flags + { + None = 0x00, + Carry = 0x01, + Neg = 0x02, + PV = 0x04, + Hidden3 = 0x08, + HalfCarry = 0x10, + Hidden5 = 0x20, + Zero = 0x40, + Sign = 0x80 + }; + + #endregion + + #region Private data + + // Lookup tables + // + private Z80Flags[] PSZtable = new Z80Flags[512]; + private Z80Flags[] SZtable = new Z80Flags[512]; + private Z80Flags[] Ptable = new Z80Flags[512]; + private Z80Flags[] Stable = new Z80Flags[512]; + private Z80Flags[] Ztable = new Z80Flags[512]; + + // Machine accessors + // + private IMemory memory; + private IDevice device; + private Clock clock; + + // Main registers + // + private byte A; + private byte F; + private byte R; + private byte IFF1; + private byte IFF2; + private IRegister16 BC = Register16Factory.Create(); + private IRegister16 DE = Register16Factory.Create(); + private IRegister16 HL = Register16Factory.Create(); + private IRegister16 IX = Register16Factory.Create(); + private IRegister16 IY = Register16Factory.Create(); + private IRegister16 SP = Register16Factory.Create(); + private IRegister16 PC = Register16Factory.Create(); + + // Alternate registers + // + private IRegister16 AF_ = Register16Factory.Create(); + private IRegister16 BC_ = Register16Factory.Create(); + private IRegister16 DE_ = Register16Factory.Create(); + private IRegister16 HL_ = Register16Factory.Create(); + + #endregion + + #region ICpu Members + + public void Initialise(IMemory memory, IDevice device, Clock clock) + { + this.memory = memory; + this.device = device; + this.clock = clock; + + Reset(); + } + + public void Reset() + { + // TODO: Initial register settings. + } + + public void Step() + { + // TODO: Single step. + } + + public void Run() + { + // TODO: Run for a frame + } + + public void MaskableInterrupt(byte value) + { + // TODO: INT + } + + public void NonMaskableInterrupt(byte value) + { + // TODO: NMI + } + + #endregion + + #region Constructors + + public Z80Cpu() + { + // Setup lookup tables + // + for(int f = 0; f < 256; f++) + { + Z80Flags p = Z80Flags.None; + Z80Flags z = Z80Flags.None; + Z80Flags s = Z80Flags.None; + int parity = 0; + + for(int b=0; b < 8; b++) + { + if ((f & (1<<b)) == (1<<b)) + { + parity++; + } + } + + if ((parity & 1) == 1) + { + p = Z80Flags.PV; + } + + if (f == 0) + { + z = Z80Flags.Zero; + } + + if ((f & 0x80) == 0x80) + { + s = Z80Flags.Sign; + } + + Ptable[f] = p; + Stable[f] = s; + Ztable[f] = z; + SZtable[f] =z|s; + PSZtable[f] = z|s|p; + + Ptable[f+256] = Ptable[f]|Z80Flags.Carry; + Stable[f+256] = Stable[f]|Z80Flags.Carry; + Ztable[f+256] = Ztable[f]|Z80Flags.Carry; + SZtable[f+256] = SZtable[f]|Z80Flags.Carry; + PSZtable[f+256] = PSZtable[f]|Z80Flags.Carry; + } + } + + #endregion + } +} diff --git a/Noddybox.Emulation.EightBit/ICpu.cs b/Noddybox.Emulation.EightBit/ICpu.cs new file mode 100644 index 0000000..139933d --- /dev/null +++ b/Noddybox.Emulation.EightBit/ICpu.cs @@ -0,0 +1,54 @@ +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.EightBit +{ + /// <summary> + /// Defines an 8-bit CPU. + /// </summary> + public interface ICpu + { + /// <summary> + /// Initialise the CPU to give it access to memory and devices. + /// </summary> + /// <param name="memory">The memory to access.</param> + /// <param name="device">The devices to access.</param> + /// <param name="clock">The clock to use.</param> + void Initialise(IMemory memory, IDevice device, Clock clock); + + /// <summary> + /// Resets the CPU to its initial state. + /// </summary> + void Reset(); + + /// <summary> + /// Runs the next instruction. + /// </summary> + void Step(); + + /// <summary> + /// Runs the CPU until the next frame flyback. + /// </summary> + void Run(); + + /// <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> + void MaskableInterrupt(byte value); + + /// <summary> + /// Generates a non-maskable interrupt to the CPU. + /// </summary> + /// <param name="value">Optional value from an interrupting device. May be ignored depending on the CPU type.</param> + void NonMaskableInterrupt(byte value); + } +} diff --git a/Noddybox.Emulation.EightBit/IDevice.cs b/Noddybox.Emulation.EightBit/IDevice.cs index 108adf9..00ef38d 100644 --- a/Noddybox.Emulation.EightBit/IDevice.cs +++ b/Noddybox.Emulation.EightBit/IDevice.cs @@ -22,13 +22,13 @@ namespace Noddybox.Emulation.EightBit /// </summary> /// <param name="device">The address of the device.</param> /// <returns>The byte returned from the device.</returns> - byte Read(UInt16 device); + byte Read(ushort device); /// <summary> /// Write to a device. /// </summary> /// <param name="device">The address of the device.</param> /// <param name="value">The value to write to the device.</param> - void Write(UInt16 device, byte value); + void Write(ushort device, byte value); } } diff --git a/Noddybox.Emulation.EightBit/IMemory.cs b/Noddybox.Emulation.EightBit/IMemory.cs index 5131eb0..2c842a5 100644 --- a/Noddybox.Emulation.EightBit/IMemory.cs +++ b/Noddybox.Emulation.EightBit/IMemory.cs @@ -21,13 +21,13 @@ namespace Noddybox.Emulation.EightBit /// </summary> /// <param name="address">The address to read.</param> /// <returns>The value at that address.</returns> - byte Read(UInt16 address); + byte Read(ushort address); /// <summary> /// Writes a byte at a given address. /// </summary> /// <param name="address">The address to write to.</param> /// <param name="value">The value to write.</param> - void Write(UInt16 address, byte value); + void Write(ushort address, byte value); } } diff --git a/Noddybox.Emulation.EightBit/IRegister16.cs b/Noddybox.Emulation.EightBit/IRegister16.cs new file mode 100644 index 0000000..e3bfc69 --- /dev/null +++ b/Noddybox.Emulation.EightBit/IRegister16.cs @@ -0,0 +1,34 @@ +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.EightBit +{ + /// <summary> + /// Provides a common 8-bit register pattern, which is two 8-bit registers rolled into one. + /// </summary> + public interface IRegister16 + { + /// <summary> + /// Get/set the low byte of the 16-bit register. + /// </summary> + byte Low {get; set;} + + /// <summary> + /// Get/set the high byte of the 16-bit register. + /// </summary> + byte High {get; set;} + + /// <summary> + /// Get/set the value of the 16-bit register. + /// </summary> + ushort Value {get; set;} + } +} diff --git a/Noddybox.Emulation.EightBit/Noddybox.Emulation.EightBit.csproj b/Noddybox.Emulation.EightBit/Noddybox.Emulation.EightBit.csproj index 316b00b..c7d5924 100644 --- a/Noddybox.Emulation.EightBit/Noddybox.Emulation.EightBit.csproj +++ b/Noddybox.Emulation.EightBit/Noddybox.Emulation.EightBit.csproj @@ -49,9 +49,20 @@ <Reference Include="mscorlib.extensions" /> </ItemGroup> <ItemGroup> + <Compile Include="ICpu.cs" /> <Compile Include="IDevice.cs" /> <Compile Include="IMemory.cs" /> + <Compile Include="IRegister16.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Register16BigEndian.cs" /> + <Compile Include="Register16Factory.cs" /> + <Compile Include="Register16LittleEndian.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Noddybox.Emulation\Noddybox.Emulation.csproj"> + <Project>{A2478066-4DFD-4042-BF98-963922DC97F8}</Project> + <Name>Noddybox.Emulation</Name> + </ProjectReference> </ItemGroup> <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" /> <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" /> diff --git a/Noddybox.Emulation.EightBit/Register16BigEndian.cs b/Noddybox.Emulation.EightBit/Register16BigEndian.cs new file mode 100644 index 0000000..8378543 --- /dev/null +++ b/Noddybox.Emulation.EightBit/Register16BigEndian.cs @@ -0,0 +1,53 @@ +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; +using System.Runtime.InteropServices; + +namespace Noddybox.Emulation.EightBit +{ + [StructLayout(LayoutKind.Explicit)] + public struct Register16BigEndian : IRegister16 + { + #region Register fields + + [FieldOffset(0)] + ushort reg; + + [FieldOffset(1)] + byte low; + + [FieldOffset(0)] + byte high; + + #endregion + + #region IRegister16 Members + + public byte Low + { + get {return low;} + set {low = value;} + } + + public byte High + { + get {return high;} + set {high = value;} + } + + public ushort Value + { + get {return reg;} + set {reg = value;} + } + + #endregion + } +} diff --git a/Noddybox.Emulation.EightBit/Register16Factory.cs b/Noddybox.Emulation.EightBit/Register16Factory.cs new file mode 100644 index 0000000..fd31fe4 --- /dev/null +++ b/Noddybox.Emulation.EightBit/Register16Factory.cs @@ -0,0 +1,31 @@ +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.EightBit +{ + /// <summary> + /// Defines a common 16-bit register, which is two bytes which are separately addressable. + /// </summary> + public static class Register16Factory + { + public static IRegister16 Create() + { + if (BitConverter.IsLittleEndian) + { + return new Register16LittleEndian(); + } + else + { + return new Register16BigEndian(); + } + } + } +} diff --git a/Noddybox.Emulation.EightBit/Register16LittleEndian.cs b/Noddybox.Emulation.EightBit/Register16LittleEndian.cs new file mode 100644 index 0000000..a2cf8a8 --- /dev/null +++ b/Noddybox.Emulation.EightBit/Register16LittleEndian.cs @@ -0,0 +1,53 @@ +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; +using System.Runtime.InteropServices; + +namespace Noddybox.Emulation.EightBit +{ + [StructLayout(LayoutKind.Explicit)] + public struct Register16LittleEndian : IRegister16 + { + #region Register fields + + [FieldOffset(0)] + ushort reg; + + [FieldOffset(0)] + byte low; + + [FieldOffset(1)] + byte high; + + #endregion + + #region IRegister16 Members + + public byte Low + { + get {return low;} + set {low = value;} + } + + public byte High + { + get {return high;} + set {high = value;} + } + + public ushort Value + { + get {return reg;} + set {reg = value;} + } + + #endregion + } +} diff --git a/Noddybox.Emulation.sln b/Noddybox.Emulation.sln index 78f38c7..7578ca2 100644 --- a/Noddybox.Emulation.sln +++ b/Noddybox.Emulation.sln @@ -5,6 +5,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Noddybox.Emulation", "Noddy EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Noddybox.Emulation.EightBit", "Noddybox.Emulation.EightBit\Noddybox.Emulation.EightBit.csproj", "{ADC7A871-4DED-4A92-A447-2D784AB60FAF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Noddybox.Emulation.EightBit.Z80", "Noddybox.Emulation.EightBit.Z80\Noddybox.Emulation.EightBit.Z80.csproj", "{7F257886-40D3-4E2A-BA9C-C5FEE93C08E9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -19,6 +21,10 @@ Global {ADC7A871-4DED-4A92-A447-2D784AB60FAF}.Debug|Any CPU.Build.0 = Debug|Any CPU {ADC7A871-4DED-4A92-A447-2D784AB60FAF}.Release|Any CPU.ActiveCfg = Release|Any CPU {ADC7A871-4DED-4A92-A447-2D784AB60FAF}.Release|Any CPU.Build.0 = Release|Any CPU + {7F257886-40D3-4E2A-BA9C-C5FEE93C08E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F257886-40D3-4E2A-BA9C-C5FEE93C08E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F257886-40D3-4E2A-BA9C-C5FEE93C08E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F257886-40D3-4E2A-BA9C-C5FEE93C08E9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Noddybox.Emulation.suo b/Noddybox.Emulation.suo new file mode 100644 index 0000000..8cd6ad5 Binary files /dev/null and b/Noddybox.Emulation.suo differ diff --git a/Noddybox.Emulation/Clock.cs b/Noddybox.Emulation/Clock.cs index 79beafb..55a0e7b 100644 --- a/Noddybox.Emulation/Clock.cs +++ b/Noddybox.Emulation/Clock.cs @@ -64,6 +64,15 @@ namespace Noddybox.Emulation } } + /// <summary> + /// Adds a number of ticks to the clock. + /// </summary> + /// <param name="ticks">The ticks to add.</param> + public void Add(uint ticks) + { + frameCount += ticks; + } + #endregion #region Constructors -- cgit v1.2.3