Add original unix v6

This commit is contained in:
memnoth
2018-01-27 22:35:41 +09:00
commit 2c7099ee50
664 changed files with 106254 additions and 0 deletions
+285
View File
@@ -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
View File
@@ -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.
+132
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+567
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+65
View File
@@ -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
View File
@@ -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);
}
+965
View File
@@ -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 &regbuf[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 < &reglist[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();
}
+384
View File
@@ -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;
}
}
+106
View File
@@ -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.
+27
View File
@@ -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);
}
+105
View File
@@ -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.
+63
View File
@@ -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.
+90
View File
@@ -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
View File
@@ -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);
}
+168
View File
@@ -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);
}
}
+57
View File
@@ -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);
}
+27
View File
@@ -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();
}
}
+234
View File
@@ -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;
}
+207
View File
@@ -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;
}
+150
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+54
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+457
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+219
View File
@@ -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
View File
@@ -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);
}
+97
View File
@@ -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();
}
}
+463
View File
@@ -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]);
}
}
+56
View File
@@ -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
+95
View File
@@ -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
View File
@@ -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.
+451
View File
@@ -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);
}
+10
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
/* exit -- end runcom */
main() {
seek(0, 0, 2);
}
+468
View File
@@ -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));
}
+110
View File
@@ -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
+533
View File
@@ -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
+358
View File
@@ -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
+237
View File
@@ -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);
}
+449
View File
@@ -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(&not,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);
}
+165
View File
@@ -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
+92
View File
@@ -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
+147
View File
@@ -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
+250
View File
@@ -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:
+741
View File
@@ -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
+456
View File
@@ -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
+199
View File
@@ -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);
}
+256
View File
@@ -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);
}
+67
View File
@@ -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());
}
+342
View File
@@ -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
View File
@@ -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);
}
+321
View File
@@ -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
View File
@@ -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);
}
+219
View File
@@ -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);
}
}
+74
View File
@@ -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
View File
@@ -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;
}
+48
View File
@@ -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);
}
+190
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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