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