/*
 *   ops.h
 *
 *   This file is part of Emu48
 *
 *   Copyright (C) 1995 Sebastien Carlier
 *
 */
#pragma warning(disable:4244)

// Fields start and length
static UINT F_s[16] = {0/*P*/,0,2,0,15,3,0,0,0,0,0,0,0,0,0,0};
static UINT F_l[16] = {1,1/*P+1*/,1,3,1,12,2,16,0,0,0,0,0,0,0,5};

#define NFunpack(a, b, f) Nunpack((a)+F_s[f], b, F_l[f])
#define NFread(a, b, f)   Nread((a)+F_s[f], b, F_l[f])
#define NFwrite(a, b, f)  Nwrite((a)+F_s[f], b, F_l[f])
#define NFcopy(a, b, f)   memcpy((a)+F_s[f], (b)+F_s[f], F_l[f])
#define NFxchg(a, b, f)   Nxchg((a)+F_s[f], (b)+F_s[f], F_l[f])
#define NFadd(a, b, f)    Nadd((a)+F_s[f], (b)+F_s[f], F_l[f])
#define NFsub(a, b, f)    Nsub((a)+F_s[f], (b)+F_s[f], F_l[f])
#define NFrsub(a, b, f)   Nrsub((a)+F_s[f], (b)+F_s[f], F_l[f])
#define NFand(a, b, f)    Nand((a)+F_s[f], (b)+F_s[f], F_l[f])
#define NFor(a, b, f)     Nor((a)+F_s[f], (b)+F_s[f], F_l[f])
#define NFzero(a,f)       memset((a)+F_s[f], 0, F_l[f])
#define NFpack(a, f)      Npack((a)+F_s[f], F_l[f])
#define NFinc(a, f)       Ninc((a)+F_s[f], F_l[f])
#define NFdec(a, f)       Ndec((a)+F_s[f], F_l[f])
#define NFnot(a, f)       Nnot((a)+F_s[f], F_l[f])
#define NFneg(a, f)       Nneg((a)+F_s[f], F_l[f])
#define NFsl(a, f)        Nsl((a)+F_s[f], F_l[f])
#define NFsr(a, f)        Nsr((a)+F_s[f], F_l[f])
#define NFsrb(a, f)       Nsrb((a)+F_s[f], F_l[f])
#define NFdbl(a, f)       Ndbl((a)+F_s[f], F_l[f])
#define TFe(a, b, f)      Te((a)+F_s[f], (b)+F_s[f], F_l[f])
#define TFa(a, b, f)      Ta((a)+F_s[f], (b)+F_s[f], F_l[f])
#define TFb(a, b, f)      Tb((a)+F_s[f], (b)+F_s[f], F_l[f])
#define TFz(a, f)         Tz((a)+F_s[f], F_l[f])
#define TFne(a, b, f)     Tne((a)+F_s[f], (b)+F_s[f], F_l[f])
#define TFae(a, b, f)     Tae((a)+F_s[f], (b)+F_s[f], F_l[f])
#define TFbe(a, b, f)     Tbe((a)+F_s[f], (b)+F_s[f], F_l[f])
#define TFnz(a, f)        Tnz((a)+F_s[f], F_l[f])

static __inline void rstkpush(DWORD d)
{
	
	Chipset.rstk[Chipset.rstkp] = d;
	Chipset.rstkp=(Chipset.rstkp+1)&7;
}

static __inline DWORD rstkpop()
{
	DWORD r;
	
	Chipset.rstkp=(Chipset.rstkp-1)&7;
	r = Chipset.rstk[Chipset.rstkp];
	Chipset.rstk[Chipset.rstkp] = 0;
	return r;
}

__inline DWORD Npack(BYTE *a, UINT s)
{
	DWORD r = 0;
	
	while (s--) r = (r<<4)|a[s];
	return r;
}

__inline VOID Nunpack(BYTE *a, DWORD b, UINT s)
{
	UINT i;
	for (i=0; i<s; i++) { a[i] = (BYTE)(b&0xf); b>>=4; }
}

static __inline void Nxchg(BYTE *a, BYTE *b, UINT s)
{
	BYTE X[16];
	
	memcpy(X, b, s);
	memcpy(b, a, s);
	memcpy(a, X, s);
}

