summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs80
-rw-r--r--src/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs17
-rw-r--r--src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs983
-rw-r--r--src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeCB.cs18
-rw-r--r--src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeED.cs18
-rw-r--r--src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeShiftedCB.cs19
6 files changed, 1121 insertions, 14 deletions
diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs
index 0717ef5..13e8582 100644
--- a/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs
+++ b/src/Noddybox.Emulation.EightBit.Z80/Z80Cpu.cs
@@ -67,16 +67,75 @@ namespace Noddybox.Emulation.EightBit.Z80
// Auxilliary registers and flags
//
- private byte I;
+ private ushort I;
private byte R;
private bool IFF1;
private bool IFF2;
+ private bool raise;
+ private bool nmi;
+ private byte devbyte;
private int IM;
private bool HALT;
private int shift;
#endregion
+ #region Private members
+
+ private void CheckInterrupts()
+ {
+ if (raise)
+ {
+ if (nmi)
+ {
+ if (HALT)
+ {
+ HALT = false;
+ PC++;
+ }
+
+ clock.Add(2);
+ IFF1 = false;
+ nmi = false;
+ PUSH(PC);
+ PC = 0x66;
+ }
+ else if (IFF1)
+ {
+ if (HALT)
+ {
+ HALT = false;
+ PC++;
+ }
+
+ clock.Add(2);
+ IFF1 = false;
+ IFF2 = false;
+
+ switch(IM)
+ {
+ case 1:
+ PUSH(PC);
+ PC = 0x38;
+ break;
+
+ case 2:
+ PUSH(PC);
+ PC = (ushort)((I << 8) + devbyte);
+ break;
+
+ default:
+ DecodeByte(devbyte);
+ break;
+ }
+ }
+
+ raise = false;
+ }
+ }
+
+ #endregion
+
#region ICpu Members
public void Initialise(IMemory memory, IDevice device, Clock clock)
@@ -114,11 +173,17 @@ namespace Noddybox.Emulation.EightBit.Z80
R = 0;
HALT = false;
shift = 0;
+ raise = false;
+ nmi = false;
+ devbyte = 0;
}
public void Step()
{
- // TODO: Single step.
+ CheckInterrupts();
+ AddR(1);
+ shift = 0;
+ DecodeByte(memory.Read(PC++));
}
public void Run()
@@ -131,16 +196,15 @@ namespace Noddybox.Emulation.EightBit.Z80
public void MaskableInterrupt(byte value)
{
- clock.Add(2);
-
- // TODO: INT
+ raise = true;
+ devbyte = value;
+ nmi = false;
}
public void NonMaskableInterrupt(byte value)
{
- clock.Add(2);
-
- // TODO: NMI
+ raise = true;
+ nmi = true;
}
#endregion
diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs
index 378fd05..3c37561 100644
--- a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs
+++ b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs
@@ -54,7 +54,7 @@ namespace Noddybox.Emulation.EightBit.Z80
#endregion
- #region Status register helpers
+ #region Status/special register helpers
/// <summary>
/// Set a flag in the status register.
@@ -74,6 +74,15 @@ namespace Noddybox.Emulation.EightBit.Z80
F &= ~flag;
}
+ /// <summary>
+ /// Add a value to the R (refresh) register.
+ /// </summary>
+ /// <param name="v">The value.</param>
+ private void AddR(byte v)
+ {
+ R = (byte)((R & 0x80) | (R + v) & 0x7f);
+ }
+
#endregion
#region Stack commands
@@ -181,7 +190,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 CP(byte b)
{
int w = A - b;
@@ -825,7 +834,7 @@ namespace Noddybox.Emulation.EightBit.Z80
Z80Flags c = F & Z80Flags.Carry;
byte b = memory.Read(HL.reg);
- CMP8(b);
+ CP(b);
F |= c;
HL.reg++;
@@ -849,7 +858,7 @@ namespace Noddybox.Emulation.EightBit.Z80
Z80Flags c = F & Z80Flags.Carry;
byte b = memory.Read(HL.reg);
- CMP8(b);
+ CP(b);
F |= c;
HL.reg--;
diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs
index 4a747e1..65de984 100644
--- a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs
+++ b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs
@@ -11,7 +11,7 @@ namespace Noddybox.Emulation.EightBit.Z80
/// Decode and execute an opcode.
/// </summary>
/// <param name="opcode">The opcode.</param>
- private void Decode(byte opcode)
+ private void DecodeByte(byte opcode)
{
// Check for shifted opcodes
//
@@ -372,7 +372,7 @@ namespace Noddybox.Emulation.EightBit.Z80
INC8(ref A);
break;
- case 0x2d: // DEC A
+ case 0x3d: // DEC A
clock.Add(4);
DEC8(ref A);
break;
@@ -399,6 +399,985 @@ namespace Noddybox.Emulation.EightBit.Z80
SetFlag(H35table[A]);
break;
+ case 0x40: // LD B,B
+ clock.Add(4);
+ break;
+
+ case 0x41: // LD B,C
+ clock.Add(4);
+ BC.high = BC.low;
+ break;
+
+ case 0x42: // LD B,D
+ clock.Add(4);
+ BC.high = DE.high;
+ break;
+
+ case 0x43: // LD B,E
+ clock.Add(4);
+ BC.high = DE.low;
+ break;
+
+ case 0x44: // LD B,H
+ clock.Add(4);
+ BC.high = hl.high;
+ break;
+
+ case 0x45: // LD B,L
+ clock.Add(4);
+ BC.high = hl.low;
+ break;
+
+ case 0x46: // LD B,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ BC.high = memory.Read(addr);
+ break;
+
+ case 0x47: // LD B,A
+ clock.Add(4);
+ BC.high = A;
+ break;
+
+ case 0x48: // LD C,B
+ clock.Add(4);
+ BC.low = BC.high;
+ break;
+
+ case 0x49: // LD C,C
+ clock.Add(4);
+ break;
+
+ case 0x4a: // LD C,D
+ clock.Add(4);
+ BC.low = DE.high;
+ break;
+
+ case 0x4b: // LD C,E
+ clock.Add(4);
+ BC.low = DE.low;
+ break;
+
+ case 0x4c: // LD C,H
+ clock.Add(4);
+ BC.low = hl.high;
+ break;
+
+ case 0x4d: // LD C,L
+ clock.Add(4);
+ BC.low = hl.low;
+ break;
+
+ case 0x4e: // LD C,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ BC.low = memory.Read(addr);
+ break;
+
+ case 0x4f: // LD C,A
+ clock.Add(4);
+ BC.low = A;
+ break;
+
+ case 0x50: // LD D,B
+ clock.Add(4);
+ DE.high = BC.high;
+ break;
+
+ case 0x51: // LD D,C
+ clock.Add(4);
+ DE.high = BC.low;
+ break;
+
+ case 0x52: // LD D,D
+ clock.Add(4);
+ break;
+
+ case 0x53: // LD D,E
+ clock.Add(4);
+ DE.high = DE.low;
+ break;
+
+ case 0x54: // LD D,H
+ clock.Add(4);
+ DE.high = hl.high;
+ break;
+
+ case 0x55: // LD D,L
+ clock.Add(4);
+ DE.high = hl.low;
+ break;
+
+ case 0x56: // LD D,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ DE.high = memory.Read(addr);
+ break;
+
+ case 0x57: // LD D,A
+ clock.Add(4);
+ DE.high = A;
+ break;
+
+ case 0x58: // LD E,B
+ clock.Add(4);
+ DE.low = BC.high;
+ break;
+
+ case 0x59: // LD E,C
+ clock.Add(4);
+ DE.low = BC.low;
+ break;
+
+ case 0x5a: // LD E,D
+ clock.Add(4);
+ DE.low = DE.high;
+ break;
+
+ case 0x5b: // LD E,E
+ clock.Add(4);
+ break;
+
+ case 0x5c: // LD E,H
+ clock.Add(4);
+ DE.low = hl.high;
+ break;
+
+ case 0x5d: // LD E,L
+ clock.Add(4);
+ DE.low = hl.low;
+ break;
+
+ case 0x5e: // LD E,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ DE.low = memory.Read(addr);
+ break;
+
+ case 0x5f: // LD E,A
+ clock.Add(4);
+ DE.low = A;
+ break;
+
+ case 0x60: // LD H,B
+ clock.Add(4);
+ hl.high = BC.high;
+ break;
+
+ case 0x61: // LD H,C
+ clock.Add(4);
+ hl.high = BC.low;
+ break;
+
+ case 0x62: // LD H,D
+ clock.Add(4);
+ hl.high = DE.high;
+ break;
+
+ case 0x63: // LD H,E
+ clock.Add(4);
+ hl.high = DE.low;
+ break;
+
+ case 0x64: // LD H,H
+ clock.Add(4);
+ break;
+
+ case 0x65: // LD H,L
+ clock.Add(4);
+ hl.high = hl.low;
+ break;
+
+ case 0x66: // LD H,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ HL.high = memory.Read(addr);
+ break;
+
+ case 0x67: // LD H,A
+ clock.Add(4);
+ hl.high = A;
+ break;
+
+ case 0x68: // LD L,B
+ clock.Add(4);
+ hl.low = BC.high;
+ break;
+
+ case 0x69: // LD L,C
+ clock.Add(4);
+ hl.low = BC.low;
+ break;
+
+ case 0x6a: // LD L,D
+ clock.Add(4);
+ hl.low = DE.high;
+ break;
+
+ case 0x6b: // LD L,E
+ clock.Add(4);
+ hl.low = DE.low;
+ break;
+
+ case 0x6c: // LD L,H
+ clock.Add(4);
+ hl.low = hl.high;
+ break;
+
+ case 0x6d: // LD L,L
+ clock.Add(4);
+ break;
+
+ case 0x6e: // LD L,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ HL.low = memory.Read(addr);
+ break;
+
+ case 0x6f: // LD L,A
+ clock.Add(4);
+ hl.low = A;
+ break;
+
+ case 0x70: // LD (HL),B
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ memory.Write(addr, BC.high);
+ break;
+
+ case 0x71: // LD (HL),C
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ memory.Write(addr, BC.low);
+ break;
+
+ case 0x72: // LD (HL),D
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ memory.Write(addr, DE.high);
+ break;
+
+ case 0x73: // LD (HL),E
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ memory.Write(addr, DE.low);
+ break;
+
+ case 0x74: // LD (HL),H
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ memory.Write(addr, HL.high);
+ break;
+
+ case 0x75: // LD (HL),L
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ memory.Write(addr, HL.low);
+ break;
+
+ case 0x76: // HALT
+ clock.Add(4);
+ PC--;
+ HALT = true;
+ break;
+
+ case 0x77: // LD (HL),A
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ memory.Write(addr, A);
+ break;
+
+ case 0x78: // LD A,B
+ clock.Add(4);
+ A = BC.high;
+ break;
+
+ case 0x79: // LD A,C
+ clock.Add(4);
+ A = BC.low;
+ break;
+
+ case 0x7a: // LD A,D
+ clock.Add(4);
+ A = DE.high;
+ break;
+
+ case 0x7b: // LD A,E
+ clock.Add(4);
+ A = DE.low;
+ break;
+
+ case 0x7c: // LD A,H
+ clock.Add(4);
+ A = hl.high;
+ break;
+
+ case 0x7d: // LD A,L
+ clock.Add(4);
+ A = hl.low;
+ break;
+
+ case 0x7e: // LD A,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ HL.low = memory.Read(addr);
+ break;
+
+ case 0x7f: // LD A,A
+ clock.Add(4);
+ break;
+
+ case 0x80: // ADD A,B
+ clock.Add(4);
+ ADD8(BC.high);
+ break;
+
+ case 0x81: // ADD A,C
+ clock.Add(4);
+ ADD8(BC.low);
+ break;
+
+ case 0x82: // ADD A,D
+ clock.Add(4);
+ ADD8(DE.high);
+ break;
+
+ case 0x83: // ADD A,E
+ clock.Add(4);
+ ADD8(DE.low);
+ break;
+
+ case 0x84: // ADD A,H
+ clock.Add(4);
+ ADD8(hl.high);
+ break;
+
+ case 0x85: // ADD A,L
+ clock.Add(4);
+ ADD8(hl.low);
+ break;
+
+ case 0x86: // ADD A,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ ADD8(memory.Read(addr));
+ break;
+
+ case 0x87: // ADD A,A
+ clock.Add(4);
+ ADD8(A);
+ break;
+
+ case 0x88: // ADC A,B
+ clock.Add(4);
+ ADC8(BC.high);
+ break;
+
+ case 0x89: // ADC A,C
+ clock.Add(4);
+ ADC8(BC.low);
+ break;
+
+ case 0x8a: // ADC A,D
+ clock.Add(4);
+ ADC8(DE.high);
+ break;
+
+ case 0x8b: // ADC A,E
+ clock.Add(4);
+ ADC8(DE.low);
+ break;
+
+ case 0x8c: // ADC A,H
+ clock.Add(4);
+ ADC8(hl.high);
+ break;
+
+ case 0x8d: // ADC A,L
+ clock.Add(4);
+ ADC8(hl.low);
+ break;
+
+ case 0x8e: // ADC A,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ ADC8(memory.Read(addr));
+ break;
+
+ case 0x8f: // ADC A,A
+ clock.Add(4);
+ ADC8(A);
+ break;
+
+ case 0x90: // SUB A,B
+ clock.Add(4);
+ SUB8(BC.high);
+ break;
+
+ case 0x91: // SUB A,C
+ clock.Add(4);
+ SUB8(BC.low);
+ break;
+
+ case 0x92: // SUB A,D
+ clock.Add(4);
+ SUB8(DE.high);
+ break;
+
+ case 0x93: // SUB A,E
+ clock.Add(4);
+ SUB8(DE.low);
+ break;
+
+ case 0x94: // SUB A,H
+ clock.Add(4);
+ SUB8(hl.high);
+ break;
+
+ case 0x95: // SUB A,L
+ clock.Add(4);
+ SUB8(hl.low);
+ break;
+
+ case 0x96: // SUB A,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ SUB8(memory.Read(addr));
+ break;
+
+ case 0x97: // SUB A,A
+ clock.Add(4);
+ SUB8(A);
+ break;
+
+ case 0x98: // SBC A,B
+ clock.Add(4);
+ SBC8(BC.high);
+ break;
+
+ case 0x99: // SBC A,C
+ clock.Add(4);
+ SBC8(BC.low);
+ break;
+
+ case 0x9a: // SBC A,D
+ clock.Add(4);
+ SBC8(DE.high);
+ break;
+
+ case 0x9b: // SBC A,E
+ clock.Add(4);
+ SBC8(DE.low);
+ break;
+
+ case 0x9c: // SBC A,H
+ clock.Add(4);
+ SBC8(hl.high);
+ break;
+
+ case 0x9d: // SBC A,L
+ clock.Add(4);
+ SBC8(hl.low);
+ break;
+
+ case 0x9e: // SBC A,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ SBC8(memory.Read(addr));
+ break;
+
+ case 0x9f: // SBC A,A
+ clock.Add(4);
+ SBC8(A);
+ break;
+
+ case 0xa0: // AND A,B
+ clock.Add(4);
+ AND(BC.high);
+ break;
+
+ case 0xa1: // AND A,C
+ clock.Add(4);
+ AND(BC.low);
+ break;
+
+ case 0xa2: // AND A,D
+ clock.Add(4);
+ AND(DE.high);
+ break;
+
+ case 0xa3: // AND A,E
+ clock.Add(4);
+ AND(DE.low);
+ break;
+
+ case 0xa4: // AND A,H
+ clock.Add(4);
+ AND(hl.high);
+ break;
+
+ case 0xa5: // AND A,L
+ clock.Add(4);
+ AND(hl.low);
+ break;
+
+ case 0xa6: // AND A,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ AND(memory.Read(addr));
+ break;
+
+ case 0xa7: // AND A,A
+ clock.Add(4);
+ AND(A);
+ break;
+
+ case 0xa8: // XOR A,B
+ clock.Add(4);
+ XOR(BC.high);
+ break;
+
+ case 0xa9: // XOR A,C
+ clock.Add(4);
+ XOR(BC.low);
+ break;
+
+ case 0xaa: // XOR A,D
+ clock.Add(4);
+ XOR(DE.high);
+ break;
+
+ case 0xab: // XOR A,E
+ clock.Add(4);
+ XOR(DE.low);
+ break;
+
+ case 0xac: // XOR A,H
+ clock.Add(4);
+ XOR(hl.high);
+ break;
+
+ case 0xad: // XOR A,L
+ clock.Add(4);
+ XOR(hl.low);
+ break;
+
+ case 0xae: // XOR A,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ XOR(memory.Read(addr));
+ break;
+
+ case 0xaf: // XOR A,A
+ clock.Add(4);
+ XOR(A);
+ break;
+
+ case 0xb0: // OR A,B
+ clock.Add(4);
+ OR(BC.high);
+ break;
+
+ case 0xb1: // OR A,C
+ clock.Add(4);
+ OR(BC.low);
+ break;
+
+ case 0xb2: // OR A,D
+ clock.Add(4);
+ OR(DE.high);
+ break;
+
+ case 0xb3: // OR A,E
+ clock.Add(4);
+ OR(DE.low);
+ break;
+
+ case 0xb4: // OR A,H
+ clock.Add(4);
+ OR(hl.high);
+ break;
+
+ case 0xb5: // OR A,L
+ clock.Add(4);
+ OR(hl.low);
+ break;
+
+ case 0xb6: // OR A,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ OR(memory.Read(addr));
+ break;
+
+ case 0xb7: // OR A,A
+ clock.Add(4);
+ OR(A);
+ break;
+
+ case 0xb8: // CP A,B
+ clock.Add(4);
+ CP(BC.high);
+ break;
+
+ case 0xb9: // CP A,C
+ clock.Add(4);
+ CP(BC.low);
+ break;
+
+ case 0xba: // CP A,D
+ clock.Add(4);
+ CP(DE.high);
+ break;
+
+ case 0xbb: // CP A,E
+ clock.Add(4);
+ CP(DE.low);
+ break;
+
+ case 0xbc: // CP A,H
+ clock.Add(4);
+ CP(hl.high);
+ break;
+
+ case 0xbd: // CP A,L
+ clock.Add(4);
+ CP(hl.low);
+ break;
+
+ case 0xbe: // CP A,(HL)
+ clock.Add(7);
+ addr = (ushort)(hl.reg + Offset());
+ CP(memory.Read(addr));
+ break;
+
+ case 0xbf: // CP A,A
+ clock.Add(4);
+ CP(A);
+ break;
+
+ case 0xc0: // RET NZ
+ RET_COND(Z80Flags.Zero, Z80Flags.None);
+ break;
+
+ case 0xc1: // POP BC
+ clock.Add(10);
+ BC.reg = POP();
+ break;
+
+ case 0xc2: // JP NZ,nnnn
+ JP_COND(Z80Flags.Zero, Z80Flags.None);
+ break;
+
+ case 0xc3: // JP nnnn
+ clock.Add(10);
+ JP();
+ break;
+
+ case 0xc4: // CALL NZ,nnnn
+ CALL_COND(Z80Flags.Zero, Z80Flags.None);
+ break;
+
+ case 0xc5: // PUSH BC
+ clock.Add(10);
+ PUSH(BC.reg);
+ break;
+
+ case 0xc6: // ADD A,n
+ clock.Add(7);
+ ADD8(memory.Read(PC++));
+ break;
+
+ case 0xc7: // RST 0
+ RST(0);
+ break;
+
+ case 0xc8: // RET Z
+ RET_COND(Z80Flags.Zero, Z80Flags.Zero);
+ break;
+
+ case 0xc9: // RET
+ clock.Add(10);
+ SP = POP();
+ break;
+
+ case 0xca: // JP Z,nnnn
+ JP_COND(Z80Flags.Zero, Z80Flags.Zero);
+ break;
+
+ case 0xcb: // CB shift
+ AddR(1);
+
+ // Check for IX/IY shift
+ //
+ if (shift != 0)
+ {
+ if (shift == 0xdd)
+ {
+ addr = (ushort)(IX.reg + Offset());
+ }
+ else
+ {
+ addr = (ushort)(IY.reg + Offset());
+ }
+
+ DecodeShiftedCB(memory.Read(PC++), addr);
+ }
+ else
+ {
+ DecodeCB(memory.Read(PC++));
+ }
+ break;
+
+ case 0xcc: // CALL Z,nnnn
+ CALL_COND(Z80Flags.Zero, Z80Flags.Zero);
+ break;
+
+ case 0xcd: // CALL nnnn
+ clock.Add(17);
+ CALL();
+ break;
+
+ case 0xce: // ADC A,n
+ clock.Add(7);
+ ADC8(memory.Read(PC++));
+ break;
+
+ case 0xcf: // RST 8
+ RST(8);
+ break;
+
+ case 0xd0: // RET NC
+ RET_COND(Z80Flags.Carry, Z80Flags.None);
+ break;
+
+ case 0xd1: // POP DE
+ clock.Add(10);
+ DE.reg = POP();
+ break;
+
+ case 0xd2: // JP NC,nnnn
+ JP_COND(Z80Flags.Carry, Z80Flags.None);
+ break;
+
+ case 0xd3: // OUT(n),A
+ clock.Add(11);
+ addr = memory.Read(PC++);
+ addr |= (ushort)(A << 8);
+ device.Write(addr, A);
+ break;
+
+ case 0xd4: // CALL NC,nnnn
+ CALL_COND(Z80Flags.Carry, Z80Flags.None);
+ break;
+
+ case 0xd5: // PUSH DE
+ clock.Add(10);
+ PUSH(DE.reg);
+ break;
+
+ case 0xd6: // SUB A,n
+ clock.Add(7);
+ SUB8(memory.Read(PC++));
+ break;
+
+ case 0xd7: // RST 10
+ RST(0x10);
+ break;
+
+ case 0xd8: // RET C
+ RET_COND(Z80Flags.Carry, Z80Flags.Carry);
+ break;
+
+ case 0xd9: // EXX
+ clock.Add(4);
+ Swap(ref BC, ref BC_);
+ Swap(ref DE, ref DE_);
+ Swap(ref HL, ref HL_);
+ break;
+
+ case 0xda: // JP C,nnnn
+ JP_COND(Z80Flags.Carry, Z80Flags.Carry);
+ break;
+
+ case 0xdb: // IN A,(n)
+ clock.Add(11);
+ addr = memory.Read(PC++);
+ addr |= (ushort)(A << 8);
+ A = device.Read(addr);
+ break;
+
+ case 0xdc: // CALL C,nnnn
+ CALL_COND(Z80Flags.Carry, Z80Flags.Carry);
+ break;
+
+ case 0xdd: // DD (IX) PREFIX
+ AddR(1);
+ clock.Add(4);
+ shift = opcode;
+ DecodeByte(memory.Read(PC++));
+ break;
+
+ case 0xde: // SBC A,n
+ clock.Add(7);
+ SBC8(memory.Read(PC++));
+ break;
+
+ case 0xdf: // RST 18
+ RST(0x18);
+ break;
+
+ case 0xe0: // RET PO
+ RET_COND(Z80Flags.PV, Z80Flags.None);
+ break;
+
+ case 0xe1: // POP HL
+ clock.Add(10);
+ hl.reg = POP();
+ break;
+
+ case 0xe2: // JP PO,nnnn
+ JP_COND(Z80Flags.PV, Z80Flags.None);
+ break;
+
+ case 0xe3: // EX (SP),HL
+ clock.Add(19);
+ addr = POP();
+ PUSH(hl.reg);
+ hl.reg = addr;
+ break;
+
+ case 0xe4: // CALL PO,nnnn
+ CALL_COND(Z80Flags.PV, Z80Flags.None);
+ break;
+
+ case 0xe5: // PUSH HL
+ clock.Add(10);
+ PUSH(hl.reg);
+ break;
+
+ case 0xe6: // AND A,n
+ clock.Add(7);
+ AND(memory.Read(PC++));
+ break;
+
+ case 0xe7: // RST 20
+ RST(0x20);
+ break;
+
+ case 0xe8: // RET PE
+ RET_COND(Z80Flags.PV, Z80Flags.PV);
+ break;
+
+ case 0xe9: // JP (HL)
+ clock.Add(4);
+ PC = hl.reg;
+ break;
+
+ case 0xea: // JP PE,nnnn
+ JP_COND(Z80Flags.PV, Z80Flags.PV);
+ break;
+
+ case 0xeb: // EX DE,HL
+ clock.Add(4);
+ Swap(ref DE, ref hl);
+ break;
+
+ case 0xec: // CALL PE,nnnn
+ CALL_COND(Z80Flags.PV, Z80Flags.PV);
+ break;
+
+ case 0xed: // ED PREFIX
+ AddR(1);
+ DecodeED(memory.Read(PC++));
+ break;
+
+ case 0xee: // XOR A,n
+ clock.Add(7);
+ XOR(memory.Read(PC++));
+ break;
+
+ case 0xef: // RST 28
+ RST(0x28);
+ break;
+
+ case 0xf0: // RET P
+ RET_COND(Z80Flags.Sign, Z80Flags.None);
+ break;
+
+ case 0xf1: // POP AF
+ clock.Add(10);
+ addr = POP();
+ A = (byte)(addr >> 8);
+ F = (Z80Flags)(addr & 0xff);
+ break;
+
+ case 0xf2: // JP P,nnnn
+ JP_COND(Z80Flags.Sign, Z80Flags.None);
+ break;
+
+ case 0xf3: // DI
+ clock.Add(4);
+ IFF1 = false;
+ IFF2 = false;
+ break;
+
+ case 0xf4: // CALL P,nnnn
+ CALL_COND(Z80Flags.Sign, Z80Flags.None);
+ break;
+
+ case 0xf5: // PUSH AF
+ clock.Add(10);
+ PUSH((ushort)((A << 8) | (int)(F)));
+ break;
+
+ case 0xf6: // OR A,n
+ clock.Add(7);
+ OR(memory.Read(PC++));
+ break;
+
+ case 0xf7: // RST 30
+ RST(0x30);
+ break;
+
+ case 0xf8: // RET M
+ RET_COND(Z80Flags.Sign, Z80Flags.Sign);
+ break;
+
+ case 0xf9: // LD SP,HL
+ clock.Add(6);
+ SP = hl.reg;
+ break;
+
+ case 0xfa: // JP N,nnnn
+ JP_COND(Z80Flags.Sign, Z80Flags.Sign);
+ break;
+
+ case 0xfb: // EI
+ clock.Add(4);
+ IFF1 = true;
+ IFF2 = true;
+ break;
+
+ case 0xfc: // CALL M,nnnn
+ CALL_COND(Z80Flags.Sign, Z80Flags.Sign);
+ break;
+
+ case 0xfd: // DD (IY) PREFIX
+ AddR(1);
+ clock.Add(4);
+ shift = opcode;
+ DecodeByte(memory.Read(PC++));
+ break;
+
+ case 0xfe: // CP A,n
+ clock.Add(7);
+ CP(memory.Read(PC++));
+ break;
+
+ case 0xff: // RST 38
+ RST(0x18);
+ break;
+
default:
break;
}
diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeCB.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeCB.cs
new file mode 100644
index 0000000..73cb611
--- /dev/null
+++ b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeCB.cs
@@ -0,0 +1,18 @@
+//
+// Copyright (c) 2012 Ian Cowburn
+//
+using System;
+
+namespace Noddybox.Emulation.EightBit.Z80
+{
+ public partial class Z80Cpu
+ {
+ /// <summary>
+ /// Decode and execute a CB-shifted opcode.
+ /// </summary>
+ /// <param name="opcode">The opcode.</param>
+ private void DecodeCB(byte opcode)
+ {
+ }
+ }
+}
diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeED.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeED.cs
new file mode 100644
index 0000000..5d8ec1e
--- /dev/null
+++ b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeED.cs
@@ -0,0 +1,18 @@
+//
+// Copyright (c) 2012 Ian Cowburn
+//
+using System;
+
+namespace Noddybox.Emulation.EightBit.Z80
+{
+ public partial class Z80Cpu
+ {
+ /// <summary>
+ /// Decode and execute a ED-shifted opcode.
+ /// </summary>
+ /// <param name="opcode">The opcode.</param>
+ private void DecodeED(byte opcode)
+ {
+ }
+ }
+}
diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeShiftedCB.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeShiftedCB.cs
new file mode 100644
index 0000000..ad663f3
--- /dev/null
+++ b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeShiftedCB.cs
@@ -0,0 +1,19 @@
+//
+// Copyright (c) 2012 Ian Cowburn
+//
+using System;
+
+namespace Noddybox.Emulation.EightBit.Z80
+{
+ public partial class Z80Cpu
+ {
+ /// <summary>
+ /// Decode and execute a IX/IY CB-shifted opcode.
+ /// </summary>
+ /// <param name="opcode">The opcode.</param>
+ /// <param name="addr">The address to use for indirection.</param>
+ private void DecodeShiftedCB(byte opcode, ushort addr)
+ {
+ }
+ }
+}