From f96332b0913a8a365db73a1af3443c0e225a23d8 Mon Sep 17 00:00:00 2001 From: Ian C Date: Thu, 29 Dec 2011 00:17:13 +0000 Subject: Development check-in. --- .../Z80CpuBaseOpcodes.cs | 333 +++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs (limited to 'Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs') diff --git a/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs b/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs new file mode 100644 index 0000000..c42c163 --- /dev/null +++ b/Noddybox.Emulation.EightBit.Z80/Z80CpuBaseOpcodes.cs @@ -0,0 +1,333 @@ +// +// 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 Stack commands + + /// + /// Push a value on the stack. + /// + /// The value. + private void Push(ushort val) + { + unchecked + { + memory.Write(--SP, val & 0xff); + memory.Write(--SP, Binary.ShiftRight(val, 8) & 0xff); + } + } + + /// + /// Pop a value from the stack. + /// + /// + private ushort Pop() + { + SP = (ushort)((SP + 2) & 0xffff); + return (ushort)(memory.Read(SP-2) | (memory.Read(SP - 1) >> 8)); + } + + #endregion + + #region ALU arithmetic and comparison + + /// + /// Add an 8-bit value to the accumulator without carry. + /// + /// The vakue. + private void Add8(byte b) + { + int w = A + b; + + F = SZtable[w] | H35table[w & 0xff]; + + if (((A ^ w ^ b) & (int)Z80Flags.HalfCarry) == (int)Z80Flags.HalfCarry) + { + F |= Z80Flags.HalfCarry; + } + + if (((b ^ A) & (b ^ w) & 0x80) > 0) + { + F |= Z80Flags.PV; + } + + A = (byte)(w & 0xff); + } + + /// + /// Add an 8-bit value to the accumulator with carry. + /// + /// The vakue. + private void Adc8(byte b) + { + int w = A + b + (int)(F & Z80Flags.Carry); + + F = SZtable[w] | H35table[w & 0xff]; + + if (((A ^ w ^ b) & (int)Z80Flags.HalfCarry) == (int)Z80Flags.HalfCarry) + { + F |= Z80Flags.HalfCarry; + } + + if (((b ^ A) & (b ^ w) & 0x80) > 0) + { + F |= Z80Flags.PV; + } + + A = (byte)(w & 0xff); + } + + /// + /// Subtract an 8-bit value from the accumulator without carry. + /// + /// The vakue. + private void Sub8(byte b) + { + int w = A - b; + + if (w < 0) + { + w += 0x200; + } + + F = SZtable[w] | H35table[w & 0xff] | Z80Flags.Neg; + + if (((A ^ w ^ b) & (int)Z80Flags.HalfCarry) == (int)Z80Flags.HalfCarry) + { + F |= Z80Flags.HalfCarry; + } + + if (((b ^ A) & (b ^ w) & 0x80) > 0) + { + F |= Z80Flags.PV; + } + + A = (byte)(w & 0xff); + } + + /// + /// Compare an 8-bit value with the accumulator. + /// + /// The vakue. + private void Cmp8(byte b) + { + int w = A - b; + + if (w < 0) + { + w += 0x200; + } + + F = SZtable[w] | H35table[w & 0xff] | Z80Flags.Neg; + + if (((A ^ w ^ b) & (int)Z80Flags.HalfCarry) == (int)Z80Flags.HalfCarry) + { + F |= Z80Flags.HalfCarry; + } + + if (((b ^ A) & (b ^ w) & 0x80) > 0) + { + F |= Z80Flags.PV; + } + } + + /// + /// Subtract an 8-bit value from the accumulator with carry. + /// + /// The vakue. + private void Sbc8(byte b) + { + int w = A - b - (int)(F & Z80Flags.Carry); + + if (w < 0) + { + w += 0x200; + } + + F = SZtable[w] | H35table[w & 0xff] | Z80Flags.Neg; + + if (((A ^ w ^ b) & (int)Z80Flags.HalfCarry) == (int)Z80Flags.HalfCarry) + { + F |= Z80Flags.HalfCarry; + } + + if (((b ^ A) & (b ^ w) & 0x80) > 0) + { + F |= Z80Flags.PV; + } + + A = (byte)(w & 0xff); + } + + /// + /// Add a 16-bit value to a register without carry. + /// + /// The vakue. + private void Add16(ref ushort reg, ushort b) + { + int w = reg + b; + + F &= Z80Flags.Sign | Z80Flags.Zero | Z80Flags.PV; + + if (w > 0xffff) + { + F |= Z80Flags.Carry; + } + + if ((reg ^ w ^ b) == 0x1000) + { + F |= Z80Flags.HalfCarry; + } + + reg = (ushort)(w & 0xffff); + + F |= H35table[reg >> 8]; + } + + /// + /// Add a 16-bit value to a register with carry. + /// + /// The vakue. + private void Adc16(ref ushort reg, ushort b) + { + int w = reg + b + (int)(F & Z80Flags.Carry); + + F = Z80Flags.None; + + if ((w & 0xffff) == 0) + { + F |= Z80Flags.Zero; + } + + if ((w & 0x8000) == 0x8000) + { + F |= Z80Flags.Sign; + } + + if (w > 0xffff) + { + F |= Z80Flags.Carry; + } + + if (((b ^ reg ^ 0x8000) & ((reg ^ w) & 0x8000)) == 0x8000) + { + F |= Z80Flags.PV; + } + + if ((reg ^ w ^ b) == 0x1000) + { + F |= Z80Flags.HalfCarry; + } + + reg = (ushort)(w & 0xffff); + + F |= H35table[reg >> 8]; + } + + + /// + /// Subtract a 16-bit value from a register with carry. + /// + /// The vakue. + private void Sbc16(ref ushort reg, ushort b) + { + int w = reg - b - (int)(F & Z80Flags.Carry); + + F = Z80Flags.Neg; + + if (w < 0) + { + w += 0x10000; + F |= Z80Flags.Carry; + } + + if ((w & 0xffff) == 0) + { + F |= Z80Flags.Zero; + } + + if ((w & 0x8000) == 0x8000) + { + F |= Z80Flags.Sign; + } + + if (((b ^ reg) & ((reg ^ w) & 0x8000)) == 0x8000) + { + F |= Z80Flags.PV; + } + + if ((reg ^ w ^ b) == 0x1000) + { + F |= Z80Flags.HalfCarry; + } + + reg = (ushort)(w & 0xffff); + + F |= H35table[reg >> 8]; + } + + /// + /// Increment an 8-bit register. + /// + /// The register to increment. + void Inc8(ref byte reg) + { + unchecked + { + reg++; + } + + F = Z80Flags.Carry; + + if (reg == 0x80) + { + F |= Z80Flags.PV; + } + + if ((reg & 0x0f) == 0x00) + { + F |= Z80Flags.HalfCarry; + } + } + + /// + /// Decrement an 8-bit register. + /// + /// The register to decrement. + void Dec8(ref byte reg) + { + unchecked + { + reg--; + } + + F = Z80Flags.Carry | Z80Flags.Neg; + + if (reg == 0x7f) + { + F |= Z80Flags.PV; + } + + if ((reg & 0x0f) == 0x0f) + { + F |= Z80Flags.HalfCarry; + } + } + + #endregion + } +} -- cgit v1.3