static __inline void Ninc(BYTE *a, UINT s)
{
	UINT i;
	
	if (Chipset.mode_dec)
	{
		for (i=0; i<s; i++)
		{
			a[i]++;
			if (a[i]<10) { Chipset.carry=FALSE; return; }
			a[i]-=10;
		}
	}
	else
	{
		for (i=0; i<s; i++)
		{
			a[i]++;
			if (a[i]<16) { Chipset.carry=FALSE; return; }
			a[i]-=16;	
		}
	}
	Chipset.carry=TRUE;
}

static __inline void Nincx(BYTE *a, UINT s)
{
	UINT i;
	
	for (i=0; i<s; i++)
	{
		a[i]++;
		if (a[i]<16) { Chipset.carry=FALSE; return; }
		a[i]-=16;	
	}
	Chipset.carry=TRUE;
}

static __inline void Ndec(BYTE *a, UINT s)
{
	UINT i;
	
	if (Chipset.mode_dec)
	{
		for (i=0; i<s; i++)
		{
			a[i]--;
			if (a[i]<10) { Chipset.carry=FALSE; return; }
			a[i] += 10;
		}
	}
	else
	{
		for (i=0; i<s; i++)
		{
			a[i]--;
			if (a[i]<16) { Chipset.carry=FALSE; return; }
			a[i] += 16;
		}
	}
	Chipset.carry = TRUE;
}

static __inline void Nadd(BYTE *a, BYTE *b, UINT s)
{
	UINT i;
	BYTE c = 0;
	
	if (Chipset.mode_dec)
	{
		for (i=0; i<s; i++)
		{
			a[i] += b[i] + c;
			if (a[i]>=10) { a[i]-=10; c=1; } else c=0;
		}
	}
	else
	{
		for (i=0; i<s; i++)
		{
			a[i] += (BYTE)(b[i]+c);
			if (a[i]>=16) { a[i]-=16; c=1; } else c=0;
		}
	}
	if (c==1)
		Chipset.carry=TRUE;
	else
		Chipset.carry=FALSE;
}

static __inline void Ndbl(BYTE *a, UINT s)
{
	UINT i;
	BYTE b[16];
	BYTE c = 0;
	
	if (Chipset.mode_dec)
	{
		memcpy(b, a, s);
		for (i=0; i<s; i++)
		{
			a[i] += b[i] + c;
			if (a[i]>=10) { a[i]-=10; c=1; } else c=0;
		}
	}
	else
	{
		memcpy(b, a, s);
		for (i=0; i<s; i++)
		{
			a[i] += (BYTE)(b[i]+c);
			if (a[i]>=16) { a[i]-=16; c=1; } else c=0;
		}
	}
	if (c==1)
		Chipset.carry=TRUE;
	else
		Chipset.carry=FALSE;
}

static __inline void Nsub(BYTE *a, BYTE *b, UINT s)
{
	UINT i;
	BYTE c = 0;
	
	if (Chipset.mode_dec)
	{
		for (i=0; i<s; i++)
		{
			a[i] -= (BYTE)(b[i]+c);
			if (a[i]>=10) { a[i]+=10; c=1; } else c=0;
		}
	}
	else
	{
		for (i=0; i<s; i++)
		{
			a[i] -= (BYTE)(b[i]+c);
			if (a[i]>=16) { a[i]+=16; c=1; } else c=0;
		}
	}
	if (c==1)
		Chipset.carry=TRUE;
	else
		Chipset.carry=FALSE;
}

static __inline void Nrsub(BYTE *a, BYTE *b, UINT s)
{
	UINT i;
	BYTE c = 0;
	
	if (Chipset.mode_dec)
	{
		for (i=0; i<s; i++)
		{
			a[i] = (BYTE)(b[i]-(a[i]+c));
			if (a[i]>=10) { a[i]+=10; c=1; } else c=0;
		}
	}
	else
	{
		for (i=0; i<s; i++)
		{
			a[i] = (BYTE)(b[i]-(a[i]+c));
			if (a[i]>=16) { a[i]+=16; c=1; } else c=0;
		}
	}
	if (c==1)
		Chipset.carry=TRUE;
	else
		Chipset.carry=FALSE;
}

static __inline void Nand(BYTE *a, BYTE *b, UINT s)
{
	while (s--) a[s]&=b[s];
}

static __inline void Nor(BYTE *a, BYTE *b, UINT s)
{
	while (s--) a[s]|=b[s];
}

static __inline void Nnot(BYTE *a, UINT s)
{ 
	if (Chipset.mode_dec)
		while (s--) (BYTE)(a[s]=9-a[s]);
	else
		while (s--) (BYTE)(a[s]=15-a[s]);
	Chipset.carry = FALSE;
}

