summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Noddybox.Emulation.Phone.suobin42496 -> 51200 bytes
-rw-r--r--WindowsPhone/Noddybox.Emulation.EightBit.Z80/Noddybox.Emulation.EightBit.Z80.csproj3
-rw-r--r--src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs17
-rw-r--r--src/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs305
-rw-r--r--src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs407
-rw-r--r--src/Noddybox.Emulation.EightBit/Binary.cs9
-rw-r--r--src/Noddybox.Emulation.EightBit/ICpu.cs9
-rw-r--r--src/Noddybox.Emulation.EightBit/IDevice.cs9
-rw-r--r--src/Noddybox.Emulation.EightBit/IMemory.cs9
-rw-r--r--src/Noddybox.Emulation/Clock.cs9
10 files changed, 700 insertions, 77 deletions
diff --git a/Noddybox.Emulation.Phone.suo b/Noddybox.Emulation.Phone.suo
index 0e0dc15..ad9a993 100644
--- a/Noddybox.Emulation.Phone.suo
+++ b/Noddybox.Emulation.Phone.suo
Binary files differ
diff --git a/WindowsPhone/Noddybox.Emulation.EightBit.Z80/Noddybox.Emulation.EightBit.Z80.csproj b/WindowsPhone/Noddybox.Emulation.EightBit.Z80/Noddybox.Emulation.EightBit.Z80.csproj
index 1e0579f..aa1cc53 100644
--- a/WindowsPhone/Noddybox.Emulation.EightBit.Z80/Noddybox.Emulation.EightBit.Z80.csproj
+++ b/WindowsPhone/Noddybox.Emulation.EightBit.Z80/Noddybox.Emulation.EightBit.Z80.csproj
@@ -55,6 +55,9 @@
<Compile Include="..\..\src\Noddybox.Emulation.EightBit.Z80\Z80CpuBaseOpcodes.cs">
<Link>Z80CpuBaseOpcodes.cs</Link>
</Compile>
+ <Compile Include="..\..\src\Noddybox.Emulation.EightBit.Z80\Z80CpuDecodeByte.cs">
+ <Link>Z80CpuDecodeByte.cs</Link>
+ </Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs
index 5c40854..0717ef5 100644
--- a/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs
+++ b/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs
@@ -2,15 +2,6 @@
// 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
{
@@ -32,7 +23,8 @@ namespace Noddybox.Emulation.EightBit.Z80
HalfCarry = 0x10,
Hidden5 = 0x20,
Zero = 0x40,
- Sign = 0x80
+ Sign = 0x80,
+ Hidden = Hidden3 | Hidden5
};
#endregion
@@ -46,7 +38,7 @@ namespace Noddybox.Emulation.EightBit.Z80
private Z80Flags[] Ptable = new Z80Flags[512];
private Z80Flags[] Stable = new Z80Flags[512];
private Z80Flags[] Ztable = new Z80Flags[512];
- private Z80Flags[] H35table = new Z80Flags[256];
+ private Z80Flags[] H35table = new Z80Flags[512];
// Machine accessors
//
@@ -81,6 +73,7 @@ namespace Noddybox.Emulation.EightBit.Z80
private bool IFF2;
private int IM;
private bool HALT;
+ private int shift;
#endregion
@@ -120,6 +113,7 @@ namespace Noddybox.Emulation.EightBit.Z80
I = 0;
R = 0;
HALT = false;
+ shift = 0;
}
public void Step()
@@ -216,6 +210,7 @@ namespace Noddybox.Emulation.EightBit.Z80
Ztable[f+256] = Ztable[f] | Z80Flags.Carry;
SZtable[f+256] = SZtable[f] | Z80Flags.Carry;
PSZtable[f+256] = PSZtable[f] | Z80Flags.Carry;
+ H35table[f+256] = h3 | h5;
}
Reset();
diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs
index 40b31ca..378fd05 100644
--- a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs
+++ b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs
@@ -2,20 +2,58 @@
// 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
{
public partial class Z80Cpu
{
+ #region Fetch and helper operations
+
+ /// <summary>
+ /// Fetch the next word from the PC.
+ /// </summary>
+ /// <returns>The word.</returns>
+ ushort FetchWord()
+ {
+ Register16 r = new Register16(0);
+
+ r.low = memory.Read(PC++);
+ r.high = memory.Read(PC++);
+
+ return r.reg;
+ }
+
+ /// <summary>
+ /// Swap two 16-bit registers.
+ /// </summary>
+ /// <param name="a">The first register.</param>
+ /// <param name="b">The second register.</param>
+ void Swap(ref Register16 a, ref Register16 b)
+ {
+ Register16 t = a;
+ a = b;
+ b = t;
+ }
+
+ /// <summary>
+ /// Fetch the offset if the current opcode is shifted.
+ /// </summary>
+ /// <returns>The offset, or zero if the current opcode is not shifted.</returns>
+ sbyte Offset()
+ {
+ if (shift == 0xdd || shift == 0xfd)
+ {
+ byte b = memory.Read(PC++);
+ return (sbyte)b;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ #endregion
+
#region Status register helpers
/// <summary>
@@ -69,7 +107,7 @@ namespace Noddybox.Emulation.EightBit.Z80
/// Add an 8-bit value to the accumulator without carry.
/// </summary>
/// <param name="b">The vakue.</param>
- private void Add8(byte b)
+ private void ADD8(byte b)
{
int w = A + b;
@@ -92,7 +130,7 @@ namespace Noddybox.Emulation.EightBit.Z80
/// Add an 8-bit value to the accumulator with carry.
/// </summary>
/// <param name="b">The vakue.</param>
- private void Adc8(byte b)
+ private void ADC8(byte b)
{
int w = A + b + (int)(F & Z80Flags.Carry);
@@ -115,7 +153,7 @@ namespace Noddybox.Emulation.EightBit.Z80
/// Subtract an 8-bit value from the accumulator without carry.
/// </summary>
/// <param name="b">The vakue.</param>
- private void Sub8(byte b)
+ private void SUB8(byte b)
{
int w = A - b;
@@ -143,7 +181,7 @@ namespace Noddybox.Emulation.EightBit.Z80
/// Compare an 8-bit value with the accumulator.
/// </summary>
/// <param name="b">The vakue.</param>
- private void Cmp8(byte b)
+ private void CMP8(byte b)
{
int w = A - b;
@@ -169,7 +207,7 @@ namespace Noddybox.Emulation.EightBit.Z80
/// Subtract an 8-bit value from the accumulator with carry.
/// </summary>
/// <param name="b">The vakue.</param>
- private void Sbc8(byte b)
+ private void SBC8(byte b)
{
int w = A - b - (int)(F & Z80Flags.Carry);
@@ -197,7 +235,7 @@ namespace Noddybox.Emulation.EightBit.Z80
/// Add a 16-bit value to a register without carry.
/// </summary>
/// <param name="b">The vakue.</param>
- private void Add16(ref ushort reg, ushort b)
+ private void ADD16(ref ushort reg, ushort b)
{
int w = reg + b;
@@ -222,7 +260,7 @@ namespace Noddybox.Emulation.EightBit.Z80
/// Add a 16-bit value to a register with carry.
/// </summary>
/// <param name="b">The vakue.</param>
- private void Adc16(ref ushort reg, ushort b)
+ private void ADC16(ref ushort reg, ushort b)
{
int w = reg + b + (int)(F & Z80Flags.Carry);
@@ -263,7 +301,7 @@ namespace Noddybox.Emulation.EightBit.Z80
/// Subtract a 16-bit value from a register with carry.
/// </summary>
/// <param name="b">The vakue.</param>
- private void Sbc16(ref ushort reg, ushort b)
+ private void SBC(ref ushort reg, ushort b)
{
int w = reg - b - (int)(F & Z80Flags.Carry);
@@ -304,7 +342,7 @@ namespace Noddybox.Emulation.EightBit.Z80
/// Increment an 8-bit register.
/// </summary>
/// <param name="reg">The register to increment.</param>
- void Inc8(ref byte reg)
+ void INC8(ref byte reg)
{
reg++;
@@ -325,7 +363,7 @@ namespace Noddybox.Emulation.EightBit.Z80
/// Decrement an 8-bit register.
/// </summary>
/// <param name="reg">The register to decrement.</param>
- void Dec8(ref byte reg)
+ void DEC8(ref byte reg)
{
reg--;
@@ -342,6 +380,44 @@ namespace Noddybox.Emulation.EightBit.Z80
}
}
+ /// <summary>
+ /// Decimally adjust the accumulator. A bugger of an opcode.
+ /// Based on info from http://www.worldofspectrum.org/faq/reference/z80reference.htm
+ /// </summary>
+ void DAA()
+ {
+ byte add = 0;
+ Z80Flags carry = Z80Flags.None;
+ Z80Flags nf = F & Z80Flags.Neg;
+ byte acc = A;
+
+ if (acc>0x99 || (F & Z80Flags.Carry) == Z80Flags.Carry)
+ {
+ add |= 0x60;
+ carry = Z80Flags.Carry;
+ }
+
+ if ((acc & 0xf) > 0x9 || (F & Z80Flags.HalfCarry) == Z80Flags.HalfCarry)
+ {
+ add|=0x06;
+ }
+
+ if (nf == Z80Flags.Neg)
+ {
+ A -= add;
+ }
+ else
+ {
+ A += add;
+ }
+
+ F = PSZtable[A]
+ | carry
+ | nf |
+ ((Z80Flags)(acc ^ A) & Z80Flags.HalfCarry)
+ | H35table[A];
+ }
+
#endregion
#region ALU rotate and shift operations
@@ -679,8 +755,7 @@ namespace Noddybox.Emulation.EightBit.Z80
}
/// <summary>
- /// Reset the PC to an address
- /// register equals the passed check value.
+ /// Reset the PC to an address.
/// </summary>
/// <param name="addr">The address.</param>
private void RST(ushort addr)
@@ -691,5 +766,193 @@ namespace Noddybox.Emulation.EightBit.Z80
}
#endregion
+
+ #region Block operations
+
+ /// <summary>
+ /// LDI instruction.
+ /// </summary>
+ private void LDI()
+ {
+ byte b = memory.Read(HL.reg);
+ memory.Write(DE.reg, b);
+ DE.reg++;
+ HL.reg++;
+ BC.reg--;
+
+ if (BC.reg != 0)
+ {
+ ClearFlag(Z80Flags.HalfCarry | Z80Flags.Neg);
+ SetFlag(Z80Flags.PV);
+ }
+ else
+ {
+ ClearFlag(Z80Flags.HalfCarry | Z80Flags.Neg | Z80Flags.PV);
+ }
+
+ F |= H35table[A + b];
+ }
+
+ /// <summary>
+ /// LDD instruction.
+ /// </summary>
+ private void LDD()
+ {
+ byte b = memory.Read(HL.reg);
+ memory.Write(DE.reg, b);
+ DE.reg--;
+ HL.reg--;
+ BC.reg--;
+
+ if (BC.reg != 0)
+ {
+ ClearFlag(Z80Flags.HalfCarry | Z80Flags.Neg);
+ SetFlag(Z80Flags.PV);
+ }
+ else
+ {
+ ClearFlag(Z80Flags.HalfCarry | Z80Flags.Neg | Z80Flags.PV);
+ }
+
+ F |= H35table[A + b];
+ }
+
+ /// <summary>
+ /// CPI instruction.
+ /// </summary>
+ private void CPI()
+ {
+ Z80Flags c = F & Z80Flags.Carry;
+ byte b = memory.Read(HL.reg);
+
+ CMP8(b);
+ F |= c;
+
+ HL.reg++;
+ BC.reg--;
+
+ if (BC.reg != 0)
+ {
+ SetFlag(Z80Flags.PV);
+ }
+ else
+ {
+ ClearFlag(Z80Flags.PV);
+ }
+ }
+
+ /// <summary>
+ /// CPD instruction.
+ /// </summary>
+ private void CPD()
+ {
+ Z80Flags c = F & Z80Flags.Carry;
+ byte b = memory.Read(HL.reg);
+
+ CMP8(b);
+ F |= c;
+
+ HL.reg--;
+ BC.reg--;
+
+ if (BC.reg != 0)
+ {
+ SetFlag(Z80Flags.PV);
+ }
+ else
+ {
+ ClearFlag(Z80Flags.PV);
+ }
+ }
+
+ /// <summary>
+ /// INI instruction.
+ /// </summary>
+ private void INI()
+ {
+ int w;
+ byte b = device.Read(BC.reg);
+ memory.Write(HL.reg, b);
+
+ BC.high--;
+ HL.reg++;
+
+ F = SZtable[BC.high] | H35table[BC.high];
+
+ w = BC.low + b;
+
+ if ((w & 0x80) == 0x80)
+ {
+ SetFlag(Z80Flags.Neg);
+ }
+
+ if ((w & 0x100) == 0x100)
+ {
+ SetFlag(Z80Flags.Carry | Z80Flags.HalfCarry);
+ }
+ else
+ {
+ ClearFlag(Z80Flags.Carry | Z80Flags.HalfCarry);
+ }
+ }
+
+ /// <summary>
+ /// IND instruction.
+ /// </summary>
+ private void IND()
+ {
+ int w;
+ byte b = device.Read(BC.reg);
+ memory.Write(HL.reg, b);
+
+ BC.high--;
+ HL.reg--;
+
+ F = SZtable[BC.high] | H35table[BC.high];
+
+ w = BC.low + b;
+
+ if ((w & 0x80) == 0x80)
+ {
+ SetFlag(Z80Flags.Neg);
+ }
+
+ if ((w & 0x100) == 0x100)
+ {
+ SetFlag(Z80Flags.Carry | Z80Flags.HalfCarry);
+ }
+ else
+ {
+ ClearFlag(Z80Flags.Carry | Z80Flags.HalfCarry);
+ }
+ }
+
+ /// <summary>
+ /// OUTI instruction.
+ /// </summary>
+ private void OUTI()
+ {
+ device.Write(BC.reg, memory.Read(HL.reg));
+
+ HL.reg++;
+ BC.high--;
+
+ F = SZtable[BC.high] | H35table[BC.high];
+ }
+
+ /// <summary>
+ /// OUTD instruction.
+ /// </summary>
+ private void OUTD()
+ {
+ device.Write(BC.reg, memory.Read(HL.reg));
+
+ HL.reg--;
+ BC.high--;
+
+ F = SZtable[BC.high] | H35table[BC.high] | Z80Flags.Neg;
+ }
+
+ #endregion
}
}
diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs
new file mode 100644
index 0000000..4a747e1
--- /dev/null
+++ b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs
@@ -0,0 +1,407 @@
+//
+// Copyright (c) 2012 Ian Cowburn
+//
+using System;
+
+namespace Noddybox.Emulation.EightBit.Z80
+{
+ public partial class Z80Cpu
+ {
+ /// <summary>
+ /// Decode and execute an opcode.
+ /// </summary>
+ /// <param name="opcode">The opcode.</param>
+ private void Decode(byte opcode)
+ {
+ // Check for shifted opcodes
+ //
+ switch(shift)
+ {
+ case 0xdd:
+ Decode(opcode, ref IX);
+ break;
+
+ case 0xfd:
+ Decode(opcode, ref IY);
+ break;
+
+ default:
+ Decode(opcode, ref HL);
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Decode and execute an opcode.
+ /// </summary>
+ /// <param name="opcode">The opcode.</param>
+ /// <param name="hl">The register to use for HL register operations.</param>
+ private void Decode(byte opcode, ref Register16 hl)
+ {
+ ushort addr;
+ byte b;
+
+ switch(opcode)
+ {
+ case 0x00: // NOP
+ clock.Add(4);
+ break;
+
+ case 0x01: // LD BC, nnnn
+ clock.Add(10);
+ BC.reg = FetchWord();
+ break;
+
+ case 0x02: // LD (BC), A
+ clock.Add(7);
+ memory.Write(BC.reg, A);
+ break;
+
+ case 0x03: // INC BC
+ clock.Add(6);
+ BC.reg++;
+ break;
+
+ case 0x04: // INC B
+ clock.Add(4);
+ INC8(ref BC.high);
+ break;
+
+ case 0x05: // DEC B
+ clock.Add(4);
+ DEC8(ref BC.high);
+ break;
+
+ case 0x06: // LD B,n
+ clock.Add(7);
+ BC.high = memory.Read(PC++);
+ break;
+
+ case 0x07: // RLCA
+ clock.Add(4);
+ RLCA();
+ break;
+
+ case 0x08: // EX AF, AF'
+ clock.Add(4);
+ Register16 t = AF_;
+ AF_.high = A;
+ AF_.low = (byte)F;
+ A = t.high;
+ F = (Z80Flags)t.low;
+ break;
+
+ case 0x09: // ADD HL, BC
+ clock.Add(11);
+ ADD16(ref hl.reg, BC.reg);
+ break;
+
+ case 0x0a: // LD A,(BC)
+ clock.Add(7);
+ A = memory.Read(BC.reg);
+ break;
+
+ case 0x0b: // DEC BC
+ clock.Add(6);
+ BC.reg--;
+ break;
+
+ case 0x0c: // INC C
+ clock.Add(4);
+ INC8(ref BC.low);
+ break;
+
+ case 0x0d: // DEC C
+ clock.Add(4);
+ DEC8(ref BC.low);
+ break;
+
+ case 0x0e: // LD C,n
+ clock.Add(7);
+ BC.low = memory.Read(PC++);
+ break;
+
+ case 0x0f: // RRCA
+ clock.Add(4);
+ RRCA();
+ break;
+
+ case 0x10: // DJNZ
+ if (--BC.high == 0)
+ {
+ clock.Add(13);
+ JR();
+ }
+ else
+ {
+ clock.Add(8);
+ PC++;
+ }
+ break;
+
+ case 0x11: // LD DE, nnnn
+ clock.Add(10);
+ DE.reg = FetchWord();
+ break;
+
+ case 0x12: // LD (DE), A
+ clock.Add(7);
+ memory.Write(DE.reg, A);
+ break;
+
+ case 0x13: // INC DE
+ clock.Add(6);
+ DE.reg++;
+ break;
+
+ case 0x14: // INC D
+ clock.Add(4);
+ INC8(ref DE.high);
+ break;
+
+ case 0x15: // DEC D
+ clock.Add(4);
+ DEC8(ref DE.high);
+ break;
+
+ case 0x16: // LD D,n
+ clock.Add(7);
+ DE.high = memory.Read(PC++);
+ break;
+
+ case 0x17: // RLA
+ clock.Add(4);
+ RLA();
+ break;
+
+ case 0x18: // JR
+ clock.Add(12);
+ JR();
+ break;
+
+ case 0x19: // ADD HL, DE
+ clock.Add(11);
+ ADD16(ref hl.reg, DE.reg);
+ break;
+
+ case 0x1a: // LD A,(DE)
+ clock.Add(7);
+ A = memory.Read(DE.reg);
+ break;
+
+ case 0x1b: // DEC DE
+ clock.Add(6);
+ DE.reg--;
+ break;
+
+ case 0x1c: // INC E
+ clock.Add(4);
+ INC8(ref DE.low);
+ break;
+
+ case 0x1d: // DEC E
+ clock.Add(4);
+ DEC8(ref DE.low);
+ break;
+
+ case 0x1e: // LD E,n
+ clock.Add(7);
+ DE.low = memory.Read(PC++);
+ break;
+
+ case 0x1f: // RRA
+ clock.Add(4);
+ RRA();
+ break;
+
+ case 0x20: // JR NZ, r
+ JR_COND(Z80Flags.Zero, Z80Flags.None);
+ break;
+
+ case 0x21: // LD HL, nnnn
+ clock.Add(10);
+ hl.reg = FetchWord();
+ break;
+
+ case 0x22: // LD (nnnn), HL
+ clock.Add(16);
+ addr = FetchWord();
+ memory.Write(addr, hl.low);
+ memory.Write((ushort)(addr + 1), hl.high);
+ break;
+
+ case 0x23: // INC HL
+ clock.Add(6);
+ hl.reg++;
+ break;
+
+ case 0x24: // INC H
+ clock.Add(4);
+ INC8(ref hl.high);
+ break;
+
+ case 0x25: // DEC H
+ clock.Add(4);
+ DEC8(ref hl.high);
+ break;
+
+ case 0x26: // LD H,n
+ clock.Add(7);
+ hl.high = memory.Read(PC++);
+ break;
+
+ case 0x27: // DAA
+ clock.Add(4);
+ DAA();
+ break;
+
+ case 0x28: // JR Z,d
+ JR_COND(Z80Flags.Zero, Z80Flags.Zero);
+ break;
+
+ case 0x29: // ADD HL, HL
+ clock.Add(11);
+ ADD16(ref hl.reg, hl.reg);
+ break;
+
+ case 0x2a: // LD HL,(nnnnn)
+ clock.Add(7);
+ addr = FetchWord();
+ hl.low = memory.Read(addr);
+ hl.high = memory.Read((ushort)(addr + 1));
+ break;
+
+ case 0x2b: // DEC HL
+ clock.Add(6);
+ hl.reg--;
+ break;
+
+ case 0x2c: // INC L
+ clock.Add(4);
+ INC8(ref hl.low);
+ break;
+
+ case 0x2d: // DEC L
+ clock.Add(4);
+ DEC8(ref hl.low);
+ break;
+
+ case 0x2e: // LD L,n
+ clock.Add(7);
+ hl.low = memory.Read(PC++);
+ break;
+
+ case 0x2f: // CPL
+ clock.Add(4);
+ A ^= 0xff;
+ ClearFlag(Z80Flags.Hidden);
+ SetFlag(Z80Flags.HalfCarry | Z80Flags.Neg | H35table[A]);
+ break;
+
+ case 0x30: // JR NC, r
+ JR_COND(Z80Flags.Carry, Z80Flags.None);
+ break;
+
+ case 0x31: // LD SP, nnnn
+ clock.Add(10);
+ SP = FetchWord();
+ break;
+
+ case 0x32: // LD (nnnn), A
+ clock.Add(13);
+ addr = FetchWord();
+ memory.Write(addr, A);
+ break;
+
+ case 0x33: // INC SP
+ clock.Add(6);
+ SP++;
+ break;
+
+ case 0x34: // INC (HL)
+ clock.Add(11);
+ addr = (ushort)(hl.reg + Offset());
+ b = memory.Read(addr);
+ INC8(ref b);
+ memory.Write(addr, b);
+ break;
+
+ case 0x35: // DEC (HL)
+ clock.Add(11);
+ addr = (ushort)(hl.reg + Offset());
+ b = memory.Read(addr);
+ DEC8(ref b);
+ memory.Write(addr, b);
+ break;
+
+ case 0x36: // LD (HL),n
+ clock.Add(10);
+ addr = (ushort)(hl.reg + Offset());
+ memory.Write(addr, memory.Read(PC++));
+ break;
+
+ case 0x37: // SCF
+ clock.Add(4);
+ F = (F & (Z80Flags.Sign | Z80Flags.Zero | Z80Flags.PV))
+ | Z80Flags.Carry
+ | H35table[A];
+ break;
+
+ case 0x38: // JR C,d
+ JR_COND(Z80Flags.Carry, Z80Flags.Carry);
+ break;
+
+ case 0x39: // ADD HL, SP
+ clock.Add(11);
+ ADD16(ref hl.reg, SP);
+ break;
+
+ case 0x3a: // LD A,(nnnnn)
+ clock.Add(13);
+ addr = FetchWord();
+ A = memory.Read(addr);
+ break;
+
+ case 0x3b: // DEC SP
+ clock.Add(6);
+ SP--;
+ break;
+
+ case 0x3c: // INC A
+ clock.Add(4);
+ INC8(ref A);
+ break;
+
+ case 0x2d: // DEC A
+ clock.Add(4);
+ DEC8(ref A);
+ break;
+
+ case 0x3e: // LD A,n
+ clock.Add(7);
+ A = memory.Read(PC++);
+ break;
+
+ case 0x3f: // CCF
+ clock.Add(4);
+
+ if ((F & Z80Flags.Carry) == Z80Flags.Carry)
+ {
+ SetFlag(Z80Flags.HalfCarry);
+ }
+ else
+ {
+ ClearFlag(Z80Flags.HalfCarry);
+ }
+
+ F ^= Z80Flags.Carry;
+ ClearFlag(Z80Flags.Hidden);
+ SetFlag(H35table[A]);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+}
diff --git a/src/Noddybox.Emulation.EightBit/Binary.cs b/src/Noddybox.Emulation.EightBit/Binary.cs
index 0b1928b..59d2752 100644
--- a/src/Noddybox.Emulation.EightBit/Binary.cs
+++ b/src/Noddybox.Emulation.EightBit/Binary.cs
@@ -1,13 +1,4 @@
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
{
diff --git a/src/Noddybox.Emulation.EightBit/ICpu.cs b/src/Noddybox.Emulation.EightBit/ICpu.cs
index dc2f811..4f333bc 100644
--- a/src/Noddybox.Emulation.EightBit/ICpu.cs
+++ b/src/Noddybox.Emulation.EightBit/ICpu.cs
@@ -2,15 +2,6 @@
// 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
{
diff --git a/src/Noddybox.Emulation.EightBit/IDevice.cs b/src/Noddybox.Emulation.EightBit/IDevice.cs
index b8d234a..b5117fb 100644
--- a/src/Noddybox.Emulation.EightBit/IDevice.cs
+++ b/src/Noddybox.Emulation.EightBit/IDevice.cs
@@ -2,15 +2,6 @@
// 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
{
diff --git a/src/Noddybox.Emulation.EightBit/IMemory.cs b/src/Noddybox.Emulation.EightBit/IMemory.cs
index 2aa63d9..43b50cb 100644
--- a/src/Noddybox.Emulation.EightBit/IMemory.cs
+++ b/src/Noddybox.Emulation.EightBit/IMemory.cs
@@ -2,15 +2,6 @@
// 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
{
diff --git a/src/Noddybox.Emulation/Clock.cs b/src/Noddybox.Emulation/Clock.cs
index 0b733cb..178b730 100644
--- a/src/Noddybox.Emulation/Clock.cs
+++ b/src/Noddybox.Emulation/Clock.cs
@@ -2,15 +2,6 @@
// 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
{