emu48-mirror/INSTR.C
Gwenhael Le Moine c3ab4004ad
1996-02-01: Historic version 0.37
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
2024-03-19 22:11:59 +01:00

516 lines
No EOL
9.2 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 1995 Sebastien Carlier
*/
#include <memory.h>
#include "emu48.h"
#define SIMPLE_DBL 1
#define SIMPLE_XCHG 1
#define FAST_WRITE 1
INLINE long Npack(char *a, int s) {
long r = 0;
while (s--) r = (r<<4)|a[s];
return r;
}
INLINE void Nunpack(char *a, long b, int s) {
int i;
for (i=0; i<s; i++) { a[i] = (char)(b&0xf); b>>=4; }
return;
}
INLINE void Ncopy(char *a, char *b, int s) {
memcpy(a,b,s);
return;
}
INLINE void Nxchg(char *a, char *b, int s) {
#if SIMPLE_XCHG
char X[16];
memcpy(X, b, s);
memcpy(b, a, s);
memcpy(a, X, s);
#else
char t;
while (s--) { t=a[s]; a[s]=b[s]; b[s]=t; }
#endif
return;
}
INLINE void Ninc(char *a, int s) {
int i;
for (i=0; i<s; i++) {
a[i]++;
if (a[i]<MODE) { CARRY = 0; return; }
a[i]-=((char)MODE);
}
CARRY = 1;
return;
}
INLINE void Ndec(char *a, int s) {
int i;
for (i=0; i<s; i++) {
if (a[i]) { a[i]--; CARRY = 0; return; }
a[i] = ((char)MODE)-1;
}
CARRY = 1;
return;
}
INLINE void Nadd(char *a, char *b, int s) {
char carry = 0;
int i;
for (i=0; i<s; i++) {
a[i] += (char)(b[i]+carry);
if (a[i] < MODE)
carry = 0;
else
{ a[i] -= (char)MODE; carry = 1; }
}
CARRY = carry;
return;
}
INLINE void Nsub(char *a, char *b, int s) {
char carry = 0;
int i;
for (i=0; i<s; i++) {
a[i]-=(char)(b[i]+carry);
if (a[i]<0)
{ a[i]+=(char)MODE; carry = 1; }
else
carry = 0;
}
CARRY = carry;
return;
}
INLINE void Nrsub(char *a, char *b, int s) {
char carry = 0;
int i;
for (i=0; i<s; i++) {
a[i]=(char)(b[i]-(a[i]+carry));
if (a[i]<0)
{ a[i]+=(char)MODE; carry = 1; }
else
carry = 0;
}
CARRY = carry;
return;
}
INLINE void Nand(char *a, char *b, int s) {
while (s--) a[s]&=b[s];
return;
}
INLINE void Nor(char *a, char *b, int s) {
while (s--) a[s]|=b[s];
return;
}
INLINE void Nzero(char *a, int s) {
memset(a, 0, s);
return;
}
INLINE void Nnot(char *a, int s) {
char c = ((char)MODE)-1;
while (s--) a[s]=(char)(c-a[s]);
CARRY = 0;
return;
}
INLINE void Nneg(char *a, int s) {
char c = ((char)MODE)-1;
int i;
for (i=0; i<s; i++) if (a[i]) break;
if (i==s) { CARRY=0; return; } /* it was 0 */
CARRY=1;
a[i] = ((char)MODE)-a[i]; /* first non-zero */
for (i++; i<s; i++) a[i]=(char)(c-a[i]);
return;
}
INLINE void Nsl(char *a, int s) {
if (a[s-1])
HST|=SB;
while (--s) a[s]=a[s-1];
(*a)=0;
return;
}
INLINE void Nsr(char *a, int s) {
if (*a) HST|=SB;
while (--s) { (*a)=a[1]; a++; }
(*a)=0;
return;
}
INLINE void Nbit0(char *a, char b) {
a[b>>2]&=~(1<<(b&3));
return;
}
INLINE void Nbit1(char *a, char b) {
a[b>>2]|=1<<(b&3);
return;
}
INLINE void Nslc(char *a, int s) {
char c;
c = a[s-1];
while (--s) a[s] = a[s-1];
*a = c;
return;
}
INLINE void Nsrc(char *a, int s) {
char c = *a;
while (--s) { *a=a[1]; a++; }
*a = c;
return;
}
INLINE void Nsrb(char *a, int s) {
if ((*a)&1) HST|=SB;
while (--s) {
(*a)>>=1;
if (a[1]&1) (*a)|=8;
a++;
}
*a>>=1;
return;
}
INLINE void Ndbl(char *a, int s) {
#if SIMPLE_DBL
char b[16];
memcpy(b, a, s);
Nadd(a, b, s);
#else
char c, carry = 0;
int i;
for (i=0; i<s; i++) {
c = a[i]*2 + carry;
if (c>=MODE)
{ c-=MODE; carry = 1; }
else
carry = 0;
a[i] = c;
}
CARRY = carry;
#endif
return;
}
INLINE void Tbit0(char *a, char b) {
if (a[b>>2]&(1<<(b&3)))
CARRY = 0;
else
CARRY = 1;
return;
}
INLINE void Tbit1(char *a, char b) {
if (a[b>>2]&(1<<(b&3)))
CARRY = 1;
else
CARRY = 0;
return;
}
INLINE void Te(char *a, char *b, int s) {
while (s--) if (a[s]!=b[s]) { CARRY = 0; return; }
CARRY = 1;
return;
}
INLINE void Tne(char *a, char *b, int s) {
while (s--) if (a[s]!=b[s]) { CARRY=1; return; }
CARRY = 0;
return;
}
INLINE void Tz(char *a, int s) {
while (s--) if (a[s]!=0) { CARRY = 0; return; }
CARRY = 1;
return;
}
INLINE void Tnz(char *a, int s) {
while (s--) if (a[s]!=0) { CARRY=1; return; }
CARRY = 0;
return;
}
INLINE void Ta(char *a, char *b, int s) {
while (--s) if (a[s]!=b[s]) break;
CARRY = (a[s]>b[s]);
return;
}
INLINE void Tb(char *a, char *b, int s) {
while (--s) if (a[s]!=b[s]) break;
CARRY = (a[s]<b[s]);
return;
}
INLINE void Tae(char *a, char *b, int s) {
while (--s) if (a[s]!=b[s]) break;
CARRY = (a[s]>=b[s]);
return;
}
INLINE void Tbe(char *a, char *b, int s) {
while (--s) if (a[s]!=b[s]) break;
CARRY = (a[s]<=b[s]);
return;
}
INLINE char read_nibble(long d) {
if (ISMODULE(1, d)) return data[1][d-base[1]];
if (CARDSTATUS&2) if (ISMODULE(3, d)) return data[3][d-base[3]];
if (CARDSTATUS&1) if (ISMODULE(4, d)) return data[4][d-base[4]];
return rom[d];
}
INLINE char* nibble_ptr(long d) {
if (ISMODULE(1, d)) return data[1]+d-base[1];
if (CARDSTATUS&2) if (ISMODULE(3, d)) return data[3]+d-base[3];
if (CARDSTATUS&1) if (ISMODULE(4, d)) return data[4]+d-base[4];
return rom+d;
}
INLINE char read_nibble_crc(long d) {
char n;
if (ISMODULE(0, d)) return read_io(d-base[0]);
if (ISMODULE(1, d)) {n=data[1][d-base[1]];CRC(n);return n;}
if (ISMODULE(2, d)) {bank_switch((int)((d-base[2])/2));return 7;}
if (CARDSTATUS&2) if (ISMODULE(3, d)) {n=data[3][d-base[3]];CRC(n);return n;}
if (CARDSTATUS&1) if (ISMODULE(4, d)) {n=data[4][d-base[4]];CRC(n);return n;}
n=rom[d];
CRC(n);
return n;
}
INLINE void write_nibble(long d, char c) {
#if FAST_WRITE
if (ISMODULE(1, d)) {
if (display.dispon) {
if ((d>=display.start12)&&(d<display.end1)) display_plot1(d, c);
if ((d>=display.start2)&&(d<display.end2)) display_plot2(d, c);
}
data[1][d-base[1]]=c;
return;
}
if (ISMODULE(0, d)) { write_io(d-0x100, c); return; }
#else
if (ISMODULE(0, d)) { write_io(d-0x100, c); return; }
if (ISMODULE(1, d)) {
if (display.dispon) {
if ((d>=display.start12)&&(d<display.end1)) display_plot1(d, c);
if ((d>=display.start2)&&(d<display.end2)) display_plot2(d, c);
}
data[1][d-base[1]]=c;
return;
}
#endif
if (CARDSTATUS&2) if (ISMODULE(3, d)) { data[3][d-base[3]]=c; return; }
if (CARDSTATUS&1) if (ISMODULE(4, d)) { data[4][d-base[4]]=c; return; }
return;
}
INLINE void config() {
int i;
long d;
for (i=0; i<=4; i++)
if (ucfg[i]) break;
if (i==5) return;
d = Npack(C, 5);
switch (i) {
case 0:
data[0] = ioram;
base[0] = d;
size[0] = 0x40;
ucfg[0] = 0;
break;
case 1:
case 2:
case 3:
case 4:
if (ucfg[i]==2) {
base[i] = d;
ucfg[i] = 0;
break;
}
size[i] = 0x100000 - Npack(C, 5);
ucfg[i] = 2;
break;
default:
break;
}
return;
}
INLINE void unconfig() {
int i;
long d;
d = Npack(C, 5);
for (i=0; i<=4; i++)
if (d==base[i]) break;
if (i==5) return;
ucfg[i] = 1;
base[i] = 0;
size[i] = 0;
return;
}
INLINE void reset() {
int i;
for (i=0; i<=4; i++)
ucfg[i] = 1;
return;
}
int chip_id[12] = {
0x00019, 0x00003, 0x00005, 0x00007, 0x00001, 0x00000,
0x00019, 0x000F4, 0x000F6, 0x000F8, 0x000F2, 0x00000
};
INLINE void c_eq_id() {
int i;
long id;
for (i=0; i<=4; i++)
if (ucfg[i]) break;
id = chip_id[(ucfg[i]==2)?(i+6):i];
Nunpack(C, id, 3);
return;
}
INLINE long rstkpop() {
long r;
int t;
t = rstkp;
t--;
t&=7;
rstkp = t;
r = rstk[t];
rstk[t] = 0;
return r;
}
INLINE void rstkpush(long d) {
int t;
t = rstkp;
rstk[t] = d;
t++;
t &= 7;
rstkp = t;
return;
}
INLINE void Nread(char *a, long b, int s) {
int i;
for (i=0; i<s; i++) a[i]=read_nibble(b+i);
return;
}
INLINE void NCread(char *a, long b, int s) {
int i;
for (i=0; i<s; i++) a[i]=read_nibble_crc(b+i);
return;
}
INLINE void Nwrite(char *a, long b, int s) {
int i;
for (i=0; i<s; i++) write_nibble(b+i, a[i]);
return;
}
int F_s[16] = {0/*P*/,0,2,0,15,3,0,0,0,0,0,0,0,0,0,0};
int F_l[16] = {1,0/*P+1*/,1,3,1,12,2,16,0,0,0,0,0,0,0,5};
#define FIELDScl(t,fn) INLINE void t##F##fn(char *a, long b, int f) { t##fn(a+F_s[(int)f],b,F_l[(int)f]); return; }
#define FIELDScc(t,fn) INLINE void t##F##fn(char *a, char *b, int f) { t##fn(a+F_s[(int)f],b+F_s[(int)f],F_l[(int)f]); return; }
#define FIELDSc(t,fn) INLINE void t##F##fn(char *a, int f) { t##fn(a+F_s[(int)f],F_l[(int)f]); return; }
FIELDScl(N,unpack)
FIELDScl(NC,read)
FIELDScl(N,write)
FIELDScc(N,copy)
FIELDScc(N,xchg)
FIELDSc(N,inc)
FIELDSc(N,dec)
FIELDScc(N,add)
FIELDScc(N,sub)
FIELDScc(N,rsub)
FIELDScc(N,and)
FIELDScc(N,or)
FIELDSc(N,zero)
FIELDSc(N,not)
FIELDSc(N,neg)
FIELDSc(N,sr)
FIELDSc(N,sl)
FIELDSc(N,srb)
FIELDSc(N,dbl)
FIELDScc(T,e)
FIELDScc(T,ne)
FIELDSc(T,z)
FIELDSc(T,nz)
FIELDScc(T,a)
FIELDScc(T,ae)
FIELDScc(T,b)
FIELDScc(T,be)