From 7cc2452cb9af62b48ab647a725c1ab2e5c538ecd Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Tue, 26 Nov 1974 18:13:21 -0500 Subject: [PATCH] Research V5 development Work on file usr/source/s4/crt0.s Work on file usr/source/s4/reset.s Work on file usr/source/s1/ar.s Work on file usr/source/s2/pwd.c Work on file usr/source/s1/if.c Work on file usr/sys/reg.h Work on file usr/source/s2/stty.c Co-Authored-By: Dennis Ritchie Synthesized-from: v5 --- usr/source/s1/ar.s | 546 ++++++++++++++++++++++++++++++++++++++++++ usr/source/s1/if.c | 146 +++++++++++ usr/source/s2/pwd.c | 56 +++++ usr/source/s2/stty.c | 88 +++++++ usr/source/s4/crt0.s | 19 ++ usr/source/s4/reset.s | 33 +++ usr/sys/reg.h | 9 + 7 files changed, 897 insertions(+) create mode 100644 usr/source/s1/ar.s create mode 100644 usr/source/s1/if.c create mode 100644 usr/source/s2/pwd.c create mode 100644 usr/source/s2/stty.c create mode 100644 usr/source/s4/crt0.s create mode 100644 usr/source/s4/reset.s create mode 100644 usr/sys/reg.h diff --git a/usr/source/s1/ar.s b/usr/source/s1/ar.s new file mode 100644 index 0000000000..a42e574b28 --- /dev/null +++ b/usr/source/s1/ar.s @@ -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 + + .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 + + .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 + + .even + +crterr: + jsr r5,diag + + .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: + .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. + diff --git a/usr/source/s1/if.c b/usr/source/s1/if.c new file mode 100644 index 0000000000..220dd97cb0 --- /dev/null +++ b/usr/source/s1/if.c @@ -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); +} diff --git a/usr/source/s2/pwd.c b/usr/source/s2/pwd.c new file mode 100644 index 0000000000..c323323c27 --- /dev/null +++ b/usr/source/s2/pwd.c @@ -0,0 +1,56 @@ +char dot[] "."; +char dotdot[] ".."; +char root[] "/"; +char name[512]; +int file, off -1; +struct statb {int devn, inum, i[18];}x; +struct entry { int jnum; char name[16];}y; + +main() { + int n; + +loop0: + stat(dot, &x); + if((file = open(dotdot,0)) < 0) prname(); +loop1: + if((n = read(file,&y,16)) < 16) prname(); + if(y.jnum != x.inum)goto loop1; + close(file); + if(y.jnum == 1) ckroot(); + cat(); + chdir(dotdot); + goto loop0; +} +ckroot() { + int i, n; + + if((n = stat(y.name,&x)) < 0) prname(); + i = x.devn; + if((n = chdir(root)) < 0) prname(); + if((file = open(root,0)) < 0) prname(); +loop: + if((n = read(file,&y,16)) < 16) prname(); + if(y.jnum == 0) goto loop; + if((n = stat(y.name,&x)) < 0) prname(); + if(x.devn != i) goto loop; + x.i[0] =& 060000; + if(x.i[0] != 040000) goto loop; + cat(); + prname(); +} +prname() { + name[off] = '\n'; + write(1,name,off+1); + exit(); +} +cat() { + int i, j; + + i = -1; + while(y.name[++i] != 0); + if((off+i+2) > 511) prname(); + for(j=off+1; j>=0; --j) name[j+i+1] = name[j]; + off=i+off+1; + name[i] = root[0]; + for(--i; i>=0; --i) name[i] = y.name[i]; +} diff --git a/usr/source/s2/stty.c b/usr/source/s2/stty.c new file mode 100644 index 0000000000..ece5bfa5ba --- /dev/null +++ b/usr/source/s2/stty.c @@ -0,0 +1,88 @@ +char *arg; +int mode[3]; + +main(argc, argv) +char *argv[]; +{ + int i; + + gtty(1, mode); + while(--argc > 0) { + + arg = *++argv; + if(eq("erase") || eq("kill") || eq("ek")) + mode[1] = '#@'; + if(eq("even")) + set(0200); + if(eq("-even")) + reset(0200); + if(eq("odd")) + set(0100); + if(eq("-odd")) + reset(0100); + if(eq("raw")) + set(040); + if(eq("-raw") || eq("cooked")) + reset(040); + if(eq("-nl")) + set(020); + if(eq("nl")) + reset(020); + if(eq("echo")) + set(010); + if(eq("-echo")) + reset(010); + if(eq("lcase")) + set(04); + if(eq("-lcase")) + reset(04); + if(eq("-tabs")) + set(02); + if(eq("tabs")) + reset(02); + if(eq("-delay")) + set(01); + if(eq("delay")) + reset(01); + if(eq("hup")) + set(0400); + if(eq("-hup")) + reset(0400); + if(eq("tdelay")) + reset(010000); + if(eq("-tdelay")) + set(010000); + if(arg) + printf("unknown mode: %s\n", arg); + } + stty(1,mode); +} + +eq(string) +char *string; +{ + int i; + + if(!arg) + return(0); + i = 0; +loop: + if(arg[i] != string[i]) + return(0); + if(arg[i++] != '\0') + goto loop; + arg = 0; + return(1); +} + +set(b) +{ + + mode[2] =| b; +} + +reset(b) +{ + + mode[2] =& ~b; +} diff --git a/usr/source/s4/crt0.s b/usr/source/s4/crt0.s new file mode 100644 index 0000000000..22c596722d --- /dev/null +++ b/usr/source/s4/crt0.s @@ -0,0 +1,19 @@ +/ C runtime startoff + +.globl savr5 + +.globl _main + +start: + setd + mov sp,r0 + mov (r0),-(sp) + tst (r0)+ + mov r0,2(sp) + jsr pc,_main + cmp (sp)+,(sp)+ + clr r0 + sys exit + +.bss +savr5: .=.+2 diff --git a/usr/source/s4/reset.s b/usr/source/s4/reset.s new file mode 100644 index 0000000000..c2ca20a33b --- /dev/null +++ b/usr/source/s4/reset.s @@ -0,0 +1,33 @@ +/ C library -- reset, setexit + +/ reset() +/ will generate a "return" from +/ the last call to +/ setexit() +/ by restoring sp, r5 +/ and doing a return. +/ +/ useful for going back to the main loop +/ after a horrible error in a lowlevel +/ routine. + +.globl _setexit +.globl _reset + +_setexit: + mov sp,ssp + mov r5,sr5 + mov (sp),spc + rts pc + +_reset: + mov ssp,sp + mov sr5,r5 + mov spc,(sp) + rts pc + +.bss +ssp: .=.+2 +sr5: .=.+2 +spc: .=.+2 + diff --git a/usr/sys/reg.h b/usr/sys/reg.h new file mode 100644 index 0000000000..ce330b887b --- /dev/null +++ b/usr/sys/reg.h @@ -0,0 +1,9 @@ +#define R0 (0) +#define R1 (-2) +#define R2 (-9) +#define R3 (-8) +#define R4 (-7) +#define R5 (-6) +#define R6 (-3) +#define R7 (1) +#define RPS (2) -- 2.20.1