From 2b8d49726e448e22b5055da5ba4395d043030984 Mon Sep 17 00:00:00 2001 From: Ian C Date: Sun, 1 Jan 2012 14:21:26 +0000 Subject: Moved sources to help in compilation for other platforms and isolated phone projects. --- src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs | 226 ++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs (limited to 'src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs') diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs new file mode 100644 index 0000000..5c40854 --- /dev/null +++ b/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs @@ -0,0 +1,226 @@ +// +// 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.EightBit.Z80 +{ + /// + /// Provides an implementation of a Zilog Z80 processor. + /// + 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]; + private Z80Flags[] H35table = new Z80Flags[256]; + + // Machine accessors + // + private IMemory memory; + private IDevice device; + private Clock clock; + + // Main registers + // + private byte A; + private Z80Flags F; + private Register16 BC = new Register16(0); + private Register16 DE = new Register16(0); + private Register16 HL = new Register16(0); + private Register16 IX = new Register16(0); + private Register16 IY = new Register16(0); + private ushort SP; + private ushort PC; + + // Alternate registers + // + private Register16 AF_ = new Register16(0); + private Register16 BC_ = new Register16(0); + private Register16 DE_ = new Register16(0); + private Register16 HL_ = new Register16(0); + + // Auxilliary registers and flags + // + private byte I; + private byte R; + private bool IFF1; + private bool IFF2; + private int IM; + private bool HALT; + + #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() + { + PC = 0; + A = 0xff; + F = (Z80Flags)0xff; + + BC.reg = 0xffff; + DE.reg = 0xffff; + HL.reg = 0xffff; + AF_.reg = 0xffff; + BC_.reg = 0xffff; + DE_.reg = 0xffff; + HL_.reg = 0xffff; + + IX.reg = 0xffff; + IY.reg = 0xffff; + + SP = 0xffff; + + IFF1 = false; + IFF2 = false; + IM = 0; + I = 0; + R = 0; + HALT = false; + } + + public void Step() + { + // TODO: Single step. + } + + public void Run() + { + while(!clock.FrameDone) + { + Step(); + } + } + + public void MaskableInterrupt(byte value) + { + clock.Add(2); + + // TODO: INT + } + + public void NonMaskableInterrupt(byte value) + { + clock.Add(2); + + // TODO: NMI + } + + #endregion + + #region Constructors + + public Z80Cpu() + { + // Verify runtime + // + Register16.Verify(); + + // Setup lookup tables + // + for(int f = 0; f < 256; f++) + { + Z80Flags p = Z80Flags.None; + Z80Flags z = Z80Flags.None; + Z80Flags s = Z80Flags.None; + Z80Flags h3 = Z80Flags.None; + Z80Flags h5 = Z80Flags.None; + + int parity = 0; + + for(int b=0; b < 8; b++) + { + if ((f & (1<