emu48plus-mirror/source/OPS.H
Gwenhael Le Moine edf519e5a1
2013-09-14: Updated to version 53
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
2024-03-20 07:46:28 +01:00

476 lines
9 KiB
C

/*
* ops.h
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#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_l[f], F_s[f])
#define NFdec(a, f) Ndec(a, F_l[f], F_s[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 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 LPBYTE FASTPTR(DWORD d)
{
static BYTE pbyNULL[21];
LPBYTE lpbyPage;
DWORD u, v;
d &= 0xFFFFF; // handle address overflows
u = d >> 12; // page
v = d & 0xFFF; // offset
if ( !(Chipset.IOCfig && ((d & 0xFFFC0) == Chipset.IOBase))
&& RMap[u] != NULL // page valid
&& ( v < 0x1000 - ARRAYSIZEOF(pbyNULL) // complete opcode inside page
// or next page continue linear addressing
|| (RMap[u] + 0x1000 == RMap[(u+1) & (ARRAYSIZEOF(RMap)-1)])
)
)
{
lpbyPage = RMap[u] + v; // full address
}
else
{
lpbyPage = pbyNULL; // memory allocation
Npeek(lpbyPage, d, ARRAYSIZEOF(pbyNULL)); // fill with data (LAHEX + 16 digits = longest opcode)
}
return lpbyPage;
}
static __inline void rstkpush(DWORD d)
{
Chipset.rstk[Chipset.rstkp] = d;
Chipset.rstkp=(Chipset.rstkp+1)&7;
}
static __inline DWORD rstkpop(VOID)
{
DWORD r;
Chipset.rstkp=(Chipset.rstkp-1)&7;
r = Chipset.rstk[Chipset.rstkp];
Chipset.rstk[Chipset.rstkp] = 0;
return r;
}
static __inline DWORD Npack(BYTE *a, UINT s)
{
DWORD r = 0;
while (s--) r = (r<<4)|a[s];
return r;
}
static __inline VOID Nunpack(BYTE *a, DWORD b, UINT s)
{
for (; s>0; --s) { *a++ = (BYTE)(b&0xf); b>>=4; }
}
static __inline QWORD Npack64(BYTE *a, UINT s)
{
QWORD r = 0;
while (s--) r = (r<<4)|a[s];
return r;
}
static __inline VOID Nunpack64(BYTE *a, QWORD 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 d)
{
UINT i;
if (Chipset.mode_dec)
{
BYTE c = 1;
for (i=d; i<s+d; ++i)
{
// no register wrap
_ASSERT(i < ARRAYSIZEOF(((CHIPSET *) NULL)->A));
// illegal number in dec mode
if (a[i] >= 10) a[i] &= 0x7;
a[i] += c;
c = (a[i] >= 10);
if (c) a[i] -= 10;
}
Chipset.carry = (c==1);
}
else
{
for (i=d; i<s+d; ++i)
{
// no register wrap
_ASSERT(i < ARRAYSIZEOF(((CHIPSET *) NULL)->A));
a[i]++;
if (a[i] < 16)
{
Chipset.carry = FALSE;
return;
}
a[i] -= 16;
}
Chipset.carry = TRUE;
}
}
static __inline void Ninc16(BYTE *a, UINT s, UINT d)
{
UINT i;
for (i=d; i<s+d; ++i)
{
a[i&0xf]++;
if (a[i&0xf] < 16)
{
Chipset.carry = FALSE;
return;
}
a[i&0xf] -= 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 d)
{
UINT i;
BYTE cBase = Chipset.mode_dec ? 10 : 16;
for (i=d; i<s+d; ++i)
{
// no register wrap
_ASSERT(i < ARRAYSIZEOF(((CHIPSET *) NULL)->A));
a[i]--;
if ((a[i] & 0xF0) == 0) // check overflow
{
Chipset.carry = FALSE;
return;
}
a[i] += cBase;
}
Chipset.carry = TRUE;
}
static __inline void Ndec16(BYTE *a, UINT s, UINT d)
{
UINT i;
for (i=d; i<s+d; ++i)
{
a[i&0xf]--;
if (a[i&0xf] < 16)
{
Chipset.carry = FALSE;
return;
}
a[i&0xf] += 16;
}
Chipset.carry = TRUE;
}
static __inline void Nadd(BYTE *a, BYTE *b, UINT s)
{
UINT i;
BYTE c = 0;
BYTE cBase = Chipset.mode_dec ? 10 : 16;
for (i=0; i<s; ++i)
{
// illegal number in dec mode
if (a[i] >= cBase) a[i] &= 0x7;
a[i] += b[i] + c;
if (a[i] >= cBase)
{
a[i] -= cBase;
c = 1;
}
else
c = 0;
}
Chipset.carry = (c==1);
}
static __inline void Nsub(BYTE *a, BYTE *b, UINT s)
{
UINT i;
BYTE c = 0;
BYTE cBase = Chipset.mode_dec ? 10 : 16;
for (i=0; i<s; ++i)
{
a[i] = a[i] - b[i] - c;
if ((a[i] & 0xF0) != 0) // check overflow
{
a[i] += cBase;
// illegal number in dec mode
if ((a[i] & 0xF0) != 0) a[i] &= 0x7;
c = 1;
}
else
c = 0;
}
Chipset.carry = (c==1);
}
static __inline void Nrsub(BYTE *a, BYTE *b, UINT s)
{
UINT i;
BYTE c = 0;
BYTE cBase = Chipset.mode_dec ? 10 : 16;
for (i=0; i<s; ++i)
{
a[i] = b[i] - a[i] - c;
if ((a[i] & 0xF0) != 0) // check overflow
{
a[i] += cBase;
// illegal number in dec mode
if ((a[i] & 0xF0) != 0) a[i] &= 0x7;
c = 1;
}
else
c = 0;
}
Chipset.carry = (c==1);
}
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)
{
BYTE cBase = Chipset.mode_dec ? 9 : 15;
while (s--)
{
a[s] = cBase - a[s];
if ((a[s] & 0xF0) != 0) // check overflow (dec mode only)
a[s] &= 0x7;
}
Chipset.carry = FALSE;
}
static __inline void Nneg(BYTE *a, UINT s)
{
UINT i;
for (i=0; i<s && a[i]==0; ++i) { } // search for non-zero digit
if ((Chipset.carry = (i!=s))) // value was non-zero
{
BYTE cBase = Chipset.mode_dec ? 9 : 15;
_ASSERT(a[i] > 0); // check for non-zero digit
for (--a[i]; i<s; ++i)
{
a[i] = cBase - a[i];
if ((a[i] & 0xF0) != 0) // check overflow (dec mode only)
a[i] &= 0x7;
}
}
}
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 = 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;
if (c) Chipset.HST |= SB;
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;
*a |= ((a[1] & 1) << 3);
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)
{
Chipset.carry = ((a[b>>2] & (1<<(b&3))) == 0);
}
static __inline void Tbit1(BYTE *a, UINT b)
{
Chipset.carry = ((a[b>>2] & (1<<(b&3))) != 0);
}
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;
Chipset.carry = (a[s]>b[s]);
}
static __inline void Tb(BYTE *a, BYTE *b, UINT s)
{
while (--s) if (a[s]!=b[s]) break;
Chipset.carry = (a[s]<b[s]);
}
static __inline void Tae(BYTE *a, BYTE *b, UINT s)
{
while (--s) if (a[s]!=b[s]) break;
Chipset.carry = (a[s]>=b[s]);
}
static __inline void Tbe(BYTE *a, BYTE *b, UINT s)
{
while (--s) if (a[s]!=b[s]) break;
Chipset.carry = (a[s]<=b[s]);
}