// // 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 } }