c3ab4004ad
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
516 lines
No EOL
9.2 KiB
C
516 lines
No EOL
9.2 KiB
C
/*
|
||
* 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)
|
||
|