Add original unix v6
This commit is contained in:
+285
@@ -0,0 +1,285 @@
|
||||
#
|
||||
/*
|
||||
* acct [ -w wtmp ] [ -d ] [ -p people ]
|
||||
*/
|
||||
|
||||
#define TSIZE 30
|
||||
#define USIZE 200
|
||||
|
||||
struct {
|
||||
char name[8];
|
||||
char tty;
|
||||
char fill1;
|
||||
float time;
|
||||
int fill2;
|
||||
} ibuf;
|
||||
|
||||
struct ubuf {
|
||||
char name[8];
|
||||
float utime;
|
||||
} ubuf[USIZE];
|
||||
|
||||
struct tbuf {
|
||||
struct ubuf *userp;
|
||||
float ttime;
|
||||
} tbuf[TSIZE];
|
||||
|
||||
char *wtmp;
|
||||
int pflag, byday;
|
||||
double dtime;
|
||||
double midnight;
|
||||
double lastime;
|
||||
double day 1440.;
|
||||
int pcount;
|
||||
char **pptr;
|
||||
|
||||
int montab[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
|
||||
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
char *monasc[] {
|
||||
"Jan",
|
||||
"Feb",
|
||||
"Mar",
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec"
|
||||
};
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
int c, fl;
|
||||
register i;
|
||||
register char *ip;
|
||||
extern fin;
|
||||
int f;
|
||||
|
||||
wtmp = "/usr/adm/wtmp";
|
||||
while (--argc > 0 && **++argv == '-')
|
||||
switch(*++*argv) {
|
||||
case 'd':
|
||||
byday++;
|
||||
continue;
|
||||
|
||||
case 'w':
|
||||
if (--argc>0)
|
||||
wtmp = *++argv;
|
||||
continue;
|
||||
|
||||
case 'p':
|
||||
pflag++;
|
||||
continue;
|
||||
}
|
||||
pcount = argc;
|
||||
pptr = argv;
|
||||
if (fopen(wtmp, &fin) < 0) {
|
||||
printf("No %s\n", wtmp);
|
||||
return;
|
||||
}
|
||||
for(;;) {
|
||||
ip = &ibuf;
|
||||
for (i=0; i<16; i++) {
|
||||
if ((c=getc(&fin)) < 0)
|
||||
goto brk;
|
||||
*ip++ = c;
|
||||
}
|
||||
fl = 0;
|
||||
for (i=0; i<8; i++) {
|
||||
c = ibuf.name[i];
|
||||
if ('0'<=c&&c<='9'||'a'<=c&&c<='z'||'A'<=c&&c<='Z') {
|
||||
if (fl)
|
||||
goto skip;
|
||||
continue;
|
||||
}
|
||||
if (c==' ' || c=='\0') {
|
||||
fl++;
|
||||
ibuf.name[i] = '\0';
|
||||
} else
|
||||
goto skip;
|
||||
}
|
||||
loop();
|
||||
skip:;
|
||||
}
|
||||
brk:
|
||||
ibuf.name[0] = '\0';
|
||||
ibuf.tty = '~';
|
||||
time(&ibuf.time);
|
||||
loop();
|
||||
print();
|
||||
}
|
||||
|
||||
loop()
|
||||
{
|
||||
double ltod();
|
||||
register i;
|
||||
register struct tbuf *tp;
|
||||
register struct ubuf *up;
|
||||
|
||||
if (ibuf.fill1||ibuf.fill2)
|
||||
return;
|
||||
ibuf.time = ltod(&ibuf.time)/60.;
|
||||
if(ibuf.tty == '|') {
|
||||
dtime = ibuf.time;
|
||||
return;
|
||||
}
|
||||
if(ibuf.tty == '}') {
|
||||
if(dtime == 0.)
|
||||
return;
|
||||
for(tp = tbuf; tp < &tbuf[TSIZE]; tp++)
|
||||
tp->ttime =+ ibuf.time-dtime;
|
||||
dtime = 0.;
|
||||
return;
|
||||
}
|
||||
if (lastime>ibuf.time || lastime+(1.5*day)<ibuf.time)
|
||||
midnight = 0.0;
|
||||
if (midnight==0.0)
|
||||
newday();
|
||||
lastime = ibuf.time;
|
||||
if (byday && ibuf.time > midnight) {
|
||||
upall(1);
|
||||
print();
|
||||
newday();
|
||||
for (up=ubuf; up < &ubuf[USIZE]; up++)
|
||||
up->utime = 0.0;
|
||||
}
|
||||
if (ibuf.tty == '~') {
|
||||
ibuf.name[0] = '\0';
|
||||
upall(0);
|
||||
return;
|
||||
}
|
||||
if ((i = ibuf.tty) >= 'a')
|
||||
i =- 'a' - '9';
|
||||
i =- '0';
|
||||
if (i<0 || i>=TSIZE)
|
||||
i = TSIZE-1;
|
||||
tp = &tbuf[i];
|
||||
update(tp, 0);
|
||||
}
|
||||
|
||||
print()
|
||||
{
|
||||
int i;
|
||||
float ttime, t;
|
||||
|
||||
ttime = 0.0;
|
||||
for (i=0; i<USIZE; i++) {
|
||||
if(!among(i))
|
||||
continue;
|
||||
t = ubuf[i].utime;
|
||||
if (t>0.0)
|
||||
ttime =+ t;
|
||||
if (pflag && ubuf[i].utime > 0.0) {
|
||||
printf("\t%-8.8s%6.2f\n",
|
||||
ubuf[i].name, ubuf[i].utime/60.);
|
||||
}
|
||||
}
|
||||
if (ttime > 0.0) {
|
||||
pdate();
|
||||
printf("\ttotal%9.2f\n", ttime/60.);
|
||||
}
|
||||
}
|
||||
|
||||
upall(f)
|
||||
{
|
||||
register struct tbuf *tp;
|
||||
|
||||
for (tp=tbuf; tp < &tbuf[TSIZE]; tp++)
|
||||
update(tp, f);
|
||||
}
|
||||
|
||||
update(tp, f)
|
||||
struct tbuf *tp;
|
||||
{
|
||||
int i, j;
|
||||
struct ubuf *up;
|
||||
double t, t1;
|
||||
|
||||
if (f)
|
||||
t = midnight;
|
||||
else
|
||||
t = ibuf.time;
|
||||
if (tp->userp) {
|
||||
t1 = t - tp->ttime;
|
||||
if (t1>0.0 && t1 < 1.5*day)
|
||||
tp->userp->utime =+ t1;
|
||||
}
|
||||
tp->ttime = t;
|
||||
if (f)
|
||||
return;
|
||||
if (ibuf.name[0]=='\0') {
|
||||
tp->userp = 0;
|
||||
return;
|
||||
}
|
||||
for (up=ubuf; up < &ubuf[USIZE]; up++) {
|
||||
if (up->name[0] == '\0')
|
||||
break;
|
||||
for (j=0; j<8 && up->name[j]==ibuf.name[j]; j++);
|
||||
if (j>=8)
|
||||
break;
|
||||
}
|
||||
for (j=0; j<8; j++)
|
||||
up->name[j] = ibuf.name[j];
|
||||
tp->userp = up;
|
||||
}
|
||||
|
||||
among(i)
|
||||
{
|
||||
register j, k;
|
||||
register char *p;
|
||||
|
||||
if (pcount==0)
|
||||
return(1);
|
||||
for (j=0; j<pcount; j++) {
|
||||
p = pptr[j];
|
||||
for (k=0; k<8; k++) {
|
||||
if (*p == ubuf[i].name[k]) {
|
||||
if (*p++ == '\0')
|
||||
return(1);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
newday()
|
||||
{
|
||||
if(midnight == 0.)
|
||||
midnight = 240.;
|
||||
while (midnight <= ibuf.time)
|
||||
midnight =+ day;
|
||||
}
|
||||
|
||||
pdate()
|
||||
{
|
||||
register days, mons, yrs;
|
||||
double year, tim;
|
||||
|
||||
if (byday==0)
|
||||
return;
|
||||
yrs = 2;
|
||||
tim = 0.0;
|
||||
for(;;) {
|
||||
year = 365. * day;
|
||||
if(yrs%4 == 0)
|
||||
year =+ day;
|
||||
if(tim+year > midnight)
|
||||
break;
|
||||
yrs++;
|
||||
tim =+ year;
|
||||
}
|
||||
days = (midnight-tim-720.)/day;
|
||||
montab[1] = 28;
|
||||
if(yrs%4 == 0)
|
||||
montab[1]++;
|
||||
for (mons=0; montab[mons]<=days; mons++)
|
||||
days =- montab[mons];
|
||||
mons =% 12;
|
||||
printf("%s %2d", monasc[mons], days+1);
|
||||
}
|
||||
+546
@@ -0,0 +1,546 @@
|
||||
/ ar -- archive/library
|
||||
|
||||
mov (sp)+,r0
|
||||
sub $2,r0
|
||||
ble userr
|
||||
tst (sp)+
|
||||
mov (sp)+,r1
|
||||
clr r2
|
||||
1:
|
||||
tstb (r1)
|
||||
beq 1f
|
||||
cmpb (r1),$'v
|
||||
bne 2f
|
||||
inc r1
|
||||
incb vflg
|
||||
br 1b
|
||||
2:
|
||||
tst r2
|
||||
bne userr
|
||||
movb (r1)+,r2
|
||||
br 1b
|
||||
1:
|
||||
tst r2
|
||||
beq userr
|
||||
mov $arglst,r1
|
||||
1:
|
||||
mov (sp)+,(r1)+
|
||||
dec r0
|
||||
bgt 1b
|
||||
clr (r1)+
|
||||
mov $swlst,r1
|
||||
1:
|
||||
cmp r2,(r1)+
|
||||
beq 1f
|
||||
tst (r1)+
|
||||
bne 1b
|
||||
br userr
|
||||
1:
|
||||
jmp *(r1)
|
||||
|
||||
swlst:
|
||||
'r; comr
|
||||
'u; comu
|
||||
'd; comd
|
||||
'x; comx
|
||||
't; comt
|
||||
0; 0
|
||||
|
||||
userr:
|
||||
jsr r5,diag
|
||||
<bad usage\n\0>
|
||||
.even
|
||||
|
||||
putc:
|
||||
movb r0,ch
|
||||
mov $1,r0
|
||||
sys write; ch; 1
|
||||
rts r5
|
||||
|
||||
print:
|
||||
movb (r1)+,r0
|
||||
beq 1f
|
||||
jsr r5,putc
|
||||
br print
|
||||
1:
|
||||
rts r5
|
||||
|
||||
diag:
|
||||
mov r5,r1
|
||||
jsr r5,print
|
||||
tst tfo
|
||||
beq 1f
|
||||
sys unlink; tfil
|
||||
1:
|
||||
sys exit
|
||||
|
||||
getaf:
|
||||
mov arglst,0f
|
||||
sys open; 0:..; 0
|
||||
bes 1f
|
||||
mov r0,afi
|
||||
sys read; buf; 2
|
||||
cmp buf,magic
|
||||
bne magerr
|
||||
tst (r5)+
|
||||
1:
|
||||
rts r5
|
||||
|
||||
magerr:
|
||||
mov arglst,r1
|
||||
jsr r5,print
|
||||
jsr r5,diag
|
||||
< -- not in archive format\n\0>
|
||||
.even
|
||||
|
||||
mktmp:
|
||||
sys stat; tfil; buf
|
||||
bes 1f
|
||||
incb tfil+8
|
||||
cmpb tfil+8,$'z
|
||||
blo mktmp
|
||||
br tferr
|
||||
1:
|
||||
sys signal; 2; 1
|
||||
ror r0
|
||||
bcs 1f
|
||||
sys signal; 2; done
|
||||
1:
|
||||
sys creat; tfil; 600
|
||||
bes tferr
|
||||
mov r0,tfo
|
||||
sys open; tfil; 0
|
||||
bes tferr
|
||||
mov r0,tfi
|
||||
rts r5
|
||||
|
||||
tferr:
|
||||
jsr r5,diag
|
||||
<cannot open temp file\n\0>
|
||||
.even
|
||||
|
||||
getdir:
|
||||
mov afi,r0
|
||||
sys read; dir; 16.
|
||||
cmp r0,$16.
|
||||
bne 1f
|
||||
jsr r5,mvname
|
||||
tst (r5)+
|
||||
1:
|
||||
rts r5
|
||||
|
||||
mvname:
|
||||
mov name,rname
|
||||
mov name+2,rname+2
|
||||
mov name+4,rname+4
|
||||
mov name+6,rname+6
|
||||
rts r5
|
||||
|
||||
skip:
|
||||
mov size,r0
|
||||
inc r0
|
||||
bic $1,r0
|
||||
mov r0,0f
|
||||
mov afi,r0
|
||||
sys seek; 0:..; 1
|
||||
rts r5
|
||||
|
||||
trim:
|
||||
mov r0,r2
|
||||
1:
|
||||
tstb (r0)
|
||||
beq 1f
|
||||
cmpb (r0)+,$'/
|
||||
beq trim
|
||||
br 1b
|
||||
1:
|
||||
rts r5
|
||||
|
||||
match:
|
||||
mov $arglst+2,r1
|
||||
1:
|
||||
mov (r1)+,r0
|
||||
beq 1f
|
||||
cmp r0,$-1
|
||||
beq 1b
|
||||
jsr r5,trim
|
||||
mov $name,r0
|
||||
2:
|
||||
cmp r0,$name+8.
|
||||
beq 2f
|
||||
cmpb (r0),(r2)+
|
||||
bne 1b
|
||||
tstb (r0)+
|
||||
bne 2b
|
||||
2:
|
||||
cmp (r5)+,-(r1)
|
||||
1:
|
||||
rts r5
|
||||
|
||||
mvfil:
|
||||
mov (r1),9f
|
||||
mov (r1),0f
|
||||
sys stat; 0:..; buf
|
||||
bes operr
|
||||
sys open; 9:..; 0
|
||||
bes operr
|
||||
mov r0,fio
|
||||
mov (r1),r0
|
||||
mov $-1,(r1)
|
||||
jsr r5,trim
|
||||
mov $name,r0
|
||||
1:
|
||||
cmp r0,$name+8.
|
||||
beq 1f
|
||||
movb (r2)+,(r0)+
|
||||
bne 1b
|
||||
1:
|
||||
mov buf+32.,mtim
|
||||
mov buf+34.,mtim+2
|
||||
movb buf+7.,ouid
|
||||
movb buf+4.,mode
|
||||
mov buf+10.,size
|
||||
mov tfo,r0
|
||||
sys write; dir; 16.
|
||||
mov size,r2
|
||||
1:
|
||||
mov fio,r0
|
||||
sys read; buf; 512.
|
||||
sub r0,r2
|
||||
mov r0,0f
|
||||
beq 1f
|
||||
mov tfo,r0
|
||||
sys write; buf; 0:..
|
||||
br 1b
|
||||
1:
|
||||
tst r2
|
||||
bne phserr
|
||||
bit $1,size
|
||||
beq 1f
|
||||
mov tfo,r0
|
||||
sys seek; 1; 1
|
||||
1:
|
||||
mov fio,r0
|
||||
sys close
|
||||
jsr r5,mvname
|
||||
rts r5
|
||||
|
||||
operr:
|
||||
mov 9b,r1
|
||||
jsr r5,print
|
||||
jsr r5,diag
|
||||
< -- cannot open\n\0>
|
||||
.even
|
||||
|
||||
phserr:
|
||||
mov 9b,r1
|
||||
jsr r5,print
|
||||
jsr r5,diag
|
||||
< -- phase error\n\0>
|
||||
.even
|
||||
|
||||
copyfl:
|
||||
mov tfo,r0
|
||||
sys write; dir; 16.
|
||||
mov size,r1
|
||||
mov $rname,9b
|
||||
1:
|
||||
mov r1,0f
|
||||
beq 1f
|
||||
cmp r1,$512.
|
||||
blo 2f
|
||||
mov $512.,0f
|
||||
2:
|
||||
mov afi,r0
|
||||
sys read; buf; 0:..
|
||||
sub r0,r1
|
||||
mov r0,0f
|
||||
beq phserr
|
||||
mov tfo,r0
|
||||
sys write; buf; 0:..
|
||||
br 1b
|
||||
1:
|
||||
bit $1,size
|
||||
beq 1f
|
||||
mov afi,r0
|
||||
sys seek; 1; 1
|
||||
mov tfo,r0
|
||||
sys seek; 1; 1
|
||||
1:
|
||||
rts r5
|
||||
|
||||
xtract:
|
||||
/ movb mode,0f
|
||||
sys creat; rname; 0:666
|
||||
bes noxerr
|
||||
mov r0,fio
|
||||
mov size,r1
|
||||
mov $rname,9b
|
||||
1:
|
||||
mov r1,0f
|
||||
beq 1f
|
||||
cmp r1,$512.
|
||||
blo 2f
|
||||
mov $512.,0f
|
||||
2:
|
||||
mov afi,r0
|
||||
sys read; buf; 0:..
|
||||
sub r0,r1
|
||||
mov r0,0f
|
||||
beq phserr
|
||||
mov fio,r0
|
||||
sys write; buf; 0:..
|
||||
br 1b
|
||||
1:
|
||||
mov fio,r0
|
||||
sys close
|
||||
bit $1,size
|
||||
beq 1f
|
||||
mov afi,r0
|
||||
sys seek; 1; 1
|
||||
1:
|
||||
mov r0,-(sp)
|
||||
mov r1,-(sp)
|
||||
mov mtim+2,r1
|
||||
mov mtim,r0
|
||||
/ sys mdate
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r1
|
||||
rts r5
|
||||
|
||||
noxerr:
|
||||
mov $rname,r1
|
||||
jsr r5,print
|
||||
jsr r5,diag
|
||||
< -- cannot create\n\0>
|
||||
.even
|
||||
|
||||
table:
|
||||
mov $rname,r1
|
||||
jsr r5,print
|
||||
mov $'\n,r0
|
||||
jsr r5,putc
|
||||
rts r5
|
||||
|
||||
mesg:
|
||||
mov r1,-(sp)
|
||||
mov (r5)+,r0
|
||||
tstb vflg
|
||||
beq 1f
|
||||
jsr r5,putc
|
||||
mov $' ,r0
|
||||
jsr r5,putc
|
||||
mov $rname,r1
|
||||
jsr r5,print
|
||||
mov $'\n,r0
|
||||
jsr r5,putc
|
||||
1:
|
||||
mov (sp)+,r1
|
||||
rts r5
|
||||
|
||||
oldnew:
|
||||
sys stat; rname; buf
|
||||
bes 1f
|
||||
cmp buf+32.,mtim
|
||||
blo 1f
|
||||
bhi 2f
|
||||
cmp buf+34.,mtim+2
|
||||
blos 1f
|
||||
2:
|
||||
tst (r5)+
|
||||
mov $rname,tname
|
||||
mov $tname,r1
|
||||
1:
|
||||
rts r5
|
||||
|
||||
comr:
|
||||
jsr r5,mktmp
|
||||
jsr r5,getaf
|
||||
br copfl
|
||||
1:
|
||||
jsr r5,getdir
|
||||
br copfl
|
||||
jsr r5,match
|
||||
br 2f
|
||||
jsr r5,mesg; 'r
|
||||
jsr r5,skip
|
||||
jsr r5,mvfil
|
||||
br 1b
|
||||
2:
|
||||
jsr r5,copyfl
|
||||
jsr r5,mesg; 'c
|
||||
br 1b
|
||||
|
||||
comu:
|
||||
jsr r5,mktmp
|
||||
jsr r5,getaf
|
||||
br noaf
|
||||
1:
|
||||
jsr r5,getdir
|
||||
br copfl
|
||||
tst arglst+2
|
||||
beq 2f
|
||||
jsr r5,match
|
||||
br 3f
|
||||
mov $-1,(r1)
|
||||
2:
|
||||
jsr r5,oldnew
|
||||
br 3f
|
||||
jsr r5,mesg; 'r
|
||||
jsr r5,skip
|
||||
jsr r5,mvfil
|
||||
br 1b
|
||||
3:
|
||||
jsr r5,copyfl
|
||||
jsr r5,mesg; 'c
|
||||
br 1b
|
||||
|
||||
comd:
|
||||
jsr r5,mktmp
|
||||
jsr r5,getaf
|
||||
br noaf
|
||||
1:
|
||||
jsr r5,getdir
|
||||
br 1f
|
||||
jsr r5,match
|
||||
br 2f
|
||||
mov $-1,(r1)
|
||||
jsr r5,skip
|
||||
jsr r5,mesg; 'd
|
||||
br 1b
|
||||
2:
|
||||
jsr r5,copyfl
|
||||
jsr r5,mesg; 'c
|
||||
br 1b
|
||||
1:
|
||||
jsr r5,nfound
|
||||
br copfl
|
||||
|
||||
noaf:
|
||||
jsr r5,diag
|
||||
<no archive file\n\0>
|
||||
.even
|
||||
|
||||
crterr:
|
||||
jsr r5,diag
|
||||
<cannot create archive file\n\0>
|
||||
.even
|
||||
|
||||
copfl:
|
||||
mov $arglst,r1
|
||||
mov (r1)+,0f
|
||||
1:
|
||||
tst (r1)+
|
||||
beq 1f
|
||||
cmp -2(r1),$-1
|
||||
beq 1b
|
||||
tst -(r1)
|
||||
jsr r5,mvfil
|
||||
jsr r5,mesg; 'a
|
||||
br 1b
|
||||
1:
|
||||
sys signal; 2; 1 / no interrupts during copy back
|
||||
sys creat; 0:..; 666
|
||||
bes crterr
|
||||
mov r0,afo
|
||||
sys write; magic; 2
|
||||
1:
|
||||
mov tfi,r0
|
||||
sys read; buf; 512.
|
||||
mov r0,0f
|
||||
beq done
|
||||
mov afo,r0
|
||||
sys write; buf; 0:..
|
||||
br 1b
|
||||
|
||||
done:
|
||||
jsr r5,diag
|
||||
<\0>
|
||||
.even
|
||||
|
||||
comx:
|
||||
jsr r5,getaf
|
||||
br noaf
|
||||
1:
|
||||
jsr r5,getdir
|
||||
br 1f
|
||||
tst arglst+2
|
||||
beq 3f
|
||||
jsr r5,match
|
||||
br 2f
|
||||
mov $-1,(r1)
|
||||
3:
|
||||
jsr r5,xtract
|
||||
jsr r5,mesg; 'x
|
||||
br 1b
|
||||
2:
|
||||
jsr r5,skip
|
||||
br 1b
|
||||
1:
|
||||
jsr r5,nfound
|
||||
br done
|
||||
|
||||
comt:
|
||||
jsr r5,getaf
|
||||
br noaf
|
||||
1:
|
||||
jsr r5,getdir
|
||||
br 1f
|
||||
tst arglst+2
|
||||
beq 2f
|
||||
jsr r5,match
|
||||
br 3f
|
||||
mov $-1,(r1)
|
||||
2:
|
||||
jsr r5,table
|
||||
3:
|
||||
jsr r5,skip
|
||||
br 1b
|
||||
1:
|
||||
jsr r5,nfound
|
||||
br done
|
||||
|
||||
nfound:
|
||||
mov $arglst+2,r2
|
||||
1:
|
||||
mov (r2)+,r1
|
||||
beq 1f
|
||||
cmp r1,$-1
|
||||
beq 1b
|
||||
mov $-1,-(r2)
|
||||
jsr r5,print
|
||||
mov $notfnd,r1
|
||||
jsr r5,print
|
||||
br 1b
|
||||
1:
|
||||
rts r5
|
||||
|
||||
notfnd:
|
||||
< -- not found\n\0>
|
||||
.even
|
||||
|
||||
tfil: </tmp/vtma\0>
|
||||
.even
|
||||
magic: -147.
|
||||
|
||||
.bss
|
||||
|
||||
afi: .=.+2
|
||||
afo: .=.+2
|
||||
tfi: .=.+2
|
||||
tfo: .=.+2
|
||||
fio: .=.+2
|
||||
rname: .=.+9.
|
||||
ch: .=.+1
|
||||
vflg: .=.+1
|
||||
.even
|
||||
tname: .=.+2
|
||||
dir:
|
||||
name: .=.+8.
|
||||
mtim: .=.+4
|
||||
ouid: .=.+1
|
||||
mode: .=.+1
|
||||
size: .=.+2
|
||||
arglst: .=.+200.
|
||||
buf: .=.+512.
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
#define nchars 64 /*number of chars in char set*/
|
||||
#define nlines 6 /*number of lines in a banner character*/
|
||||
#define pposs 85 /*number of print positions on a line (must be multiple of 4)*/
|
||||
/*followed by end of string character*/
|
||||
#define pospch 8 /*number of char positions per banner char*/
|
||||
#define chpln 10 /*number of banner characters per line*/
|
||||
|
||||
struct bann{
|
||||
char alpha[nlines][pposs];
|
||||
};
|
||||
struct bann buffer,*bp buffer;
|
||||
char ctbl[nchars][nlines]{
|
||||
036,041,046,051,046,035, /*@*/
|
||||
014,022,041,077,041,041, /*A*/
|
||||
076,041,076,041,041,076, /*B*/
|
||||
036,041,040,040,041,036, /*C*/
|
||||
076,041,041,041,041,076, /*D*/
|
||||
077,040,076,040,040,077, /*E*/
|
||||
077,040,076,040,040,040, /*F*/
|
||||
036,041,040,047,041,036, /*G*/
|
||||
041,041,077,041,041,041, /*H*/
|
||||
004,004,004,004,004,004, /*I*/
|
||||
001,001,001,001,041,036, /*J*/
|
||||
041,042,074,044,042,041, /*K*/
|
||||
040,040,040,040,040,077, /*L*/
|
||||
041,063,055,041,041,041, /*M*/
|
||||
041,061,051,045,043,041, /*N*/
|
||||
036,041,041,041,041,036, /*O*/
|
||||
076,041,041,076,040,040, /*P*/
|
||||
036,041,041,045,042,035, /*Q*/
|
||||
076,041,041,076,042,041, /*R*/
|
||||
036,040,036,001,041,036, /*S*/
|
||||
037,004,004,004,004,004, /*T*/
|
||||
041,041,041,041,041,036, /*U*/
|
||||
041,041,041,041,022,014, /*V*/
|
||||
041,041,041,055,063,041, /*W*/
|
||||
041,022,014,014,022,041, /*X*/
|
||||
021,012,004,004,004,004, /*Y*/
|
||||
077,002,004,010,020,077, /*Z*/
|
||||
016,010,010,010,010,016, /*[*/
|
||||
040,020,010,004,002,001, /*\*/
|
||||
034,004,004,004,004,034, /*]*/
|
||||
004,012,000,000,000,000, /*^*/
|
||||
000,000,000,000,000,077, /*_*/
|
||||
000,000,000,000,000,000, /* */
|
||||
010,010,010,010,000,010, /*!*/
|
||||
022,022,000,000,000,000, /*"*/
|
||||
022,077,022,022,077,022, /*#*/
|
||||
036,054,036,015,055,036, /*$*/
|
||||
001,062,064,013,023,040, /*%*/
|
||||
014,022,014,024,042,035, /*&*/
|
||||
010,010,000,000,000,000, /*'*/
|
||||
004,010,010,010,010,004, /*(*/
|
||||
010,004,004,004,004,010, /*)*/
|
||||
000,022,014,014,022,000 /***/
|
||||
};
|
||||
char blank ' ';
|
||||
char plot 'X';
|
||||
int msk 040; /*mask at sixth bit*/
|
||||
|
||||
main(argc,argp)
|
||||
char **argp;int argc;
|
||||
{
|
||||
int i;
|
||||
|
||||
/*if invoked with no arguments, prints error comment;
|
||||
if invoked with an argument, prints it in banner form.
|
||||
*/
|
||||
|
||||
if(argc<2){
|
||||
printf("missing argument\n");
|
||||
exit();
|
||||
}
|
||||
banner(argp[1],bp);
|
||||
banprt(bp);
|
||||
}
|
||||
|
||||
banner(s,bufp)
|
||||
char *s;struct bann *bufp;
|
||||
{
|
||||
char c,*p,*q,*r;
|
||||
p=s;
|
||||
r=bufp;
|
||||
banset(blank,bufp);
|
||||
|
||||
while((c= *s++)!=0){
|
||||
if((s-p)>chpln)return(s-p);
|
||||
if(c>='`')c =- ' '; /*map lower to upper case*/
|
||||
if(c<' ')c='#';
|
||||
if(c>'?')c=- 0100;
|
||||
q=ctbl[c];
|
||||
banfil(q,r);
|
||||
r=+pospch;
|
||||
}
|
||||
}
|
||||
|
||||
banfil(c,p)
|
||||
char *c;
|
||||
struct bann *p;
|
||||
{
|
||||
int i,j;
|
||||
for(i=0;i<nlines;i++){
|
||||
for(j=0;j<pospch;j++){
|
||||
if(((c[i]<<j)&msk)!=0)p->alpha[i][j] = plot;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
banset(c,p)
|
||||
char c;
|
||||
struct bann *p;
|
||||
{
|
||||
int i,j;
|
||||
for(i=0;i<nlines;i++)
|
||||
for(j=0;j<pposs-1;j++)
|
||||
p->alpha[i][j] = c;
|
||||
}
|
||||
|
||||
banprt(ptr)
|
||||
struct bann *ptr;
|
||||
{
|
||||
int i,j;
|
||||
for(i=0;i<nlines;i++){
|
||||
ptr->alpha[i][pposs-1]='\0';
|
||||
for(j=pposs-2;j>=0;j--){
|
||||
if(ptr->alpha[i][j]!=blank)break;
|
||||
ptr->alpha[i][j]='\0';
|
||||
}
|
||||
printf("%s\n",ptr->alpha[i]);
|
||||
}
|
||||
}
|
||||
+2113
File diff suppressed because it is too large
Load Diff
+567
@@ -0,0 +1,567 @@
|
||||
%right '='
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
%right '^'
|
||||
%left UMINUS
|
||||
|
||||
%term LETTER DIGIT SQRT _IF FFF EQ
|
||||
%term _WHILE _FOR NE LE GE INCR DECR
|
||||
%term _RETURN _BREAK _DEFINE BASE OBASE SCALE
|
||||
%term EQPL EQMI EQMUL EQDIV EQREM EQEXP
|
||||
%term _AUTO DOT
|
||||
%term QSTR
|
||||
|
||||
%{
|
||||
char cary[1000], *cp { cary };
|
||||
char string[1000], *str {string};
|
||||
int crs '0';
|
||||
int rcrs '0'; /* reset crs */
|
||||
int bindx 0;
|
||||
int lev 0;
|
||||
int bstack[10] { 0 };
|
||||
char *numb[15] {
|
||||
" 0", " 1", " 2", " 3", " 4", " 5",
|
||||
" 6", " 7", " 8", " 9", " 10", " 11",
|
||||
" 12", " 13", " 14" };
|
||||
int *pre, *post;
|
||||
%}
|
||||
%%
|
||||
start :
|
||||
| start stat tail
|
||||
= output( $2 );
|
||||
| start def dargs ')' '{' dlist slist '}'
|
||||
={ bundle( pre, $7, post );
|
||||
conout( $$, $2 );
|
||||
rcrs = crs;
|
||||
output( "" );
|
||||
lev = bindx = 0;
|
||||
}
|
||||
;
|
||||
|
||||
dlist : tail
|
||||
| dlist _AUTO dlets tail
|
||||
;
|
||||
|
||||
stat : e
|
||||
={ bundle( $1, "ps." ); }
|
||||
|
|
||||
={ bundle( "" ); }
|
||||
| QSTR
|
||||
={ bundle("[",$1,"]P");}
|
||||
| LETTER '=' e
|
||||
={ bundle( $3, "s", $1 ); }
|
||||
| LETTER '[' e ']' '=' e
|
||||
={ bundle( $6, $3, ":", geta($1)); }
|
||||
| LETTER EQOP e
|
||||
={ bundle( "l", $1, $3, $2, "s", $1 ); }
|
||||
| LETTER '[' e ']' EQOP e
|
||||
={ bundle($3, ";", geta($1), $6, $5, $3, ":", geta($1));}
|
||||
| _BREAK
|
||||
={ bundle( numb[lev-bstack[bindx-1]], "Q" ); }
|
||||
| _RETURN '(' e ')'
|
||||
= bundle( $3, post, numb[lev], "Q" );
|
||||
| _RETURN '(' ')'
|
||||
= bundle( "0", post, numb[lev], "Q" );
|
||||
| SCALE e
|
||||
= bundle( $2, "k" );
|
||||
| SCALE '=' e
|
||||
= bundle( $3, "k");
|
||||
| SCALE EQOP e
|
||||
= bundle("K",$3,$2,"k");
|
||||
| BASE e
|
||||
= bundle( $2, "i" );
|
||||
| BASE '=' e
|
||||
= bundle($3, "i");
|
||||
| BASE EQOP e
|
||||
= bundle("I",$3,$2,"i");
|
||||
| OBASE e
|
||||
= bundle( $2, "o" );
|
||||
| OBASE '=' e
|
||||
= bundle($3,"o");
|
||||
| OBASE EQOP e
|
||||
= bundle("O",$3,$2,"o");
|
||||
| '{' slist '}'
|
||||
={ $$ = $2; }
|
||||
| FFF
|
||||
={ bundle("f"); }
|
||||
| error
|
||||
={ bundle("c"); }
|
||||
| _IF CRS BLEV '(' re ')' stat
|
||||
={ conout( $7, $2 );
|
||||
bundle( $5, $2, " " );
|
||||
}
|
||||
| _WHILE CRS '(' re ')' stat BLEV
|
||||
={ bundle( $6, $4, $2 );
|
||||
conout( $$, $2 );
|
||||
bundle( $4, $2, " " );
|
||||
}
|
||||
| fprefix CRS re ';' e ')' stat BLEV
|
||||
={ bundle( $7, $5, "s.", $3, $2 );
|
||||
conout( $$, $2 );
|
||||
bundle( $1, "s.", $3, $2, " " );
|
||||
}
|
||||
| '~' LETTER '=' e
|
||||
={ bundle($4,"S",$2); }
|
||||
;
|
||||
|
||||
EQOP : EQPL
|
||||
={ $$ = "+"; }
|
||||
| EQMI
|
||||
={ $$ = "-"; }
|
||||
| EQMUL
|
||||
={ $$ = "*"; }
|
||||
| EQDIV
|
||||
={ $$ = "/"; }
|
||||
| EQREM
|
||||
={ $$ = "%%"; }
|
||||
| EQEXP
|
||||
={ $$ = "^"; }
|
||||
;
|
||||
|
||||
fprefix : _FOR '(' e ';'
|
||||
={ $$ = $3; }
|
||||
;
|
||||
|
||||
BLEV :
|
||||
={ --bindx; }
|
||||
;
|
||||
|
||||
slist : stat
|
||||
| slist tail stat
|
||||
={ bundle( $1, $3 ); }
|
||||
;
|
||||
|
||||
tail : '\n'
|
||||
| ';'
|
||||
;
|
||||
|
||||
re : e EQ e
|
||||
= bundle( $1, $3, "=" );
|
||||
| e '<' e
|
||||
= bundle( $1, $3, ">" );
|
||||
| e '>' e
|
||||
= bundle( $1, $3, "<" );
|
||||
| e NE e
|
||||
= bundle( $1, $3, "!=" );
|
||||
| e GE e
|
||||
= bundle( $1, $3, "!>" );
|
||||
| e LE e
|
||||
= bundle( $1, $3, "!<" );
|
||||
| e
|
||||
= bundle( $1, " 0!=" );
|
||||
;
|
||||
|
||||
e : e '+' e
|
||||
= bundle( $1, $3, "+" );
|
||||
| e '-' e
|
||||
= bundle( $1, $3, "-" );
|
||||
| '-' e %prec UMINUS
|
||||
= bundle( " 0", $2, "-" );
|
||||
| e '*' e
|
||||
= bundle( $1, $3, "*" );
|
||||
| e '/' e
|
||||
= bundle( $1, $3, "/" );
|
||||
| e '%' e
|
||||
= bundle( $1, $3, "%%" );
|
||||
| e '^' e
|
||||
= bundle( $1, $3, "^" );
|
||||
| LETTER '[' e ']'
|
||||
={ bundle($3, ";", geta($1)); }
|
||||
| LETTER INCR
|
||||
= bundle( "l", $1, "d1+s", $1 );
|
||||
| INCR LETTER
|
||||
= bundle( "l", $2, "1+ds", $2 );
|
||||
| DECR LETTER
|
||||
= bundle( "l", $2, "1-ds", $2 );
|
||||
| LETTER DECR
|
||||
= bundle( "l", $1, "d1-s", $1 );
|
||||
| LETTER '[' e ']' INCR
|
||||
= bundle($3,";",geta($1),"d1+",$3,":",geta($1));
|
||||
| INCR LETTER '[' e ']'
|
||||
= bundle($4,";",geta($2),"1+d",$4,":",geta($2));
|
||||
| LETTER '[' e ']' DECR
|
||||
= bundle($3,";",geta($1),"d1-",$3,":",geta($1));
|
||||
| DECR LETTER '[' e ']'
|
||||
= bundle($4,";",geta($2),"1-d",$4,":",geta($2));
|
||||
| SCALE INCR
|
||||
= bundle("Kd1+k");
|
||||
| INCR SCALE
|
||||
= bundle("K1+dk");
|
||||
| SCALE DECR
|
||||
= bundle("Kd1-k");
|
||||
| DECR SCALE
|
||||
= bundle("K1-dk");
|
||||
| BASE INCR
|
||||
= bundle("Id1+i");
|
||||
| INCR BASE
|
||||
= bundle("I1+di");
|
||||
| BASE DECR
|
||||
= bundle("Id1-i");
|
||||
| DECR BASE
|
||||
= bundle("I1-di");
|
||||
| OBASE INCR
|
||||
= bundle("Od1+o");
|
||||
| INCR OBASE
|
||||
= bundle("O1+do");
|
||||
| OBASE DECR
|
||||
= bundle("Od1-o");
|
||||
| DECR OBASE
|
||||
= bundle("O1-do");
|
||||
| LETTER '(' cargs ')'
|
||||
= bundle( $3, "l", getf($1), "x" );
|
||||
| LETTER '(' ')'
|
||||
= bundle( "l", getf($1), "x" );
|
||||
| cons
|
||||
={ bundle( " ", $1 ); }
|
||||
| DOT cons
|
||||
={ bundle( " .", $2 ); }
|
||||
| cons DOT cons
|
||||
={ bundle( " ", $1, ".", $3 ); }
|
||||
| cons DOT
|
||||
={ bundle( " ", $1, "." ); }
|
||||
| DOT
|
||||
={ $$ = "l."; }
|
||||
| LETTER
|
||||
= { bundle( "l", $1 ); }
|
||||
| LETTER '=' e
|
||||
={ bundle( $3, "ds", $1 ); }
|
||||
| LETTER EQOP e %prec '='
|
||||
={ bundle( "l", $1, $3, $2, "ds", $1 ); }
|
||||
| '(' e ')'
|
||||
= { $$ = $2; }
|
||||
| '?'
|
||||
={ bundle( "?" ); }
|
||||
| SQRT '(' e ')'
|
||||
={ bundle( $3, "v" ); }
|
||||
| '~' LETTER
|
||||
={ bundle("L",$2); }
|
||||
| SCALE e
|
||||
= bundle($2,"dk");
|
||||
| SCALE '=' e
|
||||
= bundle($3,"dk");
|
||||
| SCALE EQOP e %prec '='
|
||||
= bundle("K",$3,$2,"dk");
|
||||
| BASE e
|
||||
= bundle($2,"di");
|
||||
| BASE '=' e
|
||||
= bundle($3,"di");
|
||||
| BASE EQOP e %prec '='
|
||||
= bundle("I",$3,$2,"di");
|
||||
| OBASE e
|
||||
= bundle($2,"do");
|
||||
| OBASE '=' e
|
||||
= bundle($3,"do");
|
||||
| OBASE EQOP e %prec '='
|
||||
= bundle("O",$3,$2,"do");
|
||||
| SCALE
|
||||
= bundle("K");
|
||||
| BASE
|
||||
= bundle("I");
|
||||
| OBASE
|
||||
= bundle("O");
|
||||
;
|
||||
|
||||
cargs : eora
|
||||
| cargs ',' eora
|
||||
= bundle( $1, $3 );
|
||||
;
|
||||
eora: e
|
||||
| LETTER '[' ']'
|
||||
=bundle("l",geta($1));
|
||||
;
|
||||
|
||||
cons : constant
|
||||
={ *cp++ = '\0'; }
|
||||
|
||||
constant:
|
||||
'_'
|
||||
={ $$ = cp; *cp++ = '_'; }
|
||||
| DIGIT
|
||||
={ $$ = cp; *cp++ = $1; }
|
||||
| constant DIGIT
|
||||
={ *cp++ = $2; }
|
||||
;
|
||||
|
||||
CRS :
|
||||
={ $$ = cp; *cp++ = crs++; *cp++ = '\0'; bstack[bindx++] = lev++; }
|
||||
;
|
||||
|
||||
def : _DEFINE LETTER '('
|
||||
={ $$ = getf($2);
|
||||
pre = "";
|
||||
post = "";
|
||||
lev = 1;
|
||||
bstack[bindx=0] = 0;
|
||||
}
|
||||
;
|
||||
|
||||
dargs :
|
||||
| lora
|
||||
={ pp( $1 ); }
|
||||
| dargs ',' lora
|
||||
={ pp( $3 ); }
|
||||
;
|
||||
|
||||
dlets : lora
|
||||
={ tp($1); }
|
||||
| dlets ',' lora
|
||||
={ tp($3); }
|
||||
;
|
||||
lora : LETTER
|
||||
| LETTER '[' ']'
|
||||
={ $$ = geta($1); }
|
||||
;
|
||||
|
||||
%%
|
||||
# define error 256
|
||||
|
||||
int peekc -1;
|
||||
int sargc;
|
||||
int ifile;
|
||||
char **sargv;
|
||||
extern int fin;
|
||||
|
||||
char *funtab[26]{
|
||||
01,02,03,04,05,06,07,010,011,012,013,014,015,016,017,
|
||||
020,021,022,023,024,025,026,027,030,031,032 };
|
||||
char *atab[26]{
|
||||
0241,0242,0243,0244,0245,0246,0247,0250,0251,0252,0253,
|
||||
0254,0255,0256,0257,0260,0261,0262,0263,0264,0265,0266,
|
||||
0267,0270,0271,0272};
|
||||
char *letr[26] {
|
||||
"a","b","c","d","e","f","g","h","i","j",
|
||||
"k","l","m","n","o","p","q","r","s","t",
|
||||
"u","v","w","x","y","z" } ;
|
||||
char *dot { "." };
|
||||
yylex(){
|
||||
int c,ch;
|
||||
restart:
|
||||
c = getc();
|
||||
peekc = -1;
|
||||
while( c == ' ' || c == '\t' ) c = getc();
|
||||
if( c<= 'z' && c >= 'a' ) {
|
||||
/* look ahead to look for reserved words */
|
||||
peekc = getc();
|
||||
if( peekc >= 'a' && peekc <= 'z' ){ /* must be reserved word */
|
||||
if( c=='i' && peekc=='f' ){ c=_IF; goto skip; }
|
||||
if( c=='w' && peekc=='h' ){ c=_WHILE; goto skip; }
|
||||
if( c=='f' && peekc=='o' ){ c=_FOR; goto skip; }
|
||||
if( c=='s' && peekc=='q' ){ c=SQRT; goto skip; }
|
||||
if( c=='r' && peekc=='e' ){ c=_RETURN; goto skip; }
|
||||
if( c=='b' && peekc=='r' ){ c=_BREAK; goto skip; }
|
||||
if( c=='d' && peekc=='e' ){ c=_DEFINE; goto skip; }
|
||||
if( c=='s' && peekc=='c' ){ c= SCALE; goto skip; }
|
||||
if( c=='b' && peekc=='a' ){ c=BASE; goto skip; }
|
||||
if( c=='o' && peekc=='b' ){ c=OBASE; goto skip; }
|
||||
if( c=='d' && peekc=='i' ){ c=FFF; goto skip; }
|
||||
if( c=='a' && peekc=='u' ){ c=_AUTO; goto skip; }
|
||||
if( c == 'q' && peekc == 'u')getout();
|
||||
/* could not be found */
|
||||
return( error );
|
||||
skip: /* skip over rest of word */
|
||||
peekc = -1;
|
||||
while( (ch = getc()) >= 'a' && ch <= 'z' );
|
||||
peekc = ch;
|
||||
return( c );
|
||||
}
|
||||
|
||||
/* usual case; just one single letter */
|
||||
|
||||
yylval = letr[c-'a'];
|
||||
return( LETTER );
|
||||
}
|
||||
if( c>= '0' && c <= '9' || c>= 'A' && c<= 'F' ){
|
||||
yylval = c;
|
||||
return( DIGIT );
|
||||
}
|
||||
switch( c ){
|
||||
case '.': return( DOT );
|
||||
case '=':
|
||||
switch( peekc = getc() ){
|
||||
case '=': c=EQ; goto gotit;
|
||||
case '+': c=EQPL; goto gotit;
|
||||
case '-': c=EQMI; goto gotit;
|
||||
case '*': c=EQMUL; goto gotit;
|
||||
case '/': c=EQDIV; goto gotit;
|
||||
case '%': c=EQREM; goto gotit;
|
||||
case '^': c=EQEXP; goto gotit;
|
||||
default: return( '=' );
|
||||
gotit: peekc = -1; return(c);
|
||||
}
|
||||
case '+': return( cpeek( '+', INCR, '+' ) );
|
||||
case '-': return( cpeek( '-', DECR, '-' ) );
|
||||
case '<': return( cpeek( '=', LE, '<' ) );
|
||||
case '>': return( cpeek( '=', GE, '>' ) );
|
||||
case '!': return( cpeek( '=', NE, '!' ) );
|
||||
case '/':
|
||||
if((peekc = getc()) == '*'){
|
||||
peekc = -1;
|
||||
while((getc() != '*') || ((peekc = getc()) != '/'));
|
||||
peekc = -1;
|
||||
goto restart;
|
||||
}
|
||||
else return(c);
|
||||
case '"':
|
||||
yylval = str;
|
||||
while((c=getc()) != '"')*str++ = c;
|
||||
*str++ = '\0';
|
||||
return(QSTR);
|
||||
default: return( c );
|
||||
}
|
||||
}
|
||||
|
||||
cpeek( c, yes, no ){
|
||||
if( (peekc=getc()) != c ) return( no );
|
||||
else {
|
||||
peekc = -1;
|
||||
return( yes );
|
||||
}
|
||||
}
|
||||
|
||||
getc(){
|
||||
int ch;
|
||||
loop:
|
||||
ch = (peekc < 0) ? getchar() : peekc;
|
||||
peekc = -1;
|
||||
if(ch != '\0')return(ch);
|
||||
if(++ifile > sargc){
|
||||
if(ifile >= sargc+2)getout();
|
||||
fin = dup(0);
|
||||
goto loop;
|
||||
}
|
||||
close(fin);
|
||||
if((fin = open(sargv[ifile],0)) >= 0)goto loop;
|
||||
yyerror("cannot open input file");
|
||||
}
|
||||
# define b_sp_max 1500
|
||||
int b_space [ b_sp_max ];
|
||||
int * b_sp_nxt { b_space };
|
||||
|
||||
bdebug 0;
|
||||
bundle(a){
|
||||
int i, *p, *q;
|
||||
|
||||
i = nargs();
|
||||
q = b_sp_nxt;
|
||||
|
||||
if( bdebug ) printf("bundle %d elements at %o\n", i, q );
|
||||
|
||||
for( p = &a; i-->0; ++p ){
|
||||
|
||||
if( b_sp_nxt >= & b_space[b_sp_max] ) yyerror( "bundling space exceeded" );
|
||||
|
||||
* b_sp_nxt++ = *p;
|
||||
}
|
||||
* b_sp_nxt++ = 0;
|
||||
yyval = q;
|
||||
return( q );
|
||||
}
|
||||
|
||||
routput(p) int *p; {
|
||||
if( bdebug ) printf("routput(%o)\n", p );
|
||||
if( p >= &b_space[0] && p < &b_space[b_sp_max]){
|
||||
/* part of a bundle */
|
||||
while( *p != 0 ) routput( *p++ );
|
||||
}
|
||||
else printf( p ); /* character string */
|
||||
}
|
||||
|
||||
output( p ) int *p; {
|
||||
routput( p );
|
||||
b_sp_nxt = & b_space[0];
|
||||
printf( "\n" );
|
||||
cp = cary;
|
||||
str = string;
|
||||
crs = rcrs;
|
||||
}
|
||||
|
||||
conout( p, s ) int *p; char *s; {
|
||||
printf("[");
|
||||
routput( p );
|
||||
printf("]s%s\n", s );
|
||||
lev--;
|
||||
str = string;
|
||||
}
|
||||
|
||||
yyerror( s ) char *s; {
|
||||
printf("c[%s]pc\n", s );
|
||||
cp = cary;
|
||||
crs = rcrs;
|
||||
bindx = 0;
|
||||
lev = 0;
|
||||
b_sp_nxt = &b_space[0];
|
||||
str = string;
|
||||
}
|
||||
|
||||
pp( s ) char *s; {
|
||||
/* puts the relevant stuff on pre and post for the letter s */
|
||||
|
||||
bundle( "S", s, pre );
|
||||
pre = yyval;
|
||||
bundle( post, "L", s, "s." );
|
||||
post = yyval;
|
||||
}
|
||||
|
||||
tp( s ) char *s; { /* same as pp, but for temps */
|
||||
bundle( "0S", s, pre );
|
||||
pre = yyval;
|
||||
bundle( post, "L", s, "s." );
|
||||
post = yyval;
|
||||
}
|
||||
|
||||
yyinit(argc,argv) int argc; char *argv[];{
|
||||
int (*getout)();
|
||||
signal( 2, getout ); /* ignore all interrupts */
|
||||
sargv=argv;
|
||||
sargc= -- argc;
|
||||
if(sargc == 0)fin=dup(0);
|
||||
else if((fin = open(sargv[1],0)) < 0)
|
||||
yyerror("cannot open input file");
|
||||
ifile = 1;
|
||||
}
|
||||
getout(){
|
||||
printf("q");
|
||||
exit();
|
||||
}
|
||||
|
||||
getf(p) char *p;{
|
||||
return(&funtab[*p -0141]);
|
||||
}
|
||||
geta(p) char *p;{
|
||||
return(&atab[*p - 0141]);
|
||||
}
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
int p[2];
|
||||
|
||||
|
||||
if (argc > 1 && *argv[1] == '-') {
|
||||
if(argv[1][1] == 'd'){
|
||||
yyinit(--argc, ++argv);
|
||||
yyparse();
|
||||
exit();
|
||||
}
|
||||
if(argv[1][1] != 'l'){
|
||||
printf("unrecognizable argument\n");
|
||||
exit();
|
||||
}
|
||||
argv[1] = "/usr/lib/lib.b";
|
||||
}
|
||||
pipe(p);
|
||||
if (fork()==0) {
|
||||
close(1);
|
||||
dup(p[1]);
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
yyinit(argc, argv);
|
||||
yyparse();
|
||||
exit();
|
||||
}
|
||||
close(0);
|
||||
dup(p[0]);
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
execl("/bin/dc", "dc", "-", 0);
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
int chtab[]{
|
||||
00000, /* */
|
||||
03004, /* ! */
|
||||
02404, /* " */
|
||||
02040, /* sharp */
|
||||
02042, /* $ */
|
||||
02104, /* % */
|
||||
00001, /* & */
|
||||
03002, /* ' */
|
||||
02201, /* ( */
|
||||
02202, /* ) */
|
||||
02102, /* * */
|
||||
00005, /* + */
|
||||
02044, /* , */
|
||||
00002, /* - */
|
||||
02041, /* . */
|
||||
00014, /* / */
|
||||
00004, /* 0 */
|
||||
00010, /* 1 */
|
||||
00020, /* 2 */
|
||||
00040, /* 3 */
|
||||
00100, /* 4 */
|
||||
00200, /* 5 */
|
||||
00400, /* 6 */
|
||||
01000, /* 7 */
|
||||
02000, /* 8 */
|
||||
04000, /* 9 */
|
||||
02200, /* : */
|
||||
02402, /* ; */
|
||||
02401, /* < */
|
||||
02204, /* = */
|
||||
02400, /* > */
|
||||
03000, /* ? */
|
||||
02100, /* at */
|
||||
011,
|
||||
021,
|
||||
041,
|
||||
0101,
|
||||
0201,
|
||||
0401,
|
||||
01001,
|
||||
02001,
|
||||
04001,
|
||||
012,
|
||||
022,
|
||||
042,
|
||||
0102,
|
||||
0202,
|
||||
0402,
|
||||
01002,
|
||||
02002,
|
||||
02002,
|
||||
024,
|
||||
044,
|
||||
0104,
|
||||
0204,
|
||||
0404,
|
||||
01004,
|
||||
02004,
|
||||
04004,
|
||||
02020, /* [ */
|
||||
03001, /* \ */
|
||||
02101, /* ] */
|
||||
00006, /* ^ */
|
||||
02024 /* _ */
|
||||
};
|
||||
char s[128];
|
||||
char *sp {&s[0]};
|
||||
main(argc, argv)
|
||||
char *argv[];
|
||||
{
|
||||
char *spp;
|
||||
int i;
|
||||
int j;
|
||||
int c;
|
||||
int l;
|
||||
|
||||
if (argc<2) {
|
||||
puts("% ");
|
||||
while ((c=getchar())!='\0'&c!='\n')
|
||||
*sp++ = c;
|
||||
*sp = 0;
|
||||
sp = &s[0];
|
||||
} else
|
||||
sp = *++argv;
|
||||
puts("\n\n\n\n");
|
||||
puts(" ________________________________");
|
||||
puts("________________\n");
|
||||
spp = sp;
|
||||
while(*spp++);
|
||||
spp--;
|
||||
l = spp - sp;
|
||||
putchar('/');
|
||||
puts(sp);
|
||||
i = 49 - l;
|
||||
while(--i>0) putchar(' ');
|
||||
puts("|\n");
|
||||
j = 0;
|
||||
spp = sp;
|
||||
while (j++<12) {
|
||||
putchar('|');
|
||||
i = 0;
|
||||
spp = sp;
|
||||
while (i<48) {
|
||||
c = *spp++ - 040;
|
||||
i++;
|
||||
if (c>='a'-040) c = c - 040;
|
||||
if (i>l) c = 0;
|
||||
if (c<0 | c>137) c = 0;
|
||||
if ((chtab[c]>>(j-1))&1)
|
||||
puts("[]");
|
||||
else
|
||||
putchar(j>3?'0'+j-3:' ');
|
||||
}
|
||||
puts("|\n");
|
||||
}
|
||||
putchar('|');
|
||||
puts("____________");
|
||||
puts("____________________________________");
|
||||
puts("|\n");
|
||||
puts("\n\n\n\n");
|
||||
}
|
||||
|
||||
puts(ss) char *ss; {
|
||||
int i;
|
||||
char t;
|
||||
i = 0;
|
||||
while(t = *ss++) {
|
||||
if(t >= 'a' && t <= 'z')
|
||||
t =+ 'A'-'a';
|
||||
putchar(t);
|
||||
}
|
||||
}
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
char dayw[]
|
||||
{
|
||||
" S M Tu W Th F S"
|
||||
};
|
||||
char *smon[]
|
||||
{
|
||||
"Jan", "Feb", "Mar", "Apr",
|
||||
"May", "Jun", "Jul", "Aug",
|
||||
"Sep", "Oct", "Nov", "Dec",
|
||||
};
|
||||
char string[432];
|
||||
main(argc, argv)
|
||||
char *argv[];
|
||||
{
|
||||
register y, i, j;
|
||||
int m;
|
||||
|
||||
if(argc < 2) {
|
||||
printf("usage: cal [month] year\n");
|
||||
exit();
|
||||
}
|
||||
if(argc == 2)
|
||||
goto xlong;
|
||||
|
||||
/*
|
||||
* print out just month
|
||||
*/
|
||||
|
||||
m = number(argv[1]);
|
||||
if(m<1 || m>12)
|
||||
goto badarg;
|
||||
y = number(argv[2]);
|
||||
if(y<1 || y>9999)
|
||||
goto badarg;
|
||||
printf(" %s %l\n", smon[m-1], y);
|
||||
printf("%s\n", dayw);
|
||||
cal(m, y, string, 24);
|
||||
for(i=0; i<6*24; i=+24)
|
||||
pstr(string+i, 24);
|
||||
exit();
|
||||
|
||||
/*
|
||||
* print out complete year
|
||||
*/
|
||||
|
||||
xlong:
|
||||
y = number(argv[1]);
|
||||
if(y<1 || y>9999)
|
||||
goto badarg;
|
||||
printf("\n\n\n");
|
||||
printf(" %l\n", y);
|
||||
printf("\n");
|
||||
for(i=0; i<12; i=+3) {
|
||||
for(j=0; j<6*72; j++)
|
||||
string[j] = '\0';
|
||||
printf(" %s", smon[i]);
|
||||
printf(" %s", smon[i+1]);
|
||||
printf(" %s\n", smon[i+2]);
|
||||
printf("%s %s %s\n", dayw, dayw, dayw);
|
||||
cal(i+1, y, string, 72);
|
||||
cal(i+2, y, string+23, 72);
|
||||
cal(i+3, y, string+46, 72);
|
||||
for(j=0; j<6*72; j=+72)
|
||||
pstr(string+j, 72);
|
||||
}
|
||||
printf("\n\n\n");
|
||||
exit();
|
||||
|
||||
badarg:
|
||||
printf("Bad argument\n");
|
||||
}
|
||||
|
||||
number(str)
|
||||
char *str;
|
||||
{
|
||||
register n, c;
|
||||
register char *s;
|
||||
|
||||
n = 0;
|
||||
s = str;
|
||||
while(c = *s++) {
|
||||
if(c<'0' || c>'9')
|
||||
return(0);
|
||||
n = n*10 + c-'0';
|
||||
}
|
||||
return(n);
|
||||
}
|
||||
|
||||
pstr(str, n)
|
||||
char *str;
|
||||
{
|
||||
register i;
|
||||
register char *s;
|
||||
|
||||
s = str;
|
||||
i = n;
|
||||
while(i--)
|
||||
if(*s++ == '\0')
|
||||
s[-1] = ' ';
|
||||
i = n+1;
|
||||
while(i--)
|
||||
if(*--s != ' ')
|
||||
break;
|
||||
s[1] = '\0';
|
||||
printf("%s\n", str);
|
||||
}
|
||||
|
||||
char mon[]
|
||||
{
|
||||
0,
|
||||
31, 29, 31, 30,
|
||||
31, 30, 31, 31,
|
||||
30, 31, 30, 31,
|
||||
};
|
||||
|
||||
cal(m, y, p, w)
|
||||
char *p;
|
||||
{
|
||||
register d, i;
|
||||
register char *s;
|
||||
|
||||
s = p;
|
||||
d = jan1(y);
|
||||
mon[2] = 29;
|
||||
mon[9] = 30;
|
||||
|
||||
switch((jan1(y+1)+7-d)%7) {
|
||||
|
||||
/*
|
||||
* non-leap year
|
||||
*/
|
||||
case 1:
|
||||
mon[2] = 28;
|
||||
break;
|
||||
|
||||
/*
|
||||
* 1752
|
||||
*/
|
||||
default:
|
||||
mon[9] = 19;
|
||||
break;
|
||||
|
||||
/*
|
||||
* leap year
|
||||
*/
|
||||
case 2:
|
||||
;
|
||||
}
|
||||
for(i=1; i<m; i++)
|
||||
d =+ mon[i];
|
||||
d =% 7;
|
||||
s =+ 3*d;
|
||||
for(i=1; i<=mon[m]; i++) {
|
||||
if(i==3 & mon[m]==19) {
|
||||
i =+ 11;
|
||||
mon[m] =+ 11;
|
||||
}
|
||||
if(i > 9)
|
||||
*s = i/10+'0';
|
||||
s++;
|
||||
*s++ = i%10+'0';
|
||||
s++;
|
||||
if(++d == 7) {
|
||||
d = 0;
|
||||
s = p+w;
|
||||
p = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* return day of the week
|
||||
* of jan 1 of given year
|
||||
*/
|
||||
|
||||
jan1(yr)
|
||||
{
|
||||
register y, d;
|
||||
|
||||
/*
|
||||
* normal gregorian calendar
|
||||
* one extra day per four years
|
||||
*/
|
||||
|
||||
y = yr;
|
||||
d = 4+y+(y+3)/4;
|
||||
|
||||
/*
|
||||
* julian calendar
|
||||
* regular gregorian
|
||||
* less three days per 400
|
||||
*/
|
||||
|
||||
if(y > 1800) {
|
||||
d =- (y-1701)/100;
|
||||
d =+ (y-1601)/400;
|
||||
}
|
||||
|
||||
/*
|
||||
* great calendar changeover instant
|
||||
*/
|
||||
|
||||
if(y > 1752)
|
||||
d =+ 3;
|
||||
|
||||
return(d%7);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/ cat -- concatinate files
|
||||
|
||||
mov (sp)+,r5
|
||||
tst (sp)+
|
||||
mov $obuf,r2
|
||||
cmp r5,$1
|
||||
beq 3f
|
||||
|
||||
loop:
|
||||
dec r5
|
||||
ble done
|
||||
mov (sp)+,r0
|
||||
cmpb (r0),$'-
|
||||
bne 2f
|
||||
clr fin
|
||||
br 3f
|
||||
2:
|
||||
mov r0,0f
|
||||
sys open; 0:..; 0
|
||||
bes loop
|
||||
mov r0,fin
|
||||
3:
|
||||
mov fin,r0
|
||||
sys read; ibuf; 512.
|
||||
bes 3f
|
||||
mov r0,r4
|
||||
beq 3f
|
||||
mov $ibuf,r3
|
||||
4:
|
||||
movb (r3)+,r0
|
||||
jsr pc,putc
|
||||
dec r4
|
||||
bne 4b
|
||||
br 3b
|
||||
3:
|
||||
mov fin,r0
|
||||
beq loop
|
||||
sys close
|
||||
br loop
|
||||
|
||||
done:
|
||||
sub $obuf,r2
|
||||
beq 1f
|
||||
mov r2,0f
|
||||
mov $1,r0
|
||||
sys write; obuf; 0:..
|
||||
1:
|
||||
sys exit
|
||||
|
||||
putc:
|
||||
movb r0,(r2)+
|
||||
cmp r2,$obuf+512.
|
||||
blo 1f
|
||||
mov $1,r0
|
||||
sys write; obuf; 512.
|
||||
mov $obuf,r2
|
||||
1:
|
||||
rts pc
|
||||
|
||||
.bss
|
||||
ibuf: .=.+512.
|
||||
obuf: .=.+512.
|
||||
fin: .=.+2
|
||||
.text
|
||||
|
||||
+811
@@ -0,0 +1,811 @@
|
||||
#define SBSIZE 2000
|
||||
char sbf[SBSIZE];
|
||||
/* C command */
|
||||
|
||||
char *tmp0;
|
||||
char *tmp1;
|
||||
char *tmp2;
|
||||
char *tmp3;
|
||||
char *tmp4;
|
||||
char *tmp5;
|
||||
char ts[1000];
|
||||
char *tsp ts;
|
||||
char *av[50];
|
||||
char *clist[50];
|
||||
char *llist[50];
|
||||
int instring;
|
||||
int pflag;
|
||||
int sflag;
|
||||
int cflag;
|
||||
int oflag;
|
||||
int proflag;
|
||||
int depth;
|
||||
int *ibuf;
|
||||
int *ibuf1;
|
||||
int *ibuf2;
|
||||
int *obuf;
|
||||
char *lp;
|
||||
char *line;
|
||||
int lineno;
|
||||
int exfail;
|
||||
struct symtab {
|
||||
char name[8];
|
||||
char *value;
|
||||
} *symtab;
|
||||
int symsiz 200;
|
||||
struct symtab *defloc;
|
||||
struct symtab *incloc;
|
||||
struct symtab *eifloc;
|
||||
struct symtab *ifdloc;
|
||||
struct symtab *ifnloc;
|
||||
struct symtab *unxloc;
|
||||
int trulvl;
|
||||
int flslvl;
|
||||
char *stringbuf;
|
||||
char *pass0 "/lib/c0";
|
||||
char *pass1 "/lib/c1";
|
||||
char *pass2 "/lib/c2";
|
||||
char *pref "/lib/crt0.o";
|
||||
|
||||
main(argc, argv)
|
||||
char *argv[]; {
|
||||
char *t;
|
||||
int nc, nl, i, j, c, f20, nxo;
|
||||
int dexit();
|
||||
|
||||
i = nc = nl = f20 = nxo = 0;
|
||||
while(++i < argc) {
|
||||
if(*argv[i] == '-')
|
||||
switch (argv[i][1]) {
|
||||
default:
|
||||
goto passa;
|
||||
case 'S':
|
||||
sflag++;
|
||||
cflag++;
|
||||
break;
|
||||
case 'O':
|
||||
oflag++;
|
||||
break;
|
||||
case 'p':
|
||||
proflag++;
|
||||
pref = "/lib/mcrt0.o";
|
||||
break;
|
||||
case 'P':
|
||||
pflag++;
|
||||
case 'c':
|
||||
cflag++;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
pref = "/lib/fcrt0.o";
|
||||
pass0 = "/lib/fc0";
|
||||
pass1 = "/lib/fc1";
|
||||
break;
|
||||
|
||||
case '2':
|
||||
if(argv[i][2] == '\0')
|
||||
pref = "/lib/crt2.o";
|
||||
else {
|
||||
pref = "/lib/crt20.o";
|
||||
f20 = 1;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
if (argv[i][2]=='0')
|
||||
pass0 = "/usr/c/c0";
|
||||
if (argv[i][2]=='1')
|
||||
pass1 = "/usr/c/c1";
|
||||
if (argv[i][2]=='2')
|
||||
pass2 = "/usr/c/c2";
|
||||
break;
|
||||
}
|
||||
else {
|
||||
passa:
|
||||
t = argv[i];
|
||||
if(getsuf(t)=='c') {
|
||||
clist[nc++] = t;
|
||||
t = setsuf(t, 'o');
|
||||
}
|
||||
if (nodup(llist, t)) {
|
||||
llist[nl++] = t;
|
||||
if (getsuf(t)=='o')
|
||||
nxo++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(nc==0)
|
||||
goto nocom;
|
||||
if (pflag==0) {
|
||||
tmp0 = copy("/tmp/ctm0a");
|
||||
while((c=open(tmp0, 0))>=0) {
|
||||
close(c);
|
||||
tmp0[9]++;
|
||||
}
|
||||
while((creat(tmp0, 0400))<0)
|
||||
tmp0[9]++;
|
||||
}
|
||||
if ((signal(2, 1) & 01) == 0)
|
||||
signal(2, &dexit);
|
||||
(tmp1 = copy(tmp0))[8] = '1';
|
||||
(tmp2 = copy(tmp0))[8] = '2';
|
||||
(tmp3 = copy(tmp0))[8] = '3';
|
||||
if (oflag)
|
||||
(tmp5 = copy(tmp0))[8] = '5';
|
||||
if (pflag==0)
|
||||
(tmp4 = copy(tmp0))[8] = '4';
|
||||
for (i=0; i<nc; i++) {
|
||||
if (nc>1)
|
||||
printf("%s:\n", clist[i]);
|
||||
av[0] = "c0";
|
||||
if (pflag)
|
||||
tmp4 = setsuf(clist[i], 'i');
|
||||
av[1] = expand(clist[i]);
|
||||
if (pflag || exfail)
|
||||
continue;
|
||||
if (av[1] == 0) {
|
||||
cflag++;
|
||||
continue;
|
||||
}
|
||||
av[2] = tmp1;
|
||||
av[3] = tmp2;
|
||||
if (proflag) {
|
||||
av[4] = "-P";
|
||||
av[5] = 0;
|
||||
} else
|
||||
av[4] = 0;
|
||||
if (callsys(pass0, av)) {
|
||||
cflag++;
|
||||
continue;
|
||||
}
|
||||
av[0] = "c1";
|
||||
av[1] = tmp1;
|
||||
av[2] = tmp2;
|
||||
if (sflag)
|
||||
tmp3 = setsuf(clist[i], 's');
|
||||
av[3] = tmp3;
|
||||
if (oflag)
|
||||
av[3] = tmp5;
|
||||
av[4] = 0;
|
||||
if(callsys(pass1, av)) {
|
||||
cflag++;
|
||||
continue;
|
||||
}
|
||||
if (oflag) {
|
||||
av[0] = "c2";
|
||||
av[1] = tmp5;
|
||||
av[2] = tmp3;
|
||||
av[3] = 0;
|
||||
callsys(pass2, av);
|
||||
unlink(tmp5);
|
||||
}
|
||||
if (sflag)
|
||||
continue;
|
||||
av[0] = "as";
|
||||
av[1] = "-";
|
||||
av[2] = tmp3;
|
||||
av[3] = 0;
|
||||
cunlink(tmp1);
|
||||
cunlink(tmp2);
|
||||
cunlink(tmp4);
|
||||
callsys("/bin/as", av);
|
||||
t = setsuf(clist[i], 'o');
|
||||
cunlink(t);
|
||||
if(link("a.out", t) || cunlink("a.out")) {
|
||||
printf("move failed: %s\n", t);
|
||||
cflag++;
|
||||
}
|
||||
}
|
||||
nocom:
|
||||
if (cflag==0 && nl!=0) {
|
||||
i = 0;
|
||||
av[0] = "ld";
|
||||
av[1] = "-X";
|
||||
av[2] = pref;
|
||||
j = 3;
|
||||
while(i<nl)
|
||||
av[j++] = llist[i++];
|
||||
if(f20)
|
||||
av[j++] = "-l2";
|
||||
else {
|
||||
av[j++] = "-lc";
|
||||
av[j++] = "-l";
|
||||
}
|
||||
av[j++] = 0;
|
||||
callsys("/bin/ld", av);
|
||||
if (nc==1 && nxo==1)
|
||||
cunlink(setsuf(clist[0], 'o'));
|
||||
}
|
||||
dexit();
|
||||
}
|
||||
|
||||
dexit()
|
||||
{
|
||||
if (!pflag) {
|
||||
cunlink(tmp1);
|
||||
cunlink(tmp2);
|
||||
if (sflag==0)
|
||||
cunlink(tmp3);
|
||||
cunlink(tmp4);
|
||||
cunlink(tmp5);
|
||||
cunlink(tmp0);
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
expand(file)
|
||||
char *file;
|
||||
{
|
||||
int ib1[259], ib2[259], ob[259];
|
||||
struct symtab stab[200];
|
||||
char ln[196];
|
||||
register int c;
|
||||
register char *rlp;
|
||||
|
||||
exfail = 0;
|
||||
ibuf = ibuf1 = ib1;
|
||||
ibuf2 = ib2;
|
||||
if (fopen(file, ibuf1)<0)
|
||||
return(file);
|
||||
if (getc(ibuf1) != '#') {
|
||||
close(ibuf1[0]);
|
||||
return(file);
|
||||
}
|
||||
ibuf1[1]++;
|
||||
ibuf1[2]--;
|
||||
obuf = ob;
|
||||
symtab = stab;
|
||||
for (c=0; c<200; c++) {
|
||||
stab[c].name[0] = '\0';
|
||||
stab[c].value = 0;
|
||||
}
|
||||
insym(&defloc, "define");
|
||||
insym(&incloc, "include");
|
||||
insym(&eifloc, "endif");
|
||||
insym(&ifdloc, "ifdef");
|
||||
insym(&ifnloc, "ifndef");
|
||||
insym(&unxloc, "unix");
|
||||
stringbuf = sbf;
|
||||
trulvl = 0;
|
||||
flslvl = 0;
|
||||
line = ln;
|
||||
lineno = 0;
|
||||
if (fcreat(tmp4, obuf) < 0) {
|
||||
printf("Can't creat %s\n", tmp4);
|
||||
dexit();
|
||||
}
|
||||
while(getline()) {
|
||||
if (ibuf==ibuf2 && pflag==0)
|
||||
putc(001, obuf); /*SOH: insert */
|
||||
if (ln[0] != '#' && flslvl==0)
|
||||
for (rlp = line; c = *rlp++;)
|
||||
putc(c, obuf);
|
||||
putc('\n', obuf);
|
||||
}
|
||||
for(rlp=line; c = *rlp++;)
|
||||
putc(c,obuf);
|
||||
fflush(obuf);
|
||||
close(obuf[0]);
|
||||
close(ibuf1[0]);
|
||||
return(tmp4);
|
||||
}
|
||||
|
||||
getline()
|
||||
{
|
||||
register int c, sc, state;
|
||||
struct symtab *np;
|
||||
char *namep, *filname;
|
||||
|
||||
if (ibuf==ibuf1)
|
||||
lineno++;
|
||||
lp = line;
|
||||
*lp = '\0';
|
||||
state = 0;
|
||||
if ((c=getch()) == '#')
|
||||
state = 1;
|
||||
while (c!='\n' && c!='\0') {
|
||||
if ('a'<=c && c<='z' || 'A'<=c && c<='Z' || c=='_') {
|
||||
namep = lp;
|
||||
sch(c);
|
||||
while ('a'<=(c=getch()) && c<='z'
|
||||
||'A'<=c && c<='Z'
|
||||
||'0'<=c && c<='9'
|
||||
||c=='_')
|
||||
sch(c);
|
||||
sch('\0');
|
||||
lp--;
|
||||
if (state>3) {
|
||||
if (flslvl==0 &&(state+!lookup(namep,-1)->name[0])==5)
|
||||
trulvl++;
|
||||
else
|
||||
flslvl++;
|
||||
out:
|
||||
while (c!='\n' && c!= '\0')
|
||||
c = getch();
|
||||
return(c);
|
||||
}
|
||||
if (state!=2 || flslvl==0)
|
||||
{
|
||||
ungetc(c);
|
||||
np = lookup(namep, state);
|
||||
c = getch();
|
||||
}
|
||||
if (state==1) {
|
||||
if (np==defloc)
|
||||
state = 2;
|
||||
else if (np==incloc)
|
||||
state = 3;
|
||||
else if (np==ifnloc)
|
||||
state = 4;
|
||||
else if (np==ifdloc)
|
||||
state = 5;
|
||||
else if (np==eifloc) {
|
||||
if (flslvl)
|
||||
--flslvl;
|
||||
else if (trulvl)
|
||||
--trulvl;
|
||||
else error("If-less endif");
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
error("Undefined control");
|
||||
while (c!='\n' && c!='\0')
|
||||
c = getch();
|
||||
return(c);
|
||||
}
|
||||
} else if (state==2) {
|
||||
if (flslvl)
|
||||
goto out;
|
||||
np->value = stringbuf;
|
||||
savch(c);
|
||||
while ((c=getch())!='\n' && c!='\0')
|
||||
savch(c);
|
||||
savch('\0');
|
||||
return(1);
|
||||
}
|
||||
continue;
|
||||
} else if ((sc=c)=='\'' || sc=='"') {
|
||||
sch(sc);
|
||||
filname = lp;
|
||||
instring++;
|
||||
while ((c=getch())!=sc && c!='\n' && c!='\0') {
|
||||
sch(c);
|
||||
if (c=='\\')
|
||||
sch(getch());
|
||||
}
|
||||
instring = 0;
|
||||
if (flslvl)
|
||||
goto out;
|
||||
if (state==3) {
|
||||
if (flslvl)
|
||||
goto out;
|
||||
*lp = '\0';
|
||||
while ((c=getch())!='\n' && c!='\0');
|
||||
if (ibuf==ibuf2)
|
||||
error("Nested 'include'");
|
||||
if (fopen(filname, ibuf2)<0)
|
||||
error("Missing file %s", filname);
|
||||
else
|
||||
ibuf = ibuf2;
|
||||
return(c);
|
||||
}
|
||||
}
|
||||
sch(c);
|
||||
c = getch();
|
||||
}
|
||||
sch('\0');
|
||||
if (state>1)
|
||||
error("Control syntax");
|
||||
return(c);
|
||||
}
|
||||
|
||||
insym(sp, namep)
|
||||
struct symtab **sp;
|
||||
char *namep;
|
||||
{
|
||||
register struct symtab *np;
|
||||
|
||||
*sp = np = lookup(namep, 1);
|
||||
np->value = np->name;
|
||||
}
|
||||
|
||||
error(s, x)
|
||||
{
|
||||
printf("%d: ", lineno);
|
||||
printf(s, x);
|
||||
putchar('\n');
|
||||
exfail++;
|
||||
cflag++;
|
||||
}
|
||||
|
||||
sch(c)
|
||||
{
|
||||
register char *rlp;
|
||||
|
||||
rlp = lp;
|
||||
if (rlp==line+194)
|
||||
error("Line overflow");
|
||||
*rlp++ = c;
|
||||
if (rlp>line+195)
|
||||
rlp = line+195;
|
||||
lp = rlp;
|
||||
}
|
||||
|
||||
savch(c)
|
||||
{
|
||||
*stringbuf++ = c;
|
||||
if (stringbuf-sbf < SBSIZE)
|
||||
return;
|
||||
error("Too much defining");
|
||||
dexit();
|
||||
}
|
||||
|
||||
getch()
|
||||
{
|
||||
register int c;
|
||||
|
||||
loop:
|
||||
if ((c=getc1())=='/' && !instring) {
|
||||
if ((c=getc1())!='*')
|
||||
{
|
||||
ungetc(c);
|
||||
return('/');
|
||||
}
|
||||
for(;;) {
|
||||
c = getc1();
|
||||
cloop:
|
||||
switch (c) {
|
||||
|
||||
case '\0':
|
||||
return('\0');
|
||||
|
||||
case '*':
|
||||
if ((c=getc1())=='/')
|
||||
goto loop;
|
||||
goto cloop;
|
||||
|
||||
case '\n':
|
||||
if (ibuf==ibuf1) {
|
||||
putc('\n', obuf);
|
||||
lineno++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(c);
|
||||
}
|
||||
char pushbuff[300];
|
||||
char *pushp pushbuff;
|
||||
ungetc(c)
|
||||
{
|
||||
*++pushp = c;
|
||||
}
|
||||
|
||||
getc1()
|
||||
{
|
||||
register c;
|
||||
|
||||
if (*pushp !=0)
|
||||
return(*pushp--);
|
||||
depth=0;
|
||||
if ((c = getc(ibuf)) < 0 && ibuf==ibuf2) {
|
||||
close(ibuf2[0]);
|
||||
ibuf = ibuf1;
|
||||
putc('\n', obuf);
|
||||
lineno++;
|
||||
c = getc1();
|
||||
}
|
||||
if (c<0)
|
||||
return(0);
|
||||
return(c);
|
||||
}
|
||||
|
||||
lookup(namep, enterf)
|
||||
char *namep;
|
||||
{
|
||||
register char *np, *snp;
|
||||
register struct symtab *sp;
|
||||
int i, c, around;
|
||||
np = namep;
|
||||
around = i = 0;
|
||||
while (c = *np++)
|
||||
i =+ c;
|
||||
i =% symsiz;
|
||||
sp = &symtab[i];
|
||||
while (sp->name[0]) {
|
||||
snp = sp;
|
||||
np = namep;
|
||||
while (*snp++ == *np)
|
||||
if (*np++ == '\0' || np==namep+8) {
|
||||
if (!enterf)
|
||||
subst(namep, sp);
|
||||
return(sp);
|
||||
}
|
||||
if (++sp >= &symtab[symsiz])
|
||||
if (around++)
|
||||
{
|
||||
error("too many defines");
|
||||
dexit();
|
||||
}
|
||||
else
|
||||
sp = symtab;
|
||||
}
|
||||
if (enterf>0) {
|
||||
snp = namep;
|
||||
for (np = &sp->name[0]; np < &sp->name[8];)
|
||||
if (*np++ = *snp)
|
||||
snp++;
|
||||
}
|
||||
return(sp);
|
||||
}
|
||||
char revbuff[200];
|
||||
char *bp;
|
||||
backsch(c)
|
||||
{
|
||||
if (bp-revbuff > 200)
|
||||
error("Excessive define looping", bp--);
|
||||
*bp++ = c;
|
||||
}
|
||||
|
||||
subst(np, sp)
|
||||
char *np;
|
||||
struct symtab *sp;
|
||||
{
|
||||
register char *vp;
|
||||
|
||||
lp = np;
|
||||
bp = revbuff;
|
||||
if (depth++>100)
|
||||
{
|
||||
error("define recursion loop\n");
|
||||
return;
|
||||
}
|
||||
if ((vp = sp->value) == 0)
|
||||
return;
|
||||
/* arrange that define unix unix still
|
||||
has no effect, avoiding rescanning */
|
||||
if (streq(sp->name,sp->value))
|
||||
{
|
||||
while (*vp)
|
||||
sch(*vp++);
|
||||
return;
|
||||
}
|
||||
backsch(' ');
|
||||
if (*vp == '(')
|
||||
expdef(vp);
|
||||
else
|
||||
while (*vp)
|
||||
backsch(*vp++);
|
||||
backsch(' ');
|
||||
while (bp>revbuff)
|
||||
ungetc(*--bp);
|
||||
}
|
||||
|
||||
getsuf(as)
|
||||
char as[];
|
||||
{
|
||||
register int c;
|
||||
register char *s;
|
||||
register int t;
|
||||
|
||||
s = as;
|
||||
c = 0;
|
||||
while(t = *s++)
|
||||
if (t=='/')
|
||||
c = 0;
|
||||
else
|
||||
c++;
|
||||
s =- 3;
|
||||
if (c<=14 && c>2 && *s++=='.')
|
||||
return(*s);
|
||||
return(0);
|
||||
}
|
||||
|
||||
setsuf(as, ch)
|
||||
char as[];
|
||||
{
|
||||
register char *s, *s1;
|
||||
|
||||
s = s1 = copy(as);
|
||||
while(*s)
|
||||
if (*s++ == '/')
|
||||
s1 = s;
|
||||
s[-1] = ch;
|
||||
return(s1);
|
||||
}
|
||||
|
||||
callsys(f, v)
|
||||
char f[], *v[]; {
|
||||
int t, status;
|
||||
|
||||
if ((t=fork())==0) {
|
||||
execv(f, v);
|
||||
printf("Can't find %s\n", f);
|
||||
exit(1);
|
||||
} else
|
||||
if (t == -1) {
|
||||
printf("Try again\n");
|
||||
return(1);
|
||||
}
|
||||
while(t!=wait(&status));
|
||||
if ((t=(status&0377)) != 0 && t!=14) {
|
||||
if (t!=2) /* interrupt */
|
||||
printf("Fatal error in %s\n", f);
|
||||
dexit();
|
||||
}
|
||||
return((status>>8) & 0377);
|
||||
}
|
||||
|
||||
copy(as)
|
||||
char as[];
|
||||
{
|
||||
register char *otsp, *s;
|
||||
|
||||
otsp = tsp;
|
||||
s = as;
|
||||
while(*tsp++ = *s++);
|
||||
return(otsp);
|
||||
}
|
||||
|
||||
nodup(l, os)
|
||||
char **l, *os;
|
||||
{
|
||||
register char *t, *s;
|
||||
register int c;
|
||||
|
||||
s = os;
|
||||
if (getsuf(s) != 'o')
|
||||
return(1);
|
||||
while(t = *l++) {
|
||||
while(c = *s++)
|
||||
if (c != *t++)
|
||||
break;
|
||||
if (*t=='\0' && c=='\0')
|
||||
return(0);
|
||||
s = os;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
cunlink(f)
|
||||
char *f;
|
||||
{
|
||||
if (f==0)
|
||||
return(0);
|
||||
return(unlink(f));
|
||||
}
|
||||
expdef(proto)
|
||||
char *proto;
|
||||
{
|
||||
char buffer[100], *parg[20], *pval[20], name[20], *cspace, *wp;
|
||||
char protcop[100], *pr;
|
||||
int narg, k, i, c;
|
||||
pr = protcop;
|
||||
while (*pr++ = *proto++);
|
||||
proto= protcop;
|
||||
for (narg=0; (parg[narg] = token(&proto)) != 0; narg++)
|
||||
;
|
||||
/* now scan input */
|
||||
cspace = buffer;
|
||||
while ((c=getch()) == ' ');
|
||||
if (c != '(')
|
||||
{
|
||||
error("defined function requires arguments");
|
||||
return;
|
||||
}
|
||||
ungetc(c);
|
||||
for(k=0; pval[k] = coptok(&cspace); k++);
|
||||
if (k!=narg)
|
||||
{
|
||||
error("define argument mismatch");
|
||||
return;
|
||||
}
|
||||
while (c= *proto++)
|
||||
{
|
||||
if (!letter(c))
|
||||
backsch(c);
|
||||
else
|
||||
{
|
||||
wp = name;
|
||||
*wp++ = c;
|
||||
while (letnum(*proto))
|
||||
*wp++ = *proto++;
|
||||
*wp = 0;
|
||||
for (k=0; k<narg; k++)
|
||||
if(streq(name,parg[k]))
|
||||
break;
|
||||
wp = k <narg ? pval[k] : name;
|
||||
while (*wp) backsch(*wp++);
|
||||
}
|
||||
}
|
||||
}
|
||||
token(cpp) char **cpp;
|
||||
{
|
||||
char *val;
|
||||
int stc;
|
||||
stc = **cpp;
|
||||
*(*cpp)++ = '\0';
|
||||
if (stc==')') return(0);
|
||||
while (**cpp == ' ') (*cpp)++;
|
||||
for (val = *cpp; (stc= **cpp) != ',' && stc!= ')'; (*cpp)++)
|
||||
{
|
||||
if (!letnum(stc) || (val == *cpp && !letter(stc)))
|
||||
{
|
||||
error("define prototype argument error");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(val);
|
||||
}
|
||||
coptok (cpp) char **cpp; {
|
||||
char *val;
|
||||
int stc, stop,paren;
|
||||
paren = 0;
|
||||
val = *cpp;
|
||||
if (getch() == ')')
|
||||
return(0);
|
||||
while (((stc = getch()) != ',' && stc != ')') || paren > 0)
|
||||
{
|
||||
if (stc == '"' || stc == '\'')
|
||||
{
|
||||
stop = stc;
|
||||
if (stop == '\'')
|
||||
*(*cpp)++ = '\'';
|
||||
while ( (stc = getch()) != stop)
|
||||
{
|
||||
if (stc == '\n')
|
||||
{
|
||||
error ("non-terminated string");
|
||||
break;
|
||||
}
|
||||
if (stc == '\\')
|
||||
if ((stc= getch()) != stop && stc != '\\')
|
||||
*(*cpp)++ = '\\';
|
||||
*(*cpp)++ = stc;
|
||||
}
|
||||
if (stop == '\'')
|
||||
*(*cpp)++ = '\'';
|
||||
}
|
||||
else if (stc == '\\')
|
||||
{
|
||||
stc = getch();
|
||||
if (stc != '"' && stc != '\\')
|
||||
*(*cpp)++ = '\\';
|
||||
*(*cpp)++ = stc;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(*cpp)++ = stc;
|
||||
if (stc == '(')
|
||||
paren++;
|
||||
if (stc == ')')
|
||||
paren--;
|
||||
}
|
||||
}
|
||||
*(*cpp)++ = 0;
|
||||
ungetc(stc);
|
||||
return(val);
|
||||
}
|
||||
letter(c)
|
||||
{
|
||||
if ((c >= 'a' && c <= 'z') ||
|
||||
(c >= 'A' && c <= 'Z') ||
|
||||
(c == '_'))
|
||||
return (1);
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
letnum(c)
|
||||
{
|
||||
if (letter(c) || (c >= '0' && c <= '9'))
|
||||
return(1);
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
streq(s,t) char *s, *t;
|
||||
{
|
||||
int c;
|
||||
while ( (c= *s++) == *t++)
|
||||
if (c==0) return(1);
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,965 @@
|
||||
#
|
||||
/*
|
||||
|
||||
C debugger
|
||||
|
||||
*/
|
||||
|
||||
#include "/usr/sys/param.h"
|
||||
#include "/usr/sys/user.h"
|
||||
|
||||
#define DSP 0
|
||||
#define ISP 1
|
||||
#define NBKP 10
|
||||
#define SYMSIZ 12*400
|
||||
#define BADJST 01
|
||||
|
||||
int fcore;
|
||||
int errno;
|
||||
int fsym;
|
||||
int symoff;
|
||||
char *lp;
|
||||
int errflg;
|
||||
int symlen;
|
||||
int symct;
|
||||
int symcor;
|
||||
int symbuf[SYMSIZ];
|
||||
int *symptr;
|
||||
struct {
|
||||
int loc;
|
||||
int ins;
|
||||
int count;
|
||||
int flag;
|
||||
} bkptl[NBKP];
|
||||
int lastbp;
|
||||
char symbol[8];
|
||||
int symflg;
|
||||
int symval;
|
||||
char tsym[8];
|
||||
char fsymbol[10];
|
||||
char ssymbol[8];
|
||||
int ssymflg;
|
||||
int ssymval;
|
||||
int signo;
|
||||
char line[128];
|
||||
int regbuf[512];
|
||||
char **uregs ®buf[512];
|
||||
char *rtsize;
|
||||
int loccsv;
|
||||
int locsr5;
|
||||
#define RUSER 1
|
||||
#define RIUSER 2
|
||||
#define WUSER 4
|
||||
#define RUREGS 3
|
||||
#define WUREGS 6
|
||||
#define SETTRC 0
|
||||
#define CONTIN 7
|
||||
#define EXIT 8
|
||||
|
||||
#define ps -1
|
||||
#define pc -2
|
||||
#define sp -6
|
||||
#define r5 -9
|
||||
#define r4 -10
|
||||
#define r3 -11
|
||||
#define r2 -12
|
||||
#define r1 -5
|
||||
#define r0 -3
|
||||
struct reglist {
|
||||
char *rname;
|
||||
int roffs;
|
||||
} reglist[] {
|
||||
"ps", ps,
|
||||
"pc", pc,
|
||||
"sp", sp,
|
||||
"r5", r5,
|
||||
"r4", r4,
|
||||
"r3", r3,
|
||||
"r2", r2,
|
||||
"r1", r1,
|
||||
"r0", r0,
|
||||
};
|
||||
|
||||
struct sfregs {
|
||||
int junk[2];
|
||||
int fpsr;
|
||||
float sfr[6];
|
||||
};
|
||||
|
||||
struct lfregs {
|
||||
int junk[2];
|
||||
int fpsr;
|
||||
double lfr[6];
|
||||
};
|
||||
|
||||
int frnames[] { 0, 3, 4, 5, 1, 2 };
|
||||
int dot;
|
||||
int tdot;
|
||||
int dotinc 2;
|
||||
int lastcom '/';
|
||||
int lastype 'o';
|
||||
int modifier;
|
||||
char *symfil "a.out";
|
||||
char *corfil "core";
|
||||
int callist[50];
|
||||
int entpt[50];
|
||||
int callev;
|
||||
int pid;
|
||||
int adrflg;
|
||||
int idsep;
|
||||
char *signals[] {
|
||||
"",
|
||||
"Hangup",
|
||||
"Interrupt",
|
||||
"Quit",
|
||||
"Illegal instruction",
|
||||
"Trace/BTP",
|
||||
"IOT",
|
||||
"EMT",
|
||||
"Floating exception",
|
||||
"Killed",
|
||||
"Bus error",
|
||||
"Memory fault",
|
||||
"Bad system call",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
};
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
int onintr();
|
||||
|
||||
if (argc>1)
|
||||
symfil = argv[1];
|
||||
if (argc>2)
|
||||
corfil = argv[2];
|
||||
fcore = open(corfil, 0);
|
||||
if ((fsym = open(symfil, 0)) < 0) {
|
||||
printf("%s not found\n", symfil);
|
||||
return;
|
||||
}
|
||||
read(fsym, regbuf, 020);
|
||||
if (regbuf[0]==0411) /* I/D separated */
|
||||
idsep++;
|
||||
else if (regbuf[0]!=0410 && regbuf[0]!=0407) { /* magic */
|
||||
printf("Bad format: %s\n", symfil);
|
||||
return;
|
||||
}
|
||||
symoff = regbuf[1] + regbuf[2];
|
||||
symlen = regbuf[4];
|
||||
if (regbuf[7] != 1)
|
||||
symoff =<< 1;
|
||||
symoff =+ 020;
|
||||
seek(fsym, symoff, 0);
|
||||
symcor = read(fsym, symbuf, sizeof symbuf);
|
||||
if (symcor>0)
|
||||
symoff =+ symcor;
|
||||
symcor =>> 1;
|
||||
read(fcore, regbuf, 1024);
|
||||
signo = regbuf[0].u_arg[0]&017;
|
||||
regbuf->u_tsize =<< 6;
|
||||
regbuf->u_dsize =<< 6;
|
||||
regbuf->u_ssize =<< 6;
|
||||
rtsize = (regbuf->u_tsize+017777) & ~017777;
|
||||
if (symlook("csv\0\0\0\0"))
|
||||
loccsv = ssymval;
|
||||
if (symlook("savr5\0\0\0"))
|
||||
locsr5 = ssymval;
|
||||
setstack();
|
||||
signal(SIGINS, onintr);
|
||||
setexit();
|
||||
signal(SIGINT, onintr);
|
||||
loop:
|
||||
if (errflg) {
|
||||
printf("?\n");
|
||||
errflg = 0;
|
||||
}
|
||||
lp = line;
|
||||
while ((*lp = getchar()) != '\n')
|
||||
if (*lp++ == '\0') {
|
||||
if (pid)
|
||||
ptrace(EXIT, pid, 0, 0);
|
||||
return;
|
||||
}
|
||||
lp = line;
|
||||
command();
|
||||
goto loop;
|
||||
}
|
||||
|
||||
command()
|
||||
{
|
||||
register n;
|
||||
|
||||
adrflg = expr();
|
||||
if (errflg)
|
||||
return;
|
||||
n = getcnt();
|
||||
if (lastcom=='$')
|
||||
lastcom = '/';
|
||||
if (*lp == '\n') {
|
||||
if (!adrflg)
|
||||
dot =+ dotinc;
|
||||
} else
|
||||
lastcom = *lp++;
|
||||
modifier = 0;
|
||||
if (*lp != '\n')
|
||||
modifier = *lp++;
|
||||
if (lastcom=='%' && modifier=='r') {
|
||||
runcom();
|
||||
return;
|
||||
}
|
||||
if (*lp != '\n') {
|
||||
errflg++;
|
||||
return;
|
||||
}
|
||||
if (adrflg)
|
||||
dot = tdot;
|
||||
while(n) {
|
||||
scommand(n);
|
||||
if (errflg)
|
||||
return;
|
||||
if (--n)
|
||||
dot =+ dotinc;
|
||||
}
|
||||
}
|
||||
|
||||
scommand(n)
|
||||
{
|
||||
register w, c;
|
||||
double fw;
|
||||
struct { int i[4]; };
|
||||
int onintr();
|
||||
|
||||
switch(lastcom) {
|
||||
|
||||
case '/':
|
||||
w = cget(dot, DSP);
|
||||
if (modifier)
|
||||
lastype = modifier;
|
||||
switch(lastype) {
|
||||
|
||||
case 'o':
|
||||
printf("%.1o\n", w);
|
||||
dotinc = 2;
|
||||
return;
|
||||
|
||||
case 'i':
|
||||
printf("%d\n", w);
|
||||
dotinc = 2;
|
||||
return;
|
||||
|
||||
case 'f':
|
||||
fw = 0;
|
||||
fw.i[0] = w;
|
||||
fw.i[1] = cget(dot+2, DSP);
|
||||
printf("%e\n", fw);
|
||||
dotinc = 4;
|
||||
return;
|
||||
|
||||
case 'd':
|
||||
fw.i[0] = w;
|
||||
fw.i[1] = cget(dot+2, DSP);
|
||||
fw.i[2] = cget(dot+4, DSP);
|
||||
fw.i[3] = cget(dot+6, DSP);
|
||||
printf("%e\n", fw);
|
||||
dotinc = 8;
|
||||
return;
|
||||
}
|
||||
errflg++;
|
||||
return;
|
||||
|
||||
case '\\':
|
||||
printf("%.1o\n", cget(dot, DSP)&0377);
|
||||
dotinc = 1;
|
||||
return;
|
||||
|
||||
case '=':
|
||||
printf("%.1o\n", dot);
|
||||
return;
|
||||
|
||||
case '\'':
|
||||
printc(cget(dot, DSP) & 0377);
|
||||
if (n<=1)
|
||||
putchar('\n');
|
||||
dotinc = 1;
|
||||
return;
|
||||
|
||||
case '"':
|
||||
w = cget(dot, DSP);
|
||||
while(c = cget(w++, DSP)&0377)
|
||||
printc(c);
|
||||
putchar('\n');
|
||||
return;
|
||||
|
||||
case '&':
|
||||
psymoff(cget(dot, DSP), 0100000);
|
||||
printf("\n");
|
||||
return;
|
||||
|
||||
case '$':
|
||||
printf("%s\n", signals[signo]);
|
||||
printtrace();
|
||||
return;
|
||||
|
||||
case '?':
|
||||
printins(0);
|
||||
printf("\n");
|
||||
return;
|
||||
|
||||
case '%':
|
||||
runcom();
|
||||
signal(SIGINT, onintr);
|
||||
return;
|
||||
|
||||
}
|
||||
errflg++;
|
||||
}
|
||||
|
||||
getcnt()
|
||||
{
|
||||
register t1, t2;
|
||||
|
||||
if (*lp != ',')
|
||||
return(1);
|
||||
lp++;
|
||||
t1 = tdot;
|
||||
if (expr() == 0) {
|
||||
tdot = t1;
|
||||
return(1);
|
||||
}
|
||||
t2 = tdot;
|
||||
tdot = t1;
|
||||
return(t2);
|
||||
}
|
||||
|
||||
cget(n, space)
|
||||
{
|
||||
register w;
|
||||
|
||||
w = get(n, space);
|
||||
if (errflg)
|
||||
reset();
|
||||
return(w);
|
||||
}
|
||||
|
||||
printc(c)
|
||||
{
|
||||
if (c<' ' || c>'~')
|
||||
printf("\\%o", c);
|
||||
else
|
||||
printf("%c", c);
|
||||
}
|
||||
|
||||
expr()
|
||||
{
|
||||
int i, t1, t2, donef, lastop, b;
|
||||
|
||||
tdot = 0;
|
||||
adrflg = 0;
|
||||
lastop = '+';
|
||||
ssymval = 0;
|
||||
donef = 0;
|
||||
loop:
|
||||
fsymbol[0] = 0;
|
||||
if (symchar(0)) {
|
||||
adrflg++;
|
||||
symcollect('_');
|
||||
if (*lp++==':' && symchar(0)) {
|
||||
for (i=0; i<8; i++)
|
||||
fsymbol[i] = tsym[i];
|
||||
fsymbol[0] = '~';
|
||||
symcollect(0);
|
||||
} else
|
||||
lp--;
|
||||
if (symlook(tsym) == 0) {
|
||||
errflg++;
|
||||
reset();
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
if (*lp>='0' && *lp<='9') {
|
||||
adrflg++;
|
||||
ssymval = 0;
|
||||
if (*lp == '0')
|
||||
b = 8;
|
||||
else
|
||||
b = 10;
|
||||
while (*lp>='0' && *lp<='9') {
|
||||
ssymval =* b;
|
||||
ssymval =+ *lp++ -'0';
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
switch (*lp) {
|
||||
|
||||
default:
|
||||
donef++;
|
||||
|
||||
case '+':
|
||||
case '-':
|
||||
switch(lastop) {
|
||||
|
||||
case '+':
|
||||
tdot =+ ssymval;
|
||||
goto op;
|
||||
|
||||
case '-':
|
||||
tdot =- ssymval;
|
||||
|
||||
op:
|
||||
if (donef)
|
||||
return(adrflg);
|
||||
else
|
||||
lastop = *lp++;
|
||||
}
|
||||
goto loop;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
lp++;
|
||||
goto loop;
|
||||
|
||||
case '[':
|
||||
lp++;
|
||||
t1 = ssymval;
|
||||
t2 = tdot;
|
||||
if (expr() == 0)
|
||||
tdot = 0;
|
||||
ssymval = cget(t1 + (tdot<<1), DSP);
|
||||
tdot = t2;
|
||||
if (*lp == ']')
|
||||
lp++;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
|
||||
symcollect(c)
|
||||
{
|
||||
register char *p;
|
||||
|
||||
p = tsym;
|
||||
if (c)
|
||||
*p++ = c;
|
||||
while (symchar(1)) {
|
||||
if (p < &tsym[8])
|
||||
*p++ = *lp;
|
||||
lp++;
|
||||
}
|
||||
while (p < &tsym[8])
|
||||
*p++ = 0;
|
||||
}
|
||||
|
||||
symchar(dig)
|
||||
{
|
||||
if (*lp>='a'&&*lp<='z' || *lp=='_')
|
||||
return(1);
|
||||
if (dig && *lp>='0' && *lp<='9')
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
error()
|
||||
{
|
||||
errflg++;
|
||||
reset();
|
||||
}
|
||||
|
||||
printtrace()
|
||||
{
|
||||
int tpc, tr5, narg, argp, i;
|
||||
|
||||
if (modifier=='r') {
|
||||
printregs();
|
||||
return;
|
||||
}
|
||||
if (modifier=='f' || modifier=='d') {
|
||||
printfregs();
|
||||
return;
|
||||
}
|
||||
tpc = uregs[pc];
|
||||
tr5 = uregs[r5];
|
||||
if (locsr5)
|
||||
if (narg = get(locsr5, DSP)) {
|
||||
tr5 = narg;
|
||||
}
|
||||
callev = 0;
|
||||
while (errflg == 0) {
|
||||
narg = findroutine(tpc, tr5);
|
||||
printf("%2d: %.8s(", callev, ssymbol);
|
||||
if (--narg >= 0)
|
||||
printf("%.1o", get(tr5+4, DSP));
|
||||
argp = tr5+4;
|
||||
while(--narg >= 0)
|
||||
printf(",%.1o", get(argp =+ 2, DSP));
|
||||
printf(")\n");
|
||||
tpc = get(tr5+2, DSP);
|
||||
if (callev < 50) {
|
||||
entpt[callev] = ssymval;
|
||||
callist[callev++] = tr5;
|
||||
}
|
||||
if ((tr5 = get(tr5, DSP)) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
setstack()
|
||||
{
|
||||
register int tpc, tr5, i;
|
||||
|
||||
tpc = uregs[pc];
|
||||
tr5 = uregs[r5];
|
||||
if (locsr5)
|
||||
if (i = get(locsr5, DSP)) {
|
||||
tr5 = i;
|
||||
}
|
||||
callev = 0;
|
||||
while (errflg == 0) {
|
||||
findroutine(tpc, tr5);
|
||||
tpc = get(tr5+2, DSP);
|
||||
if (callev >= 50)
|
||||
break;
|
||||
entpt[callev] = ssymval;
|
||||
callist[callev++] = tr5;
|
||||
if ((tr5 = get(tr5, DSP)) == 0)
|
||||
break;
|
||||
}
|
||||
errflg = 0;
|
||||
}
|
||||
|
||||
printfregs()
|
||||
{
|
||||
register i;
|
||||
double f;
|
||||
|
||||
printf("fpsr %.1o\n", regbuf[0].fpsr);
|
||||
for (i=0; i<6; i++) {
|
||||
if (regbuf[0].fpsr&0200) /* long mode */
|
||||
f = regbuf[0].lfr[frnames[i]];
|
||||
else
|
||||
f = regbuf[0].sfr[frnames[i]];
|
||||
printf("fr%d %e\n", i, f);
|
||||
}
|
||||
}
|
||||
|
||||
printregs()
|
||||
{
|
||||
register struct reglist *p;
|
||||
register char *v, *d;
|
||||
|
||||
for (p=reglist; p < ®list[9]; p++) {
|
||||
printf("%s %.1o", p->rname, v=uregs[p->roffs]);
|
||||
d = vallook(v);
|
||||
if (d < 010000) {
|
||||
printf(" %.8s", ssymbol);
|
||||
if (d)
|
||||
printf("+%.1o", d);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
findroutine(rpc, rr5)
|
||||
{
|
||||
register callpt, inst, narg;
|
||||
|
||||
callpt = get(rr5+2, DSP);
|
||||
if ((inst=get(callpt-4, ISP)) == 04737) /* jsr pc,*$... */
|
||||
narg = 1;
|
||||
else if ((inst&~077)==04700) /* jsr pc,... */
|
||||
narg = 0;
|
||||
else {
|
||||
errflg++;
|
||||
return(0);
|
||||
}
|
||||
inst = vallook((inst==04767?callpt:0) + get(callpt-2, ISP));
|
||||
if (inst) {
|
||||
ssymbol[0] = '?';
|
||||
ssymbol[1] = 0;
|
||||
ssymval = 0;
|
||||
}
|
||||
inst = get(callpt, ISP);
|
||||
if (inst == 05726) /* tst (sp)+ */
|
||||
return(narg+1);
|
||||
if (inst == 022626) /* cmp (sp)+,(sp)+ */
|
||||
return(narg+2);
|
||||
if (inst == 062706) /* add $n,sp */
|
||||
return(narg+get(callpt+2, ISP)/2);
|
||||
return(narg);
|
||||
}
|
||||
|
||||
runcom()
|
||||
{
|
||||
int stat;
|
||||
register w, i;
|
||||
|
||||
switch(modifier) {
|
||||
|
||||
|
||||
/* delete breakpoint */
|
||||
case 'd':
|
||||
if (adrflg==0)
|
||||
error();
|
||||
for (w=0; w<NBKP; w++) {
|
||||
i = bkptl[w].loc;
|
||||
if (bkptl[w].flag & BADJST)
|
||||
i =- 4;
|
||||
if (dot==i) {
|
||||
if (lastbp==bkptl[w].loc) {
|
||||
ptrace(WUREGS,pid,2*(512+ps),uregs[ps]&~020);
|
||||
lastbp = 0;
|
||||
} else {
|
||||
ptrace(WUSER,pid,bkptl[w].loc,bkptl[w].ins);
|
||||
}
|
||||
bkptl[w].loc = 0;
|
||||
bkptl[w].flag = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
error();
|
||||
|
||||
/* set breakpoint */
|
||||
case 'b':
|
||||
if (adrflg==0)
|
||||
error();
|
||||
for (w=0; w<NBKP; w++) {
|
||||
i = bkptl[w].loc;
|
||||
if (bkptl[w].flag&BADJST)
|
||||
i =- 4;
|
||||
if (i==dot)
|
||||
return;
|
||||
}
|
||||
for (w=0; w<NBKP; w++)
|
||||
if (bkptl[w].loc==0) {
|
||||
bkptl[w].loc = dot;
|
||||
return;
|
||||
}
|
||||
error();
|
||||
|
||||
/* run program */
|
||||
case 'r':
|
||||
lastbp = 0;
|
||||
if (pid) {
|
||||
ptrace(EXIT, pid, 0, 0);
|
||||
pid = 0;
|
||||
}
|
||||
if ((pid = fork())==0) {
|
||||
ptrace(SETTRC, 0, 0, 0);
|
||||
signal(SIGINT, 0);
|
||||
signal(SIGINS, 0);
|
||||
doexec();
|
||||
printf("Can't execute %s\n", symfil);
|
||||
exit(0);
|
||||
}
|
||||
bpwait(0);
|
||||
setbp(1);
|
||||
ptrace(WUREGS, pid, 2*(512+ps), 0170000);
|
||||
|
||||
case 'c':
|
||||
if (pid==0)
|
||||
error();
|
||||
setbp(0);
|
||||
if (lastbp) {
|
||||
w = lastbp;
|
||||
ptrace(CONTIN, pid, 0, 0);
|
||||
bpwait(1);
|
||||
ptrace(WUSER, pid, w, 03);
|
||||
ptrace(WUREGS, pid, 2*(512+ps), uregs[ps]&~020);
|
||||
lastbp = 0;
|
||||
}
|
||||
ptrace(CONTIN, pid, 0, 0);
|
||||
bpwait(1);
|
||||
w = uregs[pc]-2;
|
||||
for (i=0; i<NBKP; i++)
|
||||
if (bkptl[i].loc == w)
|
||||
break;
|
||||
if (i >= NBKP) {
|
||||
printf("%s\n", signals[signo]);
|
||||
return;
|
||||
}
|
||||
lastbp = w;
|
||||
ptrace(WUSER, pid, w, bkptl[i].ins);
|
||||
ptrace(WUREGS, pid, 2*(512+pc), w);
|
||||
ptrace(WUREGS, pid, 2*(512+ps), uregs[ps]|020);
|
||||
printf("Breakpoint: ");
|
||||
psymoff(w, 0777);
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
error();
|
||||
}
|
||||
|
||||
doexec()
|
||||
{
|
||||
extern _exectrap;
|
||||
char *argl[32];
|
||||
register char *p, **ap;
|
||||
register c;
|
||||
|
||||
_exectrap++;
|
||||
ap = argl;
|
||||
*ap++ = symfil;
|
||||
p = lp;
|
||||
do {
|
||||
while (*p==' ')
|
||||
p++;
|
||||
if (*p=='\n' || *p=='\0')
|
||||
break;
|
||||
*ap++ = p;
|
||||
while (*p!=' ' && *p!='\n')
|
||||
p++;
|
||||
c = *p;
|
||||
*p++ = '\0';
|
||||
} while (c != '\n');
|
||||
*ap++ = 0;
|
||||
execv(symfil, argl);
|
||||
}
|
||||
|
||||
setbp(runflag)
|
||||
{
|
||||
register w, i1, l;
|
||||
int i2;
|
||||
|
||||
for (w=0; w<NBKP; w++) {
|
||||
l = bkptl[w].loc;
|
||||
if (l && (runflag||bkptl[w].ins==0)) {
|
||||
i1 = ptrace(RUSER, pid, l, 0);
|
||||
if (i1==04567) { /* jsr r5,... */
|
||||
i2 = ptrace(RUSER, pid, l+2, 0);
|
||||
if (loccsv == i2+l+4) { /* jsr r5,csv */
|
||||
l =+ 4;
|
||||
bkptl[w].loc = l;
|
||||
bkptl[w].flag =| BADJST;
|
||||
i1 = ptrace(RUSER, pid, l, 0);
|
||||
}
|
||||
}
|
||||
bkptl[w].ins = i1;
|
||||
ptrace(WUSER, pid, l, 03);
|
||||
if (errno) {
|
||||
printf("Can't set breakpoint ");
|
||||
psymoff(bkptl[w].loc);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bpwait(f)
|
||||
{
|
||||
extern int onintr();
|
||||
register w;
|
||||
int stat;
|
||||
|
||||
loop:
|
||||
signal(SIGINT, 1);
|
||||
while ((w = wait(&stat))!=pid && w != -1);
|
||||
signal(SIGINT, onintr);
|
||||
if (w == -1) {
|
||||
ptrace(EXIT, pid, 0, 0);
|
||||
pid = 0;
|
||||
printf("Wait error\n");
|
||||
reset();
|
||||
}
|
||||
if ((stat & 0377) != 0177) {
|
||||
if (signo = stat&0177)
|
||||
printf("%s\n", signals[signo]);
|
||||
printf("Process terminated.\n");
|
||||
if (pid == w) {
|
||||
pid = 0;
|
||||
reset();
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
signo = stat>>8;
|
||||
collinfo();
|
||||
if (signo!=SIGTRC) {
|
||||
printf("%s\n", signals[signo]);
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
collinfo()
|
||||
{
|
||||
register i;
|
||||
|
||||
for (i=0; i<9; i++)
|
||||
uregs[reglist[i].roffs] =
|
||||
ptrace(RUREGS, pid, 2*(512+reglist[i].roffs), 0);
|
||||
setstack();
|
||||
}
|
||||
|
||||
symlook(symstr)
|
||||
char *symstr;
|
||||
{
|
||||
register i;
|
||||
register symv;
|
||||
|
||||
symset();
|
||||
if (fsymbol[0]==0) {
|
||||
while(symget()) {
|
||||
if (eqstr(symbol, symstr)) {
|
||||
savsym();
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
while (symget()) {
|
||||
/* wait for function symbol */
|
||||
if (symbol[0]!='~' || !eqstr(symbol, fsymbol))
|
||||
continue;
|
||||
symv = symval;
|
||||
while (symget()&& symbol[0]!='~' &&symflg!=037)
|
||||
if (eqstr(symbol, symstr))
|
||||
return(localsym(symv));
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
localsym(s)
|
||||
{
|
||||
register i, xr5;
|
||||
|
||||
/* label, static */
|
||||
if (symflg>=2 && symflg<=4) {
|
||||
ssymval = symval;
|
||||
return(1);
|
||||
}
|
||||
/* auto, arg */
|
||||
if (symflg==1) {
|
||||
for (i=0; i<callev; i++)
|
||||
if (entpt[i]==s) {
|
||||
ssymval = symval+callist[i];
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
/* register */
|
||||
if (symflg==20) {
|
||||
for (i=0; i<callev; i++)
|
||||
if (entpt[i]==s) {
|
||||
if (i==0) {
|
||||
return(0); /* temp, no reg lvalue */
|
||||
}
|
||||
ssymval = callist[i-1] - 10 + 2*symval;
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
eqstr(as1, as2)
|
||||
int *as1, *as2;
|
||||
{
|
||||
register char *s1, *s2, *es1;
|
||||
|
||||
s1 = as1;
|
||||
s2 = as2;
|
||||
for (es1 = s1+8; s1 < es1; )
|
||||
if (*s1++ != *s2++)
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
vallook(value)
|
||||
char *value;
|
||||
{
|
||||
register char *diff;
|
||||
|
||||
diff = 0177777;
|
||||
symset();
|
||||
while (symget())
|
||||
if (symflg&040 && value-symval<=diff) {
|
||||
if (symflg==1 && value!=symval)
|
||||
continue;
|
||||
savsym('_');
|
||||
diff = value-symval;
|
||||
}
|
||||
return(diff);
|
||||
}
|
||||
|
||||
get(aaddr, space)
|
||||
char *aaddr;
|
||||
{
|
||||
int w;
|
||||
register int w1;
|
||||
register char *addr;
|
||||
|
||||
addr = aaddr;
|
||||
if (pid) { /* tracing on? */
|
||||
w = ptrace(space==DSP?RUSER:RIUSER, pid, addr, 0);
|
||||
if (addr&01) {
|
||||
w1 = ptrace(space==DSP?RUSER:RIUSER, pid, addr+1, 0);
|
||||
w = (w>>8)&0377 | (w1<<8);
|
||||
}
|
||||
errflg = errno;
|
||||
return(w);
|
||||
}
|
||||
w = 0;
|
||||
if (idsep==0&&addr<regbuf->u_tsize || idsep&&space==ISP) {
|
||||
seek(fsym, addr+020, 0);
|
||||
if (read(fsym, &w, 2) != 2)
|
||||
errflg++;
|
||||
return(w);
|
||||
}
|
||||
if (addr < rtsize+regbuf->u_dsize) {
|
||||
if (idsep==0)
|
||||
addr =- rtsize;
|
||||
} else if (-addr < regbuf->u_ssize)
|
||||
addr =+ regbuf->u_dsize + regbuf->u_ssize;
|
||||
else
|
||||
errflg++;
|
||||
seek(fcore, addr+1024, 0);
|
||||
if (read(fcore, &w, 2) < 2)
|
||||
errflg++;
|
||||
return(w);
|
||||
}
|
||||
|
||||
symset()
|
||||
{
|
||||
symct = symlen;
|
||||
symptr = symbuf;
|
||||
seek(fsym, symoff, 0);
|
||||
}
|
||||
|
||||
symget()
|
||||
{
|
||||
register int *p, *q;
|
||||
if ((symct =- 12) < 0)
|
||||
return(0);
|
||||
if (symptr < &symbuf[symcor]) {
|
||||
p = symptr;
|
||||
for (q=symbol; q <= &symval;)
|
||||
*q++ = *p++;
|
||||
symptr = p;
|
||||
return(1);
|
||||
}
|
||||
return(read(fsym, symbol, 12) == 12);
|
||||
}
|
||||
|
||||
savsym(skip)
|
||||
{
|
||||
register int ch;
|
||||
register char *p, *q;
|
||||
|
||||
p = symbol;
|
||||
q = ssymbol;
|
||||
while (p<symbol+8 && (ch = *p++)) {
|
||||
if (ch == skip)
|
||||
continue;
|
||||
*q++ = ch;
|
||||
}
|
||||
while (q < ssymbol+8)
|
||||
*q++ = '\0';
|
||||
ssymflg = symflg;
|
||||
ssymval = symval;
|
||||
}
|
||||
|
||||
onintr()
|
||||
{
|
||||
putchar('\n');
|
||||
errflg++;
|
||||
reset();
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
#
|
||||
/*
|
||||
* C debugger -- part 2
|
||||
*/
|
||||
|
||||
char ssymbol[];
|
||||
int dotinc;
|
||||
int dot;
|
||||
|
||||
|
||||
psymoff(v, lim)
|
||||
{
|
||||
register char *w;
|
||||
|
||||
w = vallook(v);
|
||||
if (w > lim) {
|
||||
printf("%.1o", v);
|
||||
return;
|
||||
}
|
||||
printf("%.8s", ssymbol);
|
||||
if (w)
|
||||
printf("+%d", w);
|
||||
}
|
||||
|
||||
#define ISP 1
|
||||
#define DOUBLE 0
|
||||
#define SINGLE 1
|
||||
#define SINGLW 2
|
||||
#define MULDIV 4
|
||||
#define BRANCH 5
|
||||
#define NOADDR 6
|
||||
#define FLTREV 7
|
||||
#define FLTNOR 8
|
||||
#define SPECL1 9
|
||||
#define SPECL2 10
|
||||
#define SPECL3 11
|
||||
#define SPECL4 12
|
||||
#define SPECL5 13
|
||||
#define SPECL6 14
|
||||
#define SPECL7 15
|
||||
#define SPECL8 18
|
||||
#define SPECL9 19
|
||||
|
||||
struct optab {
|
||||
int mask;
|
||||
int val;
|
||||
int itype;
|
||||
char *iname;
|
||||
} optab[] {
|
||||
0107777, 0010000, DOUBLE, "mov",
|
||||
0107777, 0020000, DOUBLE, "cmp",
|
||||
0107777, 0030000, DOUBLE, "bit",
|
||||
0107777, 0040000, DOUBLE, "bic",
|
||||
0107777, 0050000, DOUBLE, "bis",
|
||||
0007777, 0060000, DOUBLE, "add",
|
||||
0007777, 0160000, DOUBLE, "su",
|
||||
0100077, 0005000, SINGLE, "clr",
|
||||
0100077, 0005100, SINGLE, "com",
|
||||
0100077, 0005200, SINGLE, "inc",
|
||||
0100077, 0005300, SINGLE, "dec",
|
||||
0100077, 0005400, SINGLE, "neg",
|
||||
0100077, 0005500, SINGLE, "adc",
|
||||
0100077, 0005600, SINGLE, "sbc",
|
||||
0100077, 0005700, SINGLE, "tst",
|
||||
0100077, 0006000, SINGLE, "ror",
|
||||
0100077, 0006100, SINGLE, "rol",
|
||||
0100077, 0006200, SINGLE, "asr",
|
||||
0100077, 0006300, SINGLE, "asl",
|
||||
0000077, 0000100, SINGLE, "jmp",
|
||||
0000077, 0000300, SINGLE, "swab",
|
||||
0000077, 0170100, SINGLW, "ldfps",
|
||||
0000077, 0170200, SINGLW, "stfps",
|
||||
0000077, 0170300, SINGLW, "stst",
|
||||
0000077, 0170400, SINGLW, "clrf",
|
||||
0000077, 0170500, SINGLW, "tstf",
|
||||
0000077, 0170600, SINGLW, "absf",
|
||||
0000077, 0170700, SINGLW, "negf",
|
||||
0000077, 0006700, SINGLW, "sxt",
|
||||
0000077, 0006600, SINGLW, "mtpi",
|
||||
0000077, 0106600, SINGLW, "mtpd",
|
||||
0000077, 0006500, SINGLW, "mfpi",
|
||||
0000077, 0106500, SINGLW, "mfpd",
|
||||
0000777, 0070000, MULDIV, "mul",
|
||||
0000777, 0071000, MULDIV, "div",
|
||||
0000777, 0072000, MULDIV, "ash",
|
||||
0000777, 0073000, MULDIV, "ashc",
|
||||
0000377, 0000400, BRANCH, "br",
|
||||
0000377, 0001000, BRANCH, "bne",
|
||||
0000377, 0001400, BRANCH, "beq",
|
||||
0000377, 0002000, BRANCH, "bge",
|
||||
0000377, 0002400, BRANCH, "blt",
|
||||
0000377, 0003000, BRANCH, "bgt",
|
||||
0000377, 0003400, BRANCH, "ble",
|
||||
0000377, 0100000, BRANCH, "bpl",
|
||||
0000377, 0100400, BRANCH, "bmi",
|
||||
0000377, 0101000, BRANCH, "bhi",
|
||||
0000377, 0101400, BRANCH, "blos",
|
||||
0000377, 0102000, BRANCH, "bvc",
|
||||
0000377, 0102400, BRANCH, "bvs",
|
||||
0000377, 0103000, BRANCH, "bhis",
|
||||
0000377, 0103400, BRANCH, "blo",
|
||||
0000000, 0000000, NOADDR, "halt",
|
||||
0000000, 0000001, NOADDR, "wait",
|
||||
0000000, 0000002, NOADDR, "rti",
|
||||
0000000, 0000004, NOADDR, "iot",
|
||||
0000000, 0000005, NOADDR, "reset",
|
||||
0000377, 0171000, FLTREV, "mulf",
|
||||
0000377, 0171400, FLTREV, "modf",
|
||||
0000377, 0172000, FLTREV, "addf",
|
||||
0000377, 0172400, FLTREV, "movf",
|
||||
0000377, 0173000, FLTREV, "subf",
|
||||
0000377, 0173400, FLTREV, "cmpf",
|
||||
0000377, 0174000, FLTNOR, "movf",
|
||||
0000377, 0174400, FLTREV, "divf",
|
||||
0000377, 0175000, FLTNOR, "movei",
|
||||
0000377, 0175400, FLTNOR, "movfi",
|
||||
0000377, 0176000, FLTNOR, "movfo",
|
||||
0000377, 0176400, FLTREV, "movie",
|
||||
0000377, 0177000, FLTREV, "movif",
|
||||
0000377, 0177400, FLTREV, "movof",
|
||||
0000000, 0170000, NOADDR, "cfcc",
|
||||
0000000, 0170001, NOADDR, "setf",
|
||||
0000000, 0170002, NOADDR, "seti",
|
||||
0000000, 0170011, NOADDR, "setd",
|
||||
0000000, 0170012, NOADDR, "setl",
|
||||
0000777, 0004000, SPECL1, "jsr",
|
||||
0000777, 0074000, SPECL1, "xor",
|
||||
0000007, 0000200, SPECL2, "rts",
|
||||
0000017, 0000240, SPECL3, "cflg",
|
||||
0000017, 0000260, SPECL3, "sflg",
|
||||
0000377, 0104000, SPECL4, "emt",
|
||||
0000377, 0104400, SPECL5, "sys",
|
||||
0000077, 0006400, SPECL7, "mark",
|
||||
0000777, 0077000, SPECL8, "sob",
|
||||
0000007, 0000230, SPECL9, "spl",
|
||||
0177777, 0000000, SPECL6, "oct",
|
||||
};
|
||||
|
||||
struct systab {
|
||||
int argc;
|
||||
char *sname;
|
||||
} systab[] {
|
||||
1, "indir",
|
||||
0, "exit",
|
||||
0, "fork",
|
||||
2, "read",
|
||||
2, "write",
|
||||
2, "open",
|
||||
0, "close",
|
||||
0, "wait",
|
||||
2, "creat",
|
||||
2, "link",
|
||||
1, "unlink",
|
||||
2, "exec",
|
||||
1, "chdir",
|
||||
0, "time",
|
||||
3, "mknod",
|
||||
2, "chmod",
|
||||
2, "chown",
|
||||
1, "break",
|
||||
2, "stat",
|
||||
2, "seek",
|
||||
0, "getpid",
|
||||
3, "mount",
|
||||
1, "umount",
|
||||
0, "setuid",
|
||||
0, "getuid",
|
||||
0, "stime",
|
||||
3, "ptrace",
|
||||
0, "27",
|
||||
1, "fstat",
|
||||
0, "29",
|
||||
1, "smdate",
|
||||
1, "stty",
|
||||
1, "gtty",
|
||||
0, "33",
|
||||
0, "nice",
|
||||
0, "sleep",
|
||||
0, "sync",
|
||||
1, "kill",
|
||||
0, "switch",
|
||||
0, "39",
|
||||
0, "40",
|
||||
0, "dup",
|
||||
0, "pipe",
|
||||
1, "times",
|
||||
4, "profil",
|
||||
0, "45",
|
||||
0, "setgid",
|
||||
0, "getgid",
|
||||
2, "signal",
|
||||
0, "49",
|
||||
0, "50",
|
||||
0, "51",
|
||||
0, "52",
|
||||
0, "53",
|
||||
0, "54",
|
||||
0, "55",
|
||||
0, "56",
|
||||
0, "57",
|
||||
0, "58",
|
||||
0, "59",
|
||||
0, "60",
|
||||
0, "61",
|
||||
0, "62",
|
||||
0, "63",
|
||||
};
|
||||
|
||||
char *regname[] { "r0", "r1", "r2", "r3", "r4", "r5", "sp", "pc"};
|
||||
|
||||
printins(f)
|
||||
{
|
||||
register ins, w;
|
||||
register struct optab *p;
|
||||
|
||||
dotinc = 2;
|
||||
ins = cget(dot, ISP);
|
||||
if (vallook(dot)==0)
|
||||
printf("%.8s:", ssymbol);
|
||||
printf("\t");
|
||||
for (p=optab;; p++)
|
||||
if ((ins & ~p->mask) == p->val)
|
||||
break;
|
||||
printf("%s", p->iname);
|
||||
switch (p->itype) {
|
||||
|
||||
/* rts */
|
||||
case SPECL2:
|
||||
ins =& 07;
|
||||
|
||||
case SINGLE:
|
||||
if (ins < 0)
|
||||
printf("b");
|
||||
|
||||
case SINGLW:
|
||||
printf("\t");
|
||||
paddr(ins);
|
||||
return;
|
||||
|
||||
case FLTREV:
|
||||
ins =& 0377;
|
||||
|
||||
case MULDIV:
|
||||
ins = ((ins>>6)&07) | ((ins<<6)&07700);
|
||||
goto doub;
|
||||
|
||||
case FLTNOR:
|
||||
ins =& 0377;
|
||||
|
||||
/* jsr, xor */
|
||||
case SPECL1:
|
||||
ins =& 0777;
|
||||
goto doub;
|
||||
|
||||
case DOUBLE:
|
||||
if (ins<0)
|
||||
printf("b");
|
||||
doub:
|
||||
printf("\t");
|
||||
paddr(ins>>6);
|
||||
printf(",");
|
||||
paddr(ins);
|
||||
return;
|
||||
|
||||
case NOADDR:
|
||||
return;
|
||||
|
||||
/* sob */
|
||||
case SPECL8:
|
||||
printf("\t");
|
||||
paddr((ins>>6)&07);
|
||||
printf(",");
|
||||
ins = - (ins&077);
|
||||
goto bran;
|
||||
|
||||
case BRANCH:
|
||||
printf("\t");
|
||||
bran:
|
||||
ins =& 0377;
|
||||
if (ins&0200)
|
||||
ins =| 0177400;
|
||||
ins = dot + (ins<<1) + 2;
|
||||
psymoff(ins, 010000);
|
||||
return;
|
||||
|
||||
/* emt */
|
||||
case SPECL4:
|
||||
ins =& 0377;
|
||||
/* mark */
|
||||
case SPECL7:
|
||||
ins =& 077;
|
||||
/* spl */
|
||||
case SPECL9:
|
||||
ins =& 07;
|
||||
printf("\t%d", ins);
|
||||
return;
|
||||
|
||||
/* sys */
|
||||
case SPECL5:
|
||||
printf("\t%s", systab[ins =& 077].sname);
|
||||
if (ins==0 && f==0) { /* indir */
|
||||
w = dot;
|
||||
dot = cget(dot+2, ISP);
|
||||
printf(" {");
|
||||
printins(1);
|
||||
printf("}");
|
||||
dotinc = 4;
|
||||
dot = w;
|
||||
return;
|
||||
}
|
||||
w = systab[ins].argc;
|
||||
while (w--) {
|
||||
printf("; ");
|
||||
psymoff(cget(dot+dotinc, ISP), 010000);
|
||||
dotinc =+ 2;
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
printf("\t%.1o", ins);
|
||||
}
|
||||
}
|
||||
|
||||
paddr(aa)
|
||||
{
|
||||
register a, r;
|
||||
|
||||
a = aa;
|
||||
r = a&07;
|
||||
a =& 070;
|
||||
if (r==7 && a&020) {
|
||||
if (a&010)
|
||||
printf("*");
|
||||
if (a&040)
|
||||
psymoff(cget(dot+dotinc, ISP)+dot+dotinc+2, 010000);
|
||||
else {
|
||||
printf("$");
|
||||
psymoff(cget(dot+dotinc, ISP), 010000);
|
||||
}
|
||||
dotinc =+ 2;
|
||||
return;
|
||||
}
|
||||
r = regname[r];
|
||||
switch (a) {
|
||||
/* r */
|
||||
case 000:
|
||||
printf("%s", r);
|
||||
return;
|
||||
|
||||
/* (r) */
|
||||
case 010:
|
||||
printf("(%s)", r);
|
||||
return;
|
||||
|
||||
/* *(r)+ */
|
||||
case 030:
|
||||
printf("*");
|
||||
|
||||
/* (r)+ */
|
||||
case 020:
|
||||
printf("(%s)+", r);
|
||||
return;
|
||||
|
||||
/* *-(r) */
|
||||
case 050:
|
||||
printf("*");
|
||||
|
||||
/* -(r) */
|
||||
case 040:
|
||||
printf("-(%s)", r);
|
||||
return;
|
||||
|
||||
/* *x(r) */
|
||||
case 070:
|
||||
printf("*");
|
||||
|
||||
/* x(r) */
|
||||
case 060:
|
||||
psymoff(cget(dot+dotinc, ISP), 010000);
|
||||
dotinc =+ 2;
|
||||
printf("(%s)", r);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/ chgrp -- change group
|
||||
|
||||
|
||||
.globl fopen, getc, mesg
|
||||
|
||||
mov sp,r5
|
||||
mov (r5),r4
|
||||
cmp r4,$3
|
||||
bge 1f
|
||||
jsr r5,mesg; <chown uid f1 ...\n\0>; .even
|
||||
1:
|
||||
add $4,r5
|
||||
mov (r5),r3
|
||||
cmpb (r3),$'0
|
||||
blt 1f
|
||||
cmpb (r3),$'9
|
||||
bgt 1f
|
||||
jsr r5,cvnum; geta
|
||||
br do
|
||||
1:
|
||||
mov $uids,r0
|
||||
jsr r5,fopen; ubuf
|
||||
bec 1f
|
||||
jsr r5,mesg; <Can't open /etc/uids\n\0>; .even
|
||||
sys exit
|
||||
1:
|
||||
mov r3,r2
|
||||
2:
|
||||
jsr r5,getc; ubuf
|
||||
bcc 3f
|
||||
who:
|
||||
jsr r5,mesg; <Who?\n\0>; .even
|
||||
sys exit
|
||||
3:
|
||||
cmp r0,$':
|
||||
beq 3f
|
||||
cmpb (r2)+,r0
|
||||
beq 2b
|
||||
2:
|
||||
jsr r5,getc; ubuf
|
||||
bcs who
|
||||
cmp r0,$'\n
|
||||
bne 2b
|
||||
br 1b
|
||||
3:
|
||||
tstb (r2)
|
||||
bne 2b
|
||||
3:
|
||||
jsr r5,getc; ubuf
|
||||
cmpb r0,$':
|
||||
bne 3b
|
||||
jsr r5,cvnum; getc
|
||||
do:
|
||||
sub $2,r4
|
||||
swab r1
|
||||
mov r1,0f+2
|
||||
tst (r5)+
|
||||
1:
|
||||
mov (r5),0f
|
||||
mov (r5)+,9f
|
||||
sys stat; 9:..; statb
|
||||
movb statb+7,0f+2
|
||||
sys chown; 0:..; 0
|
||||
bec 2f
|
||||
mov 0b,r0
|
||||
mov r0,0f
|
||||
clr 0f+2
|
||||
3:
|
||||
tstb (r0)+
|
||||
beq 3f
|
||||
inc 0f+2
|
||||
br 3b
|
||||
3:
|
||||
mov $1,r0
|
||||
sys write; 0:..; ..
|
||||
jsr r5,mesg; <?\n\0>; .even
|
||||
2:
|
||||
dec r4
|
||||
bgt 1b
|
||||
sys exit
|
||||
|
||||
cvnum:
|
||||
clr r1
|
||||
1:
|
||||
jsr r5,*(r5); ubuf
|
||||
bcs 1f
|
||||
sub $'0,r0
|
||||
cmp r0,$9.
|
||||
bhi 1f
|
||||
mpy $10.,r1
|
||||
add r0,r1
|
||||
br 1b
|
||||
1:
|
||||
tst (r5)+
|
||||
rts r5
|
||||
|
||||
geta:
|
||||
movb (r3)+,r0
|
||||
tst (r5)+
|
||||
rts r5
|
||||
|
||||
uids: </etc/group\0>
|
||||
|
||||
.bss
|
||||
statb: .=.+36.
|
||||
ubuf: .=.+518.
|
||||
@@ -0,0 +1,27 @@
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
register i, m;
|
||||
register char *c;
|
||||
int count;
|
||||
|
||||
if(argc < 3) {
|
||||
printf("arg count\n");
|
||||
exit(1);
|
||||
}
|
||||
c = argv[1];
|
||||
m = 0;
|
||||
for(m=0; *c; c++) {
|
||||
if(*c < '0' || *c > '7') {
|
||||
printf("bad mode\n");
|
||||
exit(1);
|
||||
}
|
||||
m = (m<<3) | *c - '0';
|
||||
}
|
||||
for(i=2; i<argc; i++)
|
||||
if(chmod(argv[i], m) < 0) {
|
||||
count++;
|
||||
perror(argv[i]);
|
||||
}
|
||||
exit(count);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/ chown -- change owner
|
||||
|
||||
|
||||
.globl fopen, getc, mesg
|
||||
|
||||
mov sp,r5
|
||||
mov (r5),r4
|
||||
cmp r4,$3
|
||||
bge 1f
|
||||
jsr r5,mesg; <chown uid f1 ...\n\0>; .even
|
||||
1:
|
||||
add $4,r5
|
||||
mov (r5),r3
|
||||
cmpb (r3),$'0
|
||||
blt 1f
|
||||
cmpb (r3),$'9
|
||||
bgt 1f
|
||||
jsr r5,cvnum; geta
|
||||
br do
|
||||
1:
|
||||
mov $uids,r0
|
||||
jsr r5,fopen; ubuf
|
||||
bec 1f
|
||||
jsr r5,mesg; <Can't open /etc/uids\n\0>; .even
|
||||
sys exit
|
||||
1:
|
||||
mov r3,r2
|
||||
2:
|
||||
jsr r5,getc; ubuf
|
||||
bcc 3f
|
||||
who:
|
||||
jsr r5,mesg; <Who?\n\0>; .even
|
||||
sys exit
|
||||
3:
|
||||
cmp r0,$':
|
||||
beq 3f
|
||||
cmpb (r2)+,r0
|
||||
beq 2b
|
||||
2:
|
||||
jsr r5,getc; ubuf
|
||||
bcs who
|
||||
cmp r0,$'\n
|
||||
bne 2b
|
||||
br 1b
|
||||
3:
|
||||
tstb (r2)
|
||||
bne 2b
|
||||
3:
|
||||
jsr r5,getc; ubuf
|
||||
cmpb r0,$':
|
||||
bne 3b
|
||||
jsr r5,cvnum; getc
|
||||
do:
|
||||
sub $2,r4
|
||||
mov r1,0f+2
|
||||
tst (r5)+
|
||||
1:
|
||||
mov (r5),0f
|
||||
mov (r5)+,9f
|
||||
sys stat; 9:..; statb
|
||||
movb statb+8,0f+3
|
||||
sys chown; 0:..; 0
|
||||
bec 2f
|
||||
mov 0b,r0
|
||||
mov r0,0f
|
||||
clr 0f+2
|
||||
3:
|
||||
tstb (r0)+
|
||||
beq 3f
|
||||
inc 0f+2
|
||||
br 3b
|
||||
3:
|
||||
mov $1,r0
|
||||
sys write; 0:..; ..
|
||||
jsr r5,mesg; <?\n\0>; .even
|
||||
2:
|
||||
dec r4
|
||||
bgt 1b
|
||||
sys exit
|
||||
|
||||
cvnum:
|
||||
clr r1
|
||||
1:
|
||||
jsr r5,*(r5); ubuf
|
||||
bcs 1f
|
||||
sub $'0,r0
|
||||
cmp r0,$9.
|
||||
bhi 1f
|
||||
mpy $10.,r1
|
||||
add r0,r1
|
||||
br 1b
|
||||
1:
|
||||
tst (r5)+
|
||||
rts r5
|
||||
|
||||
geta:
|
||||
movb (r3)+,r0
|
||||
tst (r5)+
|
||||
rts r5
|
||||
|
||||
uids: </etc/passwd\0>
|
||||
|
||||
.bss
|
||||
statb: .=.+36.
|
||||
ubuf: .=.+518.
|
||||
@@ -0,0 +1,63 @@
|
||||
/ clri -- clear inode
|
||||
|
||||
cmp (sp)+,$2
|
||||
blt error
|
||||
beq 1f
|
||||
mov 4(sp),fs1
|
||||
mov 4(sp),fs2
|
||||
1:
|
||||
tst (sp)+
|
||||
mov (sp)+,r0
|
||||
clr r5
|
||||
1:
|
||||
movb (r0)+,r1
|
||||
beq 1f
|
||||
mpy $10.,r5
|
||||
sub $'0,r1
|
||||
cmp r1,$10.
|
||||
bhis error
|
||||
add r1,r5
|
||||
br 1b
|
||||
1:
|
||||
add $31.,r5
|
||||
mov r5,r0
|
||||
als $-4,r0
|
||||
mov r0,0f
|
||||
sys open; fs1: filsys; 0
|
||||
bes error
|
||||
mov r0,-(sp)
|
||||
sys seek; 0:..; 3
|
||||
mov (sp),r0
|
||||
sys read; buf; 512.
|
||||
mov (sp)+,r0
|
||||
sys close
|
||||
mov r5,r0
|
||||
als $5,r0
|
||||
bic $!777,r0
|
||||
add $buf,r0
|
||||
mov $16.,r5
|
||||
1:
|
||||
clr (r0)+
|
||||
sob r5,1b
|
||||
sys open; fs2: filsys; 1
|
||||
bes error
|
||||
mov r0,-(sp)
|
||||
mov 0b,0f
|
||||
sys seek; 0:..; 3
|
||||
mov (sp)+,r0
|
||||
sys write; buf; 512.
|
||||
bes error
|
||||
sys exit
|
||||
|
||||
error:
|
||||
mov $1,r0
|
||||
sys write; 1f; 2f-1f
|
||||
sys exit
|
||||
1:
|
||||
<error\n>
|
||||
2:
|
||||
|
||||
filsys: </dev/junk\0>
|
||||
.even
|
||||
.bss
|
||||
buf: .=.+512.
|
||||
@@ -0,0 +1,90 @@
|
||||
int ibuf1[259];
|
||||
int ibuf2[259];
|
||||
int eflg;
|
||||
int lflg 1;
|
||||
int line[2] {0, 1};
|
||||
int chr[2] { -1, -1};
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
register c1, c2;
|
||||
char *arg;
|
||||
|
||||
if(argc < 3)
|
||||
goto narg;
|
||||
arg = argv[1];
|
||||
if(arg[0] == '-' && arg[1] == 's') {
|
||||
lflg--;
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
arg = argv[1];
|
||||
if(arg[0] == '-' && arg[1] == 'l') {
|
||||
lflg++;
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
if(argc < 3)
|
||||
goto narg;
|
||||
arg = argv[1];
|
||||
if( arg[0]=='-' && arg[1]==0 )
|
||||
ibuf1[0] = dup(0);
|
||||
else if(fopen(arg, ibuf1) < 0)
|
||||
goto barg;
|
||||
arg = argv[2];
|
||||
if(fopen(arg, ibuf2) < 0)
|
||||
goto barg;
|
||||
|
||||
loop:
|
||||
if (++chr[1]==0)
|
||||
chr[0]++;
|
||||
c1 = getc(ibuf1);
|
||||
c2 = getc(ibuf2);
|
||||
if(c1 == c2) {
|
||||
if (c1 == '\n')
|
||||
if (++line[1]==0)
|
||||
line[0]++;
|
||||
if(c1 == -1) {
|
||||
if(eflg)
|
||||
exit(1);
|
||||
exit(0);
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
if(lflg == 0)
|
||||
exit(1);
|
||||
if(c1 == -1) {
|
||||
arg = argv[1];
|
||||
goto earg;
|
||||
}
|
||||
if(c2 == -1)
|
||||
goto earg;
|
||||
if(lflg == 1) {
|
||||
printf("%s %s differ: char %s, line ", argv[1], arg,
|
||||
locv(chr[0], chr[1]));
|
||||
printf("%s\n", locv(line[0], line[1]));
|
||||
exit(1);
|
||||
}
|
||||
eflg = 1;
|
||||
printf("%5s %3o %3o\n", locv(chr[0], chr[1]), c1, c2);
|
||||
goto loop;
|
||||
|
||||
narg:
|
||||
printf("arg count\n");
|
||||
exit(2);
|
||||
|
||||
barg:
|
||||
printf("cannot open %s\n", arg);
|
||||
exit(2);
|
||||
|
||||
earg:
|
||||
printf("EOF on %s\n", arg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
putchar(c)
|
||||
{
|
||||
|
||||
write(1, &c, 1);
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
# define PL 102
|
||||
# define ESC 033
|
||||
# define SI 017
|
||||
# define SO 016
|
||||
# define LINELN 800
|
||||
char *page[PL];
|
||||
char lbuff [LINELN], *line;
|
||||
main ()
|
||||
{
|
||||
int c, i, j, ll, cp, mustwr;
|
||||
extern int fin, fout;
|
||||
fin = dup(0);
|
||||
fout = dup(1);
|
||||
|
||||
for (ll=0; ll<PL; ll++)
|
||||
page[ll] = 0;
|
||||
|
||||
c = 1;
|
||||
cp = ll = 0;
|
||||
line = lbuff;
|
||||
mustwr = PL;
|
||||
|
||||
while (c>0)
|
||||
switch (c = getchar())
|
||||
{
|
||||
case '\n':
|
||||
store (ll%PL);
|
||||
if (++ll >= mustwr)
|
||||
if (page[ll%PL] != 0)
|
||||
{
|
||||
printf ("%s\n",page[ll%PL]);
|
||||
mustwr++;
|
||||
free (page[ll%PL]);
|
||||
page[ll%PL]=0;
|
||||
}
|
||||
fetch (ll%PL);
|
||||
cp = 0;
|
||||
continue;
|
||||
case '\0': continue;
|
||||
case ESC:
|
||||
c = getchar();
|
||||
if (c == '7')
|
||||
{
|
||||
store(ll%PL);
|
||||
ll--;
|
||||
fetch (ll%PL);
|
||||
}
|
||||
else
|
||||
{
|
||||
outc (ESC, &line);
|
||||
outc (c, &line );
|
||||
}
|
||||
continue;
|
||||
case '\r':
|
||||
line = lbuff;
|
||||
continue;
|
||||
case '\t':
|
||||
outc (' ', &line);
|
||||
cp = line-lbuff;
|
||||
while (cp++%8)
|
||||
outc(' ', &line);
|
||||
continue;
|
||||
default:
|
||||
outc(c, &line);
|
||||
}
|
||||
for (i=0; i<PL; i++)
|
||||
if (page[(mustwr+i)%PL] != 0)
|
||||
printf ("%s\n",page[(mustwr+i) % PL]);
|
||||
flush();
|
||||
}
|
||||
outc (c, lp)
|
||||
char **lp;
|
||||
{
|
||||
int j;
|
||||
j = 0;
|
||||
while (j >0 || *(*lp) == '\b' || *(*lp) == ESC || **lp == SI || **lp == SO)
|
||||
{
|
||||
switch (*(*lp))
|
||||
{
|
||||
case '\b':
|
||||
j++;
|
||||
(*lp)++;
|
||||
break;
|
||||
case '\0':
|
||||
*(*lp)++ = ' ';
|
||||
j--;
|
||||
break;
|
||||
case ESC: /* 'escape' */
|
||||
(*lp) =+ 2;
|
||||
break;
|
||||
case SI:
|
||||
case SO:
|
||||
(*lp)++;
|
||||
break;
|
||||
default:
|
||||
(*lp)++;
|
||||
j--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c != ' ' || *(*lp) == '\0')
|
||||
*(*lp) = c;
|
||||
(*lp)++;
|
||||
}
|
||||
store (ll)
|
||||
{
|
||||
if (page[ll] != 0)
|
||||
free (page[ll]);
|
||||
page[ll] = alloc ( leng (lbuff) + 2);
|
||||
copy (page[ll],lbuff);
|
||||
}
|
||||
fetch(ll)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < LINELN; i++)
|
||||
lbuff[i] = '\0';
|
||||
copy (line=lbuff, page[ll]);
|
||||
}
|
||||
copy (s,t)
|
||||
char *s, *t;
|
||||
{
|
||||
if (t == 0)
|
||||
return (*s=0);
|
||||
while (*s++ = *t++);
|
||||
}
|
||||
leng (s)
|
||||
char *s;
|
||||
{
|
||||
int l;
|
||||
for (l=0; s[l]; l++);
|
||||
return (l);
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
#define LB 250
|
||||
int one;
|
||||
int two;
|
||||
int three;
|
||||
|
||||
char *ldr[3];
|
||||
|
||||
char ib1[518];
|
||||
char ib2[518];
|
||||
main(argc,argv)
|
||||
char *argv[];
|
||||
{
|
||||
extern fout;
|
||||
int l;
|
||||
char lb1[LB],lb2[80];
|
||||
|
||||
ldr[0] = "";
|
||||
ldr[1] = "\t";
|
||||
ldr[2] = "\t\t";
|
||||
if(argc > 1) {
|
||||
if(*argv[1] == '-' && argv[1][1] != 0) {
|
||||
l = 1;
|
||||
while(*++argv[1]) {
|
||||
switch(*argv[1]) {
|
||||
case'1':
|
||||
if(!one) {
|
||||
one = 1;
|
||||
ldr[1][0] =
|
||||
ldr[2][l--] = '\0';
|
||||
}
|
||||
break;
|
||||
case '2':
|
||||
if(!two) {
|
||||
two = 1;
|
||||
ldr[2][l--] = '\0';
|
||||
}
|
||||
break;
|
||||
case '3':
|
||||
three = 1;
|
||||
break;
|
||||
default:
|
||||
printf("Illegal flag: %c\n",*argv[1]);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
}
|
||||
|
||||
if(argc < 3) {
|
||||
printf("Argc = %d\n",argc);
|
||||
exit();
|
||||
}
|
||||
|
||||
openfil(argv[1],ib1);
|
||||
openfil(argv[2],ib2);
|
||||
fout = dup(1);
|
||||
|
||||
|
||||
if(rd(ib1,lb1) < 0) {
|
||||
if(rd(ib2,lb2) < 0) exit();
|
||||
copy(ib2,lb2,2);
|
||||
}
|
||||
if(rd(ib2,lb2) < 0) copy(ib1,lb1,1);
|
||||
|
||||
while(1) {
|
||||
|
||||
switch(compare(lb1,lb2)) {
|
||||
|
||||
case 0:
|
||||
wr(lb1,3);
|
||||
if(rd(ib1,lb1) < 0) {
|
||||
if(rd(ib2,lb2) < 0) fexit();
|
||||
copy(ib2,lb2,2);
|
||||
}
|
||||
if(rd(ib2,lb2) < 0) copy(ib1,lb1,1);
|
||||
continue;
|
||||
|
||||
case 1:
|
||||
wr(lb1,1);
|
||||
if(rd(ib1,lb1) < 0) copy(ib2,lb2,2);
|
||||
continue;
|
||||
|
||||
case 2:
|
||||
wr(lb2,2);
|
||||
if(rd(ib2,lb2) < 0) copy(ib1,lb1,1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rd(file,buf)
|
||||
char *buf;
|
||||
{
|
||||
|
||||
register int i;
|
||||
i = 0;
|
||||
while((*buf = getc(file)) >=0) {
|
||||
if(*buf == '\n' || i > LB-2) {
|
||||
*buf = '\0';
|
||||
return(0);
|
||||
}
|
||||
i++;
|
||||
buf++;
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
wr(str,n)
|
||||
char *str;
|
||||
{
|
||||
|
||||
switch(n) {
|
||||
|
||||
case 1:
|
||||
if(one) return;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if(two) return;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if(three) return;
|
||||
}
|
||||
printf("%s%s\n",ldr[n-1],str);
|
||||
}
|
||||
|
||||
copy(ibuf,lbuf,n)
|
||||
{
|
||||
do {
|
||||
wr(lbuf,n);
|
||||
} while(rd(ibuf,lbuf) >= 0);
|
||||
|
||||
flush();
|
||||
exit();
|
||||
}
|
||||
|
||||
compare(a,b)
|
||||
char *a,*b;
|
||||
{
|
||||
register char *ra,*rb;
|
||||
|
||||
ra = --a;
|
||||
rb = --b;
|
||||
while(*++ra == *++rb)
|
||||
if(*ra == '\0') return(0);
|
||||
if(*ra < *rb) return(1);
|
||||
return(2);
|
||||
}
|
||||
fexit()
|
||||
{
|
||||
flush();
|
||||
exit();
|
||||
}
|
||||
|
||||
openfil(s,b)
|
||||
char *s;
|
||||
int *b;
|
||||
{
|
||||
if(s[0]=='-' && s[1]==0)
|
||||
b[0] = 0;
|
||||
else if(fopen(s, b) == -1) {
|
||||
printf("Can't open %s\n", s);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* cp oldfile newfile
|
||||
*/
|
||||
|
||||
main(argc,argv)
|
||||
char **argv;
|
||||
{
|
||||
static int buf[256];
|
||||
int fold, fnew, n;
|
||||
register char *p1, *p2, *bp;
|
||||
int mode;
|
||||
|
||||
if(argc != 3) {
|
||||
write(1, "Usage: cp oldfile newfile\n", 26);
|
||||
exit(1);
|
||||
}
|
||||
if((fold = open(argv[1], 0)) < 0) {
|
||||
write(1, "Cannot open old file.\n", 22);
|
||||
exit(1);
|
||||
}
|
||||
fstat(fold, buf);
|
||||
mode = buf[2];
|
||||
/* is target a directory? */
|
||||
if (stat(argv[2], buf+50)>=0 && (buf[52]&060000)==040000) {
|
||||
p1 = argv[1];
|
||||
p2 = argv[2];
|
||||
bp = buf+100;
|
||||
while(*bp++ = *p2++);
|
||||
bp[-1] = '/';
|
||||
p2 = bp;
|
||||
while(*bp = *p1++)
|
||||
if(*bp++ == '/')
|
||||
bp = p2;
|
||||
argv[2] = buf+100;
|
||||
}
|
||||
if (stat(argv[2], buf+50) >= 0) {
|
||||
if (buf[0]==buf[50] && buf[1]==buf[51]) {
|
||||
write(1, "Copying file to itself.\n", 24);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if ((fnew = creat(argv[2], mode)) < 0) {
|
||||
write(1, "Can't create new file.\n", 23);
|
||||
exit(1);
|
||||
}
|
||||
while(n = read(fold, buf, 512)) {
|
||||
if(n < 0) {
|
||||
write(1, "Read error\n", 11);
|
||||
exit(1);
|
||||
} else
|
||||
if(write(fnew, buf, n) != n){
|
||||
write(1, "Write error.\n", 13);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
char buf[100];
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
register i;
|
||||
register char *c1, *c2;
|
||||
|
||||
if(argc < 3) {
|
||||
write(2, "arg count\n", 10);
|
||||
exit();
|
||||
}
|
||||
argc--;
|
||||
c1 = buf;
|
||||
c2 = argv[argc];
|
||||
while(*c1++ = *c2++);
|
||||
c1[-1] = '/';
|
||||
*c1++ = '.';
|
||||
*c1 = '\0';
|
||||
for(i=1; i<argc; i++) {
|
||||
if(fork()==0) {
|
||||
execl("/bin/cp", "cp", argv[i], buf);
|
||||
exit();
|
||||
}
|
||||
wait();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
#define ANY -1
|
||||
#define LIST -2
|
||||
#define RANGE -3
|
||||
#define EOF -4
|
||||
char *crontab "/usr/lib/crontab";
|
||||
char *crontmp "/tmp/crontmp";
|
||||
char *aend;
|
||||
char *itime[2];
|
||||
int *loct;
|
||||
int *localtime();
|
||||
int reset();
|
||||
int flag;
|
||||
|
||||
main()
|
||||
{
|
||||
register i, t;
|
||||
register char *cp;
|
||||
extern char end[];
|
||||
|
||||
setuid(1);
|
||||
itime[0] = fork();
|
||||
if(itime[0])
|
||||
exit();
|
||||
setexit();
|
||||
signal(1, reset);
|
||||
time(itime);
|
||||
while(*localtime(itime))
|
||||
if(itime[1]-- == 0)
|
||||
itime[0]--;
|
||||
|
||||
loop:
|
||||
init();
|
||||
for(i=60; i; i--) {
|
||||
loct = localtime(itime);
|
||||
for(cp = end; *cp != EOF;) {
|
||||
flag = 0;
|
||||
cp = cmp(cp, loct[1]); /* minute */
|
||||
cp = cmp(cp, loct[2]); /* hour */
|
||||
cp = cmp(cp, loct[3]); /* day */
|
||||
cp = cmp(cp, loct[4]); /* month */
|
||||
cp = cmp(cp, loct[6]); /* day of week */
|
||||
if(flag == 0) {
|
||||
slp();
|
||||
ex(cp);
|
||||
}
|
||||
while(*cp++ != 0)
|
||||
;
|
||||
}
|
||||
t = itime[1] + 60;
|
||||
if(t < itime[1])
|
||||
itime[0]++;
|
||||
itime[1] = t;
|
||||
}
|
||||
slp();
|
||||
goto loop;
|
||||
}
|
||||
|
||||
cmp(p, v)
|
||||
char *p;
|
||||
{
|
||||
register char *cp;
|
||||
|
||||
cp = p;
|
||||
switch(*cp++) {
|
||||
|
||||
case ANY:
|
||||
return(cp);
|
||||
|
||||
case LIST:
|
||||
while(*cp != LIST)
|
||||
if(*cp++ == v) {
|
||||
while(*cp++ != LIST)
|
||||
;
|
||||
return(cp);
|
||||
}
|
||||
flag++;
|
||||
return(cp+1);
|
||||
|
||||
case RANGE:
|
||||
if(*cp > v || cp[1] < v)
|
||||
flag++;
|
||||
return(cp+2);
|
||||
}
|
||||
if(cp[-1] != v)
|
||||
flag++;
|
||||
return(cp);
|
||||
}
|
||||
|
||||
slp()
|
||||
{
|
||||
register i;
|
||||
int t[2];
|
||||
|
||||
time(t);
|
||||
i = itime[1] - t[1];
|
||||
if(i > 0)
|
||||
sleep(i);
|
||||
}
|
||||
|
||||
ex(s)
|
||||
char *s;
|
||||
{
|
||||
register i;
|
||||
|
||||
if(fork()) {
|
||||
wait();
|
||||
return;
|
||||
}
|
||||
for(i=0; s[i]; i++);
|
||||
close(0);
|
||||
creat(crontmp, 0600);
|
||||
write(0, s, i);
|
||||
close(0);
|
||||
open(crontmp, 0);
|
||||
unlink(crontmp);
|
||||
if(fork())
|
||||
exit();
|
||||
execl("/bin/sh", "sh", "-t", 0);
|
||||
exit();
|
||||
}
|
||||
|
||||
init()
|
||||
{
|
||||
int ib[259], t[10];
|
||||
register i, c;
|
||||
register char *cp;
|
||||
char *ocp;
|
||||
int n;
|
||||
extern char end[];
|
||||
|
||||
if(fopen(crontab, ib) < 0) {
|
||||
write(1, "cannot open table\n", 18);
|
||||
exit();
|
||||
}
|
||||
cp = end;
|
||||
if(aend == 0)
|
||||
aend = cp;
|
||||
|
||||
loop:
|
||||
ocp = cp;
|
||||
if(cp+100 > aend) {
|
||||
aend =+ 512;
|
||||
brk(aend);
|
||||
}
|
||||
for(i=0;; i++) {
|
||||
do
|
||||
c = getc(ib);
|
||||
while(c == ' ' || c == '\t');
|
||||
if(c <= 0 || c == '\n')
|
||||
goto ignore;
|
||||
if(i == 5)
|
||||
break;
|
||||
if(c == '*') {
|
||||
*cp++ = ANY;
|
||||
continue;
|
||||
}
|
||||
n = 0;
|
||||
while(c >= '0' && c <= '9') {
|
||||
n = n*10 + c-'0';
|
||||
c = getc(ib);
|
||||
}
|
||||
if(n < 0 || n > 100)
|
||||
goto ignore;
|
||||
if(c == ',')
|
||||
goto list;
|
||||
if(c == '-')
|
||||
goto range;
|
||||
if(c != '\t' && c != ' ')
|
||||
goto ignore;
|
||||
*cp++ = n;
|
||||
continue;
|
||||
|
||||
list:
|
||||
*cp++ = LIST;
|
||||
*cp++ = n;
|
||||
list1:
|
||||
n = 0;
|
||||
c = getc(ib);
|
||||
while(c >= '0' && c <= '9') {
|
||||
n = n*10 + c-'0';
|
||||
c = getc(ib);
|
||||
}
|
||||
if(n < 0 || n > 100)
|
||||
goto ignore;
|
||||
*cp++ = n;
|
||||
if(c == ',')
|
||||
goto list1;
|
||||
if(c != '\t' && c != ' ')
|
||||
goto ignore;
|
||||
*cp++ = LIST;
|
||||
continue;
|
||||
|
||||
range:
|
||||
*cp++ = RANGE;
|
||||
*cp++ = n;
|
||||
n = 0;
|
||||
c = getc(ib);
|
||||
while(c >= '0' && c <= '9') {
|
||||
n = n*10 + c-'0';
|
||||
c = getc(ib);
|
||||
}
|
||||
if(n < 0 || n > 100)
|
||||
goto ignore;
|
||||
if(c != '\t' && c != ' ')
|
||||
goto ignore;
|
||||
*cp++ = n;
|
||||
}
|
||||
while(c != '\n') {
|
||||
if(c <= 0)
|
||||
goto ignore;
|
||||
if(c == '%')
|
||||
c = '\n';
|
||||
*cp++ = c;
|
||||
c = getc(ib);
|
||||
}
|
||||
*cp++ = '\n';
|
||||
*cp++ = 0;
|
||||
goto loop;
|
||||
|
||||
ignore:
|
||||
cp = ocp;
|
||||
while(c != '\n') {
|
||||
if(c <= 0) {
|
||||
close(ib[0]);
|
||||
*cp++ = EOF;
|
||||
*cp++ = EOF;
|
||||
aend = cp;
|
||||
brk(aend);
|
||||
return;
|
||||
}
|
||||
c = getc(ib);
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
This routine is an exact implementation of Boris Hagelin's
|
||||
cryptographic machine. See U. S. Patent #2,089,603.
|
||||
*/
|
||||
|
||||
int cagetable[] { 0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 8, 8, 9, 10, 12, 16,
|
||||
16, 17, 18, 20, 24, 32, 32, 33, 34, 36, 40, 48};
|
||||
int warr1[52];
|
||||
int warr2[50];
|
||||
int warr3[46];
|
||||
int warr4[42];
|
||||
int warr5[38];
|
||||
int warr6[34];
|
||||
int *wheel1 warr1;
|
||||
int *wheel2 warr2;
|
||||
int *wheel3 warr3;
|
||||
int *wheel4 warr4;
|
||||
int *wheel5 warr5;
|
||||
int *wheel6 warr6;
|
||||
char key[130];
|
||||
int xxx;
|
||||
|
||||
|
||||
/*
|
||||
subroutine to manufacture a wheel
|
||||
*/
|
||||
|
||||
setup(list,n) int list[];
|
||||
{int *lp;
|
||||
lp = list;
|
||||
while(--n){
|
||||
*lp = lp+2;
|
||||
lp[1] = getbit();
|
||||
if(xxx) putchar(lp[1]+'0');
|
||||
lp = lp + 2;
|
||||
}
|
||||
*lp = list;
|
||||
lp[1] = getbit();
|
||||
if(xxx){
|
||||
putchar(lp[1]+'0');
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
subroutine to return the next bit from the main routines
|
||||
argument
|
||||
*/
|
||||
|
||||
getbit(){
|
||||
static i,j;
|
||||
int b;
|
||||
b = (key[j] >> i) & 1;
|
||||
if (i++ > 5) {
|
||||
j++;
|
||||
i = 0;
|
||||
}
|
||||
return (b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
main(ncooky,cookyp)
|
||||
int ncooky;
|
||||
char *cookyp[];
|
||||
{
|
||||
char *ip, *jp;
|
||||
int temp;
|
||||
int random;
|
||||
int i,j;
|
||||
int precious;
|
||||
int crypt;
|
||||
int cage[27];
|
||||
xxx = 0;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
copy input key and pad with clever junk
|
||||
*/
|
||||
|
||||
jp = key;
|
||||
*jp++ = 004;
|
||||
*jp++ = 034;
|
||||
if(ncooky > 1){
|
||||
while (*jp++ = *cookyp[1]++);
|
||||
jp--;
|
||||
}
|
||||
ip = key;
|
||||
while (jp < key+128) {
|
||||
*jp = jp[-1] ^ *ip++;
|
||||
jp++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
manufacture six wheels of various length
|
||||
*/
|
||||
|
||||
setup(wheel1,26);
|
||||
setup(wheel2,25);
|
||||
setup(wheel3,23);
|
||||
setup(wheel4,21);
|
||||
setup(wheel5,19);
|
||||
setup(wheel6,17);
|
||||
|
||||
/*
|
||||
set up the cage bars from the key area
|
||||
*/
|
||||
|
||||
jp = key;
|
||||
i = 27;
|
||||
while (i--){
|
||||
cage[i] = cagetable[*jp++ % 28];
|
||||
if(xxx && (cage[i] != 0)){
|
||||
putchar( cage[i]/8 + '0');
|
||||
putchar( cage[i]%8 + '0');
|
||||
putchar(' ');
|
||||
}
|
||||
}
|
||||
if(xxx) putchar('\n');
|
||||
|
||||
|
||||
/*
|
||||
the internal settings are now complete
|
||||
it's time to turn the crank, running the cage
|
||||
bars against the wheel lugs.
|
||||
*/
|
||||
|
||||
|
||||
while ((precious = getchar()) >=0){
|
||||
temp = 040*wheel1[1] + 020*wheel2[1] + 010*wheel3[1]
|
||||
+ 004*wheel4[1] + 002*wheel5[1] + 001*wheel6[1];
|
||||
wheel1 = *wheel1;
|
||||
wheel2 = *wheel2;
|
||||
wheel3 = *wheel3;
|
||||
wheel4 = *wheel4;
|
||||
wheel5 = *wheel5;
|
||||
wheel6 = *wheel6;
|
||||
|
||||
random = 0;
|
||||
i = 27;
|
||||
while (i--){
|
||||
random = random + ((temp & cage[i]) != 0);
|
||||
}
|
||||
random =% 26;
|
||||
|
||||
/*
|
||||
now we have a random number to use to encrypt the input
|
||||
it is done in such a way that the process is its own
|
||||
inverse.
|
||||
*/
|
||||
|
||||
|
||||
if ( precious=='\n' || precious==' ')
|
||||
crypt = precious;
|
||||
else{
|
||||
crypt = ('a' + 'z' - precious + random)%0400;
|
||||
if (crypt >= 'a' && crypt <= 'z' && precious > 'z')
|
||||
crypt =+ 26;
|
||||
if (crypt > 'z' && precious >= 'a' & precious <= 'z')
|
||||
crypt =- 26;
|
||||
if (crypt == '\n' || crypt == ' ')
|
||||
crypt = precious;
|
||||
}
|
||||
putchar(crypt);
|
||||
}
|
||||
flush();
|
||||
return;
|
||||
}
|
||||
|
||||
char ibuf[512];
|
||||
char obuf[512];
|
||||
char *ibufp;
|
||||
int icnt;
|
||||
int ocnt;
|
||||
getchar()
|
||||
{
|
||||
|
||||
if(icnt == 0) {
|
||||
icnt = read(0, ibuf, 512);
|
||||
if(icnt <= 0)
|
||||
return(-1);
|
||||
ibufp = ibuf;
|
||||
}
|
||||
icnt --;
|
||||
return(*ibufp++ & 0377);
|
||||
}
|
||||
|
||||
putchar(c)
|
||||
{
|
||||
|
||||
obuf[ocnt++] = c;
|
||||
if(ocnt >= 512)
|
||||
flush();
|
||||
}
|
||||
|
||||
flush()
|
||||
{
|
||||
|
||||
if(ocnt > 0)
|
||||
write(1, obuf, ocnt);
|
||||
ocnt = 0;
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
int timbuf[2];
|
||||
char *cbp;
|
||||
|
||||
char *tzname[2];
|
||||
int dmsize[];
|
||||
char cbuf[];
|
||||
char *cbp;
|
||||
|
||||
struct {
|
||||
char name[8];
|
||||
char tty;
|
||||
char fill1;
|
||||
int wtime[2];
|
||||
int fill2;
|
||||
} wtmp[2];
|
||||
|
||||
main(argc, argv)
|
||||
int argc, **argv;
|
||||
{
|
||||
register char *tzn;
|
||||
extern int timezone, *localtime();
|
||||
int wf, tfailed;
|
||||
|
||||
tfailed = 0;
|
||||
if(argc > 1) {
|
||||
cbp = argv[1];
|
||||
if(gtime()) {
|
||||
write(1, "bad conversion\n", 15);
|
||||
exit();
|
||||
}
|
||||
if (*cbp != 's') {
|
||||
/* convert to Greenwich time, on assumption of Standard time. */
|
||||
dpadd(timbuf, timezone);
|
||||
/* Now fix up to local daylight time. */
|
||||
if (localtime(timbuf)[8])
|
||||
dpadd(timbuf, -1*60*60);
|
||||
}
|
||||
time(wtmp[0].wtime);
|
||||
wtmp[0].tty = '|';
|
||||
if(stime(timbuf) < 0) {
|
||||
tfailed++;
|
||||
write(1, "no permission\n", 14);
|
||||
} else if ((wf = open("/usr/adm/wtmp", 1)) >= 0) {
|
||||
time(wtmp[1].wtime);
|
||||
wtmp[1].tty = '}';
|
||||
seek(wf, 0, 2);
|
||||
write(wf, wtmp, 32);
|
||||
}
|
||||
}
|
||||
if (tfailed==0)
|
||||
time(timbuf);
|
||||
cbp = cbuf;
|
||||
ctime(timbuf);
|
||||
write(1, cbuf, 20);
|
||||
tzn = tzname[localtime(timbuf)[8]];
|
||||
if (tzn)
|
||||
write(1, tzn, 3);
|
||||
write(1, cbuf+19, 6);
|
||||
}
|
||||
|
||||
gtime()
|
||||
{
|
||||
register int i;
|
||||
register int y, t;
|
||||
int d, h, m;
|
||||
extern int *localtime();
|
||||
int nt[2];
|
||||
|
||||
t = gpair();
|
||||
if(t<1 || t>12)
|
||||
goto bad;
|
||||
d = gpair();
|
||||
if(d<1 || d>31)
|
||||
goto bad;
|
||||
h = gpair();
|
||||
if(h == 24) {
|
||||
h = 0;
|
||||
d++;
|
||||
}
|
||||
m = gpair();
|
||||
if(m<0 || m>59)
|
||||
goto bad;
|
||||
y = gpair();
|
||||
if (y<0) {
|
||||
time(nt);
|
||||
y = localtime(nt)[5];
|
||||
}
|
||||
if (*cbp == 'p')
|
||||
h =+ 12;
|
||||
if (h<0 || h>23)
|
||||
goto bad;
|
||||
timbuf[0] = 0;
|
||||
timbuf[1] = 0;
|
||||
y =+ 1900;
|
||||
for(i=1970; i<y; i++)
|
||||
gdadd(dysize(i));
|
||||
/* Leap year */
|
||||
if (dysize(y)==366 && t >= 3)
|
||||
gdadd(1);
|
||||
while(--t)
|
||||
gdadd(dmsize[t-1]);
|
||||
gdadd(d-1);
|
||||
gmdadd(24, h);
|
||||
gmdadd(60, m);
|
||||
gmdadd(60, 0);
|
||||
return(0);
|
||||
|
||||
bad:
|
||||
return(1);
|
||||
}
|
||||
|
||||
gdadd(n)
|
||||
{
|
||||
register char *t;
|
||||
|
||||
t = timbuf[1]+n;
|
||||
if(t < timbuf[1])
|
||||
timbuf[0]++;
|
||||
timbuf[1] = t;
|
||||
}
|
||||
|
||||
gmdadd(m, n)
|
||||
{
|
||||
register int t1;
|
||||
|
||||
timbuf[0] =* m;
|
||||
t1 = timbuf[1];
|
||||
while(--m)
|
||||
gdadd(t1);
|
||||
gdadd(n);
|
||||
}
|
||||
|
||||
gpair()
|
||||
{
|
||||
register int c, d;
|
||||
register char *cp;
|
||||
|
||||
cp = cbp;
|
||||
if(*cp == 0)
|
||||
return(-1);
|
||||
c = (*cp++ - '0') * 10;
|
||||
if (c<0 || c>100)
|
||||
return(-1);
|
||||
if(*cp == 0)
|
||||
return(-1);
|
||||
if ((d = *cp++ - '0') < 0 || d > 9)
|
||||
return(-1);
|
||||
cbp = cp;
|
||||
return (c+d);
|
||||
}
|
||||
+726
@@ -0,0 +1,726 @@
|
||||
/ db1 -- debugger
|
||||
|
||||
fpp = 0
|
||||
eae = 0
|
||||
ldfps = 170100^tst
|
||||
|
||||
|
||||
db:
|
||||
mov sp,r5
|
||||
mov (r5)+,r4
|
||||
tst (r5)+
|
||||
cmp r4,$2
|
||||
blt 1f
|
||||
mov (r5),dbfile
|
||||
mov (r5),odbfil
|
||||
mov (r5)+,namfil
|
||||
cmp r4,$2
|
||||
beq 1f
|
||||
mov (r5)+,namfil
|
||||
1:
|
||||
sys open; dbfile: core; 0
|
||||
bec 9f
|
||||
jmp fnfnd
|
||||
9:
|
||||
mov r0,dbfin
|
||||
clr dbfout
|
||||
sys open; odbfil:core; 1
|
||||
bes 1f
|
||||
mov r0,dbfout
|
||||
1:
|
||||
sys open; namfil: a.out; 0
|
||||
bes 1f
|
||||
mov r0,r1
|
||||
mov r0,symfin
|
||||
sys read; nambuf; 20
|
||||
cmp nambuf,nobjmagic
|
||||
beq 2f
|
||||
cmp nambuf,objmagic
|
||||
bne 1f
|
||||
2:
|
||||
mov nambuf+2,r0 / text
|
||||
add nambuf+4,r0 / data
|
||||
cmp nambuf+16,$1 / relocation?
|
||||
beq 6f
|
||||
asl r0 / sym origin
|
||||
6:
|
||||
add $20,r0
|
||||
mov r0,0f
|
||||
mov r1,r0
|
||||
sys seek; 0:..; 0
|
||||
mov nambuf+10,r0 / symbol size
|
||||
cmp r0,$maxsym
|
||||
blos 3f
|
||||
mov $maxsym,r0
|
||||
3:
|
||||
add r0,0f
|
||||
sys break; 0: nambuf
|
||||
mov r0,0f
|
||||
mov r1,r0
|
||||
sys read; nambuf; 0:..
|
||||
add $nambuf,r0
|
||||
mov r0,namsiz
|
||||
1:
|
||||
jsr r5,get; zero / test new object
|
||||
cmp r0,nobjmagic
|
||||
beq 2f
|
||||
cmp r0,objmagic
|
||||
bne 1f
|
||||
2:
|
||||
mov $20,getoff
|
||||
1:
|
||||
mov sp,savsp
|
||||
sys signal; 2; 1
|
||||
ror r0
|
||||
bcs 1f
|
||||
sys signal; 2; errexit
|
||||
1:
|
||||
cmp r4,$2 / arg count
|
||||
beq 9f / not core image
|
||||
cmp r4,$4 / no-core image flag
|
||||
beq 9f
|
||||
mov $1024.,getoff
|
||||
mov dbfin,r0
|
||||
sys seek; 0; 0
|
||||
mov dbfin,r0
|
||||
sys read; regbuf; 1024.
|
||||
mov txtsiz,r0
|
||||
ash $6,r0
|
||||
mov r0,txtsiz
|
||||
add $17777,r0
|
||||
bic $17777,r0
|
||||
mov r0,rtxtsiz
|
||||
mov datsiz,r0
|
||||
ash $6,r0
|
||||
mov r0,datsiz
|
||||
mov stksiz,r0
|
||||
ash $6,r0
|
||||
mov r0,stksiz
|
||||
mov *locfpsr,r0
|
||||
bic $!200,r0
|
||||
mov r0,fpsr
|
||||
br loop
|
||||
9:
|
||||
loop:
|
||||
clr error
|
||||
jsr pc,readlin
|
||||
jsr pc,readexp
|
||||
tst error
|
||||
bne errexit
|
||||
mov $1,count
|
||||
cmpb r0,$',
|
||||
bne 2f
|
||||
movb (r4)+,r0
|
||||
mov addres,-(sp)
|
||||
mov adrflg,-(sp)
|
||||
jsr pc,readexp
|
||||
mov addres,count
|
||||
mov (sp)+,adrflg
|
||||
mov (sp)+,addres
|
||||
tst error
|
||||
bne errexit
|
||||
2:
|
||||
movb (r4),r0
|
||||
jsr pc,command
|
||||
tst error
|
||||
beq loop
|
||||
errexit:
|
||||
sys signal; 2; errexit
|
||||
mov savsp,sp
|
||||
jsr r5,mesg; <?\n\0>; .even
|
||||
br loop
|
||||
|
||||
fnfnd:
|
||||
jsr r5,mesg; <File not found.\n\0>; .even
|
||||
ex:
|
||||
sys exit
|
||||
|
||||
readlin:
|
||||
mov $inbuf,r4
|
||||
1:
|
||||
mov ttyfin,r0
|
||||
sys read; ch; 1
|
||||
tst r0
|
||||
beq ex
|
||||
cmpb ch,$'\n
|
||||
beq 1f
|
||||
movb ch,(r4)+
|
||||
br 1b
|
||||
1:
|
||||
clrb (r4)
|
||||
mov $inbuf,r4
|
||||
rts pc
|
||||
|
||||
switch:
|
||||
mov (r5)+,r1
|
||||
2:
|
||||
cmp r0,(r1)+
|
||||
bne 1f
|
||||
tst (sp)+
|
||||
jmp *(r1)
|
||||
1:
|
||||
tst (r1)+
|
||||
bne 2b
|
||||
rts r5
|
||||
|
||||
readexp:
|
||||
mov $'+,lastop
|
||||
clr addres
|
||||
clr starmod
|
||||
clr taddr
|
||||
clr adrflg
|
||||
nextxp:
|
||||
movb (r4)+,r0
|
||||
cmp r0,$'0
|
||||
blt 1f
|
||||
cmp r0,$'9
|
||||
ble numin
|
||||
cmp r0,$'a
|
||||
blt 1f
|
||||
cmp r0,$'z
|
||||
bgt 1f
|
||||
jmp letin
|
||||
1:
|
||||
cmp r0,$'a-40
|
||||
blt 1f
|
||||
cmp r0,$'z-40
|
||||
ble letin
|
||||
1:
|
||||
jsr r5,switch; expsw
|
||||
tstb -(r4)
|
||||
tst starmod
|
||||
beq 1f
|
||||
mov dot,taddr
|
||||
br operand
|
||||
1:
|
||||
rts pc
|
||||
|
||||
expsw:
|
||||
'+; opex
|
||||
'-; opex
|
||||
' ; nextxp
|
||||
'.; letin
|
||||
'_; letin
|
||||
'^; circumf
|
||||
'*; star
|
||||
-1; 0
|
||||
|
||||
star:
|
||||
mov pc,starmod
|
||||
br nextxp
|
||||
|
||||
operand:
|
||||
inc adrflg
|
||||
tst starmod
|
||||
beq 1f
|
||||
clr starmod
|
||||
bis bytemod,error
|
||||
jsr r5,get; taddr
|
||||
tst error
|
||||
bne 1f
|
||||
mov r0,taddr
|
||||
1:
|
||||
cmp lastop,$'+
|
||||
beq 1f
|
||||
sub taddr,addres
|
||||
br 2f
|
||||
1:
|
||||
add taddr,addres
|
||||
2:
|
||||
mov $'+,lastop
|
||||
br nextxp
|
||||
|
||||
circumf:
|
||||
mov dot,taddr
|
||||
dec taddr
|
||||
tst bytemod
|
||||
bne operand
|
||||
dec taddr
|
||||
br operand
|
||||
|
||||
numin:
|
||||
clr r1
|
||||
clr r3
|
||||
1:
|
||||
sub $'0,r0
|
||||
asl r1
|
||||
asl r1
|
||||
asl r1
|
||||
mpy $10.,r3
|
||||
bis r0,r1
|
||||
add r0,r3
|
||||
movb (r4)+,r0
|
||||
cmp r0,$'0
|
||||
blo 1f
|
||||
cmp r0,$'9
|
||||
blos 1b
|
||||
1:
|
||||
cmp r0,$'.
|
||||
bne 1f
|
||||
mov r3,r1
|
||||
inc r4
|
||||
1:
|
||||
mov r1,taddr
|
||||
dec r4
|
||||
br operand
|
||||
|
||||
letin:
|
||||
dec r4
|
||||
mov $nambuf,namstrt
|
||||
letin1:
|
||||
mov $symbol,r1
|
||||
clr (r1)+
|
||||
clr (r1)+
|
||||
clr (r1)+
|
||||
clr (r1)
|
||||
mov $symbol,r1
|
||||
mov $8.,-(sp)
|
||||
br 2f
|
||||
1:
|
||||
tstb (r4)+
|
||||
cmpb (r4),$'.
|
||||
beq 2f
|
||||
cmpb (r4),$'0
|
||||
blo 3f
|
||||
cmpb (r4),$'9
|
||||
blos 2f
|
||||
cmpb (r4),$'A
|
||||
blo 3f
|
||||
cmpb (r4),$'Z
|
||||
blos 2f
|
||||
cmpb (r4),$'_
|
||||
beq 2f
|
||||
cmpb (r4),$'a
|
||||
blo 3f
|
||||
cmpb (r4),$'z
|
||||
bhi 3f
|
||||
2:
|
||||
dec (sp)
|
||||
blt 1b
|
||||
movb (r4),(r1)+
|
||||
br 1b
|
||||
3:
|
||||
tst (sp)+
|
||||
jsr pc,lookupn
|
||||
tst error
|
||||
bne 1f
|
||||
cmpb (r4),$';
|
||||
beq 2f
|
||||
1:
|
||||
jmp operand
|
||||
2:
|
||||
tstb (r4)+
|
||||
mov r1,namstrt
|
||||
br letin1
|
||||
|
||||
opex:
|
||||
mov r0,lastop
|
||||
jmp nextxp
|
||||
|
||||
|
||||
command:
|
||||
jsr r5,switch; comsw
|
||||
inc error
|
||||
rts pc
|
||||
|
||||
comsw:
|
||||
'/; slash
|
||||
'\\; bslash
|
||||
'?; quest
|
||||
'\0; newln
|
||||
'^; circumf
|
||||
'=; equal
|
||||
':; colon
|
||||
'!; excla
|
||||
''; squote
|
||||
'"; dquote
|
||||
'$; dolr
|
||||
'&; amper
|
||||
'%; ex
|
||||
'`; grave
|
||||
-1; 0
|
||||
|
||||
dolr:
|
||||
mov sigp,r1
|
||||
bic $!17,r1
|
||||
asl r1
|
||||
mov traptab(r1),r1
|
||||
jsr pc,string
|
||||
jsr pc,pnl
|
||||
mov $doltab,r5
|
||||
1:
|
||||
mov (r5)+,r1
|
||||
beq 1f
|
||||
jsr pc,*(r5)+
|
||||
br 1b
|
||||
.if fpp
|
||||
1:
|
||||
mov (r5)+,r1
|
||||
beq 1f
|
||||
ldfps fpsr
|
||||
jsr pc,*(r5)+
|
||||
br 1b
|
||||
1:
|
||||
mov (r5)+,r1
|
||||
jsr pc,*(r5)+
|
||||
.endif
|
||||
1:
|
||||
rts pc
|
||||
|
||||
traptab:
|
||||
1f; .data; 1:<?0\0>; .text
|
||||
1f; .data; 1:<Hangup\0>; .text
|
||||
1f; .data; 1:<Interrupt\0>; .text
|
||||
1f; .data; 1:<Quit\0>; .text
|
||||
1f; .data; 1:<Illegal instruction\0>; .text
|
||||
1f; .data; 1:<Trace/BPT\0>; .text
|
||||
1f; .data; 1:<IOT\0>; .text
|
||||
1f; .data; 1:<EMT\0>; .text
|
||||
1f; .data; 1:<FP exception\0>; .text
|
||||
1f; .data; 1:<Killed\0>; .text
|
||||
1f; .data; 1:<Bus error\0>; .text
|
||||
1f; .data; 1:<Segmentation violation\0>; .text
|
||||
1f; .data; 1:<Bad system call\0>; .text
|
||||
1f; .data; 1:<?15\0>; .text
|
||||
1f; .data; 1:<?16\0>; .text
|
||||
1f; .data; 1:<?17\0>; .text
|
||||
|
||||
locps: regbuf+1776
|
||||
locpc: regbuf+1774
|
||||
locr0: regbuf+1772
|
||||
locr1: regbuf+1766
|
||||
locr2: regbuf+1750
|
||||
locr3: regbuf+1752
|
||||
locr4: regbuf+1754
|
||||
locsp: regbuf+1764
|
||||
locr5: regbuf+1756
|
||||
locfpsr: regbuf+4
|
||||
locfr0: regbuf+6
|
||||
locfr4: regbuf+16
|
||||
locfr5: regbuf+26
|
||||
locfr1: regbuf+36
|
||||
locfr2: regbuf+46
|
||||
locfr3: regbuf+56
|
||||
|
||||
doltab:
|
||||
1f; prgreg; locsp; .data; 1:<sp \0>; .text
|
||||
1f; proct; locps; .data; 1:<ps \0>; .text
|
||||
1f; prgreg; locpc; .data; 1:<pc \0>; .text
|
||||
1f; prgreg; locr0; .data; 1:<r0 \0>; .text
|
||||
1f; prgreg; locr1; .data; 1:<r1 \0>; .text
|
||||
1f; prgreg; locr2; .data; 1:<r2 \0>; .text
|
||||
1f; prgreg; locr3; .data; 1:<r3 \0>; .text
|
||||
1f; prgreg; locr4; .data; 1:<r4 \0>; .text
|
||||
1f; prgreg; locr5; .data; 1:<r5 \0>; .text
|
||||
0
|
||||
.if fpp
|
||||
1f; prfreg; locfr0; .data; 1:<fr0 \0>; .text
|
||||
1f; prfreg; locfr1; .data; 1:<fr1 \0>; .text
|
||||
1f; prfreg; locfr2; .data; 1:<fr2 \0>; .text
|
||||
1f; prfreg; locfr3; .data; 1:<fr3 \0>; .text
|
||||
1f; prfreg; locfr4; .data; 1:<fr4 \0>; .text
|
||||
1f; prfreg; locfr5; .data; 1:<fr5 \0>; .text
|
||||
0
|
||||
1f; proct; locfpsr; .data; 1:<fpsr \0>; .text
|
||||
.endif
|
||||
.data
|
||||
.even
|
||||
.text
|
||||
|
||||
.if fpp
|
||||
prfreg:
|
||||
mov *(r5)+,r4
|
||||
movf (r4),fr0
|
||||
cfcc
|
||||
beq 1f
|
||||
jsr pc,string
|
||||
jsr pc,printf
|
||||
jsr pc,pnl
|
||||
1:
|
||||
rts pc
|
||||
.endif
|
||||
|
||||
prgreg:
|
||||
jsr pc,string
|
||||
mov *(r5)+,r4
|
||||
mov (r4),r0
|
||||
jsr pc,printo
|
||||
mov (r4),r0
|
||||
jsr pc,lookupv
|
||||
tst r2
|
||||
beq 1f
|
||||
jsr r5,mesg; < \0>; .even
|
||||
mov (r4),r0
|
||||
jsr pc,pname
|
||||
1:
|
||||
jsr pc,pnl
|
||||
rts pc
|
||||
|
||||
proct:
|
||||
jsr pc,string
|
||||
mov *(r5)+,r4
|
||||
mov (r4),r0
|
||||
jsr pc,printo
|
||||
jsr pc,pnl
|
||||
rts pc
|
||||
|
||||
string:
|
||||
movb (r1)+,r0
|
||||
beq 1f
|
||||
jsr pc,putc
|
||||
br string
|
||||
1:
|
||||
rts pc
|
||||
|
||||
putc:
|
||||
mov r0,och
|
||||
mov $1,r0
|
||||
sys write; och; 1
|
||||
rts pc
|
||||
|
||||
equal:
|
||||
jsr r5,coleq; printo
|
||||
rts pc
|
||||
amper:
|
||||
clr bytemod
|
||||
mov $2,incdot
|
||||
jsr r5,cycle; asymp
|
||||
rts pc
|
||||
|
||||
asymp:
|
||||
jsr pc,pname
|
||||
jsr pc,pnl
|
||||
rts pc
|
||||
|
||||
bslash:
|
||||
inc bytemod
|
||||
mov $1,incdot
|
||||
br 1f
|
||||
|
||||
slash:
|
||||
clr bytemod
|
||||
mov $2,incdot
|
||||
1:
|
||||
jsr r5,cycle; octp
|
||||
rts pc
|
||||
|
||||
grave:
|
||||
clr bytemod
|
||||
mov $2,incdot
|
||||
jsr r5,cycle; decp
|
||||
rts pc
|
||||
|
||||
quest:
|
||||
clr bytemod
|
||||
jsr r5,cycle; psym
|
||||
rts pc
|
||||
|
||||
decp:
|
||||
jsr pc,printd
|
||||
jsr r5,mesg; <.\n\0>; .even
|
||||
rts pc
|
||||
|
||||
octp:
|
||||
jsr pc,printo
|
||||
jsr pc,pnl
|
||||
rts pc
|
||||
|
||||
newln:
|
||||
tst adrflg
|
||||
bne 1f
|
||||
add incdot,dot
|
||||
1:
|
||||
mov nlcom,r0
|
||||
jmp command
|
||||
|
||||
excla:
|
||||
tst adrflg
|
||||
bne 1f
|
||||
2:
|
||||
inc error
|
||||
rts pc
|
||||
1:
|
||||
bit $1,dot
|
||||
beq 1f
|
||||
tst bytemod
|
||||
beq 2b
|
||||
1:
|
||||
jsr r5,put; dot; addres
|
||||
rts pc
|
||||
|
||||
squote:
|
||||
inc bytemod
|
||||
mov $1,incdot
|
||||
br 2f
|
||||
dquote:
|
||||
clr bytemod
|
||||
mov $2,incdot
|
||||
2:
|
||||
jsr r5,cycle; ascp
|
||||
rts pc
|
||||
|
||||
ascp:
|
||||
mov r0,-(sp)
|
||||
jsr pc,ascp1
|
||||
mov (sp)+,r0
|
||||
tst bytemod
|
||||
bne 1f
|
||||
swab r0
|
||||
jsr pc,ascp1
|
||||
1:
|
||||
cmp count,$1
|
||||
bgt 1f
|
||||
jsr pc,pnl
|
||||
1:
|
||||
rts pc
|
||||
|
||||
ascp1:
|
||||
bic $!377,r0
|
||||
cmp r0,$'\n
|
||||
beq 2f
|
||||
cmp r0,$011
|
||||
beq 2f
|
||||
cmp r0,$40
|
||||
blo 1f
|
||||
cmp r0,$177
|
||||
bhis 1f
|
||||
2:
|
||||
jsr pc,putc
|
||||
rts pc
|
||||
1:
|
||||
mov r0,r1
|
||||
jsr r5,mesg; <\\\0>
|
||||
clr r0
|
||||
alsc $10.,r0
|
||||
add $'0,r0
|
||||
jsr pc,putc
|
||||
clr r0
|
||||
alsc $3,r0
|
||||
add $'0,r0
|
||||
jsr pc,putc
|
||||
clr r0
|
||||
alsc $3,r0
|
||||
add $'0,r0
|
||||
jsr pc,putc
|
||||
rts pc
|
||||
|
||||
colon:
|
||||
jsr r5,coleq; pname
|
||||
rts pc
|
||||
|
||||
coleq:
|
||||
jsr pc,setadr
|
||||
mov addres,r0
|
||||
jsr pc,*(r5)+
|
||||
jsr pc,pnl
|
||||
rts r5
|
||||
|
||||
cycle:
|
||||
mov r0,nlcom
|
||||
jsr pc,setadr
|
||||
mov addres,dot
|
||||
tst bytemod
|
||||
bne 1f
|
||||
bic $1,dot
|
||||
1:
|
||||
jsr r5,get; dot
|
||||
tst error
|
||||
bne 1f
|
||||
tst bytemod
|
||||
beq 2f
|
||||
bic $!377,r0
|
||||
2:
|
||||
jsr pc,*(r5)
|
||||
tst error
|
||||
bne 1f
|
||||
dec count
|
||||
ble 1f
|
||||
add incdot,dot
|
||||
br 1b
|
||||
1:
|
||||
tst (r5)+
|
||||
rts r5
|
||||
|
||||
setadr:
|
||||
tst adrflg
|
||||
bne 1f
|
||||
mov dot,addres
|
||||
1:
|
||||
rts pc
|
||||
|
||||
.if fpp
|
||||
printf:
|
||||
ldfps $200 / round+double
|
||||
mov r4,-(sp)
|
||||
mov r3,-(sp)
|
||||
movif $10.,r3
|
||||
movif $1,r2
|
||||
clr r4
|
||||
tstf r0
|
||||
cfcc
|
||||
beq 2f
|
||||
bge 1f
|
||||
negf r0
|
||||
mov $'-,r0
|
||||
jsr pc,putc
|
||||
1:
|
||||
cmpf r3,r0
|
||||
cfcc
|
||||
bgt 1f
|
||||
inc r4
|
||||
divf r3,r0
|
||||
br 1b
|
||||
1:
|
||||
cmpf r2,r0
|
||||
cfcc
|
||||
ble 2f
|
||||
dec r4
|
||||
mulf r3,r0
|
||||
br 1b
|
||||
2:
|
||||
modf r2,r0
|
||||
movfi r1,r0
|
||||
add $'0,r0
|
||||
jsr pc,putc
|
||||
mov $'.,r0
|
||||
jsr pc,putc
|
||||
mov $8.,r3
|
||||
1:
|
||||
modf r3,r0
|
||||
movfi r1,r0
|
||||
add $'0,r0
|
||||
jsr pc,putc
|
||||
dec r3
|
||||
bgt 1b
|
||||
mov $'E,r0
|
||||
jsr pc,putc
|
||||
mov r4,r0
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r4
|
||||
br printd
|
||||
.endif
|
||||
|
||||
printd:
|
||||
mov r1,-(sp)
|
||||
mov r0,r1
|
||||
bpl 1f
|
||||
neg r1
|
||||
mov $'-,r0
|
||||
jsr pc,putc
|
||||
1:
|
||||
jsr pc,1f
|
||||
mov (sp)+,r1
|
||||
rts pc
|
||||
1:
|
||||
clr r0
|
||||
dvd $10.,r0
|
||||
mov r1,-(sp)
|
||||
mov r0,r1
|
||||
beq 1f
|
||||
jsr pc,1b
|
||||
1:
|
||||
mov (sp)+,r0
|
||||
add $'0,r0
|
||||
jsr pc,putc
|
||||
rts pc
|
||||
|
||||
+375
@@ -0,0 +1,375 @@
|
||||
/ db2 -- debugger
|
||||
|
||||
lookupn:
|
||||
cmp symbol,$'.
|
||||
bne 1f
|
||||
mov dot,taddr
|
||||
rts pc
|
||||
1:
|
||||
tst error
|
||||
beq 1f
|
||||
rts pc
|
||||
1:
|
||||
mov r2,-(sp)
|
||||
mov namstrt,r1
|
||||
mov namsiz,r2
|
||||
jsr pc,1f
|
||||
mov (sp)+,r2
|
||||
rts pc
|
||||
1:
|
||||
mov $symbol,r0
|
||||
cmp (r0)+,(r1)+
|
||||
bne 2f
|
||||
cmp (r0)+,(r1)+
|
||||
bne 3f
|
||||
cmp (r0)+,(r1)+
|
||||
bne 4f
|
||||
cmp (r0)+,(r1)+
|
||||
bne 5f
|
||||
tst (r1)+
|
||||
mov (r1)+,taddr
|
||||
rts pc
|
||||
2:
|
||||
tst (r1)+
|
||||
3:
|
||||
tst (r1)+
|
||||
4:
|
||||
tst (r1)+
|
||||
5:
|
||||
cmp (r1)+,(r1)+
|
||||
cmp r1,r2
|
||||
blo 1b
|
||||
inc error
|
||||
clr taddr
|
||||
rts pc
|
||||
|
||||
lookupv:
|
||||
mov r5,-(sp)
|
||||
mov $nambuf,r5
|
||||
clr r2
|
||||
mov $177777,r3
|
||||
1:
|
||||
cmp r5,namsiz
|
||||
bhis 4f
|
||||
mov 12(r5),r1
|
||||
sub r0,r1
|
||||
neg r1
|
||||
blt 3f
|
||||
cmp r1,r3
|
||||
bhi 3f
|
||||
cmp r1,$4000
|
||||
bhis 3f
|
||||
cmp r2,r5
|
||||
bhi 3f
|
||||
mov r1,r3
|
||||
mov r5,r2
|
||||
3:
|
||||
add $14,r5
|
||||
br 1b
|
||||
4:
|
||||
mov (sp)+,r5
|
||||
rts pc
|
||||
|
||||
get:
|
||||
mov *(r5)+,r0
|
||||
jsr r5,remap
|
||||
tst error
|
||||
bne 2f
|
||||
mov r0,0f
|
||||
mov curfin,r0
|
||||
sys seek; 0:0; 0
|
||||
bec 1f
|
||||
2:
|
||||
inc error
|
||||
rts r5
|
||||
1:
|
||||
mov curfin,r0
|
||||
sys read; temp; 2
|
||||
bes 2b
|
||||
tst r0
|
||||
beq 2b
|
||||
mov temp,r0
|
||||
rts r5
|
||||
|
||||
remap:
|
||||
mov dbfin,curfin
|
||||
cmp getoff,$1024.
|
||||
bne 1f
|
||||
cmp r0,txtsiz
|
||||
bhis 2f
|
||||
add $20,r0
|
||||
mov symfin,curfin
|
||||
rts r5
|
||||
2:
|
||||
cmp r0,rtxtsiz
|
||||
blo 3f
|
||||
sub rtxtsiz,r0
|
||||
cmp r0,datsiz
|
||||
bhis 2f
|
||||
add $1024.,r0
|
||||
rts r5
|
||||
2:
|
||||
add rtxtsiz,r0
|
||||
neg r0
|
||||
cmp r0,stksiz
|
||||
bhi 3f
|
||||
neg r0
|
||||
add datsiz,r0
|
||||
add stksiz,r0
|
||||
add $1024.,r0
|
||||
rts r5
|
||||
1:
|
||||
add getoff,r0
|
||||
rts r5
|
||||
3:
|
||||
inc error
|
||||
rts r5
|
||||
|
||||
printo:
|
||||
mov $obuf+6,r1
|
||||
clr r2
|
||||
1:
|
||||
inc r2
|
||||
movb r0,-(r1)
|
||||
bicb $!7,(r1)
|
||||
bisb $'0,(r1)
|
||||
clc
|
||||
ror r0
|
||||
asr r0
|
||||
asr r0
|
||||
bne 1b
|
||||
mov r2,0f+2
|
||||
mov r1,0f
|
||||
mov $1,r0
|
||||
sys write; 0:obuf; 6
|
||||
rts pc
|
||||
|
||||
mesg:
|
||||
movb (r5)+,r0
|
||||
beq 1f
|
||||
jsr pc,putc
|
||||
br mesg
|
||||
1:
|
||||
inc r5
|
||||
bic $1,r5
|
||||
rts r5
|
||||
|
||||
pnl:
|
||||
jsr r5,mesg; <\n\0>
|
||||
rts pc
|
||||
|
||||
psp:
|
||||
jsr r5,mesg; < \0>
|
||||
rts pc
|
||||
|
||||
pstar:
|
||||
jsr r5,mesg; <*\0>
|
||||
rts pc
|
||||
|
||||
plp:
|
||||
jsr r5,mesg; <(\0>
|
||||
rts pc
|
||||
|
||||
prp:
|
||||
jsr r5,mesg; <)\0>
|
||||
rts pc
|
||||
|
||||
pb:
|
||||
jsr r5,mesg; <b\0>
|
||||
rts pc
|
||||
|
||||
pcom:
|
||||
jsr r5,mesg; <,\0>
|
||||
rts pc
|
||||
|
||||
put:
|
||||
mov *(r5)+,r0
|
||||
jsr r5,remap
|
||||
tst error
|
||||
bne 2f
|
||||
cmp curfin,dbfin
|
||||
bne 2f
|
||||
mov r0,0f
|
||||
mov dbfout,r0
|
||||
bne 1f
|
||||
2:
|
||||
tst (r5)+
|
||||
3:
|
||||
inc error
|
||||
rts r5
|
||||
1:
|
||||
tst error
|
||||
bne 3b
|
||||
sys seek; 0:0; 0
|
||||
bes 2b
|
||||
mov (r5)+,0f
|
||||
mov dbfout,r0
|
||||
tst bytemod
|
||||
beq 1f
|
||||
mov $1,0f+2
|
||||
br 2f
|
||||
1:
|
||||
mov $2,0f+2
|
||||
2:
|
||||
sys write; 0:0; 2
|
||||
bes 3b
|
||||
rts r5
|
||||
|
||||
decodadr:
|
||||
mov r0,r3
|
||||
mov r3,-(sp)
|
||||
bic $!10,(sp)
|
||||
bic $!7,r0
|
||||
cmp r0,$7
|
||||
beq pcadr
|
||||
7:
|
||||
mov r3,r0
|
||||
asr r0
|
||||
asr r0
|
||||
asr r0
|
||||
bic $!6,r0
|
||||
jmp *1f(r0)
|
||||
|
||||
1:
|
||||
simp
|
||||
incr
|
||||
decr
|
||||
indx
|
||||
|
||||
simp:
|
||||
tst (sp)
|
||||
beq 1f
|
||||
jsr pc,plp
|
||||
1:
|
||||
jsr pc,preg
|
||||
tst (sp)+
|
||||
beq 9f
|
||||
jsr pc,prp
|
||||
br 9f
|
||||
|
||||
incr:
|
||||
tst (sp)+
|
||||
beq 1f
|
||||
jsr pc,pstar
|
||||
1:
|
||||
jsr pc,plp
|
||||
jsr pc,preg
|
||||
jsr r5,mesg; <)+\0>; .even
|
||||
br 9f
|
||||
|
||||
decr:
|
||||
tst (sp)+
|
||||
beq 1f
|
||||
jsr pc,pstar
|
||||
1:
|
||||
jsr r5,mesg; <-(\0>; .even
|
||||
jsr pc,preg
|
||||
jsr pc,prp
|
||||
br 9f
|
||||
|
||||
indx:
|
||||
tst (sp)+
|
||||
beq 1f
|
||||
jsr pc,pstar
|
||||
1:
|
||||
jsr pc,get1
|
||||
jsr pc,pname
|
||||
jsr pc,plp
|
||||
jsr pc,preg
|
||||
jsr pc,prp
|
||||
br 5f
|
||||
|
||||
pcadr:
|
||||
mov r3,r0
|
||||
bit $20,r3
|
||||
beq 7b
|
||||
tst (sp)+
|
||||
beq 1f
|
||||
jsr pc,pstar
|
||||
1:
|
||||
bit $40,r3
|
||||
bne 6f
|
||||
jsr r5,mesg; <$\0>
|
||||
jsr pc,get1
|
||||
jsr pc,pname
|
||||
br 5f
|
||||
6:
|
||||
jsr pc,get1
|
||||
add $2,r0
|
||||
add r1,r0
|
||||
mov $3,r1
|
||||
jsr pc,pname
|
||||
br 5f
|
||||
9:
|
||||
tst (r5)+
|
||||
clr r0
|
||||
rts r5
|
||||
5:
|
||||
mov $2,r0
|
||||
rts r5
|
||||
|
||||
preg:
|
||||
mov r3,r0
|
||||
bic $!7,r0
|
||||
asl r0
|
||||
mov regtab(r0),obuf
|
||||
mov $1,r0
|
||||
sys write; obuf; 2
|
||||
rts pc
|
||||
|
||||
regtab:
|
||||
"r0
|
||||
"r1
|
||||
"r2
|
||||
"r3
|
||||
"r4
|
||||
"r5
|
||||
"sp
|
||||
"pc
|
||||
|
||||
pname:
|
||||
mov r5,-(sp)
|
||||
mov r3,-(sp)
|
||||
mov r1,-(sp)
|
||||
jsr pc,lookupv
|
||||
tst r2
|
||||
beq 5f
|
||||
cmp (sp),$1
|
||||
bne 1f
|
||||
tst r3
|
||||
bne 5f
|
||||
1:
|
||||
mov r2,r1
|
||||
mov $8,-(sp)
|
||||
mov r0,r5
|
||||
1:
|
||||
movb (r1)+,r0
|
||||
beq 1f
|
||||
jsr pc,putc
|
||||
dec (sp)
|
||||
bne 1b
|
||||
1:
|
||||
tst (sp)+
|
||||
cmp 12(r2),r5
|
||||
beq 1f
|
||||
blt 2f
|
||||
jsr r5,mesg; <-\0>
|
||||
br 3f
|
||||
2:
|
||||
jsr r5,mesg; <+\0>
|
||||
3:
|
||||
mov r3,r0
|
||||
5:
|
||||
jsr pc,printo
|
||||
1:
|
||||
tst (sp)+
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r5
|
||||
rts pc
|
||||
|
||||
get1:
|
||||
mov *(r5)+,r1
|
||||
add $2,r1
|
||||
mov r1,temp
|
||||
jsr r5,get; temp
|
||||
rts pc
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
/ db3 -- debugger
|
||||
|
||||
psym:
|
||||
mov $2,incdot
|
||||
jsr pc,prints
|
||||
jsr pc,pnl
|
||||
rts pc
|
||||
|
||||
prints:
|
||||
mov r0,-(sp)
|
||||
mov $optab,r1
|
||||
1:
|
||||
mov (sp),r0
|
||||
bic (r1)+,r0
|
||||
cmp (r1)+,r0
|
||||
bne 2f
|
||||
mov (r1)+,-(sp)
|
||||
jsr pc,string
|
||||
jmp *(sp)+
|
||||
2:
|
||||
add $8.,r1
|
||||
br 1b
|
||||
|
||||
optab:
|
||||
107777; 010000; double; <mov\0\0\0>
|
||||
107777; 020000; double; <cmp\0\0\0>
|
||||
107777; 030000; double; <bit\0\0\0>
|
||||
107777; 040000; double; <bic\0\0\0>
|
||||
107777; 050000; double; <bis\0\0\0>
|
||||
007777; 060000; double; <add\0\0\0>
|
||||
007777; 160000; double; <su\0\0\0\0>
|
||||
|
||||
100077; 005000; single; <clr\0\0\0>
|
||||
100077; 005100; single; <com\0\0\0>
|
||||
100077; 005200; single; <inc\0\0\0>
|
||||
100077; 005300; single; <dec\0\0\0>
|
||||
100077; 005400; single; <neg\0\0\0>
|
||||
100077; 005500; single; <adc\0\0\0>
|
||||
100077; 005600; single; <sbc\0\0\0>
|
||||
100077; 005700; single; <tst\0\0\0>
|
||||
100077; 006000; single; <ror\0\0\0>
|
||||
100077; 006100; single; <rol\0\0\0>
|
||||
100077; 006200; single; <asr\0\0\0>
|
||||
100077; 006300; single; <asl\0\0\0>
|
||||
000077; 000100; single; <jmp\0\0\0>
|
||||
000077; 000300; single; <swab\0\0>
|
||||
000077; 170100; singlw; <ldfps\0>
|
||||
000077; 170200; singlw; <stfps\0>
|
||||
000077; 170300; singlw; <stst\0\0>
|
||||
000077; 170400; singlw; <clrf\0\0>
|
||||
000077; 170500; singlw; <tstf\0\0>
|
||||
000077; 170600; singlw; <absf\0\0>
|
||||
000077; 170700; singlw; <negf\0\0>
|
||||
000077; 006700; singlw; <sxt\0\0\0>
|
||||
000077; 006600; singlw; <mtpi\0\0>
|
||||
000077; 106600; singlw; <mtpd\0\0>
|
||||
000077; 006500; singlw; <mfpi\0\0>
|
||||
000077; 106500; singlw; <mfpd\0\0>
|
||||
000777; 070000; muldiv; <mul\0\0\0>
|
||||
000777; 071000; muldiv; <div\0\0\0>
|
||||
000777; 072000; muldiv; <ash\0\0\0>
|
||||
000777; 073000; muldiv; <ashc\0\0>
|
||||
|
||||
000377; 000400; branch; <br\0\0\0\0>
|
||||
000377; 001000; branch; <bne\0\0\0>
|
||||
000377; 001400; branch; <beq\0\0\0>
|
||||
000377; 002000; branch; <bge\0\0\0>
|
||||
000377; 002400; branch; <blt\0\0\0>
|
||||
000377; 003000; branch; <bgt\0\0\0>
|
||||
000377; 003400; branch; <ble\0\0\0>
|
||||
000377; 100000; branch; <bpl\0\0\0>
|
||||
000377; 100400; branch; <bmi\0\0\0>
|
||||
000377; 101000; branch; <bhi\0\0\0>
|
||||
000377; 101400; branch; <blos\0\0>
|
||||
000377; 102000; branch; <bvc\0\0\0>
|
||||
000377; 102400; branch; <bvs\0\0\0>
|
||||
000377; 103000; branch; <bhis\0\0>
|
||||
000377; 103400; branch; <blo\0\0\0>
|
||||
|
||||
000000; 000000; noaddr; <halt\0\0>
|
||||
000000; 000001; noaddr; <wait\0\0>
|
||||
000000; 000002; noaddr; <rti\0\0\0>
|
||||
000000; 000004; noaddr; <iot\0\0\0>
|
||||
000000; 000005; noaddr; <reset\0>
|
||||
|
||||
000377; 171000; fltrev; <mulf\0\0>
|
||||
000377; 171400; fltrev; <modf\0\0>
|
||||
000377; 172000; fltrev; <addf\0\0>
|
||||
000377; 172400; fltrev; <movf\0\0>
|
||||
000377; 173000; fltrev; <subf\0\0>
|
||||
000377; 173400; fltrev; <cmpf\0\0>
|
||||
000377; 174000; fltnor; <movf\0\0>
|
||||
000377; 174400; fltrev; <divf\0\0>
|
||||
000377; 175000; fltnor; <movei\0>
|
||||
000377; 175400; fltnor; <movfi\0>
|
||||
000377; 176000; fltnor; <movfo\0>
|
||||
000377; 176400; fltrev; <movie\0>
|
||||
000377; 177000; fltrev; <movif\0>
|
||||
000377; 177400; fltrev; <movof\0>
|
||||
000000; 170000; noaddr; <cfcc\0\0>
|
||||
000000; 170001; noaddr; <setf\0\0>
|
||||
000000; 170002; noaddr; <seti\0\0>
|
||||
000000; 170011; noaddr; <setd\0\0>
|
||||
000000; 170012; noaddr; <setl\0\0>
|
||||
|
||||
000777; 004000; specl1; <jsr\0\0\0>
|
||||
000777; 074000; specl1; <xor\0\0\0>
|
||||
000007; 000200; specl2; <rts\0\0\0>
|
||||
000017; 000240; specl3; <cflg\0\0>
|
||||
000017; 000260; specl3; <sflg\0\0>
|
||||
000377; 104000; specl4; <emt\0\0\0>
|
||||
000377; 104400; specl5; <sys\0\0\0>
|
||||
000077; 006400; specl7; <mark\0\0>
|
||||
000777; 077000; specl8; <sob\0\0\0>
|
||||
000007; 000230; specl9; <spl\0\0\0>
|
||||
177777; 000000; specl6; <oct\0\0\0>
|
||||
|
||||
fltrev:
|
||||
bic $!377,(sp)
|
||||
muldiv:
|
||||
jsr pc,psp
|
||||
mov (sp)+,r0
|
||||
asl r0
|
||||
asl r0
|
||||
swab r0
|
||||
aslb r0
|
||||
aslb r0
|
||||
aslb r0
|
||||
aslb r0
|
||||
asr r0
|
||||
asr r0
|
||||
asr r0
|
||||
asr r0
|
||||
bic $!7707,r0
|
||||
mov r0,-(sp)
|
||||
br fltnor1
|
||||
|
||||
fltnor:
|
||||
bic $!377,(sp)
|
||||
br 1f
|
||||
|
||||
double:
|
||||
tst (sp)
|
||||
bge 1f
|
||||
jsr pc,pb
|
||||
1:
|
||||
jsr pc,psp
|
||||
mov (sp),r0
|
||||
fltnor1:
|
||||
als $-6,r0
|
||||
jsr r5,decodadr; dot
|
||||
add r0,incdot
|
||||
add dot,r0
|
||||
mov r0,temp
|
||||
jsr pc,pcom
|
||||
mov (sp)+,r0
|
||||
jsr r5,decodadr; temp
|
||||
add r0,incdot
|
||||
rts pc
|
||||
|
||||
single:
|
||||
tst (sp)
|
||||
bge singlw
|
||||
jsr pc,pb
|
||||
singlw:
|
||||
jsr pc,psp
|
||||
mov (sp)+,r0
|
||||
jsr r5,decodadr; dot
|
||||
add r0,incdot
|
||||
rts pc
|
||||
|
||||
specl8: / sob
|
||||
jsr pc,psp
|
||||
mov (sp),r3
|
||||
als $-6,r3
|
||||
jsr pc,preg
|
||||
jsr pc,pcom
|
||||
mov (sp)+,r0
|
||||
bic $!77,r0
|
||||
neg r0
|
||||
br 1f
|
||||
|
||||
branch:
|
||||
jsr pc,psp
|
||||
mov (sp)+,r0
|
||||
bic $!377,r0
|
||||
bit $200,r0
|
||||
beq 1f
|
||||
bis $177400,r0
|
||||
1:
|
||||
inc r0
|
||||
asl r0
|
||||
add dot,r0
|
||||
jsr pc,pname
|
||||
rts pc
|
||||
|
||||
noaddr:
|
||||
tst (sp)+
|
||||
rts pc
|
||||
|
||||
specl1: / jsr
|
||||
jsr pc,psp
|
||||
mov (sp),r3
|
||||
als $-6,r3
|
||||
jsr pc,preg
|
||||
jsr pc,pcom
|
||||
mov (sp)+,r0
|
||||
jsr r5,decodadr; dot
|
||||
add r0,incdot
|
||||
rts pc
|
||||
|
||||
specl2: / rts
|
||||
jsr pc,psp
|
||||
mov (sp)+,r3
|
||||
jsr pc,preg
|
||||
rts pc
|
||||
|
||||
specl3: / opr
|
||||
jsr pc,psp
|
||||
mov (sp)+,r2
|
||||
mov $3f,r1
|
||||
1:
|
||||
bit $17,r2
|
||||
beq 1f
|
||||
bit $10,r2
|
||||
beq 2f
|
||||
movb (r1),r0
|
||||
jsr pc,putc
|
||||
2:
|
||||
inc r1
|
||||
asl r2
|
||||
br 1b
|
||||
1:
|
||||
rts pc
|
||||
3:
|
||||
<nzvc>
|
||||
|
||||
specl7: / mark
|
||||
bic $!77,(sp)
|
||||
br specl4
|
||||
|
||||
specl9: / spl
|
||||
bic $!7,(sp)
|
||||
br specl4
|
||||
|
||||
specl4: / emt
|
||||
jsr pc,psp
|
||||
mov (sp)+,r0
|
||||
bic $!377,r0
|
||||
8:
|
||||
jsr pc,printo
|
||||
rts pc
|
||||
|
||||
specl5: / sys
|
||||
jsr pc,psp
|
||||
mov (sp)+,r2
|
||||
bic $!377,r2
|
||||
mov r2,r0
|
||||
asl r2
|
||||
asl r2
|
||||
cmp r2,$esystab-systab
|
||||
bhis 8b
|
||||
mov systab(r2),r1
|
||||
jsr pc,string
|
||||
mov systab+2(r2),-(sp)
|
||||
mov dot,temp1
|
||||
1:
|
||||
dec (sp)
|
||||
bge 2f
|
||||
tst (sp)+
|
||||
rts pc
|
||||
2:
|
||||
jsr r5,mesg; <;\0>
|
||||
add $2,temp1
|
||||
add $2,incdot
|
||||
jsr r5,get; temp1
|
||||
jsr pc,pname
|
||||
br 1b
|
||||
|
||||
systab:
|
||||
1f; 0; .data; 1:<rele\0>; .text
|
||||
1f; 0; .data; 1:<exit\0>; .text
|
||||
1f; 0; .data; 1:<fork\0>; .text
|
||||
1f; 2; .data; 1:<read\0>; .text
|
||||
1f; 2; .data; 1:<write\0>; .text
|
||||
1f; 2; .data; 1:<open\0>; .text
|
||||
1f; 0; .data; 1:<close\0>; .text
|
||||
1f; 0; .data; 1:<wait\0>; .text
|
||||
1f; 2; .data; 1:<creat\0>; .text
|
||||
1f; 2; .data; 1:<link\0>; .text
|
||||
1f; 1; .data; 1:<unlink\0>; .text
|
||||
1f; 2; .data; 1:<exec\0>; .text
|
||||
1f; 1; .data; 1:<chdir\0>; .text
|
||||
1f; 0; .data; 1:<time\0>; .text
|
||||
1f; 1; .data; 1:<makdir\0>; .text
|
||||
1f; 2; .data; 1:<chmod\0>; .text
|
||||
1f; 2; .data; 1:<chown\0>; .text
|
||||
1f; 1; .data; 1:<break\0>; .text
|
||||
1f; 2; .data; 1:<stat\0>; .text
|
||||
1f; 2; .data; 1:<seek\0>; .text
|
||||
1f; 2; .data; 1:<tell\0>; .text
|
||||
1f; 2; .data; 1:<mount\0>; .text
|
||||
1f; 1; .data; 1:<umount\0>; .text
|
||||
1f; 0; .data; 1:<setuid\0>; .text
|
||||
1f; 0; .data; 1:<getuid\0>; .text
|
||||
1f; 0; .data; 1:<stime\0>; .text
|
||||
1f; 1; .data; 1:<quit\0>; .text
|
||||
1f; 1; .data; 1:<intr\0>; .text
|
||||
1f; 1; .data; 1:<fstat\0>; .text
|
||||
1f; 1; .data; 1:<emt\0>; .text
|
||||
1f; 1; .data; 1:<smdate\0>; .text
|
||||
1f; 1; .data; 1:<stty\0>; .text
|
||||
1f; 1; .data; 1:<gtty\0>; .text
|
||||
1f; 1; .data; 1:<ilgins\0>; .text
|
||||
1f; 0; .data; 1:<hog\0>; .text
|
||||
1f; 0; .data; 1:<sleep\0>; .text
|
||||
1f; 0; .data; 1:<sync\0>; .text
|
||||
1f; 0; .data; 1:<kill\0>; .text
|
||||
1f; 0; .data; 1:<switches\0>; .text
|
||||
1f; 0; .data; 1:<boot\0>; .text
|
||||
esystab:
|
||||
.data
|
||||
.even
|
||||
.text
|
||||
|
||||
specl6: / unknown
|
||||
jsr pc,psp
|
||||
mov (sp)+,r0
|
||||
jsr pc,printo
|
||||
rts pc
|
||||
@@ -0,0 +1,54 @@
|
||||
/ db4 -- debugger
|
||||
|
||||
maxsym = 24000.
|
||||
core:
|
||||
<core\0>
|
||||
a.out:
|
||||
<a.out\0>
|
||||
.even
|
||||
zero: 0
|
||||
.bss
|
||||
regbuf:
|
||||
.=.+1024.
|
||||
sigp = regbuf+310
|
||||
txtsiz = regbuf+322
|
||||
datsiz = regbuf+324
|
||||
stksiz = regbuf+326
|
||||
rtxtsiz: .=.+2
|
||||
.data
|
||||
objmagic: 407
|
||||
nobjmagic: 410
|
||||
namsiz: nambuf
|
||||
incdot: 2
|
||||
nlcom: '/
|
||||
|
||||
.bss
|
||||
|
||||
starmod:.=.+2
|
||||
symbol: .=.+10.
|
||||
getoff: .=.+2
|
||||
namstrt: .=.+2
|
||||
bytemod: .=.+2
|
||||
savsp: .=.+2
|
||||
error: .=.+2
|
||||
ttyfin: .=.+2
|
||||
dbfin: .=.+2
|
||||
symfin: .=.+2
|
||||
curfin: .=.+2
|
||||
dbfout: .=.+2
|
||||
ch: .=.+2
|
||||
lastop: .=.+2
|
||||
addres: .=.+2
|
||||
taddr: .=.+2
|
||||
adrflg: .=.+2
|
||||
fpsr: .=.+2
|
||||
och: .=.+2
|
||||
dot: .=.+2
|
||||
count: .=.+2
|
||||
syscnt: .=.+2
|
||||
temp: .=.+2
|
||||
temp1: .=.+2
|
||||
obuf: .=.+8.
|
||||
inbuf: .=.+128.
|
||||
nambuf: .=.+20
|
||||
|
||||
+2542
File diff suppressed because it is too large
Load Diff
+457
@@ -0,0 +1,457 @@
|
||||
/
|
||||
/
|
||||
/ routine to add the two centennial numbers
|
||||
/ pointed to by r2 and r3.
|
||||
/ a pointer to the result is returned in r1
|
||||
/ r2 and r3 are preserved
|
||||
/
|
||||
/ mov ptr1,r2
|
||||
/ mov ptr2,r3
|
||||
/ jsr pc,add3
|
||||
/ mov r1,...
|
||||
/
|
||||
add3: mov r0,-(sp)
|
||||
mov r4,-(sp)
|
||||
mov r5,-(sp)
|
||||
mov r3,-(sp)
|
||||
mov r2,-(sp)
|
||||
/
|
||||
/ allocate a new string whose length is
|
||||
/ the max of the two addends.
|
||||
/
|
||||
mov w(r2),r0
|
||||
sub a(r2),r0
|
||||
mov w(r3),r4
|
||||
sub a(r3),r4
|
||||
cmp r0,r4
|
||||
bgt 1f
|
||||
mov r4,r0
|
||||
1: mov r0,r4
|
||||
jsr pc,allocate
|
||||
mov r1,-(sp)
|
||||
/
|
||||
/ get everything ready
|
||||
/
|
||||
mov 2(sp),r1
|
||||
jsr pc,rewind
|
||||
mov 4(sp),r1
|
||||
jsr pc,rewind
|
||||
clr carry
|
||||
/
|
||||
/ now add them
|
||||
/
|
||||
2: dec r4
|
||||
blt 3f
|
||||
mov 2(sp),r1 /r2
|
||||
jsr pc,getchar
|
||||
mov r0,r5
|
||||
mov 4(sp),r1 /r3
|
||||
jsr pc,getchar
|
||||
add r5,r0
|
||||
add carry,r0
|
||||
clr carry
|
||||
cmp r0,$100.
|
||||
blt 1f
|
||||
sub $100.,r0
|
||||
mov $1,carry
|
||||
1:
|
||||
tstb r0
|
||||
bpl 1f
|
||||
add $100.,r0
|
||||
mov $-1,carry
|
||||
1: mov (sp),r1 /r1
|
||||
jsr pc,putchar
|
||||
br 2b
|
||||
/
|
||||
/ perhaps there is an extra digit
|
||||
/
|
||||
3: mov carry,r0
|
||||
beq 2f
|
||||
mov (sp),r1 /r1
|
||||
jsr pc,putchar
|
||||
/
|
||||
/ strip leading zeros
|
||||
/
|
||||
2:
|
||||
jsr pc,fsfile
|
||||
2: jsr pc,backspace
|
||||
bes 2f
|
||||
beq 2b
|
||||
inc r(r1)
|
||||
2: mov r(r1),w(r1)
|
||||
/
|
||||
/ strip leading 99's
|
||||
/
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
cmpb r0,$-1
|
||||
bne 1f
|
||||
2:
|
||||
jsr pc,backspace
|
||||
bes 2f
|
||||
cmpb r0,$99.
|
||||
beq 2b
|
||||
jsr pc,getchar
|
||||
2:
|
||||
mov $-1,r0
|
||||
jsr pc,alterchar
|
||||
mov r(r1),w(r1)
|
||||
/
|
||||
/ restore and return
|
||||
/
|
||||
1:
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r5
|
||||
mov (sp)+,r4
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
.bss
|
||||
carry: .=.+2
|
||||
.text
|
||||
/
|
||||
/
|
||||
/ routine to change the sign of the centennial number
|
||||
/ pointed to by r1.
|
||||
/ negative numbers are stored in 100's complement form with
|
||||
/ -1 as the high order digit; the second digit is not 99.
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,chsign
|
||||
/
|
||||
chsign:
|
||||
mov r1,-(sp)
|
||||
mov r0,-(sp)
|
||||
jsr pc,rewind
|
||||
clr chcarry
|
||||
/
|
||||
1:
|
||||
jsr pc,lookchar
|
||||
bes 1f
|
||||
negb r0
|
||||
sub chcarry,r0
|
||||
mov $1,chcarry
|
||||
add $100.,r0
|
||||
cmpb $100.,r0
|
||||
bgt 2f
|
||||
sub $100.,r0
|
||||
clr chcarry
|
||||
2:
|
||||
jsr pc,alterchar
|
||||
br 1b
|
||||
/
|
||||
1:
|
||||
clr r0
|
||||
sub chcarry,r0
|
||||
beq 2f
|
||||
jsr pc,putchar
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
jsr pc,backspace
|
||||
cmp r0,$99.
|
||||
bne 1f
|
||||
mov r(r1),w(r1)
|
||||
mov $-1,r0
|
||||
jsr pc,putchar
|
||||
br 1f
|
||||
/
|
||||
2:
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
bne 1f
|
||||
mov r(r1),w(r1)
|
||||
/
|
||||
1:
|
||||
mov (sp)+,r0
|
||||
mov (sp)+,r1
|
||||
rts pc
|
||||
/
|
||||
.bss
|
||||
chcarry: .=.+2
|
||||
.text
|
||||
/
|
||||
/
|
||||
/
|
||||
/
|
||||
/ routine to multiply the two centennial numbers
|
||||
/ pointed to by r2 and r3.
|
||||
/ a pointer to the result is returned in r1
|
||||
/ r2 and r3 are preserved
|
||||
/
|
||||
/ mov ptr1,r2
|
||||
/ mov ptr2,r3
|
||||
/ jsr pc,mul3
|
||||
/ mov r1,...
|
||||
/
|
||||
/ save registers and make space for temps
|
||||
/
|
||||
mul3:
|
||||
mov r5,-(sp)
|
||||
mov r3,-(sp) /arg2
|
||||
mov r2,-(sp) /arg1
|
||||
mov r0,-(sp)
|
||||
tst -(sp) /result
|
||||
tst -(sp) /arg1
|
||||
tst -(sp) /arg2
|
||||
tst -(sp) /carry
|
||||
/
|
||||
/ compute sign of result and make args positive
|
||||
/
|
||||
clr outsign
|
||||
mov r2,r1
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
bmi 2f
|
||||
mov r2,4(sp) /arg1
|
||||
br 1f
|
||||
2:
|
||||
jsr pc,length
|
||||
jsr pc,allocate
|
||||
mov r1,4(sp)
|
||||
mov r2,r0
|
||||
jsr pc,move
|
||||
jsr pc,chsign
|
||||
com outsign
|
||||
1:
|
||||
mov r3,r1
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
bmi 2f
|
||||
mov r3,2(sp) /arg2
|
||||
br 1f
|
||||
2:
|
||||
mov r3,r1
|
||||
jsr pc,length
|
||||
jsr pc,allocate
|
||||
mov r1,2(sp)
|
||||
mov r3,r0
|
||||
jsr pc,move
|
||||
jsr pc,chsign
|
||||
com outsign
|
||||
1:
|
||||
/
|
||||
/ compute the length of the result and
|
||||
/ allocate space for it
|
||||
/
|
||||
mov w(r2),r0
|
||||
sub a(r2),r0
|
||||
add w(r3),r0
|
||||
sub a(r3),r0
|
||||
jsr pc,allocate
|
||||
jsr pc,zero
|
||||
mov r1,6(sp) /result
|
||||
clr offset
|
||||
mov 2(sp),r1 /arg2
|
||||
jsr pc,rewind
|
||||
/
|
||||
/ work on next digit of arg2, starting over on arg1
|
||||
/
|
||||
1: mov 4(sp),r1 /arg1
|
||||
jsr pc,rewind
|
||||
mov 2(sp),r1 /arg2
|
||||
jsr pc,getchar
|
||||
bes 3f
|
||||
mov r0,r2
|
||||
mov 6(sp),r1 /result
|
||||
jsr pc,rewind
|
||||
add offset,r(r1)
|
||||
clr 0(sp) /carry
|
||||
/
|
||||
/ work on next digit of arg3
|
||||
/ form the product of the two digits,
|
||||
/ add to what is already there and add in old carry
|
||||
/ to generate new dit and new carry.
|
||||
/
|
||||
2: mov 4(sp),r1 /arg1
|
||||
jsr pc,getchar
|
||||
bes 2f
|
||||
mov r0,r3
|
||||
mpy r2,r3
|
||||
add (sp),r3 /carry
|
||||
mov 6(sp),r1 /result
|
||||
jsr pc,lookchar
|
||||
add r0,r3
|
||||
mov r3,r1
|
||||
clr r0
|
||||
dvd $100.,r0
|
||||
mov r0,(sp) /carry
|
||||
mov r1,r0
|
||||
mov 6(sp),r1 /result
|
||||
jsr pc,alterchar
|
||||
br 2b
|
||||
/
|
||||
2:
|
||||
inc offset
|
||||
tst (sp) /carry
|
||||
beq 1b
|
||||
mov 6(sp),r1 /result
|
||||
jsr pc,lookchar
|
||||
add (sp),r0 /carry
|
||||
jsr pc,alterchar
|
||||
br 1b
|
||||
/
|
||||
3:
|
||||
/
|
||||
/ change sign of result if necessary
|
||||
/
|
||||
tst outsign
|
||||
bpl 1f
|
||||
mov 6(sp),r1 /result
|
||||
jsr pc,chsign
|
||||
/
|
||||
/ release dregs if necessary
|
||||
/
|
||||
1:
|
||||
cmp 2(sp),14(sp)
|
||||
beq 1f
|
||||
mov 2(sp),r1
|
||||
jsr pc,release
|
||||
1:
|
||||
cmp 4(sp),12(sp)
|
||||
beq 1f
|
||||
mov 4(sp),r1
|
||||
jsr pc,release
|
||||
1:
|
||||
/
|
||||
/ restore registers and return
|
||||
/
|
||||
tst (sp)+
|
||||
tst (sp)+
|
||||
tst (sp)+
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r0
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r5
|
||||
rts pc
|
||||
/
|
||||
.bss
|
||||
outsign: .=.+2
|
||||
offset: .=.+2
|
||||
k: .=.+2
|
||||
kptr: .=.+2
|
||||
.text
|
||||
/
|
||||
sqrt:
|
||||
mov r4,-(sp)
|
||||
mov r3,-(sp)
|
||||
mov r2,-(sp)
|
||||
mov r0,-(sp)
|
||||
/
|
||||
/ check for zero or negative
|
||||
/
|
||||
mov w(r1),r2
|
||||
sub a(r1),r2
|
||||
/
|
||||
/ look at the top one or two digits
|
||||
/
|
||||
mov r1,r3
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
mov r0,r4
|
||||
bit $1,r2
|
||||
bne 2f
|
||||
mov r4,r1
|
||||
mul $100.,r1
|
||||
mov r1,r4
|
||||
mov r3,r1
|
||||
jsr pc,backspace
|
||||
add r0,r4
|
||||
2:
|
||||
/
|
||||
/ allocate space for result
|
||||
/
|
||||
inc r2
|
||||
asr r2
|
||||
mov r2,r0
|
||||
jsr pc,allocate
|
||||
jsr pc,zero
|
||||
mov r2,r0
|
||||
jsr pc,seekchar
|
||||
mov r1,r2
|
||||
/
|
||||
/ get high order digit of arg and square root it
|
||||
/
|
||||
mov $1,r0
|
||||
2: sub r0,r4
|
||||
blt 2f
|
||||
add $2,r0
|
||||
br 2b
|
||||
2: inc r0
|
||||
asr r0
|
||||
mov r0,r4
|
||||
mov r2,r1
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
cmp r4,$100.
|
||||
blt 1f
|
||||
sub $100.,r4
|
||||
mov r4,r0
|
||||
jsr pc,alterchar
|
||||
mov $1,r0
|
||||
jsr pc,putchar
|
||||
br 2f
|
||||
1:
|
||||
mov r4,r0
|
||||
jsr pc,alterchar
|
||||
2:
|
||||
mov r1,-(sp)
|
||||
mov r3,-(sp)
|
||||
/
|
||||
/ get successive approx. from Newton
|
||||
/
|
||||
1: mov (sp),r3 /arg
|
||||
mov 2(sp),r2 /approx
|
||||
jsr pc,div3
|
||||
mov r1,r3
|
||||
jsr pc,add3
|
||||
mov r1,-(sp)
|
||||
mov r3,r1
|
||||
jsr pc,release
|
||||
mov r4,r1
|
||||
jsr pc,release
|
||||
mov (sp)+,r1
|
||||
mov sqtemp,r2
|
||||
mov r1,r3
|
||||
jsr pc,div3
|
||||
mov r1,-(sp)
|
||||
mov r3,r1
|
||||
jsr pc,release
|
||||
mov r4,r1
|
||||
jsr pc,release
|
||||
mov (sp)+,r3
|
||||
mov 2(sp),r1
|
||||
jsr pc,length
|
||||
jsr pc,allocate
|
||||
mov 2(sp),r0
|
||||
jsr pc,move
|
||||
jsr pc,chsign
|
||||
mov r1,r2
|
||||
jsr pc,add3
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
jsr pc,release
|
||||
mov r2,r1
|
||||
jsr pc,release
|
||||
tst r0
|
||||
bpl 2f
|
||||
/
|
||||
/ loop if new < old
|
||||
mov 2(sp),r1
|
||||
jsr pc,release
|
||||
mov r3,2(sp)
|
||||
br 1b
|
||||
/
|
||||
2:
|
||||
mov r3,r1
|
||||
jsr pc,release
|
||||
mov (sp)+,r1
|
||||
jsr pc,release
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r0
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r4
|
||||
rts pc
|
||||
+460
@@ -0,0 +1,460 @@
|
||||
/
|
||||
/
|
||||
/ routine to divide the two centennial numbers pointed
|
||||
/ to by r2 (the divisor) and r3 (the dividend).
|
||||
/ A pointer to the result is returned in r1. All other
|
||||
/ registers are preserved. If the divisor is zero, zero
|
||||
/ is returned and the carry bit is set.
|
||||
/ Remainder is returned in r4 and has the sign
|
||||
/ of the dividend.
|
||||
/
|
||||
/
|
||||
/ mov divisor,r2
|
||||
/ mov dividend,r3
|
||||
/ jsr pc,div3
|
||||
/ mov r1,result
|
||||
/ mov r4,remainder
|
||||
/
|
||||
/
|
||||
div3:
|
||||
mov r5,-(sp)
|
||||
mov r3,-(sp) /dividend
|
||||
mov r2,-(sp) /divisor
|
||||
mov r0,-(sp)
|
||||
tst -(sp) /result
|
||||
/
|
||||
/ allocate space for result; allocate temps if necessary
|
||||
/
|
||||
clr r0
|
||||
jsr pc,allocate
|
||||
mov r1,0(sp) /result
|
||||
/
|
||||
/
|
||||
/ check for divisor zero
|
||||
/
|
||||
mov 4(sp),r2 /divisor
|
||||
mov w(r2),r0
|
||||
sub a(r2),r0
|
||||
bne 1f
|
||||
jmp eh
|
||||
1:
|
||||
/
|
||||
/ compute sign of result and make arguments positive
|
||||
/
|
||||
clr divsign
|
||||
mov r2,r1
|
||||
jsr pc,length
|
||||
jsr pc,allocate
|
||||
mov r1,divisor
|
||||
mov r2,r0
|
||||
jsr pc,move
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
bpl 1f
|
||||
2:
|
||||
jsr pc,chsign
|
||||
mov r1,divisor
|
||||
com divsign
|
||||
1:
|
||||
clr remsign
|
||||
mov r3,r1
|
||||
jsr pc,length
|
||||
jsr pc,allocate
|
||||
mov r1,dividend
|
||||
mov r3,r0
|
||||
jsr pc,move
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
bpl 1f
|
||||
2:
|
||||
jsr pc,chsign
|
||||
mov r1,dividend
|
||||
com divsign
|
||||
com remsign
|
||||
1:
|
||||
/
|
||||
/
|
||||
/ find out how many digits in the quotient result
|
||||
/
|
||||
1:
|
||||
mov dividend,r2
|
||||
mov divisor,r3
|
||||
mov w(r2),r0
|
||||
sub a(r2),r0
|
||||
add a(r3),r0
|
||||
sub w(r3),r0
|
||||
jlo bugout
|
||||
mov r0,divoffset
|
||||
mov 0(sp),r1 /result
|
||||
inc r0
|
||||
jsr pc,seekchar
|
||||
clr r0
|
||||
mov dividend,r1
|
||||
jsr pc,putchar
|
||||
/
|
||||
/ load r5 with binary divisor for finding
|
||||
/ trial quotient digits. If leading digit of
|
||||
/ divisor is <10, it is scaled
|
||||
/
|
||||
clr magic
|
||||
mov divisor,r1
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
mov r0,r5
|
||||
cmp r5,$10.
|
||||
bge 2f
|
||||
inc magic
|
||||
2:
|
||||
mpy $100.,r5
|
||||
jsr pc,backspace
|
||||
add r0,r5
|
||||
tst magic
|
||||
beq 2f
|
||||
mov r5,r4
|
||||
mpy $100.,r4
|
||||
jsr pc,backspace
|
||||
add r0,r5
|
||||
adc r4
|
||||
asl r5
|
||||
rol r4
|
||||
dvd $25.,r4
|
||||
mov r4,r5
|
||||
2:
|
||||
/
|
||||
/ compute trial quotient digit
|
||||
/
|
||||
1:
|
||||
mov dividend,r1
|
||||
jsr pc,fsfile
|
||||
jsr pc,backspace
|
||||
bec 9f; 4; 9:
|
||||
mov r0,r3
|
||||
mpy $100.,r3
|
||||
mov r3,r2
|
||||
jsr pc,backspace
|
||||
add r0,r2
|
||||
mpy $100.,r2
|
||||
jsr pc,backspace
|
||||
add r0,r3
|
||||
adc r2
|
||||
tst divoffset
|
||||
bne 2f
|
||||
add $1,r3
|
||||
adc r2
|
||||
2:
|
||||
/
|
||||
tst magic
|
||||
beq 3f
|
||||
ashc $3,r2
|
||||
3:
|
||||
mov r5,r0
|
||||
tst divoffset
|
||||
beq 2f
|
||||
inc r0
|
||||
2:
|
||||
dvd r0,r2
|
||||
mov r2,trial
|
||||
/
|
||||
/
|
||||
/ multiply divisor by trial digit
|
||||
/
|
||||
mov divisor,r1
|
||||
jsr pc,rewind
|
||||
jsr pc,length
|
||||
inc r0
|
||||
mov divxyz,r1
|
||||
jsr pc,rewind
|
||||
clr -(sp)
|
||||
2:
|
||||
mov divisor,r1
|
||||
jsr pc,getchar
|
||||
bes 2f
|
||||
mov r0,r3
|
||||
mpy trial,r3
|
||||
add (sp),r3 /carry
|
||||
clr r2
|
||||
dvd $100.,r2
|
||||
mov r2,(sp) /carry
|
||||
mov r3,r0
|
||||
mov divxyz,r1
|
||||
jsr pc,alterchar
|
||||
br 2b
|
||||
2:
|
||||
mov divxyz,r1
|
||||
mov (sp)+,r0
|
||||
jsr pc,alterchar
|
||||
3:
|
||||
/
|
||||
/ and subtract from dividend
|
||||
/
|
||||
jsr pc,rewind
|
||||
mov divoffset,r0
|
||||
mov dividend,r1
|
||||
jsr pc,seekchar
|
||||
clr -(sp)
|
||||
/
|
||||
2: mov dividend,r1
|
||||
jsr pc,lookchar
|
||||
bes 2f
|
||||
mov r0,r2
|
||||
/
|
||||
mov divxyz,r1
|
||||
jsr pc,getchar
|
||||
sub r0,r2
|
||||
sub (sp),r2
|
||||
clr (sp)
|
||||
mov r2,r0
|
||||
bpl 3f
|
||||
add $100.,r0
|
||||
mov $1.,(sp)
|
||||
3: mov dividend,r1
|
||||
jsr pc,alterchar
|
||||
br 2b
|
||||
/
|
||||
/ put away the quotient digit
|
||||
/
|
||||
2:
|
||||
mov (sp)+,divcarry
|
||||
mov 0(sp),r1 /result
|
||||
jsr pc,backspace
|
||||
mov trial,r0
|
||||
jsr pc,alterchar
|
||||
jsr pc,backspace
|
||||
/
|
||||
/ and go for another digit
|
||||
/
|
||||
dec divoffset
|
||||
bmi 1f
|
||||
mov dividend,r1
|
||||
dec w(r1)
|
||||
cmp w(r1),a(r1)
|
||||
bhis 9f; 4; 9:
|
||||
jmp 1b
|
||||
/
|
||||
/ fix up the result
|
||||
/
|
||||
1:
|
||||
tst divcarry
|
||||
beq 1f
|
||||
mov trial,r0
|
||||
dec r0
|
||||
jsr pc,alterchar
|
||||
mov dividend,r1
|
||||
mov $-1,r0
|
||||
jsr pc,alterchar
|
||||
mov divisor,r2
|
||||
mov dividend,r3
|
||||
jsr pc,add3
|
||||
mov r1,-(sp)
|
||||
mov r3,r1
|
||||
jsr pc,release
|
||||
mov (sp)+,dividend
|
||||
1:
|
||||
mov 0(sp),r1 /result
|
||||
jsr pc,rewind
|
||||
clr divcarry
|
||||
1:
|
||||
jsr pc,lookchar
|
||||
bes 1f
|
||||
bic $!377,r0
|
||||
add divcarry,r0
|
||||
clr divcarry
|
||||
cmp r0,$100.
|
||||
blt 2f
|
||||
sub $100.,r0
|
||||
inc divcarry
|
||||
2: jsr pc,alterchar
|
||||
br 1b
|
||||
/
|
||||
1:
|
||||
tst divcarry
|
||||
beq 1f
|
||||
mov $1.,r0
|
||||
jsr pc,alterchar
|
||||
1:
|
||||
jsr pc,fsfile
|
||||
1:
|
||||
jsr pc,backspace
|
||||
bes 1f
|
||||
bne 1f
|
||||
mov r(r1),w(r1)
|
||||
br 1b
|
||||
1:
|
||||
/
|
||||
/ change sign of result if necessary
|
||||
/
|
||||
tst divsign
|
||||
bpl 1f
|
||||
jsr pc,chsign
|
||||
1:
|
||||
mov dividend,r1
|
||||
jsr pc,fsfile
|
||||
1:
|
||||
jsr pc,backspace
|
||||
bes 1f
|
||||
bne 1f
|
||||
mov r(r1),w(r1)
|
||||
br 1b
|
||||
1:
|
||||
bugout:
|
||||
tst remsign
|
||||
bpl 1f
|
||||
mov dividend,r1
|
||||
jsr pc,chsign
|
||||
/
|
||||
/ clean up junk, restore registers, and return
|
||||
/
|
||||
1:
|
||||
mov divisor,r1
|
||||
jsr pc,release
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r0
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r3
|
||||
mov dividend,r4
|
||||
mov (sp)+,r5
|
||||
clc
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/
|
||||
/
|
||||
.bss
|
||||
divisor: .=.+2
|
||||
dividend: .=.+2
|
||||
divxyz: .=.+2
|
||||
divoffset:.=.+2
|
||||
divcarry: .=.+2
|
||||
divsign: .=.+2
|
||||
trial: .=.+2
|
||||
remsign: .=.+2
|
||||
magic: .=.+2
|
||||
.text
|
||||
/
|
||||
/
|
||||
/
|
||||
/ routine to exponentiate the two centennial numbers
|
||||
/ pointed to by r2 (the base) and r3 (the exponent).
|
||||
/ A pointer to the result is returned in r1.
|
||||
/
|
||||
/ mov base,r2
|
||||
/ mov exp,r3
|
||||
/ jsr pc,exp3
|
||||
/ mov r1,...
|
||||
/
|
||||
/
|
||||
/ save registers
|
||||
/
|
||||
exp3:
|
||||
mov r3,-(sp) /exponent
|
||||
mov r2,-(sp) /base
|
||||
mov r0,-(sp)
|
||||
/
|
||||
/
|
||||
1:
|
||||
mov $1,r0
|
||||
jsr pc,allocate
|
||||
mov r1,-(sp) /accumulated result
|
||||
mov $1,r0
|
||||
jsr pc,putchar
|
||||
/
|
||||
mov r2,r1
|
||||
jsr pc,length
|
||||
jsr pc,allocate
|
||||
mov r1,-(sp) /powers of the base
|
||||
mov r2,r0
|
||||
jsr pc,move
|
||||
/
|
||||
mov r3,r1
|
||||
jsr pc,length
|
||||
jsr pc,allocate
|
||||
mov r1,-(sp) /exponent
|
||||
mov r3,r0
|
||||
jsr pc,move
|
||||
jsr pc,fsfile
|
||||
clr exptemp
|
||||
jsr pc,backspace
|
||||
bpl 1f
|
||||
inc exptemp
|
||||
jsr pc,chsign
|
||||
/
|
||||
1:
|
||||
mov 0(sp),r1
|
||||
jsr pc,length
|
||||
beq 1f
|
||||
mov sqtemp,r2
|
||||
mov 0(sp),r3
|
||||
jsr pc,div3
|
||||
mov r1,0(sp)
|
||||
mov r3,r1
|
||||
jsr pc,release
|
||||
mov r4,r1
|
||||
jsr pc,length
|
||||
jsr pc,release
|
||||
tst r0
|
||||
beq 2f
|
||||
/
|
||||
/
|
||||
/
|
||||
mov 2(sp),r2
|
||||
mov 4(sp),r3
|
||||
jsr pc,mul3
|
||||
mov r1,4(sp)
|
||||
mov r3,r1
|
||||
jsr pc,release
|
||||
2:
|
||||
mov 2(sp),r3
|
||||
mov r3,r1
|
||||
jsr pc,length
|
||||
jsr pc,allocate
|
||||
mov r1,r2
|
||||
mov r3,r0
|
||||
jsr pc,move
|
||||
jsr pc,mul3
|
||||
mov r1,2(sp)
|
||||
mov r3,r1
|
||||
jsr pc,release
|
||||
mov r2,r1
|
||||
jsr pc,release
|
||||
br 1b
|
||||
1:
|
||||
tst exptemp
|
||||
beq 1f
|
||||
mov 10(sp),r1
|
||||
jsr pc,length
|
||||
bne 2f
|
||||
jmp eh
|
||||
2:
|
||||
cmp r0,$1
|
||||
blos 2f
|
||||
mov 4(sp),r1
|
||||
jsr pc,create
|
||||
br 1f
|
||||
2:
|
||||
jsr pc,rewind
|
||||
jsr pc,getchar
|
||||
cmp r0,$1
|
||||
bgt 2f
|
||||
mov 4(sp),r1
|
||||
jsr pc,create
|
||||
jsr pc,putchar
|
||||
br 1f
|
||||
2:
|
||||
mov 4(sp),r1
|
||||
jsr pc,create
|
||||
1:
|
||||
mov (sp)+,r1
|
||||
jsr pc,release
|
||||
mov (sp)+,r1
|
||||
jsr pc,release
|
||||
mov (sp)+,r1
|
||||
/
|
||||
mov (sp)+,r0
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r3
|
||||
rts pc
|
||||
/
|
||||
.bss
|
||||
exptemp: .=.+2
|
||||
.text
|
||||
/
|
||||
+408
@@ -0,0 +1,408 @@
|
||||
.globl getchar
|
||||
.globl stats
|
||||
.globl lookchar
|
||||
.globl fsfile
|
||||
.globl seekchar
|
||||
.globl backspace
|
||||
.globl putchar
|
||||
.globl alterchar
|
||||
.globl move
|
||||
.globl rewind
|
||||
.globl create
|
||||
.globl zero
|
||||
.globl allocate
|
||||
.globl release
|
||||
.globl collect
|
||||
.globl getword, putword
|
||||
.globl length, position
|
||||
.globl w, r, a, l
|
||||
/
|
||||
testing = 0
|
||||
/
|
||||
/
|
||||
/ routine to return the length of a string
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,length
|
||||
/ mov r0,...
|
||||
/
|
||||
length:
|
||||
mov w(r1),r0
|
||||
sub a(r1),r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to return the read pointer position
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,position
|
||||
/ mov r0,...
|
||||
/
|
||||
position:
|
||||
mov r(r1),r0
|
||||
sub a(r1),r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/
|
||||
/
|
||||
/ routine to get a word from the string
|
||||
/ mov ...,r1
|
||||
/ jsr pc,getword
|
||||
/ mov r0,...
|
||||
/
|
||||
getword:
|
||||
jsr pc,getchar
|
||||
bes noch
|
||||
movb r0,nchar
|
||||
jsr pc,getchar
|
||||
bec 2f
|
||||
dec r(r1)
|
||||
br noch
|
||||
2: movb r0,nchar+1
|
||||
mov nchar,r0
|
||||
tst r0 /tst clears c-bit
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to put a word onto the string
|
||||
/ mov ...,r1
|
||||
/ mov ...,r0
|
||||
/ jsr pc,putword
|
||||
/
|
||||
putword:
|
||||
jsr pc,putchar
|
||||
swab r0
|
||||
jsr pc,putchar
|
||||
swab r0
|
||||
rts pc
|
||||
/
|
||||
.bss
|
||||
nchar: .=.+2
|
||||
.text
|
||||
/
|
||||
/
|
||||
/
|
||||
/ routine to read next character from string
|
||||
/ pointed to by r1; character returned in r0
|
||||
/ c-bit set if character not available (end of file)
|
||||
/ r1 is preserved
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,getchar
|
||||
/ movb r0,...
|
||||
/
|
||||
getchar:
|
||||
jsr pc,lookchar
|
||||
bec 2f
|
||||
rts pc
|
||||
2: inc r(r1)
|
||||
tst r0 /tst clears c-bit
|
||||
rts pc
|
||||
/
|
||||
noch: clr r0
|
||||
sec
|
||||
rts pc
|
||||
/
|
||||
/ routine to look at next character from string
|
||||
/ pointed to by r1; character returned in r0
|
||||
/ c-bit set if character not available (end of file)
|
||||
/ r1 is preserved
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,lookchar
|
||||
/ movb r0,...
|
||||
/
|
||||
lookchar:
|
||||
.if testing
|
||||
jsr pc,plausible
|
||||
inc stats+6.
|
||||
.endif
|
||||
cmp w(r1),r(r1)
|
||||
blos noch
|
||||
movb *r(r1),r0
|
||||
clc
|
||||
rts pc
|
||||
/
|
||||
plausible:
|
||||
cmp r1,$headers
|
||||
bhis 9f; 4; 9:
|
||||
cmp r1,$headend
|
||||
blo 9f; 4; 9:
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/
|
||||
/ routine to move the read pointer of a string to a
|
||||
/ specified point. If the string is not long enough,
|
||||
/ the string is extended
|
||||
/
|
||||
/ mov position,r0
|
||||
/ mov ...,r1
|
||||
/ jsr pc,seekchar
|
||||
/
|
||||
seekchar:
|
||||
mov r1,-(sp)
|
||||
mov r0,-(sp)
|
||||
.if testing
|
||||
jsr pc,plausible
|
||||
inc stats+10.
|
||||
.endif
|
||||
1:
|
||||
mov (sp),r0
|
||||
add a(r1),r0
|
||||
cmp r0,l(r1)
|
||||
bhi 3f
|
||||
mov r0,r(r1)
|
||||
cmp r0,w(r1)
|
||||
blo 1f
|
||||
mov r0,w(r1)
|
||||
br 1f
|
||||
3:
|
||||
mov (sp),r0
|
||||
jsr pc,allocate
|
||||
mov 2(sp),r0
|
||||
jsr pc,move
|
||||
jsr pc,swap
|
||||
jsr pc,release
|
||||
mov 2(sp),r1
|
||||
br 1b
|
||||
1:
|
||||
mov (sp)+,r0
|
||||
mov (sp)+,r1
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to move read pointer of string to end of string
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,fsfile
|
||||
/
|
||||
fsfile:
|
||||
.if testing
|
||||
jsr pc,plausible
|
||||
inc stats+10.
|
||||
.endif
|
||||
mov w(r1),r(r1)
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to read a string backwards
|
||||
/ the read pointer is decremented before reading
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,backspace
|
||||
/ mov r0,...
|
||||
/
|
||||
backspace:
|
||||
.if testing
|
||||
jsr pc,plausible
|
||||
inc stats+6.
|
||||
.endif
|
||||
cmp a(r1),r(r1)
|
||||
bhis noch
|
||||
dec r(r1)
|
||||
movb *r(r1),r0
|
||||
clc
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/
|
||||
/
|
||||
/ routine to put a character into the string
|
||||
/ pointed to by r1; character in r0
|
||||
/ r0 and r1 are preserved.
|
||||
/
|
||||
/ movb ch,r0
|
||||
/ mov ...,r1
|
||||
/ jsr pc,putchar
|
||||
/
|
||||
putchar:
|
||||
mov r1,-(sp)
|
||||
mov r0,-(sp)
|
||||
.if testing
|
||||
jsr pc,plausible
|
||||
inc stats+8.
|
||||
.endif
|
||||
1: cmp w(r1),l(r1)
|
||||
blt 3f
|
||||
mov w(r1),r0
|
||||
inc r0
|
||||
sub a(r1),r0 /W-A+1
|
||||
jsr pc,allocate
|
||||
mov 2(sp),r0 /r1
|
||||
jsr pc,move
|
||||
jsr pc,swap
|
||||
jsr pc,release
|
||||
mov 2(sp),r1 /r1
|
||||
cmp w(r1),l(r1)
|
||||
blt 3f
|
||||
jmp err
|
||||
/
|
||||
3: movb (sp),*w(r1)
|
||||
inc w(r1)
|
||||
mov (sp)+,r0
|
||||
tst (sp)+
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
swap:
|
||||
mov w(r1),-(sp)
|
||||
mov w(r0),w(r1)
|
||||
mov (sp),w(r0)
|
||||
mov r(r1),(sp)
|
||||
mov r(r0),r(r1)
|
||||
mov (sp),r(r0)
|
||||
mov a(r1),(sp)
|
||||
mov a(r0),a(r1)
|
||||
mov (sp),a(r0)
|
||||
mov l(r1),(sp)
|
||||
mov l(r0),l(r1)
|
||||
mov (sp)+,l(r0)
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to alter a character in the string
|
||||
/ pointed to by r1; character in r0
|
||||
/ r0 and r1 are preserved.
|
||||
/
|
||||
/ movb ch,r0
|
||||
/ mov ...,r1
|
||||
/ jsr pc,alterchar
|
||||
/
|
||||
alterchar:
|
||||
mov r1,-(sp)
|
||||
mov r0,-(sp)
|
||||
.if testing
|
||||
jsr pc,preposterous
|
||||
inc stats+8.
|
||||
.endif
|
||||
1: cmp r(r1),l(r1)
|
||||
blt 3f
|
||||
mov l(r1),r0
|
||||
inc r0
|
||||
sub a(r1),r0 /W-A+1
|
||||
jsr pc,allocate
|
||||
mov 2(sp),r0 /r1
|
||||
jsr pc,move
|
||||
jsr pc,swap
|
||||
jsr pc,release
|
||||
mov 2(sp),r1 /r1
|
||||
cmp r(r1),l(r1)
|
||||
blt 3f
|
||||
jmp err
|
||||
/
|
||||
3: movb (sp),*r(r1)
|
||||
inc r(r1)
|
||||
cmp r(r1),w(r1)
|
||||
ble 1f
|
||||
mov r(r1),w(r1)
|
||||
1:
|
||||
mov (sp)+,r0
|
||||
tst (sp)+
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to move the contents of one string
|
||||
/ to another.
|
||||
/
|
||||
/ mov source,r0
|
||||
/ mov dest,r1
|
||||
/ jsr pc,move
|
||||
/
|
||||
/ on return, r1 points to the new string and should
|
||||
/ be saved. r0 is preserved.
|
||||
/
|
||||
move:
|
||||
mov r3,-(sp)
|
||||
mov r2,-(sp)
|
||||
mov r1,-(sp)
|
||||
mov r0,-(sp)
|
||||
mov w(r0),r2
|
||||
sub a(r0),r2 /W-A
|
||||
mov l(r1),r3
|
||||
sub a(r1),r3 /L-A
|
||||
cmp r2,r3
|
||||
ble 1f
|
||||
mov r2,r0
|
||||
jsr pc,allocate
|
||||
mov 2(sp),r0 /r1
|
||||
jsr pc,swap
|
||||
jsr pc,release
|
||||
mov r0,r1
|
||||
mov 0(sp),r0 /r0
|
||||
/
|
||||
1: mov a(r0),(r0)
|
||||
mov a(r1),(r1)
|
||||
1: dec r2
|
||||
blt 1f
|
||||
movb *(r0),*(r1)
|
||||
inc (r0)
|
||||
inc (r1)
|
||||
br 1b
|
||||
/
|
||||
/ fix up read ptr of new string
|
||||
/
|
||||
1: mov r(r0),r2
|
||||
sub a(r0),r2
|
||||
add a(r1),r2
|
||||
mov r2,r(r1)
|
||||
/
|
||||
/ restore and return
|
||||
/
|
||||
mov (sp)+,r0
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r3
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to rewind read pointer of string
|
||||
/ pointed to by r1
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,rewind
|
||||
/
|
||||
rewind:
|
||||
.if testing
|
||||
jsr pc,plausible
|
||||
inc stats+10.
|
||||
.endif
|
||||
mov a(r1),r(r1)
|
||||
rts pc
|
||||
/
|
||||
/ routine to rewind write pointer of string
|
||||
/ pointed to by r1
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,create
|
||||
/
|
||||
create:
|
||||
.if testing
|
||||
jsr pc,plausible
|
||||
inc stats+10.
|
||||
.endif
|
||||
mov a(r1),w(r1)
|
||||
mov a(r1),r(r1)
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to zero a string
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,zero
|
||||
/
|
||||
zero:
|
||||
mov r0,-(sp)
|
||||
.if testing
|
||||
jsr pc,preposterous
|
||||
.endif
|
||||
mov a(r1),r0
|
||||
1: cmp r0,l(r1)
|
||||
bhis 1f
|
||||
clrb (r0)+
|
||||
br 1b
|
||||
1: mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
+540
@@ -0,0 +1,540 @@
|
||||
/
|
||||
/
|
||||
/ here to allocate a new block
|
||||
/
|
||||
/ mov ...,r0
|
||||
/ jsr pc,allocate
|
||||
/ mov r1,...
|
||||
/
|
||||
/ requested size in bytes in r0
|
||||
/ pointer to header of allocated block returned in r1
|
||||
/ r0 is preserved
|
||||
/
|
||||
/ convert to words, adjust for header, round up
|
||||
/ to a power of two
|
||||
/
|
||||
/ each block has a four-word header
|
||||
/ W - write ptr (also used as link ptr in frlist)
|
||||
/ R - read ptr
|
||||
/ A - pointer to head of data
|
||||
/ L - ptr to (end+1) of data
|
||||
w=0
|
||||
r=2
|
||||
a=4
|
||||
l=6
|
||||
/
|
||||
allocate:
|
||||
clr garbage
|
||||
mov r0,-(sp)
|
||||
mov r2,-(sp)
|
||||
tst stats
|
||||
bne 1f
|
||||
jsr pc,init
|
||||
1:
|
||||
inc stats
|
||||
bne 9f; inc stats; 9:
|
||||
cmp r0,$strend-strbuf
|
||||
blos 9f; 4; 9:
|
||||
1:
|
||||
cmp $8.,r0
|
||||
blo 2f
|
||||
mov $3.,r0
|
||||
br 1f
|
||||
2:
|
||||
sub $1,r0
|
||||
bmi 1f
|
||||
jsr pc,log2
|
||||
add $1,r0
|
||||
1: asl r0 /bite to word
|
||||
mov r0,-(sp)
|
||||
add $2,r0
|
||||
cmp r0,$frend-frlist+2
|
||||
blo zzz
|
||||
jmp err
|
||||
/
|
||||
/ look on free list for block of required size
|
||||
/
|
||||
zzz:
|
||||
mov (sp),r0
|
||||
tst frlist(r0)
|
||||
beq xxx
|
||||
/
|
||||
/ found it, allocate and return
|
||||
/
|
||||
mov frlist(r0),r1
|
||||
mov (r1),frlist(r0)
|
||||
mov a(r1),r0
|
||||
mov r0,w(r1) /W
|
||||
mov r0,r(r1) /R
|
||||
tst (sp)+
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/ no block of required size
|
||||
/ look for larger block
|
||||
/
|
||||
xxx:
|
||||
tst hdrptr
|
||||
bne 1f
|
||||
mov r0,-(sp)
|
||||
jsr pc,morehd
|
||||
tst r0
|
||||
bne out
|
||||
mov (sp)+,r0
|
||||
1:
|
||||
tst (r0)+
|
||||
cmp r0,$frend-frlist
|
||||
bhis www
|
||||
tst frlist(r0)
|
||||
bne yyy
|
||||
br xxx
|
||||
/
|
||||
/ there are no larger blocks; must garbage collect
|
||||
/
|
||||
www:
|
||||
jsr pc,collect
|
||||
tst r0
|
||||
bne zzz
|
||||
jsr pc,moresp
|
||||
tst r0
|
||||
beq zzz
|
||||
/
|
||||
/ out of space
|
||||
/
|
||||
out:
|
||||
mov $1,r0
|
||||
sys write; 1f; 2f-1f
|
||||
jmp reset
|
||||
1: <Out of space.\n>
|
||||
2: .even
|
||||
/
|
||||
/ split larger block into two smaller pieces and
|
||||
/ link together as smaller blocks in the free list.
|
||||
/
|
||||
yyy:
|
||||
mov frlist(r0),r1
|
||||
mov (r1),frlist(r0)
|
||||
mov hdrptr,r2
|
||||
bne 1f
|
||||
mov r0,-(sp)
|
||||
jsr pc,morehd
|
||||
tst r0
|
||||
bne out
|
||||
mov (sp)+,r0
|
||||
mov hdrptr,r2
|
||||
1:
|
||||
mov (r2),hdrptr
|
||||
clr (r2)
|
||||
mov r2,(r1)
|
||||
mov r1,hdrptr(r0)
|
||||
mov l(r1),l(r2)
|
||||
mov l(r1),r0
|
||||
sub a(r1),r0
|
||||
asr r0
|
||||
add a(r1),r0
|
||||
mov r0,l(r1)
|
||||
mov r0,a(r2)
|
||||
br zzz
|
||||
/
|
||||
/
|
||||
/ here to release a block
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,release
|
||||
/
|
||||
/ pointer to block in r1
|
||||
/
|
||||
release:
|
||||
/
|
||||
/ discover that this is a plausible pointer
|
||||
/
|
||||
mov r0,-(sp)
|
||||
jsr pc,preposterous
|
||||
/
|
||||
/ find free list index and link block to that entry
|
||||
/
|
||||
inc stats+2
|
||||
mov frlist(r0),(r1)
|
||||
clr r(r1)
|
||||
mov r1,frlist(r0)
|
||||
clr r1 /self-defense
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ jsr pc,collect
|
||||
/
|
||||
/ coalesce free storage by rejoining paired blocks
|
||||
/ on the free list.
|
||||
/ zero is returned in r0 if no paired blocks were found.
|
||||
/
|
||||
collect:
|
||||
mov r1,-(sp)
|
||||
mov r2,-(sp)
|
||||
mov r3,-(sp)
|
||||
mov r4,-(sp)
|
||||
clr useful
|
||||
inc stats+4.
|
||||
clr r0 /start with smallest blocks
|
||||
/r0 contains frlist index
|
||||
loop1: mov $frlist,r1
|
||||
add r0,r1
|
||||
/
|
||||
/ try next list member at this level
|
||||
/
|
||||
loop2: mov (r1),r3
|
||||
beq advance /list is empty
|
||||
tst *(r1) /W
|
||||
beq advance /only one list element
|
||||
/
|
||||
/ calculate address of buddy
|
||||
/
|
||||
mov a(r3),r4
|
||||
mov $block,r2
|
||||
1:
|
||||
cmp r4,(r2)
|
||||
blo 1f
|
||||
cmp r2,lblock
|
||||
beq 2f
|
||||
add $2,r2
|
||||
br 1b
|
||||
1:
|
||||
sub $2,r2
|
||||
2:
|
||||
mov (r2),beg
|
||||
sub beg,r4
|
||||
bit exp2(r0),r4
|
||||
beq 2f
|
||||
bic exp2(r0),r4
|
||||
br 1f
|
||||
2: bis exp2(r0),r4
|
||||
1: add beg,r4
|
||||
/
|
||||
/ and search for him
|
||||
/
|
||||
loop3: tst 0(r3)
|
||||
beq nocoal
|
||||
mov (r3),r2
|
||||
cmp a(r2),r4
|
||||
beq coal
|
||||
mov (r3),r3
|
||||
br loop3
|
||||
/
|
||||
/ have found a pair; remove both blocks from list,
|
||||
/ coalesce them, and put them on next higher list
|
||||
/
|
||||
coal: inc useful
|
||||
mov (r3),r4
|
||||
mov (r4),(r3) /remove him from list
|
||||
mov (r1),r2
|
||||
mov (r2),(r1) /remove the other one
|
||||
cmp a(r2),a(r4)
|
||||
bgt 1f
|
||||
mov r2,-(sp)
|
||||
mov r4,r2
|
||||
mov (sp)+,r4
|
||||
1: add exp2(r0),l(r4)
|
||||
clr r(r4)
|
||||
mov frlist+2(r0),(r4)
|
||||
mov r4,frlist+2(r0)
|
||||
mov hdrptr,(r2)
|
||||
mov r2,hdrptr
|
||||
clr r(r2)
|
||||
mov beg,a(r2)
|
||||
mov beg,l(r2)
|
||||
br loop2
|
||||
/
|
||||
/ no buddy found, try next block on this list
|
||||
/
|
||||
nocoal:
|
||||
mov (r1),r1
|
||||
br loop2
|
||||
/
|
||||
/ advance to next free list
|
||||
/
|
||||
advance:
|
||||
tst (r0)+
|
||||
cmp r0,$frend-frlist
|
||||
blo loop1
|
||||
mov useful,r0
|
||||
/
|
||||
/ do we have enough headers to continue?
|
||||
/
|
||||
cmp garbage,$2
|
||||
blo 1f
|
||||
mov $1,r0
|
||||
sys write; 4f; 5f-4f
|
||||
jmp reset
|
||||
/
|
||||
4: <Out of space - too big a block.\n>
|
||||
5: .even
|
||||
/
|
||||
/
|
||||
/ restore registers and return
|
||||
/
|
||||
1:
|
||||
inc garbage
|
||||
mov (sp)+,r4
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r1
|
||||
rts pc
|
||||
/
|
||||
.bss
|
||||
garbage: .=.+2
|
||||
.text
|
||||
/
|
||||
/ routine to get more space for strings
|
||||
/
|
||||
moresp:
|
||||
mov r2,-(sp)
|
||||
mov r1,-(sp)
|
||||
mov brk,r1
|
||||
mov $block,r2
|
||||
add nblock,r2
|
||||
cmp r2,$blkend
|
||||
bhis rout
|
||||
mov r1,(r2)
|
||||
mov r1,lblock
|
||||
add $2,nblock
|
||||
add $10000,r1
|
||||
mov r1,9f
|
||||
sys break;9:..
|
||||
bes 2f
|
||||
mov hdrptr,r2
|
||||
bne 1f
|
||||
jsr pc,morehd
|
||||
tst r0
|
||||
beq 2f
|
||||
mov hdrptr,r2
|
||||
1:
|
||||
mov (r2),hdrptr
|
||||
mov brk,a(r2)
|
||||
mov r1,brk
|
||||
mov r1,l(r2)
|
||||
clr r(r2)
|
||||
mov $10000,r0
|
||||
jsr pc,log2
|
||||
asl r0
|
||||
mov frlist(r0),w(r2)
|
||||
mov r2,frlist(r0)
|
||||
clr r0
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r2
|
||||
rts pc
|
||||
2:
|
||||
mov $1,r0
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r2
|
||||
rts pc
|
||||
/
|
||||
/ routine to get move space for headers
|
||||
/
|
||||
morehd:
|
||||
mov r2,-(sp)
|
||||
mov brk,r0
|
||||
mov $hblock,r2
|
||||
add nhdr,r2
|
||||
cmp r2,$hblkend
|
||||
bhis rout
|
||||
mov r0,(r2)
|
||||
mov r0,lhblock
|
||||
add $2,nhdr
|
||||
add $1024.,r0
|
||||
mov r0,9f
|
||||
sys break;9:..
|
||||
bes 2f
|
||||
mov brk,r2
|
||||
mov r2,hdrptr
|
||||
mov r0,brk
|
||||
sub $8,r0
|
||||
1:
|
||||
add $8,r2
|
||||
mov r2,-8(r2)
|
||||
cmp r2,r0
|
||||
blos 1b
|
||||
clr -8(r2)
|
||||
clr r0
|
||||
mov (sp)+,r2
|
||||
rts pc
|
||||
2:
|
||||
mov $1,r0
|
||||
mov (sp)+,r2
|
||||
rts pc
|
||||
rout:
|
||||
mov $1,r0
|
||||
sys write; 4f; 5f-4f
|
||||
jmp reset
|
||||
/
|
||||
4: <out of space - no more block storage\n>
|
||||
5: .even
|
||||
/
|
||||
/ routine to find integer part of log2(x)
|
||||
/
|
||||
/ jsr pc,log2
|
||||
/
|
||||
/ r0 = log2(r0)
|
||||
/
|
||||
log2:
|
||||
mov r0,-(sp)
|
||||
bge 9f; 4; 9:
|
||||
mov $15.,r0
|
||||
1:
|
||||
rol (sp)
|
||||
bmi 1f
|
||||
sob r0,1b
|
||||
1:
|
||||
dec r0
|
||||
tst (sp)+
|
||||
rts pc
|
||||
/
|
||||
0 /Don't move me, I'm exp(-1)
|
||||
exp2:
|
||||
1;2;4;10;20;40;100;200;400;1000;2000;4000;
|
||||
10000;20000;40000;100000
|
||||
/
|
||||
/ routine to discover whether r1 points to
|
||||
/ a plausible header - to avoid ruination.
|
||||
/
|
||||
/ r1 is preserved and r0 gets a suitable index for frlist
|
||||
/
|
||||
/ jsr pc,preposterous
|
||||
/
|
||||
preposterous:
|
||||
mov r2,-(sp)
|
||||
mov $hblock,r2
|
||||
1:
|
||||
cmp r1,(r2)
|
||||
blo 1f
|
||||
cmp (r2),lhblock
|
||||
beq 2f
|
||||
add $2,r2
|
||||
br 1b
|
||||
1:
|
||||
sub $2,r2
|
||||
2:
|
||||
mov (r2),r2
|
||||
add $1024.,r2
|
||||
cmp r1,r2
|
||||
blo 9f;4;9:
|
||||
mov $block,r2
|
||||
1:
|
||||
cmp a(r1),(r2)
|
||||
blo 1f
|
||||
cmp (r2),lblock
|
||||
beq 2f
|
||||
add $2,r2
|
||||
br 1b
|
||||
1:
|
||||
sub $2,r2
|
||||
2:
|
||||
cmp l(r1),(r2)
|
||||
bhis 9f;4;9:
|
||||
mov (r2),r2
|
||||
add $10000,r2
|
||||
cmp a(r1),r2
|
||||
blo 9f;4;9:
|
||||
cmp l(r1),r2
|
||||
blos 9f;4;9:
|
||||
mov (sp)+,r2
|
||||
mov l(r1),r0 /L
|
||||
sub a(r1),r0 /A
|
||||
mov r0,-(sp)
|
||||
jsr pc,log2
|
||||
asl r0
|
||||
cmp exp2(r0),(sp)
|
||||
beq 9f; 4; 9:
|
||||
add $2,r0
|
||||
cmp r0,$frend-frlist+2
|
||||
blo 9f; 4; 9:
|
||||
sub $2,r0
|
||||
mov r0,(sp)
|
||||
mov frlist(r0),r0
|
||||
1: beq 1f
|
||||
cmp r0,r1
|
||||
bne 9f; 4; 9:
|
||||
mov (r0),r0
|
||||
br 1b
|
||||
1: mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to initialize storage area, headers and
|
||||
/ free list upon first call to allocate a block.
|
||||
/ The entire storage area is formed into a single block.
|
||||
/
|
||||
init:
|
||||
mov r0,-(sp)
|
||||
mov r1,-(sp)
|
||||
/
|
||||
/ form all the headers into a single list.
|
||||
/
|
||||
mov $headers,r0
|
||||
mov r0,hdrptr
|
||||
1: add $8,r0
|
||||
mov r0,-8(r0)
|
||||
cmp r0,$headend-8
|
||||
blos 1b
|
||||
clr -8(r0)
|
||||
mov $frlist,r0
|
||||
1: clr (r0)+
|
||||
cmp r0,$frend
|
||||
blo 1b
|
||||
/
|
||||
mov hdrptr,r1
|
||||
mov (r1),hdrptr
|
||||
clr w(r1)
|
||||
mov $strbuf,r0
|
||||
mov r0,a(r1)
|
||||
mov $strend-strbuf,r0
|
||||
jsr pc,log2
|
||||
asl r0
|
||||
cmp r0,$frend-frlist
|
||||
blo 9f; 4; 9:
|
||||
mov r1,frlist(r0)
|
||||
mov exp2(r0),r0
|
||||
add $strbuf,r0
|
||||
mov r0,l(r1)
|
||||
mov $hdrptr,r1
|
||||
1: mov (r1),r1
|
||||
tst r1
|
||||
beq 1f
|
||||
mov $strbuf,a(r1)
|
||||
mov $strbuf,l(r1)
|
||||
br 1b
|
||||
1:
|
||||
mov $end,brk
|
||||
add $2,nblock
|
||||
mov $strbuf,block
|
||||
mov $strbuf,lblock
|
||||
mov $headers,hblock
|
||||
add $2,nhdr
|
||||
mov $headers,lhblock
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
.bss
|
||||
nhdr: .=.+2
|
||||
lhblock: .=.+2
|
||||
hblock: .=.+20.
|
||||
hblkend:
|
||||
stats: .=.+16.
|
||||
useful: .=.+2
|
||||
beg: .=.+2
|
||||
lblock: .=.+2
|
||||
nblock: .=.+2
|
||||
block: .=.+40.
|
||||
blkend:
|
||||
brk: .=.+2
|
||||
hdrptr: .=.+2 /do not move me
|
||||
frlist: .=hdrptr+32.
|
||||
frend:
|
||||
headers:.=hdrptr+1024.
|
||||
headend:
|
||||
strbuf: .=.+10000
|
||||
strend:
|
||||
end:
|
||||
signal = 48.
|
||||
@@ -0,0 +1,219 @@
|
||||
#
|
||||
|
||||
char *dargv[]
|
||||
{
|
||||
"/dev/rrk2",
|
||||
"/dev/rrp0",
|
||||
0
|
||||
};
|
||||
|
||||
#define NINODE 16*16
|
||||
#define NI 20
|
||||
|
||||
#include "/usr/sys/ino.h"
|
||||
#include "/usr/sys/filsys.h"
|
||||
|
||||
struct inode inode[NINODE];
|
||||
struct filsys sblock;
|
||||
|
||||
int sflg;
|
||||
int headpr;
|
||||
|
||||
int ilist[NI] { -1};
|
||||
int fi;
|
||||
char *ecount;
|
||||
char *lasts;
|
||||
int ino;
|
||||
int nerror;
|
||||
int nfiles;
|
||||
struct dir {
|
||||
int ino;
|
||||
char name[14];
|
||||
};
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
register char **p;
|
||||
register int n, *lp;
|
||||
|
||||
ecount = sbrk(0);
|
||||
if (argc == 1) {
|
||||
for (p = dargv; *p;)
|
||||
check(*p++);
|
||||
return(nerror);
|
||||
}
|
||||
while (--argc) {
|
||||
argv++;
|
||||
if (**argv=='-') switch ((*argv)[1]) {
|
||||
case 's':
|
||||
sflg++;
|
||||
continue;
|
||||
|
||||
case 'i':
|
||||
lp = ilist;
|
||||
while (lp < &ilist[NI-1] && (n = number(argv[1]))) {
|
||||
*lp++ = n;
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
*lp++ = -1;
|
||||
continue;
|
||||
|
||||
default:
|
||||
printf("Bad flag\n");
|
||||
}
|
||||
check(*argv);
|
||||
}
|
||||
return(nerror);
|
||||
}
|
||||
|
||||
check(file)
|
||||
char *file;
|
||||
{
|
||||
register i, j;
|
||||
fi = open(file, 0);
|
||||
if(fi < 0) {
|
||||
printf("cannot open %s\n", file);
|
||||
return;
|
||||
}
|
||||
headpr = 0;
|
||||
printf("%s:\n", file);
|
||||
sync();
|
||||
bread(1, &sblock, 512);
|
||||
nfiles = sblock.s_isize*16;
|
||||
if (lasts < nfiles) {
|
||||
if ((sbrk(nfiles - lasts)) == -1) {
|
||||
printf("Not enough core\n");
|
||||
exit(04);
|
||||
}
|
||||
lasts = nfiles;
|
||||
}
|
||||
for (i=0; i<nfiles; i++)
|
||||
ecount[i] = 0;
|
||||
for(i=0; ino<nfiles; i =+ NINODE/16) {
|
||||
bread(i+2, inode, sizeof inode);
|
||||
for(j=0; j<NINODE && ino<nfiles; j++) {
|
||||
ino++;
|
||||
pass1(&inode[j]);
|
||||
}
|
||||
}
|
||||
ino = 0;
|
||||
for (i=0; ino<nfiles; i =+ NINODE/16) {
|
||||
bread(i+2, inode, sizeof inode);
|
||||
for (j=0; j<NINODE && ino<nfiles; j++) {
|
||||
ino++;
|
||||
pass2(&inode[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pass1(aip)
|
||||
struct inode *aip;
|
||||
{
|
||||
register doff;
|
||||
register struct inode *ip;
|
||||
register struct dir *dp;
|
||||
int i;
|
||||
|
||||
ip = aip;
|
||||
if((ip->i_mode&IALLOC) == 0)
|
||||
return;
|
||||
if((ip->i_mode&IFMT) != IFDIR)
|
||||
return;
|
||||
doff = 0;
|
||||
while (dp = dread(ip, doff)) {
|
||||
doff =+ 16;
|
||||
if (dp->ino==0)
|
||||
continue;
|
||||
for (i=0; ilist[i] != -1; i++)
|
||||
if (ilist[i]==dp->ino)
|
||||
printf("%5l arg; %l/%.14s\n", dp->ino, ino, dp->name);
|
||||
ecount[dp->ino]++;
|
||||
}
|
||||
}
|
||||
|
||||
pass2(aip)
|
||||
{
|
||||
register struct inode *ip;
|
||||
register i;
|
||||
|
||||
ip = aip;
|
||||
i = ino;
|
||||
if ((ip->i_mode&IALLOC)==0 && ecount[i]==0)
|
||||
return;
|
||||
if (ip->i_nlink==ecount[i] && ip->i_nlink!=0)
|
||||
return;
|
||||
if (headpr==0) {
|
||||
printf("entries link cnt\n");
|
||||
headpr++;
|
||||
}
|
||||
printf("%l %d %d\n", ino,
|
||||
ecount[i]&0377, ip->i_nlink&0377);
|
||||
}
|
||||
|
||||
dread(aip, aoff)
|
||||
{
|
||||
register b, off;
|
||||
register struct inode *ip;
|
||||
static ibuf[256];
|
||||
static char buf[512];
|
||||
|
||||
off = aoff;
|
||||
ip = aip;
|
||||
if ((off&0777)==0) {
|
||||
if (off==0177000) {
|
||||
printf("Monstrous directory %l\n", ino);
|
||||
return(0);
|
||||
}
|
||||
if ((ip->i_mode&ILARG)==0) {
|
||||
if (off>=010000 || (b = ip->i_addr[off>>9])==0)
|
||||
return(0);
|
||||
bread(b, buf, 512);
|
||||
} else {
|
||||
if (off==0) {
|
||||
if (ip->i_addr[0]==0)
|
||||
return(0);
|
||||
bread(ip->i_addr[0], ibuf, 512);
|
||||
}
|
||||
if ((b = ibuf[(off>>9)&0177])==0)
|
||||
return(0);
|
||||
bread(b, buf, 512);
|
||||
}
|
||||
}
|
||||
return(&buf[off&0777]);
|
||||
}
|
||||
|
||||
bread(bno, buf, cnt)
|
||||
{
|
||||
|
||||
seek(fi, bno, 3);
|
||||
if(read(fi, buf, cnt) != cnt) {
|
||||
printf("read error %d\n", bno);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
bwrite(bno, buf)
|
||||
{
|
||||
|
||||
seek(fi, bno, 3);
|
||||
if(write(fi, buf, 512) != 512) {
|
||||
printf("write error %d\n", bno);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
number(as)
|
||||
char *as;
|
||||
{
|
||||
register n, c;
|
||||
register char *s;
|
||||
|
||||
s = as;
|
||||
n = 0;
|
||||
while ((c = *s++) >= '0' && c <= '9') {
|
||||
n = n*10+c-'0';
|
||||
}
|
||||
return(n);
|
||||
}
|
||||
+458
@@ -0,0 +1,458 @@
|
||||
#define LCASE 01
|
||||
#define UCASE 02
|
||||
#define SWAB 04
|
||||
#define NERR 010
|
||||
#define SYNC 020
|
||||
int cflag;
|
||||
int fflag;
|
||||
int skip;
|
||||
int count;
|
||||
char *string;
|
||||
char *ifile;
|
||||
char *ofile;
|
||||
char *ibuf;
|
||||
char *obuf;
|
||||
char *ibs 512;
|
||||
char *obs 512;
|
||||
char *bs;
|
||||
char *cbs;
|
||||
char *ibc;
|
||||
char *obc;
|
||||
char *cbc;
|
||||
int nifr;
|
||||
int nipr;
|
||||
int nofr;
|
||||
int nopr;
|
||||
int ntrunc;
|
||||
int ibf;
|
||||
int obf;
|
||||
char *op;
|
||||
int nspace;
|
||||
char etoa[]
|
||||
{
|
||||
0000,0001,0002,0003,0234,0011,0206,0177,
|
||||
0227,0215,0216,0013,0014,0015,0016,0017,
|
||||
0020,0021,0022,0023,0235,0205,0010,0207,
|
||||
0030,0031,0222,0217,0034,0035,0036,0037,
|
||||
0200,0201,0202,0203,0204,0012,0027,0033,
|
||||
0210,0211,0212,0213,0214,0005,0006,0007,
|
||||
0220,0221,0026,0223,0224,0225,0226,0004,
|
||||
0230,0231,0232,0233,0024,0025,0236,0032,
|
||||
0040,0240,0241,0242,0243,0244,0245,0246,
|
||||
0247,0250,0133,0056,0074,0050,0053,0041,
|
||||
0046,0251,0252,0253,0254,0255,0256,0257,
|
||||
0260,0261,0135,0044,0052,0051,0073,0136,
|
||||
0055,0057,0262,0263,0264,0265,0266,0267,
|
||||
0270,0271,0174,0054,0045,0137,0076,0077,
|
||||
0272,0273,0274,0275,0276,0277,0300,0301,
|
||||
0302,0140,0072,0043,0100,0047,0075,0042,
|
||||
0303,0141,0142,0143,0144,0145,0146,0147,
|
||||
0150,0151,0304,0305,0306,0307,0310,0311,
|
||||
0312,0152,0153,0154,0155,0156,0157,0160,
|
||||
0161,0162,0313,0314,0315,0316,0317,0320,
|
||||
0321,0176,0163,0164,0165,0166,0167,0170,
|
||||
0171,0172,0322,0323,0324,0325,0326,0327,
|
||||
0330,0331,0332,0333,0334,0335,0336,0337,
|
||||
0340,0341,0342,0343,0344,0345,0346,0347,
|
||||
0173,0101,0102,0103,0104,0105,0106,0107,
|
||||
0110,0111,0350,0351,0352,0353,0354,0355,
|
||||
0175,0112,0113,0114,0115,0116,0117,0120,
|
||||
0121,0122,0356,0357,0360,0361,0362,0363,
|
||||
0134,0237,0123,0124,0125,0126,0127,0130,
|
||||
0131,0132,0364,0365,0366,0367,0370,0371,
|
||||
0060,0061,0062,0063,0064,0065,0066,0067,
|
||||
0070,0071,0372,0373,0374,0375,0376,0377,
|
||||
};
|
||||
char atoe[]
|
||||
{
|
||||
0000,0001,0002,0003,0067,0055,0056,0057,
|
||||
0026,0005,0045,0013,0014,0015,0016,0017,
|
||||
0020,0021,0022,0023,0074,0075,0062,0046,
|
||||
0030,0031,0077,0047,0034,0035,0036,0037,
|
||||
0100,0117,0177,0173,0133,0154,0120,0175,
|
||||
0115,0135,0134,0116,0153,0140,0113,0141,
|
||||
0360,0361,0362,0363,0364,0365,0366,0367,
|
||||
0370,0371,0172,0136,0114,0176,0156,0157,
|
||||
0174,0301,0302,0303,0304,0305,0306,0307,
|
||||
0310,0311,0321,0322,0323,0324,0325,0326,
|
||||
0327,0330,0331,0342,0343,0344,0345,0346,
|
||||
0347,0350,0351,0112,0340,0132,0137,0155,
|
||||
0171,0201,0202,0203,0204,0205,0206,0207,
|
||||
0210,0211,0221,0222,0223,0224,0225,0226,
|
||||
0227,0230,0231,0242,0243,0244,0245,0246,
|
||||
0247,0250,0251,0300,0152,0320,0241,0007,
|
||||
0040,0041,0042,0043,0044,0025,0006,0027,
|
||||
0050,0051,0052,0053,0054,0011,0012,0033,
|
||||
0060,0061,0032,0063,0064,0065,0066,0010,
|
||||
0070,0071,0072,0073,0004,0024,0076,0341,
|
||||
0101,0102,0103,0104,0105,0106,0107,0110,
|
||||
0111,0121,0122,0123,0124,0125,0126,0127,
|
||||
0130,0131,0142,0143,0144,0145,0146,0147,
|
||||
0150,0151,0160,0161,0162,0163,0164,0165,
|
||||
0166,0167,0170,0200,0212,0213,0214,0215,
|
||||
0216,0217,0220,0232,0233,0234,0235,0236,
|
||||
0237,0240,0252,0253,0254,0255,0256,0257,
|
||||
0260,0261,0262,0263,0264,0265,0266,0267,
|
||||
0270,0271,0272,0273,0274,0275,0276,0277,
|
||||
0312,0313,0314,0315,0316,0317,0332,0333,
|
||||
0334,0335,0336,0337,0352,0353,0354,0355,
|
||||
0356,0357,0372,0373,0374,0375,0376,0377,
|
||||
};
|
||||
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
register (*conv)();
|
||||
register char *ip;
|
||||
register c;
|
||||
int ebcdic(), ascii(), null(), cnull(), term();
|
||||
int a;
|
||||
|
||||
conv = null;
|
||||
for(c=1; c<argc; c++) {
|
||||
string = argv[c];
|
||||
if(match("ibs=")) {
|
||||
ibs = number();
|
||||
continue;
|
||||
}
|
||||
if(match("obs=")) {
|
||||
obs = number();
|
||||
continue;
|
||||
}
|
||||
if(match("cbs=")) {
|
||||
cbs = number();
|
||||
continue;
|
||||
}
|
||||
if (match("bs=")) {
|
||||
bs = number();
|
||||
continue;
|
||||
}
|
||||
if(match("if=")) {
|
||||
ifile = string;
|
||||
continue;
|
||||
}
|
||||
if(match("of=")) {
|
||||
ofile = string;
|
||||
continue;
|
||||
}
|
||||
if(match("skip=")) {
|
||||
skip = number();
|
||||
continue;
|
||||
}
|
||||
if(match("count=")) {
|
||||
count = number();
|
||||
continue;
|
||||
}
|
||||
if(match("conv=")) {
|
||||
cloop:
|
||||
if(match(","))
|
||||
goto cloop;
|
||||
if(*string == '\0')
|
||||
continue;
|
||||
if(match("ebcdic")) {
|
||||
conv = ebcdic;
|
||||
goto cloop;
|
||||
}
|
||||
if(match("ascii")) {
|
||||
conv = ascii;
|
||||
goto cloop;
|
||||
}
|
||||
if(match("lcase")) {
|
||||
cflag =| LCASE;
|
||||
goto cloop;
|
||||
}
|
||||
if(match("ucase")) {
|
||||
cflag =| UCASE;
|
||||
goto cloop;
|
||||
}
|
||||
if(match("swab")) {
|
||||
cflag =| SWAB;
|
||||
goto cloop;
|
||||
}
|
||||
if(match("noerror")) {
|
||||
cflag =| NERR;
|
||||
goto cloop;
|
||||
}
|
||||
if(match("sync")) {
|
||||
cflag =| SYNC;
|
||||
goto cloop;
|
||||
}
|
||||
}
|
||||
printf("bad arg: %s\n", string);
|
||||
exit();
|
||||
}
|
||||
if(conv == null && cflag&(LCASE|UCASE))
|
||||
conv = cnull;
|
||||
if (ifile)
|
||||
ibf = open(ifile, 0);
|
||||
else
|
||||
ibf = dup(0);
|
||||
if(ibf < 0) {
|
||||
printf("cannot open: %s\n", ifile);
|
||||
exit();
|
||||
}
|
||||
if (ofile)
|
||||
obf = creat(ofile, 0666);
|
||||
else
|
||||
obf = dup(1);
|
||||
if(obf < 0) {
|
||||
printf("cannot create: %s\n", ofile);
|
||||
exit();
|
||||
}
|
||||
if (bs) {
|
||||
ibs = obs = bs;
|
||||
if (conv == null)
|
||||
fflag++;
|
||||
}
|
||||
if(ibs == 0 || obs == 0) {
|
||||
printf("counts: cannot be zero\n");
|
||||
exit();
|
||||
}
|
||||
ibuf = sbrk(ibs);
|
||||
if (fflag)
|
||||
obuf = ibuf;
|
||||
else
|
||||
obuf = sbrk(obs);
|
||||
if(ibuf == -1 || obuf == -1) {
|
||||
printf("not enough memory\n");
|
||||
exit();
|
||||
}
|
||||
ibc = 0;
|
||||
obc = 0;
|
||||
cbc = 0;
|
||||
op = obuf;
|
||||
|
||||
if ((signal(2, 1) & 01) == 0)
|
||||
signal(2, term);
|
||||
while(skip) {
|
||||
read(ibf, ibuf, ibs);
|
||||
skip--;
|
||||
}
|
||||
|
||||
loop:
|
||||
if(ibc-- == 0) {
|
||||
ibc = 0;
|
||||
if(count==0 || nifr+nipr!=count) {
|
||||
if(cflag&(NERR|SYNC))
|
||||
for(ip=ibuf+ibs; ip>ibuf;)
|
||||
*--ip = 0;
|
||||
ibc = read(ibf, ibuf, ibs);
|
||||
}
|
||||
if(ibc == -1) {
|
||||
perror("read");
|
||||
if((cflag&NERR) == 0) {
|
||||
flsh();
|
||||
term();
|
||||
}
|
||||
ibc = 0;
|
||||
for(c=0; c<ibs; c++)
|
||||
if(ibuf[c] != 0)
|
||||
ibc = c;
|
||||
stats();
|
||||
}
|
||||
if(ibc == 0) {
|
||||
flsh();
|
||||
term();
|
||||
}
|
||||
if(ibc != ibs) {
|
||||
nipr++;
|
||||
if(cflag&SYNC)
|
||||
ibc = ibs;
|
||||
} else
|
||||
nifr++;
|
||||
ip = ibuf;
|
||||
c = (ibc>>1) & ~1;
|
||||
if(cflag&SWAB && c)
|
||||
do {
|
||||
a = *ip++;
|
||||
ip[-1] = *ip;
|
||||
*ip++ = a;
|
||||
} while(--c);
|
||||
ip = ibuf;
|
||||
if (fflag) {
|
||||
obc = ibc;
|
||||
flsh();
|
||||
ibc = 0;
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
c = 0;
|
||||
c =| *ip++;
|
||||
(*conv)(c);
|
||||
goto loop;
|
||||
}
|
||||
|
||||
flsh()
|
||||
{
|
||||
register c;
|
||||
|
||||
if(obc) {
|
||||
if(obc == obs)
|
||||
nofr++; else
|
||||
nopr++;
|
||||
c = write(obf, obuf, obc);
|
||||
if(c != obc) {
|
||||
perror("write");
|
||||
term();
|
||||
}
|
||||
obc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
match(s)
|
||||
char *s;
|
||||
{
|
||||
register char *cs;
|
||||
|
||||
cs = string;
|
||||
while(*cs++ == *s)
|
||||
if(*s++ == '\0')
|
||||
goto true;
|
||||
if(*s != '\0')
|
||||
return(0);
|
||||
|
||||
true:
|
||||
cs--;
|
||||
string = cs;
|
||||
return(1);
|
||||
}
|
||||
|
||||
number()
|
||||
{
|
||||
register char *cs;
|
||||
register n;
|
||||
|
||||
cs = string;
|
||||
n = 0;
|
||||
while(*cs >= '0' && *cs <= '9')
|
||||
n = n*10 + *cs++ - '0';
|
||||
for(;;)
|
||||
switch(*cs++) {
|
||||
|
||||
case 'k':
|
||||
n =* 1024;
|
||||
continue;
|
||||
|
||||
case 'w':
|
||||
n =* 2;
|
||||
continue;
|
||||
|
||||
case 'b':
|
||||
n =* 512;
|
||||
continue;
|
||||
|
||||
case '*':
|
||||
case 'x':
|
||||
string = cs;
|
||||
n =* number();
|
||||
|
||||
case '\0':
|
||||
return(n);
|
||||
}
|
||||
printf("not a number: %s\n", string);
|
||||
exit();
|
||||
}
|
||||
|
||||
cnull(cc)
|
||||
{
|
||||
register c;
|
||||
|
||||
c = cc;
|
||||
if(cflag&UCASE && c>='a' && c<='z')
|
||||
c =+ 'A'-'a';
|
||||
if(cflag&LCASE && c>='A' && c<='Z')
|
||||
c =+ 'a'-'A';
|
||||
null(c);
|
||||
}
|
||||
|
||||
null(c)
|
||||
{
|
||||
|
||||
*op = c;
|
||||
op++;
|
||||
if(++obc >= obs) {
|
||||
flsh();
|
||||
op = obuf;
|
||||
}
|
||||
}
|
||||
|
||||
ascii(cc)
|
||||
{
|
||||
register c;
|
||||
|
||||
c = 0;
|
||||
c =| etoa[cc];
|
||||
if(cbs == 0) {
|
||||
cnull(c);
|
||||
return;
|
||||
}
|
||||
if(c == ' ') {
|
||||
nspace++;
|
||||
goto out;
|
||||
}
|
||||
while(nspace > 0) {
|
||||
null(' ');
|
||||
nspace--;
|
||||
}
|
||||
cnull(c);
|
||||
|
||||
out:
|
||||
if(++cbc >= cbs) {
|
||||
null('\n');
|
||||
cbc = 0;
|
||||
nspace = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ebcdic(cc)
|
||||
{
|
||||
register c;
|
||||
|
||||
c = cc;
|
||||
if(cflag&UCASE && c>='a' && c<='z')
|
||||
c =+ 'A'-'a';
|
||||
if(cflag&LCASE && c>='A' && c<='Z')
|
||||
c =+ 'a'-'A';
|
||||
c = atoe[c] & 0377;
|
||||
if(cbs == 0) {
|
||||
null(c);
|
||||
return;
|
||||
}
|
||||
if(cc == '\n') {
|
||||
while(cbc < cbs) {
|
||||
null(atoe[' ']);
|
||||
cbc++;
|
||||
}
|
||||
cbc = 0;
|
||||
return;
|
||||
}
|
||||
if(cbc == cbs)
|
||||
ntrunc++;
|
||||
cbc++;
|
||||
if(cbc <= cbs)
|
||||
null(c);
|
||||
}
|
||||
|
||||
term()
|
||||
{
|
||||
|
||||
stats();
|
||||
exit();
|
||||
}
|
||||
|
||||
stats()
|
||||
{
|
||||
|
||||
printf("%l+%l records in\n", nifr, nipr);
|
||||
printf("%l+%l records out\n", nofr, nopr);
|
||||
if(ntrunc)
|
||||
printf("%l truncated records\n", ntrunc);
|
||||
}
|
||||
|
||||
putchar(c)
|
||||
{
|
||||
|
||||
write(2, &c, 1);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
char *dargv[]
|
||||
{
|
||||
0,
|
||||
"/dev/rk2",
|
||||
"/dev/rp0",
|
||||
0
|
||||
};
|
||||
struct
|
||||
{
|
||||
char *s_isize;
|
||||
char *s_fsize;
|
||||
int s_nfree;
|
||||
int s_free[100];
|
||||
int s_ninode;
|
||||
int s_inode[100];
|
||||
char s_flock;
|
||||
char s_ilock;
|
||||
char s_fmod;
|
||||
int time[2];
|
||||
int pad[50];
|
||||
} sblock;
|
||||
|
||||
int fi;
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
int i;
|
||||
|
||||
if(argc <= 1) {
|
||||
for(argc = 1; dargv[argc]; argc++);
|
||||
argv = dargv;
|
||||
}
|
||||
|
||||
for(i=1; i<argc; i++) {
|
||||
if(argc > 1)
|
||||
printf("%s ", argv[i]);
|
||||
dfree(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
dfree(file)
|
||||
char *file;
|
||||
{
|
||||
int i;
|
||||
|
||||
fi = open(file, 0);
|
||||
if(fi < 0) {
|
||||
printf("cannot open %s\n", file);
|
||||
return;
|
||||
}
|
||||
sync();
|
||||
bread(1, &sblock);
|
||||
i = 0;
|
||||
while(alloc())
|
||||
i++;
|
||||
printf("%l\n", i);
|
||||
close(fi);
|
||||
}
|
||||
|
||||
alloc()
|
||||
{
|
||||
int b, i, buf[256];
|
||||
|
||||
i = --sblock.s_nfree;
|
||||
if(i<0 || i>=100) {
|
||||
printf("bad free count\n");
|
||||
return(0);
|
||||
}
|
||||
b = sblock.s_free[i];
|
||||
if(b == 0)
|
||||
return(0);
|
||||
if(b<sblock.s_isize+2 || b>=sblock.s_fsize) {
|
||||
printf("bad free block (%l)\n", b);
|
||||
return(0);
|
||||
}
|
||||
if(sblock.s_nfree <= 0) {
|
||||
bread(b, buf);
|
||||
sblock.s_nfree = buf[0];
|
||||
for(i=0; i<100; i++)
|
||||
sblock.s_free[i] = buf[i+1];
|
||||
}
|
||||
return(b);
|
||||
}
|
||||
|
||||
bread(bno, buf)
|
||||
{
|
||||
int n;
|
||||
extern errno;
|
||||
|
||||
seek(fi, bno, 3);
|
||||
if((n=read(fi, buf, 512)) != 512) {
|
||||
printf("read error %d\n", bno);
|
||||
printf("count = %d; errno = %d\n", n, errno);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
/* diff - differential file comparison
|
||||
*
|
||||
* Uses an algorithm due to Harold Stone, which finds
|
||||
* a pair of longest identical subsequences in the two
|
||||
* files.
|
||||
*
|
||||
* The major goal is to generate the match vector J.
|
||||
* J[i] is the index of the line in file1 corresponding
|
||||
* to line i file0. J[i] = 0 if there is no
|
||||
* such line in file1.
|
||||
*
|
||||
* Lines are hashed so as to work in core. All potential
|
||||
* matches are located by sorting the lines of each file
|
||||
* on the hash (called value_____). In particular, this
|
||||
* collects the equivalence classes in file1 together.
|
||||
* Subroutine equiv____ replaces the value of each line in
|
||||
* file0 by the index of the first element of its
|
||||
* matching equivalence in (the reordered) file1.
|
||||
* To save space equiv_____ squeezes file1 into a single
|
||||
* array member______ in which the equivalence classes
|
||||
* are simply concatenated, except that their first
|
||||
* members are flagged by changing sign.
|
||||
*
|
||||
* Next the indices that point into member______ are unsorted_______ into
|
||||
* array class_____ according to the original order of file0.
|
||||
*
|
||||
* The cleverness lies in routine stone______. This marches
|
||||
* through the lines of file0, developing a vector klist_____
|
||||
* of "k-candidates". At step i a k-candidate is a matched
|
||||
* pair of lines x,y (x in file0 y in file1) such that
|
||||
* there is a common subsequence of lenght k
|
||||
* between the first i lines of file0 and the first y
|
||||
* lines of file1, but there is no such subsequence for
|
||||
* any smaller y. x is the earliest possible mate to y
|
||||
* that occurs in such a subsequence.
|
||||
*
|
||||
* Whenever any of the members of the equivalence class of
|
||||
* lines in file1 matable to a line in file0 has serial number
|
||||
* less than the y of some k-candidate, that k-candidate
|
||||
* with the smallest such y is replaced. The new
|
||||
* k-candidate is chained (via pred____) to the current
|
||||
* k-1 candidate so that the actual subsequence can
|
||||
* be recovered. When a member has serial number greater
|
||||
* that the y of all k-candidates, the klist is extended.
|
||||
* At the end, the longest subsequence is pulled out
|
||||
* and placed in the array J by unravel_______.
|
||||
*
|
||||
* With J in hand, the matches there recorded are
|
||||
* check_____ed against reality to assure that no spurious
|
||||
* matches have crept in due to hashing. If they have,
|
||||
* they are broken, and "jackpot " is recorded--a harmless
|
||||
* matter except that a true match for a spuriously
|
||||
* mated line may now be unnecessarily reported as a change.
|
||||
*
|
||||
* Much of the complexity of the program comes simply
|
||||
* from trying to minimize core utilization and
|
||||
* maximize the range of doable problems by dynamically
|
||||
* allocating what is needed and reusing what is not.
|
||||
* The core requirements for problems larger than somewhat
|
||||
* are (in words) 2*length(file0) + length(file1) +
|
||||
* 3*(number of k-candidates installed), typically about
|
||||
* 6n words for files of length n. There is also space for buf1
|
||||
* used which could, by moving data underfoot and reallocating
|
||||
* buf1 together with buf2, be completely overlaid.
|
||||
*/
|
||||
struct buf {
|
||||
int fdes;
|
||||
char data[516];
|
||||
} *buf1, *buf2;
|
||||
|
||||
struct cand {
|
||||
int x;
|
||||
int y;
|
||||
struct cand *pred;
|
||||
} cand;
|
||||
struct line {
|
||||
int serial;
|
||||
int value;
|
||||
} *file[2], line;
|
||||
int len[2];
|
||||
int *class; /*will be overlaid on file[0]*/
|
||||
int *member; /*will be overlaid on file[1]*/
|
||||
struct cand **klist; /*will be overlaid on file[0] after class*/
|
||||
int *J; /*will be overlaid on class*/
|
||||
int *ixold; /*will be overlaid on klist*/
|
||||
int *ixnew; /*will be overlaid on file[1]*/
|
||||
|
||||
char *area;
|
||||
char *top;
|
||||
alloc(n)
|
||||
{
|
||||
register char *p;
|
||||
p = area;
|
||||
n = (n+1) & ~1;
|
||||
area =+ n;
|
||||
while(area > top) {
|
||||
if(sbrk(1024) == -1) {
|
||||
mesg("Out of space\n");
|
||||
exit(1);
|
||||
}
|
||||
top =+ 1024;
|
||||
}
|
||||
return(p);
|
||||
}
|
||||
|
||||
mesg(s)
|
||||
char *s;
|
||||
{
|
||||
while(*s)
|
||||
write(2,s++,1);
|
||||
}
|
||||
|
||||
sort(a,n) /*shellsort CACM #201*/
|
||||
struct line *a;
|
||||
{
|
||||
struct line w;
|
||||
register int j,m;
|
||||
struct line *ai;
|
||||
register struct line *aim;
|
||||
int k;
|
||||
for(j=1;j<=n;j=* 2)
|
||||
m = 2*j - 1;
|
||||
for(m=/2;m!=0;m=/2) {
|
||||
k = n-m;
|
||||
for(j=1;j<=k;j++) {
|
||||
for(ai = &a[j]; ai > a; ai =- m) {
|
||||
aim = &ai[m];
|
||||
if(aim->value > ai[0].value ||
|
||||
aim->value == ai[0].value &&
|
||||
aim->serial > ai[0].serial)
|
||||
break;
|
||||
w.value = ai[0].value;
|
||||
ai[0].value = aim->value;
|
||||
aim->value = w.value;
|
||||
w.serial = ai[0].serial;
|
||||
ai[0].serial = aim->serial;
|
||||
aim->serial = w.serial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsort(f, l, b)
|
||||
struct line *f;
|
||||
int *b;
|
||||
{
|
||||
int *a;
|
||||
int i;
|
||||
a = alloc((l+1)*sizeof(a[0]));
|
||||
for(i=1;i<=l;i++)
|
||||
a[f[i].serial] = f[i].value;
|
||||
for(i=1;i<=l;i++)
|
||||
b[i] = a[i];
|
||||
area = a;
|
||||
}
|
||||
|
||||
prepare(i, arg)
|
||||
char *arg;
|
||||
{
|
||||
register char *temp;
|
||||
temp = file[i] = area;
|
||||
alloc(sizeof(line));
|
||||
input(arg);
|
||||
len[i] = (area - temp)/sizeof(line) - 1;
|
||||
alloc(sizeof(line));
|
||||
sort(file[i], len[i]);
|
||||
}
|
||||
|
||||
input(arg)
|
||||
{
|
||||
register int h, i;
|
||||
register struct line *p;
|
||||
if(fopen(arg,buf1) == -1) {
|
||||
mesg("Cannot open ");
|
||||
mesg(arg);
|
||||
mesg("\n");
|
||||
exit(1);
|
||||
}
|
||||
for(i=0; h=readhash(buf1);) {
|
||||
p = alloc(sizeof(line));
|
||||
p->serial = ++i;
|
||||
p->value = h;
|
||||
}
|
||||
close(buf1->fdes);
|
||||
}
|
||||
|
||||
equiv(a,n,b,m,c)
|
||||
struct line *a, *b;
|
||||
int *c;
|
||||
{
|
||||
register int i, j;
|
||||
i = j = 1;
|
||||
while(i<=n && j<=m) {
|
||||
if(a[i].value <b[j].value)
|
||||
a[i++].value = 0;
|
||||
else if(a[i].value == b[j].value)
|
||||
a[i++].value = j;
|
||||
else
|
||||
j++;
|
||||
}
|
||||
while(i <= n)
|
||||
a[i++].value = 0;
|
||||
b[m+1].value = 0;
|
||||
j = 0;
|
||||
while(++j <= m) {
|
||||
c[j] = -b[j].serial;
|
||||
while(b[j+1].value == b[j].value) {
|
||||
j++;
|
||||
c[j] = b[j].serial;
|
||||
}
|
||||
}
|
||||
c[j] = -1;
|
||||
}
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
int k;
|
||||
|
||||
if(argc>1 && *argv[1]=='-') {
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
if(argc!=3) {
|
||||
mesg("Arg count\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
area = top = sbrk(0);
|
||||
buf1 = alloc(sizeof(*buf1));
|
||||
prepare(0, argv[1]);
|
||||
prepare(1, argv[2]);
|
||||
|
||||
member = file[1];
|
||||
equiv(file[0], len[0], file[1], len[1], member);
|
||||
|
||||
class = file[0];
|
||||
unsort(file[0], len[0], class);
|
||||
|
||||
klist = &class[len[0]+2];
|
||||
area = &member[len[1]+2];
|
||||
k = stone(class, len[0], member, klist);
|
||||
J = class;
|
||||
unravel(klist[k]);
|
||||
|
||||
ixold = klist;
|
||||
ixnew = file[1];
|
||||
area = &ixnew[len[1]+2];
|
||||
buf2 = alloc(sizeof(*buf2));
|
||||
if(check(argv))
|
||||
mesg("Jackpot\n");
|
||||
output(argv);
|
||||
}
|
||||
|
||||
stone(a,n,b,c)
|
||||
int *a;
|
||||
int *b;
|
||||
struct cand **c;
|
||||
{
|
||||
register int i, k,y;
|
||||
int j, l;
|
||||
int skip;
|
||||
k = 0;
|
||||
c[0] = 0;
|
||||
for(i=1; i<=n; i++) {
|
||||
j = a[i];
|
||||
if(j==0)
|
||||
continue;
|
||||
skip = 0;
|
||||
do {
|
||||
y = b[j];
|
||||
if(y<0) y = -y;
|
||||
if(skip)
|
||||
continue;
|
||||
l = search(c, k, y);
|
||||
if(l > k) {
|
||||
c[k+1] = newcand(i,y,c[k]);
|
||||
skip = 1;
|
||||
k++;
|
||||
}
|
||||
else if(c[l]->y > y && c[l]->x < i)
|
||||
c[l] = newcand(i,y,c[l-1]);
|
||||
} while(b[++j] > 0);
|
||||
}
|
||||
return(k);
|
||||
}
|
||||
|
||||
struct cand *
|
||||
newcand(x,y,pred)
|
||||
struct cand *pred;
|
||||
{
|
||||
struct cand *p;
|
||||
p = alloc(sizeof(cand));
|
||||
p->x = x;
|
||||
p->y = y;
|
||||
p->pred = pred;
|
||||
return(p);
|
||||
}
|
||||
|
||||
search(c, k, y)
|
||||
struct cand **c;
|
||||
{
|
||||
register int i, j, l;
|
||||
int t;
|
||||
i = 0;
|
||||
j = k+1;
|
||||
while((l=(i+j)/2) > i) {
|
||||
t = c[l]->y;
|
||||
if(t > y)
|
||||
j = l;
|
||||
else if(t < y)
|
||||
i = l;
|
||||
else
|
||||
return(l);
|
||||
}
|
||||
return(l+1);
|
||||
}
|
||||
|
||||
unravel(p)
|
||||
struct cand *p;
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<=len[0]; i++)
|
||||
J[i] = 0;
|
||||
while(p) {
|
||||
J[p->x] = p->y;
|
||||
p = p->pred;
|
||||
}
|
||||
}
|
||||
|
||||
/* check does double duty:
|
||||
1. ferret out any fortuitous correspondences due
|
||||
to counfounding by hashing (which result in "jackpot")
|
||||
2. collect random access indexes to the two files */
|
||||
|
||||
check(argv)
|
||||
char **argv;
|
||||
{
|
||||
register int i, j;
|
||||
int ctold, ctnew;
|
||||
int jackpot;
|
||||
char c,d;
|
||||
fopen(argv[1],buf1);
|
||||
fopen(argv[2],buf2);
|
||||
j = 1;
|
||||
ctold = ctnew = 0;
|
||||
ixold[0] = ixnew[0] = 0;
|
||||
jackpot = 0;
|
||||
for(i=1;i<=len[0];i++) {
|
||||
if(J[i]==0) {
|
||||
while(getc(buf1)!='\n') ctold++;
|
||||
ixold[i] = ++ctold;
|
||||
continue;
|
||||
}
|
||||
while(j<J[i]) {
|
||||
while(getc(buf2)!='\n') ctnew++;
|
||||
ixnew[j] = ++ctnew;
|
||||
j++;
|
||||
}
|
||||
while((c=getc(buf1))==(d=getc(buf2))) {
|
||||
if(c=='\n') break;
|
||||
ctold++;
|
||||
ctnew++;
|
||||
}
|
||||
while(c!='\n') {
|
||||
jackpot++;
|
||||
J[i] = 0;
|
||||
c = getc(buf1);
|
||||
ctold++;
|
||||
}
|
||||
ixold[i] = ++ctold;
|
||||
while(d!='\n') {
|
||||
jackpot++;
|
||||
J[i] = 0;
|
||||
d = getc(buf2);
|
||||
ctnew++;
|
||||
}
|
||||
ixnew[j] = ++ctnew;
|
||||
j++;
|
||||
}
|
||||
for(;j<=len[1];j++) {
|
||||
while(getc(buf2)!='\n') ctnew++;
|
||||
ixnew[j] = ++ctnew;
|
||||
}
|
||||
close(buf1->fdes);
|
||||
close(buf2->fdes);
|
||||
return(jackpot);
|
||||
}
|
||||
|
||||
output(argv)
|
||||
char **argv;
|
||||
{
|
||||
int dir;
|
||||
int m;
|
||||
int i0,i1,j0,j1;
|
||||
extern fout;
|
||||
dir = **argv=='-';
|
||||
fout = dup(1);
|
||||
buf1->fdes = open(argv[1],0);
|
||||
buf2->fdes = open(argv[2],0);
|
||||
m = len[0];
|
||||
J[0] = 0;
|
||||
J[m+1] = len[1]+1;
|
||||
if(dir==0) for(i0=1;i0<=m;i0=i1+1) {
|
||||
while(i0<=m&&J[i0]==J[i0-1]+1) i0++;
|
||||
j0 = J[i0-1]+1;
|
||||
i1 = i0-1;
|
||||
while(i1<m&&J[i1+1]==0) i1++;
|
||||
j1 = J[i1+1]-1;
|
||||
J[i1] = j1;
|
||||
change(i0,i1,j0,j1,dir);
|
||||
} else for(i0=m;i0>=1;i0=i1-1) {
|
||||
while(i0>=1&&J[i0]==J[i0+1]-1&&J[i0]!=0) i0--;
|
||||
j0 = J[i0+1]-1;
|
||||
i1 = i0+1;
|
||||
while(i1>1&&J[i1-1]==0) i1--;
|
||||
j1 = J[i1-1]+1;
|
||||
J[i1] = j1;
|
||||
change(i1,i0,j1,j0,dir);
|
||||
}
|
||||
if(m==0)
|
||||
change(1,0,1,len[1],dir);
|
||||
flush();
|
||||
}
|
||||
|
||||
change(a,b,c,d,dir)
|
||||
{
|
||||
if(a>b&&c>d) return;
|
||||
range(a,b);
|
||||
putchar(a>b?'a':c>d?'d':'c');
|
||||
if(dir==0) range(c,d);
|
||||
putchar('\n');
|
||||
if(dir==0) {
|
||||
fetch(ixold,a,b,buf1,"* ");
|
||||
if(a<=b&&c<=d) printf("---\n");
|
||||
}
|
||||
fetch(ixnew,c,d,buf2,dir==0?". ":"");
|
||||
if(dir!=0&&c<=d) printf(".\n");
|
||||
}
|
||||
|
||||
range(a,b)
|
||||
{
|
||||
if(a>b) printf("%d",b);
|
||||
if(a<=b) printf("%d",a);
|
||||
if(a<b) printf(",%d",b);
|
||||
}
|
||||
|
||||
fetch(f,a,b,lb,pref)
|
||||
int *f;
|
||||
struct buf *lb;
|
||||
char *pref;
|
||||
{
|
||||
int i, j;
|
||||
int nc;
|
||||
for(i=a;i<=b;i++) {
|
||||
seek(lb->fdes,f[i-1],0);
|
||||
nc = read(lb->fdes,lb->data,f[i]-f[i-1]);
|
||||
printf(pref);
|
||||
for(j=0;j<nc;j++)
|
||||
putchar(lb->data[j]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/ hash routine for diff
|
||||
/ effectively spreads the string out into 7-bit
|
||||
/ bytes, then sums the result 1's-complement
|
||||
/ by 16-bit bytes and adds 1 to avoid zero answer
|
||||
|
||||
/ r4 hash accumulator
|
||||
/ r3 current offset
|
||||
/ r2 first time flag
|
||||
.globl _readhash
|
||||
.globl getc
|
||||
|
||||
.data
|
||||
_readhash:
|
||||
mov 2(sp),0f
|
||||
mov r5,-(sp)
|
||||
mov r4,-(sp)
|
||||
mov r3,-(sp)
|
||||
mov r2,-(sp)
|
||||
mov $1,r4
|
||||
mov r4,r2
|
||||
clr r3
|
||||
1:
|
||||
jsr r5,getc; 0: 0
|
||||
bes 2f
|
||||
clr r2
|
||||
cmp r0,$'\n
|
||||
beq 1f
|
||||
ashc $-16.,r0
|
||||
ashc r3,r0
|
||||
add r0,r4
|
||||
adc r4
|
||||
add r1,r4
|
||||
adc r4
|
||||
add $7,r3
|
||||
cmp r3,$16.
|
||||
blt 1b
|
||||
sub $16.,r3
|
||||
br 1b
|
||||
2:
|
||||
tst r2
|
||||
bne 2f
|
||||
mov $2,r0
|
||||
sys write; 3f; 4f-3f
|
||||
2:
|
||||
clr r4
|
||||
1:
|
||||
mov r4,r0
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r4
|
||||
mov (sp)+,r5
|
||||
rts pc
|
||||
3:
|
||||
<incomplete line omitted\n>
|
||||
4:
|
||||
.even
|
||||
@@ -0,0 +1,95 @@
|
||||
/ dsw - delete from tty
|
||||
|
||||
cmp (sp)+,$2
|
||||
blt 1f
|
||||
tst (sp)+
|
||||
mov (sp)+,0f
|
||||
1:
|
||||
sys stat; 0:dot; stbuf
|
||||
bes error
|
||||
mov stbuf+4,r0
|
||||
bic $!60000,r0
|
||||
cmp r0,$40000
|
||||
bne error
|
||||
mov 0b,0f
|
||||
sys open; 0:..; 0
|
||||
bes error
|
||||
mov r0,r1
|
||||
1:
|
||||
clrb buf+17.
|
||||
mov r1,r0
|
||||
sys read; buf; 16.
|
||||
bes done
|
||||
tst r0
|
||||
beq done
|
||||
tst buf
|
||||
beq 1b
|
||||
mov 0b,r2
|
||||
mov $obuf,r3
|
||||
2:
|
||||
movb (r2)+,(r3)+
|
||||
bne 2b
|
||||
mov $buf+2,r2
|
||||
dec r3
|
||||
cmpb -1(r3),$'/
|
||||
beq 2f
|
||||
movb $'/,(r3)+
|
||||
2:
|
||||
movb (r2)+,(r3)+
|
||||
bne 2b
|
||||
sys stat; obuf; stbuf
|
||||
bes error
|
||||
bit $60000,stbuf+4
|
||||
bne 1b
|
||||
mov $buf+2,r2
|
||||
2:
|
||||
tstb (r2)+
|
||||
bne 2b
|
||||
movb $' ,-(r2)
|
||||
sub $buf+1,r2
|
||||
mov r2,0f
|
||||
|
||||
2:
|
||||
mov $1,r0
|
||||
sys write; buf+2; 0:..
|
||||
clr r0
|
||||
sys read; ch; 1
|
||||
cmpb ch,$'\n
|
||||
beq 1b
|
||||
clr r0
|
||||
sys read; ch1; 1
|
||||
cmpb ch1,$'\n
|
||||
beq 3f
|
||||
4:
|
||||
clr r0
|
||||
sys read; ch; 1
|
||||
cmpb ch,$'\n
|
||||
beq 2b
|
||||
br 4b
|
||||
3:
|
||||
cmpb ch,$'x
|
||||
beq done
|
||||
cmpb ch,$'y
|
||||
bne 2b
|
||||
sys unlink; obuf
|
||||
bes error
|
||||
br 1b
|
||||
|
||||
done:
|
||||
sys exit
|
||||
|
||||
error:
|
||||
mov $1,r0
|
||||
sys write; mes; 2
|
||||
sys exit
|
||||
|
||||
dot: <.\0>
|
||||
mes: <?\n>
|
||||
|
||||
.bss
|
||||
obuf: .=.+100.
|
||||
stbuf: .=.+40.
|
||||
buf: .=.+18.
|
||||
ch: .=.+1
|
||||
ch1: .=.+1
|
||||
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/ dusg -- summarize disk usage
|
||||
|
||||
.globl putc, flush, _end
|
||||
mov $1,obuf
|
||||
mov (sp)+,r5
|
||||
tst (sp)+
|
||||
1:
|
||||
dec r5
|
||||
bgt 2f
|
||||
tstb buf1
|
||||
beq 3f
|
||||
jsr r5,flush; obuf
|
||||
sys exit
|
||||
3:
|
||||
mov $dot,r0
|
||||
br 3f
|
||||
2:
|
||||
mov (sp)+,r0
|
||||
3:
|
||||
cmpb (r0),$'-
|
||||
bne 2f
|
||||
cmpb 1(r0),$'a
|
||||
bne 3f
|
||||
inc aflg
|
||||
br 1b
|
||||
3:
|
||||
cmpb 1(r0),$'s
|
||||
bne 1b
|
||||
dec aflg
|
||||
br 1b
|
||||
2:
|
||||
mov $buf1,r1
|
||||
2:
|
||||
movb (r0)+,(r1)+
|
||||
bne 2b
|
||||
dec r1
|
||||
clr buf3+10.
|
||||
mov $_end,iptr
|
||||
mov $_end,brk
|
||||
sys break; _end
|
||||
jsr pc,tree
|
||||
tst aflg
|
||||
bpl 1b
|
||||
jsr r5,name
|
||||
br 1b
|
||||
|
||||
tree:
|
||||
sys stat; buf1; buf2
|
||||
bes 1f
|
||||
bic $!60000,buf2+4
|
||||
bit $20000,buf2+4
|
||||
beq 2f
|
||||
1:
|
||||
clr r4
|
||||
rts pc
|
||||
2:
|
||||
mov $_end,r2
|
||||
mov buf2+2,r3
|
||||
1:
|
||||
cmp r2,iptr
|
||||
bhis 1f
|
||||
cmp r3,(r2)+
|
||||
bne 1b
|
||||
clr r4
|
||||
jsr r5,cname
|
||||
rts pc
|
||||
1:
|
||||
cmp r2,brk
|
||||
blo 1f
|
||||
add $512.,brk
|
||||
sys break; brk: ..
|
||||
1:
|
||||
mov r3,(r2)+
|
||||
mov r2,iptr
|
||||
cmp $40000,buf2+4
|
||||
beq 1f
|
||||
jsr pc,gsize
|
||||
jsr r5,cname
|
||||
rts pc
|
||||
1:
|
||||
jsr pc,gsize
|
||||
mov r4,r3
|
||||
sys open; buf1; 0
|
||||
bec 1f
|
||||
rts pc
|
||||
1:
|
||||
mov r0,-(sp)
|
||||
mov r1,-(sp)
|
||||
1:
|
||||
mov 2(sp),r0
|
||||
sys read; buf3; 16.
|
||||
bes 1f
|
||||
tst r0
|
||||
beq 1f
|
||||
tst buf3
|
||||
beq 1b
|
||||
cmp buf3+2,$".\0
|
||||
beq 1b
|
||||
cmp buf3+2,$"..
|
||||
bne 2f
|
||||
tst buf3+4
|
||||
beq 1b
|
||||
2:
|
||||
mov $buf3+2,r2
|
||||
mov (sp),r1
|
||||
movb $'/,(r1)+
|
||||
cmpb -2(r1),$'/
|
||||
bne 2f
|
||||
dec r1
|
||||
2:
|
||||
movb (r2)+,(r1)+
|
||||
bne 2b
|
||||
dec r1
|
||||
mov r3,-(sp)
|
||||
jsr pc,tree
|
||||
mov r4,r3
|
||||
add (sp)+,r3
|
||||
br 1b
|
||||
1:
|
||||
mov (sp)+,r1
|
||||
clrb (r1)
|
||||
mov (sp)+,r0
|
||||
sys close
|
||||
mov r3,r4
|
||||
tst aflg
|
||||
bmi 1f
|
||||
jsr r5,name
|
||||
1:
|
||||
rts pc
|
||||
|
||||
cname:
|
||||
tst aflg
|
||||
bgt name
|
||||
rts r5
|
||||
|
||||
name:
|
||||
jsr pc,pnum
|
||||
mov $011,r0
|
||||
jsr pc,pchar
|
||||
mov $buf1,r2
|
||||
1:
|
||||
movb (r2)+,r0
|
||||
beq 1f
|
||||
jsr pc,pchar
|
||||
br 1b
|
||||
1:
|
||||
mov $'\n,r0
|
||||
jsr pc,pchar
|
||||
rts r5
|
||||
|
||||
gsize:
|
||||
mov r5,-(sp)
|
||||
mov buf2+10.,r5 / size
|
||||
movb buf2+9.,r4
|
||||
add $511.,r5
|
||||
adc r4
|
||||
alsc $-9,r4
|
||||
cmp r5,$8.
|
||||
blo 1f
|
||||
mov r5,-(sp)
|
||||
add $255.,r5
|
||||
alsc $-8,r4
|
||||
add (sp)+,r5
|
||||
1:
|
||||
mov r5,r4
|
||||
mov (sp)+,r5
|
||||
rts pc
|
||||
|
||||
pnum:
|
||||
mov r4,-(sp)
|
||||
mov r5,-(sp)
|
||||
mov r4,r5
|
||||
jsr pc,1f
|
||||
mov (sp)+,r5
|
||||
mov (sp)+,r4
|
||||
rts pc
|
||||
1:
|
||||
clr r4
|
||||
dvd $10.,r4
|
||||
mov r5,-(sp)
|
||||
mov r4,r5
|
||||
beq 1f
|
||||
jsr pc,1b
|
||||
1:
|
||||
mov (sp)+,r0
|
||||
add $'0,r0
|
||||
jsr pc,pchar
|
||||
rts pc
|
||||
|
||||
pchar:
|
||||
jsr r5,putc; obuf
|
||||
rts pc
|
||||
|
||||
dot: <.\0>
|
||||
|
||||
.bss
|
||||
|
||||
iptr: .=.+2
|
||||
buf1: .=.+100.
|
||||
buf2: .=.+40.
|
||||
buf3: .=.+18.
|
||||
aflg: .=.+2
|
||||
obuf: .=.+520.
|
||||
@@ -0,0 +1,451 @@
|
||||
#
|
||||
|
||||
/*
|
||||
* incremental dump
|
||||
* dump fisbuodh filesystem
|
||||
* f take output tape from arglist
|
||||
* i from date in /etc/dtab
|
||||
* s specify tape size in feet (feet = blocks/9)
|
||||
* b specify tape size in blocks
|
||||
* u update /etc/dtab to current date
|
||||
* 0 dump from the epoch
|
||||
* d dump specified number of days
|
||||
* h dump specified number of hours
|
||||
* a on incremental dump, dump files even >= MAXSIZE
|
||||
*/
|
||||
|
||||
char *dargv[]
|
||||
{
|
||||
0,
|
||||
"i",
|
||||
"/dev/rp0",
|
||||
0
|
||||
};
|
||||
|
||||
#include "/usr/sys/ino.h"
|
||||
#include "/usr/sys/filsys.h"
|
||||
#define MAXSIZE 1000
|
||||
struct filsys sblock;
|
||||
struct
|
||||
{
|
||||
char name[16];
|
||||
int date[2];
|
||||
} dtab[10];
|
||||
char *dfile "/etc/dtab";
|
||||
char *ofile;
|
||||
int *talist;
|
||||
int fi;
|
||||
int buf[256];
|
||||
int dbuf[256];
|
||||
int ibuf[256];
|
||||
int vbuf[256];
|
||||
char *date[2];
|
||||
char *ddate[2];
|
||||
int fo -1;
|
||||
int pher;
|
||||
int dflg;
|
||||
int iflg;
|
||||
int cflg;
|
||||
int aflg;
|
||||
char *tsize 19000;
|
||||
char *taddr;
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
char *key;
|
||||
int s, i, nfil, nblk, f;
|
||||
register *tap;
|
||||
register struct inode *ip;
|
||||
int ino;
|
||||
|
||||
ofile = "/dev/mt0";
|
||||
time(date);
|
||||
if(argc == 1) {
|
||||
argv = dargv;
|
||||
for(argc = 1; dargv[argc]; argc++);
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
key = *argv;
|
||||
while(*key)
|
||||
switch(*key++) {
|
||||
|
||||
default:
|
||||
printf("bad character in key\n");
|
||||
exit();
|
||||
|
||||
case 'a': /* dump all (even large) */
|
||||
aflg++;
|
||||
continue;
|
||||
|
||||
case '-':
|
||||
continue;
|
||||
|
||||
case 'c': /* increment file name */
|
||||
cflg++;
|
||||
continue;
|
||||
|
||||
case 'f': /* file name from arg list */
|
||||
argc--;
|
||||
argv++;
|
||||
ofile = *argv;
|
||||
continue;
|
||||
|
||||
case 'i': /* date from date file */
|
||||
iflg++;
|
||||
continue;
|
||||
|
||||
case 's': /* tape size */
|
||||
tsize = number(argv[1]) * 9;
|
||||
argv++;
|
||||
argc--;
|
||||
continue;
|
||||
|
||||
case 'b': /* tape size */
|
||||
tsize = number(argv[1]);
|
||||
argv++;
|
||||
argc--;
|
||||
continue;
|
||||
|
||||
case 'u': /* rewrite date */
|
||||
dflg++;
|
||||
continue;
|
||||
|
||||
case '0': /* dump all */
|
||||
ddate[0] = ddate[1] = 0;
|
||||
continue;
|
||||
|
||||
case 'd': /* dump some number of days */
|
||||
i = 21600;
|
||||
goto sd;
|
||||
|
||||
case 'h': /* dump some number of hours */
|
||||
i = 900;
|
||||
goto sd;
|
||||
|
||||
sd:
|
||||
ddate[0] = date[0];
|
||||
ddate[1] = date[1];
|
||||
s = number(argv[1])*4;
|
||||
argv++;
|
||||
argc--;
|
||||
while(s) {
|
||||
if(i > ddate[1])
|
||||
ddate[0]--;
|
||||
ddate[1] =- i;
|
||||
s--;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(argc <= 1) {
|
||||
printf("no file system specified\n");
|
||||
exit();
|
||||
}
|
||||
if(iflg) {
|
||||
f = open(dfile, 0);
|
||||
if(f >= 0) {
|
||||
read(f, dtab, sizeof dtab);
|
||||
close(f);
|
||||
for(i=0; i<10; i++)
|
||||
if(equal(dtab[i].name, argv[1])) {
|
||||
ddate[0] = dtab[i].date[0];
|
||||
ddate[1] = dtab[i].date[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%s:\n", argv[1]);
|
||||
fi = open(argv[1], 0);
|
||||
if(fi < 0) {
|
||||
printf("cannot open %s\n", argv[1]);
|
||||
exit();
|
||||
}
|
||||
printf("incremental dump from\n");
|
||||
pdate(ddate);
|
||||
sync();
|
||||
bread(1, &sblock);
|
||||
talist = sbrk(size(0, sblock.s_isize*32)*512);
|
||||
tap = talist;
|
||||
if(tap == -1) {
|
||||
printf("No memory\n");
|
||||
exit();
|
||||
}
|
||||
nfil = 0;
|
||||
nblk = size(0, sblock.s_isize*32);
|
||||
ino = 0;
|
||||
for(i=0; i<sblock.s_isize; i++) {
|
||||
bread(i+2, buf);
|
||||
for(ip = &buf[0]; ip < &buf[256]; ip++) {
|
||||
ino++;
|
||||
if(ip->i_mode == 0 || ip->i_nlink == 0) {
|
||||
*tap++ = -1;
|
||||
continue;
|
||||
}
|
||||
if(ip->i_mtime[0] < ddate[0])
|
||||
goto no;
|
||||
if(ip->i_mtime[0] == ddate[0] &&
|
||||
ip->i_mtime[1] < ddate[1])
|
||||
goto no;
|
||||
s = size(ip->i_size0&0377, ip->i_size1) + 1;
|
||||
if (s>MAXSIZE && aflg==0 && iflg!=0) {
|
||||
printf("%l big; not dumped.\n", ino);
|
||||
goto no;
|
||||
}
|
||||
nfil++;
|
||||
nblk =+ s;
|
||||
*tap++ = s;
|
||||
continue;
|
||||
no:
|
||||
*tap++ = 0;
|
||||
}
|
||||
}
|
||||
printf("%l files\n%l blocks\n", nfil, nblk);
|
||||
i = ldiv(0, nblk, ldiv(0, tsize, 10));
|
||||
printf("%l.%l tapes\n", i/10, i%10);
|
||||
tap = buf;
|
||||
clrbuf(tap);
|
||||
*tap++ = sblock.s_isize;
|
||||
*tap++ = sblock.s_fsize;
|
||||
*tap++ = date[0];
|
||||
*tap++ = date[1];
|
||||
*tap++ = ddate[0];
|
||||
*tap++ = ddate[1];
|
||||
*tap++ = tsize;
|
||||
swrite(buf);
|
||||
i = size(0, sblock.s_isize*32);
|
||||
tap = talist;
|
||||
while(i--) {
|
||||
bwrite(tap);
|
||||
tap =+ 256;
|
||||
}
|
||||
tap = talist;
|
||||
for(i=0; i<sblock.s_isize; i++) {
|
||||
bread(i+2, buf);
|
||||
for(ip = &buf[0]; ip < &buf[256]; ip++) {
|
||||
if(*tap && *tap != -1)
|
||||
dump(ip, *tap-1);
|
||||
tap++;
|
||||
}
|
||||
}
|
||||
printf("%l phase errors\n", pher);
|
||||
if(!dflg)
|
||||
exit();
|
||||
for(i=0; i<10; i++)
|
||||
dtab[i].name[0] = 0;
|
||||
f = open(dfile, 2);
|
||||
if(f < 0) {
|
||||
f = creat(dfile, 0666);
|
||||
if(f < 0) {
|
||||
printf("cannot create %s\n", dfile);
|
||||
exit();
|
||||
}
|
||||
} else
|
||||
read(f, dtab, sizeof dtab);
|
||||
for(i=0; i<10; i++)
|
||||
if(dtab[i].name[0] == 0 || equal(dtab[i].name, argv[1]))
|
||||
goto found;
|
||||
printf("%s full\n", dfile);
|
||||
exit();
|
||||
|
||||
found:
|
||||
for(s=0; s<15; s++) {
|
||||
dtab[i].name[s] = argv[1][s];
|
||||
if(argv[1][s] == 0)
|
||||
break;
|
||||
}
|
||||
dtab[i].date[0] = date[0];
|
||||
dtab[i].date[1] = date[1];
|
||||
seek(f, 0, 0);
|
||||
write(f, dtab, sizeof dtab);
|
||||
printf("date updated\n");
|
||||
pdate(date);
|
||||
}
|
||||
|
||||
pdate(d)
|
||||
int *d;
|
||||
{
|
||||
|
||||
if(d[0] == 0 && d[1] == 0)
|
||||
printf("the epoch\n"); else
|
||||
printf(ctime(d));
|
||||
}
|
||||
|
||||
dump(ip, sz)
|
||||
struct inode *ip;
|
||||
{
|
||||
register *p, *q, *r;
|
||||
|
||||
p = dbuf;
|
||||
q = ip;
|
||||
clrbuf(p);
|
||||
while(q < &ip->i_mtime[2])
|
||||
*p++ = *q++;
|
||||
swrite(dbuf);
|
||||
if(ip->i_mode & (IFBLK&IFCHR)) {
|
||||
if(sz != 0)
|
||||
printf("special\n");
|
||||
return;
|
||||
}
|
||||
for(p = &ip->i_addr[0]; p < &ip->i_addr[8]; p++)
|
||||
if(*p) {
|
||||
if(ip->i_mode&ILARG) {
|
||||
bread(*p, ibuf);
|
||||
for(q = &ibuf[0]; q < &ibuf[256]; q++)
|
||||
if(*q) {
|
||||
if(p == &ip->i_addr[7]) {
|
||||
bread(*q, vbuf);
|
||||
for(r = &vbuf[0]; r < &vbuf[256]; r++)
|
||||
if(*r) {
|
||||
if(--sz < 0)
|
||||
goto pe;
|
||||
bread(*r, dbuf);
|
||||
bwrite(dbuf);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(--sz < 0)
|
||||
goto pe;
|
||||
bread(*q, dbuf);
|
||||
bwrite(dbuf);
|
||||
}
|
||||
} else {
|
||||
if(--sz < 0)
|
||||
goto pe;
|
||||
bread(*p, dbuf);
|
||||
bwrite(dbuf);
|
||||
}
|
||||
}
|
||||
if(sz)
|
||||
goto pe;
|
||||
return;
|
||||
|
||||
pe:
|
||||
clrbuf(dbuf);
|
||||
while(--sz >= 0)
|
||||
bwrite(dbuf);
|
||||
pher++;
|
||||
}
|
||||
|
||||
bread(bno, b)
|
||||
{
|
||||
|
||||
seek(fi, bno, 3);
|
||||
if(read(fi, b, 512) != 512) {
|
||||
printf("read error %l\n", bno);
|
||||
}
|
||||
}
|
||||
|
||||
clrbuf(b)
|
||||
int *b;
|
||||
{
|
||||
register i, *p;
|
||||
|
||||
p = b;
|
||||
i = 256;
|
||||
while(i--)
|
||||
*p++ = 0;
|
||||
}
|
||||
|
||||
swrite(b)
|
||||
int *b;
|
||||
{
|
||||
register i, s, *p;
|
||||
|
||||
i = 254;
|
||||
s = taddr;
|
||||
p = b;
|
||||
while(i--)
|
||||
s =+ *p++;
|
||||
*p++ = taddr;
|
||||
*p = 031415 - s;
|
||||
bwrite(b);
|
||||
}
|
||||
|
||||
bwrite(b)
|
||||
{
|
||||
|
||||
if(taddr == 0) {
|
||||
if(fo != -1) {
|
||||
printf("change tapes\n");
|
||||
close(fo);
|
||||
rdline();
|
||||
}
|
||||
otape();
|
||||
}
|
||||
wloop:
|
||||
if(write(fo, b, 512) != 512) {
|
||||
printf("write error\n");
|
||||
rdline();
|
||||
seek(fo, taddr, 3);
|
||||
goto wloop;
|
||||
}
|
||||
taddr++;
|
||||
if(taddr >= tsize)
|
||||
taddr = 0;
|
||||
}
|
||||
|
||||
rdline()
|
||||
{
|
||||
int c;
|
||||
|
||||
loop:
|
||||
c = 0;
|
||||
read(0, &c, 1);
|
||||
if(c == 0)
|
||||
exit();
|
||||
if(c != '\n')
|
||||
goto loop;
|
||||
}
|
||||
|
||||
number(s)
|
||||
char *s;
|
||||
{
|
||||
register n, c;
|
||||
|
||||
n = 0;
|
||||
while(c = *s++) {
|
||||
if(c<'0' || c>'9')
|
||||
continue;
|
||||
n = n*10+c-'0';
|
||||
}
|
||||
return(n);
|
||||
}
|
||||
|
||||
size(s0, s1)
|
||||
{
|
||||
register s;
|
||||
extern ldivr;
|
||||
|
||||
s = ldiv(s0&0377, s1, 512);
|
||||
if(ldivr)
|
||||
s++;
|
||||
return(s);
|
||||
}
|
||||
|
||||
otape()
|
||||
{
|
||||
register char *p;
|
||||
|
||||
fo = creat(ofile, 0666);
|
||||
if(fo < 0) {
|
||||
printf("can not open %s\n", ofile);
|
||||
exit();
|
||||
}
|
||||
if(!cflg)
|
||||
return;
|
||||
p = ofile;
|
||||
while(*p++)
|
||||
;
|
||||
p[-2]++;
|
||||
}
|
||||
|
||||
equal(a, b)
|
||||
char *a, *b;
|
||||
{
|
||||
|
||||
while(*a++ == *b)
|
||||
if(*b++ == 0)
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i;
|
||||
|
||||
argc--;
|
||||
for(i=1; i<=argc; i++)
|
||||
printf("%s%c", argv[i], i==argc? '\n': ' ');
|
||||
}
|
||||
+1333
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
/* exit -- end runcom */
|
||||
|
||||
main() {
|
||||
seek(0, 0, 2);
|
||||
}
|
||||
+468
@@ -0,0 +1,468 @@
|
||||
/* Fortran command */
|
||||
|
||||
char *tmp;
|
||||
char ts[1000];
|
||||
char *tsp ts;
|
||||
char *av[50];
|
||||
char *clist[50];
|
||||
char *llist[50];
|
||||
int instring;
|
||||
int pflag;
|
||||
int cflag;
|
||||
char *complr;
|
||||
int *ibuf;
|
||||
int *ibuf1;
|
||||
int *ibuf2;
|
||||
int *obuf;
|
||||
char *lp;
|
||||
char *line;
|
||||
int lineno;
|
||||
int exfail;
|
||||
struct symtab {
|
||||
char name[8];
|
||||
char *value;
|
||||
} *symtab;
|
||||
int symsiz 200;
|
||||
struct symtab *defloc;
|
||||
struct symtab *incloc;
|
||||
char *stringbuf;
|
||||
|
||||
main(argc, argv)
|
||||
char *argv[]; {
|
||||
char *t;
|
||||
int nc, nl, i, j, c, nxo;
|
||||
int dexit();
|
||||
|
||||
complr = "/usr/fort/fc1";
|
||||
i = nc = nl = nxo = 0;
|
||||
while(++i < argc) {
|
||||
if(*argv[i] == '-')
|
||||
switch (argv[i][1]) {
|
||||
default:
|
||||
goto passa;
|
||||
case 'p':
|
||||
pflag++;
|
||||
case 'c':
|
||||
cflag++;
|
||||
break;
|
||||
case '2':
|
||||
complr = "/usr/fort/fc2";
|
||||
break;
|
||||
}
|
||||
else {
|
||||
passa:
|
||||
t = argv[i];
|
||||
if(getsuf(t)=='f') {
|
||||
clist[nc++] = t;
|
||||
t = setsuf(copy(t), 'o');
|
||||
}
|
||||
if (nodup(llist, t)) {
|
||||
llist[nl++] = t;
|
||||
if (getsuf(t)=='o')
|
||||
nxo++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(nc==0)
|
||||
goto nocom;
|
||||
if ((signal(2, 1) & 01) == 0)
|
||||
signal(2, &dexit);
|
||||
for (i=0; i<nc; i++) {
|
||||
if (nc>1)
|
||||
printf("%s:\n", clist[i]);
|
||||
tmp = 0;
|
||||
av[0] = complr;
|
||||
av[1] = expand(clist[i]);
|
||||
if (pflag || exfail)
|
||||
continue;
|
||||
if (av[1] == 0) {
|
||||
cflag++;
|
||||
continue;
|
||||
}
|
||||
av[2] = 0;
|
||||
t = callsys(complr, av);
|
||||
if(tmp)
|
||||
cunlink(tmp);
|
||||
if(t) {
|
||||
cflag++;
|
||||
continue;
|
||||
}
|
||||
av[0] = "as";
|
||||
av[1] = "-";
|
||||
av[2] = "f.tmp1";
|
||||
av[3] = 0;
|
||||
callsys("/bin/as", av);
|
||||
t = setsuf(clist[i], 'o');
|
||||
cunlink(t);
|
||||
if(link("a.out", t) || cunlink("a.out")) {
|
||||
printf("move failed: %s\n", t);
|
||||
cflag++;
|
||||
}
|
||||
}
|
||||
nocom:
|
||||
if (cflag==0 && nl!=0) {
|
||||
i = 0;
|
||||
av[0] = "ld";
|
||||
av[1] = "-x";
|
||||
av[2] = "/lib/fr0.o";
|
||||
j = 3;
|
||||
while(i<nl)
|
||||
av[j++] = llist[i++];
|
||||
av[j++] = "-lf";
|
||||
av[j++] = "/lib/filib.a";
|
||||
av[j++] = "-l";
|
||||
av[j++] = 0;
|
||||
callsys("/bin/ld", av);
|
||||
if (nc==1 && nxo==1)
|
||||
cunlink(setsuf(clist[0], 'o'));
|
||||
}
|
||||
dexit();
|
||||
}
|
||||
|
||||
dexit()
|
||||
{
|
||||
unlink("f.tmp1");
|
||||
exit();
|
||||
}
|
||||
|
||||
expand(file)
|
||||
char *file;
|
||||
{
|
||||
int ib1[259], ib2[259], ob[259];
|
||||
struct symtab stab[200];
|
||||
char ln[196], sbf[1024];
|
||||
int c;
|
||||
|
||||
exfail = 0;
|
||||
ibuf = ibuf1 = ib1;
|
||||
ibuf2 = ib2;
|
||||
if (fopen(file, ibuf1)<0)
|
||||
return(file);
|
||||
if (getc(ibuf1) != '#') {
|
||||
close(ibuf1[0]);
|
||||
return(file);
|
||||
}
|
||||
ibuf1[1]++;
|
||||
ibuf1[2]--;
|
||||
obuf = ob;
|
||||
symtab = stab;
|
||||
for (c=0; c<200; c++) {
|
||||
stab[c].name[0] = '\0';
|
||||
stab[c].value = 0;
|
||||
}
|
||||
defloc = lookup("define", 1);
|
||||
defloc->value = defloc->name;
|
||||
incloc = lookup("include", 1);
|
||||
incloc->value = incloc->name;
|
||||
stringbuf = sbf;
|
||||
line = ln;
|
||||
lineno = 0;
|
||||
tmp = setsuf(copy(file), 'i');
|
||||
if (fcreat(tmp, obuf) < 0) {
|
||||
printf("Can't creat %s\n", tmp);
|
||||
dexit();
|
||||
}
|
||||
while(getline()) {
|
||||
/*
|
||||
if (ibuf==ibuf2)
|
||||
putc(001, obuf); /*SOH: insert */
|
||||
if (ln[0] != '#')
|
||||
for (lp=line; *lp!='\0'; lp++)
|
||||
putc(*lp, obuf);
|
||||
putc('\n', obuf);
|
||||
}
|
||||
fflush(obuf);
|
||||
close(obuf[0]);
|
||||
close(ibuf1[0]);
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
getline()
|
||||
{
|
||||
int c, sc, state;
|
||||
struct symtab *np;
|
||||
char *namep, *filname;
|
||||
|
||||
if (ibuf==ibuf1)
|
||||
lineno++;
|
||||
lp = line;
|
||||
*lp = '\0';
|
||||
state = 0;
|
||||
if ((c=getch()) == '#')
|
||||
state = 1;
|
||||
while (c!='\n' && c!='\0') {
|
||||
if ('a'<=c && c<='z' || 'A'<=c && c<='Z' || c=='_') {
|
||||
namep = lp;
|
||||
sch(c);
|
||||
while ('a'<=(c=getch()) && c<='z'
|
||||
||'A'<=c && c<='Z'
|
||||
||'0'<=c && c<='9'
|
||||
||c=='_')
|
||||
sch(c);
|
||||
sch('\0');
|
||||
lp--;
|
||||
np = lookup(namep, state);
|
||||
if (state==1) {
|
||||
if (np==defloc)
|
||||
state = 2;
|
||||
else if (np==incloc)
|
||||
state = 3;
|
||||
else {
|
||||
error("Undefined control");
|
||||
while (c!='\n' && c!='\0')
|
||||
c = getch();
|
||||
return(c);
|
||||
}
|
||||
} else if (state==2) {
|
||||
np->value = stringbuf;
|
||||
while ((c=getch())!='\n' && c!='\0')
|
||||
savch(c);
|
||||
savch('\0');
|
||||
return(1);
|
||||
}
|
||||
continue;
|
||||
} else if ((sc=c)=='\'' || sc=='"') {
|
||||
sch(sc);
|
||||
filname = lp;
|
||||
instring++;
|
||||
while ((c=getch())!=sc && c!='\n' && c!='\0') {
|
||||
sch(c);
|
||||
if (c=='\\')
|
||||
sch(getch());
|
||||
}
|
||||
instring = 0;
|
||||
if (state==3) {
|
||||
*lp = '\0';
|
||||
while ((c=getch())!='\n' && c!='\0');
|
||||
if (ibuf==ibuf2)
|
||||
error("Nested 'include'");
|
||||
if (fopen(filname, ibuf2)<0)
|
||||
error("Missing file %s", filname);
|
||||
else
|
||||
ibuf = ibuf2;
|
||||
return(c);
|
||||
}
|
||||
}
|
||||
sch(c);
|
||||
c = getch();
|
||||
}
|
||||
sch('\0');
|
||||
if (state>1)
|
||||
error("Control syntax");
|
||||
return(c);
|
||||
}
|
||||
|
||||
error(s, x)
|
||||
{
|
||||
printf("%d: ", lineno);
|
||||
printf(s, x);
|
||||
putchar('\n');
|
||||
exfail++;
|
||||
cflag++;
|
||||
}
|
||||
|
||||
sch(c)
|
||||
{
|
||||
if (lp==line+194)
|
||||
error("Line overflow");
|
||||
*lp++ = c;
|
||||
if (lp>line+195)
|
||||
lp = line+195;
|
||||
}
|
||||
|
||||
savch(c)
|
||||
{
|
||||
*stringbuf++ = c;
|
||||
}
|
||||
|
||||
getch()
|
||||
{
|
||||
static peekc;
|
||||
int c;
|
||||
|
||||
if (peekc) {
|
||||
c = peekc;
|
||||
peekc = 0;
|
||||
return(c);
|
||||
}
|
||||
loop:
|
||||
if ((c=getc1())=='/' && !instring) {
|
||||
if ((peekc=getc1())!='*')
|
||||
return('/');
|
||||
peekc = 0;
|
||||
for(;;) {
|
||||
c = getc1();
|
||||
cloop:
|
||||
switch (c) {
|
||||
|
||||
case '\0':
|
||||
return('\0');
|
||||
|
||||
case '*':
|
||||
if ((c=getc1())=='/')
|
||||
goto loop;
|
||||
goto cloop;
|
||||
|
||||
case '\n':
|
||||
if (ibuf==ibuf1) {
|
||||
putc('\n', obuf);
|
||||
lineno++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(c);
|
||||
}
|
||||
|
||||
getc1()
|
||||
{
|
||||
int c;
|
||||
|
||||
if ((c = getc(ibuf)) < 0 && ibuf==ibuf2) {
|
||||
close(ibuf2[0]);
|
||||
ibuf = ibuf1;
|
||||
putc('\n', obuf);
|
||||
c = getc1();
|
||||
}
|
||||
if (c<0)
|
||||
return(0);
|
||||
return(c);
|
||||
}
|
||||
|
||||
lookup(namep, enterf)
|
||||
char *namep;
|
||||
{
|
||||
char *np, *snp;
|
||||
struct symtab *sp;
|
||||
int i, c;
|
||||
|
||||
np = namep;
|
||||
i = 0;
|
||||
while (c = *np++)
|
||||
i =+ c;
|
||||
i =% symsiz;
|
||||
sp = &symtab[i];
|
||||
while (sp->name[0]) {
|
||||
snp = sp;
|
||||
np = namep;
|
||||
while (*snp++ == *np)
|
||||
if (*np++ == '\0' || np==namep+8) {
|
||||
if (!enterf)
|
||||
subst(namep, sp);
|
||||
return(sp);
|
||||
}
|
||||
if (sp++ > &symtab[symsiz])
|
||||
sp = symtab;
|
||||
}
|
||||
if (enterf) {
|
||||
for (i=0; i<8; i++)
|
||||
if (sp->name[i] = *namep)
|
||||
namep++;
|
||||
while (*namep)
|
||||
namep++;
|
||||
}
|
||||
return(sp);
|
||||
}
|
||||
|
||||
subst(np, sp)
|
||||
char *np;
|
||||
struct symtab *sp;
|
||||
{
|
||||
char *vp;
|
||||
|
||||
lp = np;
|
||||
if ((vp = sp->value) == 0)
|
||||
return;
|
||||
sch(' ');
|
||||
while (*vp)
|
||||
sch(*vp++);
|
||||
sch(' ');
|
||||
}
|
||||
|
||||
getsuf(s)
|
||||
char s[];
|
||||
{
|
||||
int c;
|
||||
char t, *os;
|
||||
|
||||
c = 0;
|
||||
os = s;
|
||||
while(t = *s++)
|
||||
if (t=='/')
|
||||
c = 0;
|
||||
else
|
||||
c++;
|
||||
s =- 3;
|
||||
if (c<=14 && c>2 && *s++=='.')
|
||||
return(*s);
|
||||
return(0);
|
||||
}
|
||||
|
||||
setsuf(s, ch)
|
||||
char s[];
|
||||
{
|
||||
char *os;
|
||||
|
||||
os = s;
|
||||
while(*s++);
|
||||
s[-2] = ch;
|
||||
return(os);
|
||||
}
|
||||
|
||||
callsys(f, v)
|
||||
char f[], *v[]; {
|
||||
int t, status;
|
||||
|
||||
if ((t=fork())==0) {
|
||||
execv(f, v);
|
||||
printf("Can't find %s\n", f);
|
||||
exit(1);
|
||||
} else
|
||||
if (t == -1) {
|
||||
printf("Try again\n");
|
||||
return(1);
|
||||
}
|
||||
while(t!=wait(&status));
|
||||
if ((t=(status&0377)) != 0 && t!=14) {
|
||||
if (t!=2) /* interrupt */
|
||||
printf("Fatal error in %s\n", f);
|
||||
dexit();
|
||||
}
|
||||
return((status>>8) & 0377);
|
||||
}
|
||||
|
||||
copy(s)
|
||||
char s[]; {
|
||||
char *otsp;
|
||||
|
||||
otsp = tsp;
|
||||
while(*tsp++ = *s++);
|
||||
return(otsp);
|
||||
}
|
||||
|
||||
nodup(l, s)
|
||||
char **l, s[]; {
|
||||
char *t, *os, c;
|
||||
|
||||
if (getsuf(s) != 'o')
|
||||
return(1);
|
||||
os = s;
|
||||
while(t = *l++) {
|
||||
s = os;
|
||||
while(c = *s++)
|
||||
if (c != *t++)
|
||||
break;
|
||||
if (*t++ == '\0')
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
cunlink(f)
|
||||
char *f;
|
||||
{
|
||||
if (f==0)
|
||||
return(0);
|
||||
return(unlink(f));
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
signal = 48.
|
||||
testing = 0
|
||||
/
|
||||
/ command interpreter for form letter editor
|
||||
/
|
||||
/
|
||||
/
|
||||
command:
|
||||
sys signal; 2; inter
|
||||
jsr pc,initl
|
||||
mov sp,spi
|
||||
loop:
|
||||
mov spi,sp
|
||||
mov $buffer,r2
|
||||
clr r4
|
||||
clr iflag
|
||||
1:
|
||||
jsr pc,tfiget
|
||||
cmpb $' ,r0
|
||||
beq 1f
|
||||
cmpb $'\n,r0
|
||||
bne 2f
|
||||
clrb (r2)
|
||||
br 4f
|
||||
2:
|
||||
movb r0,(r2)+
|
||||
br 1b
|
||||
1:
|
||||
clrb (r2)
|
||||
mov $argc,r3
|
||||
3:
|
||||
mov $arg,r2
|
||||
2:
|
||||
jsr pc,tfiget
|
||||
cmpb $' ,r0
|
||||
beq 1f
|
||||
cmpb $'\n,r0
|
||||
beq 1f
|
||||
movb r0,(r2)+
|
||||
br 2b
|
||||
1:
|
||||
clrb (r2)+
|
||||
inc r4
|
||||
1:
|
||||
movb -(r2),sv
|
||||
cmp r2,$arg
|
||||
blos 1f
|
||||
movb -(r2),-(sp)
|
||||
movb sv,1(sp)
|
||||
cmp r2,$arg
|
||||
bhi 1b
|
||||
mov sp,(r3)+
|
||||
br 2f
|
||||
1:
|
||||
clrb -(sp)
|
||||
movb sv,1(sp)
|
||||
mov sp,(r3)
|
||||
add $1,(r3)+
|
||||
2:
|
||||
cmpb r0,$'\n
|
||||
bne 3b
|
||||
1:
|
||||
mov -(r3),-(sp)
|
||||
cmp r3,$argc
|
||||
bhi 1b
|
||||
4:
|
||||
mov r4,-(sp)
|
||||
3:
|
||||
clr r0
|
||||
mov $tabl,r4
|
||||
2:
|
||||
mov (r4)+,r1
|
||||
cmp r4,$tend
|
||||
bhi error
|
||||
add $2,r0
|
||||
mov $buffer,r2
|
||||
1:
|
||||
cmpb (r1)+,(r2)+
|
||||
bne 2b
|
||||
tstb (r1)
|
||||
bne 1b
|
||||
tstb (r2)
|
||||
bne 2b
|
||||
sub $2,r0
|
||||
add $jtable,r0
|
||||
clr vflag
|
||||
clr qflag
|
||||
jmp *(r0)
|
||||
/
|
||||
error:
|
||||
mov $1,r0
|
||||
sys write; err; 2
|
||||
br loop
|
||||
/
|
||||
/
|
||||
tabl: c1; c2; c3; c4; c5; c6; c7; c8;
|
||||
tend: 0
|
||||
c1: <n\0>
|
||||
c2: <p\0>
|
||||
c3: <e\0>
|
||||
c4: <d\0>
|
||||
c5: <m\0>
|
||||
c6: <fin\0>
|
||||
c7: <q\0>
|
||||
c8: <c\0>
|
||||
err: <?\n>
|
||||
endt: .even
|
||||
jtable: list; listf; ed; remove; rename; fin; q; memck;
|
||||
spi: .=.+2
|
||||
sv: .=.+2
|
||||
@@ -0,0 +1,533 @@
|
||||
/
|
||||
/
|
||||
ed:
|
||||
mov (sp)+,r3
|
||||
ble error
|
||||
econ:
|
||||
sys stat; ftemp; buffer
|
||||
bec 2f
|
||||
sys creat; ftemp; 666
|
||||
mov r0,tmpw
|
||||
sys open; ftemp; 0
|
||||
mov r0,tmpr
|
||||
br 1f
|
||||
2:
|
||||
cmpb $'z,ftemp+9.
|
||||
bne 2f
|
||||
mov $1,r0
|
||||
sys write; erm; 23.
|
||||
jmp loop
|
||||
2:
|
||||
incb ftemp+9.
|
||||
br econ
|
||||
1:
|
||||
mov (sp),r0
|
||||
jsr pc,getspq
|
||||
bes 3f
|
||||
mov r0,r4
|
||||
mov r2,r1
|
||||
jsr pc,rewind
|
||||
mov $buffer,r2
|
||||
1:
|
||||
jsr pc,getchar
|
||||
bes 1f
|
||||
movb r0,(r2)+
|
||||
br 1b
|
||||
1:
|
||||
movb $'\n,(r2)+
|
||||
jsr pc,output
|
||||
mov r4,r1
|
||||
jsr pc,rewind
|
||||
2:
|
||||
mov $buffer,r2
|
||||
1:
|
||||
jsr pc,getchar
|
||||
bes 1f
|
||||
movb r0,(r2)+
|
||||
cmp r2,$bufend
|
||||
blo 1b
|
||||
mov tmpw,r0
|
||||
sys write; buffer; 512.
|
||||
br 2b
|
||||
1:
|
||||
sub $buffer,r2
|
||||
beq 4f
|
||||
mov r2,0f
|
||||
mov tmpw,r0
|
||||
sys write; buffer; 0:..
|
||||
4:
|
||||
tst iflag
|
||||
beq 1f
|
||||
mov tmpw,r0
|
||||
sys close
|
||||
mov tmpr,r0
|
||||
sys close
|
||||
sys unlink; ftemp
|
||||
jmp loop
|
||||
1:
|
||||
mov tmpw,r0
|
||||
sys close
|
||||
sys fork
|
||||
br 5f
|
||||
mov r1,-(sp)
|
||||
sys wait
|
||||
sys signal; 2; inter
|
||||
mov (sp)+,r1
|
||||
mov a(r1),w(r1)
|
||||
2:
|
||||
mov tmpr,r0
|
||||
sys read; buffer; 512.
|
||||
tst r0
|
||||
beq 2f
|
||||
add $buffer,r0
|
||||
mov r0,bufend
|
||||
mov $buffer,r2
|
||||
1:
|
||||
movb (r2)+,r0
|
||||
jsr pc,putchar
|
||||
cmp r2,bufend
|
||||
blo 1b
|
||||
br 2b
|
||||
2:
|
||||
mov tmpr,r0
|
||||
sys close
|
||||
sys unlink; ftemp
|
||||
tst iflag
|
||||
beq 1f
|
||||
jmp loop
|
||||
1:
|
||||
tst qflag
|
||||
bgt 1f
|
||||
tst (sp)+
|
||||
dec r3
|
||||
bgt 1f
|
||||
jmp loop
|
||||
1: jmp econ
|
||||
jmp loop
|
||||
3:
|
||||
mov (sp),r2
|
||||
mov $2,r0
|
||||
jsr pc,allocate
|
||||
1:
|
||||
tstb (r2)
|
||||
beq 1f
|
||||
movb (r2)+,r0
|
||||
jsr pc,putchar
|
||||
br 1b
|
||||
1:
|
||||
mov r1,r0
|
||||
mov asmem,r1
|
||||
jsr pc,putword
|
||||
mov $2,r0
|
||||
jsr pc,allocate
|
||||
mov r1,r0
|
||||
mov asmem,r1
|
||||
jsr pc,putword
|
||||
mov r0,r1
|
||||
br 4b
|
||||
5:
|
||||
mov $2,r0
|
||||
1:
|
||||
sys close
|
||||
inc r0
|
||||
cmp r0,$10.
|
||||
blo 1b
|
||||
sys exec; edd; eda
|
||||
sys exit
|
||||
eda: edd; ftemp; 0
|
||||
edd: </bin/ed\0>
|
||||
.even
|
||||
ftemp: </tmp/ftmpa\0>
|
||||
erm: <Cannot open temp. file\n>
|
||||
.even
|
||||
tmpw: .=.+2
|
||||
tmpr: .=.+2
|
||||
/
|
||||
/ remove a 'file' from memory
|
||||
/
|
||||
remove:
|
||||
mov (sp)+,r3
|
||||
bgt 5f
|
||||
mov $1,vflag
|
||||
mov asmem,r1
|
||||
jsr pc,rewind
|
||||
mov r(r1),-(sp)
|
||||
4:
|
||||
tst iflag
|
||||
beq 1f
|
||||
jmp loop
|
||||
1:
|
||||
jsr pc,getword
|
||||
bes 4f
|
||||
mov r0,r2
|
||||
jsr pc,ask
|
||||
bec 1f
|
||||
mov r(r1),(sp)
|
||||
br 4b
|
||||
1:
|
||||
jsr pc,getword
|
||||
br 2f
|
||||
5:
|
||||
mov (sp),r0
|
||||
jsr pc,getspq
|
||||
bec 2f
|
||||
tst qflag
|
||||
blt 6f
|
||||
mov (sp),r1
|
||||
jsr pc,nothere
|
||||
br 3f
|
||||
2:
|
||||
mov r0,r1
|
||||
jsr pc,release
|
||||
mov r2,r1
|
||||
jsr pc,release
|
||||
jsr pc,rm
|
||||
3:
|
||||
tst vflag
|
||||
bne 3f
|
||||
tst iflag
|
||||
beq 1f
|
||||
jmp loop
|
||||
1:
|
||||
tst qflag
|
||||
bgt 5b
|
||||
6:
|
||||
tst (sp)+
|
||||
dec r3
|
||||
bgt 5b
|
||||
jmp loop
|
||||
3:
|
||||
mov asmem,r1
|
||||
mov (sp),r(r1)
|
||||
br 4b
|
||||
4:
|
||||
tst (sp)+
|
||||
jmp loop
|
||||
/
|
||||
/ rename a 'file'
|
||||
/
|
||||
rename:
|
||||
mov (sp)+,r3
|
||||
bne 1f
|
||||
jmp error
|
||||
1:
|
||||
sub $2,r3
|
||||
blt 1f
|
||||
5:
|
||||
mov (sp),r0
|
||||
jsr pc,getsp
|
||||
bes 4f
|
||||
tst (sp)+
|
||||
sub $4,r(r1)
|
||||
mov (sp),r0
|
||||
mov r2,-(sp)
|
||||
mov r(r1),-(sp)
|
||||
jsr pc,getsp
|
||||
bes 3f
|
||||
mov r2,-(sp)
|
||||
mov r0,r1
|
||||
jsr pc,release
|
||||
jsr pc,rm
|
||||
mov (sp)+,r0
|
||||
mov (sp)+,r(r1)
|
||||
jsr pc,alterword
|
||||
mov (sp)+,r1
|
||||
jsr pc,release
|
||||
br 5f
|
||||
3:
|
||||
mov (sp)+,r(r1)
|
||||
mov (sp)+,r1
|
||||
jsr pc,release
|
||||
mov $2,r0
|
||||
jsr pc,allocate
|
||||
mov (sp)+,r2
|
||||
2:
|
||||
movb (r2)+,r0
|
||||
beq 2f
|
||||
jsr pc,putchar
|
||||
br 2b
|
||||
2:
|
||||
mov r1,r0
|
||||
mov asmem,r1
|
||||
jsr pc,alterword
|
||||
5:
|
||||
tst iflag
|
||||
beq 2f
|
||||
jmp loop
|
||||
2:
|
||||
tst r3
|
||||
beq 2f
|
||||
sub $2,r3
|
||||
bge 5b
|
||||
1:
|
||||
tst (sp)+
|
||||
jmp error
|
||||
2:
|
||||
jmp loop
|
||||
4:
|
||||
mov (sp)+,r1
|
||||
jsr pc,nothere
|
||||
tst (sp)+
|
||||
br 5b
|
||||
/
|
||||
/ list contents of asmem
|
||||
/
|
||||
list:
|
||||
mov $buffer,r2
|
||||
movb $'\n,(r2)+
|
||||
jsr pc,output
|
||||
mov (sp)+,r3
|
||||
beq 1f
|
||||
mov $1,vflag
|
||||
5:
|
||||
tst iflag
|
||||
beq 2f
|
||||
jmp loop
|
||||
2:
|
||||
mov (sp),r0
|
||||
jsr pc,getspq
|
||||
bes 4f
|
||||
mov r2,r1
|
||||
br 3f
|
||||
1:
|
||||
mov asmem,r1
|
||||
jsr pc,fsfile
|
||||
sub $2,r(r1)
|
||||
2:
|
||||
tst iflag
|
||||
bne 2f
|
||||
jsr pc,backword
|
||||
bes 2f
|
||||
mov r0,r1
|
||||
3:
|
||||
jsr pc,getn
|
||||
movb $'\n,(r2)+
|
||||
jsr pc,output
|
||||
tst vflag
|
||||
bne 1f
|
||||
mov asmem,r1
|
||||
sub $2,r(r1)
|
||||
br 2b
|
||||
1:
|
||||
tst qflag
|
||||
bgt 5b
|
||||
4:
|
||||
tst (sp)+
|
||||
dec r3
|
||||
bgt 5b
|
||||
2:
|
||||
mov $buffer,r2
|
||||
movb $'\n,(r2)+
|
||||
jsr pc,output
|
||||
jmp loop
|
||||
/
|
||||
/ list a 'file
|
||||
/
|
||||
listf:
|
||||
mov (sp)+,r3
|
||||
bgt 4f
|
||||
jmp error
|
||||
4:
|
||||
mov (sp),r0
|
||||
jsr pc,getspq
|
||||
bes 3f
|
||||
mov r0,r4
|
||||
mov r2,r1
|
||||
jsr pc,rewind
|
||||
mov $buffer,r2
|
||||
movb $'\n,(r2)+
|
||||
1:
|
||||
jsr pc,getchar
|
||||
bes 1f
|
||||
movb r0,(r2)+
|
||||
cmp r2,$bufend
|
||||
blo 1b
|
||||
jsr pc,output
|
||||
br 1b
|
||||
1:
|
||||
mov r4,r1
|
||||
jsr pc,rewind
|
||||
movb $':,(r2)+
|
||||
cmp r2,$bufend
|
||||
blo 2f
|
||||
jsr pc,output
|
||||
2:
|
||||
movb $'\n,(r2)+
|
||||
1:
|
||||
tst iflag
|
||||
beq 2f
|
||||
jmp loop
|
||||
2:
|
||||
cmp r2,$bufend
|
||||
blo 2f
|
||||
jsr pc,output
|
||||
2:
|
||||
jsr pc,getchar
|
||||
bes 1f
|
||||
movb r0,(r2)+
|
||||
br 1b
|
||||
1:
|
||||
jsr pc,output
|
||||
3:
|
||||
tst qflag
|
||||
bgt 4b
|
||||
tst (sp)+
|
||||
dec r3
|
||||
bgt 4b
|
||||
mov $buffer,r2
|
||||
movb $'\n,(r2)+
|
||||
jsr pc,output
|
||||
jmp loop
|
||||
/
|
||||
fin:
|
||||
jsr pc,flush
|
||||
jsr pc,whead
|
||||
4
|
||||
q:
|
||||
jsr pc,flush
|
||||
jsr pc,whead
|
||||
sys exit
|
||||
memck: mov (sp)+,r3
|
||||
2:
|
||||
ble 2f
|
||||
mov (sp)+,r1
|
||||
cmpb (r1),$'p
|
||||
bne 1f
|
||||
bis $1,vflag
|
||||
br 3f
|
||||
1:
|
||||
cmpb (r1),$'f
|
||||
bne 3f
|
||||
bis $2,vflag
|
||||
3:
|
||||
dec r3
|
||||
br 2b
|
||||
2:
|
||||
clr freeh
|
||||
mov $freeb,r2
|
||||
1:
|
||||
clr (r2)+
|
||||
cmp r2,$freen
|
||||
blo 1b
|
||||
mov $headers,r2
|
||||
2:
|
||||
cmp l(r2),$hsz
|
||||
beq 6f
|
||||
jsr pc,ck
|
||||
bec 1f
|
||||
cmp r2,asmem
|
||||
beq 1f
|
||||
mov asmem,r1
|
||||
jsr pc,rewind
|
||||
clr r3
|
||||
4:
|
||||
inc r3
|
||||
jsr pc,getword
|
||||
bes 5f
|
||||
cmp r0,r2
|
||||
bne 4b
|
||||
6:
|
||||
inc freeh
|
||||
1:
|
||||
cont:
|
||||
add $8.,r2
|
||||
cmp r2,$headend-4
|
||||
blo 2b
|
||||
mov asmem,r1
|
||||
jsr pc,rewind
|
||||
4:
|
||||
jsr pc,getword
|
||||
bes 4f
|
||||
tst r(r0)
|
||||
beq 2f
|
||||
mov r0,r2
|
||||
jsr pc,ck
|
||||
bes 4b
|
||||
2:
|
||||
sub $hblk,r0
|
||||
jsr r5,oct
|
||||
mov $1,r0
|
||||
sys write; re; 24.
|
||||
cmp vflag,$1
|
||||
beq 4b
|
||||
bit $1,r3
|
||||
beq 2f
|
||||
jsr pc,getword
|
||||
mov r0,r1
|
||||
jsr pc,release
|
||||
br 3f
|
||||
2:
|
||||
jsr pc,backword
|
||||
add $4,r(r1)
|
||||
mov r0,r1
|
||||
jsr pc,release
|
||||
3:
|
||||
jsr pc,rm
|
||||
clr r3
|
||||
br 4b
|
||||
4:
|
||||
mov freeh,r0
|
||||
jsr r5,decml
|
||||
mov $1,r0
|
||||
sys write; frh; 14.
|
||||
mov $freeb,r2
|
||||
mov $1,r3
|
||||
6:
|
||||
cmp r2,$freen
|
||||
bhis 6f
|
||||
mov (r2)+,r0
|
||||
beq 3f
|
||||
jsr r5,decml
|
||||
mov $1,r0
|
||||
sys write; frb; 18.
|
||||
mov r3,r0
|
||||
jsr r5,decml
|
||||
mov $1,r0
|
||||
sys write; lf; 1.
|
||||
3:
|
||||
asl r3
|
||||
br 6b
|
||||
6:
|
||||
mov $1,r0
|
||||
sys write; lf; 1.
|
||||
jmp loop
|
||||
5:
|
||||
mov r2,r0
|
||||
sub $hblk,r0
|
||||
jsr r5,oct
|
||||
mov $1,r0
|
||||
sys write; un; 26.
|
||||
tst vflag
|
||||
beq 1b
|
||||
mov r2,r1
|
||||
cmp vflag,$2
|
||||
beq 3f
|
||||
jsr pc,rewind
|
||||
mov $buffer,r2
|
||||
2:
|
||||
jsr pc,getchar
|
||||
bes 2f
|
||||
movb r0,(r2)+
|
||||
cmp r2,$buffer+80.
|
||||
blo 2b
|
||||
jsr pc,output
|
||||
br 2b
|
||||
2:
|
||||
movb $'\n,(r2)+
|
||||
jsr pc,output
|
||||
mov r1,r2
|
||||
cmp vflag,$1
|
||||
bne 3f
|
||||
jmp cont
|
||||
3:
|
||||
jsr pc,release
|
||||
jmp cont
|
||||
/
|
||||
interrupt: 4
|
||||
/
|
||||
un: < header not accounted for\n>
|
||||
re: < part of asmem released\n>
|
||||
lf: <\n>
|
||||
frh: < free headers\n >
|
||||
frb: < free blocks size >
|
||||
endc: .even
|
||||
@@ -0,0 +1,358 @@
|
||||
rti = 2
|
||||
.globl rm
|
||||
.globl ck
|
||||
.globl loop
|
||||
.globl oct
|
||||
.globl argc
|
||||
.globl arg
|
||||
.globl tfiget
|
||||
.globl asmem
|
||||
.globl qflag
|
||||
.globl vflag
|
||||
.globl getspq
|
||||
.globl q
|
||||
.globl ask
|
||||
.globl getword
|
||||
.globl r
|
||||
.globl w
|
||||
.globl output
|
||||
.globl buffer
|
||||
.globl bufend
|
||||
.globl fv
|
||||
.globl getsp
|
||||
.globl release
|
||||
.globl nothere
|
||||
.globl getn
|
||||
.globl getchar
|
||||
.globl rewind
|
||||
.globl iflag
|
||||
.globl inter
|
||||
/ output buffer
|
||||
/ r2 = last char in buffer + 1
|
||||
/ r2 returned at beginning of buffer
|
||||
/
|
||||
output:
|
||||
sub $buffer,r2
|
||||
blos 1f
|
||||
mov r2,0f
|
||||
mov $1,r0
|
||||
sys write; buffer; 0:..
|
||||
mov $buffer,r2
|
||||
1:
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to find the string pointed to by r0
|
||||
/ in either memory or curly
|
||||
/ r1 = where to look
|
||||
/
|
||||
/ returns error set if string not there
|
||||
/ returns r1 = header of string if there
|
||||
getsp:
|
||||
mov r0,-(sp)
|
||||
mov asmem,r1
|
||||
jsr pc,rewind /memory
|
||||
3:
|
||||
jsr pc,getword
|
||||
bes 1f
|
||||
mov r0,r1
|
||||
jsr pc,rewind
|
||||
mov (sp),r2
|
||||
2:
|
||||
jsr pc,getchar
|
||||
bes 2f
|
||||
tstb (r2)
|
||||
beq 4f
|
||||
cmpb r0,(r2)+
|
||||
beq 2b
|
||||
4:
|
||||
mov asmem,r1
|
||||
add $2,r(r1)
|
||||
br 3b
|
||||
2:
|
||||
tstb (r2)
|
||||
bne 4b
|
||||
mov r1,r2
|
||||
mov asmem,r1
|
||||
jsr pc,getword
|
||||
tst (sp)+
|
||||
rts pc
|
||||
1:
|
||||
mov (sp)+,r0
|
||||
sec
|
||||
rts pc
|
||||
/
|
||||
/ finds header of string with name same as that pointed to by r0
|
||||
/ taking into account ? and *
|
||||
getspq:
|
||||
mov r0,-(sp)
|
||||
mov asmem,r1
|
||||
tst qflag
|
||||
bgt 1f
|
||||
jsr pc,rewind
|
||||
1:
|
||||
jsr pc,getword
|
||||
bes 1f
|
||||
mov r0,r1
|
||||
jsr pc,rewind
|
||||
mov (sp),r2
|
||||
2:
|
||||
cmpb (r2),$'*
|
||||
bne 3f
|
||||
clr strflg
|
||||
mov $2,qflag
|
||||
inc r2
|
||||
tstb (r2)
|
||||
beq 6f
|
||||
mov r2,ch
|
||||
3:
|
||||
jsr pc,getchar
|
||||
bes 2f
|
||||
tstb (r2)
|
||||
bne 3f
|
||||
cmp $2,qflag
|
||||
bne 4f
|
||||
mov ch,r2
|
||||
3:
|
||||
cmpb (r2),$'?
|
||||
bne 3f
|
||||
inc r2
|
||||
tst qflag
|
||||
bne 2b
|
||||
mov $1,qflag
|
||||
br 2b
|
||||
3:
|
||||
cmpb r0,(r2)+
|
||||
bne 5f
|
||||
inc strflg
|
||||
br 2b
|
||||
5:
|
||||
cmp $2,qflag
|
||||
bne 4f
|
||||
tst strflg
|
||||
bne 4f
|
||||
dec r2
|
||||
br 2b
|
||||
4:
|
||||
mov asmem,r1
|
||||
add $2,r(r1)
|
||||
br 1b
|
||||
2:
|
||||
tstb (r2)
|
||||
bne 4b
|
||||
6:
|
||||
mov r1,r2
|
||||
mov asmem,r1
|
||||
jsr pc,getword
|
||||
tst (sp)+
|
||||
rts pc
|
||||
1:
|
||||
mov $-1.,qflag
|
||||
mov (sp)+,r0
|
||||
sec
|
||||
rts pc
|
||||
/
|
||||
/ tfiget
|
||||
/ jsr r5,tfiget
|
||||
/
|
||||
tfiget:
|
||||
clr r0
|
||||
sys read; ch; 1
|
||||
bes 1f
|
||||
tst iflag
|
||||
beq 9f; jmp loop; 9:
|
||||
tst r0
|
||||
beq 1f
|
||||
movb ch,r0
|
||||
rts pc
|
||||
1: jmp q
|
||||
/
|
||||
/ routine to print file name and error message
|
||||
/ r2 = next free byte in buffer
|
||||
/
|
||||
nothere:
|
||||
mov $buffer,r2
|
||||
1:
|
||||
tstb (r1)
|
||||
beq 1f
|
||||
movb (r1)+,(r2)+
|
||||
br 1b
|
||||
1:
|
||||
sub $buffer,r2
|
||||
mov r2,0f
|
||||
mov $1,r0
|
||||
sys write; buffer; 0:..
|
||||
mov $1,r0
|
||||
sys write; err4; 16.
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to put characters from string in buffer
|
||||
/ r1 = header of string
|
||||
/ on return r2 = next free byte in buffer
|
||||
/
|
||||
getn:
|
||||
mov $buffer,r2
|
||||
jsr pc,rewind
|
||||
1:
|
||||
jsr pc,getchar
|
||||
bes 1f
|
||||
movb r0,(r2)+
|
||||
cmp r2,$bufend
|
||||
bhis 1f
|
||||
br 1b
|
||||
1: rts pc
|
||||
/
|
||||
ask:
|
||||
mov r2,-(sp)
|
||||
mov r0,r1
|
||||
jsr pc,getn
|
||||
movb $' ,(r2)+
|
||||
jsr pc,output
|
||||
jsr pc,tfiget
|
||||
cmpb $'\n,r0
|
||||
bne 1f
|
||||
2:
|
||||
mov asmem,r1
|
||||
add $2,r(r1)
|
||||
mov (sp)+,r2
|
||||
sec
|
||||
rts pc
|
||||
1:
|
||||
cmpb r0,$'y
|
||||
beq 4f
|
||||
cmpb r0,$'q
|
||||
beq 3f
|
||||
1:
|
||||
tst iflag
|
||||
bne 2b
|
||||
jsr pc,tfiget
|
||||
cmpb $'\n,r0
|
||||
bne 1b
|
||||
br 2b
|
||||
4:
|
||||
tst iflag
|
||||
bne 2b
|
||||
jsr pc,tfiget
|
||||
cmpb $'\n,r0
|
||||
bne 1b
|
||||
mov asmem,r1
|
||||
mov (sp)+,r2
|
||||
clc
|
||||
rts pc
|
||||
3:
|
||||
tst iflag
|
||||
bne 2b
|
||||
jsr pc,tfiget
|
||||
cmpb $'\n,r0
|
||||
bne 1b
|
||||
mov (sp)+,r2
|
||||
jmp loop
|
||||
inter:
|
||||
inc iflag
|
||||
rti
|
||||
/ to remove an entry from asmem - r points to name ptr
|
||||
/
|
||||
rm:
|
||||
mov r3,-(sp)
|
||||
mov asmem,r1
|
||||
mov r(r1),r3
|
||||
sub $4,r(r1)
|
||||
mov r(r1),r2
|
||||
mov r2,-(sp)
|
||||
1:
|
||||
mov r3,r(r1)
|
||||
jsr pc,getword
|
||||
bes 1f
|
||||
mov r(r1),r3
|
||||
mov r2,r(r1)
|
||||
jsr pc,alterword
|
||||
mov r(r1),r2
|
||||
br 1b
|
||||
1:
|
||||
mov r2,w(r1)
|
||||
mov (sp)+,r(r1)
|
||||
mov (sp)+,r3
|
||||
rts pc
|
||||
/
|
||||
/ check that header pointed to by r2 released
|
||||
/
|
||||
ck:
|
||||
mov r2,-(sp)
|
||||
mov l(r2),r0
|
||||
sub a(r2),r0
|
||||
sub $hblk,r2
|
||||
jsr pc,log2
|
||||
asl r0
|
||||
mov r0,ch
|
||||
mov frlist(r0),r0
|
||||
1:
|
||||
beq 1f
|
||||
cmp r2,r0
|
||||
beq 2f
|
||||
add $hblk,r0
|
||||
mov (r0),r0
|
||||
br 1b
|
||||
2:
|
||||
mov ch,r0
|
||||
inc freeb(r0)
|
||||
mov (sp)+,r2
|
||||
rts pc
|
||||
1:
|
||||
mov (sp)+,r2
|
||||
sec
|
||||
rts pc
|
||||
oct:
|
||||
mov r1,-(sp)
|
||||
mov r0,r1
|
||||
clr r0
|
||||
div $8.,r0
|
||||
mov r1,-(sp)
|
||||
add $'0,(sp)
|
||||
tst r0
|
||||
beq 1f
|
||||
jsr r5,oct
|
||||
1:
|
||||
movb (sp)+,ch
|
||||
mov $1,r0
|
||||
sys write; ch; 1
|
||||
mov (sp)+,r1
|
||||
rts r5
|
||||
|
||||
decml:
|
||||
mov r1,-(sp)
|
||||
mov r0,r1
|
||||
clr r0
|
||||
div $10.,r0
|
||||
mov r1,-(sp)
|
||||
add $'0,(sp)
|
||||
tst r0
|
||||
beq 1f
|
||||
jsr r5,decml
|
||||
1:
|
||||
movb (sp)+,ch
|
||||
mov $1,r0
|
||||
sys write; ch; 1
|
||||
mov (sp)+,r1
|
||||
rts r5
|
||||
/
|
||||
/
|
||||
iflag: 0
|
||||
qflag: 0
|
||||
vflag: 0
|
||||
.data
|
||||
err4: < not in memory.\n>
|
||||
err1: <Cannot open file >
|
||||
end1: .even
|
||||
.bss
|
||||
freeh: .=.+2
|
||||
freeb: .=.+32.
|
||||
freen:
|
||||
ch: .=.+2
|
||||
strflg: .=.+2
|
||||
buffer: .=.+512.
|
||||
bufend: .=.+2
|
||||
argc = buffer + 20.
|
||||
arg = buffer + 256.
|
||||
fv: .=.+2
|
||||
.text
|
||||
@@ -0,0 +1,237 @@
|
||||
int in;
|
||||
int i 0;
|
||||
char buf[512];
|
||||
int *wd {
|
||||
&buf[0]};
|
||||
char *fort[]{
|
||||
"function","subroutine","common","dimension","block","integer",
|
||||
"real","data","double",0};
|
||||
char *asc[]{
|
||||
"sys","mov","tst","clr","jmp",0};
|
||||
char *c[]{
|
||||
"int","char","float","double","struct","extern",0};
|
||||
char *as[]{
|
||||
"globl","byte","even","text","data","bss","comm",0};
|
||||
int ibuf[260];
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
|
||||
while(argc > 1) {
|
||||
printf("%s: ", argv[1]);
|
||||
type(argv[1]);
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
|
||||
type(file)
|
||||
char *file;
|
||||
{
|
||||
int j,nl;
|
||||
char ch;
|
||||
int mbuf[20];
|
||||
|
||||
if(stat(file, mbuf) < 0) {
|
||||
printf("cannot stat\n");
|
||||
return;
|
||||
}
|
||||
switch(mbuf[2]&060000) {
|
||||
|
||||
case 020000:
|
||||
printf("character");
|
||||
goto spcl;
|
||||
|
||||
case 040000:
|
||||
printf("directory\n");
|
||||
return;
|
||||
|
||||
case 060000:
|
||||
printf("block");
|
||||
|
||||
spcl:
|
||||
printf(" special (%d/%d)\n",
|
||||
(mbuf[6]>>8)&0377,
|
||||
mbuf[6]&0377);
|
||||
return;
|
||||
}
|
||||
|
||||
ibuf[0] = open(file, 0);
|
||||
if(ibuf[0] < 0) {
|
||||
printf("cannot open\n");
|
||||
return;
|
||||
}
|
||||
in = read(ibuf[0], buf, 512);
|
||||
switch(*wd) {
|
||||
|
||||
case 0407:
|
||||
printf("executable\n");
|
||||
goto out;
|
||||
|
||||
case 0410:
|
||||
printf("pure executable\n");
|
||||
goto out;
|
||||
|
||||
case 0411:
|
||||
printf("separate executable\n");
|
||||
goto out;
|
||||
|
||||
case 0177555:
|
||||
printf("archive\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if(ccom() == 0)goto notc;
|
||||
while(buf[i] == '#'){
|
||||
j = i;
|
||||
while(buf[i++] != '\n'){
|
||||
if(i - j > 255){
|
||||
printf("data\n");
|
||||
goto out;
|
||||
}
|
||||
if(i >= in)goto notc;
|
||||
}
|
||||
if(ccom() == 0)goto notc;
|
||||
}
|
||||
check:
|
||||
if(lookup(c) == 1){
|
||||
while((ch = buf[i++]) != ';' && ch != '{')if(i >= in)goto notc;
|
||||
printf("c program");
|
||||
goto outa;
|
||||
}
|
||||
nl = 0;
|
||||
while(buf[i] != '('){
|
||||
if(buf[i] <= 0){
|
||||
printf("data\n");
|
||||
goto out;
|
||||
}
|
||||
if(buf[i] == ';'){
|
||||
i++;
|
||||
goto check;
|
||||
}
|
||||
if(buf[i++] == '\n')
|
||||
if(nl++ > 6)goto notc;
|
||||
if(i >= in)goto notc;
|
||||
}
|
||||
while(buf[i] != ')'){
|
||||
if(buf[i++] == '\n')
|
||||
if(nl++ > 6)goto notc;
|
||||
if(i >= in)goto notc;
|
||||
}
|
||||
while(buf[i] != '{'){
|
||||
if(buf[i++] == '\n')
|
||||
if(nl++ > 6)goto notc;
|
||||
if(i >= in)goto notc;
|
||||
}
|
||||
printf("c program");
|
||||
goto outa;
|
||||
notc:
|
||||
i = 0;
|
||||
while(buf[i] == 'c' || buf[i] == '#'){
|
||||
while(buf[i++] != '\n')if(i >= in)goto notfort;
|
||||
}
|
||||
if(lookup(fort) == 1){
|
||||
printf("fortran");
|
||||
goto outa;
|
||||
}
|
||||
notfort:
|
||||
i=0;
|
||||
if(ascom() == 0)goto notas;
|
||||
j = i-1;
|
||||
if(buf[i] == '.'){
|
||||
i++;
|
||||
if(lookup(as) == 1){
|
||||
printf("assembler program");
|
||||
goto outa;
|
||||
}
|
||||
else if(buf[j] == '\n'){
|
||||
printf("roff, nroff, or eqn input");
|
||||
goto outa;
|
||||
}
|
||||
}
|
||||
while(lookup(asc) == 0){
|
||||
if(ascom() == 0)goto notas;
|
||||
while(buf[i] != '\n' && buf[i++] != ':')
|
||||
if(i >= in)goto notas;
|
||||
while(buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\t')if(i++ >= in)goto notas;
|
||||
j = i-1;
|
||||
if(buf[i] == '.'){
|
||||
i++;
|
||||
if(lookup(as) == 1){
|
||||
printf("assembler program");
|
||||
goto outa;
|
||||
}
|
||||
else if(buf[j] == '\n'){
|
||||
printf("roff, nroff, or eqn input");
|
||||
goto outa;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("assembler program");
|
||||
goto outa;
|
||||
notas:
|
||||
for(i=0; i < in; i++)if(buf[i] <= 0){
|
||||
printf("data\n");
|
||||
goto out;
|
||||
}
|
||||
if((mbuf[2] & 00111) != 0)
|
||||
printf("commands");
|
||||
else printf("probably text");
|
||||
outa:
|
||||
while(i < in)
|
||||
if(buf[i++] <= 0){
|
||||
printf(" with garbage\n");
|
||||
goto out;
|
||||
}
|
||||
while((in = read(ibuf[0],buf,512)) > 0)
|
||||
for(i = 0; i < in; i++)
|
||||
if(buf[i] <= 0){
|
||||
printf(" with garbage\n");
|
||||
goto out;
|
||||
}
|
||||
printf("\n");
|
||||
out:
|
||||
close(ibuf[0]);
|
||||
}
|
||||
lookup(tab)
|
||||
char *tab[];
|
||||
{
|
||||
char r;
|
||||
int k,j,l;
|
||||
while(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n')i++;
|
||||
for(j=0; tab[j] != 0; j++){
|
||||
l=0;
|
||||
for(k=i; ((r=tab[j][l++]) == buf[k] && r != '\0');k++);
|
||||
if(r == '\0')
|
||||
if(buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\t'
|
||||
|| buf[k] == '{' || buf[k] == '/'){
|
||||
i=k;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
ccom(){
|
||||
char cc;
|
||||
while((cc = buf[i]) == ' ' || cc == '\t' || cc == '\n')if(i++ >= in)return(0);
|
||||
if(buf[i] == '/' && buf[i+1] == '*'){
|
||||
i =+ 2;
|
||||
while(buf[i] != '*' || buf[i+1] != '/'){
|
||||
if(buf[i] == '\\')i =+ 2;
|
||||
else i++;
|
||||
if(i >= in)return(0);
|
||||
}
|
||||
if((i =+ 2) >= in)return(0);
|
||||
}
|
||||
if(buf[i] == '\n')if(ccom() == 0)return(0);
|
||||
return(1);
|
||||
}
|
||||
ascom(){
|
||||
while(buf[i] == '/'){
|
||||
i++;
|
||||
while(buf[i++] != '\n')if(i >= in)return(0);
|
||||
while(buf[i] == '\n')if(i++ >= in)return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
@@ -0,0 +1,449 @@
|
||||
/* find -- find files in a pathname.
|
||||
Use of find is documented in /usr/man/man1/find.1 .
|
||||
|
||||
In addition, find has a secret first arg "+" which
|
||||
causes each file name to be printed along with a period
|
||||
if the predicates succeed.
|
||||
*/
|
||||
int randlast;
|
||||
char *pathname;
|
||||
int verbose;
|
||||
struct anode {
|
||||
int (*F)();
|
||||
struct anode *L, *R;
|
||||
} node[100];
|
||||
int nn; /* number of nodes */
|
||||
char *fname, *path;
|
||||
int now[2];
|
||||
int ap, ac;
|
||||
char **av;
|
||||
|
||||
struct ibuf {
|
||||
int idev;
|
||||
int inum;
|
||||
int iflags;
|
||||
char inl;
|
||||
char iuid;
|
||||
char igid;
|
||||
char isize0;
|
||||
char *isize;
|
||||
int iaddr[8];
|
||||
int iatime[2];
|
||||
int imtime[2];
|
||||
} statb;
|
||||
|
||||
main(argc,argv) char *argv[]; {
|
||||
|
||||
struct anode *exlist;
|
||||
int find();
|
||||
|
||||
time(&now);
|
||||
ac = argc; av = argv; ap = 2;
|
||||
pathname = argv[1];
|
||||
if(compstr(argv[1],"+")==0) {
|
||||
verbose++;
|
||||
ap++;
|
||||
pathname = argv[2];
|
||||
} else verbose = 0;
|
||||
argv[argc] = 0;
|
||||
if(argc<3) {
|
||||
printf("Insufficient args\n");
|
||||
exit(9);
|
||||
}
|
||||
if(!(exlist = exp())) { /* parse and compile the arguments */
|
||||
printf("Odd usage\n");
|
||||
exit(9);
|
||||
}
|
||||
if(ap<argc) {
|
||||
printf("Missing conjunction\n");
|
||||
exit(9);
|
||||
}
|
||||
descend(pathname,'f',find,exlist); /* to find files that match */
|
||||
}
|
||||
|
||||
/* compile time functions: priority is exp()<e1()<e2()<e3() */
|
||||
|
||||
struct anode *exp() { /* parse -o ... */
|
||||
int or();
|
||||
int p1;
|
||||
char *na;
|
||||
p1 = e1() /* get left operand */ ;
|
||||
if(compstr(na=nxtarg(),"-o")==0) {
|
||||
randlast--;
|
||||
return(mk(&or,p1,exp()));
|
||||
}
|
||||
else if(*na!=0) --ap;
|
||||
return(p1);
|
||||
}
|
||||
struct anode *e1() { /* parse -a */
|
||||
int and();
|
||||
int p1;
|
||||
char *na;
|
||||
p1 = e2();
|
||||
if(compstr(na=nxtarg(),"-a")==0) {
|
||||
randlast--;
|
||||
return(mk(&and,p1,e1()));
|
||||
}
|
||||
else if(*na!=0) --ap;
|
||||
return(p1);
|
||||
}
|
||||
struct anode *e2() { /* parse not (!) */
|
||||
int not();
|
||||
char *na;
|
||||
if(randlast) {
|
||||
printf("operand follows operand.\n");
|
||||
exit(9);
|
||||
}
|
||||
randlast++;
|
||||
if(compstr(na=nxtarg(),"!")==0)
|
||||
return(mk(¬,e3(),0));
|
||||
else if(*na!=0) --ap;
|
||||
return(e3());
|
||||
}
|
||||
struct anode *e3() { /* parse parens and predicates */
|
||||
int exeq(), ok(), glob(), mtime(), atime(), user(),
|
||||
group(), size(), perm(), links(), print(),
|
||||
type();
|
||||
int p1, i;
|
||||
char *a, *b, s;
|
||||
a = nxtarg();
|
||||
if(compstr(a,"(")==0) {
|
||||
randlast--;
|
||||
p1 = exp();
|
||||
a = nxtarg();
|
||||
if(compstr(a,")")!=0) goto err;
|
||||
return(p1);
|
||||
}
|
||||
else if(compstr(a,"-print")==0) {
|
||||
return(mk(&print,0,0));
|
||||
}
|
||||
b = nxtarg();
|
||||
s = *b;
|
||||
if(s=='+') b++;
|
||||
if(compstr(a,"-name")==0)
|
||||
return(mk(&glob,b,0));
|
||||
else if(compstr(a,"-mtime")==0)
|
||||
return(mk(&mtime,atoi(b),s));
|
||||
else if(compstr(a,"-atime")==0)
|
||||
return(mk(&atime,atoi(b),s));
|
||||
else if(compstr(a,"-user")==0) {
|
||||
if((i=getunum(b)) == -1) {
|
||||
printf("Cannot find user \"%s\"\n",b);
|
||||
exit(9);
|
||||
}
|
||||
return(mk(&user,i,s));
|
||||
}
|
||||
else if(compstr(a,"-group")==0)
|
||||
return(mk(&group,atoi(b),s));
|
||||
else if(compstr(a,"-size")==0)
|
||||
return(mk(&size,atoi(b),s));
|
||||
else if(compstr(a,"-links")==0)
|
||||
return(mk(&links,atoi(b),s));
|
||||
else if(compstr(a,"-perm")==0) {
|
||||
for(i=0; *b ; ++b) {
|
||||
if(*b=='-') continue;
|
||||
i =<< 3;
|
||||
i = i + (*b - '0');
|
||||
}
|
||||
return(mk(&perm,i,s));
|
||||
}
|
||||
else if(compstr(a,"-type")==0) {
|
||||
i = s=='d' ? 040000 :
|
||||
s=='b' ? 060000 :
|
||||
s=='c' ? 020000 :
|
||||
000000;
|
||||
return(mk(&type,i,0));
|
||||
}
|
||||
else if (compstr(a,"-exec")==0) {
|
||||
i = ap - 1;
|
||||
while(compstr(nxtarg(),";")!=0);
|
||||
return(mk(&exeq,i,0));
|
||||
}
|
||||
else if (compstr(a,"-ok")==0) {
|
||||
i = ap - 1;
|
||||
while(compstr(nxtarg(),";")!=0);
|
||||
return(mk(&ok,i,0));
|
||||
}
|
||||
err: printf("Bad option: \"%s\" \"%s\"\n",a,b);
|
||||
exit(9);
|
||||
}
|
||||
struct anode *mk(f,l,r) struct anode *l,*r; { /*make an expression node*/
|
||||
node[nn].F = f;
|
||||
node[nn].L = l;
|
||||
node[nn].R = r;
|
||||
return(&(node[nn++]));
|
||||
}
|
||||
|
||||
nxtarg() { /* get next arg from command line */
|
||||
if(ap>=ac) return("");
|
||||
return(av[ap++]);
|
||||
}
|
||||
|
||||
find(exlist,fullname) /* execute predicat list with current file */
|
||||
struct anode *exlist;
|
||||
char *fullname;
|
||||
{
|
||||
register int i;
|
||||
path = fullname;
|
||||
if(verbose) printf("%s",path);
|
||||
for(i=0;fullname[i];++i)
|
||||
if(fullname[i]=='/') fname = &fullname[i+1];
|
||||
i = (*exlist->F)(exlist);
|
||||
if(verbose)
|
||||
if(i) printf(".\n");
|
||||
else printf("\n");
|
||||
}
|
||||
|
||||
/* execution time functions */
|
||||
and(p) struct anode *p; {
|
||||
return(((*p->L->F)(p->L)) && ((*p->R->F)(p->R))?1:0);
|
||||
}
|
||||
or(p) struct anode *p; {
|
||||
return(((*p->L->F)(p->L)) || ((*p->R->F)(p->R))?1:0);
|
||||
}
|
||||
not(p) struct anode *p; {
|
||||
return( !((*p->L->F)(p->L)));
|
||||
}
|
||||
glob(p) struct { int f; char *pat; } *p; {
|
||||
return(gmatch(fname,p->pat));
|
||||
}
|
||||
print() {
|
||||
printf("%s\n",path);
|
||||
return(1);
|
||||
}
|
||||
mtime(p) struct { int f, t, s; } *p; {
|
||||
return(scomp((now[0]-statb.imtime[0])*3/4,p->t,p->s));
|
||||
}
|
||||
atime(p) struct { int f, t, s; } *p; {
|
||||
return(scomp((now[0]-statb.iatime[0])*3/4,p->t,p->s));
|
||||
}
|
||||
user(p) struct { int f, u, s; } *p; {
|
||||
return(scomp(statb.iuid,p->u,p->s));
|
||||
}
|
||||
group(p) struct { int f, u; } *p; {
|
||||
return(p->u == statb.igid);
|
||||
}
|
||||
links(p) struct { int f, link, s; } *p; {
|
||||
return(scomp(statb.inl,p->link,p->s));
|
||||
}
|
||||
size(p) struct { int f, sz, s; } *p; {
|
||||
register int i;
|
||||
i = statb.isize0 << 7;
|
||||
i = i | ((statb.isize>>9) & 0177);
|
||||
return(scomp(i,p->sz,p->s));
|
||||
}
|
||||
perm(p) struct { int f, per, s; } *p; {
|
||||
int i;
|
||||
i = (p->s=='-') ? p->per : 03777; /* '-' means only arg bits */
|
||||
return((statb.iflags & i & 017777) == p->per);
|
||||
}
|
||||
type(p) struct { int f, per, s; } *p; {
|
||||
return((statb.iflags&060000)==p->per);
|
||||
}
|
||||
exeq(p) struct { int f, com; } *p; {
|
||||
return(doex(p->com));
|
||||
}
|
||||
ok(p) struct { int f, com; } *p; {
|
||||
char c; int yes;
|
||||
yes = 0;
|
||||
printf("%s ... %s ...? ",av[p->com],path);
|
||||
if((c=getchar())=='y') yes = 1;
|
||||
while(c!='\n') c = getchar();
|
||||
if(yes) return(doex(p->com));
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* support functions */
|
||||
scomp(a,b,s) char s; { /* funny signed compare */
|
||||
if(s == '+')
|
||||
return(a > b);
|
||||
if(s == '-')
|
||||
return(a < (b * -1));
|
||||
return(a == b);
|
||||
}
|
||||
doex(com) {
|
||||
int ccode;
|
||||
int np, i, c;
|
||||
char *nargv[50], *ncom, *na;
|
||||
|
||||
ccode = np = 0;
|
||||
while (na=av[com++]) {
|
||||
if(compstr(na,";")==0) break;
|
||||
if(compstr(na,"{}")==0) nargv[np++] = path;
|
||||
else nargv[np++] = na;
|
||||
}
|
||||
nargv[np] = 0;
|
||||
if (np==0) return(9);
|
||||
if(fork()) /*parent*/ wait(&ccode);
|
||||
else { /*child*/
|
||||
execv(nargv[0], nargv, np);
|
||||
i = 0;
|
||||
ncom = "/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
while(c=nargv[0][i]) {
|
||||
ncom[9+i++] = c;
|
||||
}
|
||||
ncom[9+i] = '\0';
|
||||
execv(ncom+4, nargv, np);
|
||||
execv(ncom, nargv, np);
|
||||
exit(9);
|
||||
}
|
||||
return(ccode ? 0:1);
|
||||
}
|
||||
|
||||
char fin[518];
|
||||
getunum(s) char *s; { /* find username in /etc/passwd & return num. */
|
||||
int i;
|
||||
char str[20], *sp, c;
|
||||
i = -1;
|
||||
fin[0] = open("/etc/passwd",0);
|
||||
while(c = getchar()) {
|
||||
if(c=='\n') {
|
||||
sp = str;
|
||||
while((*sp = getchar()) != ':')
|
||||
if(! *sp++) goto RET;
|
||||
*sp = '\0';
|
||||
if(compstr(str,s)==0) {
|
||||
while((c=getchar()) != ':')
|
||||
if(! c) goto RET;
|
||||
sp = str;
|
||||
while((*sp = getchar()) != ':') sp++;
|
||||
*sp = '\0';
|
||||
i = atoi(str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
RET:
|
||||
close(fin);
|
||||
fin[0] = 0;
|
||||
return(i);
|
||||
}
|
||||
|
||||
compstr(s1,s2) char s1[], s2[]; { /* compare strings: */
|
||||
register char *c1, *c2;
|
||||
c1 = s1; c2 = s2;
|
||||
while(*c1 == *c2)
|
||||
if(*c1++ == '\0')
|
||||
return(0); /* s1 == s2 */
|
||||
else c2++;
|
||||
return(*c1 > *c2 ? 1 : -1);
|
||||
}
|
||||
|
||||
int descend(name,goal,func,arg)
|
||||
int (*func)();
|
||||
char *name, goal;
|
||||
{
|
||||
int dir /* open directory */, offset /* in directory */;
|
||||
int dsize, top;
|
||||
struct {
|
||||
int dinode;
|
||||
char dname[14];
|
||||
} dentry[32];
|
||||
register int i, j, k;
|
||||
char aname[128];
|
||||
|
||||
if(stat(name,&statb)<0) {
|
||||
printf("--bad status %s\n",name);
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
if((statb.iflags&060000)!=040000){ /*not a directory*/
|
||||
/*
|
||||
if(goal=='f'||goal=='b') /* search goal for files */
|
||||
/*
|
||||
(*func)(arg,name);
|
||||
return(1);
|
||||
} else if(goal=='d' || goal=='b') /* search goal is directories */
|
||||
/*
|
||||
(*func)(arg,name);
|
||||
*/
|
||||
(*func)(arg,name);
|
||||
if((statb.iflags&060000)!=040000)
|
||||
return(1);
|
||||
|
||||
top = statb.isize;
|
||||
for(offset=0 ; offset < top ; offset =+ 512) { /* each block */
|
||||
dsize = 512<(top-offset) ? 512 : (top-offset);
|
||||
if((dir=open(name,0))<0) {
|
||||
printf("--cannot open %s\n",name);
|
||||
return(0);
|
||||
}
|
||||
if(offset) seek(dir,offset,0);
|
||||
if(read(dir,&dentry,dsize)<0) {
|
||||
printf("--cannot read %s\n",name);
|
||||
return(0);
|
||||
}
|
||||
close(dir);
|
||||
for(i = 0; i < (dsize>>4); ++i) { /* each dir. entry */
|
||||
if(dentry[i].dinode==0 ||
|
||||
compstr(dentry[i].dname,".")==0 ||
|
||||
compstr(dentry[i].dname,"..")==0)
|
||||
continue;
|
||||
if (dentry[i].dinode == -1) break;
|
||||
for(j=0;aname[j]=name[j];++j);
|
||||
if(aname[j-1]!='/') aname[j++] = '/';
|
||||
for(k=0; (aname[j++]=dentry[i].dname[k]) &&
|
||||
k<13; ++k);
|
||||
aname[j] = '\0';
|
||||
if(descend(aname,goal,func,arg)==0)
|
||||
printf("--%s\n",name);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
gmatch(s, p) /* string match as in glob */
|
||||
char *s, *p; {
|
||||
if (*s=='.' && *p!='.') return(0);
|
||||
return(amatch(s, p));
|
||||
}
|
||||
|
||||
amatch(s, p)
|
||||
char *s, *p;
|
||||
{
|
||||
register int cc, scc, k;
|
||||
int c, lc;
|
||||
|
||||
scc = *s;
|
||||
lc = 077777;
|
||||
switch (c = *p) {
|
||||
|
||||
case '[':
|
||||
k = 0;
|
||||
while (cc = *++p) {
|
||||
switch (cc) {
|
||||
|
||||
case ']':
|
||||
if (k)
|
||||
return(amatch(++s, ++p));
|
||||
else
|
||||
return(0);
|
||||
|
||||
case '-':
|
||||
k =| lc <= scc & scc <= (cc=p[1]);
|
||||
}
|
||||
if (scc==(lc=cc)) k++;
|
||||
}
|
||||
return(0);
|
||||
|
||||
case '?':
|
||||
caseq:
|
||||
if(scc) return(amatch(++s, ++p));
|
||||
return(0);
|
||||
case '*':
|
||||
return(umatch(s, ++p));
|
||||
case 0:
|
||||
return(!scc);
|
||||
}
|
||||
if (c==scc) goto caseq;
|
||||
return(0);
|
||||
}
|
||||
|
||||
umatch(s, p)
|
||||
char *s, *p;
|
||||
{
|
||||
if(*p==0) return(1);
|
||||
while(*s)
|
||||
if (amatch(s++,p)) return(1);
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
signal = 48.
|
||||
testing = 0
|
||||
/ form letter generator
|
||||
/ command sequence
|
||||
/ form proto arg1 arg2...
|
||||
/ where proto is letter
|
||||
rfo:
|
||||
sys signal; 2; int
|
||||
mov $-1,buf
|
||||
mov (sp)+,r2 /arg count
|
||||
tst (sp)+ /skip first arg
|
||||
sub $2,r2
|
||||
bge 2f
|
||||
mov $default,-(sp)
|
||||
2:
|
||||
mov (sp)+,letter
|
||||
|
||||
1: sys stat; otfil; buf
|
||||
bec 2f
|
||||
sys creat; otfil; 666
|
||||
bec cont
|
||||
2: cmpb $'z,otfil+4
|
||||
beq err3
|
||||
incb otfil+4
|
||||
br 1b
|
||||
|
||||
err3:
|
||||
mov $1,r0
|
||||
sys write; mes3; 24.
|
||||
sys exit
|
||||
mes3: <cannot open output file\n>
|
||||
otfil: <forma\0>
|
||||
default: <letter\0>
|
||||
.even
|
||||
|
||||
cont: mov r0,rfo
|
||||
clr rfo+2
|
||||
jsr pc,initl
|
||||
|
||||
/ set up argument list
|
||||
/
|
||||
mov $arg,r3
|
||||
mov $10.,r0
|
||||
jsr pc,allocate
|
||||
mov r1,(r3)+
|
||||
1:
|
||||
dec r2
|
||||
blt 1f
|
||||
mov $10.,r0
|
||||
jsr pc,allocate
|
||||
mov r1,(r3)+
|
||||
mov (sp)+,r4
|
||||
2:
|
||||
movb (r4)+,r0
|
||||
beq 1b
|
||||
jsr pc,putchar
|
||||
br 2b
|
||||
|
||||
1:
|
||||
sys time
|
||||
ashc $-7,r0
|
||||
div $675.,r0
|
||||
mov $daytab,r2
|
||||
sub $1461.,r0
|
||||
|
||||
1: sub (r2)+,r0
|
||||
bge 1b
|
||||
add -(r2),r0
|
||||
mov r0,-(sp)
|
||||
mov arg,r1
|
||||
mov montab-daytab(r2),r2
|
||||
1:
|
||||
movb (r2)+,r0
|
||||
beq 1f
|
||||
jsr pc,putchar
|
||||
br 1b
|
||||
1:
|
||||
movb $' ,r0
|
||||
jsr pc,putchar
|
||||
clr r0
|
||||
mov (sp),r1
|
||||
inc r1
|
||||
div $10.,r0
|
||||
mov r1,(sp)
|
||||
mov arg,r1
|
||||
tst r0
|
||||
beq 1f
|
||||
add $'0,r0
|
||||
jsr pc,putchar
|
||||
1:
|
||||
mov (sp)+,r0
|
||||
add $'0,r0
|
||||
jsr pc,putchar
|
||||
jmp loop
|
||||
|
||||
daytab: 31.; 28.; 31.; 30.; 31.; 30.; 31.; 31.; 30.; 31.; 30.; 999.
|
||||
|
||||
montab: m1; m2; m3; m4; m5; m6; m7; m8; m9; m10; m11; m12
|
||||
|
||||
m1: <January\0>
|
||||
m2: <February\0>
|
||||
m3: <March\0>
|
||||
m4: <April\0>
|
||||
m5: <May\0>
|
||||
m6: <June\0>
|
||||
m7: <July\0>
|
||||
m8: <August\0>
|
||||
m9: <September\0>
|
||||
m10: <October\0>
|
||||
m11: <November\0>
|
||||
m12: <December\0>
|
||||
|
||||
buf: .=.+34.
|
||||
.=rfo+516.
|
||||
|
||||
loop:
|
||||
mov $10.,r0
|
||||
jsr pc,allocate
|
||||
mov r1,opointer
|
||||
jsr pc,allocate
|
||||
mov r1,ipointer
|
||||
jsr pc,allocate
|
||||
mov r1,curly
|
||||
mov $10.,r0
|
||||
jsr pc,allocate
|
||||
mov r1,scr
|
||||
mov letter,r3
|
||||
movb $'\{,r0
|
||||
jsr pc,putchar
|
||||
1:
|
||||
movb (r3)+,r0
|
||||
beq 1f
|
||||
jsr pc,putchar
|
||||
br 1b
|
||||
1:
|
||||
movb $'\},r0
|
||||
jsr pc,putchar
|
||||
|
||||
clr switch
|
||||
|
||||
tst iflag
|
||||
beq 1f
|
||||
mov $1,tflag
|
||||
jmp interrupt
|
||||
1:
|
||||
jsr pc,scan
|
||||
|
||||
movb $'\n,r0
|
||||
jsr r5,putc
|
||||
jsr r5,flushb
|
||||
|
||||
mov scr,r1
|
||||
jsr pc,release
|
||||
jsr pc,relarg
|
||||
mov opointer,r1
|
||||
jsr pc,release
|
||||
mov ipointer,r1
|
||||
jsr pc,release
|
||||
jsr pc,relcurl
|
||||
jsr pc,flush
|
||||
jsr pc,whead
|
||||
.if testing
|
||||
4
|
||||
.endif
|
||||
sys exit
|
||||
@@ -0,0 +1,92 @@
|
||||
/ scan
|
||||
/ r1 = pointer to input header
|
||||
/ r0 = pointer to output header
|
||||
/ switch = 0 real output
|
||||
/ not 0 output to r0
|
||||
scan:
|
||||
mov r0,-(sp)
|
||||
mov r1,-(sp)
|
||||
|
||||
1:
|
||||
mov (sp),r1
|
||||
jsr pc,getchar
|
||||
bes 5f
|
||||
cmpb r0,$'\\
|
||||
beq 3f
|
||||
cmpb r0,$'\[
|
||||
beq 4f
|
||||
cmpb r0,$'\{
|
||||
beq 4f
|
||||
cmpb r0,$'\]
|
||||
beq 1f
|
||||
cmpb r0,$'\}
|
||||
beq 7f
|
||||
cmpb r0,$'\n
|
||||
bne 6f
|
||||
jsr pc,lookchar
|
||||
bes 5f
|
||||
movb $'\n,r0
|
||||
6:
|
||||
tst switch
|
||||
beq 2f
|
||||
mov 2(sp),r1
|
||||
jsr pc,putchar
|
||||
br 1b
|
||||
2:
|
||||
jsr r5,putc
|
||||
br 1b
|
||||
3:
|
||||
jsr pc,getchar
|
||||
br 6b
|
||||
/ have [ or {
|
||||
4:
|
||||
mov r(r1),-(sp)
|
||||
jsr pc,getchar
|
||||
bes 1f
|
||||
cmpb r0,$'0
|
||||
blt 4f
|
||||
cmpb r0,$'9
|
||||
bgt 4f
|
||||
jsr pc,getchar
|
||||
cmpb r0,$'\]
|
||||
beq 3f
|
||||
cmpb r0,$'\}
|
||||
beq 3f
|
||||
|
||||
4:
|
||||
mov (sp)+,r(r1)
|
||||
mov 2(sp),r0
|
||||
jsr pc,esub
|
||||
mov r1,(sp)
|
||||
mov r0,2(sp)
|
||||
br 1b
|
||||
|
||||
/ have arg
|
||||
3:
|
||||
tst switch
|
||||
beq 2f
|
||||
mov opointer,r1
|
||||
mov 4(sp),r0
|
||||
jsr pc,putword
|
||||
mov 2(sp),r1
|
||||
2:
|
||||
mov (sp)+,r(r1)
|
||||
jsr pc,getchar
|
||||
inc r(r1) /skip ]
|
||||
jsr pc,earg
|
||||
br 1b
|
||||
|
||||
5:
|
||||
tst argf
|
||||
bne 1f
|
||||
mov ipointer,r1
|
||||
jsr pc,pop
|
||||
bes 1f
|
||||
mov r0,(sp)
|
||||
br 1b
|
||||
7:
|
||||
inc curlyf
|
||||
1:
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
@@ -0,0 +1,147 @@
|
||||
/ esub
|
||||
/ r1 = pointer to input string
|
||||
/
|
||||
esub:
|
||||
mov r1,-(sp)
|
||||
tst switch
|
||||
beq 1f
|
||||
mov opointer,r1
|
||||
jsr pc,putword
|
||||
1:
|
||||
tst iflag
|
||||
beq 1f
|
||||
mov $2,tflag
|
||||
jmp interrupt
|
||||
1:
|
||||
inc switch
|
||||
mov $10.,r0
|
||||
jsr pc,allocate
|
||||
mov r1,r0
|
||||
mov opointer,r1
|
||||
jsr pc,putword
|
||||
mov (sp)+,r1
|
||||
jsr pc,scan
|
||||
|
||||
tst iflag
|
||||
beq 1f
|
||||
mov $3,tflag
|
||||
jmp interrupt
|
||||
1:
|
||||
mov r2,-(sp)
|
||||
mov r1,r0
|
||||
mov ipointer,r1
|
||||
jsr pc,putword
|
||||
mov opointer,r1
|
||||
jsr pc,pop
|
||||
bec 9f; 4; 9:
|
||||
mov r0,-(sp) /last output
|
||||
mov asmem,r1
|
||||
jsr pc,getsp
|
||||
bes 2f
|
||||
5:
|
||||
clr curlyf
|
||||
mov (sp),r1
|
||||
mov r0,r2
|
||||
jsr pc,release
|
||||
6:
|
||||
mov opointer,r1
|
||||
jsr pc,pop
|
||||
bec 4f
|
||||
clr switch
|
||||
4: mov r2,r1
|
||||
jsr pc,rewind
|
||||
tst (sp)+
|
||||
mov (sp)+,r2
|
||||
rts pc
|
||||
|
||||
|
||||
/ not in memory
|
||||
2:
|
||||
mov curly,r1
|
||||
jsr pc,getsp
|
||||
bes 2f
|
||||
br 5b
|
||||
2:
|
||||
mov (sp),r1
|
||||
jsr pc,rewind
|
||||
mov $'\[,r0
|
||||
1:
|
||||
jsr r5,tfoput
|
||||
jsr pc,getchar
|
||||
bec 1b
|
||||
mov $'\],r0
|
||||
jsr r5,tfoput
|
||||
mov $10.,r0
|
||||
jsr pc,allocate
|
||||
mov r1,r2
|
||||
mov (sp),r0
|
||||
tst curlyf
|
||||
beq 1f
|
||||
clr curlyf
|
||||
mov curly,r1
|
||||
jsr pc,addentry
|
||||
br 2f
|
||||
1:
|
||||
mov asmem,r1
|
||||
jsr pc,whead
|
||||
jsr pc,addentry
|
||||
2:
|
||||
mov r2,r1
|
||||
jsr pc,accept
|
||||
br 6b
|
||||
/
|
||||
/
|
||||
/ earg
|
||||
/ r0 = number in ascii
|
||||
/
|
||||
earg:
|
||||
tst iflag
|
||||
beq 1f
|
||||
mov $4,tflag
|
||||
jmp interrupt
|
||||
1:
|
||||
mov r1,-(sp)
|
||||
inc argf
|
||||
sub $'0,r0
|
||||
asl r0
|
||||
mov arg(r0),r1
|
||||
beq 5f
|
||||
4:
|
||||
mov (sp),r0
|
||||
mov r1,(sp)
|
||||
mov ipointer,r1
|
||||
jsr pc,putword
|
||||
mov opointer,r1
|
||||
jsr pc,pop
|
||||
bec 3f
|
||||
clr switch
|
||||
3:
|
||||
mov (sp)+,r1
|
||||
jsr pc,rewind
|
||||
jsr pc,scan
|
||||
mov r0,-(sp)
|
||||
mov ipointer,r1
|
||||
jsr pc,pop
|
||||
bec 9f; 4; 9:
|
||||
mov r0,r1
|
||||
clr argf
|
||||
clr curlyf
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
5:
|
||||
mov r0,-(sp)
|
||||
mov $'\[,r0
|
||||
jsr r5,tfoput
|
||||
mov (sp),r0
|
||||
asr r0
|
||||
add $'0,r0
|
||||
jsr r5,tfoput
|
||||
mov $'\],r0
|
||||
jsr r5,tfoput
|
||||
mov $10.,r0
|
||||
jsr pc,allocate
|
||||
mov (sp)+,r0
|
||||
mov r1,arg(r0)
|
||||
jsr pc,accept
|
||||
|
||||
br 4b
|
||||
@@ -0,0 +1,250 @@
|
||||
rti = 2
|
||||
/ accept
|
||||
/ r1 = header of where to put it
|
||||
/
|
||||
accept:
|
||||
mov r0,-(sp)
|
||||
movb $':,r0
|
||||
jsr r5,tfoput
|
||||
movb $' ,r0
|
||||
jsr r5,tfoput
|
||||
2:
|
||||
jsr r5,tfiget
|
||||
cmpb r0,$'\n
|
||||
beq 1f
|
||||
jsr pc,putchar
|
||||
br 2b
|
||||
1:
|
||||
jsr pc,putchar
|
||||
jsr r5,tfiget
|
||||
cmpb r0,$'\n
|
||||
beq 1f
|
||||
jsr pc,putchar
|
||||
br 2b
|
||||
1:
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to get the last word from the string
|
||||
/ r1=header addr
|
||||
/
|
||||
pop:
|
||||
jsr pc,fsfile
|
||||
jsr pc,backword
|
||||
bes 1f
|
||||
sub $2,w(r1)
|
||||
1:
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to add an entry to assoc mem or curly
|
||||
/ r1 = header
|
||||
/ r0 = header of string name
|
||||
/ r2 = header of string
|
||||
/
|
||||
addentry:
|
||||
jsr pc,putword
|
||||
mov r2,r0
|
||||
jsr pc,putword
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to find the string pointed to by r0
|
||||
/ in either memory or curly
|
||||
/ r1 = where to look
|
||||
/
|
||||
/ returns error set if string not there
|
||||
/ returns r1 = header of string if there
|
||||
/
|
||||
getsp:
|
||||
mov r0,-(sp)
|
||||
mov r1,-(sp)
|
||||
jsr pc,rewind /memory
|
||||
3:
|
||||
mov 2(sp),r1
|
||||
jsr pc,rewind /output
|
||||
mov (sp),r1
|
||||
jsr pc,getword
|
||||
bes 1f
|
||||
mov r0,r1
|
||||
mov r0,-(sp)
|
||||
jsr pc,rewind /string
|
||||
2:
|
||||
mov (sp),r1
|
||||
jsr pc,getchar
|
||||
bes 2f
|
||||
movb r0,r2
|
||||
mov 4(sp),r1
|
||||
jsr pc,getchar
|
||||
bes 4f
|
||||
cmpb r0,r2
|
||||
beq 2b
|
||||
4:
|
||||
tst (sp)+
|
||||
4:
|
||||
mov (sp),r1
|
||||
add $2,r(r1)
|
||||
br 3b
|
||||
2:
|
||||
tst (sp)+
|
||||
mov 2(sp),r1
|
||||
cmp r(r1),w(r1)
|
||||
bne 4b
|
||||
mov (sp)+,r1
|
||||
jsr pc,getword
|
||||
tst (sp)+
|
||||
rts pc
|
||||
1:
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r0
|
||||
sec
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ tfoput
|
||||
/
|
||||
/ jsr r5,tfoput
|
||||
/
|
||||
tfoput:
|
||||
mov r0,ch
|
||||
mov $1,r0
|
||||
sys write; ch; 1
|
||||
rts r5
|
||||
/
|
||||
/
|
||||
/ tfiget
|
||||
/
|
||||
/ jsr r5,tfiget
|
||||
/
|
||||
tfiget:
|
||||
clr r0
|
||||
sys read; ch; 1
|
||||
bes 1f
|
||||
tst r0
|
||||
beq 1f
|
||||
movb ch,r0
|
||||
rts r5
|
||||
1:
|
||||
jsr r5,flushb
|
||||
tst argf
|
||||
beq 1f
|
||||
mov opointer,r1
|
||||
jsr pc,pop
|
||||
1:
|
||||
mov $5,tflag
|
||||
jmp interrupt
|
||||
/
|
||||
/ putc
|
||||
/ jsr r5,putc
|
||||
/
|
||||
putc:
|
||||
mov r1,-(sp)
|
||||
mov r2,-(sp)
|
||||
mov $rfo+2,r1
|
||||
mov r1,r2
|
||||
add (r1),r2
|
||||
movb r0,2(r2)
|
||||
inc (r1)
|
||||
cmp (r1),$512.
|
||||
bge 1f
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r1
|
||||
rts r5
|
||||
1:
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r1
|
||||
/
|
||||
/
|
||||
/ flush output buffer to output file.
|
||||
/
|
||||
flushb:
|
||||
mov r1,-(sp)
|
||||
mov r0,-(sp)
|
||||
mov $rfo,r1
|
||||
mov (r1)+,r0
|
||||
mov (r1),0f+2
|
||||
beq 1f
|
||||
clr (r1)+
|
||||
mov r1,0f
|
||||
sys write; 0:..;..
|
||||
1:
|
||||
mov (sp)+,r0
|
||||
mov (sp)+,r1
|
||||
rts r5
|
||||
relarg:
|
||||
mov $arg,r2
|
||||
1:
|
||||
mov (r2)+,r1
|
||||
beq 2f
|
||||
jsr pc,release
|
||||
br 1b
|
||||
2:
|
||||
cmp r2,$arge
|
||||
blt 1b
|
||||
rts pc
|
||||
/
|
||||
relcurl:
|
||||
mov curly,r1
|
||||
jsr pc,rewind
|
||||
1:
|
||||
jsr pc,getword
|
||||
bes 1f
|
||||
mov r0,r1
|
||||
jsr pc,release
|
||||
mov curly,r1
|
||||
br 1b
|
||||
1:
|
||||
jsr pc,release
|
||||
rts pc
|
||||
/
|
||||
int:
|
||||
inc iflag
|
||||
rti
|
||||
/
|
||||
interrupt:
|
||||
jsr pc,relarg
|
||||
tst opointer
|
||||
beq 2f
|
||||
1:
|
||||
mov opointer,r1
|
||||
jsr pc,rewind
|
||||
1:
|
||||
jsr pc,getword
|
||||
bes 1f
|
||||
mov r0,r1
|
||||
jsr pc,release
|
||||
mov opointer,r1
|
||||
br 1b
|
||||
1:
|
||||
mov opointer,r1
|
||||
jsr pc,release
|
||||
tst ipointer
|
||||
beq 2f
|
||||
mov ipointer,r1
|
||||
jsr pc,release
|
||||
tst curly
|
||||
beq 2f
|
||||
jsr pc,relcurl
|
||||
tst scr
|
||||
beq 2f
|
||||
mov scr,r1
|
||||
jsr pc,release
|
||||
2:
|
||||
jsr pc,flush
|
||||
jsr pc,whead
|
||||
sys exit
|
||||
letter: .=.+2
|
||||
arg: .=.+20.
|
||||
arge: 0
|
||||
argf: .=.+2
|
||||
switch: .=.+2
|
||||
curly: .=.+2
|
||||
curlyf: .=.+2
|
||||
ch: .=.+2
|
||||
opointer: .=.+2
|
||||
ipointer: .=.+2
|
||||
scr: .=.+2
|
||||
iflag: 0
|
||||
tflag: 0
|
||||
end:
|
||||
@@ -0,0 +1,741 @@
|
||||
.globl b1
|
||||
.globl hblk
|
||||
.globl headers
|
||||
.globl initl
|
||||
.globl asmem
|
||||
.globl b1s
|
||||
.globl b1e
|
||||
.globl w1
|
||||
.globl stats
|
||||
.globl lookchar
|
||||
.globl flush
|
||||
.globl fsfile
|
||||
.globl seekchar
|
||||
.globl backspace
|
||||
.globl alterchar
|
||||
.globl zero
|
||||
.globl getchar
|
||||
.globl putchar
|
||||
.globl copy
|
||||
.globl rewind
|
||||
.globl create
|
||||
.globl allocate
|
||||
.globl release
|
||||
.globl collect
|
||||
.globl w,r,a,l
|
||||
.globl getword
|
||||
.globl putword
|
||||
.globl backword
|
||||
.globl alterword
|
||||
/
|
||||
/
|
||||
/ routine to read next character from string
|
||||
/ pointer to by r1; character returned in r0
|
||||
/ c-bit set if character not availiable (eof)
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,getchar
|
||||
/ movb r0,...
|
||||
/
|
||||
getchar:
|
||||
jsr pc,lookchar
|
||||
bes 1f
|
||||
inc r(r1)
|
||||
tst r0 /clears c-bit
|
||||
1: rts pc
|
||||
/
|
||||
/
|
||||
/ routine to read a string backwards
|
||||
/ the read pointer is decremented before reading
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,backspace
|
||||
/ mov r0,...
|
||||
/
|
||||
backspace:
|
||||
cmp a(r1),r(r1)
|
||||
bhis nochc
|
||||
dec r(r1)
|
||||
jsr pc,lookchar
|
||||
rts pc
|
||||
nochc: clr r0
|
||||
sec
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to put a word onto the string
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ mov ...,r0
|
||||
/ jsr pc,putword
|
||||
/
|
||||
putword:
|
||||
mov r0,-(sp)
|
||||
sub $hblk,r0
|
||||
jsr pc,putchar
|
||||
swab r0
|
||||
jsr pc,putchar
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to get a word from the string
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,getword
|
||||
/ mov r0,...
|
||||
/
|
||||
getword:
|
||||
jsr pc,lookchar
|
||||
bes 1f
|
||||
movb r0,nchar
|
||||
inc r(r1)
|
||||
jsr pc,lookchar
|
||||
bes 1f
|
||||
movb r0,nchar+1
|
||||
inc r(r1)
|
||||
mov nchar,r0
|
||||
add $hblk,r0
|
||||
1: rts pc
|
||||
/
|
||||
/
|
||||
/ routine to alter the word pointed to by r(r1)
|
||||
/ by replacing the word there with r0
|
||||
/
|
||||
/ mov wd,r0
|
||||
/ mov ...,r1
|
||||
/ jsr pc,alterword
|
||||
/
|
||||
alterword:
|
||||
mov r0,-(sp)
|
||||
sub $hblk,r0
|
||||
jsr pc,alterchar
|
||||
swab r0
|
||||
jsr pc,alterchar
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to get words backwards from string
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,backword
|
||||
/ mov r0,...
|
||||
/
|
||||
backword:
|
||||
cmp a(r1),r(r1)
|
||||
bhis nochw
|
||||
dec r(r1)
|
||||
jsr pc,lookchar
|
||||
movb r0,nchar+1
|
||||
cmp a(r1),r(r1)
|
||||
bhis nochw
|
||||
dec r(r1)
|
||||
jsr pc,lookchar
|
||||
movb r0,nchar
|
||||
mov nchar,r0
|
||||
add $hblk,r0
|
||||
rts pc
|
||||
/
|
||||
nochw:
|
||||
clr r0
|
||||
sec
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to copy the contents of one string
|
||||
/ to another.
|
||||
/
|
||||
/ mov source,r0
|
||||
/ mov dest,r1
|
||||
/ jsr pc,copy
|
||||
/ mov r1,...
|
||||
/
|
||||
/ on return, r1 points to the new string and should
|
||||
/ be saved. r0 is preserved.
|
||||
/
|
||||
copy:
|
||||
inc stats+12.
|
||||
mov r0,-(sp)
|
||||
mov r1,-(sp)
|
||||
mov r2,-(sp)
|
||||
mov r3,-(sp)
|
||||
mov w(r0),r2
|
||||
sub a(r0),r2 /W-A (old)
|
||||
mov l(r1),r3
|
||||
sub a(r1),r3 /L-A (new)
|
||||
cmp r2,r3
|
||||
blos 1f
|
||||
mov r2,r0
|
||||
jsr pc,allocate
|
||||
mov 4(sp),r0 /new
|
||||
jsr pc,swap
|
||||
jsr pc,release
|
||||
mov r0,r1
|
||||
mov 0(sp),r0 /old
|
||||
1:
|
||||
mov a(r1),w(r1) /rewind w pointer
|
||||
cmp r2,$512.
|
||||
blos copy1 /is a short string
|
||||
/
|
||||
jsr pc,flush
|
||||
jsr pc,reset
|
||||
/
|
||||
mov a(r0),-(sp)
|
||||
4:
|
||||
mov (sp),0f
|
||||
mov afi,r0
|
||||
sys seek;0:.. ;0 /set input pointer
|
||||
cmp r2,$512.
|
||||
blos 2f
|
||||
mov $512.,r3 /# output this time
|
||||
mov r3,0f
|
||||
mov r3,3f
|
||||
add r3,(sp)
|
||||
sub r3,r2 /# left to output
|
||||
br 1f
|
||||
2:
|
||||
mov r2,0f
|
||||
mov r2,3f
|
||||
mov r2,r3
|
||||
clr r2
|
||||
1:
|
||||
mov afi,r0
|
||||
sys read;b1;0:..
|
||||
bes bad
|
||||
cmp r0,r3
|
||||
bne bad
|
||||
mov afout,r0
|
||||
mov (r1),0f
|
||||
add r3,(r1)
|
||||
sys seek;0:.. ;0
|
||||
sys write;b1;3:..
|
||||
bes bad
|
||||
tst r2
|
||||
bgt 4b
|
||||
tst (sp)+
|
||||
/
|
||||
/ fix up read ptr of new string
|
||||
/
|
||||
copy2:
|
||||
mov 6(sp),r0 /restore r0
|
||||
mov r(r0),r2
|
||||
sub a(r0),r2
|
||||
add a(r1),r2
|
||||
mov r2,r(r1)
|
||||
/
|
||||
/ restore and return
|
||||
/
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
bad: mov $1,r0
|
||||
sys write;1f;2f-1f
|
||||
4
|
||||
1: <error on copy\n>
|
||||
2: .even
|
||||
/
|
||||
swap:
|
||||
mov w(r1),-(sp)
|
||||
mov w(r0),w(r1)
|
||||
mov (sp),w(r0)
|
||||
mov r(r1),(sp)
|
||||
|
||||
mov r(r0),r(r1)
|
||||
mov (sp),r(r0)
|
||||
mov a(r1),(sp)
|
||||
mov a(r0),a(r1)
|
||||
mov (sp),a(r0)
|
||||
mov l(r1),(sp)
|
||||
mov l(r0),l(r1)
|
||||
mov (sp)+,l(r0)
|
||||
rts pc
|
||||
/
|
||||
/ copy a short string
|
||||
/
|
||||
copy1:
|
||||
mov r(r0),-(sp)
|
||||
mov a(r0),r(r0)
|
||||
mov nchar,-(sp)
|
||||
mov r0,r2 /old
|
||||
mov r1,r3 /new
|
||||
1:
|
||||
mov r2,r1
|
||||
jsr pc,getchar
|
||||
bes 1f
|
||||
mov r3,r1
|
||||
jsr pc,putchar
|
||||
br 1b
|
||||
1:
|
||||
mov r2,r0
|
||||
mov (sp)+,nchar
|
||||
mov (sp)+,r(r0)
|
||||
mov r3,r1
|
||||
br copy2
|
||||
/
|
||||
/
|
||||
/
|
||||
/
|
||||
/
|
||||
/ routine to rewind read pointer of string
|
||||
/ pointed to by r1
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,rewind
|
||||
/
|
||||
rewind:
|
||||
mov a(r1),r(r1)
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to rewind write pointer of string
|
||||
/ pointed to by r1
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,create
|
||||
/
|
||||
create:
|
||||
mov a(r1),w(r1)
|
||||
mov a(r1),r(r1)
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to zero a string
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,zero
|
||||
/
|
||||
zero:
|
||||
mov r0,-(sp)
|
||||
.if testing
|
||||
jsr pc,preposterous
|
||||
.endif
|
||||
mov a(r1),w(r1)
|
||||
clrb r0
|
||||
1: cmp w(r1),l(r1)
|
||||
bhis 1f
|
||||
jsr pc,putchar
|
||||
br 1b
|
||||
1: mov a(r1),w(r1)
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/
|
||||
/ routine to move the read pointer of a string to the
|
||||
/ relative position indicated by r0. the string is
|
||||
/ extended if necessary - there is no error return.
|
||||
/
|
||||
/ mov position,r0
|
||||
/ mov ...,r1
|
||||
/ jsr pc,seekchar
|
||||
/
|
||||
seekchar:
|
||||
mov r1,-(sp)
|
||||
mov r0,-(sp)
|
||||
.if testing
|
||||
jsr pc,preposterous
|
||||
.endif
|
||||
inc stats+10.
|
||||
1:
|
||||
mov (sp),r0
|
||||
add a(r1),r0
|
||||
cmp r0,l(r1)
|
||||
bhi 3f
|
||||
mov r0,r(r1)
|
||||
cmp r0,w(r1)
|
||||
blo 1f
|
||||
mov r0,w(r1)
|
||||
br 1f
|
||||
3:
|
||||
mov (sp),r0
|
||||
jsr pc,allocate
|
||||
mov 2(sp),r0
|
||||
jsr pc,copy
|
||||
jsr pc,swap
|
||||
jsr pc,release
|
||||
mov 2(sp),r1
|
||||
br 1b
|
||||
1:
|
||||
mov (sp)+,r0
|
||||
mov (sp)+,r1
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to move read pointer of string to end of string
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,fsfile
|
||||
/
|
||||
fsfile:
|
||||
mov r0,-(sp)
|
||||
.if testing
|
||||
jsr pc,preposterous
|
||||
.endif
|
||||
inc stats+10.
|
||||
mov w(r1),r(r1)
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to place the character in r0 at the current
|
||||
/ position of the read pointer - the read pointer
|
||||
/ is not moved.
|
||||
/
|
||||
/ movb ch,r0
|
||||
/ mov ...,r1
|
||||
/ jsr pc,alterchar
|
||||
/ mov r1,...
|
||||
/
|
||||
alterchar:
|
||||
mov r2,-(sp)
|
||||
mov r1,-(sp)
|
||||
mov r0,nchar
|
||||
.if testing
|
||||
jsr pc,preposterous
|
||||
.endif
|
||||
inc stats+8.
|
||||
1: cmp r(r1),l(r1) /W,L
|
||||
blo 3f
|
||||
mov l(r1),r0
|
||||
inc r0
|
||||
sub a(r1),r0 /W-A+1
|
||||
jsr pc,allocate
|
||||
mov (sp),r0
|
||||
jsr pc,copy
|
||||
jsr pc,swap
|
||||
jsr pc,release
|
||||
mov (sp),r1
|
||||
3:
|
||||
mov r(r1),r0
|
||||
jsr pc,bufchar
|
||||
bec 2f
|
||||
jsr pc,getbuf
|
||||
|
||||
2: movb nchar,(r0)
|
||||
mov $1,w1(r2)
|
||||
mov nchar,r0 /to preserve r0 for user
|
||||
inc r(r1)
|
||||
cmp r(r1),w(r1)
|
||||
blos 3f
|
||||
mov r(r1),w(r1)
|
||||
3:
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r2
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to look at next character from string
|
||||
/ pointed to by r1; character returned in r0
|
||||
/ c-bit set if character not available (end of file)
|
||||
/ r1 is preserved
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,lookchar
|
||||
/ movb r0,...
|
||||
/
|
||||
lookchar:
|
||||
mov r2,-(sp)
|
||||
inc stats+6.
|
||||
.if testing
|
||||
jsr pc,preposterous
|
||||
.endif
|
||||
cmp w(r1),r(r1) /W,R
|
||||
blos noch
|
||||
mov r(r1),r0
|
||||
jsr pc,bufchar
|
||||
bec 2f
|
||||
jsr pc,getbuf
|
||||
/
|
||||
2:
|
||||
inc flag
|
||||
bne 2f
|
||||
jsr pc,fixct
|
||||
br 1f
|
||||
2:
|
||||
mov flag,u1(r2)
|
||||
1:
|
||||
mov (sp)+,r2
|
||||
movb (r0),r0
|
||||
tst r0 /clears c-bit
|
||||
rts pc
|
||||
/
|
||||
noch:
|
||||
mov (sp)+,r2
|
||||
clr r0
|
||||
sec
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to put a character into the string
|
||||
/ pointed to by r1; character in r0
|
||||
/ r0 is preserved; r1 points to the string
|
||||
/ after return and must be saved.
|
||||
/
|
||||
/ movb ch,r0
|
||||
/ mov ...,r1
|
||||
/ jsr pc,putchar
|
||||
/ mov r1,...
|
||||
/
|
||||
putchar:
|
||||
mov r2,-(sp)
|
||||
mov r1,-(sp)
|
||||
mov r0,nchar
|
||||
.if testing
|
||||
jsr pc,preposterous
|
||||
.endif
|
||||
inc stats+8.
|
||||
1: cmp w(r1),l(r1) /W,L
|
||||
blo 3f
|
||||
mov w(r1),r0
|
||||
inc r0
|
||||
sub a(r1),r0 /W-A+1
|
||||
jsr pc,allocate
|
||||
mov (sp),r0
|
||||
jsr pc,copy
|
||||
jsr pc,swap
|
||||
jsr pc,release
|
||||
mov (sp),r1
|
||||
3:
|
||||
mov w(r1),r0
|
||||
jsr pc,bufchar
|
||||
bec 2f
|
||||
jsr pc,getbuf
|
||||
2: movb nchar,(r0)
|
||||
mov $1,w1(r2)
|
||||
mov nchar,r0 /to preserve r0 for user
|
||||
inc w(r1)
|
||||
inc flag
|
||||
bne 2f
|
||||
jsr pc,fixct
|
||||
br 1f
|
||||
2:
|
||||
mov flag,u1(r2)
|
||||
1:
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r2
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to flush contents of all buffers.
|
||||
/
|
||||
/ jsr pc,flush
|
||||
/
|
||||
flush:
|
||||
mov r1,-(sp)
|
||||
mov r2,-(sp)
|
||||
mov r3,-(sp)
|
||||
clr r3
|
||||
1:
|
||||
cmp r3,$numb
|
||||
bhis 1f
|
||||
mov r3,r2
|
||||
asl r2
|
||||
tst w1(r2)
|
||||
ble 2f
|
||||
mov r3,r1
|
||||
ashc $9.,r1
|
||||
bic $777,r1
|
||||
add $b1,r1
|
||||
jsr pc,clean
|
||||
2:
|
||||
inc r3
|
||||
br 1b
|
||||
1:
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r1
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
reset:
|
||||
mov r3,-(sp)
|
||||
mov r2,-(sp)
|
||||
clr r3
|
||||
1:
|
||||
cmp r3,$numb
|
||||
bge 1f
|
||||
mov r3,r2
|
||||
asl r2
|
||||
mov $-1.,w1(r2)
|
||||
clr b1s(r2)
|
||||
clr b1e(r2)
|
||||
clr u1(r2)
|
||||
inc r3
|
||||
br 1b
|
||||
1:
|
||||
clr flag
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r3
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to read from disc to a buffer
|
||||
/ wcing the buffer if necessary
|
||||
/
|
||||
/ mov disc addr,r0
|
||||
/ mov buffer addr,r2
|
||||
/ jsr pc,getb
|
||||
/
|
||||
/ on return r0 = addr of byte in buffer
|
||||
/
|
||||
getb:
|
||||
mov r3,-(sp)
|
||||
mov r1,-(sp)
|
||||
mov r0,-(sp)
|
||||
mov r2,r3
|
||||
asr r3
|
||||
mov r3,r1
|
||||
ashc $9.,r1
|
||||
bic $777,r1
|
||||
add $b1,r1
|
||||
tst w1(r2) / w
|
||||
ble 1f
|
||||
|
||||
jsr pc,clean
|
||||
|
||||
1: mov (sp),r0
|
||||
bic $777,r0 /get lowest multiple of 512.
|
||||
mov r0,0f
|
||||
mov r0,b1s(r2) /set start
|
||||
mov afi,r0
|
||||
sys seek;0:..;0
|
||||
mov r1,0f
|
||||
sys read;0:..;512.
|
||||
|
||||
mov b1s(r2),b1e(r2)
|
||||
add $512.,b1e(r2) / set end
|
||||
clr w1(r2) /clear w
|
||||
mov (sp)+,r0
|
||||
sub b1s(r2),r0
|
||||
add r1,r0 / set r0=byte addr in buffer
|
||||
mov (sp)+,r1
|
||||
mov (sp)+,r3
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to wc a buffer
|
||||
/
|
||||
/ mov buffer addr,r2
|
||||
/ mov buffer addr+6,r1 beginning of buffer
|
||||
/ jsr pc,clean
|
||||
/
|
||||
clean:
|
||||
inc stats+24.
|
||||
mov r0,-(sp)
|
||||
mov b1s(r2),0f
|
||||
mov afout,r0
|
||||
sys seek;0:..;0
|
||||
mov r1,0f
|
||||
sys write;0:..;512.
|
||||
|
||||
clr w1(r2) /clear w
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to get buffer addr of byte whose disc
|
||||
/ addr is in r0 - also returns addr of write
|
||||
/ flag for buffer in r2
|
||||
/
|
||||
/ mov disc addr,r0
|
||||
/ jsr pc,bufchar
|
||||
/ mov (r0),r0 for read
|
||||
/ inc (r2) for write must inc w
|
||||
/
|
||||
/ c-bit set if char not in either buffer
|
||||
/
|
||||
bufchar:
|
||||
mov r1,-(sp)
|
||||
mov r3,-(sp)
|
||||
clr r3
|
||||
1:
|
||||
mov r3,r2
|
||||
asl r2
|
||||
cmp r0,b1s(r2)
|
||||
blo 2f
|
||||
cmp r0,b1e(r2)
|
||||
bhis 2f
|
||||
sub b1s(r2),r0
|
||||
mov r3,r1
|
||||
ashc $9.,r1
|
||||
bic $777,r1
|
||||
add r1,r0
|
||||
add $b1,r0
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r1
|
||||
clc
|
||||
rts pc
|
||||
2:
|
||||
inc r3
|
||||
cmp r3,$numb
|
||||
blt 1b
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r1
|
||||
sec
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ routine to get a buffer
|
||||
/
|
||||
/ mov disc addr,r0
|
||||
/ jsr pc,getbuf
|
||||
/ mov (r0),r0 (for read)
|
||||
/ inc (r2) must inc w for w
|
||||
/
|
||||
getbuf:
|
||||
mov r4,-(sp)
|
||||
mov r3,-(sp)
|
||||
mov $2,r3
|
||||
clr r2
|
||||
mov $1,r4
|
||||
1:
|
||||
cmp r4,$numb
|
||||
bge 1f
|
||||
cmp u1(r3),u1(r2)
|
||||
bhis 2f
|
||||
mov r3,r2
|
||||
2:
|
||||
inc r4
|
||||
add $2.,r3
|
||||
br 1b
|
||||
1:
|
||||
mov r2,r3
|
||||
jsr pc,getb
|
||||
add $stats+14.,r3
|
||||
inc (r3)
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r4
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ this routine renumbers the time used cell u1(r2)
|
||||
/ of the buffers when the clock overflows
|
||||
/
|
||||
fixct:
|
||||
mov r1,-(sp)
|
||||
mov r3,-(sp)
|
||||
mov $numb,r1
|
||||
mov $numb,flag
|
||||
2:
|
||||
mov r1,u1(r2)
|
||||
dec r1
|
||||
bge 1f
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r1
|
||||
rts pc
|
||||
1:
|
||||
clr r2
|
||||
mov $2,r3
|
||||
1:
|
||||
cmp r3,$numb2
|
||||
bge 2b
|
||||
cmp u1(r3),u1(r2)
|
||||
blo 2f
|
||||
mov r3,r2
|
||||
2:
|
||||
add $2,r3
|
||||
br 1b
|
||||
@@ -0,0 +1,456 @@
|
||||
.globl b1
|
||||
.globl log2
|
||||
.globl frlist
|
||||
.globl stats
|
||||
.globl b1s
|
||||
.globl b1e
|
||||
.globl w1
|
||||
/ here to allocate a new block
|
||||
/
|
||||
/
|
||||
/ mov ...,r0
|
||||
/ jsr pc,allocate
|
||||
/ mov r1,...
|
||||
/
|
||||
/ requested size in bytes in r0
|
||||
/ pointer to header of allocated block returned in r1
|
||||
/ r0 is preserved
|
||||
/
|
||||
/ convert to words, adjust for header, round up
|
||||
/ to a power of two
|
||||
/
|
||||
/ each block has a four-word header
|
||||
/ W - write ptr (also used as link ptr in frlist)
|
||||
/ R - read ptr
|
||||
/ A - pointer to head of data
|
||||
/ L - ptr to (end+1) of data
|
||||
hsz=6144.
|
||||
datasz = 32768.
|
||||
numb=4.
|
||||
numb2=2*numb
|
||||
w=0
|
||||
r=2
|
||||
a=4
|
||||
l=6
|
||||
/
|
||||
allocate:
|
||||
clr garbage
|
||||
mov r0,-(sp)
|
||||
mov r2,-(sp)
|
||||
mov r3,-(sp)
|
||||
inc stats
|
||||
bne 9f; inc stats; 9:
|
||||
cmp r0,$datasz
|
||||
blo 9f; 4; 9:
|
||||
dec r0
|
||||
bmi 1f
|
||||
jsr pc,log2
|
||||
inc r0
|
||||
1: asl r0
|
||||
mov r0,-(sp)
|
||||
add $2,r0
|
||||
cmp r0,$frend-frlist+2
|
||||
blo zzz
|
||||
4
|
||||
/
|
||||
/ look on free list for block of required size
|
||||
/
|
||||
zzz:
|
||||
mov (sp),r0
|
||||
tst frlist(r0)
|
||||
beq xxx
|
||||
/
|
||||
/ found it, allocate and return
|
||||
/
|
||||
mov frlist(r0),r1
|
||||
add $hblk,r1
|
||||
mov (r1),frlist(r0)
|
||||
mov a(r1),r0
|
||||
mov r0,w(r1) /W
|
||||
mov r0,r(r1) /R
|
||||
tst (sp)+
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r0
|
||||
/ jsr pc,whead
|
||||
rts pc
|
||||
/
|
||||
/ no block of required size
|
||||
/ look for larger block
|
||||
/
|
||||
xxx:
|
||||
tst hblk
|
||||
beq www
|
||||
tst (r0)+
|
||||
cmp r0,$frend-frlist
|
||||
bhis www
|
||||
tst frlist(r0)
|
||||
bne yyy
|
||||
br xxx
|
||||
/
|
||||
/ there are no larger blocks; must garbage collect
|
||||
/
|
||||
www: jsr pc,collect
|
||||
tst r0
|
||||
bne zzz
|
||||
/
|
||||
/ out of space
|
||||
/
|
||||
mov $1,r0
|
||||
sys write; 1f; 2f-1f
|
||||
jmp interrupt
|
||||
1: <Out of space.\n>
|
||||
2: .even
|
||||
/
|
||||
/ split larger block into two smaller pieces and
|
||||
/ link together as smaller blocks in the free list.
|
||||
/
|
||||
yyy:
|
||||
mov hblk,r3 /get free header block
|
||||
beq www /should never get this
|
||||
mov frlist(r0),r1
|
||||
add $hblk,r1
|
||||
mov w(r1),frlist(r0)
|
||||
mov r3,w(r1)
|
||||
add $hblk,r3
|
||||
mov exp2-2(r0),r2
|
||||
add a(r1),r2
|
||||
mov w(r3),hblk
|
||||
mov l(r1),l(r3)
|
||||
mov r2,l(r1) /L
|
||||
mov r2,a(r3)
|
||||
clr w(r3) /W'
|
||||
mov r1,r2
|
||||
sub $hblk,r2
|
||||
mov r2,frlist-2(r0)
|
||||
br zzz
|
||||
/
|
||||
/
|
||||
/ here to release a block
|
||||
/
|
||||
/ mov ...,r1
|
||||
/ jsr pc,release
|
||||
/
|
||||
/ pointer to block in r1
|
||||
/
|
||||
release:
|
||||
/
|
||||
/ discover that this is a plausible pointer
|
||||
/
|
||||
mov r0,-(sp)
|
||||
jsr pc,preposterous
|
||||
/
|
||||
/ find free list index and link block to that entry
|
||||
/
|
||||
inc stats+2
|
||||
mov frlist(r0),w(r1)
|
||||
clr r(r1)
|
||||
sub $hblk,r1
|
||||
mov r1,frlist(r0)
|
||||
clr r1 /self-defense
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/ jsr pc,collect
|
||||
/
|
||||
/ coalesce free storage by rejoining paired blocks
|
||||
/ on the free list.
|
||||
/ zero is returned in r0 if no paired blocks were found.
|
||||
/
|
||||
collect:
|
||||
mov r1,-(sp)
|
||||
mov r2,-(sp)
|
||||
mov r3,-(sp)
|
||||
mov r4,-(sp)
|
||||
clr useful
|
||||
inc stats+4.
|
||||
clr r0 /start with smallest blocks
|
||||
/r0 contains frlist index
|
||||
loop1: mov $frlist,r1
|
||||
add r0,r1
|
||||
/
|
||||
/ try next list member at this level
|
||||
/
|
||||
loop2: mov (r1),r3
|
||||
beq advance /list is empty
|
||||
add $hblk,r3
|
||||
tst (r3) /W
|
||||
beq advance /only one list element
|
||||
/
|
||||
/ calculate address of buddy
|
||||
/
|
||||
mov a(r3),r4
|
||||
sub $hsz,r4
|
||||
mov exp2(r0),r2
|
||||
xor r2,r4
|
||||
1: add $hsz,r4
|
||||
/
|
||||
/ and search for him
|
||||
/
|
||||
loop3:
|
||||
cmp a(r3),r4
|
||||
beq coal
|
||||
mov r3,r2
|
||||
mov w(r3),r3
|
||||
tst r3
|
||||
beq nocoal
|
||||
add $hblk,r3
|
||||
br loop3
|
||||
/
|
||||
/ have found a pair; remove both blocks from list,
|
||||
/ coalesce them, and put them on next higher list
|
||||
/
|
||||
coal: mov $1,useful
|
||||
mov w(r3),w(r2) /remove him from list
|
||||
mov (r1),r2
|
||||
add $hblk,r2
|
||||
mov r3,r4
|
||||
mov w(r2),w(r1) /remove other one
|
||||
cmp a(r2),a(r4)
|
||||
bhi 1f
|
||||
mov r2,-(sp)
|
||||
mov r4,r2
|
||||
mov (sp)+,r4
|
||||
1: mov hblk,(r2)
|
||||
clr r(r2)
|
||||
mov $hsz,a(r2)
|
||||
mov $hsz,l(r2)
|
||||
sub $hblk,r2
|
||||
mov r2,hblk
|
||||
add exp2(r0),l(r4) /L
|
||||
clr r(r4)
|
||||
mov frlist+2(r0),w(r4)
|
||||
sub $hblk,r4
|
||||
mov r4,frlist+2(r0)
|
||||
br loop2
|
||||
/
|
||||
/ no buddy found, try next block on this list
|
||||
/
|
||||
nocoal:
|
||||
mov (r1),r1
|
||||
add $hblk,r1
|
||||
br loop2
|
||||
/
|
||||
/ advance to next free list
|
||||
/
|
||||
advance:
|
||||
tst (r0)+
|
||||
cmp r0,$frend-frlist
|
||||
blo loop1
|
||||
mov useful,r0
|
||||
/
|
||||
/ do we have enough headers to continue?
|
||||
/
|
||||
tst garbage
|
||||
beq 1f
|
||||
mov $1,r0
|
||||
sys write; 4f; 5f-4f
|
||||
4
|
||||
/
|
||||
4: <Out of headers.\n>
|
||||
5: .even
|
||||
/
|
||||
/
|
||||
/ restore registers and return
|
||||
/
|
||||
1:
|
||||
inc garbage
|
||||
mov (sp)+,r4
|
||||
mov (sp)+,r3
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r1
|
||||
rts pc
|
||||
/
|
||||
garbage:.=.+2
|
||||
/
|
||||
/ routine to find integer part of log2(x)
|
||||
/
|
||||
/ jsr pc,log2
|
||||
/
|
||||
/ r0 = log2(r0)
|
||||
/
|
||||
log2:
|
||||
mov $15.,-(sp)
|
||||
tst r0
|
||||
bne 1f
|
||||
clr (sp)
|
||||
br 2f
|
||||
1: asl r0
|
||||
bcs 2f
|
||||
dec (sp)
|
||||
br 1b
|
||||
2: mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
0
|
||||
exp2:
|
||||
1;2;4;10;20;40;100;200;400;1000;2000;4000;
|
||||
10000;20000;40000;100000
|
||||
/
|
||||
/ routine to discover whether r1 points to
|
||||
/ a plausible header - to avoid ruination.
|
||||
/
|
||||
/ r1 is preserved and r0 gets a suitable index for frlist
|
||||
/
|
||||
/ jsr pc,preposterous
|
||||
/
|
||||
preposterous:
|
||||
cmp r1,$headers
|
||||
bhis 9f; 4; 9:
|
||||
cmp r1,$headend
|
||||
blo 9f; 4; 9:
|
||||
cmp a(r1),$hsz /A
|
||||
bhis 9f; 4; 9:
|
||||
cmp l(r1),$hsz+datasz /L
|
||||
blos 9f; 4; 9:
|
||||
mov l(r1),r0 /L
|
||||
sub a(r1),r0 /A
|
||||
mov r0,-(sp)
|
||||
jsr pc,log2
|
||||
asl r0
|
||||
cmp exp2(r0),(sp)
|
||||
beq 9f; 4; 9:
|
||||
add $2,r0
|
||||
cmp r0,$frend-frlist+2
|
||||
blo 9f; 4; 9:
|
||||
sub $2,r0
|
||||
mov r0,(sp)
|
||||
mov frlist(r0),r0
|
||||
1: beq 1f
|
||||
add $hblk,r0
|
||||
cmp r0,r1
|
||||
bne 9f; 4; 9:
|
||||
mov (r0),r0
|
||||
br 1b
|
||||
1: mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
/
|
||||
whead:
|
||||
inc stats+22.
|
||||
mov r0,-(sp)
|
||||
mov afout,r0
|
||||
sys seek; 0; 0
|
||||
sys write; hblk; hsz
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
initl:
|
||||
clr hblk
|
||||
mov r0,-(sp)
|
||||
mov r2,-(sp)
|
||||
sys open;almem; 1 /open for write
|
||||
bec 2f
|
||||
sys creat;almem; 666
|
||||
bes err2
|
||||
inc hblk
|
||||
2:
|
||||
mov r0,afout
|
||||
sys open; almem; 0 /open for read
|
||||
bes err2
|
||||
mov r0,afi
|
||||
br 1f
|
||||
/
|
||||
err2:
|
||||
mov $1,r0
|
||||
sys write; 4f; 5f-4f
|
||||
4
|
||||
.data
|
||||
4: <cannot open output file\n>
|
||||
5:
|
||||
almem: <form.m\0>
|
||||
.even
|
||||
.text
|
||||
/
|
||||
1:
|
||||
tst hblk
|
||||
bgt 1f
|
||||
sys read; hblk; hsz /r0 already afi
|
||||
mov asmdisc,asmem
|
||||
add $hblk,asmem
|
||||
br 2f
|
||||
1:
|
||||
mov $headers,r2
|
||||
mov r2,r0
|
||||
sub $hblk,r0
|
||||
mov r0,hblk
|
||||
1:
|
||||
add $8,r0
|
||||
mov r0,(r2)
|
||||
add $8,r2
|
||||
cmp r2,$headend-8.
|
||||
blo 1b
|
||||
clr -8(r2)
|
||||
mov $frlist,r0
|
||||
1:
|
||||
clr (r0)+
|
||||
cmp r0,$frend
|
||||
blo 1b
|
||||
|
||||
mov hblk,r2
|
||||
add $hblk,r2
|
||||
mov (r2),hblk
|
||||
clr w(r2)
|
||||
mov $hsz,a(r2)
|
||||
mov $hsz+datasz,l(r2)
|
||||
mov $datasz,r0
|
||||
jsr pc,log2
|
||||
asl r0
|
||||
cmp r0,$frend-frlist
|
||||
blo 9f; 4; 9:
|
||||
sub $hblk,r2
|
||||
mov r2,frlist(r0)
|
||||
/
|
||||
/ install plausible pointers to make octal dumps look nice
|
||||
/
|
||||
mov $hblk,r1
|
||||
1:
|
||||
mov (r1),r1
|
||||
tst r1
|
||||
beq 1f
|
||||
add $hblk,r1
|
||||
mov $hsz,a(r1)
|
||||
mov $hsz,l(r1)
|
||||
mov $hsz,r(r1)
|
||||
br 1b
|
||||
1:
|
||||
mov afout,r0
|
||||
sys write;hblk;hsz
|
||||
jsr pc,reset
|
||||
mov $4,r0
|
||||
jsr pc,allocate
|
||||
mov r1,asmem
|
||||
mov r1,asmdisc
|
||||
sub $hblk,asmdisc
|
||||
2:
|
||||
mov (sp)+,r2
|
||||
mov (sp)+,r0
|
||||
rts pc
|
||||
/
|
||||
/
|
||||
.bss
|
||||
/
|
||||
b1s: .=.+numb2
|
||||
b1e: .=.+numb2
|
||||
w1: .=.+numb2
|
||||
u1: .=.+numb2
|
||||
b1: .=. + [512.*numb]
|
||||
flag: .=.+2
|
||||
stats: .=.+24. /alloc/release/collect/get/put/seek/copy
|
||||
useful: .=.+2
|
||||
afi: .=.+2
|
||||
afout: .=.+2
|
||||
asmem: .=.+2
|
||||
nchar: .=.+2
|
||||
/
|
||||
/
|
||||
hblk: .=.+2 /must remain here - pointer to free header
|
||||
frlist: .=hblk+34.
|
||||
frend:
|
||||
asmdisc:.=.+2
|
||||
headers: .=hblk+hsz
|
||||
headend:
|
||||
.text
|
||||
@@ -0,0 +1,199 @@
|
||||
#
|
||||
/*
|
||||
* getty -- adapt to terminal speed on dialup, and call login
|
||||
*/
|
||||
|
||||
/*
|
||||
* tty flags
|
||||
*/
|
||||
#define HUPCL 01
|
||||
#define XTABS 02
|
||||
#define LCASE 04
|
||||
#define ECHO 010
|
||||
#define CRMOD 020
|
||||
#define RAW 040
|
||||
#define ODDP 0100
|
||||
#define EVENP 0200
|
||||
#define ANYP 0300
|
||||
|
||||
/*
|
||||
* Delay algorithms
|
||||
*/
|
||||
#define CR1 010000
|
||||
#define CR2 020000
|
||||
#define CR3 030000
|
||||
#define NL1 000400
|
||||
#define NL2 001000
|
||||
#define NL3 001400
|
||||
#define TAB1 002000
|
||||
#define TAB2 004000
|
||||
#define TAB3 006000
|
||||
#define FF1 040000
|
||||
|
||||
#define ERASE '#'
|
||||
#define KILL '@'
|
||||
|
||||
/*
|
||||
* speeds
|
||||
*/
|
||||
#define B110 3
|
||||
#define B150 5
|
||||
#define B300 7
|
||||
#define B9600 13
|
||||
|
||||
#define SIGINT 2
|
||||
#define SIGQIT 3
|
||||
|
||||
struct sgtty {
|
||||
char sgispd, sgospd;
|
||||
char sgerase, sgkill;
|
||||
int sgflag;
|
||||
} tmode;
|
||||
|
||||
struct tab {
|
||||
int tname; /* this table name */
|
||||
int nname; /* successor table name */
|
||||
int iflags; /* initial flags */
|
||||
int fflags; /* final flags */
|
||||
int ispeed; /* input speed */
|
||||
int ospeed; /* output speed */
|
||||
char *message; /* login message */
|
||||
} itab[] {
|
||||
|
||||
/* table '0'-1-2 300,150,110 */
|
||||
|
||||
'0', 1,
|
||||
ANYP+RAW+NL1+CR1, ANYP+ECHO+CR1,
|
||||
B300, B300,
|
||||
"\n\r\033;\007login: ",
|
||||
|
||||
1, 2,
|
||||
ANYP+RAW+NL1+CR1, EVENP+ECHO+FF1+CR2+TAB1+NL1,
|
||||
B150, B150,
|
||||
"\n\r\033:\006\006\017login: ",
|
||||
|
||||
2, '0',
|
||||
ANYP+RAW+NL1+CR1, ANYP+ECHO+CRMOD+XTABS+LCASE+CR1,
|
||||
B110, B110,
|
||||
"\n\rlogin: ",
|
||||
|
||||
/* table '-' -- Console TTY 110 */
|
||||
'-', '-',
|
||||
ANYP+RAW+NL1+CR1, ANYP+ECHO+CRMOD+XTABS+LCASE+CR1,
|
||||
B110, B110,
|
||||
"\n\rlogin: ",
|
||||
|
||||
/* table '1' -- 150 */
|
||||
'1', '1',
|
||||
ANYP+RAW+NL1+CR1, EVENP+ECHO+FF1+CR2+TAB1+NL1,
|
||||
B150, B150,
|
||||
"\n\r\033:\006\006\017login: ",
|
||||
|
||||
/* table '2' -- 9600 */
|
||||
'2', '2',
|
||||
ANYP+RAW+NL1+CR1, ANYP+XTABS+ECHO+CRMOD+FF1,
|
||||
B9600, B9600,
|
||||
"\n\r\033;login: ",
|
||||
};
|
||||
|
||||
#define NITAB sizeof itab/sizeof itab[0]
|
||||
|
||||
char name[16];
|
||||
int crmod;
|
||||
int upper;
|
||||
int lower;
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
register struct tab *tabp;
|
||||
register tname;
|
||||
|
||||
/*
|
||||
signal(SIGINT, 1);
|
||||
signal(SIGQIT, 0);
|
||||
*/
|
||||
tname = '0';
|
||||
if (argc > 1)
|
||||
tname = *argv[1];
|
||||
for (;;) {
|
||||
for(tabp = itab; tabp < &itab[NITAB]; tabp++)
|
||||
if(tabp->tname == tname)
|
||||
break;
|
||||
if(tabp >= &itab[NITAB])
|
||||
tabp = itab;
|
||||
tmode.sgispd = tabp->ispeed;
|
||||
tmode.sgospd = tabp->ospeed;
|
||||
tmode.sgflag = tabp->iflags;
|
||||
tmode.sgispd = tabp->ispeed;
|
||||
tmode.sgospd = tabp->ospeed;
|
||||
stty(0, &tmode);
|
||||
puts(tabp->message);
|
||||
stty(0, &tmode);
|
||||
if(getname()) {
|
||||
tmode.sgerase = ERASE;
|
||||
tmode.sgkill = KILL;
|
||||
tmode.sgflag = tabp->fflags;
|
||||
if(crmod)
|
||||
tmode.sgflag =| CRMOD;
|
||||
if(upper)
|
||||
tmode.sgflag =| LCASE;
|
||||
if(lower)
|
||||
tmode.sgflag =& ~LCASE;
|
||||
stty(0, &tmode);
|
||||
execl("/bin/login", "login", name, 0);
|
||||
exit(1);
|
||||
}
|
||||
tname = tabp->nname;
|
||||
}
|
||||
}
|
||||
|
||||
getname()
|
||||
{
|
||||
register char *np;
|
||||
register c;
|
||||
static cs;
|
||||
|
||||
crmod = 0;
|
||||
upper = 0;
|
||||
lower = 0;
|
||||
np = name;
|
||||
do {
|
||||
if (read(0, &cs, 1) <= 0)
|
||||
exit(0);
|
||||
if ((c = cs&0177) == 0)
|
||||
return(0);
|
||||
write(1, &cs, 1);
|
||||
if (c>='a' && c <='z')
|
||||
lower++;
|
||||
else if (c>='A' && c<='Z') {
|
||||
upper++;
|
||||
c =+ 'a'-'A';
|
||||
} else if (c==ERASE) {
|
||||
if (np > name)
|
||||
np--;
|
||||
continue;
|
||||
} else if (c==KILL) {
|
||||
np = name;
|
||||
continue;
|
||||
}
|
||||
*np++ = c;
|
||||
} while (c!='\n' && c!='\r' && np <= &name[16]);
|
||||
*--np = 0;
|
||||
if (c == '\r') {
|
||||
write(1, "\n", 1);
|
||||
crmod++;
|
||||
} else
|
||||
write(1, "\r", 1);
|
||||
return(1);
|
||||
}
|
||||
|
||||
puts(as)
|
||||
char *as;
|
||||
{
|
||||
register char *s;
|
||||
|
||||
s = as;
|
||||
while (*s)
|
||||
write(1, s++, 1);
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
#
|
||||
/* global command --
|
||||
|
||||
glob params
|
||||
|
||||
"*" in params matches r.e ".*"
|
||||
"?" in params matches r.e. "."
|
||||
"[...]" in params matches character class
|
||||
"[...a-z...]" in params matches a through z.
|
||||
|
||||
perform command with argument list
|
||||
constructed as follows:
|
||||
if param does not contain "*", "[", or "?", use it as is
|
||||
if it does, find all files in current directory
|
||||
which match the param, sort them, and use them
|
||||
|
||||
prepend the command name with "/bin" or "/usr/bin"
|
||||
as required.
|
||||
*/
|
||||
|
||||
#define E2BIG 7
|
||||
#define ENOEXEC 8
|
||||
#define ENOENT 2
|
||||
|
||||
#define STRSIZ 522
|
||||
char ab[STRSIZ]; /* generated characters */
|
||||
char *ava[200]; /* generated arguments */
|
||||
char **av &ava[1];
|
||||
char *string ab;
|
||||
int errno;
|
||||
int ncoll;
|
||||
|
||||
main(argc, argv)
|
||||
char *argv[];
|
||||
{
|
||||
register char *cp;
|
||||
|
||||
if (argc < 3) {
|
||||
write(2, "Arg count\n", 10);
|
||||
return;
|
||||
}
|
||||
argv++;
|
||||
*av++ = *argv;
|
||||
while (--argc >= 2)
|
||||
expand(*++argv);
|
||||
if (ncoll==0) {
|
||||
write(2, "No match\n", 9);
|
||||
return;
|
||||
}
|
||||
execute(ava[1], &ava[1]);
|
||||
cp = cat("/usr/bin/", ava[1]);
|
||||
execute(cp+4, &ava[1]);
|
||||
execute(cp, &ava[1]);
|
||||
write(2, "Command not found.\n", 19);
|
||||
}
|
||||
|
||||
expand(as)
|
||||
char *as;
|
||||
{
|
||||
register char *s, *cs;
|
||||
register int dirf;
|
||||
char **oav;
|
||||
static struct {
|
||||
int ino;
|
||||
char name[16];
|
||||
} entry;
|
||||
|
||||
s = cs = as;
|
||||
while (*cs!='*' && *cs!='?' && *cs!='[') {
|
||||
if (*cs++ == 0) {
|
||||
*av++ = cat(s, "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
if (cs==s) {
|
||||
dirf = open(".", 0);
|
||||
s = "";
|
||||
break;
|
||||
}
|
||||
if (*--cs == '/') {
|
||||
*cs = 0;
|
||||
dirf = open(s==cs? "/": s, 0);
|
||||
*cs++ = 0200;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dirf<0) {
|
||||
write(2, "No directory\n", 13);
|
||||
exit();
|
||||
}
|
||||
oav = av;
|
||||
while (read(dirf, &entry, 16) == 16) {
|
||||
if (entry.ino==0)
|
||||
continue;
|
||||
if (match(entry.name, cs)) {
|
||||
*av++ = cat(s, entry.name);
|
||||
ncoll++;
|
||||
}
|
||||
}
|
||||
close(dirf);
|
||||
sort(oav);
|
||||
}
|
||||
|
||||
sort(oav)
|
||||
char **oav;
|
||||
{
|
||||
register char **p1, **p2, **c;
|
||||
|
||||
p1 = oav;
|
||||
while (p1 < av-1) {
|
||||
p2 = p1;
|
||||
while(++p2 < av) {
|
||||
if (compar(*p1, *p2) > 0) {
|
||||
c = *p1;
|
||||
*p1 = *p2;
|
||||
*p2 = c;
|
||||
}
|
||||
}
|
||||
p1++;
|
||||
}
|
||||
}
|
||||
|
||||
execute(afile, aarg)
|
||||
char *afile;
|
||||
char **aarg;
|
||||
{
|
||||
register char *file, **arg;
|
||||
|
||||
arg = aarg;
|
||||
file = afile;
|
||||
execv(file, arg);
|
||||
if (errno==ENOEXEC) {
|
||||
arg[0] = file;
|
||||
*--arg = "/bin/sh";
|
||||
execv(*arg, arg);
|
||||
}
|
||||
if (errno==E2BIG)
|
||||
toolong();
|
||||
}
|
||||
|
||||
toolong()
|
||||
{
|
||||
write(2, "Arg list too long\n", 18);
|
||||
exit();
|
||||
}
|
||||
|
||||
match(s, p)
|
||||
char *s, *p;
|
||||
{
|
||||
if (*s=='.' && *p!='.')
|
||||
return(0);
|
||||
return(amatch(s, p));
|
||||
}
|
||||
|
||||
amatch(as, ap)
|
||||
char *as, *ap;
|
||||
{
|
||||
register char *s, *p;
|
||||
register scc;
|
||||
int c, cc, ok, lc;
|
||||
|
||||
s = as;
|
||||
p = ap;
|
||||
if (scc = *s++)
|
||||
if ((scc =& 0177) == 0)
|
||||
scc = 0200;
|
||||
switch (c = *p++) {
|
||||
|
||||
case '[':
|
||||
ok = 0;
|
||||
lc = 077777;
|
||||
while (cc = *p++) {
|
||||
if (cc==']') {
|
||||
if (ok)
|
||||
return(amatch(s, p));
|
||||
else
|
||||
return(0);
|
||||
} else if (cc=='-') {
|
||||
if (lc<=scc && scc<=(c = *p++))
|
||||
ok++;
|
||||
} else
|
||||
if (scc == (lc=cc))
|
||||
ok++;
|
||||
}
|
||||
return(0);
|
||||
|
||||
default:
|
||||
if (c!=scc)
|
||||
return(0);
|
||||
|
||||
case '?':
|
||||
if (scc)
|
||||
return(amatch(s, p));
|
||||
return(0);
|
||||
|
||||
case '*':
|
||||
return(umatch(--s, p));
|
||||
|
||||
case '\0':
|
||||
return(!scc);
|
||||
}
|
||||
}
|
||||
|
||||
umatch(s, p)
|
||||
char *s, *p;
|
||||
{
|
||||
if(*p==0)
|
||||
return(1);
|
||||
while(*s)
|
||||
if (amatch(s++,p))
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
compar(as1, as2)
|
||||
char *as1, *as2;
|
||||
{
|
||||
register char *s1, *s2;
|
||||
|
||||
s1 = as1;
|
||||
s2 = as2;
|
||||
while (*s1++ == *s2)
|
||||
if (*s2++ == 0)
|
||||
return(0);
|
||||
return (*--s1 - *s2);
|
||||
}
|
||||
|
||||
cat(as1, as2)
|
||||
char *as1, *as2;
|
||||
{
|
||||
register char *s1, *s2;
|
||||
register int c;
|
||||
|
||||
s2 = string;
|
||||
s1 = as1;
|
||||
while (c = *s1++) {
|
||||
if (s2 > &ab[STRSIZ])
|
||||
toolong();
|
||||
c =& 0177;
|
||||
if (c==0) {
|
||||
*s2++ = '/';
|
||||
break;
|
||||
}
|
||||
*s2++ = c;
|
||||
}
|
||||
s1 = as2;
|
||||
do {
|
||||
if (s2 > &ab[STRSIZ])
|
||||
toolong();
|
||||
*s2++ = c = *s1++;
|
||||
} while (c);
|
||||
s1 = string;
|
||||
string = s2;
|
||||
return(s1);
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
int offset 0;
|
||||
|
||||
main(argc, argv)
|
||||
char *argv[];
|
||||
{
|
||||
extern fin;
|
||||
char line[64];
|
||||
|
||||
if (argc<2 || ttyn(0)!='x') {
|
||||
write(1, "goto error\n", 11);
|
||||
seek(0, 0, 2);
|
||||
return;
|
||||
}
|
||||
seek(0, 0, 0);
|
||||
fin = dup(0);
|
||||
|
||||
loop:
|
||||
if (getlin(line)) {
|
||||
write(1, "label not found\n", 16);
|
||||
return;
|
||||
}
|
||||
if (compar(line, argv[1])) goto loop;
|
||||
seek(0, offset, 0);
|
||||
}
|
||||
|
||||
getlin(s)
|
||||
char s[];
|
||||
{
|
||||
int ch, i;
|
||||
|
||||
i = 0;
|
||||
l:
|
||||
if ((ch=getc())=='\0') return(1);
|
||||
if (ch!=':') {
|
||||
while(ch!='\n' && ch!='\0')
|
||||
ch = getc();
|
||||
goto l;
|
||||
}
|
||||
while ((ch=getc())==' ');
|
||||
while (ch!=' ' && ch!='\n' && ch!='\0') {
|
||||
s[i++] = ch;
|
||||
ch = getc();
|
||||
}
|
||||
while(ch != '\n')
|
||||
ch = getc();
|
||||
s[i] = '\0';
|
||||
return(0);
|
||||
}
|
||||
|
||||
compar(s1, s2)
|
||||
char s1[], s2[];
|
||||
{
|
||||
int c, i;
|
||||
|
||||
i = 0;
|
||||
l:
|
||||
if(s1[i] != s2[i]) return(1);
|
||||
if (s1[i++] == '\0') return(0);
|
||||
goto l;
|
||||
}
|
||||
|
||||
getc()
|
||||
{
|
||||
|
||||
offset++;
|
||||
return(getchar());
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
#
|
||||
/*
|
||||
* grep -- print lines matching (or not matching) a pattern
|
||||
*
|
||||
*/
|
||||
|
||||
#define CCHR 2
|
||||
#define CDOT 4
|
||||
#define CCL 6
|
||||
#define NCCL 8
|
||||
#define CDOL 10
|
||||
#define CEOF 11
|
||||
|
||||
#define STAR 01
|
||||
|
||||
#define LBSIZE 256
|
||||
#define ESIZE 256
|
||||
|
||||
char ibuf[512];
|
||||
char expbuf[ESIZE];
|
||||
int lnum[2];
|
||||
char linebuf[LBSIZE+1];
|
||||
int bflag;
|
||||
int nflag;
|
||||
int cflag;
|
||||
int vflag;
|
||||
int nfile;
|
||||
int circf;
|
||||
int blkno;
|
||||
int tln[2];
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
extern fout;
|
||||
|
||||
fout = dup(1);
|
||||
flush();
|
||||
while (--argc > 0 && (++argv)[0][0]=='-')
|
||||
switch (argv[0][1]) {
|
||||
|
||||
case 'v':
|
||||
vflag++;
|
||||
continue;
|
||||
|
||||
case 'b':
|
||||
bflag++;
|
||||
continue;
|
||||
|
||||
case 'c':
|
||||
cflag++;
|
||||
continue;
|
||||
|
||||
case 'n':
|
||||
nflag++;
|
||||
continue;
|
||||
|
||||
default:
|
||||
printf2("Unknown flag\n");
|
||||
continue;
|
||||
}
|
||||
if (argc<=0)
|
||||
exit(2);
|
||||
compile(*argv);
|
||||
nfile = --argc;
|
||||
if (argc<=0)
|
||||
execute(0);
|
||||
else while (--argc >= 0) {
|
||||
argv++;
|
||||
execute(*argv);
|
||||
}
|
||||
flush();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
compile(astr)
|
||||
char *astr;
|
||||
{
|
||||
register c;
|
||||
register char *ep, *sp;
|
||||
char *lastep;
|
||||
int cclcnt;
|
||||
|
||||
ep = expbuf;
|
||||
sp = astr;
|
||||
if (*sp == '^') {
|
||||
circf++;
|
||||
sp++;
|
||||
}
|
||||
for (;;) {
|
||||
if (ep >= &expbuf[ESIZE])
|
||||
goto cerror;
|
||||
if ((c = *sp++) != '*')
|
||||
lastep = ep;
|
||||
switch (c) {
|
||||
|
||||
case '\0':
|
||||
*ep++ = CEOF;
|
||||
return;
|
||||
|
||||
case '.':
|
||||
*ep++ = CDOT;
|
||||
continue;
|
||||
|
||||
case '*':
|
||||
if (lastep==0)
|
||||
goto defchar;
|
||||
*lastep =| STAR;
|
||||
continue;
|
||||
|
||||
case '$':
|
||||
if (*sp != '\0')
|
||||
goto defchar;
|
||||
*ep++ = CDOL;
|
||||
continue;
|
||||
|
||||
case '[':
|
||||
*ep++ = CCL;
|
||||
*ep++ = 0;
|
||||
cclcnt = 1;
|
||||
if ((c = *sp++) == '^') {
|
||||
c = *sp++;
|
||||
ep[-2] = NCCL;
|
||||
}
|
||||
do {
|
||||
*ep++ = c;
|
||||
cclcnt++;
|
||||
if (c=='\0' || ep >= &expbuf[ESIZE])
|
||||
goto cerror;
|
||||
} while ((c = *sp++) != ']');
|
||||
lastep[1] = cclcnt;
|
||||
continue;
|
||||
|
||||
case '\\':
|
||||
if ((c = *sp++) == '\0')
|
||||
goto cerror;
|
||||
defchar:
|
||||
default:
|
||||
*ep++ = CCHR;
|
||||
*ep++ = c;
|
||||
}
|
||||
}
|
||||
cerror:
|
||||
printf2("RE error\n");
|
||||
}
|
||||
|
||||
execute(file)
|
||||
{
|
||||
register char *p1, *p2;
|
||||
register c;
|
||||
int f;
|
||||
char *ebp, *cbp;
|
||||
|
||||
if (file) {
|
||||
if ((f = open(file, 0)) < 0) {
|
||||
printf2("Can't open %s\n", file);
|
||||
}
|
||||
} else
|
||||
f = 0;
|
||||
ebp = ibuf;
|
||||
cbp = ibuf;
|
||||
lnum[0] = 0;
|
||||
lnum[1] = 0;
|
||||
tln[0] = 0;
|
||||
tln[1] = 0;
|
||||
blkno = -1;
|
||||
for (;;) {
|
||||
if ((++lnum[1])==0)
|
||||
lnum[1]++;
|
||||
if((lnum[1]&0377) == 0)
|
||||
flush();
|
||||
p1 = linebuf;
|
||||
p2 = cbp;
|
||||
for (;;) {
|
||||
if (p2 >= ebp) {
|
||||
if ((c = read(f, ibuf, 512)) <= 0) {
|
||||
close(f);
|
||||
if (cflag) {
|
||||
if (nfile > 1)
|
||||
printf("%s:", file);
|
||||
p1 = locv(tln[0],tln[1]);
|
||||
printf("%s\n", p1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
blkno++;
|
||||
p2 = ibuf;
|
||||
ebp = ibuf+c;
|
||||
}
|
||||
if ((c = *p2++) == '\n')
|
||||
break;
|
||||
if(c)
|
||||
if (p1 < &linebuf[LBSIZE-1])
|
||||
*p1++ = c;
|
||||
}
|
||||
*p1++ = 0;
|
||||
cbp = p2;
|
||||
p1 = linebuf;
|
||||
p2 = expbuf;
|
||||
if (circf) {
|
||||
if (advance(p1, p2))
|
||||
goto found;
|
||||
goto nfound;
|
||||
}
|
||||
/* fast check for first character */
|
||||
if (*p2==CCHR) {
|
||||
c = p2[1];
|
||||
do {
|
||||
if (*p1!=c)
|
||||
continue;
|
||||
if (advance(p1, p2))
|
||||
goto found;
|
||||
} while (*p1++);
|
||||
goto nfound;
|
||||
}
|
||||
/* regular algorithm */
|
||||
do {
|
||||
if (advance(p1, p2))
|
||||
goto found;
|
||||
} while (*p1++);
|
||||
nfound:
|
||||
if (vflag)
|
||||
succeed(file);
|
||||
continue;
|
||||
found:
|
||||
if (vflag==0)
|
||||
succeed(file);
|
||||
}
|
||||
}
|
||||
|
||||
advance(alp, aep)
|
||||
{
|
||||
register char *lp, *ep, *curlp;
|
||||
char *nextep;
|
||||
|
||||
lp = alp;
|
||||
ep = aep;
|
||||
for (;;) switch (*ep++) {
|
||||
|
||||
case CCHR:
|
||||
if (*ep++ == *lp++)
|
||||
continue;
|
||||
return(0);
|
||||
|
||||
case CDOT:
|
||||
if (*lp++)
|
||||
continue;
|
||||
return(0);
|
||||
|
||||
case CDOL:
|
||||
if (*lp==0)
|
||||
continue;
|
||||
return(0);
|
||||
|
||||
case CEOF:
|
||||
return(1);
|
||||
|
||||
case CCL:
|
||||
if (cclass(ep, *lp++, 1)) {
|
||||
ep =+ *ep;
|
||||
continue;
|
||||
}
|
||||
return(0);
|
||||
|
||||
case NCCL:
|
||||
if (cclass(ep, *lp++, 0)) {
|
||||
ep =+ *ep;
|
||||
continue;
|
||||
}
|
||||
return(0);
|
||||
|
||||
case CDOT|STAR:
|
||||
curlp = lp;
|
||||
while (*lp++);
|
||||
goto star;
|
||||
|
||||
case CCHR|STAR:
|
||||
curlp = lp;
|
||||
while (*lp++ == *ep);
|
||||
ep++;
|
||||
goto star;
|
||||
|
||||
case CCL|STAR:
|
||||
case NCCL|STAR:
|
||||
curlp = lp;
|
||||
while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)));
|
||||
ep =+ *ep;
|
||||
goto star;
|
||||
|
||||
star:
|
||||
do {
|
||||
lp--;
|
||||
if (advance(lp, ep))
|
||||
return(1);
|
||||
} while (lp > curlp);
|
||||
return(0);
|
||||
|
||||
default:
|
||||
printf2("RE botch\n");
|
||||
}
|
||||
}
|
||||
|
||||
cclass(aset, ac, af)
|
||||
{
|
||||
register char *set, c;
|
||||
register n;
|
||||
|
||||
set = aset;
|
||||
if ((c = ac) == 0)
|
||||
return(0);
|
||||
n = *set++;
|
||||
while (--n)
|
||||
if (*set++ == c)
|
||||
return(af);
|
||||
return(!af);
|
||||
}
|
||||
|
||||
printf2(s, a)
|
||||
{
|
||||
extern fout;
|
||||
flush();
|
||||
fout = 2;
|
||||
printf(s, a);
|
||||
flush();
|
||||
exit(2);
|
||||
}
|
||||
|
||||
succeed(f)
|
||||
{
|
||||
if (cflag) {
|
||||
if (++tln[1]==0)
|
||||
tln[0]++;
|
||||
return;
|
||||
}
|
||||
if (nfile > 1)
|
||||
printf("%s:", f);
|
||||
if (bflag)
|
||||
printf("%l:", blkno);
|
||||
if (nflag)
|
||||
printf("%s:", locv(lnum[0], lnum[1]));
|
||||
printf("%s\n", linebuf);
|
||||
}
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
#define PLOT 006 /* ack */
|
||||
#define BEL 007 /* exit plot mode */
|
||||
#define ESC 033 /* escape */
|
||||
#define HFWD '9'
|
||||
#define HREV '8'
|
||||
#define FREV '7'
|
||||
#define SO 016 /* shift out - enter greek */
|
||||
#define SI 017 /* shift in */
|
||||
#define UP 013
|
||||
#define DN 012
|
||||
#define RT ' '
|
||||
#define LF '\b'
|
||||
|
||||
int restore();
|
||||
int svmode, mode[3];
|
||||
|
||||
main(argc,argv) int argc; char **argv; {
|
||||
int c, textmode;
|
||||
extern int fin,fout;
|
||||
fin = dup(0);
|
||||
fout = dup(1);
|
||||
if ((signal(2, 1) & 01) == 0)
|
||||
signal(2, &restore);
|
||||
gtty(1, mode);
|
||||
svmode = mode[2];
|
||||
mode[2] =& 0777757; /* turn off cr-lf */
|
||||
mode[2] =| 03; /* turn off delays, tabs */
|
||||
stty(1, mode);
|
||||
textmode = 1;
|
||||
while( (c=getchar()) != '\0' ){
|
||||
if( c==SO ){
|
||||
special();
|
||||
continue;
|
||||
}
|
||||
if (c== PLOT) textmode = 1-textmode;
|
||||
if (c==BEL) textmode = 1;
|
||||
if( c=='\n' && textmode )
|
||||
putchar(015); /* CR */
|
||||
if( c!=ESC ){
|
||||
putchar(c);
|
||||
continue;
|
||||
}
|
||||
putchar(PLOT);
|
||||
c = getchar();
|
||||
if( c == HREV )
|
||||
nplot(4,UP);
|
||||
else if( c == HFWD )
|
||||
nplot(4,DN);
|
||||
else if( c == FREV )
|
||||
nplot(8,UP);
|
||||
putchar(PLOT);
|
||||
}
|
||||
flush();
|
||||
restore();
|
||||
}
|
||||
|
||||
restore(){
|
||||
mode[2] = svmode;
|
||||
stty(1, mode);
|
||||
exit();
|
||||
}
|
||||
|
||||
int tab[]{
|
||||
'A', /* alpha */
|
||||
'B', /* beta */
|
||||
'D', /* delta */
|
||||
'W', /* DELTA */
|
||||
'S', /* epsilon */
|
||||
'N', /* eta */
|
||||
'\\', /* gamma */
|
||||
'G', /* GAMMA */
|
||||
'o', /* infinity - not in M37 */
|
||||
'^', /* integral */
|
||||
'L', /* lambda */
|
||||
'E', /* LAMBDA */
|
||||
'M', /* mu */
|
||||
'[', /* nabla (del) */
|
||||
'_', /* not */
|
||||
'@', /* nu */
|
||||
'C', /* omega */
|
||||
'Z', /* OMEGA */
|
||||
']', /* partial */
|
||||
'U', /* phi */
|
||||
'F', /* PHI */
|
||||
'V', /* psi */
|
||||
'H', /* PSI */
|
||||
'J', /* pi */
|
||||
'P', /* PI */
|
||||
'K', /* rho */
|
||||
'Y', /* sigma */
|
||||
'R', /* SIGMA */
|
||||
'I', /* tau */
|
||||
'T', /* theta */
|
||||
'O', /* THETA */
|
||||
'X', /* xi */
|
||||
'Q', /* zeta */
|
||||
0
|
||||
};
|
||||
int trans[]{
|
||||
alpha,
|
||||
beta,
|
||||
delta,
|
||||
DELTA,
|
||||
epsilon,
|
||||
eta,
|
||||
gamma,
|
||||
GAMMA,
|
||||
infinity,
|
||||
integral,
|
||||
lambda,
|
||||
LAMBDA,
|
||||
mu,
|
||||
nabla,
|
||||
not,
|
||||
nu,
|
||||
omega,
|
||||
OMEGA,
|
||||
partial,
|
||||
phi,
|
||||
PHI,
|
||||
psi,
|
||||
PSI,
|
||||
pi,
|
||||
PI,
|
||||
rho,
|
||||
sigma,
|
||||
SIGMA,
|
||||
tau,
|
||||
theta,
|
||||
THETA,
|
||||
xi,
|
||||
zeta,
|
||||
0
|
||||
};
|
||||
|
||||
int alpha[] {LF,'c',RT,RT,'(',LF,0};
|
||||
int beta[] {'B',LF,LF,DN,DN,'|',RT,RT,UP,UP,0};
|
||||
int delta[] {'o',UP,UP,'<',DN,DN,0};
|
||||
int DELTA[] {LF,LF,'/',-3,DN,'-',-4,RT,'-',-3,UP,'\\',LF,LF,0};
|
||||
int epsilon[] {'<','-',0};
|
||||
int eta[] {'n',RT,RT,DN,DN,'|',LF,LF,UP,UP,0};
|
||||
int gamma[] {')',RT,'/',LF,0};
|
||||
int GAMMA[] {LF,LF,'|',RT,RT,-3,UP,'-',-3,DN,RT,RT,'`',LF,LF,0};
|
||||
int infinity[] {LF,LF,'c',-4,RT,'o',LF,LF,0};
|
||||
int integral[] {'|','\'',RT,RT,'`',-3,LF,-6,DN,'\'',LF,'`',RT,RT,-6,UP,0};
|
||||
int lambda[] {'\\',-4,DN,LF,'\'',DN,LF,'\'',-5,UP,RT,RT,0};
|
||||
int LAMBDA[] {LF,LF,'/',-4,RT,'\\',LF,LF,0};
|
||||
int mu[] {'u',LF,LF,',',RT,RT,0};
|
||||
int nabla[] {LF,LF,'\\',-3,UP,'-',-4,RT,'-',-3,DN,'/',LF,LF,0};
|
||||
int not[] {'-',-2,RT,UP,',',DN,-2,LF,0};
|
||||
int nu[] {LF,'(',-3,RT,'/',LF,LF,0};
|
||||
int omega[] {LF,'u',-3,RT,'u',LF,LF,0};
|
||||
int OMEGA[] {'O',DN,DN,LF,'-',RT,RT,'-',LF,UP,UP,0};
|
||||
int partial[] {'o',RT,DN,'`',LF,UP,'`',LF,UP,'`',RT,DN,0};
|
||||
int phi[] {'o','/',0};
|
||||
int PHI[] {'o','[',']',0};
|
||||
int psi[] {'/','-',DN,DN,RT,RT,'\'',-4,LF,'\'',RT,RT,UP,UP,0};
|
||||
int PSI[] {'[',']','-',DN,DN,RT,RT,'\'',-4,LF,'`',RT,RT,UP,UP,0};
|
||||
int pi[] {UP,'-',-3,DN,'"',DN,'"',-3,UP,0};
|
||||
int PI[] {LF,LF,'[',']',-4,RT,'[',']',LF,LF,-3,UP,'-',-3,DN,0};
|
||||
int rho[] {'o',LF,LF,DN,DN,'|',UP,UP,RT,RT,0};
|
||||
int sigma[] {'o',DN,RT,RT,'~',UP,LF,LF,0};
|
||||
int SIGMA[] {'>',-2,DN,'-',-5,UP,'-',-3,DN,0};
|
||||
int tau[] {'t',DN,RT,RT,'~',LF,LF,LF,'~',RT,UP,0};
|
||||
int theta[] {'O','-',0};
|
||||
int THETA[] {'O','=',0};
|
||||
int xi[] {'c',RT,DN,',',LF,-3,UP,'c',LF,DN,'`',RT,DN,0};
|
||||
int zeta[] {'c',RT,DN,',',LF,-3,UP,'<',DN,DN,0};
|
||||
|
||||
special(){
|
||||
int c,i,j,t;
|
||||
loop:
|
||||
if( (c=getchar()) == SI )
|
||||
return;
|
||||
for( i=0; tab[i]!=0; i++)
|
||||
if( c==tab[i] ){
|
||||
plot(trans[i]);
|
||||
goto loop;
|
||||
}
|
||||
putchar(c);
|
||||
goto loop;
|
||||
}
|
||||
|
||||
plot(s) int *s; {
|
||||
int i,c;
|
||||
putchar(PLOT);
|
||||
for( i=0; (c=s[i])!=0; i++ )
|
||||
if( c<0 )
|
||||
nplot(-c,s[++i]);
|
||||
else
|
||||
putchar(c);
|
||||
putchar(PLOT);
|
||||
putchar(' ');
|
||||
}
|
||||
|
||||
nplot(n,c) int n,c; {
|
||||
while(n--)
|
||||
putchar(c);
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
#
|
||||
|
||||
char *dargv[]
|
||||
{
|
||||
"/dev/rrk2",
|
||||
"/dev/rrp0",
|
||||
0
|
||||
};
|
||||
#define NINODE 16*16
|
||||
#define NB 10
|
||||
#include "/usr/sys/ino.h"
|
||||
#include "/usr/sys/filsys.h"
|
||||
|
||||
struct inode inode[NINODE];
|
||||
struct filsys sblock;
|
||||
|
||||
int sflg;
|
||||
|
||||
int fi;
|
||||
int nifiles;
|
||||
int nfile;
|
||||
int nspcl;
|
||||
int nlarg;
|
||||
int nvlarg;
|
||||
int nindir;
|
||||
int nvindir;
|
||||
int ndir;
|
||||
int nused;
|
||||
int nfree;
|
||||
int ino;
|
||||
int ndup;
|
||||
int blist[10] { -1};
|
||||
int nerror;
|
||||
int bmap[4096];
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
register char **p;
|
||||
register int n, *lp;
|
||||
|
||||
if (argc == 1) {
|
||||
for (p = dargv; *p;)
|
||||
check(*p++);
|
||||
return(nerror);
|
||||
}
|
||||
while (--argc) {
|
||||
argv++;
|
||||
if (**argv=='-') switch ((*argv)[1]) {
|
||||
case 's':
|
||||
sflg++;
|
||||
continue;
|
||||
|
||||
case 'b':
|
||||
lp = blist;
|
||||
while (lp < &blist[NB-1] && (n = number(argv[1]))) {
|
||||
*lp++ = n;
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
*lp++ = -1;
|
||||
continue;
|
||||
|
||||
default:
|
||||
printf("Bad flag\n");
|
||||
}
|
||||
check(*argv);
|
||||
}
|
||||
return(nerror);
|
||||
}
|
||||
|
||||
check(file)
|
||||
char *file;
|
||||
{
|
||||
register *ip, i, j;
|
||||
|
||||
fi = open(file, sflg?2:0);
|
||||
if (fi < 0) {
|
||||
printf("cannot open %s\n", file);
|
||||
nerror =| 04;
|
||||
return;
|
||||
}
|
||||
printf("%s:\n", file);
|
||||
nfile = 0;
|
||||
nspcl = 0;
|
||||
nlarg = 0;
|
||||
nvlarg = 0;
|
||||
nindir = 0;
|
||||
nvindir = 0;
|
||||
ndir = 0;
|
||||
nused = 0;
|
||||
nfree = 0;
|
||||
ndup = 0;
|
||||
for (ip = bmap; ip < &bmap[4096];)
|
||||
*ip++ = 0;
|
||||
sync();
|
||||
bread(1, &sblock, 512);
|
||||
nifiles = sblock.s_isize*16;
|
||||
for(i=0; ino < nifiles; i =+ NINODE/16) {
|
||||
bread(i+2, inode, sizeof inode);
|
||||
for(j=0; j<NINODE && ino<nifiles; j++) {
|
||||
ino++;
|
||||
pass1(&inode[j]);
|
||||
}
|
||||
}
|
||||
ino = 0;
|
||||
sync();
|
||||
bread(1, &sblock, 512);
|
||||
if (sflg) {
|
||||
makefree();
|
||||
return;
|
||||
}
|
||||
while(i = alloc()) {
|
||||
if (chk(i, "free"))
|
||||
break;
|
||||
nfree++;
|
||||
}
|
||||
if (ndup) {
|
||||
printf("%l dups in free\n", ndup);
|
||||
nerror =| 02;
|
||||
}
|
||||
j = 0;
|
||||
for (ip = bmap; ip < &bmap[4096];) {
|
||||
i = *ip++;
|
||||
while (i) {
|
||||
if (i<0)
|
||||
j--;
|
||||
i =<< 1;
|
||||
}
|
||||
}
|
||||
j =+ sblock.s_fsize - sblock.s_isize - 2;
|
||||
if (j)
|
||||
printf("missing%5l\n", j);
|
||||
printf("spcl %6l\n", nspcl);
|
||||
printf("files %6l\n", nfile);
|
||||
printf("large %6l\n", nlarg);
|
||||
if (nvlarg)
|
||||
printf("huge %6l\n", nvlarg);
|
||||
printf("direc %6l\n", ndir);
|
||||
printf("indir %6l\n", nindir);
|
||||
if (nvindir)
|
||||
printf("indir2%6l\n", nvindir);
|
||||
printf("used %6l\n", nused);
|
||||
printf("free %6l\n", nfree);
|
||||
close(fi);
|
||||
}
|
||||
|
||||
pass1(aip)
|
||||
struct inode *aip;
|
||||
{
|
||||
int buf[256], vbuf[256];
|
||||
register i, j, *ip;
|
||||
|
||||
ip = aip;
|
||||
if ((ip->i_mode&IALLOC) == 0)
|
||||
return;
|
||||
if ((ip->i_mode&IFCHR&IFBLK) != 0) {
|
||||
nspcl++;
|
||||
return;
|
||||
}
|
||||
if ((ip->i_mode&IFMT) == IFDIR)
|
||||
ndir++;
|
||||
else
|
||||
nfile++;
|
||||
if ((ip->i_mode&ILARG) != 0) {
|
||||
nlarg++;
|
||||
for(i=0; i<7; i++)
|
||||
if (ip->i_addr[i] != 0) {
|
||||
nindir++;
|
||||
if (chk(ip->i_addr[i], "indirect"))
|
||||
continue;
|
||||
bread(ip->i_addr[i], buf, 512);
|
||||
for(j=0; j<256; j++)
|
||||
if (buf[j] != 0)
|
||||
chk(buf[j], "data (large)");
|
||||
}
|
||||
if (ip->i_addr[7]) {
|
||||
nvlarg++;
|
||||
if (chk(ip->i_addr[7], "indirect"))
|
||||
return;
|
||||
bread(ip->i_addr[7], buf, 512);
|
||||
for(i=0; i<256; i++)
|
||||
if (buf[i] != 0) {
|
||||
nvindir++;
|
||||
if (chk(buf[i], "2nd indirect"))
|
||||
continue;
|
||||
bread(buf[i], vbuf, 512);
|
||||
for(j=0; j<256; j++)
|
||||
if (vbuf[j])
|
||||
chk(vbuf[j], "data (very large)");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
for(i=0; i<8; i++) {
|
||||
if (ip->i_addr[i] != 0)
|
||||
chk(ip->i_addr[i], "data (small)");
|
||||
}
|
||||
}
|
||||
|
||||
chk(ab, s)
|
||||
char *ab;
|
||||
{
|
||||
register char *b;
|
||||
register n, m;
|
||||
|
||||
b = ab;
|
||||
if (ino)
|
||||
nused++;
|
||||
if (b<sblock.s_isize+2 || b>=sblock.s_fsize) {
|
||||
printf("%l bad; inode=%l, class=%s\n", b, ino, s);
|
||||
return(1);
|
||||
}
|
||||
m = 1 << (b&017);
|
||||
n = (b>>4) & 07777;
|
||||
if (bmap[n]&m) {
|
||||
printf("%l dup; inode=%l, class=%s\n", b, ino, s);
|
||||
ndup++;
|
||||
}
|
||||
bmap[n] =| m;
|
||||
for (n=0; blist[n] != -1; n++)
|
||||
if (b == blist[n])
|
||||
printf("%l arg; inode=%l, class=%s\n", b, ino, s);
|
||||
return(0);
|
||||
}
|
||||
|
||||
alloc()
|
||||
{
|
||||
register b, i;
|
||||
int buf[256];
|
||||
|
||||
i = --sblock.s_nfree;
|
||||
if (i<0 || i>=100) {
|
||||
printf("bad freeblock\n");
|
||||
return(0);
|
||||
}
|
||||
b = sblock.s_free[i];
|
||||
if (b == 0)
|
||||
return(0);
|
||||
if (sblock.s_nfree <= 0) {
|
||||
bread(b, buf, 512);
|
||||
sblock.s_nfree = buf[0];
|
||||
for(i=0; i<100; i++)
|
||||
sblock.s_free[i] = buf[i+1];
|
||||
}
|
||||
return(b);
|
||||
}
|
||||
|
||||
bread(bno, buf, cnt)
|
||||
int *buf;
|
||||
{
|
||||
register *ip;
|
||||
|
||||
seek(fi, bno, 3);
|
||||
if (read(fi, buf, cnt) != cnt) {
|
||||
printf("read error %d\n", bno);
|
||||
if (sflg) {
|
||||
printf("No update\n");
|
||||
sflg = 0;
|
||||
}
|
||||
for (ip = buf; ip < &buf[256];)
|
||||
*ip++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
free(in)
|
||||
{
|
||||
register i;
|
||||
int buf[256];
|
||||
|
||||
if (sblock.s_nfree >= 100) {
|
||||
buf[0] = sblock.s_nfree;
|
||||
for(i=0; i<100; i++)
|
||||
buf[i+1] = sblock.s_free[i];
|
||||
sblock.s_nfree = 0;
|
||||
bwrite(in, buf);
|
||||
}
|
||||
sblock.s_free[sblock.s_nfree++] = in;
|
||||
}
|
||||
|
||||
bwrite(bno, buf)
|
||||
{
|
||||
|
||||
seek(fi, bno, 3);
|
||||
if (write(fi, buf, 512) != 512)
|
||||
printf("write error %d\n", bno);
|
||||
}
|
||||
|
||||
number(as)
|
||||
char *as;
|
||||
{
|
||||
register n, c;
|
||||
register char *s;
|
||||
|
||||
s = as;
|
||||
n = 0;
|
||||
while ((c = *s++) >= '0' && c <= '9') {
|
||||
n = n*10+c-'0';
|
||||
}
|
||||
return(n);
|
||||
}
|
||||
|
||||
makefree()
|
||||
{
|
||||
register i;
|
||||
|
||||
sblock.s_nfree = 0;
|
||||
sblock.s_ninode = 0;
|
||||
sblock.s_flock = 0;
|
||||
sblock.s_ilock = 0;
|
||||
sblock.s_fmod = 0;
|
||||
free(0);
|
||||
for(i=sblock.s_fsize-1; i>=sblock.s_isize+2; i--) {
|
||||
if ((bmap[(i>>4)&07777] & (1<<(i&017)))==0)
|
||||
free(i);
|
||||
}
|
||||
bwrite(1, &sblock);
|
||||
close(fi);
|
||||
sync();
|
||||
return;
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
/* if command */
|
||||
|
||||
int ap;
|
||||
int ac;
|
||||
char **av;
|
||||
|
||||
main(argc, argv)
|
||||
char *argv[];
|
||||
{
|
||||
|
||||
argv[argc] = 0;
|
||||
ac = argc; av = argv; ap = 1;
|
||||
if (argc<2) return;
|
||||
if (exp())
|
||||
if(doex(0)) {
|
||||
write(1, "no command\n", 11);
|
||||
seek(0, 0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
char *nxtarg() {
|
||||
|
||||
if (ap>ac) return(0*ap++);
|
||||
return(av[ap++]);
|
||||
}
|
||||
|
||||
exp(s) {
|
||||
int p1;
|
||||
|
||||
p1 = e1();
|
||||
if (eq(nxtarg(), "-o")) return(p1 | exp());
|
||||
ap--;
|
||||
return(p1);
|
||||
}
|
||||
|
||||
e1() {
|
||||
int p1;
|
||||
|
||||
p1 = e2();
|
||||
if (eq(nxtarg(), "-a")) return (p1 & e1());
|
||||
ap--;
|
||||
return(p1);
|
||||
}
|
||||
|
||||
e2() {
|
||||
if (eq(nxtarg(), "!"))
|
||||
return(!e3());
|
||||
ap--;
|
||||
return(e3());
|
||||
}
|
||||
|
||||
e3() {
|
||||
int p1, ccode;
|
||||
register char *a;
|
||||
|
||||
ccode = 0;
|
||||
if ((a=nxtarg())==0) goto err;
|
||||
if(eq(a, "(")) {
|
||||
p1 = exp();
|
||||
if(!eq(nxtarg(), ")")) goto err;
|
||||
return(p1);
|
||||
}
|
||||
|
||||
if(eq(a, "-r"))
|
||||
return(tio(nxtarg(), 0));
|
||||
|
||||
if(eq(a, "-w"))
|
||||
return(tio(nxtarg(), 1));
|
||||
|
||||
if(eq(a, "-c"))
|
||||
return(tcreat(nxtarg()));
|
||||
|
||||
if(eq(a, "{")) { /* execute a command for exit code */
|
||||
if(fork()) /*parent*/ wait(&ccode);
|
||||
else { /*child*/
|
||||
doex(1);
|
||||
goto err;
|
||||
}
|
||||
while((a=nxtarg()) && (!eq(a,"}")));
|
||||
return(ccode? 0 : 1);
|
||||
}
|
||||
|
||||
p1 = nxtarg();
|
||||
if (p1==0) goto err;
|
||||
if(eq(p1, "="))
|
||||
return(eq(a, nxtarg()));
|
||||
|
||||
if(eq(p1, "!="))
|
||||
return(!eq(a, nxtarg()));
|
||||
err:
|
||||
write(1, "if error\n", 9);
|
||||
exit(9);
|
||||
}
|
||||
|
||||
tio(a, f) {
|
||||
|
||||
a = open(a, f);
|
||||
if (a>=0) {
|
||||
close(a);
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
tcreat(a) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
eq(a, b)
|
||||
char *a, *b;
|
||||
{
|
||||
register int i;
|
||||
|
||||
i = 0;
|
||||
l:
|
||||
if(a[i] != b[i])
|
||||
return(0);
|
||||
if(a[i++] == '\0')
|
||||
return(1);
|
||||
goto l;
|
||||
}
|
||||
|
||||
doex(earg) {
|
||||
|
||||
register int np, i, c;
|
||||
char *nargv[50], *ncom, *na;
|
||||
|
||||
np = 0;
|
||||
while (na=nxtarg()) {
|
||||
if(earg && eq(na,"}")) break;
|
||||
nargv[np++] = na;
|
||||
}
|
||||
if(earg && (!eq(na, "}"))) return(9);
|
||||
nargv[np] = 0;
|
||||
if (np==0) return(earg);
|
||||
execv(nargv[0], nargv, np);
|
||||
i = 0;
|
||||
ncom = "/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
while(c=nargv[0][i]) {
|
||||
ncom[9+i++] = c;
|
||||
}
|
||||
ncom[9+i] = '\0';
|
||||
execv(ncom+4, nargv, np);
|
||||
execv(ncom, nargv, np);
|
||||
return(1);
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
#define tabsize 20
|
||||
#define all p = &itab[0]; p < &itab[20]; p++
|
||||
#define ever ;;
|
||||
#define single 0173030
|
||||
#define reboot 0173040
|
||||
char shell[] "/bin/sh";
|
||||
char minus[] "-";
|
||||
char runc[] "/etc/rc";
|
||||
char init[] "/etc/init";
|
||||
char ifile[] "/etc/ttys";
|
||||
char utmp[] "/etc/utmp";
|
||||
char wtmpf[] "/usr/adm/wtmp";
|
||||
char ctty[] "/dev/tty8";
|
||||
int fi;
|
||||
struct
|
||||
{
|
||||
int flag;
|
||||
int line;
|
||||
char coms[2];
|
||||
} line;
|
||||
struct tab
|
||||
{
|
||||
int pid;
|
||||
int line;
|
||||
int comn;
|
||||
} itab[tabsize];
|
||||
|
||||
struct {
|
||||
char name[8];
|
||||
char tty;
|
||||
char fill;
|
||||
int time[2];
|
||||
int wfill;
|
||||
} wtmp;
|
||||
|
||||
main()
|
||||
{
|
||||
register i;
|
||||
register struct tab *p, *q;
|
||||
int reset();
|
||||
|
||||
/*
|
||||
* if not single user,
|
||||
* run shell sequence
|
||||
*/
|
||||
|
||||
if(getcsw() != single) {
|
||||
i = fork();
|
||||
if(i == 0) {
|
||||
open("/", 0);
|
||||
dup(0);
|
||||
dup(0);
|
||||
execl(shell, shell, runc, 0);
|
||||
exit();
|
||||
}
|
||||
while(wait() != i);
|
||||
close(creat(utmp, 0644));
|
||||
if ((i = open(wtmpf, 1)) >= 0) {
|
||||
seek(i, 0, 2);
|
||||
wtmp.tty = '~';
|
||||
time(wtmp.time);
|
||||
write(i, &wtmp, 16);
|
||||
close(i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* main loop for hangup signal
|
||||
* close all files and
|
||||
* check switches for magic values
|
||||
*/
|
||||
|
||||
setexit();
|
||||
signal(1, reset);
|
||||
for(i=0; i<10; i++)
|
||||
close(i);
|
||||
switch(getcsw()) {
|
||||
|
||||
case single:
|
||||
error:
|
||||
termall();
|
||||
i = fork();
|
||||
if(i == 0) {
|
||||
open(ctty, 2);
|
||||
dup(0);
|
||||
execl(shell, minus, 0);
|
||||
exit();
|
||||
}
|
||||
while(wait() != i);
|
||||
|
||||
case reboot:
|
||||
termall();
|
||||
execl(init, minus, 0);
|
||||
reset();
|
||||
}
|
||||
|
||||
/*
|
||||
* open and merge in init file
|
||||
*/
|
||||
|
||||
fi = open(ifile, 0);
|
||||
q = &itab[0];
|
||||
while(rline()) {
|
||||
if(line.flag == '0')
|
||||
continue;
|
||||
for(all)
|
||||
if(p->line==line.line || p->line==0) {
|
||||
if(p >= q) {
|
||||
i = p->pid;
|
||||
p->pid = q->pid;
|
||||
q->pid = i;
|
||||
p->line = q->line;
|
||||
p->comn = q->comn;
|
||||
q->line = line.line;
|
||||
q->coms[0] = line.comn;
|
||||
q++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(fi);
|
||||
if(q == &itab[0])
|
||||
goto error;
|
||||
for(; q < &itab[tabsize]; q++)
|
||||
term(q);
|
||||
for(all)
|
||||
if(p->line != 0 && p->pid == 0)
|
||||
dfork(p);
|
||||
for(ever) {
|
||||
i = wait();
|
||||
for(all)
|
||||
if(p->pid == i) {
|
||||
rmut(p);
|
||||
dfork(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
termall()
|
||||
{
|
||||
register struct tab *p;
|
||||
|
||||
for(all)
|
||||
term(p);
|
||||
}
|
||||
|
||||
term(ap)
|
||||
struct tab *ap;
|
||||
{
|
||||
register struct tab *p;
|
||||
|
||||
p = ap;
|
||||
if(p->pid != 0) {
|
||||
rmut(p);
|
||||
kill(p->pid, 9);
|
||||
}
|
||||
p->pid = 0;
|
||||
p->line = 0;
|
||||
}
|
||||
|
||||
rline()
|
||||
{
|
||||
static char c[4];
|
||||
|
||||
if(read(fi, c, 4) != 4 || c[3] != '\n')
|
||||
return(0);
|
||||
line.flag = c[0];
|
||||
line.line = c[1];
|
||||
line.comn = c[2];
|
||||
return(1);
|
||||
}
|
||||
|
||||
dfork(ap)
|
||||
struct tab *ap;
|
||||
{
|
||||
register i;
|
||||
register char *tty;
|
||||
register struct tab *p;
|
||||
|
||||
p = ap;
|
||||
i = fork();
|
||||
if(i == 0) {
|
||||
signal(1, 0);
|
||||
tty = "/dev/ttyx";
|
||||
tty[8] = p->line;
|
||||
chown(tty, 0);
|
||||
chmod(tty, 0622);
|
||||
open(tty, 2);
|
||||
dup(0);
|
||||
execl("etc/getty", minus, p->coms, 0);
|
||||
exit();
|
||||
}
|
||||
p->pid = i;
|
||||
}
|
||||
|
||||
rmut(p)
|
||||
struct tab *p;
|
||||
{
|
||||
register i, f;
|
||||
static char zero[16];
|
||||
|
||||
f = open(utmp, 1);
|
||||
if(f >= 0) {
|
||||
i = p->line;
|
||||
if(i >= 'a')
|
||||
i =+ '0' + 10 - 'a';
|
||||
seek(f, (i-'0')*16, 0);
|
||||
write(f, zero, 16);
|
||||
close(f);
|
||||
}
|
||||
f = open(wtmpf, 1);
|
||||
if (f >= 0) {
|
||||
wtmp.tty = p->line;
|
||||
time(wtmp.time);
|
||||
seek(f, 0, 2);
|
||||
write(f, &wtmp, 16);
|
||||
close(f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/ kill process
|
||||
|
||||
mov (sp)+,r4
|
||||
tst (sp)+
|
||||
|
||||
loop:
|
||||
dec r4
|
||||
ble done
|
||||
mov (sp)+,r5
|
||||
clr r3
|
||||
cmpb (r5),$'-
|
||||
bne 1f
|
||||
inc r5
|
||||
clr signo
|
||||
1:
|
||||
movb (r5)+,r0
|
||||
beq 1f
|
||||
sub $'0,r0
|
||||
cmp r0,$9
|
||||
bhi error
|
||||
mul $10.,r3
|
||||
add r0,r3
|
||||
br 1b
|
||||
1:
|
||||
tst signo
|
||||
bne 1f
|
||||
tst r3
|
||||
ble error
|
||||
cmp r3,$12.
|
||||
bgt error
|
||||
mov r3,signo
|
||||
br loop
|
||||
1:
|
||||
mov r3,r0
|
||||
sys 37.; signo: 9. / kill
|
||||
bec loop
|
||||
mov r3,r0
|
||||
jsr pc,decml
|
||||
mov $1,r0
|
||||
sys write; m1; em1-m1
|
||||
br loop
|
||||
|
||||
error:
|
||||
mov $1,r0
|
||||
sys write; m2; em2-m2
|
||||
br loop
|
||||
|
||||
done:
|
||||
sys exit
|
||||
|
||||
decml:
|
||||
mov r0,r1
|
||||
clr r0
|
||||
div $10.,r0
|
||||
mov r1,-(sp)
|
||||
tst r0
|
||||
beq 1f
|
||||
jsr pc,decml
|
||||
1:
|
||||
mov (sp)+,r0
|
||||
add $'0,r0
|
||||
mov r0,ch
|
||||
mov $1,r0
|
||||
sys write; ch; 1
|
||||
rts pc
|
||||
|
||||
m1:
|
||||
<: not found\n>
|
||||
em1:
|
||||
m2:
|
||||
<non-numeric arg\n>
|
||||
em2:
|
||||
.bss
|
||||
ch: .=.+2
|
||||
+921
@@ -0,0 +1,921 @@
|
||||
#
|
||||
/*
|
||||
* link editor
|
||||
*/
|
||||
|
||||
#define SIGINT 2
|
||||
#define ARCMAGIC 0177555
|
||||
#define FMAGIC 0407
|
||||
#define NMAGIC 0410
|
||||
#define IMAGIC 0411
|
||||
|
||||
#define EXTERN 040
|
||||
#define UNDEF 00
|
||||
#define ABS 01
|
||||
#define TEXT 02
|
||||
#define DATA 03
|
||||
#define BSS 04
|
||||
#define COMM 05 /* internal use only */
|
||||
|
||||
#define RABS 00
|
||||
#define RTEXT 02
|
||||
#define RDATA 04
|
||||
#define RBSS 06
|
||||
#define REXT 010
|
||||
|
||||
#define RELFLG 01
|
||||
#define NROUT 256
|
||||
#define NSYM 501
|
||||
#define NSYMPR 500
|
||||
|
||||
#define RONLY 0400
|
||||
|
||||
char premeof[] "Premature EOF on %s";
|
||||
|
||||
struct page {
|
||||
int nuser;
|
||||
int bno;
|
||||
int nibuf;
|
||||
int buff[256];
|
||||
} page[2];
|
||||
|
||||
struct {
|
||||
int nuser;
|
||||
int bno;
|
||||
} fpage;
|
||||
|
||||
struct stream {
|
||||
int *ptr;
|
||||
int bno;
|
||||
int nibuf;
|
||||
int size;
|
||||
struct page *pno;
|
||||
};
|
||||
|
||||
struct stream text;
|
||||
struct stream reloc;
|
||||
|
||||
struct archdr {
|
||||
char aname[8];
|
||||
int atime[2];
|
||||
char auid, amode;
|
||||
int asize;
|
||||
} archdr;
|
||||
|
||||
struct filhdr {
|
||||
int fmagic;
|
||||
int tsize;
|
||||
int dsize;
|
||||
int bsize;
|
||||
int ssize;
|
||||
int entry;
|
||||
int pad;
|
||||
int relflg;
|
||||
} filhdr;
|
||||
|
||||
struct liblist {
|
||||
int off;
|
||||
int bno;
|
||||
};
|
||||
|
||||
struct liblist liblist[NROUT];
|
||||
struct liblist *libp { &liblist[0] };
|
||||
|
||||
struct symbol {
|
||||
char sname[8];
|
||||
char stype;
|
||||
char spad;
|
||||
int svalue;
|
||||
};
|
||||
|
||||
struct symbol cursym;
|
||||
struct symbol symtab[NSYM];
|
||||
struct symbol *hshtab[NSYM+2];
|
||||
struct symbol *symp { symtab };
|
||||
struct symbol **local[NSYMPR];
|
||||
struct symbol *p_etext;
|
||||
struct symbol *p_edata;
|
||||
struct symbol *p_end;
|
||||
|
||||
int xflag; /* discard local symbols */
|
||||
int Xflag; /* discard locals starting with 'L' */
|
||||
int rflag; /* preserve relocation bits, don't define common */
|
||||
int arflag; /* original copy of rflag */
|
||||
int sflag; /* discard all symbols */
|
||||
int nflag; /* pure procedure */
|
||||
int dflag; /* define common even with rflag */
|
||||
int iflag; /* I/D space separated */
|
||||
|
||||
int infil;
|
||||
char *filname;
|
||||
|
||||
int tsize;
|
||||
int dsize;
|
||||
int bsize;
|
||||
int ssize;
|
||||
int nsym;
|
||||
|
||||
int torigin;
|
||||
int dorigin;
|
||||
int borigin;
|
||||
|
||||
int ctrel;
|
||||
int cdrel;
|
||||
int cbrel;
|
||||
|
||||
int errlev;
|
||||
int delarg 4;
|
||||
char tfname[] "/tmp/lxyyyyy";
|
||||
int toutb[259];
|
||||
int doutb[259];
|
||||
int troutb[259];
|
||||
int droutb[259];
|
||||
int soutb[259];
|
||||
|
||||
struct symbol **lookup();
|
||||
struct symbol **slookup();
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
extern int delexit();
|
||||
register c;
|
||||
register char *ap, **p;
|
||||
struct symbol **hp;
|
||||
|
||||
if ((signal(SIGINT, 1) & 01) == 0)
|
||||
signal(SIGINT, delexit);
|
||||
if (argc == 1)
|
||||
exit(4);
|
||||
p = argv + 1;
|
||||
for (c = 1; c<argc; c++) {
|
||||
filname = 0;
|
||||
ap = *p++;
|
||||
if (*ap == '-') switch (ap[1]) {
|
||||
|
||||
case 'u':
|
||||
if (++c >= argc)
|
||||
error(1, "Bad 'use'");
|
||||
if (*(hp = slookup(*p++)) == 0) {
|
||||
*hp = symp;
|
||||
enter();
|
||||
}
|
||||
continue;
|
||||
|
||||
case 'l':
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
xflag++;
|
||||
continue;
|
||||
|
||||
case 'X':
|
||||
Xflag++;
|
||||
continue;
|
||||
|
||||
case 'r':
|
||||
rflag++;
|
||||
arflag++;
|
||||
continue;
|
||||
|
||||
case 's':
|
||||
sflag++;
|
||||
xflag++;
|
||||
continue;
|
||||
|
||||
case 'n':
|
||||
nflag++;
|
||||
continue;
|
||||
|
||||
case 'd':
|
||||
dflag++;
|
||||
continue;
|
||||
|
||||
case 'i':
|
||||
iflag++;
|
||||
continue;
|
||||
}
|
||||
load1arg(ap);
|
||||
close(infil);
|
||||
}
|
||||
middle();
|
||||
setupout();
|
||||
p = argv+1;
|
||||
libp = liblist;
|
||||
for (c=1; c<argc; c++) {
|
||||
ap = *p++;
|
||||
if (*ap == '-') switch (ap[1]) {
|
||||
|
||||
case 'u':
|
||||
++c;
|
||||
++p;
|
||||
default:
|
||||
continue;
|
||||
|
||||
case 'l':
|
||||
break;
|
||||
}
|
||||
load2arg(ap);
|
||||
close(infil);
|
||||
}
|
||||
finishout();
|
||||
}
|
||||
|
||||
load1arg(acp)
|
||||
char *acp;
|
||||
{
|
||||
register char *cp;
|
||||
register noff, nbno;
|
||||
|
||||
cp = acp;
|
||||
if (getfile(cp)==0) {
|
||||
load1(0, 0, 0);
|
||||
return;
|
||||
}
|
||||
nbno = 0;
|
||||
noff = 1;
|
||||
for (;;) {
|
||||
dseek(&text, nbno, noff, sizeof archdr);
|
||||
if (text.size <= 0) {
|
||||
libp->bno = -1;
|
||||
libp++;
|
||||
return;
|
||||
}
|
||||
mget(&archdr, sizeof archdr);
|
||||
if (load1(1, nbno, noff + (sizeof archdr) / 2)) {
|
||||
libp->bno = nbno;
|
||||
libp->off = noff;
|
||||
libp++;
|
||||
}
|
||||
noff =+ (archdr.asize + sizeof archdr)>>1;
|
||||
nbno =+ (noff >> 8) & 0377;
|
||||
noff =& 0377;
|
||||
}
|
||||
}
|
||||
|
||||
load1(libflg, bno, off)
|
||||
{
|
||||
register struct symbol *sp, **hp, ***cp;
|
||||
struct symbol *ssymp;
|
||||
int ndef, nloc;
|
||||
|
||||
readhdr(bno, off);
|
||||
ctrel = tsize;
|
||||
cdrel =+ dsize;
|
||||
cbrel =+ bsize;
|
||||
ndef = 0;
|
||||
nloc = sizeof cursym;
|
||||
cp = local;
|
||||
ssymp = symp;
|
||||
if ((filhdr.relflg&RELFLG)==1) {
|
||||
error(0, "No relocation bits");
|
||||
return(0);
|
||||
}
|
||||
off =+ (sizeof filhdr)/2 + filhdr.tsize + filhdr.dsize;
|
||||
dseek(&text, bno, off, filhdr.ssize);
|
||||
while (text.size > 0) {
|
||||
mget(&cursym, sizeof cursym);
|
||||
if ((cursym.stype&EXTERN)==0) {
|
||||
if (Xflag==0 || cursym.sname[0]!='L')
|
||||
nloc =+ sizeof cursym;
|
||||
continue;
|
||||
}
|
||||
symreloc();
|
||||
hp = lookup();
|
||||
if ((sp = *hp) == 0) {
|
||||
*hp = enter();
|
||||
*cp++ = hp;
|
||||
continue;
|
||||
}
|
||||
if (sp->stype != EXTERN+UNDEF)
|
||||
continue;
|
||||
if (cursym.stype == EXTERN+UNDEF) {
|
||||
if (cursym.svalue > sp->svalue)
|
||||
sp->svalue = cursym.svalue;
|
||||
continue;
|
||||
}
|
||||
if (sp->svalue != 0 && cursym.stype == EXTERN+TEXT)
|
||||
continue;
|
||||
ndef++;
|
||||
sp->stype = cursym.stype;
|
||||
sp->svalue = cursym.svalue;
|
||||
}
|
||||
if (libflg==0 || ndef) {
|
||||
tsize =+ filhdr.tsize;
|
||||
dsize =+ filhdr.dsize;
|
||||
bsize =+ filhdr.bsize;
|
||||
ssize =+ nloc;
|
||||
return(1);
|
||||
}
|
||||
/*
|
||||
* No symbols defined by this library member.
|
||||
* Rip out the hash table entries and reset the symbol table.
|
||||
*/
|
||||
symp = ssymp;
|
||||
while (cp > local)
|
||||
**--cp = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
middle()
|
||||
{
|
||||
register struct symbol *sp;
|
||||
register t, csize;
|
||||
int nund, corigin;
|
||||
|
||||
p_etext = *slookup("_etext");
|
||||
p_edata = *slookup("_edata");
|
||||
p_end = *slookup("_end");
|
||||
/*
|
||||
* If there are any undefined symbols, save the relocation bits.
|
||||
*/
|
||||
if (rflag==0) for (sp=symtab; sp<symp; sp++)
|
||||
if (sp->stype==EXTERN+UNDEF && sp->svalue==0
|
||||
&& sp!=p_end && sp!=p_edata && sp!=p_etext) {
|
||||
rflag++;
|
||||
dflag = 0;
|
||||
nflag = 0;
|
||||
iflag = 0;
|
||||
sflag = 0;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Assign common locations.
|
||||
*/
|
||||
csize = 0;
|
||||
if (dflag || rflag==0) {
|
||||
for (sp=symtab; sp<symp; sp++)
|
||||
if (sp->stype==EXTERN+UNDEF && (t=sp->svalue)!=0) {
|
||||
t = (t+1) & ~01;
|
||||
sp->svalue = csize;
|
||||
sp->stype = EXTERN+COMM;
|
||||
csize =+ t;
|
||||
}
|
||||
if (p_etext && p_etext->stype==EXTERN+UNDEF) {
|
||||
p_etext->stype = EXTERN+TEXT;
|
||||
p_etext->svalue = tsize;
|
||||
}
|
||||
if (p_edata && p_edata->stype==EXTERN+UNDEF) {
|
||||
p_edata->stype = EXTERN+DATA;
|
||||
p_edata->svalue = dsize;
|
||||
}
|
||||
if (p_end && p_end->stype==EXTERN+UNDEF) {
|
||||
p_end->stype = EXTERN+BSS;
|
||||
p_end->svalue = bsize;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Now set symbols to their final value
|
||||
*/
|
||||
if (nflag || iflag)
|
||||
tsize = (tsize + 077) & ~077;
|
||||
dorigin = tsize;
|
||||
if (nflag)
|
||||
dorigin = (tsize+017777) & ~017777;
|
||||
if (iflag)
|
||||
dorigin = 0;
|
||||
corigin = dorigin + dsize;
|
||||
borigin = corigin + csize;
|
||||
nund = 0;
|
||||
for (sp=symtab; sp<symp; sp++) switch (sp->stype) {
|
||||
case EXTERN+UNDEF:
|
||||
errlev =| 01;
|
||||
if (arflag==0 && sp->svalue==0) {
|
||||
if (nund==0)
|
||||
printf("Undefined:\n");
|
||||
nund++;
|
||||
printf("%.8s\n", sp->sname);
|
||||
}
|
||||
continue;
|
||||
|
||||
case EXTERN+ABS:
|
||||
default:
|
||||
continue;
|
||||
|
||||
case EXTERN+TEXT:
|
||||
sp->svalue =+ torigin;
|
||||
continue;
|
||||
|
||||
case EXTERN+DATA:
|
||||
sp->svalue =+ dorigin;
|
||||
continue;
|
||||
|
||||
case EXTERN+BSS:
|
||||
sp->svalue =+ borigin;
|
||||
continue;
|
||||
|
||||
case EXTERN+COMM:
|
||||
sp->stype = EXTERN+BSS;
|
||||
sp->svalue =+ corigin;
|
||||
continue;
|
||||
}
|
||||
if (sflag || xflag)
|
||||
ssize = 0;
|
||||
bsize =+ csize;
|
||||
nsym = ssize / (sizeof cursym);
|
||||
}
|
||||
|
||||
setupout()
|
||||
{
|
||||
register char *p;
|
||||
register pid;
|
||||
|
||||
if ((toutb[0] = creat("l.out", 0666)) < 0)
|
||||
error(1, "Can't create l.out");
|
||||
pid = getpid();
|
||||
for (p = &tfname[12]; p > &tfname[7];) {
|
||||
*--p = (pid&07) + '0';
|
||||
pid =>> 3;
|
||||
}
|
||||
tcreat(doutb, 'a');
|
||||
if (sflag==0 || xflag==0)
|
||||
tcreat(soutb, 'b');
|
||||
if (rflag) {
|
||||
tcreat(troutb, 'c');
|
||||
tcreat(droutb, 'd');
|
||||
}
|
||||
filhdr.fmagic = FMAGIC;
|
||||
if (nflag)
|
||||
filhdr.fmagic = NMAGIC;
|
||||
if (iflag)
|
||||
filhdr.fmagic = IMAGIC;
|
||||
filhdr.tsize = tsize;
|
||||
filhdr.dsize = dsize;
|
||||
filhdr.bsize = bsize;
|
||||
filhdr.ssize = sflag? 0: (ssize + (sizeof cursym)*(symp-symtab));
|
||||
filhdr.entry = 0;
|
||||
filhdr.pad = 0;
|
||||
filhdr.relflg = (rflag==0);
|
||||
mput(toutb, &filhdr, sizeof filhdr);
|
||||
return;
|
||||
}
|
||||
|
||||
tcreat(buf, letter)
|
||||
int *buf;
|
||||
{
|
||||
tfname[6] = letter;
|
||||
if ((buf[0] = creat(tfname, RONLY)) < 0)
|
||||
error(1, "Can't create temp");
|
||||
}
|
||||
|
||||
load2arg(acp)
|
||||
char *acp;
|
||||
{
|
||||
register char *cp;
|
||||
register struct liblist *lp;
|
||||
|
||||
cp = acp;
|
||||
if (getfile(cp) == 0) {
|
||||
while (*cp)
|
||||
cp++;
|
||||
while (cp >= acp && *--cp != '/');
|
||||
mkfsym(++cp);
|
||||
load2(0, 0);
|
||||
return;
|
||||
}
|
||||
for (lp = libp; lp->bno != -1; lp++) {
|
||||
dseek(&text, lp->bno, lp->off, sizeof archdr);
|
||||
mget(&archdr, sizeof archdr);
|
||||
mkfsym(archdr.aname);
|
||||
load2(lp->bno, lp->off + (sizeof archdr) / 2);
|
||||
}
|
||||
libp = ++lp;
|
||||
}
|
||||
|
||||
load2(bno, off)
|
||||
{
|
||||
register struct symbol *sp;
|
||||
register int *lp, symno;
|
||||
|
||||
readhdr(bno, off);
|
||||
ctrel = torigin;
|
||||
cdrel =+ dorigin;
|
||||
cbrel =+ borigin;
|
||||
/*
|
||||
* Reread the symbol table, recording the numbering
|
||||
* of symbols for fixing external references.
|
||||
*/
|
||||
lp = local;
|
||||
symno = -1;
|
||||
off =+ (sizeof filhdr)/2;
|
||||
dseek(&text, bno, off+filhdr.tsize+filhdr.dsize, filhdr.ssize);
|
||||
while (text.size > 0) {
|
||||
symno++;
|
||||
mget(&cursym, sizeof cursym);
|
||||
symreloc();
|
||||
if ((cursym.stype&EXTERN) == 0) {
|
||||
if (!sflag&&!xflag&&(!Xflag||cursym.sname[0]!='L'))
|
||||
mput(soutb, &cursym, sizeof cursym);
|
||||
continue;
|
||||
}
|
||||
if ((sp = *lookup()) == 0)
|
||||
error(1, "internal error: symbol not found");
|
||||
if (cursym.stype == EXTERN+UNDEF) {
|
||||
if (lp >= &local[NSYMPR])
|
||||
error(1, "Local symbol overflow");
|
||||
*lp++ = symno;
|
||||
*lp++ = sp;
|
||||
continue;
|
||||
}
|
||||
if (cursym.stype!=sp->stype || cursym.svalue!=sp->svalue) {
|
||||
printf("%.8s: ", cursym.sname);
|
||||
error(0, "Multiply defined");
|
||||
}
|
||||
}
|
||||
dseek(&text, bno, off, filhdr.tsize);
|
||||
dseek(&reloc, bno, off+(filhdr.tsize+filhdr.dsize)/2, filhdr.tsize);
|
||||
load2td(lp, ctrel, toutb, troutb);
|
||||
dseek(&text, bno, off+(filhdr.tsize/2), filhdr.dsize);
|
||||
dseek(&reloc, bno, off+filhdr.tsize+(filhdr.dsize/2), filhdr.dsize);
|
||||
load2td(lp, cdrel, doutb, droutb);
|
||||
torigin =+ filhdr.tsize;
|
||||
dorigin =+ filhdr.dsize;
|
||||
borigin =+ filhdr.bsize;
|
||||
}
|
||||
|
||||
load2td(lp, creloc, b1, b2)
|
||||
int *lp;
|
||||
{
|
||||
register r, t;
|
||||
register struct symbol *sp;
|
||||
|
||||
for (;;) {
|
||||
/*
|
||||
* The pickup code is copied from "get" for speed.
|
||||
*/
|
||||
if (--text.size <= 0) {
|
||||
if (text.size < 0)
|
||||
break;
|
||||
text.size++;
|
||||
t = get(&text);
|
||||
} else if (--text.nibuf < 0) {
|
||||
text.nibuf++;
|
||||
text.size++;
|
||||
t = get(&text);
|
||||
} else
|
||||
t = *text.ptr++;
|
||||
if (--reloc.size <= 0) {
|
||||
if (reloc.size < 0)
|
||||
error(1, "Relocation error");
|
||||
reloc.size++;
|
||||
r = get(&reloc);
|
||||
} else if (--reloc.nibuf < 0) {
|
||||
reloc.nibuf++;
|
||||
reloc.size++;
|
||||
r = get(&reloc);
|
||||
} else
|
||||
r = *reloc.ptr++;
|
||||
switch (r&016) {
|
||||
|
||||
case RTEXT:
|
||||
t =+ ctrel;
|
||||
break;
|
||||
|
||||
case RDATA:
|
||||
t =+ cdrel;
|
||||
break;
|
||||
|
||||
case RBSS:
|
||||
t =+ cbrel;
|
||||
break;
|
||||
|
||||
case REXT:
|
||||
sp = lookloc(lp, r);
|
||||
if (sp->stype==EXTERN+UNDEF) {
|
||||
r = (r&01) + ((nsym+(sp-symtab))<<4) + REXT;
|
||||
break;
|
||||
}
|
||||
t =+ sp->svalue;
|
||||
r = (r&01) + ((sp->stype-(EXTERN+ABS))<<1);
|
||||
break;
|
||||
}
|
||||
if (r&01)
|
||||
t =- creloc;
|
||||
putw(t, b1);
|
||||
if (rflag)
|
||||
putw(r, b2);
|
||||
}
|
||||
}
|
||||
|
||||
finishout()
|
||||
{
|
||||
register n, *p;
|
||||
|
||||
if (nflag||iflag) {
|
||||
n = torigin;
|
||||
while (n&077) {
|
||||
n =+ 2;
|
||||
putw(0, toutb);
|
||||
if (rflag)
|
||||
putw(0, troutb);
|
||||
}
|
||||
}
|
||||
copy(doutb, 'a');
|
||||
if (rflag) {
|
||||
copy(troutb, 'c');
|
||||
copy(droutb, 'd');
|
||||
}
|
||||
if (sflag==0) {
|
||||
if (xflag==0)
|
||||
copy(soutb, 'b');
|
||||
for (p=symtab; p < symp;)
|
||||
putw(*p++, toutb);
|
||||
}
|
||||
fflush(toutb);
|
||||
close(toutb[0]);
|
||||
unlink("a.out");
|
||||
link("l.out", "a.out");
|
||||
delarg = errlev;
|
||||
delexit();
|
||||
}
|
||||
|
||||
delexit()
|
||||
{
|
||||
register c;
|
||||
|
||||
unlink("l.out");
|
||||
for (c = 'a'; c <= 'd'; c++) {
|
||||
tfname[6] = c;
|
||||
unlink(tfname);
|
||||
}
|
||||
if (delarg==0)
|
||||
chmod("a.out", 0777);
|
||||
exit(delarg);
|
||||
}
|
||||
|
||||
copy(buf, c)
|
||||
int *buf;
|
||||
{
|
||||
register f, *p, n;
|
||||
|
||||
fflush(buf);
|
||||
close(buf[0]);
|
||||
tfname[6] = c;
|
||||
f = open(tfname, 0);
|
||||
while ((n = read(f, doutb, 512)) > 1) {
|
||||
n =>> 1;
|
||||
p = doutb;
|
||||
do
|
||||
putw(*p++, toutb);
|
||||
while (--n);
|
||||
}
|
||||
close(f);
|
||||
}
|
||||
|
||||
mkfsym(s)
|
||||
char *s;
|
||||
{
|
||||
|
||||
if (sflag || xflag)
|
||||
return;
|
||||
cp8c(s, cursym.sname);
|
||||
cursym.stype = 037;
|
||||
cursym.svalue = torigin;
|
||||
mput(soutb, &cursym, sizeof cursym);
|
||||
}
|
||||
|
||||
mget(aloc, an)
|
||||
int *aloc;
|
||||
{
|
||||
register *loc, n;
|
||||
register *p;
|
||||
|
||||
n = an;
|
||||
n =>> 1;
|
||||
loc = aloc;
|
||||
if ((text.nibuf =- n) >= 0) {
|
||||
if ((text.size =- n) > 0) {
|
||||
p = text.ptr;
|
||||
do
|
||||
*loc++ = *p++;
|
||||
while (--n);
|
||||
text.ptr = p;
|
||||
return;
|
||||
} else
|
||||
text.size =+ n;
|
||||
}
|
||||
text.nibuf =+ n;
|
||||
do {
|
||||
*loc++ = get(&text);
|
||||
} while (--n);
|
||||
}
|
||||
|
||||
mput(buf, aloc, an)
|
||||
int *aloc;
|
||||
{
|
||||
register *loc;
|
||||
register n;
|
||||
|
||||
loc = aloc;
|
||||
n = an>>1;
|
||||
do {
|
||||
putw(*loc++, buf);
|
||||
} while (--n);
|
||||
}
|
||||
|
||||
dseek(asp, ab, o, s)
|
||||
{
|
||||
register struct stream *sp;
|
||||
register struct page *p;
|
||||
register b;
|
||||
int n;
|
||||
|
||||
sp = asp;
|
||||
b = ab + ((o>>8) & 0377);
|
||||
o =& 0377;
|
||||
--sp->pno->nuser;
|
||||
if ((p = &page[0])->bno!=b && (p = &page[1])->bno!=b)
|
||||
if (p->nuser==0 || (p = &page[0])->nuser==0) {
|
||||
if (page[0].nuser==0 && page[1].nuser==0)
|
||||
if (page[0].bno < page[1].bno)
|
||||
p = &page[0];
|
||||
p->bno = b;
|
||||
seek(infil, b, 3);
|
||||
if ((n = read(infil, p->buff, 512)>>1) < 0)
|
||||
n = 0;
|
||||
p->nibuf = n;
|
||||
} else
|
||||
error(1, "No pages");
|
||||
++p->nuser;
|
||||
sp->bno = b;
|
||||
sp->pno = p;
|
||||
sp->ptr = p->buff + o;
|
||||
if (s != -1)
|
||||
sp->size = (s>>1) & 077777;
|
||||
if ((sp->nibuf = p->nibuf-o) <= 0)
|
||||
sp->size = 0;
|
||||
}
|
||||
|
||||
get(asp)
|
||||
struct stream *asp;
|
||||
{
|
||||
register struct stream *sp;
|
||||
|
||||
sp = asp;
|
||||
if (--sp->nibuf < 0) {
|
||||
dseek(sp, sp->bno+1, 0, -1);
|
||||
--sp->nibuf;
|
||||
}
|
||||
if (--sp->size <= 0) {
|
||||
if (sp->size < 0)
|
||||
error(1, premeof);
|
||||
++fpage.nuser;
|
||||
--sp->pno->nuser;
|
||||
sp->pno = &fpage;
|
||||
}
|
||||
return(*sp->ptr++);
|
||||
}
|
||||
|
||||
getfile(acp)
|
||||
char *acp;
|
||||
{
|
||||
register char *cp;
|
||||
register c;
|
||||
|
||||
cp = acp;
|
||||
archdr.aname[0] = '\0';
|
||||
if (cp[0]=='-' && cp[1]=='l') {
|
||||
if ((c = cp[2]) == '\0')
|
||||
c = 'a';
|
||||
cp = "/lib/lib?.a";
|
||||
cp[8] = c;
|
||||
}
|
||||
filname = cp;
|
||||
if ((infil = open(cp, 0)) < 0)
|
||||
error(1, "cannot open");
|
||||
page[0].bno = page[1].bno = -1;
|
||||
page[0].nuser = page[1].nuser = 0;
|
||||
text.pno = reloc.pno = &fpage;
|
||||
fpage.nuser = 2;
|
||||
dseek(&text, 0, 0, 2);
|
||||
if (text.size <= 0)
|
||||
error(1, premeof);
|
||||
return(get(&text) == ARCMAGIC);
|
||||
}
|
||||
|
||||
struct symbol **lookup()
|
||||
{
|
||||
int i;
|
||||
register struct symbol **hp;
|
||||
register char *cp, *cp1;
|
||||
|
||||
i = 0;
|
||||
for (cp=cursym.sname; cp < &cursym.sname[8];)
|
||||
i = (i<<1) + *cp++;
|
||||
for (hp = &hshtab[(i&077777)%NSYM+2]; *hp!=0;) {
|
||||
cp1 = (*hp)->sname;
|
||||
for (cp=cursym.sname; cp < &cursym.sname[8];)
|
||||
if (*cp++ != *cp1++)
|
||||
goto no;
|
||||
break;
|
||||
no:
|
||||
if (++hp >= &hshtab[NSYM+2])
|
||||
hp = hshtab;
|
||||
}
|
||||
return(hp);
|
||||
}
|
||||
|
||||
struct symbol **slookup(s)
|
||||
char *s;
|
||||
{
|
||||
cp8c(s, cursym.sname);
|
||||
cursym.stype = EXTERN+UNDEF;
|
||||
cursym.svalue = 0;
|
||||
return(lookup());
|
||||
}
|
||||
|
||||
enter()
|
||||
{
|
||||
register struct symbol *sp;
|
||||
|
||||
if ((sp=symp) >= &symtab[NSYM])
|
||||
error(1, "Symbol table overflow");
|
||||
cp8c(cursym.sname, sp->sname);
|
||||
sp->stype = cursym.stype;
|
||||
sp->svalue = cursym.svalue;
|
||||
symp++;
|
||||
return(sp);
|
||||
}
|
||||
|
||||
symreloc()
|
||||
{
|
||||
switch (cursym.stype) {
|
||||
|
||||
case TEXT:
|
||||
case EXTERN+TEXT:
|
||||
cursym.svalue =+ ctrel;
|
||||
return;
|
||||
|
||||
case DATA:
|
||||
case EXTERN+DATA:
|
||||
cursym.svalue =+ cdrel;
|
||||
return;
|
||||
|
||||
case BSS:
|
||||
case EXTERN+BSS:
|
||||
cursym.svalue =+ cbrel;
|
||||
return;
|
||||
|
||||
case EXTERN+UNDEF:
|
||||
return;
|
||||
}
|
||||
if (cursym.stype&EXTERN)
|
||||
cursym.stype = EXTERN+ABS;
|
||||
}
|
||||
|
||||
error(n, s)
|
||||
char *s;
|
||||
{
|
||||
if (filname) {
|
||||
printf("%s", filname);
|
||||
if (archdr.aname[0])
|
||||
printf("(%.8s)", archdr.aname);
|
||||
printf(": ");
|
||||
}
|
||||
printf("%s\n", s);
|
||||
if (n)
|
||||
delexit();
|
||||
errlev = 2;
|
||||
}
|
||||
|
||||
lookloc(alp, r)
|
||||
{
|
||||
register int *clp, *lp;
|
||||
register sn;
|
||||
|
||||
lp = alp;
|
||||
sn = (r>>4) & 07777;
|
||||
for (clp=local; clp<lp; clp =+ 2)
|
||||
if (clp[0] == sn)
|
||||
return(clp[1]);
|
||||
error(1, "Local symbol botch");
|
||||
}
|
||||
|
||||
readhdr(bno, off)
|
||||
{
|
||||
register st, sd;
|
||||
|
||||
dseek(&text, bno, off, sizeof filhdr);
|
||||
mget(&filhdr, sizeof filhdr);
|
||||
if (filhdr.fmagic != FMAGIC)
|
||||
error(1, "Bad format");
|
||||
st = (filhdr.tsize+01) & ~01;
|
||||
filhdr.tsize = st;
|
||||
cdrel = -st;
|
||||
sd = (filhdr.dsize+01) & ~01;
|
||||
cbrel = - (st+sd);
|
||||
filhdr.bsize = (filhdr.bsize+01) & ~01;
|
||||
}
|
||||
|
||||
cp8c(from, to)
|
||||
char *from, *to;
|
||||
{
|
||||
register char *f, *t, *te;
|
||||
|
||||
f = from;
|
||||
t = to;
|
||||
te = t+8;
|
||||
while ((*t++ = *f++) && t<te);
|
||||
while (t<te)
|
||||
*t++ = 0;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#
|
||||
/*
|
||||
* ln target [ new name ]
|
||||
*/
|
||||
|
||||
struct ibuf {
|
||||
int inum;
|
||||
int iflags;
|
||||
char inl;
|
||||
char iuid;
|
||||
int isize;
|
||||
int iaddr[8];
|
||||
char *ictime[2];
|
||||
char *imtime[2];
|
||||
int fill;
|
||||
};
|
||||
|
||||
#define DIR 040000
|
||||
#define FMT 060000
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
static struct ibuf statb;
|
||||
register char *np;
|
||||
|
||||
if (argc<2) {
|
||||
write(1, "Usage: ln target [ newname ]\n", 29);
|
||||
exit(1);
|
||||
}
|
||||
if (argc==2) {
|
||||
np = argv[1];
|
||||
while(*np++);
|
||||
while (*--np!='/' && np>argv[1]);
|
||||
np++;
|
||||
argv[2] = np;
|
||||
}
|
||||
stat(argv[1], &statb);
|
||||
if ((statb.iflags&FMT) == DIR) {
|
||||
write(1, "No directory link\n", 18);
|
||||
exit(1);
|
||||
}
|
||||
if (link(argv[1], argv[2])<0) {
|
||||
write(1, "Can't link\n", 11);
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
#
|
||||
/*
|
||||
* login [ name ]
|
||||
*/
|
||||
|
||||
struct {
|
||||
char name[8];
|
||||
char tty;
|
||||
char ifill;
|
||||
int time[2];
|
||||
int ufill;
|
||||
} utmp;
|
||||
|
||||
struct {
|
||||
int speeds;
|
||||
char erase, kill;
|
||||
int tflags;
|
||||
} ttyb;
|
||||
|
||||
struct {
|
||||
int junk[5];
|
||||
int size;
|
||||
int more[12];
|
||||
} statb;
|
||||
|
||||
char *ttyx;
|
||||
|
||||
#define ECHO 010
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
char pbuf[128];
|
||||
register char *namep, *np;
|
||||
char pwbuf[9];
|
||||
int t, sflags, f, c, uid, gid;
|
||||
|
||||
signal(3, 1);
|
||||
signal(2, 1);
|
||||
nice(0);
|
||||
ttyx = "/dev/ttyx";
|
||||
if ((utmp.tty=ttyn(0)) == 'x') {
|
||||
write(1, "Sorry.\n", 7);
|
||||
exit();
|
||||
}
|
||||
ttyx[8] = utmp.tty;
|
||||
gtty(0, &ttyb);
|
||||
ttyb.erase = '#';
|
||||
ttyb.kill = '@';
|
||||
stty(0, &ttyb);
|
||||
loop:
|
||||
namep = utmp.name;
|
||||
if (argc>1) {
|
||||
np = argv[1];
|
||||
while (namep<utmp.name+8 && *np)
|
||||
*namep++ = *np++;
|
||||
argc = 0;
|
||||
} else {
|
||||
write(1, "Name: ", 7);
|
||||
while ((c = getchar()) != '\n') {
|
||||
if (c <= 0)
|
||||
exit();
|
||||
if (namep < utmp.name+8)
|
||||
*namep++ = c;
|
||||
}
|
||||
}
|
||||
while (namep < utmp.name+8)
|
||||
*namep++ = ' ';
|
||||
if (getpwentry(utmp.name, pbuf))
|
||||
goto bad;
|
||||
np = colon(pbuf);
|
||||
if (*np!=':') {
|
||||
sflags = ttyb.tflags;
|
||||
ttyb.tflags =& ~ ECHO;
|
||||
stty(0, &ttyb);
|
||||
write(1, "Password: ", 10);
|
||||
namep = pwbuf;
|
||||
while ((c=getchar()) != '\n') {
|
||||
if (c <= 0)
|
||||
exit();
|
||||
if (namep<pwbuf+8)
|
||||
*namep++ = c;
|
||||
}
|
||||
*namep++ = '\0';
|
||||
ttyb.tflags = sflags;
|
||||
stty(0, &ttyb);
|
||||
write(1, "\n", 1);
|
||||
namep = crypt(pwbuf);
|
||||
while (*namep++ == *np++);
|
||||
if (*--namep!='\0' || *--np!=':')
|
||||
goto bad;
|
||||
}
|
||||
np = colon(np);
|
||||
uid = 0;
|
||||
while (*np != ':')
|
||||
uid = uid*10 + *np++ - '0';
|
||||
np++;
|
||||
gid = 0;
|
||||
while (*np != ':')
|
||||
gid = gid*10 + *np++ - '0';
|
||||
np++;
|
||||
np = colon(np);
|
||||
namep = np;
|
||||
np = colon(np);
|
||||
if (chdir(namep)<0) {
|
||||
write(1, "No directory\n", 13);
|
||||
goto loop;
|
||||
}
|
||||
time(utmp.time);
|
||||
if ((f = open("/etc/utmp", 1)) >= 0) {
|
||||
t = utmp.tty;
|
||||
if (t>='a')
|
||||
t =- 'a' - (10+'0');
|
||||
seek(f, (t-'0')*16, 0);
|
||||
write(f, &utmp, 16);
|
||||
close(f);
|
||||
}
|
||||
if ((f = open("/usr/adm/wtmp", 1)) >= 0) {
|
||||
seek(f, 0, 2);
|
||||
write(f, &utmp, 16);
|
||||
close(f);
|
||||
}
|
||||
if ((f = open("/etc/motd", 0)) >= 0) {
|
||||
while(read(f, &t, 1) > 0)
|
||||
write(1, &t, 1);
|
||||
close(f);
|
||||
}
|
||||
if(stat(".mail", &statb) >= 0 && statb.size)
|
||||
write(1, "You have mail.\n", 15);
|
||||
chown(ttyx, uid);
|
||||
setgid(gid);
|
||||
setuid(uid);
|
||||
if (*np == '\0')
|
||||
np = "/bin/sh";
|
||||
execl(np, "-", 0);
|
||||
write(1, "No shell.\n", 9);
|
||||
exit();
|
||||
bad:
|
||||
write(1, "Login incorrect.\n", 17);
|
||||
goto loop;
|
||||
}
|
||||
|
||||
getpwentry(name, buf)
|
||||
char *name, *buf;
|
||||
{
|
||||
extern fin;
|
||||
int fi, r, c;
|
||||
register char *gnp, *rnp;
|
||||
|
||||
fi = fin;
|
||||
r = 1;
|
||||
if((fin = open("/etc/passwd", 0)) < 0)
|
||||
goto ret;
|
||||
loop:
|
||||
gnp = name;
|
||||
rnp = buf;
|
||||
while((c=getchar()) != '\n') {
|
||||
if(c <= 0)
|
||||
goto ret;
|
||||
*rnp++ = c;
|
||||
}
|
||||
*rnp++ = '\0';
|
||||
rnp = buf;
|
||||
while (*gnp++ == *rnp++);
|
||||
if ((*--gnp!=' ' && gnp<name+8) || *--rnp!=':')
|
||||
goto loop;
|
||||
r = 0;
|
||||
ret:
|
||||
close(fin);
|
||||
fin = 0;
|
||||
(&fin)[1] = 0;
|
||||
(&fin)[2] = 0;
|
||||
return(r);
|
||||
}
|
||||
|
||||
colon(p)
|
||||
char *p;
|
||||
{
|
||||
register char *rp;
|
||||
|
||||
rp = p;
|
||||
while (*rp != ':') {
|
||||
if (*rp++ == '\0') {
|
||||
write(1, "Bad /etc/passwd\n", 16);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
*rp++ = '\0';
|
||||
return(rp);
|
||||
}
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/ lpd -- Line Printer daemon
|
||||
|
||||
.globl fopen, getc
|
||||
.globl fcreat, putc, flush
|
||||
.globl switch
|
||||
|
||||
sys signal; 1; 1
|
||||
sys signal; 2; 1
|
||||
sys signal; 3; 1 / ignore quit,intr,hup
|
||||
sys stat; lock; buf
|
||||
bec 2f
|
||||
sys creat; lock; 0
|
||||
bes 2f
|
||||
sys open; lpd; 0
|
||||
bes 3f
|
||||
mov r0,r1
|
||||
1:
|
||||
mov r1,r0
|
||||
sys read; dbuf; 16.
|
||||
bes 3f
|
||||
tst r0
|
||||
beq 3f
|
||||
tst dbuf
|
||||
beq 1b
|
||||
cmp dbuf+2,$"df
|
||||
bne 1b
|
||||
sys fork
|
||||
br retry
|
||||
sys exit
|
||||
3:
|
||||
sys unlink; lock
|
||||
2:
|
||||
sys exit
|
||||
|
||||
/ get line printer
|
||||
retry:
|
||||
jsr r5,aclose
|
||||
mov $lpr,r0
|
||||
jsr r5,fcreat; print
|
||||
bes error
|
||||
sys chdir; lpd
|
||||
bes error
|
||||
sys open; lpd; 0
|
||||
bes error
|
||||
mov r0,dfi
|
||||
br loop
|
||||
|
||||
done:
|
||||
sys unlink; lock
|
||||
sys exit
|
||||
|
||||
error:
|
||||
jsr r5,aclose
|
||||
mov $10.,r0
|
||||
sys sleep
|
||||
sys stat; lock; buf
|
||||
bes done / die if lock is gone
|
||||
br retry
|
||||
|
||||
/ look in directory for work
|
||||
loop:
|
||||
mov dfi,r0
|
||||
sys seek; 0; 0
|
||||
|
||||
1:
|
||||
mov dfi,r0
|
||||
sys read; dbuf; 16.
|
||||
bes error
|
||||
tst r0
|
||||
beq done / only non-error return
|
||||
tst dbuf
|
||||
beq 1b
|
||||
mov $dbuf+2,r0
|
||||
cmp (r0),$"df / look for daemon file
|
||||
bne 1b
|
||||
|
||||
/ found prototype file
|
||||
jsr r5,fopen; proto
|
||||
bes 1b
|
||||
|
||||
/ copy a line into buf
|
||||
/ only work is expansion of tabs
|
||||
loop1:
|
||||
mov $buf,r1
|
||||
1:
|
||||
jsr r5,getc; proto
|
||||
bes eloop1
|
||||
movb r0,(r1)
|
||||
cmp r0,$'\t
|
||||
beq 2f
|
||||
cmpb (r1)+,$'\n
|
||||
bne 1b
|
||||
br 1f
|
||||
2:
|
||||
movb $' ,(r1)+
|
||||
cmp r1,$buf+8.
|
||||
beq 1b
|
||||
cmp r1,$buf+16.
|
||||
bhis 1b
|
||||
br 2b
|
||||
1:
|
||||
movb buf,r0
|
||||
jsr r5,switch; sptab
|
||||
|
||||
/ done with a prototype file
|
||||
/ look for U's in second pass
|
||||
eloop1:
|
||||
mov proto,r0
|
||||
sys seek; 0; 0
|
||||
br 2f
|
||||
1:
|
||||
jsr r5,getc; proto
|
||||
bes 1f
|
||||
3:
|
||||
cmp r0,$'\n
|
||||
bne 1b
|
||||
2:
|
||||
jsr r5,getc; proto
|
||||
bes 1f
|
||||
cmp r0,$'U
|
||||
bne 3b
|
||||
mov $buf,r1
|
||||
3:
|
||||
jsr r5,getc; proto
|
||||
bes 1f
|
||||
movb r0,(r1)+
|
||||
cmp r0,$'\n
|
||||
bne 3b
|
||||
clrb -(r1)
|
||||
sys unlink; buf
|
||||
br 2b
|
||||
1:
|
||||
mov proto,r0
|
||||
sys close
|
||||
sys unlink; dbuf+2
|
||||
br loop
|
||||
|
||||
/ list of special characters
|
||||
/ switchout
|
||||
sptab:
|
||||
'L; literal
|
||||
'B; binary
|
||||
'F; form
|
||||
'U; loop1 / unlink on second pass
|
||||
0; 0
|
||||
|
||||
|
||||
literal:
|
||||
jmp loop1
|
||||
|
||||
form:
|
||||
clrb -(r1)
|
||||
mov $buf+1,r0
|
||||
jsr r5,fopen; insert
|
||||
bes loop1
|
||||
mov $14,r0
|
||||
jsr r5,putc; print
|
||||
br 1f
|
||||
|
||||
binary:
|
||||
clrb -(r1)
|
||||
mov $buf+1,r0
|
||||
jsr r5,fopen; insert
|
||||
bes loop1
|
||||
|
||||
1:
|
||||
jsr r5,getc; insert
|
||||
bes 1f
|
||||
jsr r5,putc; print
|
||||
br 1b
|
||||
1:
|
||||
jsr r5,flush; print
|
||||
mov insert,r0
|
||||
sys close
|
||||
br loop1
|
||||
|
||||
aclose:
|
||||
mov $9.,r1
|
||||
1:
|
||||
mov r1,r0
|
||||
sys close
|
||||
dec r1
|
||||
bge 1b
|
||||
rts r5
|
||||
|
||||
lpr:
|
||||
</dev/lp\0>
|
||||
lock:
|
||||
</usr/lpd/lock\0>
|
||||
lpd:
|
||||
</usr/lpd\0>
|
||||
.even
|
||||
.bss
|
||||
|
||||
ch: .=.+2
|
||||
dfi: .=.+2
|
||||
dbuf: .=.+18.
|
||||
print: .=.+518.
|
||||
proto: .=.+518.
|
||||
insert: .=.+518.
|
||||
buf: .=.+400.
|
||||
sleep = 35.
|
||||
signal = 48.
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* dpr -- off line print via dataphone daemon to GCOS
|
||||
* normally invoked through opr
|
||||
*/
|
||||
|
||||
char tfname[] "/usr/lpd/tfaXXXXX";
|
||||
char cfname[] "/usr/lpd/cfaXXXXX";
|
||||
char lfname[] "/usr/lpd/lfaXXXXX";
|
||||
char dfname[] "/usr/lpd/dfaXXXXX";
|
||||
int nact;
|
||||
int tff;
|
||||
int mailflg;
|
||||
char person[10];
|
||||
int inchar;
|
||||
int maxrec 1000;
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
register char *arg;
|
||||
int c, f, flag;
|
||||
int out();
|
||||
|
||||
pidfn();
|
||||
if((signal(1, 1) & 01) == 0)
|
||||
signal(1, out);
|
||||
if((signal(2, 1) & 01) == 0)
|
||||
signal(2, out);
|
||||
if((signal(3, 1) & 01) == 0)
|
||||
signal(3, out);
|
||||
flag = 0;
|
||||
tff = nfile(tfname);
|
||||
while (argc>1 && (arg = argv[1])[0]=='-') {
|
||||
switch (arg[1]) {
|
||||
|
||||
case 'c':
|
||||
flag = '+';
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
flag = '-';
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
mailflg = 1;
|
||||
break;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
ident();
|
||||
|
||||
if(argc == 1)
|
||||
copy(0);
|
||||
while(--argc) {
|
||||
arg = *++argv;
|
||||
if(flag == '+')
|
||||
goto cf;
|
||||
if(*arg == '/' && flag != '-') {
|
||||
card('F', arg);
|
||||
nact++;
|
||||
continue;
|
||||
}
|
||||
if(link(arg, lfname) < 0)
|
||||
goto cf;
|
||||
card('F', lfname);
|
||||
card('U', lfname);
|
||||
lfname[inchar]++;
|
||||
nact++;
|
||||
goto df;
|
||||
|
||||
cf:
|
||||
f = open(arg, 0);
|
||||
if(f < 0) {
|
||||
printf("Cannot open %s\n", arg);
|
||||
continue;
|
||||
}
|
||||
copy(f);
|
||||
close(f);
|
||||
|
||||
df:
|
||||
if(flag == '-') {
|
||||
f = unlink(arg);
|
||||
if(f < 0)
|
||||
printf("Cannot remove %s\n", arg);
|
||||
}
|
||||
}
|
||||
|
||||
if(nact) {
|
||||
tfname[inchar]--;
|
||||
f = link(tfname, dfname);
|
||||
if(f < 0) {
|
||||
printf("Cannot rename %s\n", dfname);
|
||||
tfname[inchar]++;
|
||||
out();
|
||||
}
|
||||
unlink(tfname);
|
||||
execl("/etc/lpd", "lpd", 0);
|
||||
dfname[inchar]++;
|
||||
}
|
||||
out();
|
||||
}
|
||||
|
||||
copy(f)
|
||||
int f;
|
||||
{
|
||||
int ff, i, nr, nc;
|
||||
static int buf[256];
|
||||
|
||||
card('F', cfname);
|
||||
card('U', cfname);
|
||||
ff = nfile(cfname);
|
||||
nc = 0;
|
||||
nr = 0;
|
||||
while((i = read(f, buf, 512)) > 0) {
|
||||
write(ff, buf, i);
|
||||
nc =+ i;
|
||||
if(nc >= 512) {
|
||||
nc =- 512;
|
||||
nr++;
|
||||
if(nr > maxrec) {
|
||||
printf("Copy file is too large\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(ff);
|
||||
nact++;
|
||||
}
|
||||
|
||||
card(c, s)
|
||||
int c;
|
||||
char s[];
|
||||
{
|
||||
char *p1, *p2;
|
||||
static char buf[512];
|
||||
int col;
|
||||
|
||||
p1 = buf;
|
||||
p2 = s;
|
||||
col = 0;
|
||||
*p1++ = c;
|
||||
while((c = *p2++) != '\0') {
|
||||
*p1++ = c;
|
||||
col++;
|
||||
}
|
||||
*p1++ = '\n';
|
||||
write(tff, buf, col+2);
|
||||
}
|
||||
|
||||
ident()
|
||||
{
|
||||
int c, n;
|
||||
register char *b1p, *pp, *b2p;
|
||||
static char b1[100], b2[100];
|
||||
|
||||
b1p = b1;
|
||||
if(getpw(getuid(), b1p)) {
|
||||
b1p = "pdp::::m0000,m000:";
|
||||
}
|
||||
n = 0;
|
||||
b2p = b2;
|
||||
while(*b2p++ = "$ ident "[n++]);
|
||||
b2p--;
|
||||
n = 5;
|
||||
while(--n) while(*b1p++ != ':');
|
||||
while((*b2p++ = *b1p++) != ':');
|
||||
b2p[-1] = ',';
|
||||
b1p = b1;
|
||||
pp = person;
|
||||
while((c = *b1p++) != ':') {
|
||||
*b2p++ = c;
|
||||
*pp++ = c;
|
||||
}
|
||||
*b2p++ = 0;
|
||||
*pp++ = 0;
|
||||
card('L', b2);
|
||||
if (mailflg)
|
||||
card('M', person);
|
||||
}
|
||||
|
||||
pidfn()
|
||||
{
|
||||
register i, j, c;
|
||||
int p;
|
||||
|
||||
p = getpid();
|
||||
i = 0;
|
||||
while(tfname[i] != 'X')
|
||||
i++;
|
||||
i =+ 4;
|
||||
for(j=0; j<5; j++) {
|
||||
c = (p%10) + '0';
|
||||
p =/ 10;
|
||||
tfname[i] = c;
|
||||
cfname[i] = c;
|
||||
lfname[i] = c;
|
||||
dfname[i] = c;
|
||||
i--;
|
||||
}
|
||||
inchar = i;
|
||||
}
|
||||
|
||||
nfile(name)
|
||||
char *name;
|
||||
{
|
||||
register f;
|
||||
|
||||
f = creat(name, 0666);
|
||||
if(f < 0) {
|
||||
printf("Cannot create %s\n", name);
|
||||
out();
|
||||
}
|
||||
name[inchar]++;
|
||||
return(f);
|
||||
}
|
||||
|
||||
out()
|
||||
{
|
||||
register i;
|
||||
|
||||
signal(1, 1);
|
||||
signal(1, 2);
|
||||
signal(1, 3);
|
||||
i = inchar;
|
||||
while(tfname[i] != 'a') {
|
||||
tfname[i]--;
|
||||
unlink(tfname);
|
||||
}
|
||||
while(cfname[i] != 'a') {
|
||||
cfname[i]--;
|
||||
unlink(cfname);
|
||||
}
|
||||
while(lfname[i] != 'a') {
|
||||
lfname[i]--;
|
||||
unlink(lfname);
|
||||
}
|
||||
while(dfname[i] != 'a') {
|
||||
dfname[i]--;
|
||||
unlink(dfname);
|
||||
}
|
||||
exit();
|
||||
}
|
||||
+461
@@ -0,0 +1,461 @@
|
||||
#
|
||||
/*
|
||||
* list file or directory
|
||||
*/
|
||||
|
||||
struct {
|
||||
int fdes;
|
||||
int nleft;
|
||||
char *nextc;
|
||||
char buff[512];
|
||||
} inf;
|
||||
|
||||
struct ibuf {
|
||||
int idev;
|
||||
int inum;
|
||||
int iflags;
|
||||
char inl;
|
||||
char iuid;
|
||||
char igid;
|
||||
char isize0;
|
||||
int isize;
|
||||
int iaddr[8];
|
||||
char *iatime[2];
|
||||
char *imtime[2];
|
||||
};
|
||||
|
||||
struct lbuf {
|
||||
char lname[15];
|
||||
int lnum;
|
||||
int lflags;
|
||||
char lnl;
|
||||
char luid;
|
||||
char lgid;
|
||||
char lsize0;
|
||||
int lsize;
|
||||
char *lmtime[2];
|
||||
};
|
||||
|
||||
struct lbufx {
|
||||
char *namep;
|
||||
};
|
||||
|
||||
int aflg, dflg, lflg, sflg, tflg, uflg, iflg, fflg, gflg;
|
||||
int fout;
|
||||
int rflg 1;
|
||||
char *year;
|
||||
int flags;
|
||||
int uidfil -1;
|
||||
int lastuid -1;
|
||||
char tbuf[16];
|
||||
int tblocks;
|
||||
int statreq;
|
||||
struct lbuf *lastp &end;
|
||||
struct lbuf *rlastp &end;
|
||||
char *dotp ".";
|
||||
|
||||
#define IFMT 060000
|
||||
#define DIR 0100000
|
||||
#define CHR 020000
|
||||
#define BLK 040000
|
||||
#define ISARG 01000
|
||||
#define LARGE 010000
|
||||
#define STXT 010000
|
||||
#define SUID 04000
|
||||
#define SGID 02000
|
||||
#define ROWN 0400
|
||||
#define WOWN 0200
|
||||
#define XOWN 0100
|
||||
#define RGRP 040
|
||||
#define WGRP 020
|
||||
#define XGRP 010
|
||||
#define ROTH 04
|
||||
#define WOTH 02
|
||||
#define XOTH 01
|
||||
#define RSTXT 01000
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
int i, j;
|
||||
extern struct lbuf end;
|
||||
register struct lbuf *ep, *ep1;
|
||||
register struct lbuf *slastp;
|
||||
struct lbuf lb;
|
||||
int t;
|
||||
int compar();
|
||||
|
||||
fout = dup(1);
|
||||
time(lb.lmtime);
|
||||
year = lb.lmtime[0] - 245; /* 6 months ago */
|
||||
if (--argc > 0 && *argv[1] == '-') {
|
||||
argv++;
|
||||
while (*++*argv) switch (**argv) {
|
||||
case 'a':
|
||||
aflg++;
|
||||
continue;
|
||||
|
||||
case 's':
|
||||
sflg++;
|
||||
statreq++;
|
||||
continue;
|
||||
|
||||
case 'd':
|
||||
dflg++;
|
||||
continue;
|
||||
|
||||
case 'g':
|
||||
gflg++;
|
||||
continue;
|
||||
|
||||
case 'l':
|
||||
lflg++;
|
||||
statreq++;
|
||||
continue;
|
||||
|
||||
case 'r':
|
||||
rflg = -1;
|
||||
continue;
|
||||
|
||||
case 't':
|
||||
tflg++;
|
||||
statreq++;
|
||||
continue;
|
||||
|
||||
case 'u':
|
||||
uflg++;
|
||||
continue;
|
||||
|
||||
case 'i':
|
||||
iflg++;
|
||||
continue;
|
||||
|
||||
case 'f':
|
||||
fflg++;
|
||||
continue;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
argc--;
|
||||
}
|
||||
if (fflg) {
|
||||
aflg++;
|
||||
lflg = 0;
|
||||
sflg = 0;
|
||||
tflg = 0;
|
||||
statreq = 0;
|
||||
}
|
||||
if(lflg) {
|
||||
t = "/etc/passwd";
|
||||
if(gflg)
|
||||
t = "/etc/group";
|
||||
uidfil = open(t, 0);
|
||||
}
|
||||
if (argc==0) {
|
||||
argc++;
|
||||
argv = &dotp - 1;
|
||||
}
|
||||
for (i=0; i < argc; i++) {
|
||||
if ((ep = gstat(*++argv, 1))==0)
|
||||
continue;
|
||||
ep->namep = *argv;
|
||||
ep->lflags =| ISARG;
|
||||
}
|
||||
qsort(&end, lastp - &end, sizeof *lastp, compar);
|
||||
slastp = lastp;
|
||||
for (ep = &end; ep<slastp; ep++) {
|
||||
if (ep->lflags&DIR && dflg==0 || fflg) {
|
||||
if (argc>1)
|
||||
printf("\n%s:\n", ep->namep);
|
||||
lastp = slastp;
|
||||
readdir(ep->namep);
|
||||
if (fflg==0)
|
||||
qsort(slastp,lastp - slastp,sizeof *lastp,compar);
|
||||
if (statreq)
|
||||
printf("total %d\n", tblocks);
|
||||
for (ep1=slastp; ep1<lastp; ep1++)
|
||||
pentry(ep1);
|
||||
} else
|
||||
pentry(ep);
|
||||
}
|
||||
flush();
|
||||
}
|
||||
|
||||
pentry(ap)
|
||||
struct lbuf *ap;
|
||||
{
|
||||
struct { char dminor, dmajor;};
|
||||
register t;
|
||||
register struct lbuf *p;
|
||||
register char *cp;
|
||||
|
||||
p = ap;
|
||||
if (p->lnum == -1)
|
||||
return;
|
||||
if (iflg)
|
||||
printf("%5d ", p->lnum);
|
||||
if (lflg) {
|
||||
pmode(p->lflags);
|
||||
printf("%2d ", p->lnl);
|
||||
t = p->luid;
|
||||
if(gflg)
|
||||
t = p->lgid;
|
||||
t =& 0377;
|
||||
if (getname(t, tbuf)==0)
|
||||
printf("%-6.6s", tbuf);
|
||||
else
|
||||
printf("%-6d", t);
|
||||
if (p->lflags & (BLK|CHR))
|
||||
printf("%3d,%3d", p->lsize.dmajor&0377,
|
||||
p->lsize.dminor&0377);
|
||||
else
|
||||
printf("%7s", locv(p->lsize0, p->lsize));
|
||||
cp = ctime(p->lmtime);
|
||||
if(p->lmtime[0] < year)
|
||||
printf(" %-7.7s %-4.4s ", cp+4, cp+20); else
|
||||
printf(" %-12.12s ", cp+4);
|
||||
} else if (sflg)
|
||||
printf("%4d ", nblock(p->lsize0, p->lsize));
|
||||
if (p->lflags&ISARG)
|
||||
printf("%s\n", p->namep);
|
||||
else
|
||||
printf("%.14s\n", p->lname);
|
||||
}
|
||||
|
||||
getname(uid, buf)
|
||||
int uid;
|
||||
char buf[];
|
||||
{
|
||||
int j, c, n, i;
|
||||
|
||||
if (uid==lastuid)
|
||||
return(0);
|
||||
inf.fdes = uidfil;
|
||||
seek(inf.fdes, 0, 0);
|
||||
inf.nleft = 0;
|
||||
lastuid = -1;
|
||||
do {
|
||||
i = 0;
|
||||
j = 0;
|
||||
n = 0;
|
||||
while((c=getc(&inf)) != '\n') {
|
||||
if (c<0)
|
||||
return(-1);
|
||||
if (c==':') {
|
||||
j++;
|
||||
c = '0';
|
||||
}
|
||||
if (j==0)
|
||||
buf[i++] = c;
|
||||
if (j==2)
|
||||
n = n*10 + c - '0';
|
||||
}
|
||||
} while (n != uid);
|
||||
buf[i++] = '\0';
|
||||
lastuid = uid;
|
||||
return(0);
|
||||
}
|
||||
|
||||
nblock(size0, size)
|
||||
char *size0, *size;
|
||||
{
|
||||
register int n;
|
||||
|
||||
n = ldiv(size0, size, 512);
|
||||
if (size&0777)
|
||||
n++;
|
||||
if (n>8)
|
||||
n =+ (n+255)/256;
|
||||
return(n);
|
||||
}
|
||||
|
||||
int m0[] { 3, DIR, 'd', BLK, 'b', CHR, 'c', '-'};
|
||||
int m1[] { 1, ROWN, 'r', '-' };
|
||||
int m2[] { 1, WOWN, 'w', '-' };
|
||||
int m3[] { 2, SUID, 's', XOWN, 'x', '-' };
|
||||
int m4[] { 1, RGRP, 'r', '-' };
|
||||
int m5[] { 1, WGRP, 'w', '-' };
|
||||
int m6[] { 2, SGID, 's', XGRP, 'x', '-' };
|
||||
int m7[] { 1, ROTH, 'r', '-' };
|
||||
int m8[] { 1, WOTH, 'w', '-' };
|
||||
int m9[] { 1, XOTH, 'x', '-' };
|
||||
int m10[] { 1, STXT, 't', ' ' };
|
||||
|
||||
int *m[] { m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10};
|
||||
|
||||
pmode(aflag)
|
||||
{
|
||||
register int **mp;
|
||||
|
||||
flags = aflag;
|
||||
for (mp = &m[0]; mp < &m[11];)
|
||||
select(*mp++);
|
||||
}
|
||||
|
||||
select(pairp)
|
||||
int *pairp;
|
||||
{
|
||||
register int n, *ap;
|
||||
|
||||
ap = pairp;
|
||||
n = *ap++;
|
||||
while (--n>=0 && (flags&*ap++)==0)
|
||||
ap++;
|
||||
putchar(*ap);
|
||||
}
|
||||
|
||||
makename(dir, file)
|
||||
char *dir, *file;
|
||||
{
|
||||
static char dfile[100];
|
||||
register char *dp, *fp;
|
||||
register int i;
|
||||
|
||||
dp = dfile;
|
||||
fp = dir;
|
||||
while (*fp)
|
||||
*dp++ = *fp++;
|
||||
*dp++ = '/';
|
||||
fp = file;
|
||||
for (i=0; i<14; i++)
|
||||
*dp++ = *fp++;
|
||||
*dp = 0;
|
||||
return(dfile);
|
||||
}
|
||||
|
||||
readdir(dir)
|
||||
char *dir;
|
||||
{
|
||||
static struct {
|
||||
int dinode;
|
||||
char dname[14];
|
||||
} dentry;
|
||||
register char *p;
|
||||
register int j;
|
||||
register struct lbuf *ep;
|
||||
|
||||
if (fopen(dir, &inf) < 0) {
|
||||
printf("%s unreadable\n", dir);
|
||||
return;
|
||||
}
|
||||
tblocks = 0;
|
||||
for(;;) {
|
||||
p = &dentry;
|
||||
for (j=0; j<16; j++)
|
||||
*p++ = getc(&inf);
|
||||
if (dentry.dinode==0
|
||||
|| aflg==0 && dentry.dname[0]=='.')
|
||||
continue;
|
||||
if (dentry.dinode == -1)
|
||||
break;
|
||||
ep = gstat(makename(dir, dentry.dname), 0);
|
||||
if (ep->lnum != -1)
|
||||
ep->lnum = dentry.dinode;
|
||||
for (j=0; j<14; j++)
|
||||
ep->lname[j] = dentry.dname[j];
|
||||
}
|
||||
close(inf.fdes);
|
||||
}
|
||||
|
||||
gstat(file, argfl)
|
||||
char *file;
|
||||
{
|
||||
struct ibuf statb;
|
||||
register struct lbuf *rep;
|
||||
|
||||
if (lastp+1 >= rlastp) {
|
||||
sbrk(512);
|
||||
rlastp.idev =+ 512;
|
||||
}
|
||||
rep = lastp;
|
||||
lastp++;
|
||||
rep->lflags = 0;
|
||||
rep->lnum = 0;
|
||||
if (argfl || statreq) {
|
||||
if (stat(file, &statb)<0) {
|
||||
printf("%s not found\n", file);
|
||||
statb.inum = -1;
|
||||
statb.isize0 = 0;
|
||||
statb.isize = 0;
|
||||
statb.iflags = 0;
|
||||
if (argfl) {
|
||||
lastp--;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
rep->lnum = statb.inum;
|
||||
statb.iflags =& ~DIR;
|
||||
if ((statb.iflags&IFMT) == 060000) {
|
||||
statb.iflags =& ~020000;
|
||||
} else if ((statb.iflags&IFMT)==040000) {
|
||||
statb.iflags =& ~IFMT;
|
||||
statb.iflags =| DIR;
|
||||
}
|
||||
statb.iflags =& ~ LARGE;
|
||||
if (statb.iflags & RSTXT)
|
||||
statb.iflags =| STXT;
|
||||
statb.iflags =& ~ RSTXT;
|
||||
rep->lflags = statb.iflags;
|
||||
rep->luid = statb.iuid;
|
||||
rep->lgid = statb.igid;
|
||||
rep->lnl = statb.inl;
|
||||
rep->lsize0 = statb.isize0;
|
||||
rep->lsize = statb.isize;
|
||||
if (rep->lflags & (BLK|CHR) && lflg)
|
||||
rep->lsize = statb.iaddr[0];
|
||||
rep->lmtime[0] = statb.imtime[0];
|
||||
rep->lmtime[1] = statb.imtime[1];
|
||||
if(uflg) {
|
||||
rep->lmtime[0] = statb.iatime[0];
|
||||
rep->lmtime[1] = statb.iatime[1];
|
||||
}
|
||||
tblocks =+ nblock(statb.isize0, statb.isize);
|
||||
}
|
||||
return(rep);
|
||||
}
|
||||
|
||||
compar(ap1, ap2)
|
||||
struct lbuf *ap1, *ap2;
|
||||
{
|
||||
register struct lbuf *p1, *p2;
|
||||
register int i;
|
||||
int j;
|
||||
struct { char *charp;};
|
||||
|
||||
p1 = ap1;
|
||||
p2 = ap2;
|
||||
if (dflg==0) {
|
||||
if ((p1->lflags&(DIR|ISARG)) == (DIR|ISARG)) {
|
||||
if ((p2->lflags&(DIR|ISARG)) != (DIR|ISARG))
|
||||
return(1);
|
||||
} else {
|
||||
if ((p2->lflags&(DIR|ISARG)) == (DIR|ISARG))
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
if (tflg) {
|
||||
i = 0;
|
||||
if (p2->lmtime[0] > p1->lmtime[0])
|
||||
i++;
|
||||
else if (p2->lmtime[0] < p1->lmtime[0])
|
||||
i--;
|
||||
else if (p2->lmtime[1] > p1->lmtime[1])
|
||||
i++;
|
||||
else if (p2->lmtime[1] < p1->lmtime[1])
|
||||
i--;
|
||||
return(i*rflg);
|
||||
}
|
||||
if (p1->lflags&ISARG)
|
||||
p1 = p1->namep;
|
||||
else
|
||||
p1 = p1->lname;
|
||||
if (p2->lflags&ISARG)
|
||||
p2 = p2->namep;
|
||||
else
|
||||
p2 = p2->lname;
|
||||
for (;;)
|
||||
if ((j = *p1.charp++ - *p2.charp++) || p1.charp[-1]==0)
|
||||
return(rflg*j);
|
||||
return(0);
|
||||
}
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
cc -s -f -O ac.c
|
||||
cmp a.out /usr/bin/ac
|
||||
cp a.out /usr/bin/ac
|
||||
|
||||
as ar.s
|
||||
strip a.out
|
||||
cmp a.out /bin/ar
|
||||
cp a.out /bin/ar
|
||||
|
||||
cc -s -O banner.c
|
||||
cmp a.out /usr/bin/banner
|
||||
cp a.out /usr/bin/banner
|
||||
|
||||
as bas.s
|
||||
ld -s -n a.out -l
|
||||
cmp a.out /bin/bas
|
||||
cp a.out /bin/bas
|
||||
|
||||
yacc bc.y
|
||||
cc -s -O y.tab.c -ly
|
||||
cmp a.out /usr/bin/bc
|
||||
cp a.out /usr/bin/bc
|
||||
rm y.tab.c
|
||||
|
||||
cc -s -O bcd.c
|
||||
cmp a.out /usr/bin/bcd
|
||||
cp a.out /usr/bin/bcd
|
||||
|
||||
cc -s -O cal.c
|
||||
cmp a.out /usr/bin/cal
|
||||
cp a.out /usr/bin/cal
|
||||
|
||||
as cat.s
|
||||
strip a.out
|
||||
cmp a.out /bin/cat
|
||||
cp a.out /bin/cat
|
||||
|
||||
cc -s -n -O cc.c
|
||||
cmp a.out /bin/cc
|
||||
cp a.out /bin/cc
|
||||
|
||||
cc -s -f -O cdb?.c
|
||||
cmp a.out /bin/cdb
|
||||
cp a.out /bin/cdb
|
||||
rm cdb?.o
|
||||
|
||||
as chgrp.s
|
||||
ld -s a.out -l
|
||||
cmp a.out /bin/chgrp
|
||||
cp a.out /bin/chgrp
|
||||
|
||||
cc -s -O chmod.c
|
||||
cmp a.out /bin/chmod
|
||||
cp a.out /bin/chmod
|
||||
|
||||
as chown.s
|
||||
ld -s a.out -l
|
||||
cmp a.out /bin/chown
|
||||
cp a.out /bin/chown
|
||||
|
||||
as clri.s
|
||||
strip a.out
|
||||
cmp a.out /bin/clri
|
||||
cp a.out /bin/clri
|
||||
|
||||
cc -s -O cmp.c
|
||||
cmp a.out /bin/cmp
|
||||
cp a.out /bin/cmp
|
||||
|
||||
cc -s -O col.c
|
||||
cmp a.out /usr/bin/col
|
||||
cp a.out /usr/bin/col
|
||||
|
||||
cc -s -O comm.c
|
||||
cmp a.out /usr/bin/comm
|
||||
cp a.out /usr/bin/comm
|
||||
|
||||
cc -s -O cp.c
|
||||
cmp a.out /bin/cp
|
||||
cp a.out /bin/cp
|
||||
|
||||
cc -s -O cpall.c
|
||||
cmp a.out /usr/bin/cpall
|
||||
cp a.out /usr/bin/cpall
|
||||
|
||||
cc -s -O cron.c
|
||||
cmp a.out /etc/cron
|
||||
cp a.out /etc/cron
|
||||
|
||||
cc -s -O crypt.c
|
||||
cmp a.out /usr/bin/crypt
|
||||
cp a.out /usr/bin/crypt
|
||||
|
||||
cc -s -O date.c
|
||||
cmp a.out /bin/date
|
||||
cp a.out /bin/date
|
||||
|
||||
as db?.s
|
||||
strip a.out
|
||||
cmp a.out /bin/db
|
||||
cp a.out /bin/db
|
||||
|
||||
as dc?.s
|
||||
strip a.out
|
||||
cmp a.out /bin/dc
|
||||
cp a.out /bin/dc
|
||||
|
||||
cc -s -O dcheck.c
|
||||
cmp a.out /bin/dcheck
|
||||
cp a.out /bin/dcheck
|
||||
|
||||
cc -s -O dd.c
|
||||
cmp a.out /bin/dd
|
||||
cp a.out /bin/dd
|
||||
|
||||
cc -s -O df.c
|
||||
cmp a.out /bin/df
|
||||
cp a.out /bin/df
|
||||
|
||||
cc -c -O diff1.c
|
||||
as diff2.s
|
||||
cc -s diff1.o a.out
|
||||
cmp a.out /usr/bin/diff
|
||||
cp a.out /usr/bin/diff
|
||||
rm diff1.o
|
||||
|
||||
as dsw.s
|
||||
strip a.out
|
||||
cmp a.out /bin/dsw
|
||||
cp a.out /bin/dsw
|
||||
|
||||
as du.s
|
||||
ld -s a.out -l
|
||||
cmp a.out /bin/du
|
||||
cp a.out /bin/du
|
||||
|
||||
cc -s -O dump.c
|
||||
cmp a.out /bin/dump
|
||||
cp a.out /bin/dump
|
||||
|
||||
cc -s -O echo.c
|
||||
cmp a.out /bin/echo
|
||||
cp a.out /bin/echo
|
||||
|
||||
cc -s -n -O ed.c
|
||||
cmp a.out /bin/ed
|
||||
cp a.out /bin/ed
|
||||
|
||||
cc -s -O exit.c
|
||||
cmp a.out /bin/exit
|
||||
cp a.out /bin/exit
|
||||
|
||||
cc -s -O fc.c
|
||||
cmp a.out /bin/fc
|
||||
cp a.out /bin/fc
|
||||
|
||||
as fed?.s form[56].s
|
||||
strip a.out
|
||||
cmp a.out /usr/bin/fed
|
||||
cp a.out /usr/bin/fed
|
||||
|
||||
cc -s -O file.c
|
||||
cmp a.out /bin/file
|
||||
cp a.out /bin/file
|
||||
|
||||
cc -s -O find.c
|
||||
cmp a.out /usr/bin/find
|
||||
cp a.out /usr/bin/find
|
||||
|
||||
as form?.s
|
||||
strip a.out
|
||||
cmp a.out /usr/bin/form
|
||||
cp a.out /usr/bin/form
|
||||
|
||||
cc -s -n -O getty.c
|
||||
cmp a.out /etc/getty
|
||||
cp a.out /etc/getty
|
||||
|
||||
cc -s -n -O glob.c
|
||||
cmp a.out /etc/glob
|
||||
cp a.out /etc/glob
|
||||
|
||||
cc -s -O goto.c
|
||||
cmp a.out /bin/goto
|
||||
cp a.out /bin/goto
|
||||
|
||||
cc -s -O grep.c
|
||||
cmp a.out /usr/bin/grep
|
||||
cp a.out /usr/bin/grep
|
||||
|
||||
cc -s -O gsi.c
|
||||
cmp a.out /usr/bin/gsi
|
||||
cp a.out /usr/bin/gsi
|
||||
|
||||
cc -s -O icheck.c
|
||||
cmp a.out /bin/icheck
|
||||
cp a.out /bin/icheck
|
||||
|
||||
cc -s -O if.c
|
||||
cmp a.out /bin/if
|
||||
cp a.out /bin/if
|
||||
|
||||
cc -s -n -O init.c
|
||||
cmp a.out /etc/init
|
||||
cp a.out /etc/init
|
||||
|
||||
as kill.s
|
||||
strip a.out
|
||||
cmp a.out /bin/kill
|
||||
cp a.out /bin/kill
|
||||
|
||||
cc -s -n -O ld.c
|
||||
cmp a.out /bin/ld
|
||||
cp a.out /bin/ld
|
||||
|
||||
cc -s -O ln.c
|
||||
cmp a.out /bin/ln
|
||||
cp a.out /bin/ln
|
||||
|
||||
cc -s -O login.c
|
||||
cmp a.out /bin/login
|
||||
cp a.out /bin/login
|
||||
|
||||
as lpd.s
|
||||
ld -s a.out -l
|
||||
cmp a.out /etc/lpd
|
||||
cp a.out /etc/lpd
|
||||
|
||||
cc -s -O lpr.c
|
||||
cmp a.out /lib/lpr
|
||||
cp a.out /lib/lpr
|
||||
|
||||
cc -s -n -O ls.c
|
||||
cmp a.out /bin/ls
|
||||
cp a.out /bin/ls
|
||||
|
||||
rm a.out
|
||||
Reference in New Issue
Block a user