static __inline void Nneg(BYTE *a, UINT s)
{
	UINT i;
	
	for (i=0; i<s; i++) if (a[i]) break;
	if (i==s)
	{ // it was 0
		Chipset.carry=FALSE;
		return;
	}
	Chipset.carry=TRUE;
	if (Chipset.mode_dec)
	{
		a[i] = (BYTE)(10-a[i]); /* first non-zero */
		for (i++; i<s; i++) a[i]=(BYTE)(9-a[i]);
	}
	else
	{
		a[i] = (BYTE)(16-a[i]); /* first non-zero */
		for (i++; i<s; i++) a[i]=(BYTE)(15-a[i]);
	}
}

static __inline void Nsl(BYTE *a, UINT s)
{
	
	while (--s) a[s]=a[s-1];
	(*a)=0;
}

static __inline void Nslc(BYTE *a, UINT s)
{
	BYTE c;
	
	c = a[s-1];
	while (--s) a[s] = a[s-1];
	*a = c;
}

static __inline void Nsr(BYTE *a, UINT s)
{

	if (*a) Chipset.HST|=SB;
	while (--s) { (*a)=a[1]; a++; }
	(*a)=0;
}

static __inline void Nsrc(BYTE *a, UINT s)
{
	BYTE c = *a;
	
	while (--s) { *a=a[1]; a++; }
	*a = c;
}

static __inline void Nsrb(BYTE *a, UINT s)
{
	
	if ((*a)&1) Chipset.HST|=SB;
	while (--s)
	{
		(*a)>>=1;
		if (a[1]&1) (*a)|=8;
		a++;
	}
	*a>>=1;
}

static __inline void Nbit0(BYTE *a, UINT b)
{
	a[b>>2]&=~(1<<(b&3));
}

static __inline void Nbit1(BYTE *a, UINT b)
{
	a[b>>2]|=1<<(b&3);
}

static __inline void Tbit0(BYTE *a, UINT b)
{
	if (a[b>>2]&(1<<(b&3)))
		Chipset.carry = FALSE;
	else
		Chipset.carry = TRUE;
}

static __inline void Tbit1(BYTE *a, UINT b)
{
	if (a[b>>2]&(1<<(b&3)))
		Chipset.carry = TRUE;
	else
		Chipset.carry = FALSE;
}

static __inline void Te(BYTE *a, BYTE *b, UINT s)
{
	while (s--)
	{
		if (a[s]!=b[s])
		{
			Chipset.carry = FALSE;
			return;
		}
	}
	Chipset.carry = TRUE;
}

static __inline void Tne(BYTE *a, BYTE *b, UINT s)
{
	while (s--)
	{
		if (a[s]!=b[s])
		{
			Chipset.carry = TRUE;
			return;
		}
	}
	Chipset.carry = FALSE;
}

static __inline void Tz(BYTE *a, UINT s)
{
	while (s--)
	{
		if (a[s]!=0)
		{
			Chipset.carry = FALSE;
			return;
		}
	}
	Chipset.carry = TRUE;
}

static __inline void Tnz(BYTE *a, UINT s)
{
	while (s--)
	{
		if (a[s]!=0)
		{
			Chipset.carry = TRUE;
			return;
		}
	}
	Chipset.carry = FALSE;
}

static __inline void Ta(BYTE *a, BYTE *b, UINT s)
{
	while (--s) if (a[s]!=b[s]) break;
	if (a[s]>b[s])
		Chipset.carry = TRUE;
	else
		Chipset.carry = FALSE;
}

static __inline void Tb(BYTE *a, BYTE *b, UINT s)
{
	while (--s) if (a[s]!=b[s]) break;
	if (a[s]<b[s])
		Chipset.carry = TRUE;
	else
		Chipset.carry = FALSE;
}

static __inline void Tae(BYTE *a, BYTE *b, UINT s)
{
	while (--s) if (a[s]!=b[s]) break;
	if (a[s]>=b[s])
		Chipset.carry = TRUE;
	else
		Chipset.carry = FALSE;
}

static __inline void Tbe(BYTE *a, BYTE *b, UINT s)
{
	while (--s) if (a[s]!=b[s]) break;
	if (a[s]<=b[s])
		Chipset.carry = TRUE;
	else
		Chipset.carry = FALSE;
}
