kip/kmx20.c

72 lines
2.1 KiB
C

#include"kmx20.h"
#define A a=pop()
#define AB b=pop(),A
#define DS ((W*)(mem+(MEMSZ-0x800)))
#define RS ((W*)(mem+(MEMSZ-0x400)))
#define SD (RS-DS)
B mem[MEMSZ];
W*dp=DS,*rp=RS,ip;
_ V put(W i){*dp++=i;}
_ V pur(W i){*rp++=i;}
_ V swp(V){W*t;t=dp,dp=rp,rp=t;}
B lob(W i){R mem[i];}
H loh(W i){R lob(i)<<8|lob(i+1);}
W low(W i){R loh(i)<<16|loh(i+2);}
V stb(W i,B b){mem[i]=b;}
V sth(W i,H h){stb(i,h>>8),stb(i+1,h);}
V stw(W i,W w){sth(i,w>>16),sth(i+2,w);}
V vec(W i){Q(0x100<(i=low(i)),pur(ip),ip=i)}
_ W a,b;
_ V np(V){}
_ V ex(V){ip+=0x40001;}
_ V pb(V){put(lob(ip)),ip+=1;}
_ V ph(V){put(loh(ip)),ip+=2;}
_ V pw(V){put(low(ip)),ip+=4;}
_ V pr(V){put(ip+(Bs)lob(ip)),ip+=1;}
_ V fb(V){put(lob(a));}
_ V fh(V){put(loh(a));}
_ V fw(V){put(low(a));}
_ V mb(V){stb(b,a);}
_ V mh(V){sth(b,a);}
_ V mw(V){stw(b,a);}
_ V io(V){ios[b].io(a);}
_ V ii(V){put(ios[a].oi());}
_ V ss(V){pur(a);}
_ V dr(V){(V)a;}
_ V sw(V){put(b),put(a);}
_ V du(V){put(a),put(a);}
_ V ov(V){put(a),put(b),put(a);}
_ V ad(V){put(a+b);}
_ V su(V){put(a-b);}
_ V mu(V){put(a*b);}
_ V di(V){put(a/b),put(a%b);}
_ V an(V){put(a&b);}
_ V or(V){put(a|b);}
_ V xr(V){put(a^b);}
_ V sl(V){put(a<<b);}
_ V sr(V){put(a>>b);}
_ V sa(V){put((Ws)a>>b);}
_ V eq(V){put(a==b);}
_ V lt(V){put(a<b);}
_ V gt(V){put(a>b);}
_ V no(V){put(!a);}
_ V ju(V){ip=a;}
_ V jc(V){Q(a,ip=b)}
_ V ca(V){pur(ip),ip=a;}
_ V cc(V){Q(a,pur(ip),ip=b)}
_ V(*ops[])(V)=
/*0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24*/
/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36*/
{np,ex,pb,ph,pw,pr,fb,fh,fw,mb,mh,mw,io,ii,ss,dr,sw,du,ov,ad,su,mu,di,an,or,xr,sl,sr,sa,eq,lt,gt,no,ju,jc,ca,cc};
_ B arity[]=
{ 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, 2};
_ V op(B n){B k,f,c,o;o=n&0x3f,f=n>>6&1,k=n>>7,c=arity[o];Q(f,swp())a=dp[0-c],b=dp[1-c],dp-=c*!k,ops[o]();Q(f,swp())}
V emu(V){while(ip<0x40000){op(mem[ip++]);}}
V lod(B*c,W l){for(ip=0;ip<l;++ip)mem[ip+0x100]=c[ip];ip=0x100;}