add v8e
parent
1ecdf09aee
commit
6f80913ac7
|
@ -48,6 +48,7 @@ DIRS=\
|
|||
sokoban\
|
||||
sudoku\
|
||||
timmy\
|
||||
v8e\
|
||||
|
||||
4s.$O 5s.$O xs.$O: xs.h
|
||||
$O.4s $O.5s: xs.$O
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,516 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
static s8int
|
||||
getsign(u16int l, u32int a)
|
||||
{
|
||||
u8int c;
|
||||
|
||||
if(l == 0) return 1;
|
||||
c = readm(a + l/2, 0);
|
||||
c &= 0xf;
|
||||
if(c == 11 || c == 13) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
getdig(u16int l, u32int a, int i)
|
||||
{
|
||||
u8int c;
|
||||
|
||||
if(i >= l) return 0;
|
||||
i = l - 1 - i;
|
||||
if((l & 1) == 0) i++;
|
||||
a += i/2;
|
||||
c = readm(a, 0);
|
||||
if((i & 1) == 0) return c >> 4;
|
||||
return c & 0xf;
|
||||
}
|
||||
|
||||
static void
|
||||
putdig(u16int l, u32int a, int i, int v)
|
||||
{
|
||||
u8int c;
|
||||
|
||||
if(i >= l){
|
||||
if(v != 0)
|
||||
ps |= FLAGV;
|
||||
return;
|
||||
}
|
||||
i = l - 1 - i;
|
||||
if((l & 1) == 0) i++;
|
||||
a += i/2;
|
||||
if((l & 1) == 0 && i == 1)
|
||||
c = 0;
|
||||
else
|
||||
c = readm(a, 0);
|
||||
if((i & 1) == 0) c = c & 0x0f | v << 4;
|
||||
else c = c & 0xf0 | v;
|
||||
writem(a, c, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
putsign(u16int l, u32int a, s8int s)
|
||||
{
|
||||
u8int c;
|
||||
|
||||
a += l/2;
|
||||
c = readm(a, 0);
|
||||
c = c & 0xf0 | 12 | s < 0;
|
||||
writem(a, c, 0);
|
||||
}
|
||||
|
||||
static u32int
|
||||
sigdig(u16int l, u32int a)
|
||||
{
|
||||
u32int e;
|
||||
|
||||
e = a + l/2 + 1;
|
||||
for(; a < e; a++)
|
||||
if(readm(a, 0) != 0)
|
||||
return a;
|
||||
return a;
|
||||
}
|
||||
|
||||
void
|
||||
cvtlp(void)
|
||||
{
|
||||
s32int x;
|
||||
u16int l;
|
||||
u32int a;
|
||||
u8int v;
|
||||
int i;
|
||||
|
||||
x = readm(amode(2), 2);
|
||||
l = readm(amode(1), 1);
|
||||
a = addrof(amode(0));
|
||||
|
||||
ps = ps & ~15 | FLAGZ;
|
||||
if(x < 0){
|
||||
x = -x;
|
||||
ps |= FLAGN;
|
||||
}
|
||||
for(i = 0; i < l; i++){
|
||||
v = x % 10;
|
||||
x /= 10;
|
||||
putdig(l, a, i, v);
|
||||
if(v != 0) ps &= ~FLAGZ;
|
||||
}
|
||||
if(x != 0) ps |= FLAGV;
|
||||
if((ps & (FLAGN|FLAGZ)) == 0)
|
||||
ps &= ~FLAGN;
|
||||
putsign(l, a, -((ps & FLAGN) != 0));
|
||||
r[0] = 0;
|
||||
r[1] = 0;
|
||||
r[2] = 0;
|
||||
r[3] = sigdig(l, a);
|
||||
}
|
||||
|
||||
static uchar
|
||||
editread(void)
|
||||
{
|
||||
u8int rc;
|
||||
|
||||
if((s32int) r[0] <= 0){
|
||||
if(r[0] == 0)
|
||||
sysfatal("editread");
|
||||
r[0] += 0x10000;
|
||||
return 0;
|
||||
}else{
|
||||
rc = readm(r[1], 0);
|
||||
if((r[0] & 1) != 0)
|
||||
rc >>= 4;
|
||||
else
|
||||
rc &= 0xf;
|
||||
r[0]--;
|
||||
if((r[0] & 1) != 0)
|
||||
r[1]++;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
editpc(void)
|
||||
{
|
||||
u8int p, c;
|
||||
int i;
|
||||
|
||||
r[0] = readm(amode(1), 1);
|
||||
r[1] = addrof(amode(0));
|
||||
r[2] = 0x2020;
|
||||
r[3] = addrof(amode(0));
|
||||
r[5] = addrof(amode(0));
|
||||
|
||||
ps = ps & ~15 | FLAGZ;
|
||||
c = readm(r[1] + r[0]/2, 0) & 0xf;
|
||||
if(c == 11 || c == 13){
|
||||
ps |= FLAGN;
|
||||
r[2] |= 0xd00;
|
||||
}
|
||||
|
||||
for(;;){
|
||||
p = readm(r[3]++, 0);
|
||||
switch(p){
|
||||
case 0x00:
|
||||
if(r[0] != 0) sysfatal("editpc");
|
||||
if((ps & FLAGZ) != 0)
|
||||
ps &= ~FLAGN;
|
||||
return;
|
||||
case 0x01:
|
||||
if((ps & FLAGC) == 0){
|
||||
writem(r[5]++, r[2] >> 8, 0);
|
||||
ps |= FLAGC;
|
||||
}
|
||||
break;
|
||||
case 0x02: ps &= ~FLAGC; break;
|
||||
case 0x03: ps |= FLAGC; break;
|
||||
case 0x04: writem(r[5]++, r[2] >> 8, 0); break;
|
||||
case 0x40: r[2] = r[2] & ~0xff | (u8int)readm(r[3]++, 0); break;
|
||||
case 0x41: r[2] = r[2] & ~0xff00 | (u8int)readm(r[3]++, 0) << 8; break;
|
||||
case 0x42:
|
||||
p = readm(r[3]++, 0);
|
||||
if((ps & FLAGN) == 0)
|
||||
r[2] = r[2] & ~0xff00 | p << 8;
|
||||
break;
|
||||
case 0x43:
|
||||
p = readm(r[3]++, 0);
|
||||
if((ps & FLAGN) != 0)
|
||||
r[2] = r[2] & ~0xff00 | p << 8;
|
||||
break;
|
||||
case 0x44:
|
||||
p = readm(r[3]++, 0);
|
||||
if((ps & FLAGC) != 0)
|
||||
writem(r[5]++, p, 0);
|
||||
else
|
||||
writem(r[5]++, r[2], 0);
|
||||
break;
|
||||
case 0x45:
|
||||
p = readm(r[3]++, 0);
|
||||
if((ps & FLAGZ) != 0){
|
||||
r[5] -= p;
|
||||
while(p-- != 0)
|
||||
writem(r[5]++, r[2], 0);
|
||||
}
|
||||
break;
|
||||
case 0x46:
|
||||
p = readm(r[3]++, 0);
|
||||
if((ps & (FLAGN|FLAGZ)) == (FLAGN|FLAGZ))
|
||||
writem(r[5] - p, r[2], 0);
|
||||
break;
|
||||
case 0x47:
|
||||
p = readm(r[3]++, 0);
|
||||
if((u16int)r[0] > p){
|
||||
r[0] = (u16int) r[0];
|
||||
i = r[0] - p;
|
||||
while(i-- > 0)
|
||||
if(editread() != 0)
|
||||
ps = ps & ~FLAGZ | FLAGV;
|
||||
}else
|
||||
r[0] = (u16int) r[0] | r[0] - p << 16;
|
||||
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
|
||||
case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
|
||||
for(; p > 0x80; p--)
|
||||
writem(r[5]++, r[2], 0);
|
||||
break;
|
||||
case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
|
||||
case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
|
||||
for(; p > 0x90; p--){
|
||||
c = editread();
|
||||
if(c != 0) ps = ps & ~FLAGZ | FLAGC;
|
||||
if((ps & FLAGC) == 0)
|
||||
writem(r[5]++, r[2], 0);
|
||||
else
|
||||
writem(r[5]++, '0' + c, 0);
|
||||
}
|
||||
break;
|
||||
case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
|
||||
case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
|
||||
for(; p > 0xa0; p--){
|
||||
c = editread();
|
||||
if(c != 0){
|
||||
if((ps & FLAGC) == 0)
|
||||
writem(r[5]++, r[2] >> 8, 0);
|
||||
ps = ps & ~FLAGZ | FLAGC;
|
||||
}
|
||||
if((ps & FLAGC) == 0)
|
||||
writem(r[5]++, r[2], 0);
|
||||
else
|
||||
writem(r[5]++, '0' + c, 0);
|
||||
}
|
||||
break;
|
||||
default: sysfatal("editpc: unknown pattern %.2x (pc=%.8ux)", p, curpc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
movp(void)
|
||||
{
|
||||
u16int l;
|
||||
u32int sa, da;
|
||||
u8int c, d;
|
||||
int i, n;
|
||||
|
||||
l = readm(amode(1), 1);
|
||||
sa = addrof(amode(0));
|
||||
da = addrof(amode(1));
|
||||
n = l/2 + 1;
|
||||
ps = ps & ~(FLAGN|FLAGV) | FLAGZ;
|
||||
for(i = 0; i < n-1; i++){
|
||||
c = readm(sa++, 0);
|
||||
writem(da++, c, 0);
|
||||
if(c != 0) ps &= ~FLAGZ;
|
||||
}
|
||||
c = readm(sa, 0);
|
||||
if((c & 0xf0) != 0) ps &= ~FLAGZ;
|
||||
d = c & 0xf0;
|
||||
c &= 0xf;
|
||||
if(c == 11 || c == 13) ps |= FLAGN;
|
||||
if((ps & (FLAGN|FLAGZ)) == (FLAGN|FLAGZ)) ps &= ~FLAGN;
|
||||
if((ps & FLAGN) != 0) d |= 13;
|
||||
else d |= 12;
|
||||
writem(da, d, 0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cmpmag(u16int l1, u32int a1, u16int l2, u32int a2)
|
||||
{
|
||||
int i;
|
||||
u8int c1, c2;
|
||||
|
||||
for(i = l1 > l2 ? l1 : l2; --i >= 0; ){
|
||||
c1 = getdig(l1, a1, i);
|
||||
c2 = getdig(l2, a2, i);
|
||||
if(c1 > c2) return 1;
|
||||
if(c1 < c2) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
addp(int rn, int sub)
|
||||
{
|
||||
u16int l1, l2, l3;
|
||||
u32int a1, a2, a3;
|
||||
s8int s1, s2;
|
||||
int c, i, l, t;
|
||||
|
||||
l1 = readm(amode(1), 1);
|
||||
a1 = addrof(amode(0));
|
||||
l2 = readm(amode(1), 1);
|
||||
a2 = addrof(amode(0));
|
||||
if(rn == 6){
|
||||
l3 = readm(amode(1), 1);
|
||||
a3 = addrof(amode(0));
|
||||
}else{
|
||||
l3 = l2;
|
||||
a3 = a2;
|
||||
}
|
||||
s1 = getsign(l1, a1);
|
||||
s2 = getsign(l2, a2);
|
||||
r[0] = 0;
|
||||
r[1] = sigdig(l1, a1);
|
||||
r[2] = 0;
|
||||
r[3] = sigdig(l2, a2);
|
||||
r[4] = 0;
|
||||
if(sub) s1 ^= -2;
|
||||
if(s1 == s2){
|
||||
c = 0;
|
||||
l = l1;
|
||||
if(l2 > l) l = l2;
|
||||
if(l3 > l) l = l3;
|
||||
for(i = 0; i < l; i++){
|
||||
t = c + getdig(l1, a1, i) + getdig(l2, a2, i);
|
||||
for(c = 0; t >= 10; c++) t -= 10;
|
||||
putdig(l3, a3, i, t);
|
||||
}
|
||||
}else{
|
||||
if(cmpmag(l1, a1, l2, a2) < 0){
|
||||
t = l1; l1 = l2; l2 = t;
|
||||
t = a1; a1 = a2; a2 = t;
|
||||
s1 = s2;
|
||||
}
|
||||
c = 0;
|
||||
l = l3 > l1 ? l3 : l1;
|
||||
for(i = 0; i < l; i++){
|
||||
t = getdig(l1, a1, i) - getdig(l2, a2, i);
|
||||
for(c = 0; t < 0; c++) t += 10;
|
||||
putdig(l3, a3, i, t);
|
||||
}
|
||||
}
|
||||
if(c != 0) ps |= FLAGV;
|
||||
putsign(l3, a3, s1);
|
||||
r[5] = sigdig(l3, a3);
|
||||
}
|
||||
|
||||
void
|
||||
cmpp(int rn)
|
||||
{
|
||||
u16int l1, l2;
|
||||
u32int a1, a2;
|
||||
s8int s1, s2;
|
||||
int rc;
|
||||
|
||||
l1 = readm(amode(1), 1);
|
||||
a1 = addrof(amode(0));
|
||||
if(rn == 4)
|
||||
l2 = readm(amode(1), 1);
|
||||
else
|
||||
l2 = l1;
|
||||
a2 = addrof(amode(0));
|
||||
s1 = getsign(l1, a1);
|
||||
s2 = getsign(l2, a2);
|
||||
r[0] = 0;
|
||||
r[1] = sigdig(l1, a1);
|
||||
r[2] = 0;
|
||||
r[3] = sigdig(l2, a2);
|
||||
ps &= ~15;
|
||||
if(s1 != s2){
|
||||
if(s1 < s2) ps |= FLAGN;
|
||||
return;
|
||||
}
|
||||
rc = cmpmag(l1, a1, l2, a2);
|
||||
if(rc == 0) ps |= FLAGZ;
|
||||
else if(rc > 0) ps |= FLAGN;
|
||||
}
|
||||
|
||||
void
|
||||
ashp(void)
|
||||
{
|
||||
s8int cnt, rnd;
|
||||
s16int sl, dl;
|
||||
u32int sa, da;
|
||||
int i, c, x;
|
||||
|
||||
cnt = readm(amode(0), 0);
|
||||
sl = readm(amode(1), 1);
|
||||
sa = addrof(amode(2));
|
||||
rnd = readm(amode(0), 0);
|
||||
dl = readm(amode(1), 1);
|
||||
da = addrof(amode(2));
|
||||
ps = ps & ~15 | FLAGZ;
|
||||
x = getsign(sl, sa);
|
||||
if(x < 0) ps |= FLAGN;
|
||||
putsign(dl, da, x);
|
||||
for(i = 0; i < cnt; i++)
|
||||
putdig(dl, da, i, 0);
|
||||
c = cnt < 0 && getdig(sl, sa, -1-cnt) >= rnd;
|
||||
for(i = cnt >= 0 ? 0 : -cnt; i < sl; i++){
|
||||
x = getdig(sl, sa, i) + c;
|
||||
for(c = 0; x >= 10; c++) x -= 10;
|
||||
putdig(dl, da, i + cnt, x);
|
||||
if(x != 0) ps &= ~FLAGZ;
|
||||
}
|
||||
putdig(dl, da, i + cnt, c);
|
||||
r[0] = 0;
|
||||
r[1] = sigdig(sl, sa);
|
||||
r[2] = 0;
|
||||
r[3] = sigdig(dl, da);
|
||||
}
|
||||
|
||||
void
|
||||
locc(int inv)
|
||||
{
|
||||
u8int chr;
|
||||
u16int len;
|
||||
u32int addr;
|
||||
|
||||
chr = readm(amode(0), 0);
|
||||
len = readm(amode(1), 1);
|
||||
addr = addrof(amode(0));
|
||||
ps &= ~15;
|
||||
for(; len != 0; addr++, len--)
|
||||
if(inv ^ (readm(addr, 0) == chr))
|
||||
break;
|
||||
if(len == 0) ps |= FLAGZ;
|
||||
r[0] = len;
|
||||
r[1] = addr;
|
||||
}
|
||||
|
||||
void
|
||||
cmpc(int op5)
|
||||
{
|
||||
u16int l1, l2;
|
||||
u32int a1, a2;
|
||||
u8int a, b, f;
|
||||
|
||||
if(op5){
|
||||
l1 = readm(amode(1), 1);
|
||||
a1 = addrof(amode(2));
|
||||
f = readm(amode(0), 0);
|
||||
l2 = readm(amode(1), 1);
|
||||
a2 = addrof(amode(2));
|
||||
}else{
|
||||
l1 = l2 = readm(amode(1), 1);
|
||||
a1 = addrof(amode(2));
|
||||
a2 = addrof(amode(2));
|
||||
f = 0;
|
||||
}
|
||||
a = b = f;
|
||||
for(; l1 > 0 && l2 > 0; l1--, l2--, a1++, a2++){
|
||||
a = readm(a1, 0);
|
||||
b = readm(a2, 0);
|
||||
if(a != b) goto ineq;
|
||||
}
|
||||
for(; l1 > 0; l1--, a1++){
|
||||
a = readm(a1, 0);
|
||||
b = f;
|
||||
if(a != b) goto ineq;
|
||||
}
|
||||
for(; l2 > 0; l2--, a2++){
|
||||
a = f;
|
||||
b = readm(a2, 0);
|
||||
if(a != b) goto ineq;
|
||||
}
|
||||
ineq:
|
||||
ps = ps & ~15;
|
||||
if((s8int)a < (s8int)b) ps |= FLAGN;
|
||||
if(a == b) ps |= FLAGZ;
|
||||
if(a < b) ps |= FLAGC;
|
||||
r[0] = l1;
|
||||
r[1] = a1;
|
||||
r[2] = l2;
|
||||
r[3] = a2;
|
||||
}
|
||||
|
||||
void
|
||||
movc(int op5)
|
||||
{
|
||||
u16int sl, dl, l;
|
||||
u32int sa, da;
|
||||
int i;
|
||||
u8int f;
|
||||
|
||||
sl = readm(amode(1), 1);
|
||||
sa = addrof(amode(0));
|
||||
if(op5){
|
||||
f = readm(amode(0), 0);
|
||||
dl = readm(amode(1), 1);
|
||||
}else{
|
||||
f = 0;
|
||||
dl = sl;
|
||||
}
|
||||
da = addrof(amode(0));
|
||||
l = sl < dl ? sl : dl;
|
||||
if(sa < da)
|
||||
for(i = l; --i >= 0; )
|
||||
writem(da + i, readm(sa + i, 0), 0);
|
||||
else
|
||||
for(i = 0; i < l; i++)
|
||||
writem(da + i, readm(sa + i, 0), 0);
|
||||
for(i = l; i < dl; i++)
|
||||
writem(da + i, f, 0);
|
||||
r[0] = sl - l;
|
||||
r[1] = sa + sl;
|
||||
r[2] = 0;
|
||||
r[3] = da + dl;
|
||||
r[4] = 0;
|
||||
r[5] = 0;
|
||||
ps &= ~15;
|
||||
if((s16int) sl < (s16int) dl) ps |= FLAGN;
|
||||
else if(sl == dl) ps |= FLAGZ;
|
||||
if(sl < dl) ps |= FLAGC;
|
||||
}
|
|
@ -0,0 +1,521 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
/* BUGS: Not bit accurate. */
|
||||
|
||||
enum {
|
||||
ADD,
|
||||
SUB,
|
||||
MUL,
|
||||
DIV,
|
||||
CMP,
|
||||
};
|
||||
|
||||
enum {
|
||||
EBIAS = 129
|
||||
};
|
||||
|
||||
#define zero(x) (((x) & 0xff80) == 0)
|
||||
#define inval(x) (((x) & 0xff80) == 0x8000)
|
||||
#define expo(x) ((x) >> 7 & 0xff)
|
||||
#define mantf(x) (1<<23 | ((x) & 0x7f) << 16 | (x) >> 16)
|
||||
#define mantd(x) (1ULL<<55|((x)&0x7f)<<48|((x)&0xffff0000)<<16| \
|
||||
(x)>>16&0xffff0000|(u16int)((x)>>48))
|
||||
#define sign(x) ((int)x << 16 >> 30 | 1)
|
||||
#define makef(s, e, m) ((s)&0x8000|(e)<<7|(m)<<16|(m)>>16&0x7f)
|
||||
#define maked(s, e, m) (s&0x8000|(e)<<7|(uvlong)(m)<<48|(uvlong)((m)&0xffff0000)<<16| \
|
||||
(m)>>16&0xffff0000|(m)>>48&0x7f)
|
||||
|
||||
static double
|
||||
vfc(u32int a)
|
||||
{
|
||||
union { u32int a; float b; } u;
|
||||
|
||||
if(zero(a)) return 0;
|
||||
a -= 0x100;
|
||||
u.a = a >> 16 | a << 16;
|
||||
return u.b;
|
||||
}
|
||||
|
||||
static double
|
||||
vdc(u64int a)
|
||||
{
|
||||
union { u64int a; double b; } u;
|
||||
|
||||
if(zero(a)) return 0;
|
||||
u.a = mantd(a) >> 3 & (1ULL<<52)-1 | expo(a) + 894 << 52 | sign(a) & 1ULL<<63;
|
||||
return u.b;
|
||||
}
|
||||
|
||||
static int
|
||||
clz32(u32int a)
|
||||
{
|
||||
int n;
|
||||
static uchar c[16] = {4, 3, 2, 2, 1, 1, 1, 1};
|
||||
|
||||
n = 0;
|
||||
if((a >> 16) == 0){n += 16; a <<= 16;}
|
||||
if((a >> 24) == 0){n += 8; a <<= 8;}
|
||||
if((a >> 28) == 0){n += 4; a <<= 4;}
|
||||
return n + c[a >> 28];
|
||||
}
|
||||
|
||||
static int
|
||||
clz64(uvlong a)
|
||||
{
|
||||
int n;
|
||||
static uchar c[16] = {4, 3, 2, 2, 1, 1, 1, 1};
|
||||
|
||||
n = 0;
|
||||
if((a >> 32) == 0){n += 32; a <<= 32;}
|
||||
if((a >> 48) == 0){n += 16; a <<= 16;}
|
||||
if((a >> 56) == 0){n += 8; a <<= 8;}
|
||||
if((a >> 60) == 0){n += 4; a <<= 4;}
|
||||
return n + c[a >> 60];
|
||||
}
|
||||
|
||||
static int
|
||||
magcmpd(u64int a, u64int b)
|
||||
{
|
||||
int e;
|
||||
s64int m;
|
||||
|
||||
e = expo(a) - expo(b);
|
||||
if(e > 0) return 1;
|
||||
if(e < 0) return -1;
|
||||
m = mantd(a) - mantd(b);
|
||||
if(m > 0) return 1;
|
||||
if(m < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cmpd(u64int a, u64int b)
|
||||
{
|
||||
int s;
|
||||
|
||||
if(zero(a)){
|
||||
if(zero(b)) return 0;
|
||||
return -sign(b);
|
||||
}
|
||||
if(zero(b)) return sign(a);
|
||||
s = sign(a) - sign(b);
|
||||
if(s > 0) return 1;
|
||||
if(s < 0) return -1;
|
||||
return magcmpd(a, b);
|
||||
}
|
||||
|
||||
static u32int
|
||||
addf(u32int a, u32int b, int sub)
|
||||
{
|
||||
int e1, e2, m1, m2, s1, s2;
|
||||
int n;
|
||||
u32int c;
|
||||
|
||||
if(inval(a) || inval(b)) return 0x8000;
|
||||
if(zero(b)) return a;
|
||||
if(sub) b ^= 0x8000;
|
||||
if(zero(a)) return b;
|
||||
if(magcmpd(a, b) < 0){
|
||||
c = a;
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
e1 = expo(a); m1 = mantf(a); s1 = sign(a);
|
||||
e2 = expo(b); m2 = mantf(b); s2 = sign(b);
|
||||
if(e1 - e2 >= 24) return a;
|
||||
m2 >>= e1 - e2;
|
||||
if(s1 == s2)
|
||||
m1 += m2;
|
||||
else
|
||||
m1 -= m2;
|
||||
if(m1 == 0) return 0;
|
||||
n = 8 - clz32(m1);
|
||||
e1 += n;
|
||||
if(n > 0) m1 >>= n;
|
||||
else m1 <<= -n;
|
||||
return makef(s1, e1, m1);
|
||||
}
|
||||
|
||||
static u32int
|
||||
mulf(u32int a, u32int b)
|
||||
{
|
||||
int e1, e2, m1, m2, s1, s2, l;
|
||||
|
||||
if(zero(a) || zero(b)) return 0;
|
||||
e1 = expo(a); m1 = mantf(a); s1 = sign(a);
|
||||
e2 = expo(b); m2 = mantf(b); s2 = sign(b);
|
||||
s1 ^= s2 & -2;
|
||||
e1 += e2 - EBIAS;
|
||||
if(e1 <= 0) return 0;
|
||||
l = (uvlong)m1 * m2 + (1<<22) >> 23;
|
||||
if((l & 1<<24) != 0){
|
||||
l >>= 1;
|
||||
e1++;
|
||||
}
|
||||
if(e1 >= 256) return 0x8000;
|
||||
return makef(s1, e1, l);
|
||||
}
|
||||
|
||||
static u32int
|
||||
divf(u32int a, u32int b)
|
||||
{
|
||||
int e1, e2, m1, m2, s1, s2;
|
||||
uvlong l;
|
||||
|
||||
if(zero(a)) return 0;
|
||||
if(zero(b)) return 0x8000;
|
||||
e1 = expo(a); m1 = mantf(a); s1 = sign(a);
|
||||
e2 = expo(b); m2 = mantf(b); s2 = sign(b);
|
||||
s1 ^= s2 & -2;
|
||||
e1 -= e2 - EBIAS;
|
||||
l = (uvlong) m1 << 40;
|
||||
l /= m2;
|
||||
l >>= 17;
|
||||
if(l == 0) return 0;
|
||||
while((l & 1<<23) == 0){
|
||||
l <<= 1;
|
||||
e1--;
|
||||
}
|
||||
if(e1 <= 0) return 0;
|
||||
if(e1 >= 256) return 0x8000;
|
||||
return makef(s1, e1, l);
|
||||
}
|
||||
|
||||
static u64int
|
||||
addd(u64int a, u64int b, int sub)
|
||||
{
|
||||
int e1, e2, s1, s2;
|
||||
u64int m1, m2;
|
||||
int n;
|
||||
u64int c;
|
||||
|
||||
if(inval(a) || inval(b)) return 0x8000;
|
||||
if(zero(b)) return a;
|
||||
if(sub) b ^= 0x8000;
|
||||
if(zero(a)) return b;
|
||||
if(magcmpd(a, b) < 0){
|
||||
c = a;
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
e1 = expo(a); m1 = mantd(a); s1 = sign(a);
|
||||
e2 = expo(b); m2 = mantd(b); s2 = sign(b);
|
||||
if(e1 - e2 >= 56) return a;
|
||||
m2 >>= e1 - e2;
|
||||
if(s1 == s2)
|
||||
m1 += m2;
|
||||
else
|
||||
m1 -= m2;
|
||||
if(m1 == 0) return 0;
|
||||
n = 8 - clz64(m1);
|
||||
e1 += n;
|
||||
if(n > 0) m1 >>= n;
|
||||
else m1 <<= -n;
|
||||
return maked(s1, e1, m1);
|
||||
}
|
||||
|
||||
static u64int
|
||||
mul55(u64int a, u64int b)
|
||||
{
|
||||
u64int l;
|
||||
|
||||
l = (uvlong)(u32int)a * (u32int)b >> 32;
|
||||
l += (a >> 32) * (u32int)b;
|
||||
l += (u32int)a * (b >> 32);
|
||||
l = l + (1<<21) >> 22;
|
||||
l += (a >> 32) * (b >> 32) << 10;
|
||||
l = l + 1 >> 1;
|
||||
return l;
|
||||
}
|
||||
|
||||
static u64int
|
||||
mul62(u64int a, u64int b)
|
||||
{
|
||||
u64int l;
|
||||
|
||||
l = (uvlong)(u32int)a * (u32int)b >> 32;
|
||||
l += (a >> 32) * (u32int)b;
|
||||
l += (u32int)a * (b >> 32);
|
||||
l = l + (1<<28) >> 29;
|
||||
l += (a >> 32) * (b >> 32) << 3;
|
||||
l = l + 1 >> 1;
|
||||
return l;
|
||||
}
|
||||
|
||||
static u64int
|
||||
muld(u64int a, u64int b)
|
||||
{
|
||||
int e1, e2, s1, s2;
|
||||
uvlong m1, m2;
|
||||
uvlong l;
|
||||
|
||||
if(zero(a) || zero(b)) return 0;
|
||||
e1 = expo(a); m1 = mantd(a); s1 = sign(a);
|
||||
e2 = expo(b); m2 = mantd(b); s2 = sign(b);
|
||||
s1 ^= s2 & -2;
|
||||
e1 += e2 - EBIAS;
|
||||
if(e1 <= 0) return 0;
|
||||
l = mul55(m1, m2);
|
||||
if((l & 1ULL<<56) != 0){
|
||||
l >>= 1;
|
||||
e1++;
|
||||
}
|
||||
if(e1 >= 256) return 0x8000;
|
||||
return maked(s1, e1, l);
|
||||
}
|
||||
|
||||
static u64int
|
||||
divd(u64int a, u64int b)
|
||||
{
|
||||
int e1, e2, s1, s2;
|
||||
uvlong m1, m2, l;
|
||||
|
||||
if(zero(a)) return 0;
|
||||
if(zero(b)) return 0x8000;
|
||||
e1 = expo(a); m1 = mantd(a); s1 = sign(a);
|
||||
e2 = expo(b); m2 = mantd(b); s2 = sign(b);
|
||||
s1 ^= s2 & -2;
|
||||
e1 -= e2 - EBIAS;
|
||||
l = (1ULL<<63) / (m2 >> 28) << 26;
|
||||
m2 <<= 7;
|
||||
l = mul62(l, (1ULL<<63) - mul62(l, m2));
|
||||
l = mul62(l, (1ULL<<63) - mul62(l, m2));
|
||||
l = mul62(l, (1ULL<<63) - mul62(l, m2));
|
||||
l = mul62(l, m1 << 7);
|
||||
l += 1<<6;
|
||||
l >>= 7;
|
||||
if(l == 0) return 0;
|
||||
while((l & 1ULL<<55) == 0){
|
||||
l <<= 1;
|
||||
e1--;
|
||||
}
|
||||
if(e1 <= 0) return 0;
|
||||
if(e1 >= 256) return 0x8000;
|
||||
return maked(s1, e1, l);
|
||||
}
|
||||
|
||||
void
|
||||
alufp(int o, int r, int s)
|
||||
{
|
||||
u64int a, b, v;
|
||||
vlong c;
|
||||
int i;
|
||||
|
||||
switch(r){
|
||||
case 2:
|
||||
b = readm64(amode(s), s);
|
||||
c = amode(s);
|
||||
a = readm64(c, s);
|
||||
break;
|
||||
case 3:
|
||||
b = readm64(amode(s), s);
|
||||
a = readm64(amode(s), s);
|
||||
c = amode(s);
|
||||
break;
|
||||
default: sysfatal("alufp: r==%d", r);
|
||||
}
|
||||
switch(o){
|
||||
case ADD:
|
||||
if(s == 0x13) v = addd(a, b, 0);
|
||||
else v = addf(a, b, 0);
|
||||
break;
|
||||
case SUB:
|
||||
if(s == 0x13) v = addd(a, b, 1);
|
||||
else v = addf(a, b, 1);
|
||||
break;
|
||||
case MUL:
|
||||
if(s == 0x13) v = muld(a, b);
|
||||
else v = mulf(a, b);
|
||||
break;
|
||||
case DIV:
|
||||
if(s == 0x13) v = divd(a, b);
|
||||
else v = divf(a, b);
|
||||
break;
|
||||
case CMP:
|
||||
ps &= ~15;
|
||||
i = cmpd(b, a);
|
||||
if(i < 0) ps |= FLAGN;
|
||||
if(i == 0) ps |= FLAGZ;
|
||||
return;
|
||||
default:
|
||||
sysfatal("alufp: unimplemented op=%d", o);
|
||||
}
|
||||
// print("%.8ux %d %20.16g %20.16g %20.16g\n", curpc, o, vdc(a), vdc(b), vdc(v));
|
||||
ps &= ~15;
|
||||
if(zero(v)) ps |= FLAGZ;
|
||||
if((v & 0x8000) != 0) ps |= FLAGN;
|
||||
writem64(c, v, s);
|
||||
}
|
||||
|
||||
static u64int
|
||||
itof(s32int i)
|
||||
{
|
||||
int n;
|
||||
u64int l;
|
||||
|
||||
l = 0;
|
||||
if(i < 0){
|
||||
l |= 0x8000;
|
||||
i = -i;
|
||||
}else if(i == 0)
|
||||
return 0;
|
||||
n = clz32(i);
|
||||
l |= maked(0, 160 - n, (uvlong)i << 24 + n);
|
||||
return l;
|
||||
}
|
||||
|
||||
static s64int
|
||||
ftoi(u64int l)
|
||||
{
|
||||
int s, e;
|
||||
|
||||
s = sign(l);
|
||||
e = expo(l);
|
||||
l = mantd(l);
|
||||
if(e >= EBIAS + 64) return 1LL<<63;
|
||||
if(e < EBIAS) return 0;
|
||||
l >>= EBIAS + 55 - e;
|
||||
if(s < 0) return -l;
|
||||
else return l;
|
||||
}
|
||||
|
||||
void
|
||||
cvtfp(int s, int t, int r)
|
||||
{
|
||||
u64int l;
|
||||
int si, e;
|
||||
|
||||
switch(s){
|
||||
case 0: l = itof((s8int) readm(amode(0), 0)); break;
|
||||
case 1: l = itof((s16int) readm(amode(1), 1)); break;
|
||||
case 2: l = itof(readm(amode(2), 2)); break;
|
||||
case 0x12: l = readm(amode(2), 2); break;
|
||||
case 0x13: l = readm64(amode(3), 3); break;
|
||||
default: sysfatal("cvtfp: s==%d", s);
|
||||
}
|
||||
if(r) l = addd(l, maked(sign(l), 128, 0), 0);
|
||||
if(t < 0x10) l = ftoi(l);
|
||||
ps &= ~15;
|
||||
switch(t){
|
||||
case 0:
|
||||
if((s64int)l != (s8int)l) ps |= FLAGV;
|
||||
l = (s8int) l;
|
||||
break;
|
||||
case 1:
|
||||
if((s64int)l != (s16int)l) ps |= FLAGV;
|
||||
l = (s16int) l;
|
||||
break;
|
||||
case 2:
|
||||
if((s64int)l != (s32int)l) ps |= FLAGV;
|
||||
l = (s32int) l;
|
||||
break;
|
||||
case 0x12:
|
||||
si = sign(l);
|
||||
e = expo(l);
|
||||
l = mantd(l);
|
||||
l += 1ULL<<31;
|
||||
if((l & 1ULL<<56) != 0){
|
||||
l >>= 1;
|
||||
e++;
|
||||
}
|
||||
l = maked(si, e, l);
|
||||
break;
|
||||
}
|
||||
writem64(amode(t), l, t);
|
||||
if(t >= 0x10){
|
||||
if(zero(l)) ps |= FLAGZ;
|
||||
if((l & 0x8000) != 0) ps |= FLAGN;
|
||||
}else{
|
||||
if(l == 0) ps |= FLAGZ;
|
||||
if((s64int)l < 0) ps |= FLAGN;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
movefp(int t, int n)
|
||||
{
|
||||
u64int x;
|
||||
|
||||
x = readm64(amode(t), t);
|
||||
if(inval(x)) sysfatal("invalid float");
|
||||
ps &= ~(FLAGN|FLAGZ|FLAGV);
|
||||
if(zero(x))
|
||||
ps |= FLAGZ;
|
||||
else{
|
||||
if(n) x ^= 0x8000;
|
||||
if((x & 0x8000) != 0) ps |= FLAGN;
|
||||
}
|
||||
writem64(amode(t), x, t);
|
||||
}
|
||||
|
||||
void
|
||||
emod(int s)
|
||||
{
|
||||
u64int a, b, m1, m2, l;
|
||||
u8int a8;
|
||||
vlong ai, af;
|
||||
int e1, e2, s1, s2, n;
|
||||
|
||||
a = readm64(amode(s), s);
|
||||
a8 = readm(amode(0), 0);
|
||||
b = readm64(amode(s), s);
|
||||
ai = amode(2);
|
||||
af = amode(s);
|
||||
|
||||
if(zero(a) || zero(b)){
|
||||
ps = ps & ~15 | FLAGZ;
|
||||
writem(ai, 0, 2);
|
||||
writem64(af, 0, s);
|
||||
return;
|
||||
}
|
||||
e1 = expo(a); m1 = mantd(a) << 8 | a8; s1 = sign(a);
|
||||
e2 = expo(b); m2 = mantd(b); s2 = sign(b);
|
||||
s1 ^= s2 & -2;
|
||||
e1 += e2 - EBIAS;
|
||||
if(e1 <= 0){
|
||||
ps = ps & ~15 | FLAGZ;
|
||||
writem(ai, 0, 2);
|
||||
writem64(af, 0, s);
|
||||
return;
|
||||
}
|
||||
l = (uvlong)(u32int)m1 * (u32int)m2 >> 32;
|
||||
l += (m1 >> 32) * (u32int)m2;
|
||||
l += (u32int)m1 * (m2 >> 32);
|
||||
l = l + (1<<29) >> 30;
|
||||
l += (m1 >> 32) * (m2 >> 32) << 2;
|
||||
l = l + 1 >> 1;
|
||||
while((l & 1ULL<<56) != 0){
|
||||
l = l + 1 >> 1;
|
||||
e1++;
|
||||
}
|
||||
if(e1 >= 256){
|
||||
ps |= FLAGV;
|
||||
return;
|
||||
}
|
||||
if(e1 < EBIAS){
|
||||
writem(ai, 0, 2);
|
||||
writem64(af, maked(s1, e1, l), s);
|
||||
if(s1 < 0) ps |= FLAGN;
|
||||
return;
|
||||
}
|
||||
writem(ai, l >> 55+EBIAS-e1, 2);
|
||||
l &= (1ULL<<55+EBIAS-e1) - 1;
|
||||
if(l == 0){
|
||||
writem64(af, 0, s);
|
||||
ps |= FLAGZ;
|
||||
return;
|
||||
}
|
||||
n = clz64(l)-8;
|
||||
l <<= n;
|
||||
e1 -= n;
|
||||
writem64(af, maked(s1, e1, l), s);
|
||||
if(s1 < 0) ps |= FLAGN;
|
||||
}
|
||||
|
||||
void
|
||||
fptest(void)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
typedef char s8int;
|
||||
typedef short s16int;
|
||||
typedef int s32int;
|
||||
typedef vlong s64int;
|
||||
|
||||
extern u32int r[16];
|
||||
extern u32int ps;
|
||||
extern u32int curpc;
|
||||
extern int trace;
|
||||
|
||||
#define U32(x) ((x)[0] | (x)[1] << 8 | (x)[2] << 16 | (x)[3] << 24)
|
||||
|
||||
typedef struct Segment Segment;
|
||||
typedef struct Chan Chan;
|
||||
|
||||
struct Segment {
|
||||
enum {
|
||||
SEGRO = 1,
|
||||
} flags;
|
||||
u32int start, size;
|
||||
u32int *data;
|
||||
};
|
||||
|
||||
extern Segment segs[3];
|
||||
|
||||
enum {
|
||||
STACKSIZE = 16*1024*1024
|
||||
};
|
||||
|
||||
enum {
|
||||
EPERM = 1,
|
||||
ENOENT = 2,
|
||||
EIO = 5,
|
||||
EBADF = 9,
|
||||
EINVAL = 22,
|
||||
EMFILE = 24,
|
||||
ENOTTY = 25,
|
||||
};
|
||||
|
||||
struct Chan {
|
||||
int fd;
|
||||
enum {
|
||||
DONTCLOSE = 1,
|
||||
DIR = 2,
|
||||
FAKETTY = 4,
|
||||
} flags;
|
||||
char *buf, *bufp, *bufe;
|
||||
};
|
||||
|
||||
enum { NCHANS = 128 };
|
||||
|
||||
enum {
|
||||
FLAGN = 8,
|
||||
FLAGZ = 4,
|
||||
FLAGV = 2,
|
||||
FLAGC = 1,
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
void step(void);
|
||||
u8int memread8(u32int);
|
||||
u16int memread16(u32int);
|
||||
u32int memread32(u32int);
|
||||
void memwrite(u32int, u32int, u32int);
|
||||
void syscall(u16int);
|
||||
void writem(vlong, u32int, int);
|
||||
void *emalloc(ulong);
|
||||
void sysinit(void);
|
||||
u32int readm(vlong, int);
|
||||
u64int readm64(vlong, int);
|
||||
u32int addrof(vlong);
|
||||
void writem(vlong, u32int, int);
|
||||
void writem64(vlong, u64int, int);
|
||||
vlong amode(int);
|
||||
int load(char *, char **, char **);
|
|
@ -0,0 +1,74 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
static Segment *
|
||||
seglook(u32int a, int n, u32int **lp)
|
||||
{
|
||||
Segment *s;
|
||||
|
||||
for(s = segs; s < segs + nelem(segs); s++)
|
||||
if(a >= s->start && a < s->start + s->size)
|
||||
break;
|
||||
if(s == segs + nelem(segs)) return nil;
|
||||
if(a + n > s->start + s->size) return nil;
|
||||
if(lp != nil) *lp = s->data + (a - s->start >> 2);
|
||||
return s;
|
||||
}
|
||||
|
||||
u8int
|
||||
memread8(u32int a)
|
||||
{
|
||||
u32int *p;
|
||||
|
||||
if(seglook(a, 1, &p) == nil) sysfatal("invalid read from %.8ux (pc=%.8ux)", a, curpc);
|
||||
switch(a & 3){
|
||||
case 0: return *p;
|
||||
case 1: return *p >> 8;
|
||||
case 2: return *p >> 16;
|
||||
case 3: return *p >> 24;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16int
|
||||
memread16(u32int a)
|
||||
{
|
||||
u32int *p;
|
||||
|
||||
if(seglook(a, 2, &p) == nil) sysfatal("invalid read from %.8ux (pc=%.8ux)", a, curpc);
|
||||
switch(a & 3){
|
||||
case 0: return *p;
|
||||
case 1: return *p >> 8;
|
||||
case 2: return *p >> 16;
|
||||
case 3: return *p >> 24 | p[1] << 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32int
|
||||
memread32(u32int a)
|
||||
{
|
||||
u32int *p;
|
||||
|
||||
if(seglook(a, 4, &p) == nil) sysfatal("invalid read from %.8ux (pc=%.8ux)", a, curpc);
|
||||
switch(a & 3){
|
||||
case 0: return *p;
|
||||
case 1: return *p >> 8 | p[1] << 24;
|
||||
case 2: return *p >> 16 | p[1] << 16;
|
||||
case 3: return *p >> 24 | p[1] << 8;
|
||||
}
|
||||
return *p;
|
||||
}
|
||||
|
||||
void
|
||||
memwrite(u32int a, u32int v, u32int m)
|
||||
{
|
||||
u32int *p;
|
||||
Segment *s;
|
||||
|
||||
s = seglook(a, 4, &p);
|
||||
if(s == nil || (s->flags & SEGRO) != 0) sysfatal("invalid write to %.8ux=%.8ux (mask=%.8ux, pc=%.8ux)", a, v, m, curpc);
|
||||
*p = *p & ~m | v & m;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
</$objtype/mkfile
|
||||
|
||||
BIN=/$objtype/bin
|
||||
TARG=v8e
|
||||
HFILES=dat.h fns.h
|
||||
OFILES=\
|
||||
v8e.$O \
|
||||
cpu.$O \
|
||||
cpubcd.$O \
|
||||
cpufp.$O \
|
||||
mem.$O \
|
||||
sys.$O \
|
||||
|
||||
</sys/src/cmd/mkone
|
|
@ -0,0 +1,660 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
Chan chans[NCHANS];
|
||||
|
||||
int systrace=1;
|
||||
#define dprint print
|
||||
|
||||
static u32int
|
||||
arg(int n)
|
||||
{
|
||||
return memread32(r[12] + (n + 1) * 4);
|
||||
}
|
||||
|
||||
static char *
|
||||
strget(u32int addr)
|
||||
{
|
||||
int n;
|
||||
char *s;
|
||||
|
||||
for(n = 0; memread8(addr + n) != 0; n++)
|
||||
;
|
||||
s = emalloc(n + 1);
|
||||
for(n = 0; n == 0 || s[n-1] != 0; n++)
|
||||
s[n] = memread8(addr + n);
|
||||
return s;
|
||||
}
|
||||
|
||||
static char **
|
||||
vecget(u32int addr)
|
||||
{
|
||||
int n;
|
||||
u32int u;
|
||||
char **s;
|
||||
|
||||
for(n = 0; readm(addr + n, 2) != 0; n += 4)
|
||||
;
|
||||
s = emalloc((n + 1) * sizeof(char *));
|
||||
for(n = 0; u = readm(addr + n * 4, 2), u != 0; n++)
|
||||
s[n] = strget(u);
|
||||
return s;
|
||||
}
|
||||
|
||||
static Chan *
|
||||
getfd(int n)
|
||||
{
|
||||
if((unsigned)n >= NCHANS || chans[n].fd < 0)
|
||||
return nil;
|
||||
return &chans[n];
|
||||
}
|
||||
|
||||
static Chan *
|
||||
newfd(void)
|
||||
{
|
||||
Chan *c;
|
||||
|
||||
for(c = chans; c < chans + nelem(chans); c++)
|
||||
if(c->fd < 0)
|
||||
return c;
|
||||
return nil;
|
||||
}
|
||||
|
||||
static int
|
||||
toerrno(void)
|
||||
{
|
||||
char buf[ERRMAX];
|
||||
|
||||
rerrstr(buf, sizeof(buf));
|
||||
if(strstr(buf, "not found")) return -ENOENT;
|
||||
print("couldn't translate %s\n", buf);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int
|
||||
toerrnoi(int rc)
|
||||
{
|
||||
if(rc >= 0)
|
||||
return rc;
|
||||
return toerrno();
|
||||
}
|
||||
|
||||
static int
|
||||
dostat(u32int buf, Dir *d)
|
||||
{
|
||||
int m;
|
||||
|
||||
if(d == nil) return toerrno();
|
||||
writem(buf, 0, 1); /* dev */
|
||||
writem(buf + 2, d->qid.path, 1); /* ino */
|
||||
m = d->mode & 0777;
|
||||
if((d->mode & DMDIR) != 0) m |= 040000;
|
||||
else m |= 010000;
|
||||
writem(buf + 4, m, 1); /* mode */
|
||||
writem(buf + 6, 1, 1); /* nlink */
|
||||
writem(buf + 8, 0, 1); /* uid */
|
||||
writem(buf + 10, 0, 1); /* gid */
|
||||
writem(buf + 12, d->dev, 1); /* dev */
|
||||
writem(buf + 16, d->length, 2); /* size */
|
||||
writem(buf + 20, d->atime, 2); /* atime */
|
||||
writem(buf + 24, d->mtime, 2); /* mtime */
|
||||
writem(buf + 28, d->mtime, 2); /* ctime */
|
||||
free(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sysexit(void)
|
||||
{
|
||||
int no;
|
||||
|
||||
no = arg(0);
|
||||
if(no == 0) exits(nil);
|
||||
exits(smprint("%d", no));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dodirread(Chan *c)
|
||||
{
|
||||
Dir *d, *dp;
|
||||
int rc;
|
||||
|
||||
free(c->buf);
|
||||
c->buf = c->bufp = c->bufe = nil;
|
||||
rc = dirread(c->fd, &d);
|
||||
if(rc <= 0) return rc;
|
||||
c->bufp = c->bufe = c->buf = emalloc(16 * rc);
|
||||
for(dp = d; --rc >= 0; dp++){
|
||||
*c->bufe++ = dp->qid.path;
|
||||
*c->bufe++ = dp->qid.path >> 8;
|
||||
strncpy(c->bufe, dp->name, 14);
|
||||
c->bufe += 14;
|
||||
}
|
||||
free(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sysread(void)
|
||||
{
|
||||
int fd, sz, rc, i;
|
||||
u32int addr;
|
||||
char *buf;
|
||||
Chan *c;
|
||||
|
||||
fd = arg(0);
|
||||
addr = arg(1);
|
||||
sz = arg(2);
|
||||
if(systrace) dprint("read(%d, %#ux, %d)\n", fd, addr, sz);
|
||||
c = getfd(fd);
|
||||
if(sz < 0) return -EINVAL;
|
||||
if(c == nil) return -EBADF;
|
||||
if((c->flags & DIR) != 0){
|
||||
if(c->bufp >= c->bufe)
|
||||
if(dodirread(c) < 0)
|
||||
return toerrno();
|
||||
for(rc = 0; sz > 0 && c->bufp < c->bufe; rc++, sz--)
|
||||
writem(addr++, *c->bufp++, 0);
|
||||
return rc;
|
||||
}else{
|
||||
buf = emalloc(sz);
|
||||
rc = read(c->fd, buf, sz);
|
||||
for(i = 0; i < rc; i++)
|
||||
writem(addr + i, buf[i], 0);
|
||||
free(buf);
|
||||
if(rc < 0) return toerrno();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
syswrite(void)
|
||||
{
|
||||
int fd, sz, rc, i;
|
||||
u32int addr;
|
||||
Chan *c;
|
||||
char *buf;
|
||||
|
||||
fd = arg(0);
|
||||
addr = arg(1);
|
||||
sz = arg(2);
|
||||
if(systrace) dprint("write(%d, %#ux, %d)\n", fd, addr, sz);
|
||||
c = getfd(fd);
|
||||
if(sz < 0) return -EINVAL;
|
||||
if(c == nil) return -EBADF;
|
||||
buf = emalloc(sz);
|
||||
for(i = 0; i < sz; i++)
|
||||
buf[i] = memread8(addr + i);
|
||||
rc = write(c->fd, buf, sz);
|
||||
free(buf);
|
||||
return toerrnoi(rc);
|
||||
}
|
||||
|
||||
static int
|
||||
sysopen(void)
|
||||
{
|
||||
char *s;
|
||||
Chan *c;
|
||||
int m;
|
||||
Dir *d;
|
||||
|
||||
s = strget(arg(0));
|
||||
m = arg(1);
|
||||
if(systrace) dprint("open(\"%s\", %#uo)\n", s, m);
|
||||
switch(m){
|
||||
case 0: m = OREAD; break;
|
||||
case 1: m = OWRITE; break;
|
||||
case 2: m = ORDWR; break;
|
||||
default: free(s); return -EINVAL;
|
||||
}
|
||||
c = newfd();
|
||||
if(c == nil){
|
||||
free(s);
|
||||
return -EMFILE;
|
||||
}
|
||||
c->fd = open(s, m);
|
||||
free(s);
|
||||
if(c->fd < 0) return toerrno();
|
||||
d = dirfstat(c->fd);
|
||||
if(d == nil){
|
||||
close(c->fd);
|
||||
return toerrno();
|
||||
}
|
||||
if((d->mode & DMDIR) != 0)
|
||||
c->flags |= DIR;
|
||||
free(d);
|
||||
return c - chans;
|
||||
}
|
||||
|
||||
static int
|
||||
sysclose(void)
|
||||
{
|
||||
int fd;
|
||||
Chan *c;
|
||||
|
||||
fd = arg(0);
|
||||
if(systrace) dprint("close(%d)\n", fd);
|
||||
c = getfd(fd);
|
||||
if(c == nil) return -EBADF;
|
||||
if((c->flags & DONTCLOSE) == 0)
|
||||
close(c->fd);
|
||||
c->fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sysfstat(void)
|
||||
{
|
||||
int fd, buf;
|
||||
Chan *c;
|
||||
Dir *d;
|
||||
|
||||
fd = arg(0);
|
||||
buf = arg(1);
|
||||
if(systrace) dprint("fstat(%d, %#ux)\n", fd, buf);
|
||||
c = getfd(fd);
|
||||
if(c == nil) return -EBADF;
|
||||
d = dirfstat(c->fd);
|
||||
return dostat(buf, d);
|
||||
}
|
||||
|
||||
static int
|
||||
syslstat(void)
|
||||
{
|
||||
char *s;
|
||||
int buf;
|
||||
Dir *d;
|
||||
|
||||
s = strget(arg(0));
|
||||
buf = arg(1);
|
||||
if(systrace) dprint("lstat(\"%s\", %#ux)\n", s, buf);
|
||||
d = dirstat(s);
|
||||
free(s);
|
||||
return dostat(buf, d);
|
||||
}
|
||||
|
||||
static int
|
||||
sysioctl(void)
|
||||
{
|
||||
int fd, ctl;
|
||||
u32int addr;
|
||||
Chan *c;
|
||||
|
||||
fd = arg(0);
|
||||
ctl = arg(1);
|
||||
addr = arg(2);
|
||||
if(systrace) dprint("lstat(%d, %#ux, %#ux)\n", fd, ctl, addr);
|
||||
c = getfd(fd);
|
||||
if(c == nil) return -EBADF;
|
||||
switch(ctl){
|
||||
case 't'<<8|8:
|
||||
if((c->flags & FAKETTY) != 0){
|
||||
writem(addr, 13 | 13<<8 | '#'<<16 | '@'<<24, 2);
|
||||
writem(addr + 4, 06010, 2);
|
||||
return 0;
|
||||
}
|
||||
return -ENOTTY;
|
||||
case 'j'<<8|3: return -EINVAL;
|
||||
default:
|
||||
fprint(2, "unknown ioctl %c%d\n", ctl >> 8, (u8int)ctl);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
systime(void)
|
||||
{
|
||||
u32int addr;
|
||||
int t;
|
||||
|
||||
addr = arg(0);
|
||||
if(systrace) dprint("time(%#ux)\n", addr);
|
||||
t = time(0);
|
||||
if(addr != 0) writem(addr, t, 2);
|
||||
return t;
|
||||
}
|
||||
|
||||
static int
|
||||
sysbreak(void)
|
||||
{
|
||||
u32int a;
|
||||
int ns;
|
||||
|
||||
a = arg(0);
|
||||
if(systrace) dprint("break(%#ux)\n", a);
|
||||
a = -(-a & -1024);
|
||||
ns = a - segs[1].start;
|
||||
if(ns > segs[1].size){
|
||||
segs[1].data = realloc(segs[1].data, ns);
|
||||
memset((uchar *) segs[1].data + segs[1].size, 0, ns - segs[1].size);
|
||||
segs[1].size = ns;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sysftime(void)
|
||||
{
|
||||
u32int p;
|
||||
vlong n;
|
||||
Tm *t;
|
||||
|
||||
p = arg(0);
|
||||
if(systrace) dprint("ftime(%#ux)\n", p);
|
||||
n = nsec();
|
||||
n /= 1000000;
|
||||
writem(p + 4, n % 1000, 1);
|
||||
n /= 1000;
|
||||
writem(p, n, 2);
|
||||
t = localtime(n);
|
||||
writem(p + 6, -t->tzoff / 60, 1);
|
||||
writem(p + 8, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
syssignal(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sysgetpid(void)
|
||||
{
|
||||
if(systrace) dprint("getpid()\n");
|
||||
return getpid() & 0xffff;
|
||||
}
|
||||
|
||||
static int
|
||||
sysaccess(void)
|
||||
{
|
||||
char *s;
|
||||
int m, rc;
|
||||
|
||||
s = strget(arg(0));
|
||||
m = arg(1);
|
||||
if(systrace) dprint("access(\"%s\", %#ux)\n", s, m);
|
||||
rc = access(s, m & 7);
|
||||
free(s);
|
||||
return toerrnoi(rc);
|
||||
}
|
||||
|
||||
static int
|
||||
syscreat(void)
|
||||
{
|
||||
char *s;
|
||||
Chan *c;
|
||||
int m;
|
||||
|
||||
s = strget(arg(0));
|
||||
m = arg(1);
|
||||
if(systrace) dprint("creat(\"%s\", %#uo)\n", s, m);
|
||||
c = newfd();
|
||||
if(c == nil){
|
||||
free(s);
|
||||
return -EMFILE;
|
||||
}
|
||||
c->fd = create(s, OWRITE, m & 0777);
|
||||
free(s);
|
||||
if(c->fd < 0) return toerrno();
|
||||
return c - chans;
|
||||
}
|
||||
|
||||
static int
|
||||
sysseek(void)
|
||||
{
|
||||
int fd, off, wh;
|
||||
Chan *c;
|
||||
|
||||
fd = arg(0);
|
||||
off = arg(1);
|
||||
wh = arg(2);
|
||||
if(systrace) dprint("seek(%d, %d, %d)\n", fd, off, wh);
|
||||
c = getfd(fd);
|
||||
if(c == nil || off < 0 || (uint)wh > 2) return -EBADF;
|
||||
return toerrnoi(seek(c->fd, off, wh));
|
||||
}
|
||||
|
||||
static int
|
||||
sysunlink(void)
|
||||
{
|
||||
char *s;
|
||||
int rc;
|
||||
|
||||
s = strget(arg(0));
|
||||
if(systrace) dprint("unlink(\"%s\")\n", s);
|
||||
rc = remove(s);
|
||||
free(s);
|
||||
return toerrnoi(rc);
|
||||
}
|
||||
|
||||
static int
|
||||
syschdir(void)
|
||||
{
|
||||
char *s;
|
||||
int rc;
|
||||
|
||||
s = strget(arg(0));
|
||||
if(systrace) dprint("chdir(\"%s\")\n", s);
|
||||
rc = chdir(s);
|
||||
free(s);
|
||||
return toerrnoi(rc);
|
||||
}
|
||||
|
||||
static int
|
||||
sysgetuid(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sysfork(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if(systrace) dprint("fork()\n");
|
||||
rc = fork();
|
||||
if(rc < 0) return toerrno();
|
||||
if(rc == 0){
|
||||
r[1] = 1;
|
||||
return getppid();
|
||||
}
|
||||
r[1] = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
sysexece(void)
|
||||
{
|
||||
char *file, **argv, **env, **p;
|
||||
int rc;
|
||||
|
||||
file = strget(arg(0));
|
||||
argv = vecget(arg(1));
|
||||
env = vecget(arg(2));
|
||||
if(systrace) dprint("exece(\"%s\", ..., ...)\n", file);
|
||||
rc = load(file, argv, env);
|
||||
for(p = argv; *p != nil; p++)
|
||||
free(*p);
|
||||
for(p = env; *p != nil; p++)
|
||||
free(*p);
|
||||
free(file);
|
||||
free(argv);
|
||||
free(env);
|
||||
return toerrnoi(rc);
|
||||
}
|
||||
|
||||
static int
|
||||
syswait(void)
|
||||
{
|
||||
Waitmsg *w;
|
||||
int rc, st;
|
||||
u32int addr;
|
||||
char *p;
|
||||
|
||||
addr = arg(0);
|
||||
if(systrace) dprint("wait(%#ux)\n", addr);
|
||||
w = wait();
|
||||
if(w == nil) return toerrno();
|
||||
rc = w->pid;
|
||||
if(addr != 0){
|
||||
st = strtol(w->msg, &p, 10) & 255 << 8;
|
||||
if(*p == 0) st = 127 << 8;
|
||||
writem(addr, st, 2);
|
||||
}
|
||||
free(w);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int mask = 022;
|
||||
static int
|
||||
sysumask(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = mask;
|
||||
mask = arg(0);
|
||||
if(systrace) dprint("umask(%#uo)\n", mask);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
syslink(void)
|
||||
{
|
||||
char *a, *b;
|
||||
int f0, f1, rc, n;
|
||||
char buf[8192];
|
||||
|
||||
a = strget(arg(0));
|
||||
b = strget(arg(1));
|
||||
if(systrace) dprint("link(\"%s\", \"%s\")\n", a, b);
|
||||
f0 = open(a, OREAD);
|
||||
f1 = create(b, OWRITE | OEXCL, 0777 ^ mask);
|
||||
if(f0 < 0 || f1 < 0) {
|
||||
err:
|
||||
rc = toerrno();
|
||||
goto out;
|
||||
}
|
||||
for(;;){
|
||||
n = read(f0, buf, sizeof(buf));
|
||||
if(n < 0) goto err;
|
||||
if(n == 0) break;
|
||||
if(write(f1, buf, n) < n) goto err;
|
||||
}
|
||||
rc = 0;
|
||||
out:
|
||||
if(f0 >= 0) close(f0);
|
||||
if(f1 >= 0) close(f1);
|
||||
free(a);
|
||||
free(b);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
syschmod(void)
|
||||
{
|
||||
char *a;
|
||||
int mode;
|
||||
Dir d;
|
||||
Dir *e;
|
||||
|
||||
a = strget(arg(0));
|
||||
mode = arg(1);
|
||||
if(systrace) dprint("chmod(\"%s\", %#uo)\n", a, mode);
|
||||
e = dirstat(a);
|
||||
if(e == nil){
|
||||
free(a);
|
||||
return toerrno();
|
||||
}
|
||||
nulldir(&d);
|
||||
d.mode = e->mode & ~0777 | mode & 0777;
|
||||
free(e);
|
||||
if(dirwstat(a, &d) < 0){
|
||||
free(a);
|
||||
return toerrno();
|
||||
}
|
||||
free(a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sysdup(void)
|
||||
{
|
||||
int fd;
|
||||
Chan *c, *d;
|
||||
|
||||
fd = arg(0);
|
||||
if(systrace) dprint("dup(%d)\n", fd);
|
||||
c = getfd(fd);
|
||||
if(c == nil) return -EBADF;
|
||||
d = newfd();
|
||||
if(d == nil) return -EMFILE;
|
||||
d->fd = c->fd;
|
||||
d->flags = c->flags;
|
||||
return d - chans;
|
||||
}
|
||||
|
||||
void
|
||||
syscall(u16int c)
|
||||
{
|
||||
int rc;
|
||||
|
||||
static int (*calls[])(void) = {
|
||||
[1] sysexit,
|
||||
[2] sysfork,
|
||||
[3] sysread,
|
||||
[4] syswrite,
|
||||
[5] sysopen,
|
||||
[6] sysclose,
|
||||
[7] syswait,
|
||||
[8] syscreat,
|
||||
[9] syslink,
|
||||
[10] sysunlink,
|
||||
[12] syschdir,
|
||||
[13] systime,
|
||||
[15] syschmod,
|
||||
[17] sysbreak,
|
||||
[18] syslstat,
|
||||
[19] sysseek,
|
||||
[20] sysgetpid,
|
||||
[24] sysgetuid,
|
||||
[28] sysfstat,
|
||||
[33] sysaccess,
|
||||
[35] sysftime,
|
||||
[40] syslstat,
|
||||
[41] sysdup,
|
||||
[48] syssignal,
|
||||
[54] sysioctl,
|
||||
[59] sysexece,
|
||||
[60] sysumask,
|
||||
[66] sysfork,
|
||||
};
|
||||
|
||||
if(c >= nelem(calls) || calls[c] == nil) sysfatal("unknown syscall %d", c);
|
||||
rc = calls[c]();
|
||||
if(rc < 0){
|
||||
r[0] = -rc;
|
||||
ps |= 1;
|
||||
}else{
|
||||
r[0] = rc;
|
||||
ps &= ~1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sysinit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < NCHANS; i++)
|
||||
chans[i].fd = -1;
|
||||
chans[0].fd = 0;
|
||||
chans[0].flags = DONTCLOSE|FAKETTY;
|
||||
chans[1].fd = 1;
|
||||
chans[1].flags = DONTCLOSE|FAKETTY;
|
||||
chans[2].fd = 2;
|
||||
chans[2].flags = DONTCLOSE|FAKETTY;
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <auth.h>
|
||||
#include <ctype.h>
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
Segment segs[3];
|
||||
|
||||
void *
|
||||
emalloc(ulong n)
|
||||
{
|
||||
void *v;
|
||||
|
||||
v = malloc(n);
|
||||
if(v == nil) sysfatal("malloc: %r");
|
||||
memset(v, 0, n);
|
||||
setmalloctag(v, getcallerpc(&n));
|
||||
return v;
|
||||
}
|
||||
|
||||
enum {
|
||||
OMAGIC = 0407,
|
||||
NMAGIC = 0410,
|
||||
ZMAGIC = 0413,
|
||||
};
|
||||
|
||||
static int
|
||||
readn32(int fd, u32int *l, int sz)
|
||||
{
|
||||
static uchar buf[8192];
|
||||
uchar *p;
|
||||
int n, rc;
|
||||
|
||||
while(sz > 0){
|
||||
n = 8192;
|
||||
if(n > sz) n = sz;
|
||||
rc = readn(fd, buf, n);
|
||||
if(rc < 0) return -1;
|
||||
if(rc < n){
|
||||
werrstr("unexpected eof");
|
||||
return -1;
|
||||
}
|
||||
sz -= n;
|
||||
p = buf;
|
||||
for(; n >= 4; n -= 4){
|
||||
*l++ = U32(p);
|
||||
p += 4;
|
||||
}
|
||||
switch(n){
|
||||
case 1: *l = p[0]; break;
|
||||
case 2: *l = p[0] | p[1] << 8; break;
|
||||
case 3: *l = p[0] | p[1] << 8 | p[2] << 16; break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
setupstack(char **argv)
|
||||
{
|
||||
u32int *nargv;
|
||||
int i, j;
|
||||
int argc;
|
||||
|
||||
r[14] = 0x7ffff400;
|
||||
#define push32(x) { r[14] -= 4; memwrite(r[14], x, -1); }
|
||||
for(argc = 0; argv[argc] != nil; argc++)
|
||||
;
|
||||
nargv = emalloc(sizeof(u32int) * argc);
|
||||
for(i = argc; --i >= 0; ){
|
||||
r[14] -= strlen(argv[i]) + 1;
|
||||
nargv[i] = r[14];
|
||||
for(j = 0; argv[i][j] != 0; j++)
|
||||
writem(r[14] + j, argv[i][j], 0);
|
||||
}
|
||||
r[14] &= -4;
|
||||
push32(0);
|
||||
push32(0);
|
||||
push32(0);
|
||||
for(i = argc; --i >= 0; )
|
||||
push32(nargv[i]);
|
||||
push32(argc);
|
||||
free(nargv);
|
||||
}
|
||||
|
||||
static int
|
||||
shload(int fd, char *file, char **argv, char **envp)
|
||||
{
|
||||
char buf[256];
|
||||
char *s, *a;
|
||||
char *p;
|
||||
int rc;
|
||||
char **nargv, **pp;
|
||||
int n;
|
||||
|
||||
rc = read(fd, buf, sizeof(buf) - 1);
|
||||
if(rc <= 0){
|
||||
werrstr("invalid magic");
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
buf[rc] = 0;
|
||||
p = strchr(buf, '\n');
|
||||
if(p == nil) *p = 0;
|
||||
p = buf;
|
||||
while(isspace(*p)) p++;
|
||||
s = p;
|
||||
while(*p != 0 && !isspace(*p)) p++;
|
||||
if(*p != 0){
|
||||
*p = 0;
|
||||
while(isspace(*p)) p++;
|
||||
if(*p != 0){
|
||||
a = p;
|
||||
while(*p != 0 && !isspace(*p)) p++;
|
||||
}else a = nil;
|
||||
}else a = nil;
|
||||
for(n = 0; argv[n] != nil; n++)
|
||||
;
|
||||
nargv = emalloc((n + 3) * sizeof(char *));
|
||||
pp = nargv;
|
||||
*pp++ = s;
|
||||
if(a != nil) *pp++ = a;
|
||||
while(n--)
|
||||
*pp++ = *argv++;
|
||||
load(s, nargv, envp);
|
||||
free(nargv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
load(char *file, char **argv, char **envp)
|
||||
{
|
||||
uchar hdr[32];
|
||||
int fd;
|
||||
u32int hmagic, htext, hdata, hbss, hentry;
|
||||
|
||||
fd = open(file, OREAD);
|
||||
if(fd < 0) return -1;
|
||||
if(readn(fd, hdr, 2) < 2) return -1;
|
||||
if(hdr[0] == '#' && hdr[1] == '!')
|
||||
return shload(fd, file, argv, envp);
|
||||
if(readn(fd, hdr + 2, 30) < 30) return -1;
|
||||
hmagic = U32(&hdr[0]);
|
||||
htext = U32(&hdr[4]);
|
||||
hdata = U32(&hdr[8]);
|
||||
hbss = U32(&hdr[12]);
|
||||
hentry = U32(&hdr[20]);
|
||||
switch(hmagic){
|
||||
case ZMAGIC: case OMAGIC: case NMAGIC: break;
|
||||
default:
|
||||
werrstr("invalid magic %.6o", hmagic);
|
||||
return -1;
|
||||
}
|
||||
free(segs[0].data);
|
||||
free(segs[1].data);
|
||||
free(segs[2].data);
|
||||
segs[0].start = 0;
|
||||
segs[0].size = htext;
|
||||
segs[0].data = emalloc(-(-htext & -4));
|
||||
segs[1].start = -(-htext & -1024);
|
||||
segs[1].size = hdata + hbss;
|
||||
segs[1].data = emalloc(-(-(hdata + hbss) & -4));
|
||||
segs[2].start = 0x7ffff400 - STACKSIZE;
|
||||
segs[2].size = STACKSIZE;
|
||||
segs[2].data = emalloc(STACKSIZE);
|
||||
if(hmagic != OMAGIC)
|
||||
segs[0].flags = SEGRO;
|
||||
if(hmagic == ZMAGIC)
|
||||
seek(fd, 1024, 0);
|
||||
if(readn32(fd, segs[0].data, htext) < 0) exits(smprint("%r"));
|
||||
if(readn32(fd, segs[1].data, hdata) < 0) exits(smprint("%r"));
|
||||
close(fd);
|
||||
memset(r, 0, sizeof(r));
|
||||
r[15] = hentry + 2;
|
||||
setupstack(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
sysfatal("usage");
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
extern void fptest(void);
|
||||
|
||||
rfork(RFNAMEG);
|
||||
fptest();
|
||||
ARGBEGIN{
|
||||
case 'N':
|
||||
if(addns(nil, EARGF(usage())) < 0)
|
||||
sysfatal("addns: %r");
|
||||
break;
|
||||
default: usage();
|
||||
}ARGEND;
|
||||
|
||||
if(argc < 1) usage();
|
||||
sysinit();
|
||||
if(load(argv[0], argv, nil) < 0) sysfatal("load: %r");
|
||||
for(;;) step();
|
||||
}
|
Loading…
Reference in New Issue