! "W N, R=    @ #D  D ҃TP  B ы e@W 0 ,"& 7   0ߋp@E A Ze      |@7x@ eE "  ɋ -lɋ e-RNHɋ ^?speakez/sbrk.s gn &&dcheck.c  u(df.c  y/xintel/as80.c fHN2intel/optab.8080 !NG?+dino.c t2Zgoto.c Y q8icheck.c e v:Nls.c @ {kCncheck.c  x{Kned.c 9X pcKnum.c  }Eps.c  sFbsh.c x5 t6who.c U rimlac/boda1.iml x>Gjimlac/graf1.iml >K\oimlac/load.c !GsoZ9imlac/patch.c  ,?imlac.c OFimlac/graf1n.iml >K]\plane.dat b j_imlac/convert.c R CzAtek.c Vdscanf.c HO` ge/cc70a.c Z ;ge/cc70b.c s >nhge/cc70c.c d 9ge/cc70h.c  i4(ge/creg.70s f $ lwarnock.c ,:!ge/go70 Bimlac/graf4.iml >Gjge/cvtfi.70s  4B Pge/cvtif.70s EB ^Tge/fptest.c q ~ge/c0t.s `}u-ge/i70cvt.c  $intel/types.8080 'NK#warn.s Y'T ximlac/graf4n.iml >Gjintel/opcodes.ge N^intel/opcodes.im N[E# /* * link.c -- * dynamic load/link package * * d. anderson, july,1976 * m.e. cad laboratory. purdue u. */ /* compile constants: */ /* NLIB = number of libraries */ #define NLIB 3 #define ARCID 0177555 #define FMAGIC 0407 #define RELFLG 01 /* data area */ struct lib { int fildes; int nleft; char *nextp; char buff[512]; } liblist[NLIB]; /* library buffered input */ struct lib *libp { &liblist[0] }; struct ub { /* used/free list block structure */ int fsize; /* block length including header */ char *next; /* pointer to next block, -1 at end */ char name[8]; /* usedlist function name */ int entry; /* used for addressing only- first word of code here */ }; int usedlist[] { /* the usedlist dummy header */ 0, -1, }; int freelist[] { /* the freelist dummy header */ 0, -1, }; struct archdr { /* archive file format */ char aname[8]; int atime[2]; char auid,amode; int asize; } archdr; struct filhdr { /* unix file header format */ int fmagic; int tsize; int dsize; int bsize; int ssize; int pad1; int pad2; int relflg; } filhdr ; /* * link -- main entry * * call function aname. aname null terminated <= 8 chars ! * returns the function return value, or 0 if can't be executed. * error message handled via printf. */ link(aname) char *aname; { register char *cp, *np; register struct lib *lp; int (*fp)(); /* search for function in core */ loop: for( cp=usedlist; (np=cp->next) != -1; cp=np) if( equal(aname,np->name) ){ fp= &np->entry; return( (*fp)(aname) ); } /* not in memory, search libraries */ for( lp= liblist; lpfildes,&filhdr, sizeof filhdr) != sizeof filhdr){ printf("load read error in file: %s\n",aname); return(0); } if( filhdr.relflg&RELFLG || filhdr.fmagic != FMAGIC) { printf("bad format on file: %s\n",aname); return(0); } /* get memory slot */ if( (p= getmem(filhdr.tsize+filhdr.dsize+filhdr.bsize+8) ) == 0){ printf("no room for file: %s\n",aname); return(0); } /* begin loading procedure */ /* first place name - could extend into text, but don't care */ pp= p->name; s=aname; while( *pp++ = *s++ ) ; /* copy text , data into memory */ if( (len= filhdr.tsize+filhdr.dsize) ) read(lp->fildes,&p->entry,len); /* now zero bss (assumed by many programs) */ s= &p->entry; s=+ len; t=s; s = filhdr.bsize >> 1; while( s-- ) *t++ = 0; /* now do relocation */ t = &p->entry; if( (len=>>1) ) { lp->nleft = 0; while( len-- ) *t++ =+ ((((s=getw(lp))==0) || (s&1 == 1) )? 0: &p->entry); } return(1); } /* * initlib -- initialize library (archive) file for link */ initlib(lname) char *lname; { if( libp <= &liblist[NLIB] ) { if( fopen(lname,libp) >= 0){ if( getw(libp) != ARCID ){ printf("%s not archive \n",lname); return(0); } return(libp++); } printf("can't open %s\n",lname); return(0); } printf("too many libraries\n"); return(0); } /* * inlib -- search library lp for aname */ inlib(lp,aname) char *aname; struct lib *lp; { seek(lp->fildes,2,0); while(read(lp->fildes,&archdr, sizeof archdr) == sizeof archdr){ if( equal(aname,archdr.aname) ) return(1); seek(lp->fildes,archdr.asize,1); } return(0); } /* * equal -- compare as and ap for equality to 8 char. */ equal(as,ap) char *as,*ap; { register char *s,*p; s=as; p=ap; while( *s ) if( *s++ != *p++ ) return(0); if( p== (ap+8) ) return(1); else return( *s== *p); } /* * getmem -- acquire memory of asize from dynamic area */ char *getmem(asize) int asize; { char *alloc(); int size; register char *cp, *np, *ptr; if( (size=asize) <= 0) return(0); size =+ 5; size =& 0177776; if( (ptr= alloc(size) ) != -1) { exit: for( cp=usedlist; (np=cp->next)next = np; cp->next = ptr; return( ptr ); } /* no room available, can we omit a single function ? */ for(cp=usedlist; (np=cp->next) != -1; cp=np){ if( np->fsize >= size ) { if( size+2 >= np->fsize) return( np ); cp = np+ size; cp->fsize = np->fsize - size; np->fsize = size; free( cp ); return( np ); } } /* last try, start at top, freeing space until it fits or fails */ cp = usedlist; while( (np=cp->next) != -1){ cp->next = np->next; free( np ); if( (ptr=alloc(size) ) != -1) goto exit; } return(0); } /* * listmem -- print memory allocation summary */ listmem() { register char *cp,*np; register first; first=1; for(cp=usedlist; (np=cp->next) != -1; cp=np) { if( first ) { first=0; printf("usedlist:\nname start size\n"); } printf("%-8s%6o %6o\n",np->name,np,np->fsize); } first=1; for( cp=freelist; (np=cp->next) != -1; cp=np){ if( first ){ first=0; printf("freelist:\n start size\n"); } printf("%6o %6o\n",np,np->fsize); } } /* * modified C library alloc/free */ alloc(asize) int asize; { register size; register char *np; register char *cp; char *sbrk(); if ((size = asize) == 0) return(0); for (;;) { for (cp=freelist; (np= cp->next) != -1; cp=np) { if (np->fsize>=size) { if (size+2 >= np->fsize) { cp->next = np->next; return( np ); } cp = cp->next = np+size; cp->fsize = np->fsize - size; cp->next = np->next; np->fsize = size; return( np ); } } asize = size<1024? 1024: size; if ((cp = sbrk(asize)) == -1) { return (-1); } cp->fsize = asize; free( cp ); } } free(aptr) char *aptr; { register char *ptr; register char *cp; register char *np; ptr = aptr; for( cp = freelist; (np=cp->next) < ptr; cp=np) ; if (ptr+ptr->fsize == np) { ptr->fsize =+ np->fsize; ptr->next = np->next; np = ptr; } else ptr->next = np; if (cp+cp->fsize == ptr) { cp->fsize =+ ptr->fsize; cp->next = ptr->next; } else cp->next = ptr; } } } asize = size<1024? 1024: size; if ((cp = sbrk(asize)): loop if $1x = x exit echo $1 cc -c $1.c ld -r -d $1.o -lc -l mv a.out $1 shift goto loop { register char *ptr; register char *cp; register char *np; ptr = aptr; for( cp = freelist; (np=cp->next) < ptr; cp=np) ; if (ptr+ptr->fsize == np) { ptr->fsize =+ np->fsize; ptr->next = np->next; np = ptr; } else ptr->next = np; if (cp+cp->fsize == ptr) { cp->fsize =+ ptr->fsize; cp->next = ptr->next; } else cp->next = ptr; } } } asize = size<1024? 1024: size; if ((cp = sbrk(asize))/old = sbrk(increment); / modified by dca, 12-aug-76 to check overflow condition. / /sbrk gets increment more core, and returns a pointer / to the beginning of the new core area / .globl _sbrk,_end, cerror _sbrk: mov r5,-(sp) mov sp,r5 mov nd,0f add 4(r5),0f bcs 2f / *** sys 0; 9f bec 1f 2: / *** jmp cerror 1: mov nd,r0 add 4(r5),nd mov (sp)+,r5 rts pc .globl _brk / brk(value) / as described in man2. / returns 0 for ok, -1 for error. _brk: mov r5,-(sp) mov sp,r5 mov 4(r5),0f sys 0; 9f bec 1f jmp cerror 1: mov 4(r5),nd clr r0 mov (sp)+,r5 rts pc .data 9: sys break; 0:.. nd: _end nt more core, and returns a pointer / to the beginning of the new core area / .globl _sbrk,_end, cerror _sbrk: mov r5,-(sp) mov sp,r5 mov nd,0f add 4(r5),0f bcs 2f / *** sys 0; 9f bec 1f 2: / *** jmp cerror 1: mov nd,r0 add 4(r5),nd mov (sp)+,r5 rts pc .globl _brk / brk(value) / as described in man2. / returns 0 for ok, -1 for error. _brk: mov r5,-(sp) mov sp,r5 mov 4(r5),0f sys 0; 9f # char *dargv[] { "/dev/rrp0", "/dev/rrp1", "/dev/rrp2", 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; ii_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); } 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(); } } bwchar *dargv[] { 0, "/dev/rrp0", "/dev/rrp1", "/dev/rrp2", "/dev/rrp3", "/dev/rrp4", "/dev/rrp5", "/dev/rrp6", "/dev/rrp7", 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; int nbavail; main(argc, argv) char **argv; { int i; if(argc <= 1) { for(argc = 1; dargv[argc]; argc++); argv = dargv; } for(i=1; i 1) printf("%s ", argv[i]); dfree(argv[i]); } } dfree(file) char *file; { float pcb(); int i; fi = open(file, 0); if(fi < 0) { printf("cannot open %s\n", file); return; } sync(); bread(1, &sblock); i = 0; nbavail = sblock.s_fsize - sblock.s_isize -2; while(alloc()) i++; printf("%6l %6.1f %%\n", i, pcb(i)); close(fi); } float pcb(n) { return((n*100.0)/nbavail); } 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_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(); } } nt\n"); return(0); } b = s# /* * dino -- dump inodes * * * syntax: * * dino [ [ []]] * * ::= name of device to dump inodes from * ::= first inode to dump * ::= last inode to dump * * semantics: * * no args => dump all inodes from default device. * 1 arg => dump all inodes from specified device. * 2 args => dump inode # from specified device * 3 args => dump inodes through from specified device * * if the bounds specified by or exceed those * on the device, they are trunicated. * * jjb 25 may 76 */ #include "/usr/sys/ino.h" struct{ char d_minor; char d_major; }; struct inode nodes[32]; struct{ int isize; int fsize; int junk[254]; } super_blk; int fd; int low 0; int high 0; int index 0; int blkno -1; char *device "/dev/rp0"; main(argc,argp) char **argp; { int i; switch(argc){ case 4: high = atoi(argp[3]); case 3: low = atoi(argp[2]); if(low > high) high = low; case 2: device = argp[1]; } if((fd = open(device,0)) < 0){ printf("can't open %s\n",device); exit(1); } if(seek(fd,1,3) < 0 || read(fd,&super_blk,512) != 512){ printf("can't read super block!\n"); exit(2); } if(high > super_blk.isize*32 || high <= 0) high = super_blk.isize*32; if(high < low) low = high; if(low == 0) low = 1; printf("inodes from %s, %d thru %d (isize = %d)\n", device,low,high,super_blk.isize); for(i=low; ii_mode; printf("%6o:\t",mode); if((mode&IALLOC) == 0){ printf(" not allocated\n\n"); return(0); } printf("type = "); fmt = (mode>>13)&03; if((mode&IFCHR) != 0) printf("%s device (%d,%d)",type[fmt], ino->i_addr[0].d_major, ino->i_addr[0].d_minor); else printf("%s",type[fmt]); if(mode&ILARG) if(ino->i_addr[7] != 0) printf(" (huge)"); else printf(" (large)"); printf(", prot = %3o",mode&0777); if(mode&ISUID) printf(", suid"); if(mode&ISGID) printf(", sgid"); if(mode&ISVTX) printf(", svtxt"); printf("\n\t%d links, uid=%d, gid=%d",ino->i_nlink, ino->i_uid,ino->i_gid); if((mode&IFCHR) == 0){ printf("\n\tsize = %s",locv(ino->i_size0,ino->i_size1)); printf("\n\tblocks used: "); for(i=0, p=ino->i_addr; i<8; i++) printf("%d, ",*p++); } printf("\n"); ptime("atime",ino->i_atime); putchar(';'); ptime("mtime",ino->i_mtime); printf("\n\n"); return(1); } ptime(s,t) char *s; int *t; { int *p; p = localtime(t); printf("\t%s: %d:%s%d, %d/%s%d/%d",s,p[2],(p[1]<10?"0":""),p[1],p[4],(p[3]<10?"0":""),p[3],p[5]); } gid=%d",ino->i_nlink, ino->i_uid,ino->i_gid); if((mint 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())==' ' || ch == 't'); 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()); } etlin(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# char *dargv[] { "/dev/rrp0", "/dev/rrp1", "/dev/rrp2", 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 nablks; 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; float pci(),pcb(); fi = open(file, sflg?2:0); if (fi < 0) { printf("cannot open %s\n", file); nerror =| 04; return; } printf("\n%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; nablks = sblock.s_fsize - 2 - sblock.s_isize; for(i=0; ino < nifiles; i =+ NINODE/16) { bread(i+2, inode, sizeof inode); for(j=0; ji_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_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; } 12) != 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' && /* num -- output a file with prefixed line numbers * * usage: num [infile [outfile] ] * * file defaults are to standard files. * * ...pavo 7-76 */ main(argc,argp) int argc; char **argp; { extern int fin, fout; int line, flag; char text, cr; fin = dup(0); fout = dup(1); line = 1; flag = 1; cr = '\n'; if(argc > 1) { if((fin = open(argp[1],0)) < 0) { fout = 2; printf("can't open file %s\n",argp[1]); exit(1); } if((argc > 2) && (fout = creat(argp[2],0644)) < 0) { fout = 2; printf("\nunable to write on %s\n",argp[2]); exit(1); } } while((text = getchar()) != '\0') { if(flag == 1) { flag = 0; printf(" %6d=%c",line++,text); } else putchar(text); if(text == '\n') flag = 1; } putchar(cr); flush(); } n = dup(0); fout = dup(1); line = 1; flag = 1; cr = '\n'; if(argc > 1) { if((fin = open(argp[1],0)) < 0) { fout = 2; printf("can't open file %s\n",argp[1]); exit(1); } if((argc > 2) && (fout = creat(argp[2],0644)) < 0) { f/* intel 8080 opcode table */ /* registers */ "a" ,7 ,024, "b" ,0 ,024, "c" ,1 ,024, "d" ,2 ,024, "e" ,3 ,024, "h" ,4 ,024, "l" ,5 ,024, "m" ,6 ,024, /* register pairs */ "sp" ,6 ,025, "psw" ,6 ,025, /* pseudo-opcodes */ ".word" ,0 ,03, ".byte" ,0 ,04, ".string" ,0 ,05, ".if" ,0 ,017, ".endif" ,0 ,020, ".global" ,0 ,021, /* no address opcodes */ "cma" ,0057 ,6, "cmc" ,0077 ,6, "daa" ,0047 ,6, "di" ,0363 ,6, "ei" ,0373 ,6, "hlt" ,0166 ,6, "nop" ,0000 ,6, "pchl" ,0351 ,6, "ral" ,0027 ,6, "rar" ,0037 ,6, "rc" ,0330 ,6, "ret" ,0311 ,6, "rlc" ,0007 ,6, "rm" ,0370 ,6, "rnc" ,0320 ,6, "rnz" ,0300 ,6, "rp" ,0360 ,6, "rpe" ,0350 ,6, "rpo" ,0340 ,6, "rrc" ,0017 ,6, "rz" ,0310 ,6, "sphl" ,0371 ,6, "stc" ,0067 ,6, "xchg" ,0353 ,6, "xthl" ,0343 ,6, /* mov */ "mov" ,0100 ,7, /* mvi */ "mvi" ,0006 ,010, /* rp,data16 */ "lxi" ,0001 ,011, /* rhigh */ "dcr" ,0005 ,012, "inr" ,0004 ,012, "rst" ,0307 ,012, /* address */ "call" ,0315 ,013, "cc" ,0334 ,013, "cm" ,0374 ,013, "cnc" ,0324 ,013, "cnz" ,0304 ,013, "cp" ,0364 ,013, "cpe" ,0354 ,013, "cpo" ,0344 ,013, "cz" ,0314 ,013, "jc" ,0332 ,013, "jm" ,0372 ,013, "jmp" ,0303 ,013, "jnc" ,0322 ,013, "jnz" ,0302 ,013, "jp" ,0362 ,013, "jpe" ,0352 ,013, "jpo" ,0342 ,013, "jz" ,0312 ,013, "lda" ,0072 ,013, "lhld" ,0052 ,013, "shld" ,0042 ,013, "sta" ,0062 ,013, /* rp */ "dad" ,0011 ,014, "dcx" ,0013 ,014, "inx" ,0003 ,014, "ldax" ,0012 ,014, "pop" ,0301 ,014, "push" ,0305 ,014, "stax" ,0002 ,014, /* rlow */ "adc" ,0210 ,015, "add" ,0200 ,015, "ana" ,0240 ,015, "cmp" ,0270 ,015, "ora" ,0260 ,015, "sbb" ,0230 ,015, "sub" ,0220 ,015, "xra" ,0250 ,015, /* data */ "aci" ,0316 ,016, "adi" ,0306 ,016, "ani" ,0346 ,016, "cpi" ,0376 ,016, "in" ,0333 ,016, "ori" ,0366 ,016, "out" ,0323 ,016, "sbi" ,0336 ,016, "sui" ,0326 ,016, "xri" ,0356 ,016, 013, "sta" ,0062 ,013, /* rp */ "dad" ,0011 ,014, "dcx" ,0013 ,014, "inx" ,0003 ,014, "ldax" ,0012 ,014, "pop" ,0301 ,014, "push" ,0305 ,014, "stax" ,0002 ,014, /* rlow */ "adc" ,0210 ,015, "add" ,0200 ,015, "ana" ,0240 ,015, "cmp" ,0/* symbol types */ #define ABS 00 #define REL 01 #define GLOB 02 #define WORD 03 #define BYTE 04 #define STRING 05 #define NOADDR 06 #define MOV 07 #define MVI 010 #define LXI 011 #define RHIGH 012 #define ADDR 013 #define RP 014 #define RLOW 015 #define DATA 016 #define IF 017 #define ENDIF 020 #define GLOBAL 021 #define LABEL 022 #define EQU 023 #define REG 024 #define REGPAIR 025 #define RELLOW 01 #define RELHIGH 02 ,0002 ,014, /* rlow */ "adc" ,0210 ,015, "add" ,0200 ,015, "ana" ,0240 ,015, "cmp" ,0/* * load serial or parallel imlac * load [-spn] file * s = serial interface, * p = parallel interface,(default) * n = 0-3 , unit number (default=0). * file format: * word 1: data word count, * word 2: load address, * word 3-n: data words. */ int inbuf[259]; /* input buffer */ int outbuf[259]; /* output buffer */ int unit '0'; /* tty or dr unit */ int serial 0; /* serial=1, parallel=0 */ int oldmode[3]; /* space for old tty mode */ int raw[] { 0,0, 040 }; /* raw tty mode */ main(argc,argv) int argc; char *argv[]; { register i,j,c; char *s; if( argc <2 || argc > 3){ printf("usage: load [-sn] file\n"); exit(1); } if( argv[i=1][0] == '-'){ i++; j=1; while( c=argv[1][j++] ) switch( c ){ case 's': serial =1; break; case 'p': serial=0; break; case '0': case '1': case '2': case '3': unit = c; break; default: printf("bad switch\n"); exit(1); } } if( serial ){ s= "/dev/tty0"; s[8] = unit; } else { s= "/dev/dr0"; s[7]=unit; } if( fcreat(s,outbuf) < 0){ printf("can't write to %s\n",s); exit(1); } if( fopen(argv[i],inbuf) < 0){ printf("can't open %s\n",argv[i]); exit(1); } if( serial ) { gtty( outbuf[0],oldmode); stty( outbuf[0], raw); } if( (j=getw(inbuf)) <= 0) exit(0); putw(getw(inbuf)-1,outbuf); while( j-- ) putw(getw(inbuf),outbuf); fflush(outbuf); if( serial ) stty( outbuf[0], oldmode); close(outbuf[0]); putchar(7); } ial ){ s= "/dev/tty0"; s[8] = unit; } else { s= "/dev/dr0"; s[7]=unit; } if( fcreat(s,outb# /* * imlac * imlac filter for graphics * (source) | imlac n * n = unit number (default 0) * * d.c.anderson */ char sbuf[100]; int buf[259]; main(argc,argv) int argc; char *argv[]; { register i; register x; register char *p; i=0; if( argc == 2) i= atoi(argv[1]); if( setup(i) == -1){ printf("imlac %d busy\n",i); exit(1); } seg(1); while( (i=getc(buf))>0 ) switch( i){ case 'm': x=getw(buf); ploti(x,getw(buf),3); break; case 'p': x=getw(buf); ploti(x,getw(buf),5); break; case 'l': x=getw(buf); ploti(x,getw(buf),3); x=getw(buf); ploti(x,getw(buf),2); break; case 't': p=sbuf; while( (i=getc(buf)) != '\n') if( i>0 ) *p++=i; else{ printf(" eof\n"); exit(1); } *p++=0; string(2,sbuf); break; case 'e': seg(1); break; default: printf("imlac- bad command %c\n",i); } } ploti(x,y,p) { parm(0,x); parm(1,y); parm(2,p); funct(031); } ': x=getw(buf); ploti(x,getw(b/* * tek * tek filter for graphics * (source) | tek n * n = unit number (default 0) * * d.c.anderson * august, 1977 */ char sbuf[80]; int buf[259]; char ttyn[] "/dev/ttyx"; char gs[] "\035"; /* enter graphic mode */ char defoc[] "\033\150"; /* defocused mode */ char alpha[] "\035\033\140\037"; main(argc,argv) int argc; char *argv[]; { register i; register char *p; int x,y; extern fout; fout=1; if( argc == 2){ ttyn[8]=argv[1][0]; if( (fout=open(ttyn,1)) <= 0){ printf("tek:can't write to %s\n",ttyn); exit(1); } } while( (i=getc(buf))>0 ) switch( i){ case 'm': plott(getw(buf),getw(buf),gs); break; case 'p': plott(x=getw(buf),y=getw(buf),gs); plott(x,y,defoc); break; case 'l': plott(getw(buf),getw(buf),gs); plott(getw(buf),getw(buf),defoc); break; case 't': p=sbuf; *p++= 033; *p++= ':'; while( (i=getc(buf)) != '\n') if( i>0 ) if(p < &sbuf[80]) *p++=i; else{ printf(" eof\n"); exit(1); } write(fout,sbuf,p-sbuf); break; case 'e': write(fout,"\033\014\r\r",4); break; default: printf("tek- bad command %c\n",i); } write(fout,alpha,4); } /* * plott(x,y,string) */ plott(x,y,str) int x,y; char *str; { register rx,ry; char obuf[12]; register char *s; extern fout; s=obuf; while( *str ) *s++ = *str++; rx=x; ry=y; *s++ = (ry>>5) + 32; *s++ = (ry&037) + 96; *s++ = (rx>>5) + 32; *s++ = (rx&037) + 64; write(fout,obuf,s-obuf); } eof\n"); exit(1); } writ/ warnock assembly help routines / wcode(x,y) .globl _wlx, _wrx, _wty, _wby .globl _wcode _wcode: clr r0 cmp 2(sp),_wlx blt 0f bgt 1f cmp 4(sp),_wlx+2 bhis 1f 0: inc r0 br 2f 1: cmp 2(sp),_wrx bgt 0f blt 2f cmp 4(sp),_wrx+2 blos 2f 0: mov $2,r0 2: cmp 12(sp),_wby blt 0f bgt 1f cmp 14(sp),_wby+2 bhis 1f 0: bis $4,r0 br 2f 1: cmp 12(sp),_wty bgt 0f blt 2f cmp 14(sp),_wty+2 blos 2f 0: bis $10,r0 2: rts pc / angle(x,y) .globl _angle _angle: mov (sp)+,spc jsr pc,_wcode movb tab(r0),r0 mov spc,pc .data tab: .byte -1,4,0,-1,6,5 .byte 7,-1,2,3,1,-1 .bss spc: .=.+2 de _wcode: clr r0 cmp 2(sp),_wlx blt 0f bgt 1f cmp 4(sp),_wlx+2 bhis 1f 0: inc r0 br 2f 1: cmp 2(sp),_wrx bgt 0f blt 2f cmp 4(sp),_wrx+2 blos 2f 0: mov $2,r0 2: cmp 12(sp),_wby blt 0f bgt 1f cmp 14(sp),_wby+2 bhis 1f 0: bis $4,r0 br 2f 1: cmp 12(sp),_wty bgt 0f blt 2f cmp 14(sp),_wty+2 blos 2f 0: bis $10,r0 2: rts pc / angle(x,y) .globl _angle _angle: mov (sp)+,spc jsr pc,_wcode movb tab/* * tek * tek filter for graphics * (source) | tek n * n = unit number (default 0) * * d.c.anderson * august, 1977 */ char sbuf[80]; int buf[259]; char ttyn[] "/dev/ttyx"; char gs[] "\035"; /* enter graphic mode */ char defoc[] "\033\150"; /* defocused mode */ char alpha[] "\035\033\140\037"; main(argc,argv) int argc; char *argv[]; { register i; register x; register char *p; int y; extern fout; fout=1; if( argc == 2){ ttyn[8]=argv[1][0]; if( (fout=open(ttyn,1)) <= 0){ printf("tek:can't write to %s\n",ttyn); exit(1); } } while( (i=getc(buf))>0 ) switch( i){ case 'm': x=getw(buf); plott(x,getw(buf),gs); break; case 'p': x=getw(buf); plott(x,y=getw(buf),gs); plott(x,y,defoc); break; case 'l': x=getw(buf); plott(x,getw(buf),gs); x=getw(buf); plott(x,getw(buf),defoc); break; case 't': p=sbuf; *p++= 033; *p++= ':'; while( (i=getc(buf)) != '\n') if( i>0 ) if(p < &sbuf[80]) *p++=i; else{ printf(" eof\n"); exit(1); } write(fout,sbuf,p-sbuf); break; case 'e': write(fout,"\033\014\r\r",4); break; default: printf("tek- bad command %c\n",i); } write(fout,alpha,4); } /* * plott(x,y,string) */ plott(x,y,str) int x,y; char *str; { register rx,ry; char obuf[12]; register char *s; extern fout; s=obuf; while( *str ) *s++ = *str++; rx=x; ry=y; *s++ = (ry>>5) + 32; *s++ = (ry&037) + 96; *s++ = (rx>>5) + 32; *s++ = (rx&037) + 64; write(fout,obuf,s-obuf); } eof\n"); exit(1); } write(fout,sbuf,p-sbuf); break; case 'e': write(fout,"\033\014\r\r",4); break; default: printf("tek- bad command %c\n",i); } write(fout,alpha,4); } /* * plott(x,y,string) */ plott(x,y,str) int x,y; char *str; { register rx,ry; char obuf[12]; register char *s; extern fout; s=obuf; while( *str ) *s++ = *str++; rx=x; ry=y; *s++ = (ry>>5) + 32; *s++ = (ry&037) + 96; *s++ = (rx>>5) + 32; *s++ = (rx&037) + 64; write(fout,obuf,s-obu/* * load serial or parallel imlac * load [-spn] file * s = serial interface, * p = parallel interface,(default) * n = 0-3 , unit number (default=0). * file format: * word 1: data word count, * word 2: load address, * word 3-n: data words. */ int inbuf[259]; /* input buffer */ int outbuf[259]; /* output buffer */ int unit '0'; /* tty or dr unit */ int serial 0; /* serial=1, parallel=0 */ int oldmode[3]; /* space for old tty mode */ int raw[] { 0,0, 040 }; /* raw tty mode */ main(argc,argv) int argc; char *argv[]; { register i,j,c; char *s; if( argc <2 || argc > 3){ printf("usage: load [-spn] file\n"); exit(1); } if( argv[i=1][0] == '-'){ i++; j=1; while( c=argv[1][j++] ) switch( c ){ case 's': serial=1; break; case 'p': serial=0; break; case '0': case '1': case '2': case '3': unit = c; break; default: printf("bad switch\n"); exit(1); } } if( serial ){ s= "/dev/tty0"; s[8] = unit; } else { s= "/dev/dr0"; s[7]=unit; } if( fcreat(s,outbuf) < 0){ printf("can't write to %s\n",s); exit(1); } if( fopen(argv[i],inbuf) < 0){ printf("can't open %s\n",argv[i]); exit(1); } if( (j=getw(inbuf)) <= 0) exit(0); i=getw(inbuf)-1; if( serial ) { gtty( outbuf[0],oldmode); stty( outbuf[0], raw); putc(i>>8,outbuf); putc(i,outbuf); while( j--){ i=getw(inbuf); putc(i>>8,outbuf); putc(i,outbuf); } }else{ putw(i,outbuf); while( j-- ) putw(getw(inbuf),outbuf); } fflush(outbuf); if( serial ) stty( outbuf[0], oldmode); close(outbuf[0]); putchar(7); } o %s\n",s); exit(1); } if( fopen(argv[i],inbuf) < 0){ printf("can't open %s\n",argv[i]); exit(1); } if( (j=getw(inbuf)) <= 0) exit(0); i=getw(inbuf)-1; if( serial ) { gtty( outbuf[0],oldmode); stty( outbuf[0], raw); putc(i>>8,outbuf); putc(i,outbuf); while( j--){ i=getw(inbuf); putc(i>>8,outbuf); putc(i,outbuf); } }else{ putw(i,outbuf); while( j-- ) putw(getw(inbuf),outbuf); } fflush(outbuf); if( serial ) stty( outbuf[0], oldmode); DF0 3 2 AI 9F0 3 1 AIR 4A0 3 2 AH CA0 3 2 AHI 0A0 3 1 AHR 610 3 2 AHM 260 3 1 AIS 650 3 2 ABL 640 3 2 ATL 4E0 3 2 ACH 0E0 3 1 ACHR 440 3 2 NH C40 3 2 NHI 040 3 1 NHR D50 3 AL 410 2 BAL 010 1 BALR 430 2 BFC 030 1 BFCR 420 2 BTC 020 1 BTCR 200 6 BTBS 0 210 6 BTFS 220 6 BFBS 0 230 6 BFFS C00 2 BXH C10 2 BXLE 490 2 CH C90 2 CHI 090 1 CHR D40 2 CLB 450 2 CLH C50 2 CLHI 050 1 CLHR 4D0 2 DH 0D0 1 DHR 940 1 EXBR 950 1 EPSR 470 2 XH C70 2 XHI 070 1 XHR 6A0 2 AE 2A0 1 AER 690 2 CE 290 1 CER 6D0 2 DE 2D0 1 DER 680 2 LE 280 1 LER 6C0 2 ME 2C0 1 MER 600 2 STE 6B0 2 SE 2B0 1 SER D30 2 LB 930 1 LBR 250 1 LCS 480 2 LH C80 2 LHI 080 1 LHR 240 1 LIS D10 2 LM C20 3 LPSW 4C0 2 MH 0C0 1 MHR DC0 2 MHU 9C0 1 MHUR 460 2 OH C60 2 OHI 060 1 OHR DE0 2 OC 9E0 1 OCR D70 2 RB 970 1 RBR DB0 2 RD 9B0 1 RDR D90 2 RH 990 1 RHR EB0 2 RLL EA0 2 RRL 670 2 RBL 660 2 RTL DD0 2 SS 9D0 1 SSR EF0 2 SLA ED0 2 SLL CF0 2 SLHA CD0 2 SLHL 910 1 SLLS EE0 2 SRA EC0 2 SRL CE0 2 SRHA CC0 2 SRHL 900 1 SRLS E20 3 SINT D20 2 STB 920 1 STBR 400 2 STH D00 2 STM 4B0 2 SH CB0 2 SHI 0B0 1 SHR 270 1 SIS 4F0 2 SCH 0F0 1 SCHR E10 2 SVC C30 2 THI D60 2 WB 960 1 WBR DA0 2 WD 9A0 1 WDR D80 2 WH 980 1 WHR 428 3 BC 028 4 BCR 208 5 BCBS 0 218 5 BCFS 208 218 5 BCS 438 5 BNC 038 4 BNCR 228 238 5 BNCS 433 3 BE 033 4 BER 223 5 BEBS 0 233 5 BEFS 223 233 5 BES 423 3 BNE 023 4 BNER 203 5 BNEBS 0 213 5 BNEFS 203 213 5 BNES 428 3 BL 028 4 BLR 208 5 BLBS 0 218 5 BLFS 208 218 5 BLS 438 3 BNL 038 4 BNLR 228 5 BNLBS 0 238 5 BNLFS 228 238 5 BNLS 421 3 BM 021 4 BMR 201 5 BMBS 0 211 5 BMFS 201 211 3 5 BMS 431 3 BNM 031 4 BNMR 221 5 BNMBS 0 231 5 BNMFS 221 231 5 BNMS 422 3 BP 022 4 BPR 202 5 BPBS 0 212 5 BPFS 202 212 5 BPS 432 3 BNP 032 4 BNPR 222 5 BNPBS 0 232 5 BNPFS 222 232 5 BNPS 424 3 BO 024 4 BOR 204 5 BOBS 0 214 5 BOFS 204 214 5 BOS 430 3 B 030 4 BR 220 5 BABS 0 230 5 BAFS 220 230 5 BS 433 3 BZ 033 4 BZR 223 5 BZBS 0 233 5 BZFS 223 233 5 BZS 423 3 BNZ 023 4 BNZR 203 5 BNZBS 0 213 5 BNZFS 203 213 5 BNZS 420 0 3 3 NOP 020 0 3 4 NOPR 0 1 4 0 END 0 2 4 1 DC 0 3 4 1 DS 0 4 4 1 EQU 0 5 4 1 ORG 0 6 4 0 EJECT 0 7 4 1 SPACE 0 8 4 0 TITLE 0 9 4 0 SUBTTL 0 A 4 0 OBJECT 0 B 4 0 SYMTAB 0 C 4 0 PACK 0 D 4 0 FIXFLD 0 E 4 0 LIST 0 F 4 1 DO 0 10 4 1 ENTRY 0 11 4 1 EXTRN 0 12 4 0 UPCASE 0 13 4 1 DB UPCASE 0 13 4 1 DB UPCASE 0 13 ); default: while( c= *p++ ){ if( (c=-'0') >= base) error('n'); num =* base; num =+ c; } } return(num); } /* * read string into b, return byte count */ readstr(b) char *b; { register c; register char *p; p=b; if( getnb() != '"' ){ error('s'); return(0); } instring++; for( ;; ){ switch( c=get1() ){ case EOL: error('s'); instring--; return(p-b); case '\\': *p++ = escape(); break; case '"': instring--; return(p-b); default: *p++ = c; break; } } } /* * evaluate register pair expression */ rpair() { conexp(6); return( eval = (eval>>1)&3 ); } /* * log fatal system error and exit */ syserr(s) char *s; { printf("assembler error: %s\n",s); exit(1); } if( getnb() != '"' ){ error('s'); return(0); } instring++; for( ;; ){ switch( c=get1() ){ case EOL: error('s'); instring--; return(p-b); case '\\': *p++ = escape(); break; case '"': instring--; return(p-b); default: *p++ 8 12 6 622. 439. -0.0773 494. 371. -0.0835 403. 459. -0.0754 526. 514. -0.0703 622. 571. -0.0852 494. 508. -0.0928 403. 590. -0.0829 526. 640. -0.0768 1 2 2 3 3 4 4 1 5 6 6 7 7 8 8 5 1 5 2 6 3 7 4 8 4 1 10 5 9 4 2 11 6 10 4 3 11 7 12 4 4 12 8 9 4 5 6 7 8 4 1 2 3 4 8 8 2 200. 200. -.1 400. 200. -.1 400. 400. -.1 200. 400. -.1 300. 300. -.2 500. 300. -.2 500. 500. -.2 300. 500. -.2 1 2 2 3 3 4 4 1 5 6 6 7 7 8 8 5 4 1 2 3 4 4 5 6 7 8 6 7 7 8 8 5 1 5 2 6 3 7 4 8 4 1 10 5 9 4 2 11 6 10 4 3 11 7 12 4 4 12 8 9 4 5 6 7 8 4 1 2 3 4 # /* * 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 'b': 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; eplflags&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; ep1lnum == -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 if(sflg) printf("%6dB", nblock(p->lsize0, p->lsize)); 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); } G)) == (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++ - *p# char *dargv[] { "/dev/rrp0", 0 }; #define NINODE 16*16 #include "/usr/sys/ino.h" #include "/usr/sys/filsys.h" struct filsys sblock; struct inode inode[NINODE]; int sflg; int aflg; #define NI 20 #define NDIRS 787 int ilist[NI] { -1}; int fi; struct htab { int hino; int hpino; char hname[14]; } htab[NDIRS]; int nhent 10; int (*pass[])() { pass1, pass2, pass3 }; char *lasts; int ino; int nerror; int nffil; int fout; int nfiles; struct dir { int ino; char name[14]; }; main(argc, argv) char **argv; { register char **p; register int n, *lp; nffil = dup(1); if (argc == 1) { for (p = dargv; *p;) check(*p++); return(nerror); } while (--argc) { argv++; if (**argv=='-') switch ((*argv)[1]) { case 's': sflg++; continue; case 'a': aflg++; continue; case 'i': lp = ilist; while (lp < &ilist[NI-1] && (n = number(argv[1]))) { *lp++ = n; argv++; argc--; } *lp++ = -1; continue; default: printf2("Bad flag\n"); } check(*argv); } return(nerror); } check(file) char *file; { register i, j, pno; fi = open(file, 0); if (fi < 0) { printf2("cannot open %s\n", file); return; } printf2("%s:\n", file); sync(); bread(1, &sblock, 512); nfiles = sblock.s_isize*16; for (i=0; ii_mode&IALLOC)==0 || (ip->i_mode&IFMT)!=IFDIR) return; lookup(ino, 1); } pass2(ip) struct inode *ip; { register doff; register struct htab *hp; register struct dir *dp; int i; if ((ip->i_mode&IALLOC)==0 || (ip->i_mode&IFMT)!=IFDIR) return; doff = 0; while (dp = dread(ip, doff)) { doff =+ 16; if (dp->ino==0) continue; if ((hp = lookup(dp->ino, 0)) == 0) continue; if (dotname(dp)) continue; hp->hpino = ino; for (i=0; i<14; i++) hp->hname[i] = dp->name[i]; } } pass3(ip) struct inode *ip; { register doff; register struct dir *dp; register int *ilp; if ((ip->i_mode&IALLOC)==0 || (ip->i_mode&IFMT)!=IFDIR) return; doff = 0; while (dp = dread(ip, doff)) { doff =+ 16; if (dp->ino==0) continue; if (aflg==0 && dotname(dp)) continue; for (ilp=ilist; *ilp >= 0; ilp++) if (*ilp == dp->ino) break; if (ilp > ilist && *ilp!=dp->ino) continue; printf("%d ", dp->ino); pname(ino, 0); printf("/%.14s\n", dp->name); } } dotname(adp) { register struct dir *dp; dp = adp; if (dp->name[0]=='.') if (dp->name[1]==0 || dp->name[1]=='.' && dp->name[2]==0) return(1); return(0); } pname(i, lev) { register struct htab *hp; if (i==1) return; if ((hp = lookup(i, 0)) == 0) { printf("???"); return; } if (lev > 10) { printf("..."); return; } pname(hp->hpino, ++lev); printf("/%.14s", hp->hname); } lookup(i, ef) { register struct htab *hp; for (hp = &htab[i%NDIRS]; hp->hino;) { if (hp->hino==i) return(hp); if (++hp >= &htab[NDIRS]) hp = htab; } if (ef==0) return(0); if (++nhent >= NDIRS) { printf2("Out of core-- increase NDIRS\n"); flush(); exit(1); } hp->hino = i; return(hp); } 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) { printf2("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) { printf2("read error %d\n", bno); exit(); } } bwrite(bno, buf) { seek(fi, bno, 3); if (write(fi, buf, 512) != 512) { printf2("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); } printf2(s, a1, a2) { extern fout; flush(); fout = 2; printf(s, a1, a2); fout = nffil; flush(); } bread(bno, buf, cnt) { seek(fi, bno, 3); if (read(fi, buf, cnt) != cnt) { printf2("read error %d\n", bno); exit(); } } bwrite(bno, buf) { seek(fi, bno, 3); if (write(fi, buf, 512) != 512) { printf2("write erro# /* * Editor */ #define SIGHUP 1 #define SIGINTR 2 #define SIGQUIT 3 #define FNSIZE 64 #define LBSIZE 512 #define ESIZE 128 #define GBSIZE 256 #define NBRA 5 #define EOF -1 #define CBRA 1 #define CCHR 2 #define CDOT 4 #define CCL 6 #define NCCL 8 #define CDOL 10 #define CEOF 11 #define CKET 12 #define STAR 01 #define error goto errlab #define READ 0 #define WRITE 1 int peekc; int lastc; char savedfile[FNSIZE]; char file[FNSIZE]; char linebuf[LBSIZE]; char rhsbuf[LBSIZE/2]; char expbuf[ESIZE+4]; int circfl; int *zero; int *dot; int *dol; int save_dot; /* flag--whether this command saves dot or not */ int brcount 1; /* number of lines to output on "newline" command */ int num; int *endcore; int *fendcore; int line_num; /* integer for line number on output */ char *fmtlno {" %6l="}; /* format for line-number output */ int *addr1; int *addr2; int *old_a1; /* previous address */ int *old_a2; /* " " */ char genbuf[LBSIZE]; int count[2]; char *e_prompt "*"; /* editor command prompt */ int prompt1 1; /* flag--enable or disable ALL prompting */ int prompt2 1; /*flag--enable or disable line-num prompts */ int text_was_modified 0; /* flag--on if text was modified */ int globf2 0; /* kludge for "-f" */ int num_reads 0; /* indicator to aid text_was_modified-- /* first read isn't really a modify */ char *nextip; char *linebp; int ninbuf; int io; int pflag; int eflg; /* echo input flag */ int fflg; /* "file" flag */ int sflg; /* "silent" flag -- no extra output */ int onhup; int onquit; int listf; int col; char *globp; int tfile -1; int tline; char *tfname; char *loc1; char *loc2; char *locs; char ibuff[512]; int iblock -1; char obuff[512]; int oblock -1; int ichanged; int nleft; int errfunc(); int *errlab errfunc; char TMPERR[] "TMP"; int names[26]; char *braslist[NBRA]; char *braelist[NBRA]; main(argc, argv) char **argv; { register char *p1, *p2; extern int onintr(); onquit = signal(SIGQUIT, 1); onhup = signal(SIGHUP, 1); printf("\nNed, v2.0\n"); while(argc-- > 1){ argv++; if(**argv == '-') switch((*argv)[1]){ case 'q': signal(SIGQUIT,0); break; case 'e': eflg++; break; case 's': sflg++; break; case 'f': fflg++; break; case 'n': prompt1 = 0; break; default: printf("bad flag: %s",*argv); exit(); } else { p1 = *argv; p2 = savedfile; while(*p2++ = *p1++) {} if(fflg) { globp = "a\n"; globf2 = 1; } else globp = "r"; } } fendcore = sbrk(0); init(); if ((signal(SIGINTR, 1) & 01) == 0) signal(SIGINTR, onintr); setexit(); do commands(); while(are_you_sure()); if(fflg){ globp = "w\n"; commands(); } unlink(tfname); } /*page */ commands() { int getfile(), gettty(); register *a1, c; register char *p; int r; for (;;) { if (pflag) { pflag = 0; addr1 = addr2 = dot; goto print; } if(!globp){ if(prompt2) puts2(e_prompt); old_a1 = addr1; old_a2 = addr2; } addr1 = 0; addr2 = 0; if((peekc = getchar()) == '='){ peekc = 0; addr1 = old_a1; addr2 = old_a2; if((c = peekc = getchar()) == '\n') c = 'p'; else peekc = 0; } else { r = 1; do { addr1 = addr2; if ((a1 = address())==0) { c = getchar(); break; } addr2 = a1; if ((c=getchar()) == ';') { c = ','; dot = a1; } } while (c==',' && r-- > 0); } if (addr1==0) addr1 = addr2; line_num = (addr1? addr1 : dot) - zero; /*page */ switch(c) { case 'a': setdot(); newline(); line_num++; r = append(gettty, addr2); text_was_modified =+ r; continue; case 'b': num = 0; while( '0' <= (c = getchar()) && c <= '9' ) num = num*10 + c-'0'; peekc = c; newline(); if(num > 0) brcount = num; else brcount =1; continue; case 'c': delete(); r = append(gettty, addr1-1); text_was_modified =+ r; continue; case 'd': delete(); text_was_modified = 1; continue; case 'e': if(fflg) errmsg(236,"can't change filename"); setnoaddr(); if ((peekc = getchar()) != ' ') errmsg(239,"illegal file name syntax"); /* if(text_was_modified && !are_you_sure()) /* error; */ savedfile[0] = 0; init(); addr2 = zero; text_was_modified = 0; num_reads = 0; goto caseread; case 'f': setnoaddr(); if ((c = getchar()) != '\n') { if(fflg) errmsg(254,"can't change file name"); peekc = c; savedfile[0] = 0; filename(); } puts(savedfile); continue; case 'g': global(1); continue; case 'i': setdot(); nonzero(); newline(); r = append(gettty, addr2-1); text_was_modified =+ r; continue; case 'k': if ((c = getchar()) < 'a' || c > 'z') errmsg(276,"syntax is K[a-z]"); newline(); setdot(); nonzero(); names[c-'a'] = *addr2 | 01; continue; case 'm': move(0); text_was_modified = 1; continue; case 'n': newline(); prompt1++; prompt1 =& 01; printf("%sline numbers\n",(prompt1? "" : "no ")); continue; case '\n': if (addr2==0) { addr2 = dot+1; line_num++; addr1 = addr2; if(brcount != 1) { addr2 = dot + brcount; if(addr2 > dol) addr2 = dol; if(addr2 < zero) addr2 = zero; } } goto print; case 'l': listf++; case 'p': save_dot = 0; if((c = getchar()) == 'p' || c == 'l') { save_dot = 1; addr1 = zero+1; addr2 = dol; } else peekc = c; newline(); print: setdot(); nonzero(); a1 = addr1; do { if(prompt1 && prompt2) { line_num = a1 - zero; printf(fmtlno,line_num); } puts(getline(*a1++)); } while (a1 <= addr2); if(!save_dot) dot = addr2; save_dot = 0; listf = 0; continue; case 'q': setnoaddr(); newline(); return; case 'r': caseread: filename(); if ((io = open(file, 0)) < 0) { lastc = '\n'; printf("can't read %s\n",file); error; } setall(); ninbuf = 0; r = append(getfile, addr2); printf("%l lines\n",r); exfile(); if(num_reads++) text_was_modified =+ r; else text_was_modified = 0; continue; case 's': setdot(); nonzero(); substitute(globp); text_was_modified = 1; continue; case 't': move(1); continue; case 'v': global(0); continue; case 'w': setall(); filename(); if ((io = creat(file, 0644)) < 0){ printf("can't create %s\n",file); error; } if(dol == zero){ printf("[nothing written]\n"); continue; } nonzero(); putfile(); exfile(); text_was_modified = 0; continue; case '!': unix(); continue; case EOF: return; } errmsg(396,"unrecognized command"); } } /*page */ address() { register *a1, minus, c; int n, relerr; minus = 0; a1 = 0; for (;;) { c = getchar(); if ('0'<=c && c<='9') { n = 0; do { n =* 10; n =+ c - '0'; } while ((c = getchar())>='0' && c<='9'); peekc = c; if (a1==0) a1 = zero; if (minus<0) n = -n; a1 =+ n; minus = 0; continue; } relerr = 0; if (a1 || minus) relerr++; switch(c) { case ' ': case '\t': continue; case '+': minus =+ brcount; if (a1==0) a1 = dot; continue; case '-': case '^': minus =- brcount; if (a1==0) a1 = dot; continue; case '?': case '/': compile(c); a1 = dot; for (;;) { if (c=='/') { a1++; if (a1 > dol) a1 = zero; } else { a1--; if (a1 < zero) a1 = dol; } if (execute(0, a1)) break; if (a1==dot) errmsg(462,"string not found"); } break; case '$': a1 = dol; break; case '.': a1 = dot; break; case '\'': if ((c = getchar()) < 'a' || c > 'z') errmsg(476," ' must be followed by [a-z]"); for (a1=zero; a1<=dol; a1++) if (names[c-'a'] == (*a1|01)) break; break; default: peekc = c; if (a1==0) return(0); a1 =+ minus; if(a1 < zero) a1 = zero; else if(a1 > dol) a1 = dol; return(a1); } if (relerr) errmsg(494,"\"relerror\" (?)"); } } setdot() { if (addr2 == 0) addr1 = addr2 = dot; if (addr1 > addr2) errmsg(503,"lower address bound > upper one"); } setall() { if (addr2==0) { addr1 = zero+1; addr2 = dol; if (dol==zero) addr1 = zero; } setdot(); } setnoaddr() { if (addr2) errmsg(520,"address illegal here"); } nonzero() { if(addr1 <= zero) errmsg(532,"non-existant line number"); if(addr2 > dol) errmsg(534,"bottom of file reached"); } newline() { register c; if ((c = getchar()) == '\n') return; if (c=='p' || c=='l') { pflag++; if (c=='l') listf++; if (getchar() == '\n') return; } errmsg(542,"command syntax error"); } filename() { register char *p1, *p2; register c; count[1] = 0; c = getchar(); if (c=='\n' || c==EOF) { p1 = savedfile; if (*p1==0) errmsg(555,"null file name illegal"); p2 = file; while (*p2++ = *p1++); return; } if (c!=' ') errmsg(561,"file name syntax"); while ((c = getchar()) == ' '); if (c=='\n') errmsg(564,"null file name illegal"); p1 = file; do { *p1++ = c; } while ((c = getchar()) != '\n'); *p1++ = 0; if (savedfile[0]==0) { p1 = savedfile; p2 = file; while (*p1++ = *p2++); } } exfile() { close(io); io = -1; } onintr() { signal(SIGINTR, onintr); putchar('\n'); lastc = '\n'; errmsg(588,"INTERUPT!"); } errfunc() { register c; listf = 0; /* puts("?"); */ count[0] = 0; seek(0, 0, 2); pflag = 0; if (globp) lastc = '\n'; globp = 0; peekc = lastc; while ((c = getchar()) != '\n' && c != EOF); if (io > 0) { close(io); io = -1; } reset(); } getchar() { if (lastc=peekc) { peekc = 0; return(lastc); } if (globp) { if ((lastc = *globp++) != 0) return(lastc); globp = 0; if(globf2 == 0) return(EOF); globf2 = 0; } if (read(0, &lastc, 1) <= 0) return(lastc = EOF); lastc =& 0177; return(echo(lastc)); } echo(ch) { if(eflg) putchar(ch); return(ch); } gettty() { register c, gf; register char *p; p = linebuf; gf = globp; if(prompt1 && prompt2) { printf(fmtlno,line_num++); flush_buf(); } while ((c = getchar()) != '\n') { if (c==EOF) { if (gf) peekc = c; return(c); } if ((c =& 0177) == 0) continue; *p++ = c; if (p >= &linebuf[LBSIZE-2]) errmsg(660,"input line too long"); } *p++ = 0; if (linebuf[0]=='.' && linebuf[1]==0) return(EOF); return(0); } getfile() { register c; register char *lp, *fp; lp = linebuf; fp = nextip; do { if (--ninbuf < 0) { if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0) return(EOF); fp = genbuf; } if (lp >= &linebuf[LBSIZE]) errmsg(682,"line in file too long"); /* ( 512 chars) */ if ((*lp++ = c = *fp++ & 0177) == 0) { lp--; continue; } if (++count[1] == 0) ++count[0]; } while (c != '\n'); *--lp = 0; nextip = fp; return(0); } putfile() { int *a1; register char *fp, *lp; register nib; nib = 512; fp = genbuf; a1 = addr1; do { lp = getline(*a1++); for (;;) { if (--nib < 0) { write(io, genbuf, fp-genbuf); nib = 511; fp = genbuf; } if (++count[1] == 0) ++count[0]; if ((*fp++ = *lp++) == 0) { fp[-1] = '\n'; break; } } } while (a1 <= addr2); write(io, genbuf, fp-genbuf); } append(f, a) int (*f)(); { register *a1, *a2, *rdot; int nline, tl; struct { int integer; }; nline = 0; dot = a; while ((*f)() == 0) { if (dol >= endcore) { if (sbrk(1024) == -1) errmsg(743,"file overflows available memory"); endcore.integer =+ 1024; } tl = putline(); nline++; a1 = ++dol; a2 = a1+1; rdot = ++dot; while (a1 > rdot) *--a2 = *--a1; *rdot = tl; } return(nline); } unix() { register savint, pid, rpid; int retcode; setnoaddr(); if ((pid = fork()) == 0) { signal(SIGHUP, onhup); signal(SIGQUIT, onquit); execl("/bin/sh", "sh", "-t", 0); exit(); } savint = signal(SIGINTR, 1); while ((rpid = wait(&retcode)) != pid && rpid != -1); signal(SIGINTR, savint); puts("!"); } delete() { register *a1, *a2, *a3; setdot(); newline(); nonzero(); a1 = addr1; a2 = addr2+1; a3 = dol; dol =- a2 - a1; do *a1++ = *a2++; while (a2 <= a3); a1 = addr1; if (a1 > dol) a1 = dol; dot = a1; } getline(tl) { register char *bp, *lp; register nl; lp = linebuf; bp = getblock(tl, READ); nl = nleft; tl =& ~0377; while (*lp++ = *bp++) if (--nl == 0) { bp = getblock(tl=+0400, READ); nl = nleft; } return(linebuf); } putline() { register char *bp, *lp; register nl; int tl; lp = linebuf; tl = tline; bp = getblock(tl, WRITE); nl = nleft; tl =& ~0377; while (*bp = *lp++) { if (*bp++ == '\n') { *--bp = 0; linebp = lp; break; } if (--nl == 0) { bp = getblock(tl=+0400, WRITE); nl = nleft; } } nl = tline; tline =+ (((lp-linebuf)+03)>>1)&077776; return(nl); } getblock(atl, iof) { extern read(), write(); register bno, off; bno = (atl>>8)&0377; off = (atl<<1)&0774; if (bno >= 255) { /* puts(TMPERR); */ errmsg(841,"file too large (TMPERR)"); } nleft = 512 - off; if (bno==iblock) { ichanged =| iof; return(ibuff+off); } if (bno==oblock) return(obuff+off); if (iof==READ) { if (ichanged) blkio(iblock, ibuff, write); ichanged = 0; iblock = bno; blkio(bno, ibuff, read); return(ibuff+off); } if (oblock>=0) blkio(oblock, obuff, write); oblock = bno; return(obuff+off); } blkio(b, buf, iofcn) int (*iofcn)(); { seek(tfile, b, 3); if ((*iofcn)(tfile, buf, 512) != 512) { /* puts(TMPERR); */ errmsg(870,"I/O error on temp file"); } } init() { register char *p; register pid; close(tfile); tline = 0; iblock = -1; oblock = -1; tfname = "/tmp/exxxxx"; ichanged = 0; pid = getpid(); for (p = &tfname[11]; p > &tfname[6];) { *--p = (pid&07) + '0'; pid =>> 3; } close(creat(tfname, 0600)); tfile = open(tfname, 2); brk(fendcore); dot = zero = dol = fendcore; endcore = fendcore - 2; } global(k) { register char *gp; register c; register int *a1; char globuf[GBSIZE]; if (globp) errmsg(905,"recursive global command"); setall(); nonzero(); if ((c=getchar())=='\n') errmsg(909,"missing global pattern"); compile(c); gp = globuf; while ((c = getchar()) != '\n') { if (c==EOF) errmsg(914,"missing global commands"); if (c=='\\') { c = getchar(); if (c!='\n') *gp++ = '\\'; } *gp++ = c; if (gp >= &globuf[GBSIZE-2]) errmsg(922,"global command list too long"); } *gp++ = '\n'; *gp++ = 0; for (a1=zero; a1<=dol; a1++) { *a1 =& ~01; if (a1>=addr1 && a1<=addr2 && execute(0, a1)==k) *a1 =| 01; } for (a1=zero; a1<=dol; a1++) { if (*a1 & 01) { *a1 =& ~01; dot = a1; globp = globuf; commands(); a1 = zero; } } } substitute(inglob) { register gsubf, *a1, nl; int getsub(); gsubf = compsub(); /* 0 or 1 depending on 'g' */ for (a1 = addr1; a1 <= addr2; a1++) { if (execute(0, a1)==0) continue; inglob =| 01; dosub(); if (gsubf) { while (*loc2) { if (execute(1)==0) break; dosub(); } } *a1 = putline(); nl = append(getsub, a1); a1 =+ nl; addr2 =+ nl; } if (inglob==0) errmsg(974,"substitute pattern not found"); } compsub() { register seof, c; register char *p; int gsubf; if ((seof = getchar()) == '\n') errmsg(976,"missing sub string"); compile(seof); p = rhsbuf; for (;;) { c = getchar(); if (c=='\\') c = getchar() | 0200; if (c=='\n') errmsg(984,"missing string terminator"); if (c==seof) break; *p++ = c; if (p >= &rhsbuf[LBSIZE/2]) errmsg(989,"string2 too long"); } *p++ = 0; if ((peekc = getchar()) == 'g') { /* if in 'glob' */ peekc = 0; newline(); return(1); } newline(); return(0); } getsub() { register char *p1, *p2; p1 = linebuf; if ((p2 = linebp) == 0) return(EOF); while (*p1++ = *p2++); linebp = 0; return(0); } dosub() { register char *lp, *sp, *rp; int c; lp = linebuf; sp = genbuf; rp = rhsbuf; while (lp < loc1) *sp++ = *lp++; while (c = *rp++) { if (c=='&') { sp = place(sp, loc1, loc2); continue; } else if (c<0 && (c =& 0177) >='1' && c < NBRA+'1') { sp = place(sp, braslist[c-'1'], braelist[c-'1']); continue; } *sp++ = c&0177; if (sp >= &genbuf[LBSIZE]) errmsg(1033,"sub string too long"); } lp = loc2; loc2 = sp + linebuf - genbuf; while (*sp++ = *lp++) if (sp >= &genbuf[LBSIZE]) errmsg(1039,"substituted string too big"); lp = linebuf; sp = genbuf; while (*lp++ = *sp++); } place(asp, al1, al2) { register char *sp, *l1, *l2; sp = asp; l1 = al1; l2 = al2; while (l1 < l2) { *sp++ = *l1++; if (sp >= &genbuf[LBSIZE]) errmsg(1055,"sub string too long"); } return(sp); } move(cflag) { register int *adt, *ad1, *ad2; int getcopy(); setdot(); nonzero(); if ((adt = address())==0) errmsg(1068,"missing move destination address"); newline(); ad1 = addr1; ad2 = addr2; if (cflag) { ad1 = dol; append(getcopy, ad1++); ad2 = dol; } ad2++; if (adt= ad2) { dot = adt++; reverse(ad1, ad2); reverse(ad2, adt); reverse(ad1, adt); } else errmsg(1091,"move destination not found"); } reverse(aa1, aa2) { register int *a1, *a2, t; a1 = aa1; a2 = aa2; for (;;) { t = *--a2; if (a2 <= a1) return; *a2 = *a1; *a1++ = t; } } getcopy() { if (addr1 > addr2) return(EOF); getline(*addr1++); return(0); } compile(aeof) { register eof, c; register char *ep; char *lastep; char bracket[NBRA], *bracketp; int nbra; int cclcnt; ep = expbuf; eof = aeof; bracketp = bracket; nbra = 0; if ((c = getchar()) == eof) { if (*ep==0) errmsg(1132,"null string illegal"); return; } circfl = 0; if (c=='^') { c = getchar(); circfl++; } if (c=='*') { /* if first = *, then quote it */ *ep++ = CCHR; *ep++ = c; c = 0; } peekc = c; for (;;) { if (ep >= &expbuf[ESIZE]) goto cerror; c = getchar(); if (c==eof) { *ep++ = CEOF; return; } if (c!='*') lastep = ep; switch (c) { case '\\': if ((c = getchar())=='(') { if (nbra >= NBRA){ printf("too many \("); goto cerror; } *bracketp++ = nbra; *ep++ = CBRA; *ep++ = nbra++; continue; } if (c == ')') { if (bracketp <= bracket){ printf("unbalanced ("); goto cerror; } *ep++ = CKET; *ep++ = *--bracketp; continue; } *ep++ = CCHR; if (c=='\n'){ printf("\\n illegal in pattern"); goto cerror; } *ep++ = c; continue; case '.': *ep++ = CDOT; continue; case '\n': printf("missing string terminator"); goto cerror; case '*': if (*lastep==CBRA || *lastep==CKET){ printf("illegal use of *"); goto cerror; } *lastep =| STAR; continue; case '$': if ((peekc=getchar()) != eof) goto defchar; *ep++ = CDOL; continue; case '[': *ep++ = CCL; *ep++ = 0; cclcnt = 1; if ((c=getchar()) == '^') { c = getchar(); ep[-2] = NCCL; } do { if (c=='\n'){ printf("missing ]"); goto cerror; } *ep++ = c; cclcnt++; if (ep >= &expbuf[ESIZE]){ printf("pattern too complicated"); goto cerror; } } while ((c = getchar()) != ']'); lastep[1] = cclcnt; continue; defchar: default: *ep++ = CCHR; *ep++ = c; } } cerror: expbuf[0] = 0; putchar('\n'); error; } execute(gf, addr) int *addr; { register char *p1, *p2, c; if (gf) { if (circfl) return(0); p1 = linebuf; p2 = genbuf; while (*p1++ = *p2++); locs = p1 = loc2; } else { if (addr==zero) return(0); p1 = getline(*addr); locs = 0; } p2 = expbuf; if (circfl) { loc1 = p1; return(advance(p1, p2)); } /* fast check for first character */ if (*p2==CCHR) { c = p2[1]; do { if (*p1!=c) continue; if (advance(p1, p2)) { loc1 = p1; return(1); } } while (*p1++); return(0); } /* regular algorithm */ do { if (advance(p1, p2)) { loc1 = p1; return(1); } } while (*p1++); return(0); } 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: loc2 = lp; 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 CBRA: braslist[*ep++] = lp; continue; case CKET: braelist[*ep++] = lp; continue; 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 (lp==locs) break; if (advance(lp, ep)) return(1); } while (lp > curlp); return(0); default: errmsg(1376,"\"advance\" error (?)"); } } 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); } char line[70]; char *linp line; flush_buf() { if(linp>line) { write(1,line,linp-line); linp = line; } } puts2(as) { register char *sp; sp = as; while (*sp) putchar(*sp++); if(linp>line) { write(1,line,linp-line); linp=line; } } puts(as) { register char *sp; sp=as; col=0; while(*sp) putchar(*sp++); putchar('\n'); } putchar(ac) { register char *lp; register c; lp = linp; c = ac; if (listf) { col++; if (col >= 72) { col = 0; *lp++ = '\\'; *lp++ = '\n'; } if (c=='\t') { c = '>'; goto esc; } if (c=='\b') { c = '<'; esc: *lp++ = '-'; *lp++ = '\b'; *lp++ = c; goto out; } if (c<' ' && c!= '\n') { *lp++ = '\\'; *lp++ = (c>>3)+'0'; *lp++ = (c&07)+'0'; col =+ 2; goto out; } } *lp++ = c; out: if(c == '\n' || lp >= &line[64]) { linp = line; write(1, line, lp-line); return; } linp = lp; } are_you_sure() { register int c,n; if(!text_was_modified || fflg) return(0); while(1) { printf("\ndid you forget to save your text? "); for(n=0; n<5; n++) { flush_buf(); if((c=getchar())<=0) return(0); if(c != '\n') skip_rest(); switch(c) { case 'y': return(1); case 'n': return(0); } printf("yes or no? "); } } } skip_rest() { register int c; while((c=getchar())>0 && c != '\n') {} } errmsg(n,s) char *s; { printf("%4d: %s\n",n,s); goto errlab; } lp; } are_you_sure() { register int c,n; if(!text_was_modified || fflg) return(0); while(1) { printf("\ndid you forget to save your text? "); for(n=0; n<5; n++) { flush_buf(); if((c=getchar())<=0) return(0); if(c != '\n') skip_rest(); switch(c) { case 'y': return(1); case 'n': return(0); } printf("yes or no? "); } } } skip_rest() { register int c; while((c=getchar())>0 && c != '\n') {} } errmsg(n# /* * ps - process status * examine and print certain things about processes */ #include "/usr/sys/param.h" #include "/usr/sys/proc.h" #include "/usr/sys/tty.h" #include "/usr/sys/user.h" #define dh11 (4<<8) /* dh11 major device number part */ #define swapdev "/dev/rp0" /* name of swap device */ #define addr50 050 /* address of "_proc" in system */ struct { char name[8]; int type; char *value; } nl[3]; struct proc proc[NPROC]; struct tty tty; struct user u; int lflg; int kflg; int xflg; int tflg; int aflg; int mem; int swap; int *proc_addr; int stbuf[257]; /* tty file characters and their minor-device numbers */ int ndev 9; /* number of ttys */ char devc[65] {'8','0','1','2','3','4','5','6','7' }; int devl[65] {0,dh11+0,dh11+1,dh11+2,dh11+3,dh11+4,dh11+5,dh11+6,dh11+7 }; int devt[65]; char *coref; struct ibuf { char idevmin, idevmaj; int inum; int iflags; char inl; char iuid; char igid; char isize0; int isize; int iaddr[8]; char *ictime[2]; char *imtime[2]; int fill; }; int obuf[259]; main(argc, argv) char **argv; { struct proc *p; int n, b; int i, c, mtty; char *ap; int uid, puid; obuf[0] = 1; if (argc>1) { ap = argv[1]; while (*ap) switch (*ap++) { case 'a': aflg++; break; case 't': tflg++; break; case 'x': xflg++; break; case 'l': lflg++; break; } } coref = "/dev/mem"; if ((mem = open(coref, 0)) < 0) { printf("\n can't open mem-file: %s \n",coref); done(); } seek(mem, addr50,0); read(mem,&proc_addr,2); seek(mem, proc_addr, 0); read(mem, proc, sizeof proc); swap = open(swapdev,0); if(swap < 0) { printf("\n error -- can't open swap device: %s\n",swapdev); done(); } uid = getuid() & 0377; if(lflg) printf("TTY F S UID PID PRI ADDR SZ WCHAN COMMAND\n"); else printf("TTY PID COMMAND\n"); for (i=0; i>3); if (proc[i].p_wchan) printf("%7o", proc[i].p_wchan); else printf(" "); } if (proc[i].p_stat==5) printf(" "); else prcom(i); printf("\n"); } done(); } prcom(i) { int baddr, laddr, mf; register int *ip; register char *cp, *cp1; int c, nbad; baddr = 0; laddr = 0; if(proc[i].p_pid == 0){ printf(" sched()"); return(1); } if (proc[i].p_flag&SLOAD) { laddr = proc[i].p_addr; mf = mem; } else { baddr = proc[i].p_addr; mf = swap; } laddr =+ proc[i].p_size - 8; baddr =+ laddr>>3; laddr = (laddr&07)<<6; seek(mf, baddr, 3); seek(mf, laddr, 1); if (read(mf, stbuf, 512) != 512) return(0); for (ip = &stbuf[256]; ip > &stbuf[0];) { if (*--ip == -1) { cp = ip+1; if (*cp==0) cp++; nbad = 0; for (cp1 = cp; cp1 < &stbuf[256]; cp1++) { c = *cp1; if (c==0) *cp1 = ' '; else if (c < ' ' || c > 0176) { if (++nbad >= 5) { *cp1++ = ' '; break; } *cp1 = '?'; } } while (*--cp1==' ') *cp1 = 0; printf(lflg?" %.16s":" %.64s", cp); return(1); } } return(0); } done() { fflush(obuf); exit(); } putchar(c) { putc(c, obuf); } (ip = &stbuf[256]; ip > &stbuf[0];) { if (*--ip == -1) { cp = ip+1; if (*cp==0) cp++; nbad = 0; for (cp1 = cp; cp1 < &stbuf[256]; cp1++) { c = *cp1; if (c==0) *cp1 = ' '; else if (c < ' ' || c > 0176) { if (++nbad >= 5) { *cp1++ = ' '; break; } *cp1 = '?'; # /* */ #define INTR 2 #define QUIT 3 #define LINSIZ 1000 #define ARGSIZ 50 #define TRESIZ 100 #define QUOTE 0200 #define FAND 1 #define FCAT 2 #define FPIN 4 #define FPOU 8 #define FPAR 16 #define FINT 32 #define FPRS 64 #define TCOM 1 #define TPAR 2 #define TFIL 3 #define TLST 4 #define DTYP 0 #define DLEF 1 #define DRIT 2 #define DFLG 3 #define DSPR 4 #define DCOM 5 #define ENOMEM 12 #define ENOEXEC 8 int kids[64]; /* hashed table of known kids */ int numkids 0; /* number of known, live children */ char *dolp; char pidp[6]; int ldivr; char **dolv; int dolc; char *promp; char *linep; char *elinep; char **argp; char **eargp; int *treep; int *treeend; char peekc; char gflg; char eflg 0; /* echo flag */ char statf 0; /* trace job status' */ char error; char acctf; char uid; char setintr; char *arginp; int onelflg; char *mesg[] { "Ok\n", "Hangup", "interrupt\n", "Quit", "Illegal instruction", "Trace/BPT trap", "IOT trap", "EMT trap", "Floating exception", "Killed", "Bus error", "Memory fault", "Bad system call", 0, "Sig 14", "Sig 15", "Sig 16", "Sig 17", "Sig 18", "Sig 19", }; struct stime { int proct[2]; int cputim[2]; int systim[2]; } timeb; char line[LINSIZ]; char *args[ARGSIZ]; int trebuf[TRESIZ]; main(c, av) int c; char **av; { register f; register char *acname, **v; for(f=2; f<15; f++) close(f); if((f=dup(1)) != 2) close(f); dolc = getpid(); for(f=4; f>=0; f--) { dolc = ldiv(0, dolc, 10); pidp[f] = ldivr+'0'; } v = av; acname = "/usr/adm/sha"; promp = "% "; if(((uid = getuid())&0377) == 0) promp = "# "; acctf = open(acname, 1); loop: if(c > 1) { if(v[1][0] == '-'){ switch(v[1][1]) { case 'e': eflg = 1; advance: for(f=2; f 2) { arginp = v[2]; promp = 0; break; } default: err("bad flag"); exit(1); } } else { close(0); if(open(v[1],0) != 0) { prs(v[1]); err(": cannot open"); exit(2); } if(!eflg) promp = 0; goto out; } } out: if(**v == '-') { setintr++; signal(QUIT, 1); signal(INTR, 1); } dolv = v+1; dolc = c-1; while(1) { if(promp != 0) prs(promp); peekc = getc(); main1(); } } main1() { register char c, *cp; register *t; argp = args; eargp = args+ARGSIZ-5; linep = line; elinep = line+LINSIZ-5; error = 0; gflg = 0; do { cp = linep; word(); } while(*cp != '\n'); treep = trebuf; treeend = &trebuf[TRESIZ]; if(gflg == 0) { if(error == 0) { setexit(); if (error) return; t = syntax(args, argp); } if(error != 0) err("syntax error"); else execute(t); } } word() { register char c, c1; *argp++ = linep; loop: switch(c = getc()) { case ' ': case '\t': goto loop; case '\'': case '"': c1 = c; while((c=readc()) != c1) { if(c == '\n') { error++; peekc = c; return; } *linep++ = c|QUOTE; } goto pack; case '&': case ';': case '<': case '>': case '(': case ')': case '|': case '^': case '\n': *linep++ = c; *linep++ = '\0'; return; } peekc = c; pack: for(;;) { c = getc(); if(any(c, " '\"\t;&<>()|^\n")) { peekc = c; if(any(c, "\"'")) goto loop; *linep++ = '\0'; return; } *linep++ = c; } } tree(n) int n; { register *t; t = treep; treep =+ n; if (treep>treeend) { prs("Command line overflow\n"); error++; reset(); } return(t); } getc() { register char c; if(peekc) { c = peekc; peekc = 0; return(c); } if(argp > eargp) { argp =- 10; while((c=getc()) != '\n'); argp =+ 10; err("Too many args"); gflg++; return(c); } if(linep > elinep) { linep =- 10; while((c=getc()) != '\n'); linep =+ 10; err("Too many characters"); gflg++; return(c); } getd: if(dolp) { c = *dolp++; if(c != '\0') return(c); dolp = 0; } c = readc(); if(c == '\\') { c = readc(); if(c == '\n') return(' '); return(c|QUOTE); } if(c == '$') { c = readc(); if(c>='0' && c<='9') { if(c-'0' < dolc) dolp = dolv[c-'0']; goto getd; } if(c == '$') { dolp = pidp; goto getd; } /* if $ not followed by legal char, quote it */ peekc = c; return('$' | QUOTE); } return(c&0177); } readc() { char cc; register c; if (arginp) { if (arginp == 1) exit(); if ((c = *arginp++) == 0) { arginp = 1; c = '\n'; } return(c); } if (onelflg==1) exit(); if(read(0, &cc, 1) != 1) exit(); if (cc=='\n' && onelflg) onelflg--; keepc(cc); return(cc); } char input_chars[102]; char *lppl input_chars; keepc(c) char c; { if(!eflg || (lppl > &input_chars[99] && c != '\n' ) ) return; *lppl++ = c; *lppl = 0; if(c == '\n') { p_time(); prs(input_chars); lppl = &input_chars[0]; } } p_time() {} /* * syntax * empty * syn1 */ syntax(p1, p2) char **p1, **p2; { while(p1 != p2) { if(any(**p1, ";&\n")) p1++; else return(syn1(p1, p2)); } return(0); } /* * syn1 * syn2 * syn2 & syntax * syn2 ; syntax */ syn1(p1, p2) char **p1, **p2; { register char **p; register *t, *t1; int l; l = 0; for(p=p1; p!=p2; p++) switch(**p) { case '(': l++; continue; case ')': l--; if(l < 0) error++; continue; case '&': case ';': case '\n': if(l == 0) { l = **p; t = tree(4); t[DTYP] = TLST; t[DLEF] = syn2(p1, p); t[DFLG] = 0; if(l == '&') { t1 = t[DLEF]; t1[DFLG] =| FAND|FPRS|FINT; } t[DRIT] = syntax(p+1, p2); return(t); } } if(l == 0) return(syn2(p1, p2)); error++; } /* * syn2 * syn3 * syn3 | syn2 */ syn2(p1, p2) char **p1, **p2; { register char **p; register int l, *t; l = 0; for(p=p1; p!=p2; p++) switch(**p) { case '(': l++; continue; case ')': l--; continue; case '|': case '^': if(l == 0) { t = tree(4); t[DTYP] = TFIL; t[DLEF] = syn3(p1, p); t[DRIT] = syn2(p+1, p2); t[DFLG] = 0; return(t); } } return(syn3(p1, p2)); } /* * syn3 * ( syn1 ) [ < in ] [ > out ] * word word* [ < in ] [ > out ] */ syn3(p1, p2) char **p1, **p2; { register char **p; char **lp, **rp; register *t; int n, l, i, o, c, flg; flg = 0; if(**p2 == ')') flg =| FPAR; lp = 0; rp = 0; i = 0; o = 0; n = 0; l = 0; for(p=p1; p!=p2; p++) switch(c = **p) { case '(': if(l == 0) { if(lp != 0) error++; lp = p+1; } l++; continue; case ')': l--; if(l == 0) rp = p; continue; case '>': p++; if(p!=p2 && **p=='>') flg =| FCAT; else p--; case '<': if(l == 0) { p++; if(p == p2) { error++; p--; } if(any(**p, "<>(")) error++; if(c == '<') { if(i != 0) error++; i = *p; continue; } if(o != 0) error++; o = *p; } continue; default: if(l == 0) p1[n++] = *p; } if(lp != 0) { if(n != 0) error++; t = tree(5); t[DTYP] = TPAR; t[DSPR] = syn1(lp, rp); goto out; } if(n == 0) error++; p1[n++] = 0; t = tree(n+5); t[DTYP] = TCOM; for(l=0; l= 0) { seek(i, 0, 2); goto f1; } } i = creat(t[DRIT], 0644); if(i < 0) { prs(t[DRIT]); err(": cannot create"); exit(); } f1: close(1); dup(i); close(i); } if((f&FPIN) != 0) { close(0); dup(pf1[0]); close(pf1[0]); close(pf1[1]); } if((f&FPOU) != 0) { close(1); dup(pf2[1]); close(pf2[0]); close(pf2[1]); } if((f&FINT)!=0 && t[DLEF]==0 && (f&FPIN)==0) { close(0); open("/dev/null", 0); } if((f&FINT) == 0 && setintr) { signal(INTR, 0); signal(QUIT, 0); } if(t[DTYP] == TPAR) { if(t1 = t[DSPR]) t1[DFLG] =| f&FINT; execute(t1); exit(); } close(acctf); gflg = 0; scan(t, &tglob); if(gflg) { t[DSPR] = "/etc/glob"; execv(t[DSPR], t+DSPR); prs("glob: cannot execute\n"); exit(); } scan(t, &trim); *linep = 0; texec(t[DCOM], t); cp1 = linep; cp2 = "/usr/bin/"; while(*cp1 = *cp2++) cp1++; cp2 = t[DCOM]; while(*cp1++ = *cp2++); texec(linep+4, t); texec(linep, t); prs(t[DCOM]); err(": not found"); exit(); case TFIL: f = t[DFLG]; pipe(pv); t1 = t[DLEF]; t1[DFLG] =| FPOU | (f&(FPIN|FINT|FPRS)); execute(t1, pf1, pv); t1 = t[DRIT]; t1[DFLG] =| FPIN | (f&(FPOU|FINT|FAND|FPRS)); execute(t1, pv, pf2); return; case TLST: f = t[DFLG]&FINT; if(t1 = t[DLEF]) t1[DFLG] =| f; execute(t1); if(t1 = t[DRIT]) t1[DFLG] =| f; execute(t1); return; } } texec(f, at) int *at; { extern errno; register int *t; t = at; execv(f, t+DCOM); if (errno==ENOEXEC) { if (*linep) t[DCOM] = linep; t[DSPR] = "/bin/sh"; execv(t[DSPR], t+DSPR); prs("No shell!\n"); exit(); } if (errno==ENOMEM) { prs(t[DCOM]); err(": too large"); exit(); } } err(s) char *s; { prs(s); prs("\n"); seek(0, 0, 2); } prs(as) char *as; { register char *s; s = as; while(*s) putc(*s++); } putc(c) { write(2, &c, 1); } prn(n) int n; { register a; if(a=ldiv(0,n,10)) prn(a); putc(lrem(0,n,10)+'0'); } any(c, as) int c; char *as; { register char *s; s = as; while(*s) if(*s++ == c) return(1); return(0); } equal(as1, as2) char *as1, *as2; { register char *s1, *s2; s1 = as1; s2 = as2; while(*s1++ == *s2) if(*s2++ == '\0') return(1); return(0); } pwait(i, t) int i, *t; { register p, e; int s; if(i != 0) for(;;) { times(&timeb); time(timeb.proct); p = wait(&s); deadkid(p); if(p == -1) break; e = s&0177; if(mesg[e] != 0 && ( e != 0 || p != i)) { if(p != i) { prn(p); prs(": "); } prs(mesg[e]); if(s&0200) prs(" -- Core dumped"); } if(statf) printf("PID %d: E%o, S%o\n",p,s&0377,(s>>8)&0377); /* if(s != 0) err(""); */ if(i == p) { acct(t); break; } else acct(0); } } deadkid(pid) { register int p,pp,*k; if(pid <= 0) return; numkids--; pp = pid; p = pp&077; if(kids[p] == pp) { kids[p] = 0; return; } else { for(k = &kids[p+1]; k < &kids[64]; k++) { if(*k == pp){ *k = 0; return; } } for(k = &kids; k < &kids[p]; k++) { if(*k == pp) { *k = 0; return; } } } numkids++; /* didn't delete one like we thought we would */ } newkid(pid) { register int p,i,*k; numkids++; p = pid&077; if(kids[p] == 0) { kids[p] = pid; return(0); } else { for(k = &kids[p+1]; k < &kids[64]; k++) if(*k == 0) { *k = pid; return(0); } for(k = &kids[0]; k < kids[p]; k++) if(*k == 0) { *k = pid; return(0); } i = kids[p]; kids[p] = pid; numkids--; /* didn't add one after all... */ return(i); } } acct(t) int *t; { if(t == 0) enacct("**gok"); else if(*t == TPAR) enacct("()"); else enacct(t[DCOM]); } enacct(as) char *as; { struct stime timbuf; struct { char cname[14]; char shf; char uid; int datet[2]; int realt[2]; int bcput[2]; int bsyst[2]; } tbuf; register i; register char *np, *s; s = as; times(&timbuf); time(timbuf.proct); lsub(tbuf.realt, timbuf.proct, timeb.proct); lsub(tbuf.bcput, timbuf.cputim, timeb.cputim); lsub(tbuf.bsyst, timbuf.systim, timeb.systim); do { np = s; while (*s != '\0' && *s != '/') s++; } while (*s++ != '\0'); for (i=0; i<14; i++) { tbuf.cname[i] = *np; if (*np) np++; } tbuf.datet[0] = timbuf.proct[0]; tbuf.datet[1] = timbuf.proct[1]; tbuf.uid = uid; tbuf.shf = 0; if (promp==0) tbuf.shf = 1; seek(acctf, 0, 2); write(acctf, &tbuf, sizeof(tbuf)); } mbuf); time(timbuf.proct); lsub(tbuf.realt, timbuf.proct, timeb.proct); lsub(tbuf.bcput, timbuf.cputim, timeb.cputim); lsub(tbuf.bsy/* * who */ int fout; int buf[256]; main(argc, argv) char **argv; { char *s, *cbuf; int n, fi, i, seeker; int tty; struct { char name[8]; char tty; char pad1; int time[2]; char pad2[2]; } *p; s = "/etc/utmp"; seeker = 0; if(argc == 2) { s = argv[1]; if(s[0] == '-' && (s[1] == 'h' || s[1] == 'r')) { seeker = (s[1] == 'r'? 1 : 0); s = "/usr/adm/wtmp"; } } fi = open(s, 0); if(fi < 0) { printf("cannot open history file"); exit(); } if (seeker) if(seek(fi,-02000,2)<0) printf("cannot seek on %s\n",s); fout = dup(1); close(1); if (argc==3) tty = ttyn(0); loop: n = read(fi, buf, 512); if(n == 0) { flush(); if (argc==3) write(fout, "Nobody.\n", 8); exit(); } p = &buf; for(p = &buf; (n =- 16)>=0; p++) { if (argc==3 && tty!=p->tty) continue; if(p->name[0] == '\0' && argc==1) continue; if(p->tty > '{') { switch(p->tty) { case '~': printf("system boot"); break; case '|': printf("old sys date"); break; case '}': printf("new sys date"); } } else { for(i=0; i<8; i++) { if(p->name[i] == '\0') p->name[i] = ' '; putchar(p->name[i]); } for(i=0; i<3; i++) putchar("tty"[i]); putchar(p->tty); } cbuf = ctime(p->time); for(i=3; i<16; i++) putchar(cbuf[i]); putchar('\n'); if (argc==3) { flush(); exit(); } } goto loop; } continue; if(p->tty > '{') { switch(p->tty) { case '~': printf("system boot"); break; case '|': printf("old sys date"); break; case '}': printf("new sys:@q}@@@RRp `   ` P q  q Har Ia{g|gC }gD E !!Y~g!Ba9C`@r&!!|AOG`]HG l1abp]iG0Y@aaJaz~g! !!9b1k9as1lg B!a!!OQ i !!aOQ W9!9`Q!`O!Q! h Oq9B9y91aq h a a  `ya `!OQ `ya!r͑waya!a1" b b bh  !!#&*.47>AD {;O`P FPOPGPWPG;P.F;FP`Ox;GwP F;;b;H:y"z"g#O`{" {bPx`g;ybB;zbB; ;H|zgg;g;;{OlBp;{2z2zbRz"y2R:go;9&9O`P H:g"  @q9 O9OJ`;*;go;J F; "P`Op:Q;;bƒ*;gJ o;O`Px}<g c " 02K`W;L`W;M`W;" 922# {;32#gPSPP0P`QxPhP A3F;)#Oh {;9)3#F;BD#O`E#Dsw EOEOEEE3EcPx3DkP H:*O`?O`V#VcPxMFVV3IO`VsF3Fm#W W3mcOemcm#OWBn3`n#Wz#B zcB oW@}#{ c  0O`#g#  3˜3  0# hc+OS#ww 0oЫOУ  0cУg {0$ ܓ$OW$dOW$|gC }gD E :O`P ܓ: ܓd w$ J$OI$JItwI$L$twJ$ItIdJd$ <$ 47IdJt$g 4E>>e% ?%e eeh% "%1ϕ< f>f>5ef?f?%f?f&rq6&&` & `!&f. f !f fff?f>f>f>>ff?g&>g?"QSWZW^W`W W)W/W5Wf>Ėʖʖg@9ʖ&f~>f6Ԗo  ~ `& ' ?'wwo'?/ /O W g/  @>o'>0@0`0҂а`0т`0ʐ`0`0×`0ц`0ӟ`0`0ۗ`0`0`y'f>z'ygOuygy'O?z7pfJC@Fp  @ @ ?7,0PQ}QKfu?K7$nO22l8$8  !"#'7doOpq59d3:d35++++7drO7$+7drO7$+7L;l8$sw58y\w\|\~\\\\\\\\\\\\\\\\\\\\\\\\\]] ]]]]](]/]6]<]B]H]M]T]Z]^]c]i]n]s]x]~]]]]]]]]]]]@@0`0ƃƐ`0˟`0Ъ`0Õ`0ӏ`0`0ʟ`0`0ҟ`0`0ж`0ʐ`0`0`0`0@xm0҂а`0т`0ʐ`0`0×`0ц`0ӟ`0џ`0ŗ`0`0ʂ`0`0`0ۗ`0`0ƕ`0փ`0՘Θ`0ƕ`0`0`0öص`0І`0ǃ`0ǃ`0ˇ`0ɭ`0ǃǐ`0Ӑ`0ח`0`0՘`0@xm0՘`0`0؃ǐ`0ǃˇ`0σϗ`0ǃח`0װ`0`0Ѓ`@%%%e%5}eƕ}eƕ%%eƕ%e%eƕ%e]%%e%ee%5eeƕeƕem%e%%%%e%6%%%}%ee.%e%e6%e]%eFee%eDeeeMOe!%5Getw%5V>eu]e!a%e!%e1%S%f%%eq%ff&Žyx%}ueuu%%%e"%e%M-U%u%e!%5ue!%u'%v'evv'6vg v'v7ugug=uu'v'%f&u'eu'Žww%>eזŽ%>eexwxo%yw eww %o%%o%%ww !#%')+-/1468:<=?ACEGIKLNPRSUWXZ[]_`acdfghjklmnopqrstuvwxxyzz{||}}}~~~p wZh%}ueuu%%%e"%e%M-U%u%e!%5ue!%u'%v'evv'6vg v'v7ugug=uu'v'%f&u'eu'Žww%>eזŽ%>eexwxo%yw eww %o%%o%%ww !#%')+-/1468:<=?ACEGIKLNPRSU/* intel 8080 opcode table */ /* registers */ "a" ,7 ,024, "b" ,0 ,024, "c" ,1 ,024, "d" ,2 ,024, "e" ,3 ,024, "h" ,4 ,024, "l" ,5 ,024, "m" ,6 ,024, /* register pairs */ "sp" ,6 ,025, "psw" ,6 ,025, /* pseudo-opcodes */ ".word" ,0 ,03, ".byte" ,0 ,04, ".string" ,0 ,05, ".if" ,0 ,017, ".endif" ,0 ,020, ".global" ,0 ,021, /* no address opcodes */ "cma" ,0057 ,6, "cmc" ,0077 ,6, "daa" ,0047 ,6, "di" ,0363 ,6, "ei" ,0373 ,6, "hlt" ,0166 ,6, "nop" ,0000 ,6, "pchl" ,0351 ,6, "ral" ,0027 ,6, "rar" ,0037 ,6, "rc" ,0330 ,6, "ret" ,0311 ,6, "rlc" ,0007 ,6, "rm" ,0370 ,6, "rnc" ,0320 ,6, "rnz" ,0300 ,6, "rp" ,0360 ,6, "rpe" ,0350 ,6, "rpo" ,0340 ,6, "rrc" ,0017 ,6, "rz" ,0310 ,6, "sphl" ,0371 ,6, "stc" ,0067 ,6, "xchg" ,0353 ,6, "xthl" ,0343 ,6, /* mov */ "mov" ,0100 ,7, /* mvi */ "mvi" ,0006 ,010, /* rp,data16 */ "lxi" ,0001 ,011, /* rhigh */ "dcr" ,0005 ,012, "inr" ,0004 ,012, "rst" ,0307 ,012, /* address */ "call" ,0315 ,013, "cc" ,0334 ,013, "cm" ,0374 ,013, "cnc" ,0324 ,013, "cnz" ,0304 ,013, "cp" ,0364 ,013, "cpe" ,0354 ,013, "cpo" ,0344 ,013, "cz" ,0314 ,013, "jc" ,0332 ,013, "jm" ,0372 ,013, "jmp" ,0303 ,013, "jnc" ,0322 ,013, "jnz" ,0302 ,013, "jp" ,0362 ,013, "jpe" ,0352 ,013, "jpo" ,0342 ,013, "jz" ,0312 ,013, "lda" ,0072 ,013, "lhld" ,0052 ,013, "shld" ,0042 ,013, "sta" ,0062 ,013, /* rp */ "dad" ,0011 ,014, "dcx" ,0013 ,014, "inx" ,0003 ,014, "ldax" ,0012 ,014, "pop" ,0301 ,014, "push" ,0305 ,014, "stax" ,0002 ,014, /* rlow */ "adc" ,0210 ,015, "add" ,0200 ,015, "ana" ,0240 ,015, "cmp" ,0270 ,015, "ora" ,0260 ,015, "sbb" ,0230 ,015, "sub" ,0220 ,015, "xra" ,0250 ,015, /* data */ "aci" ,0316 ,016, "adi" ,0306 ,016, "ani" ,0346 ,016, "cpi" ,0376 ,016, "in" ,0333 ,016, "ori" ,0366 ,016, "out" ,0323 ,016, "sbi" ,0336 ,016, "sui" ,0326 ,016, "xri" ,0356 ,016, 013, "sta" ,0062 ,013, /* rp */ "dad" ,0011 ,014, "dcx" ,0013 ,014, "inx" ,0003 ,014, "ldax" ,0012 ,014, "pop" ,0301 ,014, "push" ,0305 ,014, "stax" ,0002 ,014, /* rlow */ "adc" ,0210 ,015, "add" ,0200 ,015, "ana" ,0240 ,015, "cmp" ,02# /* * imlac * imlac filter for graphics * (source) | imlac n * n = unit number (default 0) * * d.c.anderson */ char sbuf[100]; int buf[259]; main(argc,argv) int argc; char *argv[]; { register i; register char *p; i=0; if( argc == 2) i= atoi(argv[1]); if( setup(i) == -1){ printf("imlac %d busy\n",i); exit(1); } seg(1); while( i=getc(buf) ) switch( i){ case 'm': ploti(getw(buf),getw(buf),3); break; case 'p': ploti(getw(buf),getw(buf),5); break; case 'l': ploti(getw(buf),getw(buf),3); ploti(getw(buf),getw(buf),2); break; case 't': p=sbuf; while( (i=getc(buf)) != '\n') if( i>0 ) *p++=i; else{ printf(" eof\n"); exit(1); } *p++=0; string(2,sbuf); break; case 'e': seg(1); break; default: printf("imlac- bad command %c\n",i); } } ploti(x,y,p) { parm(0,x); parm(1,y); parm(2,p); funct(031); } ),3); break; case 'p': ploti(getw(buf),getw(buf),5); break; case 'l': /* * scanf.c -- shortended scanf */ scanf(fmt,args) char *fmt; { struct { float *f; }; register char *s; register int **p; float atof(); int atoi(); s=fmt; p= &args; while( *s ) switch( *s++ ){ case 'd': *(*p++) = atoi(); break; case 'f': *((*p++).f) = atof(); break; } } int atoi() { register c,n,s; s=n=0; while( (c=getchar()) == ' ' || c=='\n'); if( c== '+') c=getchar(); if( c== '-'){ s++; c=getchar(); } while( c>= '0' && c<= '9'){ n =* 10; n =+ (c-'0'); c=getchar(); } if( s ) return(-n); return(n); } float atof() { register c,s; float f, base; f=0.0; s=0; while( (c=getchar()) == ' ' || c== '\n'); if( c== '+') c=getchar(); if( c== '-'){ s++; c=getchar(); } while( c>= '0' && c <= '9'){ f =* 10.0; f =+ (c-'0'); c = getchar(); } if( c== '.' ){ base = 1.0; while( (c=getchar()) >= '0' && c <= '9') f =+ (c-'0')*(base=/10.0); } if( s ) return(-f); return(f); } etchar(); } while( c>= '0' && c<= '9'){ n =* 10; n =+ (c-# /* * cc70 - Interdata 70 c translator */ /* * Computer Aided Design and Graphics Laboratory * School of Mechanical Engineering * Purdue University * West Lafayette, Indiana 47907 * D. C. Anderson * April, 1977 */ #include "cc70h.c" struct optab optab[] { "jbr", JBR+A1, "jeq", 0+BR, "jne", 1+BR, "jle", 2+BR, "jge", 3+BR, "jlt", 4+BR, "jgt", 5+BR, "jlo", 6+BR, "jhi", 7+BR, "jlos", 8+BR, "jhis", 9+BR, "jmp", JMP+A1, "mov", MOV+A2, "clr", CLR+A1, "com", COM+A1, "inc", INC+A1, "dec", DEC+A1, "neg", NEG+A1, "tst", TST+A1, "asr", ASR+A1, "asl", ASL+A1, "sxt", SXT+A1, "cmp", CMP+A2, "add", ADD+A2, "sub", SUB+A2, "bit", BIT+A2, "bic", BIC+A2, "bis", BIS+A2, "mul", MUL+A2, "div", DIV+A2, "ash", ASH+A2, "xor", XOR+A2, "movf", MOVF+A2+FLOAT, "movif", MOVIF+A2+FLOAT, "movfi", MOVFI+A2+FLOAT, "movof", MOVOF+A2+FLOAT, "movfo", MOVFO+A2+FLOAT, "addf", ADDF+A2+FLOAT, "divf", DIVF+A2+FLOAT, "mulf", MULF+A2+FLOAT, "clrf", CLRF+A1+FLOAT, "subf", SUBF+A2+FLOAT, "cmpf", CMPF+A2+FLOAT, "negf", NEGF+A1+FLOAT, "tstf", TSTF+A1+FLOAT, "cfcc", CFCC+A0+FLOAT, "sob", SOB+A2, "jsr", JSR+A2, 0, 0}; int (*fntab[])() { /* function address table */ &err, /* 0th element */ &jmp, &err, &jmp, &err, &err, &err, &err, &err, &err, &mov, &clr, &com, &inc, &dec, &neg, &tst, &asr, &asl, &sxt, &cmp, &add, &sub, &bit, &bic, &bis, &mul, &div, &ash, &xor, &err, &err, &err, &err, &movf, &movof, &movfo, &addf, &subf, &divf, &mulf, &clrf, &cmpf, &negf, &tstf, &cfcc, &sob, &jsr, &err, &movif, &movfi }; char freg[]{ '1','3','5','7' }; int storef 1; char *brtab[]{ "beq","bne","ble","bge","blt","bgt","blo", "bhi","ble","bhis"}; main(argc,argv) char **argv; { extern fin, fout; register char *p; register t; if (argc>1 && argv[1][0]=='-') { argc--; argv++; debug++; } if (argc>1) { if ((fin = open(argv[1], 0)) < 0) { printf("cc70: can't open %s\n", argv[1]); exit(1); } } else fin = dup(0); if (argc>2) { if ((fout = creat(argv[2], 0666)) < 0) { fout = 2; printf("cc70: can't create %s\n", argv[2]); exit(1); } } else fout = dup(1); opsetup(); while( getline() ){ if( debug ) printf("/---%s\n",line); t=oplook(); byte = t & BYTE; fop= t & FLOAT; switch( t& 0007400 ){ case BR: setcc(); crack(add1,&dest); singop(brtab[t&0377],&dest); break; case NC: out(line); printf("\n"); break; case A0: (*fntab[t&0377])(); break; case A1: crack(add1,&dest); (*fntab[t&0377])(); break; case A2: for(p=add1; *p != ','; p++) if( *p == '\'') p++; else if(*p== '\n') error("no add2"); *p++=0; crack(add1,&source); crack(p,&dest); (*fntab[t&0377])(); break; default: error("unrecognized optype"); } } flush(); exit(0); } setcc() { register t; if(cc.mode>=0){ load(&cc,'x'); cc.mode= -1; } } e); printf("\n"); break; case A0: (*fntab[t&0377])(); break; case A1: crack(add1,&dest); (*fntab[t&0377])(); break; case A2: /* * Header for cc70 c translator */ /* optypes */ #define BR (0<<8) #define NC (1<<8) #define A0 (2<<8) #define A1 (3<<8) #define A2 (4<<8) /* opcodes */ #define JBR 1 #define CBR 2 #define JMP 3 #define LABEL 4 #define DLABEL 5 #define EROU 7 #define JSW 9 #define MOV 10 #define CLR 11 #define COM 12 #define INC 13 #define DEC 14 #define NEG 15 #define TST 16 #define ASR 17 #define ASL 18 #define SXT 19 #define CMP 20 #define ADD 21 #define SUB 22 #define BIT 23 #define BIC 24 #define BIS 25 #define MUL 26 #define DIV 27 #define ASH 28 #define XOR 29 #define TEXT 30 #define DATA 31 #define BSS 32 #define EVEN 33 #define MOVF 34 #define MOVOF 35 #define MOVFO 36 #define ADDF 37 #define SUBF 38 #define DIVF 39 #define MULF 40 #define CLRF 41 #define CMPF 42 #define NEGF 43 #define TSTF 44 #define CFCC 45 #define SOB 46 #define JSR 47 #define END 48 #define MOVIF 49 #define MOVFI 50 /* branch types */ #define JEQ 0 #define JNE 1 #define JLE 2 #define JGE 3 #define JLT 4 #define JGT 5 #define JLO 6 #define JHI 7 #define JLOS 8 #define JHIS 9 #define BYTE 040000 #define FLOAT 0100000 #define NORM dest.reg=freg[dest.reg-'0'] #define NORMS if(source.mode==0)source.reg=freg[source.reg-'0'] char freg[]; struct { char opcode; char optype; }; struct optab { char *opstring; int opinfo; } optab[]; char line[512]; int debug; #define OPHS 57 struct optab *ophash[OPHS]; char *add1, *add2; struct address { char mode; char reg; char *add; } source, dest; int byte; /* 0=word, else byte operator */ int fop; /* 0=integer opcode, else floating */ struct address cc; /* condition code memory */ int storef ; /* 1=do store in dualop(), else don't */ source.mode==0)source.reg=freg[source.reg-'0'] char freg[]; struct { char opcode; char optype; }; struct optab { char *opstring; int opinfo; } optab[]; char line[512]; int debug; #define OPHS 57 struct optab *ophash[OPHS]; char *add1, *add2; struct address { char mode; char reg; char *add; } source, dest; int byte; /* 0=word, else byte operator */ int fop/ c70 register assignments rz = r0^r0 /constant 0 r0 = r1^r0 / r0 r1 = r2^r0 / r1 r2 = r3^r0 / r2 r3 = r4^r0 / r3 r4 = r5^r0 / r4 r5 = r6^r0 / r5 r6 = r7^r0 / sp r7 = r8^r0 / pc rt = r9^r0 / constant 2 rm = r10^r0 / constant -1 ro = r11^r0 / constant 1 rl = r12^r0 / scratch-load rp = r13^r0 / scratch-prep rx = r14^r0 / scratch rf = r15^r0 / base register / - cvtfi - convert floating rx to integer rx / -- requires that rl,rp be even-odd pair ! frx = X1e /address of frx .globl cvtfi .globl retrn cvtfi: lh rx,frx /get exp be exit lhr rl,rx nhi rx,X7f00 shi rx,X4000 / remove bias bgt 0f shr rx,rx /return 0 br exit 0: srls rx,6 clhi rx,16 bgt toobig shi rx,24 xhi rx,-1 nhi rl,Xff lh rp,frx+2 srl rl,1(rx) 1: lhr rx,rp lh rl,frx bp exit shr rx,rx shr rx,rp exit: jmp retrn(rf) toobig: lhi rp,32767 /too big br 1b yte operator */ int fop/ cvtif - convert integer rx to floating rx frx = X1e / address of fre .globl cvtif .globl retrn cvtif: lhr rl,rx bge 1f />= 0 shr rl,rl shr rl,rx 1: sth rl,1f+2 le rx,1f nhi rx,X8000 /sign ahm rx,frx jmp retrn(rf) 1: X4600 /exponent 0 ,rx /return 0 br exit 0: srls rx,6 clhi rx,16 bgt toobig shi rx,24 xhi rx,-1 nhi rl,Xff lh rp,frx+2 srl rl,1(rx) 1: lhr rx,rp lh rl,frx bp exit shr rx,rx shr rx,rp exit: jmp retrn(rf) toobig: lhi rp,32767 /too big br 1b yte operator */ int fop/* * load serial or parallel imlac * load [-spn] file * s = serial interface, * p = parallel interface,(default) * n = 0-3 , unit number (default=0). * file format: * word 1: data word count, * word 2: load address, * word 3-n: data words. */ int inbuf[259]; /* input buffer */ int outbuf[259]; /* output buffer */ int unit '0'; /* tty or dr unit */ int serial 0; /* serial=1, parallel=0 */ int oldmode[3]; /* space for old tty mode */ int raw[] { 0,0, 040 }; /* raw tty mode */ main(argc,argv) int argc; char *argv[]; { register i,j,c; char *s; if( argc <2 || argc > 3){ printf("usage: load [-sn] file\n"); exit(1); } if( argv[i=1][0] == '-'){ i++; j=1; while( c=argv[1][j++] ) switch( c ){ case 's': serial =1; break; case 'p': serial=0; break; case '0': case '1': case '2': case '3': unit = c; break; default: printf("bad switch\n"); exit(1); } } if( serial ){ s= "/dev/tty0"; s[8] = unit; } else { s= "/dev/dr0"; s[7]=unit; } if( fcreat(s,outbuf) < 0){ printf("can't write to %s\n",s); exit(1); } if( fopen(argv[i],inbuf) < 0){ printf("can't open %s\n",argv[i]); exit(1); } if( serial ) { gtty( outbuf[0],oldmode); stty( outbuf[0], raw); } if( (j=getw(inbuf)) <= 0) exit(0); putw(getw(inbuf)-1,outbuf); while( j-- ) putw(getw(inbuf),outbuf); fflush(outbuf); if( serial ) stty( outbuf[0], oldmode); close(outbuf[0]); putchar(7); } ial ){ s= "/dev/tty0"; s[8] = unit; } else { s= "/dev/dr0"; s[7]=unit; } if( fcreat(s,outb/* * pdp to ge floating representation * conversion routine test program */ float x,y; main() { float i70cvt(); for(;;){ printf("\nenter x:"); scanf("%f",&x); y=i70cvt(x); printf("pdp:%o,%o,%o,%o;i70:%o,%o\n",x,y); } } struct pdpf{ int w1; int w2; }; int mask[]{ 0177777, 0077777, 0037777, 0017777}; float i70cvt(af) float af; { register e,r,s; float f; int w2; s=1; e=((af.w1&077600)>>7)- 0200; if(e<0){ s= -1; e = -e; } if(e>077) printf("error:number too large\n"); r= e&3; f.w1=(((((e-1)>>2)+1)*s+0100)&0177)<<8 | (af.w1&0100000); s= af.w1&3; printf("e=%o,s=%o,f.w1=%o,r=%o\n",e,s,f.w1,r); e=(4-r)&3; r = (af.w1&0177)|0200; w2=af.w2; printf("e=%o,r=%o,w2=%o\n",e,r,w2); if(e){ r =>> e; w2 = (w2>>e)&mask[e] || s<<(16-e); printf("shift:r=%o,w2=%o\n",r,w2); } f.w1=|r; f.w2=w2; printf("f.w1,f.w2=%o,%o\n",f.w1,f.w2); return(f); } t f; int w2; s=1; e=((af.w1&077600)>>7)- 0200; if(e<0){ s= -1; e = -e; } if(e>077) printf("error:number too large\n"); r= e&3; f.w1struct pdpf{ int w1; int w2; }; int mask[]{ 0177777, 0077777, 0037777, 0017777}; float i70cvt(af) float af; { register e,r,s; float f; int w2; s=1; e=((af.w1&077600)>>7)- 0200; if(e<0){ s= -1; e = -e; } if(e>077) error("can't cvt num. to i70"); r= e&3; f.w1=(((((e-1)>>2)+1)*s+0100)&0177)<<8 | (af.w1&0100000); s= af.w1&3; e=(4-r)&3; r = (af.w1&0177)|0200; w2=af.w2; if(e){ r =>> e; w2 = (w2>>e)&mask[e] || s<<(16-e); } f.w1=|r; f.w2=w2; return(f); } g */ struct address cc; /* condition code memory */ int storef ; /* 1=do store in dualop(), else don't */ ource.mode==0)source.reg=freg[source.reg-'0'] char freg[]; struct { char opcode; char optype; }; struct optab { char *opstring; int opinfo; } optab[]; char line[512]; int debug; #define OPHS 57 struct optab *ophash[OPHS]; char *add1, *add2; struct address { char mode; char reg; char *add; } source, dest; int byte; /* 0=word, else byte operator */ int fop; /* 0=integer opcode, else floatin: shell file for testing cc70 : syntax: go70 files... : file names given without extensions ! : loop if $1x = x exit echo $1: cc -S $1.c cc70 - $1.s >$1.70s rm $1.s asge - creg.70s $1.70s shift goto loop m = r10^r0 / constant -1 ro = r11^r0 / constant 1 rl = r12^r0 / scratch-load rp = r13^r0 / scratch-prep rx = r14^r0 / scratch rf = r15^r0 / base register # /* * cc70c -- Interdata 70 c translator * functions */ #include "cc70h.c" jmp() { if(dest.mode==2 || dest.mode==3){ dest.reg=load(&dest,0); dest.mode=0; } singop("br",&dest); } err() { error("bad call to fntab"); } mov() { register r,t; t=dest.mode; r=source.reg; if( source.mode != 0) r=load(&source,t==0?dest.reg: 0); store(r,&dest); } clr() { store('z',&dest); } com() { register r; r=load(&dest,0); out("xhr R,rm\n",r); store(r,&dest); } inc() { source.mode=0; source.reg='o'; add(); } dec() { source.mode=0; source.reg='m'; add(); } neg() { register r; prep(&dest); out("lhr rl,rz\n"); source.reg=dest.reg; dest.reg='l'; source.mode=dest.mode; dest.mode=0; source.add=dest.add; sub(); store('l',&source); } tst() { load(&dest,'x'); } asr() { register r; r=load(&dest,0); out("srha R,1\n",r); store(r,&dest); } asl() { register r; r=load(&dest,0); out("slha R,1\n",r); store(r,&dest); } sxt() { out("bcc 0f(rf)\n"); store('m',&dest); out("br 1f(rf)\n"); out("0:"); store('z',&dest); out("1:"); } cmp() { storef=0; dualop("ch"); storef++; } add() { register r; if( byte || dest.mode==0) dualop("ah"); else{ prep(&dest); r=load(&source,0); out("ahm R",r); singop(",",&dest); cc.mode= -1; } } sub() { dualop("sh"); } bit() { register r; if( source.mode==8){ r=load(&dest,0); out("thi R,C\n",r,source.add); return; } if( dest.mode==8){ r=load(&source,0); out("thi R,C\n",r,dest.add); return; } r=load(&dest,'l'); dest.reg=r; dest.mode=0; singop("nh",&dest); } bic() { register r; r=load(&source,0); source.reg=r; source.mode=0; out("xhr R,rm\n",r); dualop("nh"); } bis() { dualop("oh"); } mul() { if(source.mode==8){ source.reg=load(&source,0); source.mode=0; } dualop("mh"); } div() { if(source.mode==8){ source.reg=load(&source,0); source.mode=0; } dualop("dh"); } ash() { register r; r=load(&source,0); out("bge 0f(rf)\n"); out("srhl R,0(R)\n",dest.reg,r); out("br 1f(rf)\n"); out("0:slhl R,0(R)\n",dest.reg,r); out("1:"); } xor() { dualop("xh"); } movf() { if( source.mode ) load(&source,freg[dest.reg-'0']); else{ if(dest.mode==0) NORM; store(freg[source.reg-'0'],&dest); } } movif() { register r; register save; save=dest.reg; fop=0; load(&source,'x'); source.reg='7'; dest.mode=6; dest.reg='f'; dest.add="cvtif"; jsr(); out("ler R,rx\n",save); } movfi() { register r; struct address save; out("ler rx,R\n",source.reg); fop=0; source.reg='7'; save.mode=dest.mode; save.reg=dest.reg; save.add=dest.add; dest.mode=6; dest.reg='f'; dest.add="cvtfi"; jsr(); source.mode=0; source.reg='x'; dest.mode=save.mode; dest.reg=save.reg; dest.add=save.add; mov(); } movof() { movf(); } movfo() { movf(); } addf() { NORM; NORMS; dualop("ae"); } subf() { NORM; NORMS; dualop("se"); } divf() { NORM; NORMS; dualop("de"); } mulf() { NORM; NORMS; dualop("me"); } clrf() { if(dest.mode==0) dest.reg=freg[dest.reg-'0']; store('z',&dest); } cmpf() { NORM; NORMS; storef=0; dualop("ce"); storef++; } negf() { if(dest.mode==0) dest.reg=freg[dest.reg-'0']; out("ler rx,rz\n"); source.mode=dest.mode; source.reg=dest.reg; source.add=dest.add; dest.mode=0; dest.reg='x'; dualop("se"); store('x',&source); } tstf() { if(dest.mode==0) dest.reg=freg[dest.reg-'0']; load(&dest,'x'); } cfcc() { setcc(); } sob() { out("sis R,1\n",source.reg); out("bne A(rf)\n",dest.add); } char bal[] "bal r?,"; jsr() { bal[3]=' '; if(dest.mode==2 || dest.mode==3){ dest.reg=load(&dest,0); dest.mode=0; bal[3]='r'; } out("sis r6,2\n"); out("sth R,0(r6)\n",source.reg); bal[6]=source.reg; singop(bal,&dest); } source.reg=dest.reg; source.add=dest.add; dest.mode=0; dest.reg='x'; dualop("se"); store('x',&source); } tstf() { if(dest.mode==0) dest.reg=freg[dest.reg-'0']; load(&dest,'x'); } cfcc() { setcc(); } sob() { out("sis R,1\n",source.reg); out("bne A(rf)\n",dest.add); } char bal[] "bal r?,"; jsr() { bal[3]=' '; if(dest.mode==2 || dest.mode==3){ dest.reg=load(&dest,0); dest.mode=0; bal[3]='r';/* * patch -- see imlac fle */ int inbuf[259]; int mem[8192]; int low 017777; int high 0; int tlen; int addr; char buf[20]; main(argc,argv) char *argv[]; { register i; register c; if( argc <= 1) exit(); for( i=0; ++i "); switch ( c=getchar() ){ case '\n': addr++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': addr=geta(c-'0'); break; case 'o': output(); break; case 'm': mem[addr] = geta(0); } printf("%o=%o\n",addr,mem[addr]); } } geta(n) { register c; while( (c=getchar()) != '\n'){ n= (n<<3) + (c-'0'); } return(n); } output() { char fn[50]; register char *p; register c; int fd; getchar(); printf("\nfile-name?"); p= fn; while( (c=getchar()) != '\n') *p++ = c; *p=0; if( (fd=creat(fn,0666) ) <= 0){ printf("can't open %s\n",fn); return; } tlen= high-low+1; write(fd,&tlen,2); write(fd,&low,2); write(fd,&mem[low],tlen*2); } load(f) char *f; { register len,a; if( (fopen(f,inbuf)) <0){ printf("%s?\n",f); return; } len=getw(inbuf); a= getw(inbuf); if( a high) high=a; close( inbuf[0]); } int fd; getchar(); printf("\nfile-name?"); p= fn; while( (c=getchar()) != '\n') *p++ = c; *p=0; if( (fd=creat(fn,0666) ) <= 0){ printf("can't open %s\n",fn); return; } tlen= high-low+1; write(fd,&tlen,2); write(fd,&low,2); write(fd,&mem[low],tlen*2); } load(f) E@ROX # PDSd9Wt<:L`L L v9M`s:`x9`x9 Pasya!aa1i!:O.C1)W9aD!a<9"D18B!aD!a<9a<9BaH",9ty<A B Ak" OQkb!Opkb"Okb#OYiDkbB`A`OM0l M ;sF(~G0s9vs$O"%O40J<bh"L WgD l `(  P `q;`;`"`2` & aq'(v9l)q*9l+,g gE l- :g.9l/E9l0N9lE1 l2`x l3:l4` l5   l693#7w8O 3K3#9w1:w13cp(3#xhpx(3c(33#`l3c9l3c ;gD bNhI lIgD l=Ol9:G(qF0ll?9lo` 1 1 `` {#9{9 9{9 qax!|dC}` dC% C5C@o##Ao#BOCO@ Σ DW#3 EW#FW#cDOGW#cOHW#Ig@9O`{#99ѓ`p9ٓ#h 93:ٓ9 (99`9`9>>gs<`?%@u>u> < 0 7-7=e>%>@m>m?%7e&77-&4>% &06mB%t04B0=lB%t=4B==$>e$>&eOLo?<>d??5?s=e8%9%:%;%<%   0  066?@O`NIe > ?e O`I<ƕ@o P`Q`ƕO<O`:8 P`;9 Q` 8:9;`?OOoc%cѕѕѕEg89:;Hg >ѕ >Pgs<ѕ8 p6&8&9 p7&6n8V8&6f7v&Dg8V8&6f7.6&;7f6vOQWs<6fO Ps<7fO8Vs<O<=mc%cec%M`Cc<=m =e<>%>?%?9?%O`ed t ^D^J^P^U^\^b^f^k^q^v^{^^^^^^^^^^^^^^^^^^^^^^^^^^^^__ ____#_(_-_1_8_>_B_G_N_S_X_^_d_e_k_0` 0`0ƃƐ`0˟`0Ъ`0Õ`0ӏ`0`0ʟ`0`0ҟ`0`0ж`0ʐ`0`0`0`0@n0҂а`0т`0ʐ`0`0×`0ц`0ӟ`0џ`0ŗ`0`0ʂ`0`0`0ۗ`0`0ƕ`0փ`0՘Θ`0ƕ`0`0`0öص`0І`0ǃ`0ǃ`0ˇ`0ɭ`0ǃǐ`0Ӑ`0ח`0`0՘`0@n0՘`0`0؃ǐ`0ǃˇ`0σϗ`0ǃח`0װ`0`0Ѓ`0ǐ`0׋`0Ѓǘ`0`0`m0Ɖ@n0@o0`0Nj@n0ب@n o0ؾ`0Ɖ@o0ѐ`0ß`0Ͱ@n0څ޾`0×`0ʂʐ`0ѐ`0`0ǁ@o0lj@o0`0ɗ`0dz`0ˆ@0Ɓ֗`0ƁΆΗ`0֨`0ո@>o0؁`0͐` o0Ѓ`0`0ب@n0ب@n0dz`0dz` `0՘`0@n0՘`0`0؃ǐ`0ǃˇ`0σϗ`0ǃח`0װ`0`0Ѓ`0ǐ`0׋`0Ѓǘ`0`0`m0Ɖ@n0@o0`0Nj@n0ب@n o0ؾ`0Ɖ@o0ѐ`0ß`0Ͱ@n0څ޾`0×`0ʂʐ`0ѐ`0`0ǁ@o0lj@o0`0ɗ`0dz`WXZ[]_`acdfghjklmnopqrstuvwxxyzz{||}}}~~~p wZh%}ueuu%%%e"%e%M-U%u%e!%5ue!%u'%v'evv'6vg v'v7ugug=uu'v'%f&u'eu'Žww%>eזŽ%>eexwxo%yw eww %o%%o%%ww !#%')+-/1468:<=?ACEGIKLNPRSUc c ... shader program c real xdat(1000),ydat(1000) real xrun(50),yrun(50),ystep integer jxrun, jdat read(5,1004) jdat 1004 format(i4) if( jdat.le.0) stop 1 read(5,1000) (xdat(i),ydat(i),i=1,jdat) 1000 format(2f10.0) write(6,1000) (xdat(i),ydat(i),i=1,jdat) 1 continue read(5,1001,end=999) ystep 1001 format(f10.0) xmin=1.e30 ymin=xmin xmax=-1.e30 ymax=xmax do 30 i=1,jdat if( xdat(i).gt.xmax) xmax=xdat(i) if( xdat(i).lt.xmin) xmin=xdat(i) if( ydat(i).gt.ymax) ymax=ydat(i) if( ydat(i).lt.ymin) ymin=ydat(i) 30 continue if( xmax .le. xmin ) stop 5 if( ymax .le. ymin ) stop 6 sf = 10. / amax0( xmax-xmin, ymax-ymin ) call plots call setmod('defocused') call erase yrun=ymax- ystep/2.0 write(6,1005) sf,xmin,xmax,ymin,ymax 1005 format( 'sf,xmin,xmax,ymin,ymax='5f8.2) 40 continue jxrun=0 do 100 j=1,jdat y1=ydat(j) jj=j+1 if(jj.gt.jxdat) jj=1 y2=ydat(jj) if( (y1-yrun)*(y2-yrun) ) 50,50,100 50 jxrun=jxrun+1 if( jxrun.gt.50) go to 999 xrun(jxrun)= (xdat(jj)-xdat(j))*(yrun-y1)/(y2-y1)+xdat(j) 100 continue if( jxrun-2) 150,130,120 120 j3=jxrun-1 do 125 j=1,j3 jj=j+1 do 125 j2=jj,jxrun if(xrun(j).gt.xrun(j2)) go to 125 t=xrun(j) xrun(j)=xrun(j2) xrun(j2)=t 125 continue c 130 do 140 j=1,jxrun,2 call plot( (xrun(j)-xmin)*sf, (yrun-ymin)*sf,3) call plot( (xrun(j+1)-xmin)*sf, (yrun-ymin)*sf,2) 140 continue 150 yrun=yrun-ystep if( yrun.gt.ymin) go to 40 go to 1 999 call plot(0.,0.,999) write(6,1006) 1006 format(' hit rubout ') 998 go to 998 end (jj)-xdat(j))*(yrun-y1)/(y2-y1)+xdat(/* * convert.c * convert coded ascii imlac core image file * to binary image. */ int mem[8193]; int low 017777; int high 0; main(argc,argv) { register word, c, loc; int j; loc = 04100; for(;;){ word=0; j=4; while( j-- ){ switch( c=getchar() & 0177){ case 0: write(2,"**eof\n",6); exit(1); case 046: finish(); exit(); case '\n': case ' ': j++; break; default: word =<< 4; word =| (c&15); } } switch( c>>4 & 7){ case 3: break; case 4: mem[loc]=word; high = loc>high? loc: high; loc++; break; case 5: loc = ++word; low = loc0){ write(1,&len,2); write(1,&low,2); write(1,&mem[low],2*len); } } nish(); exit(); case '\n': case ' ': j++; break; default: word =<< 4; word =| (c&15); } } switch( c>>4 & 7){ case 3: break; case 4: /* * warnock hidden line algorithm * version 3 * based on appendix from newman and sproull, * d.c. anderson * computer aided design and graphics laboratory * school of mechanical engineering * purdue university * west lafayette, indiana 47907 * (317) 493 9385 * * warnock [-t] [-d] [-nn] [input] * t: trace execution; * d: debug printout * nn: set resolution to nn (default 1024). * input: read raw data from input (default, si). */ int edgenum, pointnum, polynum; struct point { /* data points */ float x,y,z; /* in screen coords */ } *points; struct edge { /* polygon edges */ struct point *ed1,*ed2; /* pointers to edge endpoints */ struct edge *edlink; /* link to next edge */ } *edges; struct polygon { /* polygons */ float a,b,c,d; /* plane coeff's */ float zmin; /* min z value */ struct edge *pedge; /* ptr to first edge */ struct polygon *plink; /* ptr to next polygon */ struct polygon *plist; /* ptr for algorithm lists */ int pnum; /* polygon number for history */ float z1,z2,z3,z4; /* for surrounders */ } *polygons; struct polygon *polyptr; /* polygon list header */ struct polygon *surrounders; /* surrounder list header */ struct polygon *intersectors; /* intersector list header */ struct polygon *hider; int penetrate; char *level0, *level, *limit; float wlx,wby,wrx,wty,zmin,zminmax,z1,z2,z3,z4,nx,ny,nz,px,py,pz; float xx1,xx2,yy1,yy2,zmin1,zmin3,zmin2,zmin4,zmax1,zmax2,zmax3,zmax4; int deltatheta,theta; int trace, debug; int outbuf[259]; int resolution 1024; main(argc,argv) int argc; char *argv[]; { register char *p; register i; extern fin; char *expand(); outbuf[0]=1; for(i=1; i= '0' && *p <= '9'){ if( (resolution=atoi(p))<2 || resolution > 10000) error("bad resolution\"); } else switch( *p ){ case 't': trace++; break; case 'd': debug++; break; default: error("bad switch"); } }else if( (fin=open(p,0)) < 0) error("input file?"); } readfile(); initpolygons(); level0=level= expand( 8*polynum ); for(p=level; px,p->y,p->z); printf("e\ted1\ted2\tedlink\n"); for( e=edges; e< &edges[edgenum]; e=+ sizeof edges[0]) printf("%o\t%o\t%o\t%o\n",e,e->ed1,e->ed2,e->edlink); printf("polyptr=%o\ng\tpedge\tplink\tplist\tpnum\tzmin\n",polyptr); for( g= polygons; g< &polygons[polynum]; g++) printf("%o\t%o\t%o\t%o\t%d\t%f\n",g,g->pedge,g->plink,g->plist,g->pnum,g->zmin); printf("history:\n +1 +2 +3 +4 +5 +6 +7 +8"); for( p=level0; p<= level; p=+ polynum){ e=p; for( cnt=0; cnt < polynum; cnt++){ if( (cnt&7) == 0) printf("\n%3d",cnt); printf("%3d",*e++); } } printf("\n"); } showdot(xa,ya) int xa,ya; { if( debug ) printf("dot(%d,%d)\n",xa,ya); else { putc('p',outbuf); putw(xa,outbuf); putw(ya,outbuf); } } showline(xa,ya,xb,yb) float xa,ya,xb,yb; { register i; if( debug ) printf("line(%d,%d,%d,%d)\n",i=xa,i=ya,i=xb,i=yb); else { putc('l',outbuf); putw(i=xa,outbuf); putw(i=ya,outbuf); putw(i=xb,outbuf); putw(i=yb,outbuf); } } int clip() { register c1,c2,a1; int a2,a3; float t; deltatheta=0; c1=wcode(xx1=nx,yy1=ny); c2=wcode(xx2=px,yy2=py); while( (c1+c2) ) { if( c1&c2 ){ a1=angle(nx,ny); a2=angle(xx1,yy1); a3=angle(px,py); if( (a1=-a2)>3 || a1< -3) if( a1<0) a1=+8; else a1=-8; if( (a2=-a3)>3 || a2< -3) if( a2<0) a2=+8; else a2=-8; deltatheta=a1+a2; return(0); /* invisible */ } if( c1==0) { a1=c1; c1=c2; c2=a1; t=xx1; xx1=xx2; xx2=t; t=yy1; yy1=yy2; yy2=t; } if( c1&1 ){ yy1=(yy2-yy1)*(wlx-xx1)/(xx2-xx1)+yy1; xx1=wlx; } else if( c1&2 ){ yy1=(yy2-yy1)*(wrx-xx1)/(xx2-xx1)+yy1; xx1=wrx; } else if( c1&4 ){ xx1=(xx2-xx1)*(wby-yy1)/(yy2-yy1)+xx1; yy1=wby; } else { xx1=(xx2-xx1)*(wty-yy1)/(yy2-yy1)+xx1; yy1=wty; } c1= wcode(xx1,yy1); } return(-1); /* visible */ } char *findedge() { int m; extern fin; register char *e,*p; char *expand(); scanf("d",&m); if( (--m)<0 || m >= edgenum) error("polygon edge def. ?"); e = &edges[m]; if( e->edlink == 0) return(e); p= expand( sizeof edges[0] ); p->ed1 = e->ed1; p->ed2 = e->ed2; return(p); } readfile() { extern fin; int t1,t2; int pnum; register char *p,*e,*g; char *expand(); scanf("d",&pointnum); scanf("d",&edgenum); scanf("d",&polynum); if( pointnum <=0 || edgenum<=0 || polynum <=0) error("bad input number(s)"); points= expand(pointnum * sizeof points[0]); edges = expand(edgenum * sizeof edges[0]); for( p= points; p< &points[pointnum]; p=+ sizeof points[0]){ scanf("fff",&p->x,&p->y,&p->z); if( p->z > 0.0) error("point z > 0?"); } for( e= edges; e< &edges[edgenum]; e=+ sizeof edges[0]){ scanf("dd",&t1,&t2); if( (--t1)<0 || t1>= pointnum || (--t2)<0 || t2>= pointnum) error("edge point no. ?"); e->ed1 = &points[t1]; e->ed2 = &points[t2]; e->edlink = 0; } polyptr= 0; pnum=0; polygons = expand(polynum * sizeof polygons[0]); for( g= polygons; g< &polygons[polynum]; g=+ sizeof polygons[0]){ g->plink = polyptr; polyptr = g; g->pnum = pnum++; scanf("d",&t1); g->pedge= e= findedge(); while( --t1 ) e= e->edlink= findedge(); e->edlink = 0; e= g->pedge; p = e->ed2; if( p!= (e->edlink)->ed1 && p != (e->edlink)->ed2){ p= e->ed1; e->ed1 = e->ed2; e->ed2=p; } for(; e != 0; e=p){ p= e->edlink; if( p!= 0 && e->ed2 != p->ed1){ e= p->ed1; p->ed1 = p->ed2; p->ed2 = e; } } } } initpolygons() { float x1,x2,x3,y1,y2,y3; int change; register char *p,*j,*oldp; oldp= 0; for( p=polyptr; p!= 0; p=p->plink){ j= (p->pedge)->ed1; x1= j->x; y1= j->y; z1= j->z; j= (p->pedge)->edlink; x2= (j->ed1)->x -x1; y2= (j->ed1)->y -y1; z2= (j->ed1)->z -z1; x3= (j->ed2)->x -x1; y3= (j->ed2)->y -y1; z3= (j->ed2)->z -z1; p->a= y3*z2- y2*z3; p->b= x2*z3-x3*z2; p->c= x3*y2-x2*y3; p->d= -(p->a *x1 + p->b *y1 + p->c * z1); zmin=0.0; for( j=p->pedge; j!= 0; j= j->edlink) if( zmin > (j->ed1)->z) zmin=(j->ed1)->z; p->zmin = zmin; if( p->c == 0.0){ if( oldp == 0) polyptr=p; else oldp->plink = p->plink; } else oldp=p; } /* sort polygons by increasing zmin */ do { oldp=change=0; for( p=polyptr; p;){ j= p->plink; if( j!= 0 && p->zmin > j->zmin){ if( oldp== 0 ) polyptr=j; else oldp->plink=j; p->plink = j->plink; j->plink = p; change++; oldp=j; } else { oldp=p; p = p->plink; } } } while ( change ); } warnock(left,bottom,size) int left,bottom,size; { register char *p,*j,*oldp; char *sbrk(); wlx = left; wrx = wlx+size-0.0001; wby = bottom; wty = wby+size-0.0001; if( trace ){ showline(wlx,wby,wrx,wby); showline(wrx,wby,wrx,wty); showline(wrx,wty,wlx,wty); showline(wlx,wty,wlx,wby); } p= level+polynum; for( oldp=level; oldp < level+polynum;) *p++ = *oldp++; surrounders = intersectors = 0; zminmax=0.0; /* looker */ for( p=polyptr; p != 0; p=p->plink){ if( p->zmin > zminmax) break; theta = level[p->pnum]; if( theta == -1){ theta=0; for( j=p->pedge; j!= 0; j= j->edlink){ px= (j->ed1)->x; py= (j->ed1)->y; pz=(j->ed1)->z; nx = (j->ed2)->x; ny= (j->ed2)->y; nz= (j->ed2)->z; if( clip() ) { p->plist= intersectors; intersectors=p; goto nextpoly; } theta=+ deltatheta; } (level+polynum)[p->pnum]=theta; } if( theta==8 || theta== -8){ p->plist = surrounders; surrounders=p; z1 = p->z1 = (-p->a*wlx - p->b*wby - p->d)/p->c; z2 = p->z2 = (-p->a*wlx - p->b*wty - p->d)/p->c; z3 = p->z3 = (-p->a*wrx - p->b*wby - p->d)/p->c; z4 = p->z4 = (-p->a*wrx - p->b*wty - p->d)/p->c; if( z2>z1 ) z1=z2; if( z3>z1 ) z1=z3; if( z4>z1 ) z1=z4; zminmax=z1; } nextpoly:; } /* thinker */ if( debug ){ printlist(surrounders,"surrounders"); printlist(intersectors,"intersectors"); } zmin1=zmin2=zmin3=zmin4=0.0; hider = penetrate = 0; for(p=surrounders; p!= 0; p= p->plist){ z1=p->z1; z2=p->z2; z3=p->z3; z4=p->z4; if( z1<=zmin1 && z2<=zmin2 && z3<=zmin3 && z4<=zmin4){ penetrate=0; hider=p; zmin1=zmax1=z1; zmin2=zmax2=z2; zmin3=zmax3=z3; zmin4=zmax4=z4; } else if( z1zmax1 ) zmax1=z1; if( z2>zmax2 ) zmax2=z2; if( z3>zmax3 ) zmax3=z3; if( z4>zmax4 ) zmax4=z4; } } if( debug ) printf("after surrounders:penetrate=%d,hider=%o\n",penetrate,hider); if( penetrate ) goto fail; oldp= 0; if( hider ) for( p=intersectors; p!= 0 ; p= p->plist){ z1 = (-p->a*wlx - p->b*wby - p->d)/p->c; z2 = (-p->a*wlx - p->b*wty - p->d)/p->c; z3 = (-p->a*wrx - p->b*wby - p->d)/p->c; z4 = (-p->a*wrx - p->b*wty - p->d)/p->c; if( z1>=zmax1 && z2>=zmax2 && z3>=zmax3 && z4>=zmax4 ){ j= p->plist; if( oldp== 0) intersectors=j; else oldp->plist = j; }else { oldp=p; if( z1>zmin1 || z2>zmin2 || z3>zmin3 || z4>zmin4 ) goto fail; } } if( (p=intersectors) == 0) return; if( p->plist == 0){ for( j=p->pedge; j!= 0; j=j->edlink){ px= (j->ed1)->x; py= (j->ed1)->y; pz=(j->ed1)->z; nx = (j->ed2)->x; ny= (j->ed2)->y; nz= (j->ed2)->z; if( clip() ) showline(xx1,yy1,xx2,yy2); } return; } fail: if( size < 2) showdot(left,bottom); else { size =/ 2; level =+ polynum; if( (level +(2*polynum)) > limit){ if( sbrk( (4*polynum+64)&(~077))== -1) error("history memory overflow"); limit = sbrk(0); } warnock(left,bottom,size); warnock(left+size,bottom,size); warnock(left,bottom+size,size); warnock(left+size,bottom+size,size); level =- polynum; } } /* * print poly list */ printlist(ap,as) int ap; char *as; { register char *p; int flag; flag=1; for( p=ap; p!= 0; p=p->plist){ if( flag ){ flag=0; printf("%s list:\n",as); printf("p\tplink\tplist\tpnum\tzmin\n"); } printf("%o\t%o\t%o\t%d\t%f\n",p,p->plink,p->plist,p->pnum,p->zmin); } } /* * error message */ error(as) char *as; { register char *p; extern fout; putc('t',outbuf); for(p=as; *p; p++) putc(*p,outbuf); putc('\n',outbuf); fflush(outbuf); fout = 2; printf("warnock error: %s\n",as); dump(); exit(1); } char *expand(size) { register char *p; char *sbrk(); if( (p=sbrk(size))== -1) error("data memory overflow"); limit= sbrk(0); return(p); } ; printf("p\tplink\tplist\tpnum\tzmin\n"); } printf("%o\t%o\t%o\t%d\t%f\n",p,p->plink,p->plist,p->pnum,p->zmin); } } /* * error message */ error(as) char *as; { register char *p; extern fout; putc('t',outbuf); for(p=as; *p; p++) putc(*p,outbuf); putc('\n',outbuf); fflush(outbuf); fout = 2; printf("warnock error: %s\n",as); dump(); exit(1); } char *expand(size) { register char *p; char *sbrk(); if( (p=sbrk(size))== -1) error("data memory overflow"); limit= sLT 01700501 LE 02000501 EQ 00400501 GE 01600501 GT 02100501 NE 00500501 NOT 01000401 AND 00600301 OR 00700301 ISIN 10005402 ICOS 10005502 ISQRT 10005302 BSS 00000203 ZRO 00000303 OCT 00000403 END 00000503 ENTRY 00000603 EXT 00000703 INC 00001003 DSVM 00001003 ASC 00001103 EQU 00001203 VEC 00001303 BSSZ 00001403 MULT 00001503 DIV 00001603 RDIV 00001703 EJECT 00002003 SPACE 00002103 DATA 00002203 DLVM 00002303 ADD 06400014 AISG 07766004 AND 04400014 AREL 07600004 ASM 10200204 ASN 10200104 ASP 00200204 ASZ 00200104 CAL 10001104 CIA 10000604 CLA 10000104 CLL 10001004 CMA 10000204 CML 10002004 COA 10000504 DAC 02000014 DACS 00303004 DBLI 07762204 DCAM 07762104 DCM 04000014 DDXM 00420004 DDYM 00410004 DDSP 00402004 DEA 00302504 DFXY 07777004 DHLT 00000004 DIXM 00500004 DIYM 00440004 DJMP 06000024 DJMS 05000024 DLA 00100304 DLXA 01000004 DLYA 02000004 DNOP 00400004 DOF 00101204 DON 00310004 DRJM 00404004 DROR 07774004 DSF 00201004 DSN 10201004 DSTB 00401004 DSTS 00400404 DVIC 07772004 HLT 00000004 HSN 10240004 IAC 10000404 IOF 00116104 ION 00116204 IOR 05000014 IOT 00100004 ISZ 03000014 JMP 01000014 JMS 03400014 KCF 00102204 KRB 00102104 KRC 00102304 KSF 00202004 KSN 10202004 LAC 06000014 LACS 00303204 LAMP 00305204 LAW 00400004 LDA 10004104 LIAC 10301004 LSN 10200404 LSZ 00200404 LWC 10400004 NOP 10000004 POP 10300404 POPA 10300604 POPD 00305004 PUSH 10300004 PUSHA 10300204 PUSHD 00305104 RAL 00300004 RAR 00302004 RCF 00103204 RDAX 00300504 RDAY 00300604 RDPC 00300404 RRB 00103104 RRC 00103304 RSF 00204004 RSN 10204004 SAD 01400014 SAL 00304004 SAM 07400014 SAR 00306004 SBL 00301004 SBR 00301104 SCF 00107104 SSF 00220004 SSN 10220004 STA 10000304 STL 10003004 SUB 07000014 SWAP 00300004 TAC 00302404 TCF 00104204 TPC 00104304 TPR 00104104 TSF 00210004 TSN 10210004 XAM 02400014 XOR 05400014 00300004 TAC 00302404 TCF 00104204 TPC 00104304 TPR 00104104 TSF 00210004 TSN 10210004 XAM 02400014 XOR 05400014 00300004 TAoints[0]){ scanf("fff",&p->x,&p->y,&p->z); if( p->z > 0.0) error("point z > 0?"); } for( e= edges; e< &edges[edgenum]; e=+ sizeof edges[0]){ scanf("dd",&t1,&t2); if( (--t1)<0 || t1>= pointnum || (--t2)<0 || t2>= pointnum) error("edge point no. ?"); e->ed1 = &points[t1]; e->ed2 = &points[t2]; e->edlink = 0; } polyptr= 0; pnum=0; polygons = expand(polynum * sizeof polygons[0]); for( g= polygons; g< &polygons[polynum]; g=+ sizeof polygons[0]){ g->plink = polyptr; polyptr = g; g->pnum = pnum++; scanf("d",&t1); g->pedge= e= findedge(); while( --t1 ) e= e->edlink= findedge(); e->edlink = 0; e= g->pedge; p = e->ed2; if( p!= (e->edlink)->ed1 && p != (e->edlink)->ed2){ p= e->ed1; e->ed1 = e->ed2; e->ed2=p; } for(; e != 0; e=p){ p= e->edlink; if( p!= 0 && e->ed2 != p->ed1){ e= p->ed1; p->ed1 = p->ed2; p->ed2 = e; } } } } initpolygons() { float x1,x2,x3,y1,y2,y3; int change; register char *p,*j,*oldp; oldp= 0; for( p=polyptr; p!= 0; p=p->plink){ j= (p->pedge)->ed1; x1= j->x; y1= j->y; z1= j->z; j= (p->pedge)->edlink; x2= (j->ed1)->x -x1; y2= (j->ed1)->y -y1; z2= (j->ed1)->z -z1; x3= (j->ed2)->x -x1; y3= (j->ed2)->y -y1; z3= (j->ed2)->z -z1; p->a= y3*z2- y2*z3; p->b= x2*z3-x3*z2; p->c= x3*y2-x2*y3; p->d= -(p->a *x1 + p->b *y1 + p->c * z1); zmin=0.0; for( j=p->pedge; j!= 0; j= j->edlink) if( zmin > (j->ed1)->z) zmin=(j->ed1)->z; p->zmin = zmin; if( p->c == 0.0){ if( oldp == 0) polyptr=p; else oldp->plink = p->plink; } else oldp=p; } do { oldp= 0; change=0; p= polyptr; while(p != 0){ j= p->plink; if( j!= 0 && p->zmin > j->zmin){ if( oldp== 0 ) polyptr=j; else oldp->plink=j; p->plink = j->plink; j->plink = p; change++; oldp=j; } else { oldp=p; p = p->plink; } } } while ( change ); } warnock(left,bottom,size) int left,bottom,size; { register char *p,*j,*oldp; char *sbrk(); wlx = left; wrx = wlx+size-0.0001; wby = bottom; wty = wby+size-0.0001; if( trace ){ showline(wlx,wby,wrx,wby); showline(wrx,wby,wrx,wty); showline(wrx,wty,wlx,wty); showline(wlx,wty,wlx,wby); } p= level+polynum; for( oldp=level; oldp < level+polynum;) *p++ = *oldp++; surrounders = intersectors = 0; zminmax=0.0; /* looker */ for( p=polyptr; p != 0; p=p->plink){ if( p->zmin > zminmax) break; theta = level[p->pnum]; if( theta == -1){ theta=0; for( j=p->pedge; j!= 0; j= j->edlink){ px= (j->ed1)->x; py= (j->ed1)->y; pz=(j->ed1)->z; nx = (j->ed2)->x; ny= (j->ed2)->y; nz= (j->ed2)->z; if( clip() ) { p->plist= intersectors; intersectors=p; theta = -1; break; }else theta=+ deltatheta; } (level+polynum)[p->pnum]=theta; } if( iabs(theta) == 8) { p->plist = surrounders; surrounders=p; z1 = (-p->a*wlx - p->b*wby - p->d)/p->c; z2 = (-p->a*wlx - p->b*wty - p->d)/p->c; z3 = (-p->a*wrx - p->b*wby - p->d)/p->c; z4 = (-p->a*wrx - p->b*wty - p->d)/p->c; if( z2>z1 ) z1=z2; if( z3>z1 ) z1=z3; if( z4>z1 ) z1=z4; zminmax=z1; } } /* thinker */ if( debug ){ printlist(surrounders,"surrounders"); printlist(intersectors,"intersectors"); } zmin1=zmin2=zmin3=zmin4=0.0; hider = 0; penetrate = 0; for(p=surrounders; p!= 0; p= p->plist){ z1 = (-p->a*wlx -p->b*wby -p->d)/p->c; z2 = (-p->a*wlx -p->b*wty -p->d)/p->c; z3 = (-p->a*wrx -p->b*wby -p->d)/p->c; z4 = (-p->a*wrx -p->b*wty -p->d)/p->c; if( z1<=zmin1 && z2<=zmin2 && z3<=zmin3 && z4<=zmin4){ penetrate=0; hider=p; zmin1=zmax1=z1; zmin2=zmax2=z2; zmin3=zmax3=z3; zmin4=zmax4=z4; } else if( z1>=zmax1 && z2>=zmax2 && z3>=zmax3 && z4>=zmax4) ; else{ penetrate++; if( z1zmax1 ) zmax1=z1; if( z2>zmax2 ) zmax2=z2; if( z3>zmax3 ) zmax3=z3; if( z4>zmax4 ) zmax4=z4; } } if( debug ) printf("after surrounders:penetrate=%d,hider=%o\n",penetrate,hider); if( penetrate == 0){ oldp= 0; if( hider ) for( p=intersectors; p!= 0 ; p= p->plist){ z1 = (-p->a*wlx -p->b*wby -p->d)/p->c; z2 = (-p->a*wlx -p->b*wty -p->d)/p->c; z3 = (-p->a*wrx -p->b*wby -p->d)/p->c; z4 = (-p->a*wrx -p->b*wty -p->d)/p->c; if( z1>=zmax1 && z2>=zmax2 && z3>=zmax3 && z4>=zmax4 ){ j= p->plist; if( oldp== 0) intersectors=j; else oldp->plist = j; }else { oldp=p; if( z1<=zmin1 && z2<=zmin2 && z3<=zmin3 && z4<=zmin4 ); else goto fail; } } if( (p=intersectors) == 0) return; if( p->plist == 0){ for( j=p->pedge; j!= 0; j=j->edlink){ px= (j->ed1)->x; py= (j->ed1)->y; pz=(j->ed1)->z; nx = (j->ed2)->x; ny= (j->ed2)->y; nz= (j->ed2)->z; if( clip() ) showline(xx1,yy1,xx2,yy2); } return; } } fail: if( size < 2) showdot(left,bottom); else { size =/ 2; level =+ polynum; if( (level +(2*polynum)) > limit){ if( sbrk(4*polynum) == -1) error("history memory overflow"); limit =+ 4*polynum; } warnock(left,bottom,size); warnock(left+size,bottom,size); warnock(left,bottom+size,size); warnock(left+size,bottom+size,size); level =- polynum; } } /* * print poly list */ printlist(ap,as) int ap; char *as; { register char *p; int flag; flag=1; for( p=ap; p!= 0; p=p->plist){ if( flag ){ flag=0; printf("%s list:\n",as); printf("p\tplink\tplist\tpnum\tzmin\n"); } printf("%o\t%o\t%o\t%d\t%f\n",p,p->plink,p->plist,p->pnum,p->zmin); } } /* * error message */ error(as) char *as; { register char *p; extern fout; putc('t',outbuf); for(p=as; *p; p++) putc(*p,outbuf); putc('\n',outbuf); fflush(outbuf); fout = 2; printf("warnock error: %s\n",as); dump(); exit(1); } iabs(x) { if( x >= 0) return (x); return(-x); } char *expand(size) { register char *p; char *sbrk(); if( (p=sbrk(size))== -1) error("data memory overflow"); limit= sbrk(0); return(p); } printf("%o\t%o\t%o\t%d\t%f\n",p,p->plink,p->plist,p->pnum,p->zmin); } } /* * error message */ error(as) char *as; { register char *p; extern fout; putc(# /* * cc70b -- Interdata 70 c translator */ #include "cc70h.c" getline() { register char *p; register c; p=line; while( (c=getchar())>0){ if( c== ':'){ *p++=c; *p=0; out(p=line); continue; } if(c == '\n'){ *p = 0; return(1); } *p++ = c; } return(0); } opsetup() { register struct optab *optp, **ophp; register char *p; for( optp=optab; p=optp->opstring; optp++){ ophp= &ophash[(((p[0]<<3)+(p[1]<<1)+p[2])&077777)%OPHS]; while( *ophp++ ) if( ophp >= &ophash[OPHS] ) ophp=ophash; *--ophp=optp; } } /* * out -- output special string and arguments */ out(as,args) char *as; { int **ap; char *cp; register char *s,c; s=as; ap = &args; while( *s ) switch( c= *s++){ case 'B': if(fop) putchar('e'); else putchar(byte==0? 'h': 'b'); break; case 'T': if(fop) putchar('4'); else putchar(byte==0? '2':'1'); break; case 'R': putchar('r'); putchar( *ap++ ); break; case 'A': cp=s; s= *ap++; while( c= *s++) putchar(c); s=cp; break; case 'C': cp=s; s= *ap++; while((c= *s++)==' '); s--; while( *s ) putchar(*s++); s=cp; if( c!='-' && (c<'0' || c>'9') ) printf("(rf)"); break; default: putchar(c); break; } } oplook() { register struct optab *optp; register char *p, *op; static char top[32]; struct optab **ophp; op=top; for( p=line; *p && *p != ' ' && *p != '\t'; ) *op++= *p++; *op = 0; while( *p=='\t' || *p == ' ') p++; add1=p; ophp= &ophash[(((top[0]<<3)+(top[1]<<1)+top[2])&077777)%OPHS]; while( optp= *ophp){ op= optp->opstring; p=top; while( *p == *op++) if( *p++ == 0) return( optp->opinfo ); if( *p++ == 'b' && *p++==0 && *--op==0) return(optp->opinfo+BYTE); if( ++ophp >= &ophash[OPHS]) ophp= ophash; } return(NC); } error(as) char *as; { extern fout; flush(); fout=2; printf("cc70 error: %s\n",as); printf("at line: %s\n",line); flush(); exit(1); } /* * crack -- crack address string as into address structure ap */ crack(as,ap) char *as; struct address *ap; { char *getreg(); char *name(); register char *s,*p,c; s=as; p=ap; p->reg= 0; p->add = 0; while( *s ) switch( c= *s++ ){ case ',': case ';': case '/': return; case ' ': break; case '*': switch( *s++ ){ case '(': s=getreg(s,&p->reg); if(*s++ != '+') error("*()?"); p->mode=3; return; case '-': if( *s != '(') goto check7; p->mode=5; getreg(++s,&p->reg); return; case '$': s++; goto check6; check7: default: p->add = --s; s=name(s); c= *s; *s= 0; if( c=='(' ) getreg(++s,&p->reg); else p->reg='f'; p->mode=7; return; } case '(': p->mode=1; s=getreg(s,&p->reg); if( *s=='+') p->mode=2; return; case '-': p->mode=4; if( *s != '(') goto check6; getreg(++s,&p->reg); return; case '$': p->mode=8; p->add=s; s=name(s); return; default: p->mode=0; switch(c){ case 'r': if(*s>='0' && *s<='5'){ p->reg= *s; return; } case 's': if(*s == 'p'){ p->reg='6'; return; } case 'p': if(*s == 'c'){ p->reg='7'; return; } } check6: p->add= --s; s=name(s); c= *s; *s=0; if( c=='(') getreg(++s,&p->reg); else p->reg='f'; p->mode=6; return; } } /* * getreg -- get register and advance */ getreg(as,av) char *as; char *av; { register char *s; register c; s=as; switch( *s++ ){ case 'r': if((c= *s++) <'0' || c>'5') error("getreg-r?"); break; case 's': if( *s++ != 'p') error("getreg-s?"); c='6'; break; case 'p': if( *s++ != 'c') error("getreg-p?"); c='7'; break; default: error("getreg-failed"); } *av =c; if( *s++ != ')') error("missing )-getreg"); return(s); } /* * load -- load address ap into register 'ar' */ load(ap,ar) struct address *ap; { register char *p,r; register oldmode; int v; p=ap; if((r=ar) == 0){ if(p->mode == 0) return(p->reg); r='l'; } oldmode=prep(p); switch( p->mode ){ case 0: out("lBr R,R\n",r,p->reg); break; case 1: out("lB R,0(R)\n",r,p->reg); p->mode=6; /* restore store mode */ switch( oldmode ){ case 4: if(fop) p->add = "4"; else p->add= byte==0? "2": "1"; break; default: p->add="0"; } break; case 2: out("lB R,0(R)\n",r,p->reg); out("ais R,T\n",p->reg); break; case 6: out("lB R,A(R)\n",r,p->add,p->reg); break; case 8: if( fop ){ out("le R,0f(rf)\n",r); out(".data\n"); out("0:A;0\n",rmap(p->add)); out(".text\n"); } else{ if(*p->add=='-' || (*p->add>='0' && *p->add<='9')){ v=atoi(p->add); if(v>=0 && v<16){ out("lis R,A\n",r,p->add); break; } if(v<0 && v> -16){ out("lcs R,A\n",r,p->add+1); break; } } out("lhi R,C\n",r,p->add); } break; default: error("load-bad mode"); } cc.mode= -1; if( byte != 0){ cc.mode=0; cc.reg=r; } return(r); } /* * store -- store register into address ap */ store(ar,ap) struct address *ap; { register r,d; register char *p; prep(p=ap); d=p->reg; r=ar; switch( p->mode ){ case 0: if( r!=d) out("lBr R,R\n",d,r); break; case 1: out("stB R,0(R)\n",r,d); break; case 2: out("stB R,0(R)\n",r,d); out("ais R,T\n",d); break; case 6: out("stB R,A(R)\n",r,p->add,d); break; case 8: error("store into $A?"); default: error("store-bad mode"); } return(r); } /* * prep -- prepare address for direct access & adjust */ prep(ap) struct address *ap; { register char *p; register r; p=ap; r=p->reg; switch( p->mode ){ default: return(p->mode); case 3: out("lh R,0(R)\n",'p',r); out("ais R,T\n",r); moder: p->reg='p'; mode1: r=p->mode; p->mode=1; return(r); case 4: out("sis R,T\n",r); goto mode1; case 5: out("sis R,T\n",r); out("lh R,0(R)\n",'p',r); goto moder; case 7: out("lh R,A(R)\n",'p',p->add,r); goto moder; } } /* * name -- scan name, return end pointer */ char *name(as) char *as; { register char *s,c; s=as; for(;;) switch( *s ){ case '/': case ',': case ';': case '(': case 0: return(s); default: s++; } } /* * singop -- do single op as with address ap */ singop(as,ap) char *as; struct address *ap; { register char *s,*p; register r; s=as; prep(p=ap); r=p->reg; if(byte){ r=p->reg=load(p,0); p->mode=0; } switch( p->mode ){ case 0: out("A R\n",s,r); break; case 1: out("A 0(R)\n",s,r); break; case 2: out("A 0(R)\n",s,r); out("ais R,T\n",r); break; case 6: out("A A(R)\n",s,p->add,r); break; case 8: error("singop-$a?"); default: error("singop-mode?"); } } /* * dualop -- do standard I70 opcode */ dualop(as) char *as; { register r; r=load(&dest,0); prep(&source); if(byte){ source.reg=load(&source,'x'); source.mode=0; } switch( source.mode ){ case 0: out("Ar R,R\n",as,r,source.reg); break; case 8: if(fop){ out("A R,0f(rf)\n",as,r); out(".data\n"); out("0:A;0\n",rmap(source.add)); out(".text\n"); } else out("Ai R,C\n",as,r,source.add); break; default: out(as); out(" R",r); singop(",",&source); } if(storef) store(r,&dest); } /* * rmap-- map pdp floating to i70 */ rmap(as) char *as; { return(as); } ep(&source); if(byte){ source.reg=load(&source,'x'); source.mode=0; } switch( source.mode ){ case 0: out("Ar R,R\n",as,r,source.r/ assure fake printf (no floating) .globl fltused; fltused = 0 / convert stream to number; result is type. / value in cval or fcval / modified for interdata 70 - dca, june,1977 / no short floating constants. fpp = 1 .globl _getnum .globl _peekc .globl _getchar .globl _cval .globl _fcval .globl _error _getnum: .if fpp movif $10.,fr3 clrf fr0 .endif clr nfract clr totdig clr decpt clr _cval mov 2(sp),base mov r2,-(sp) 1: jsr r5,getdig br 2f .if fpp mulf fr3,fr0 movif r0,fr1 addf fr1,fr0 .endif inc nfract br 1b 2: tst decpt bne 1f clr nfract cmp r0,$'. bne 1f mov pc,decpt br 1b 1: tst totdig beq 1f cmp r0,$'e bne 1f clr -(sp) clr _cval mov pc,decpt clr _cval mov $10.,base jsr pc,_getchar cmp r0,$'+ beq 2f cmp r0,$'- bne 3f inc (sp) br 2f 3: mov r0,_peekc 2: jsr r5,getdig br 2f br 2b 2: tst (sp)+ beq 2f neg _cval 2: sub _cval,nfract 1: mov r0,_peekc tst totdig bne 1f mov $39.,r0 / "." operator 9: mov (sp)+,r2 rts pc 1: tst decpt bne 1f mov $21.,r0 / fixed constant br 9b 1: .if fpp movif $1,fr2 mov nfract,r2 mov r2,-(sp) beq 2f bgt 1f neg r2 1: mulf fr3,fr2 sob r2,1b 2: tst (sp)+ ble 1f divf fr2,fr0 br 2f 1: mulf fr2,fr0 2: mov $_fcval,r0 movf fr0,(r0) br 1f // *** mod. tst (r0)+ tst (r0)+ bne 1f tst (r0)+ bne 1f tst (r0)+ bne 1f mov $24.,r0 mov _fcval,_cval br 9b 1: mov $23.,r0 br 9b .endif .if 1-fpp mov $fperr,-(sp) jsr pc,_error tst (sp)+ mov $21.,r0 br 9b fperr: ; .even .endif getdig: mov _peekc,r0 beq 1f clr _peekc br 2f 1: jsr pc,_getchar 2: sub $'0,r0 cmp r0,$9. bhi 1f inc totdig mov _cval,r1 mul base,r1 add r0,r1 mov r1,_cval tst (r5)+ rts r5 1: add $'0,r0 rts r5 .bss base: .=.+2 nfract: .=.+2 decpt: .=.+2 totdig: .=.+2 (r0)+ bne 1f tst (r0)+ bne 1f tst (r0)+ bne 1f mov $24.,r0 mov _fcval,_cval br 9b 1: mov $23.,r0 br 9b .endif .if 1-fpp mov $fperr,-(sp) jsr pc,_error tst (sp)+ mov $21.,r0 br 9b fperr: ; .even .endif getdig# /* * intel 8080 assembler * * d. anderson, august, 1976 * m.e. cad and graphics laboratory * purdue university, indiana. */ /* compile constants */ #define SYMLEN 8 #define SYMSIZ 512 #define LINSIZ 120 #define NFILES 10 #define EOL 0 #define STACKSIZ 10 #include "types.8080" struct symtab { /* the symbol table structure */ char id[SYMLEN]; int value; int type; }; struct optab { /* opcode initialization table structure */ char *str; int ovalue; int otype; }; struct optab optab[] { #include "optab.8080" }; struct fblist{ /* the fb label structure */ char *fbnext; /* ptr to next fb this n */ int fbvalue; /* dot value */ }; struct fbhead{ /* fblist head structure */ struct fblist *fbfirst; struct fblist *fblast; } fbhead[10]; struct fblist *fbend, *fblim; #define FBSIZE sizeof(fbend) char oprtab[] { /* operator table */ '+','-','*','/','<','>','&','|','%',0, }; /* must end in 0 */ char (*binop[])(){ /* corresponding function addresses */ &add,&sub,&mul,&div,&lsh,&rsh,&and,&or,&modulo,0, }; struct stack { int sval; int styp; int sbop; } stack[STACKSIZ]; struct stack *stackp &stack[0]; struct symtab symtab[ SYMSIZ ]; struct symtab *loc; /* pointer to lc */ char inline[LINSIZ], *lp; int cc; /* current character */ char cursym[SYMLEN]; int lcmax; int oldloc; /* printout */ int lflag; /* list=1 */ int sflag; /* 1=list skips */ char *files[NFILES], nf, cf; int pass; int eval, etype; int val2, type2; int errors; int input[259]; int output[259]; int binbuf[LINSIZ], *bp; char outbuf[42]; /* output line buffer */ int xsum 0; /* checksum for ascii records */ int obindex 9; /* index into outbuf */ int lastloc -2; /* for put1 */ int linenum; char errc[6]; char *errcp &errc[0]; int instring; int inif; int optype, opcode; main(argc,argv) int argc; char *argv[]; { register i; register struct symtab *sp; char *sbrk(); for( i=1; ivalue = 0; cf=0; close( input[0] ); input[0] = 0; pass++; /* printf("symbol table:\n"); for( sp= &symtab[0]; sp < &symtab[SYMSIZ]; sp++ ){ if( sp->id[0] ){ if( sp->type <= REL && sp != loc) printf(" %8s %6o %6o\n",sp->id,sp->value,sp->type); } } */ if( fcreat("a.out",output) < 0) syserr("a.out ?"); outbuf[0]=':'; outbuf[7]= outbuf[8] = '0'; pass2(); if( obindex > 9) pflush(); putc(':',output); for(i=1;i<=10;i++) putc('0',output); putc('\n',output);putc('$',output); putc('\n',output); fflush(output); close( output[0] ); if( errors ){ printf("%d errors\n",errors); write(2,"as80 errors\n",12); unlink("a.out"); } } /** start of subroutines **/ /* * advance fb label number 'n' */ advfb(n) { register char *p,*fb; fb= &fbhead[n]; while( (p=fb->fbfirst)->fbvalue < loc->value) fb->fbfirst= p->fbnext; } /* * return 1 if c is alphabetic */ alpha(c) { register rc; if( (rc=c) >= 'a' && rc <= 'z' ) return(1); if( rc >= 'A' && rc <= 'Z' ) return(1); if( rc =='.' || rc=='_') return(1); return(0); } /* * count comma fields */ commas() { register n; n=1; for( ;; ){ switch( getnb() ){ case EOL: return(n); case '\'': instring++; quote(); instring--; break; case ',': n++; default: get1(); } } } /* * compare two strings, return difference */ compare(s1,s2) char *s1,*s2; { register char *f,*t,*tt; f=s1; tt=t+SYMLEN; for( t=s2; (*f && t lim || etype != ABS) error('e'); return(eval); } /* * copy one string into another */ copy(from,to) char *from,*to; { register char *f,*t,*tt; f=from; tt=to+SYMLEN; for(t=to; t< tt; t++) if( *f ) *t= *f++; else{ *t = 0; return; }; } /* * return 1 if c is a digit */ digit(c) { if( c >= '0' && c <= '9' ) return(1); return(0); } /* * define fb label n to be loc */ deffb(n) { register char *p,*q,*fb; char *sbrk(); if( (p=fbend)+FBSIZE > fblim){ if( sbrk(64*FBSIZE) == -1) syserr("too many fb labels"); fblim =+ 64*FBSIZE; } fb= &fbhead[n]; fbend =+ FBSIZE; if( q=fb->fblast) q->fbnext = p; p->fbnext=0; p->fbvalue=loc->value; fb->fblast=p; if( fb->fbfirst == 0) fb->fbfirst=p; } /* * enter a string into symbol table */ char *enter(s,v,t) char *s; { register struct symtab *sp; sp=lookup(s); if( sp->id[0] == 0) copy(s,sp->id); sp->value=v; sp->type = t; return(sp); } /* * log error */ error(c) { errors++; if( pass ) { if( errcp < &errc[4] ) *errcp++=c; return; } printf("(%s,%d) %c [%s]\n",files[cf-1],linenum,c,inline); } /* * get escaped character */ escape() { register c; switch( get1() ){ case 't': c= '\t'; break; case 'n': c= '\n'; break; case '\\': c= '\\'; break; case '\'': c= '\''; break; case '"': c= '"'; break; case 'r': c= '\r'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': return( readnum()); default: error('\\'); return(0); } get1(); return(c); } /* * process an expression to eval, etype */ express() { register char *p; register bop; etype = ABS; eval= 0; bop = 0; /* position of + */ start: if( getnb() == '-' ){ bop=1; getnb( get1() ); } else if( cc == '+' ) getnb( get1() ); symbol: type2= ABS; if( alpha( getnb() ) ){ if( (p=lookup(readname()))->id[0]){ val2=p->value; type2 = p->type; } else { error('u'); val2=0; } }else if( digit(cc) ){ val2= readnum(); if( getnb() == 'F' || cc=='B'){ val2=getfb(val2,cc); type2= loc->type; get1(); } }else switch ( cc ) { case '\'': val2 = quote(); break; case '(': if( stackp >= &stack[STACKSIZ] ) syserr("stack overflow"); stackp->sval= eval; stackp->styp = etype; stackp++->sbop = bop; express( get1() ); if( cc != ')') error(')'); get1(); val2= eval; type2=etype; eval = (--stackp)->sval; etype= stackp->styp; bop = stackp->sbop; break; default: error('e'); return; } operator: (*binop[bop])(); p= &oprtab[0]; getnb(); while( *p && (*p != cc) ) p++ ; if( *p == 0 ) return; bop = p - &oprtab[0]; get1(); goto symbol; } /* * hex -- output 2 hex chars */ hex(as,v) char *as; { as[0]= "0123456789ABCDEF"[ (v>>4)&15]; as[1]= "0123456789ABCDEF"[v&15]; } /* * arithmetic functions: eval = eval val2, set etype */ mul() { const(); eval =* val2; } div() { const(); eval =/ val2; } add() { if( types() > 1) error('r'); eval =+ val2; etype =+ type2; } sub() { eval =- val2; switch( types() ){ case 00: return; case 01: if( etype == ABS) error('r'); return; case 02: etype = ABS; return; } } lsh() { const(); eval =<< val2; } rsh() { const(); eval =>> val2; } and() { const(); eval =& val2; } or() { const(); eval =| val2; } modulo() { const(); eval =% val2; } const() { if( etype == REL || type2 == REL ) error('r'); etype = ABS; } types() { etype = (etype>REL)? ABS: etype; type2 = (type2>REL)? ABS: type2; return (etype+type2); } /* * get next fb number 'n', l is 'f' or 'b' */ getfb(n,l) { register char *p,*q; p=fbhead[n].fbfirst; if( p==0 ){ error('u'); return(0); } if(l == 'B') return(p->fbvalue); if((q=p->fbnext)==0){ error('u'); return(0); } return(q->fbvalue); } /* * getline from input */ getline() { register char *p; register c; if( input[0] ) { loop: lp=p=inline; linenum++; while( (c=getc(input)) > 0){ if( c == '\n') { *p = EOL; return(1); } if( p< &inline[LINSIZ-1] ) *p++ = c; else syserr("input line too long"); } } if( input[0] ) close(input[0]); if( cf >= nf) return(0); if( fopen(files[cf++],input) == -1){ printf("open error :%s\n",files[--cf]); exit(1); } linenum=0; goto loop; } /* * get next non-blank character */ getnb() { while( cc == ' ' ) get1(); return(cc); } /* * get next character */ get1() { register c; switch( cc= c= *lp++ ){ case '\t': return(cc=' '); case ';': if( instring ) return(c); else return(cc=EOL); default: return(c); } } /* * return hash index of string */ hash(s) char *s; { register char *lim; register char *ss; register index; ss=s; lim = &s[SYMLEN]; for ( index= *ss; (*ss && sstype){ case IF: inif++; break; case ENDIF: if( --inif ) break; return; } if( pass && sflag ) listit(); } error('f'); } /* * integer abs */ iabs(v) { return( v<0? -v: v); } /* * initialize symbol table */ initst() { register struct symtab *s; register struct optab *o; for( s= &symtab[0]; s < &symtab[SYMSIZ]; s++) s->id[0] = 0; for( o= &optab[0]; o< &optab[sizeof optab/sizeof optab[0]]; o++) enter( o->str, o->ovalue, o->otype); loc = enter(".",0,REL); } /* * listing to output */ listit() { register int *wp; printf("%4s ",errc); switch( optype ){ case EQU: case GLOBAL: case LABEL: case STRING: printf("%4h %s\n",oldloc,inline); break; case RP: case RLOW: case NOADDR: case MOV: case RHIGH: printf("%4h %2h %s\n",oldloc,binbuf[0],inline); break; case MVI: case DATA: printf("%4h %2h %2h %s\n",oldloc,binbuf[0],binbuf[1],inline); break; case ADDR: case LXI: printf("%4h %2h %2h %2h %s\n",oldloc,binbuf[0],binbuf[1],binbuf[2],inline); break; case WORD: for(wp=binbuf;wpbinbuf ) printf(" "); printf("%4h %2h %2h %s\n",oldloc,wp[0],wp[1],inline); *inline=0; oldloc=+2; } break; case BYTE: for(wp=binbuf;wpbinbuf ) printf(" "); printf("%4h %2h %s\n",oldloc,wp[0],inline); *inline=0; oldloc++; } break; case ENDIF: case IF: case 0: default: if( inif==0 || sflag ) printf(" %s\n",inline); break; } } /* * look up symbol in symtab, return pointer */ char *lookup(s) char *s; { register cnt; register struct symtab *sp; sp= &symtab[ hash(s) ]; cnt=0; while( cnt++ < SYMSIZ ) if( sp->id[0] ) { if( compare(s,sp->id) == 0) return(sp); if( (sp=+31) >= &symtab[SYMSIZ] ) sp= &symtab[0]; continue; } return(sp); syserr("symtab full"); } /* * read opcode line- pass one */ opline1() { char str[ LINSIZ ]; /* for readstr's */ register struct symtab *sp; if( (sp=lookup( cursym ))->id[0] ){ switch( sp->type ){ case MOV: case NOADDR: case RHIGH: case RP: case RLOW: loc->value++; break; case MVI: case DATA: loc->value =+ 2; break; case ADDR: case LXI: loc->value =+ 3; break; case WORD: loc->value =+ commas()<<1; break; case BYTE: loc->value =+ commas(); break; case STRING: loc->value =+ readstr(str); break; case IF: ifskip(); break; case ENDIF: break; case GLOBAL: break; default: error('o'); break; } }else error('o'); while( cc != EOL ) get1(); } /* * opline pass two */ opline2() { char str[LINSIZ]; register struct symtab *sp; register char *cp; register t; sp=lookup(cursym); optype= sp->type; opcode = sp->value; switch( optype) { case WORD: while( getnb() != EOL ){ express(); put2(eval,etype); if( getnb() == ',') get1(); else break; } break; case BYTE: while( getnb() != EOL){ put1(conexp(0377),ABS); if( getnb() == ',') get1(); else break; } break; case STRING: t=readstr(str); cp=str; while( t-- ) put1(*cp++,ABS); break; case IF: ifskip(); break; case ENDIF: break; case GLOBAL: break; case NOADDR: put1(opcode,ABS); break; case MOV: t=conexp(7); get1(); put1( opcode | t<<3 | conexp(7),ABS); break; case LXI: rpair(); if( cc!= ',') error('a'); else get1(); put1(opcode | eval<<4,ABS); express(); put2(eval,etype); break; case MVI: conexp(7); if( cc!= ',') error('a'); else get1(); put1(opcode | eval<<3,ABS); put1(conexp(0377),ABS); break; case RHIGH: put1( opcode|conexp(7)<<3,ABS); break; case ADDR: express(); put1(opcode,ABS); put2(eval,etype); break; case RP: put1( opcode|rpair()<<4,ABS); break; case RLOW: put1(opcode|conexp(7),ABS); break; case DATA: put1(opcode,ABS); put1(conexp(0377),ABS); break; } } /* * pass one */ pass1() { register saveval; char savcursym[SYMLEN]; while( getline() ) { loop: if( alpha( getnb( get1() ) ) ) { readname(); switch( getnb() ){ case ':' : if( *lookup(cursym) ) error('m'); enter(cursym,loc->value,loc->type); goto loop; case '=' : copy(cursym,savcursym); express( get1() ); if( getnb() == '^' ) { saveval=eval; express( get1() ); eval=saveval; } if( lookup(savcursym) == loc) if(evalvalue || (etype!=loc->type && loc->value>0)) error('.'); enter(savcursym,eval,etype); goto out; default: opline1(); } }else if( digit(cc) ){ saveval=readnum(); if( getnb() == ':'){ deffb(saveval); goto loop; } } out: if( getnb() != EOL ) error('e'); } return(errors); } /* * pass two */ pass2() { int olderr; char savcursym[SYMLEN]; register saveval; while( getline() ){ optype = 0; olderr=errors; bp=binbuf; errcp = errc; errc[0]=errc[1]=errc[2]=errc[3]=' '; oldloc=loc->value; loop: if( alpha( getnb( get1() ) ) ){ readname(); switch( getnb() ){ case ':': optype=LABEL; goto loop; case '=': optype=EQU; copy(cursym,savcursym); express(get1() ); if( getnb() == '^'){ saveval=eval; express(get1()); eval=saveval; } enter(savcursym,eval,etype); goto out; default: opline2(); } }else if(digit(cc) ){ saveval=readnum(); optype=LABEL; if(getnb()==':'){ advfb(saveval); goto loop; } } out: if( lflag || errors>olderr ) listit(); } } /* * abbreviated printf with h */ char *pbufp; /* used by printf rtns */ printf(fmt,args) char *fmt; { int x,width, *ap; register char c,*f,*s; struct{ char **charp; }; char pbuf[20]; f=fmt; ap= &args; while( c= *f++ ){ if( c!= '%' ) putchar(c); else { pbufp=pbuf; x= *ap++; width=0; while( (c= *f++) >= '0' && c<='9' ) width=width*10 + c - '0'; f--; switch( c= *f++ ){ case 'd': if( x<0) { x= -x; *pbufp++='-'; } printd(x); goto numgo; case 'o': printo(x); goto numgo; case 's': s = x.charp; if(width == 0) width--; while( (c= *s++) && width--) *pbufp++=c; goto strgo; case 'c': *pbufp++=x; width--; strgo: s=pbuf; break; case 'h': printh(x); numgo: if(x) s=pbuf+1; else s=pbuf; width =- pbufp-s; break; default: *pbufp++=c; width=0; break; } while( width-- >0) putchar(' '); while( s>3)&017777); *pbufp++= n&7 + '0'; } printh(n) { if( n ) printh( (n>>4)&07777); *pbufp++="0123456789ABCDEF"[n&017]; } /* * pflush -- flush line buffer */ pflush() { register char *j; char xsumc[2]; xsum=(xsum+(((obindex-9)/2)&0377))&0377; hex( &outbuf[1], (obindex-9)/2 ); for( j= &outbuf[0]; j< &outbuf[obindex]; ) putc(*j++,output); hex(&xsumc[0],-xsum); putc(xsumc[0],output); putc(xsumc[1],output); putc('\n',output); xsum=0; obindex = 9; } /* * put one byte to output */ put1(v,r) { *bp++=v&0377; if( loc->value > lastloc || obindex > 39){ if( obindex>9 ) pflush(); xsum=(xsum+((loc->value>>8)&0377))&0377; xsum=(xsum+((loc->value)&0377))&0377; hex( &outbuf[3],loc->value>>8); hex( &outbuf[5],loc->value); } xsum=((xsum+v)&0377); hex( &outbuf[obindex],v); obindex =+ 2; lastloc = ++loc->value; } /* * put a word to output */ put2(v,r) { struct { char low,high; }; put1(v.low,r==ABS? ABS:RELLOW); put1(v.high,r==ABS? ABS: RELHIGH); } /* * get single quoted character */ quote() { register c; switch(c=get1() ){ case '\\': return(escape() ); case EOL: error('q'); return(0); } get1(); return(c); } /* * read name from input */ char *readname() { register char *p,c,*lim; p=cursym; lim= cursym + SYMLEN; while( alpha(c=cc) || digit(c) ) { if( p < lim ) *p++ = c; get1(); } if( p< lim) *p=0; return(cursym); } /* * read a number from input */ readnum() { register num,c; register char *p; char buf[20]; int base; base=8; p=buf; do if( p> &buf[19] ) error('n'); else *p++ = cc; while( digit( c=get1() ) || (c>='a' && c<='f')); *p = '\0'; num=0; p=buf; switch(c){ case 'h': get1(); while( c= *p++ ){ if( (c=- 'a' )<0) c =+ ('a'-'0'); else c =+ 10; if( c>15 ) error('n'); num =<< 4; num =+ c; } break; case '.': base = 10; case 'o': case 'q': get1(); default: while( c= *p++ ){ if( (c=-'0') >= base) error('n'); num =* base; num =+ c; } } return(num); } /* * read string into b, return byte count */ readstr(b) char *b; { register c; register char *p; p=b; if( getnb() != '"' ){ error('s'); return(0); } instring++; for( ;; ){ switch( c=get1() ){ case EOL: error('s'); instring--; return(p-b); case '\\': *p++ = escape(); break; case '"': instring--; return(p-b); default: *p++ = c; break; } } } /* * evaluate register pair expression */ rpair() { conexp(6); return( eval = (eval>>1)&3 ); } /* * log fatal system error and exit */ syserr(s) char *s; { printf("assembler error: %s\n",s); if( pass ) unlink("a.out"); exit(1); } or('s'); return(0); } instring++; for( ;; ){ switch( c=get1() ){ case EOL: error('s'); instring--; return(p-b); case '\\': *p++ = escape(); break; case '"': instring--; return(p-b); default: *p++ = c; break; } } } /* * evaluate register pair expression */ rpair() { conexp(6); return( eval = (eval>>1)&3 ); } /* * log fatal system error and exit E@ROX # PN]nCa~<:L`L L v9M`s:`x9`x9 Pasya!aa1i!:O.C1)W9aD!a<9"D18B!aD!a<9a<9BaH",9ty<A B Ak"*O[kb+Opkb,Okb-OciDkbB`A`OM0l M ;sF(~G0s9vs.O"/O40JFbh"L a%gD l `(  P `{;j;`"`2` 0 aq12v9l3q49l56 g !gE l7 :)g89l9E9l:N9lE; l<`x l=:l>` l?   l@93#AwBO 3K3#Cw1Dw13cp(3#xhpx(3c(33#`l3c9l3c EgD bF'NhI lIEgD I0F7lGgD W`J (K lJHOJ0K0lIgD lHOl9:G(qF0llJ9lyj 1 1 jj #9{9 9{9 {ax!dM}` dM% M5MKo##Lo#MONO@ أ OW#3 PW#QW#cOORW#cOSW#Tg@9O`#99ۓ`p9#h 93:9 (99`9`9HH'g}<`I%JuHuH  < 0A-A! GeH%H(JmHmI%&Ae0AA-04H% 0:@mL%t:4L:GlL%tG4LGGە >[g}<ەB p@&B&C pA&@nBVB&@fAv0OgBVB&@fA.@&^D^J^P^U^\^b^f^k^q^v^{^^^^^^^^^^^^^^^^^^^^^^^^^^^^__ ____#_(_-_1_8_>_B_G_N_S_X_^_d_e_k_0` 0`0ƃƐ`0˟`0Ъ`0Õ`0ӏ`0`0ʟ`0`0ҟ`0`0ж`0ʐ`0`0`0`0@n0҂а`0т`0ʐ`0`0×`0ц`0ӟ`0џ`0ŗ`0`0ʂ`0`0`0ۗ`0`0ƕ`0փ`0՘Θ`0ƕ`0`0`0öص`0І`0ǃ`0ǃ`0ˇ`0ɭ`0ǃǐ`0Ӑ`0ח`0`0՘`0@n0՘`0`0؃ǐ`0ǃˇ`0σϗ`0ǃח`0װ`0`0Ѓ`0ǐ`0׋`0Ѓǘ`0`0`m0Ɖ@n0@o0`0Nj@n0ب@n o0ؾ`0Ɖ@o0ѐ`0ß`0Ͱ@n0څ޾`0×`0ʂʐ`0ѐ`0`0ǁ@o0lj@o0`0ɗ`0dz`0ˆ@0Ɓ֗`0ƁΆΗ`0֨`0ո@>o0؁`0͐` o0Ѓ`0`0ب@n0ب@n0dz`0dz` `0՘`0@n0՘`0`0؃ǐ`0ǃˇ`0σϗ`0ǃח`0װ`0`0Ѓ`0ǐ`0׋`0Ѓǘ`0`0`m0Ɖ@n0@o0`0Nj@n0ب@n o0ؾ`0Ɖ@o0ѐ`0ß`0Ͱ@n0څ޾`0×`0ʂʐ`0ѐ`0`0ǁ@o0lj@o0`0ɗ`0dz`stfps0i.clrx6/i.tstxX/i.absxR/i.negxH/mod0ra-mod24i-mod24d-freg^-i.mulx1i.modx1i.addx0i.ldx /i.subx0i.cmpxZ/i.stx$/i.divx@2i.stexpl0i.stcxj/i.stcxy/i.ldexpX0i.ldcjx/i.ldcyx/ret4-mod0-mod1-mod2-mod3.mod4&.mod56.mod6F.mod7V.badi1b.mod0r-ssp=checkf.pctmp=setabp.asign=seta~.bsign=norm.areg=saret.1aexp=xofloN0retad1retbR1breg=unflo1ovflo1i.mul2bexp=xorsignT3savr5.ol3_monitor"~!_sbrk"4)_main"_exit"n_etext"l3fptrap"+countbas$6savr5$=_edgenum$6_pointnu$6_polynum$6_points$6_edges$6_polygon$6_polyptr$6_surroun$6_interse$6_hider$6_penetra$6_level0$6_level$6_limit$6_wlx$6_wby$6_wrx$6_wty$6_zmin$6_zminmax$6_z1$6_z2$6_z3$6_z4$6_nx$6_ny$6_nz$6_px$6_py$6_pz$6_xx1$6_xx2$6_yy1$6_yy2$6_zmin1$6_zmin3$6_zmin2$6_zmin4$6_zmax1$7_zmax2$7_zmax3$7_zmax4$ 7_deltath$7_theta$7_c1$7_c2$7_trace$7_debug$7_outbuf$7_resolut#3mcount"&*csv" *_atoi"_open".(_fin$"9_error"_readfil" _initpol" _expand"Z_dump"v_warnock"_fflush"(cret"*_printf"B%_showdot"_putc"(_putw"(_showlin"fisdtoi"z*_wcode",fiscmpf"$+_angle"_clip""_findedg"N _scanf"fiststf"T+fisnegf"~+fisitod"R*_printli"|_fout$;fltused"l"ac0$(;_atof"H _getchar"'_profil"L(_creat"(_write"~)_close"'_nargs")_ldiv"+pfloat"l"pscien""_ecvt">#_fcvt"h#_putchar"H'_flush"v'_errno$X;cerror"D*_fcreat"p(_end$>_brk"^)fisdtol"*fisltod"*_ldivr$=_lrem"+m.ext!m.lngi!@fpsim"+fpsr$=w"(_showlin"fisdtoi"z*_wcode",fiscmpf"$+_angle"_clip""_findedg"N _scanf"fiststf"T+fisnegf"~+fisitod"R*_printli"|_fout$;fltused"l"ac0$(;_atof"H _getchar"'_profil"L(_creat"(_write"~)_close"'_nargs")_ldiv"+pfloat"l"pscien""_ecvt">#_fcvt"h#_putchar"H'_flush"v'_errno$X;cerror"D*_fcreat"p(_end$>_brk"^)fisdtol"*fisltod"*_ldivr$=_lrem"+m.ext!m.lngi!@fpsim"/* * warnock hidden line algorithm * version 3 * based on appendix from newman and sproull, * d.c. anderson * computer aided design and graphics laboratory * school of mechanical engineering * purdue university * west lafayette, indiana 47907 * (317) 493 9385 * * warnock [-t] [-d] [-nn] [input] * t: trace execution; * d: debug printout * nn: set resolution to nn (default 1024). * input: read raw data from input (default, si). */ int edgenum, pointnum, polynum; struct point { /* data points */ float x,y,z; /* in screen coords */ } *points; struct edge { /* polygon edges */ struct point *ed1,*ed2; /* pointers to edge endpoints */ struct edge *edlink; /* link to next edge */ } *edges; struct polygon { /* polygons */ float a,b,c,d; /* plane coeff's */ float zmin; /* min z value */ struct edge *pedge; /* ptr to first edge */ struct polygon *plink; /* ptr to next polygon */ struct polygon *plist; /* ptr for algorithm lists */ int pnum; /* polygon number for history */ float z1,z2,z3,z4; /* for surrounders */ float xx1,yy1,xx2,yy2; /* for clip & display */ } *polygons; struct polygon *polyptr; /* polygon list header */ struct polygon *surrounders; /* surrounder list header */ struct polygon *intersectors; /* intersector list header */ struct polygon *hider; int penetrate; char *level0, *level, *limit; float wlx,wby,wrx,wty,zmin,zminmax,z1,z2,z3,z4,nx,ny,nz,px,py,pz; float xx1,xx2,yy1,yy2,zmin1,zmin3,zmin2,zmin4,zmax1,zmax2,zmax3,zmax4; int deltatheta,theta; int trace, debug; int outbuf[259]; int resolution 1024; main(argc,argv) int argc; char *argv[]; { register char *p; register i; extern fin; char *expand(); outbuf[0]=1; for(i=1; i= '0' && *p <= '9'){ if( (resolution=atoi(p))<2 || resolution > 10000) error("bad resolution\"); } else switch( *p ){ case 't': trace++; break; case 'd': debug++; break; default: error("bad switch"); } }else if( (fin=open(p,0)) < 0) error("input file?"); } readfile(); initpolygons(); level0=level= expand( 8*polynum ); for(p=level; px,p->y,p->z); printf("e\ted1\ted2\tedlink\n"); for( e=edges; e< &edges[edgenum]; e=+ sizeof edges[0]) printf("%o\t%o\t%o\t%o\n",e,e->ed1,e->ed2,e->edlink); printf("polyptr=%o\ng\tpedge\tplink\tplist\tpnum\tzmin\n",polyptr); for( g= polygons; g< &polygons[polynum]; g++) printf("%o\t%o\t%o\t%o\t%d\t%f\n",g,g->pedge,g->plink,g->plist,g->pnum,g->zmin); printf("history:\n +1 +2 +3 +4 +5 +6 +7 +8"); for( p=level0; p<= level; p=+ polynum){ e=p; for( cnt=0; cnt < polynum; cnt++){ if( (cnt&7) == 0) printf("\n%3d",cnt); printf("%3d",*e++); } } printf("\n"); } showdot(xa,ya) int xa,ya; { if( debug ) printf("dot(%d,%d)\n",xa,ya); else { putc('p',outbuf); putw(xa,outbuf); putw(ya,outbuf); } } showline(xa,ya,xb,yb) float xa,ya,xb,yb; { register i; if( debug ) printf("line(%d,%d,%d,%d)\n",i=xa,i=ya,i=xb,i=yb); else { putc('l',outbuf); putw(i=xa,outbuf); putw(i=ya,outbuf); putw(i=xb,outbuf); putw(i=yb,outbuf); } } int clip() { register c1,c2,a1; int a2,a3; float t; deltatheta=0; c1=wcode(xx1=nx,yy1=ny); c2=wcode(xx2=px,yy2=py); while( (c1+c2) ) { if( c1&c2 ){ a1=angle(nx,ny); a2=angle(xx1,yy1); a3=angle(px,py); if( (a1=-a2)>3 || a1< -3) if( a1<0) a1=+8; else a1=-8; if( (a2=-a3)>3 || a2< -3) if( a2<0) a2=+8; else a2=-8; deltatheta=a1+a2; return(0); /* invisible */ } if( c1==0) { a1=c1; c1=c2; c2=a1; t=xx1; xx1=xx2; xx2=t; t=yy1; yy1=yy2; yy2=t; } if( c1&1 ){ yy1=(yy2-yy1)*(wlx-xx1)/(xx2-xx1)+yy1; xx1=wlx; } else if( c1&2 ){ yy1=(yy2-yy1)*(wrx-xx1)/(xx2-xx1)+yy1; xx1=wrx; } else if( c1&4 ){ xx1=(xx2-xx1)*(wby-yy1)/(yy2-yy1)+xx1; yy1=wby; } else { xx1=(xx2-xx1)*(wty-yy1)/(yy2-yy1)+xx1; yy1=wty; } c1= wcode(xx1,yy1); } return(-1); /* visible */ } char *findedge() { int m; extern fin; register char *e,*p; char *expand(); scanf("d",&m); if( (--m)<0 || m >= edgenum) error("polygon edge def. ?"); e = &edges[m]; if( e->edlink == 0) return(e); p= expand( sizeof edges[0] ); p->ed1 = e->ed1; p->ed2 = e->ed2; return(p); } readfile() { extern fin; int t1,t2; int pnum; register char *p,*e,*g; char *expand(); scanf("d",&pointnum); scanf("d",&edgenum); scanf("d",&polynum); if( pointnum <=0 || edgenum<=0 || polynum <=0) error("bad input number(s)"); points= expand(pointnum * sizeof points[0]); edges = expand(edgenum * sizeof edges[0]); for( p= points; p< &points[pointnum]; p=+ sizeof points[0]){ scanf("fff",&p->x,&p->y,&p->z); if( p->z > 0.0) error("point z > 0?"); } for( e= edges; e< &edges[edgenum]; e=+ sizeof edges[0]){ scanf("dd",&t1,&t2); if( (--t1)<0 || t1>= pointnum || (--t2)<0 || t2>= pointnum) error("edge point no. ?"); e->ed1 = &points[t1]; e->ed2 = &points[t2]; e->edlink = 0; } polyptr= 0; pnum=0; polygons = expand(polynum * sizeof polygons[0]); for( g= polygons; g< &polygons[polynum]; g=+ sizeof polygons[0]){ g->plink = polyptr; polyptr = g; g->pnum = pnum++; scanf("d",&t1); g->pedge= e= findedge(); while( --t1 ) e= e->edlink= findedge(); e->edlink = 0; e= g->pedge; p = e->ed2; if( p!= (e->edlink)->ed1 && p != (e->edlink)->ed2){ p= e->ed1; e->ed1 = e->ed2; e->ed2=p; } for(; e != 0; e=p){ p= e->edlink; if( p!= 0 && e->ed2 != p->ed1){ e= p->ed1; p->ed1 = p->ed2; p->ed2 = e; } } } } initpolygons() { float x1,x2,x3,y1,y2,y3; int change; register char *p,*j,*oldp; oldp= 0; for( p=polyptr; p!= 0; p=p->plink){ j= (p->pedge)->ed1; x1= j->x; y1= j->y; z1= j->z; j= (p->pedge)->edlink; x2= (j->ed1)->x -x1; y2= (j->ed1)->y -y1; z2= (j->ed1)->z -z1; x3= (j->ed2)->x -x1; y3= (j->ed2)->y -y1; z3= (j->ed2)->z -z1; p->a= y3*z2- y2*z3; p->b= x2*z3-x3*z2; p->c= x3*y2-x2*y3; p->d= -(p->a *x1 + p->b *y1 + p->c * z1); zmin=0.0; for( j=p->pedge; j!= 0; j= j->edlink) if( zmin > (j->ed1)->z) zmin=(j->ed1)->z; p->zmin = zmin; if( p->c == 0.0){ if( oldp == 0) polyptr=p; else oldp->plink = p->plink; } else oldp=p; } /* sort polygons by increasing zmin */ do { oldp=change=0; for( p=polyptr; p;){ j= p->plink; if( j!= 0 && p->zmin > j->zmin){ if( oldp== 0 ) polyptr=j; else oldp->plink=j; p->plink = j->plink; j->plink = p; change++; oldp=j; } else { oldp=p; p = p->plink; } } } while ( change ); } warnock(left,bottom,size) int left,bottom,size; { register char *p,*j,*oldp; char *sbrk(); int ed1,ed2; /* edge saves for no-dup */ wlx = left; wrx = wlx+size-0.0001; wby = bottom; wty = wby+size-0.0001; if( trace ){ showline(wlx,wby,wrx,wby); showline(wrx,wby,wrx,wty); showline(wrx,wty,wlx,wty); showline(wlx,wty,wlx,wby); } p= level+polynum; for( oldp=level; oldp < level+polynum;) *p++ = *oldp++; surrounders = intersectors = 0; zminmax=0.0; /* looker */ for( p=polyptr; p != 0; p=p->plink){ if( p->zmin > zminmax) break; theta = level[p->pnum]; if( theta == -1){ theta=0; for( j=p->pedge; j!= 0; j= j->edlink){ px= (j->ed1)->x; py= (j->ed1)->y; pz=(j->ed1)->z; nx = (j->ed2)->x; ny= (j->ed2)->y; nz= (j->ed2)->z; if( clip() ) { if( (ed1==j->ed1&&ed2==j->ed2)|| (ed2==j->ed1&&ed1==j->ed2)) continue; p->plist= intersectors; intersectors=p; p->xx1=xx1; p->yy1=yy1; p->xx2=xx2; p->yy2=yy2; ed1=j->ed1; ed2=j->ed2; goto nextpoly; }else theta=+ deltatheta; } (level+polynum)[p->pnum]=theta; } if( theta==8 || theta== -8){ p->plist = surrounders; surrounders=p; z1 = p->z1 = (-p->a*wlx - p->b*wby - p->d)/p->c; z2 = p->z2 = (-p->a*wlx - p->b*wty - p->d)/p->c; z3 = p->z3 = (-p->a*wrx - p->b*wby - p->d)/p->c; z4 = p->z4 = (-p->a*wrx - p->b*wty - p->d)/p->c; if( z2>z1 ) z1=z2; if( z3>z1 ) z1=z3; if( z4>z1 ) z1=z4; zminmax=z1; } nextpoly:; } /* thinker */ if( debug ){ printlist(surrounders,"surrounders"); printlist(intersectors,"intersectors"); } zmin1=zmin2=zmin3=zmin4=0.0; hider = penetrate = 0; for(p=surrounders; p!= 0; p= p->plist){ z1=p->z1; z2=p->z2; z3=p->z3; z4=p->z4; if( z1<=zmin1 && z2<=zmin2 && z3<=zmin3 && z4<=zmin4){ penetrate=0; hider=p; zmin1=zmax1=z1; zmin2=zmax2=z2; zmin3=zmax3=z3; zmin4=zmax4=z4; } else if( z1zmax1 ) zmax1=z1; if( z2>zmax2 ) zmax2=z2; if( z3>zmax3 ) zmax3=z3; if( z4>zmax4 ) zmax4=z4; } } if( debug ) printf("after surrounders:penetrate=%d,hider=%o\n",penetrate,hider); if( penetrate ) goto fail; oldp= 0; if( hider ) for( p=intersectors; p!= 0 ; p= p->plist){ z1=p->z1; z2=p->z2; z3=p->z3; z4=p->z4; if( z1>=zmax1 && z2>=zmax2 && z3>=zmax3 && z4>=zmax4 ){ j= p->plist; if( oldp== 0) intersectors=j; else oldp->plist = j; }else { oldp=p; if( z1>zmin1 || z2>zmin2 || z3>zmin3 || z4>zmin4 ) goto fail; } } if( (p=intersectors) == 0) return; if( p->plist == 0){ showline(p->xx1,p->yy1,p->xx2,p->yy2); return; } fail: if( size < 2) showdot(left,bottom); else { size =/ 2; level =+ polynum; if( (level +(2*polynum)) > limit){ if( sbrk( (4*polynum+64)&(~077))== -1) error("history memory overflow"); limit = sbrk(0); } warnock(left,bottom,size); warnock(left+size,bottom,size); warnock(left,bottom+size,size); warnock(left+size,bottom+size,size); level =- polynum; } } /* * print poly list */ printlist(ap,as) int ap; char *as; { register char *p; int flag; flag=1; for( p=ap; p!= 0; p=p->plist){ if( flag ){ flag=0; printf("%s list:\n",as); printf("p\tplink\tplist\tpnum\tzmin\n"); } printf("%o\t%o\t%o\t%d\t%f\n",p,p->plink,p->plist,p->pnum,p->zmin); } } /* * error message */ error(as) char *as; { register char *p; extern fout; putc('t',outbuf); for(p=as; *p; p++) putc(*p,outbuf); putc('\n',outbuf); fflush(outbuf); fout = 2; printf("warnock error: %s\n",as); dump(); exit(1); } char *expand(size) { register char *p; char *sbrk(); if( (p=sbrk(size))== -1) error("data memory overflow"); limit= sbrk(0); return(p); } ; printf("p\tplink\tplist\tpnum\tzmin\n"); } printf("%o\t%o\t%o\t%d\t%f\n",p,p->plink,p->plist,p->pnum,p->zmin); } } /* * error message */ error(as) char *as; { register char *p; extern fout; putc('t',outbuf); for(p=as; *p; p++) putc(*p,outbuf); putc('\n',outbuf); fflush(outbuf); fout = 2; printf("warnock error: %s\n",as); dump(); exit(1); } char *expand(size) { register char *p; char *sbrk(); if( (p=sbrk(size))== -1) error("data memory overflow"); limit= sbrk(0); return(p); }E@COX ' Pq)'E:L`L L v9M`:`x9`x9 Pasya!aa1i!(:sOt.C1)W9aD!a<9"D18B!aD!a<9a<9BaH",9tyEA B Aw"OwbxO|wbOwbOwbOuDwbB`A`XM0x M ;F(G09O"OM0J_bh"L gD x `(  P `;;`"`!â2`!â  aqv9xq9xzg {gE x :gg"xg"x9xE9xN9xE  x`x x(:x` x#  x'!9L#w.O9LKL#wJwJLcp(L#xhpxALc(LL#`xLc9xLc9gD bNhI xIgD xOIIgD W`J (K xJgD xJJJ0K0ygzgD xx9:G(}F0xx9x 1 1  #9z9 9z9 ax!dp}` dp% p5po##o#OO@  ˭W#3 ˮW#˯W#cOW#cwOW#g9O`#99`p9$h 94:9 (99`9`9'k*kg<*`l%mukuk3 C< 0<:d-dDCjek%kKmmkml%IdeSdd-S4k% S]cmo%t]4o]jlo%tj4ojj :>g<&e p&&f p&n:&fv`f.&f.&g&gvt&f1&v&f1&v&*^D^J^P^U^\^b^f^k^q^v^{^^^^^^^^^^^^^^^^^^^^^^^^^^^^__ ____#_(_-_1_8_>_B_G_N_S_X_^_d_e_k_0` 0`0ƃƐ`0˟`0Ъ`0Õ`0ӏ`0`0ʟ`0`0ҟ`0`0ж`0ʐ`0`0`0`0@n0҂а`0т`0ʐ`0`0×`0ц`0ӟ`0џ`0ŗ`0`0ʂ`0`0`0ۗ`0`0ƕ`0փ`0՘Θ`0ƕ`0`0`0öص`0І`0ǃ`0ǃ`0ˇ`0ɭ`0ǃǐ`0Ӑ`0ח`0`0՘`0@n0՘`0`0؃ǐ`0ǃˇ`0σϗ`0ǃח`0װ`0`0Ѓ`0ǐ`0׋`0Ѓǘ`0`0`m0Ɖ@n0@o0`0Nj@n0ب@n o0ؾ`0Ɖ@o0ѐ`0ß`0Ͱ@n0څ޾`0×`0ʂʐ`0ѐ`0`0ǁ@o0lj@o0`0ɗ`0dz`0ˆ@0Ɓ֗`0ƁΆΗ`0֨`0ո@>o0؁`0͐` o0Ѓ`0`0ب@n0ب@n0dz`0dz` `0՘`0@n0՘`0`0؃ǐ`0ǃˇ`0σϗ`0ǃח`0װ`0`0Ѓ`0ǐ`0׋`0Ѓǘ`0`0`m0Ɖ@n0@o0`0Nj@n0ب@n o0ؾ`0Ɖ@o0ѐ`0ß`0Ͱ@n0څ޾`0×`0ʂʐ`0ѐ`0`0ǁ@o0lj@o0`0ɗ`0dz`E@COX ' P{ 31)"E:L`L L v9M`:`x9`x9 Pasya!aa1i!(:}O~.C1)W9aD!a<9"D18B!aD!a<9a<9BaH",9tyEA B Aw"OwbO|wbOwbOwbOuDwbB`A`XM0x M ;F(G09O"OM0Jibh"L gD x `(  P `;;`"`!â2`!â  aqv9xq9xg gE x :gg"xg"x9xE9xN9xE  x`x x(:x` x#  x'!9L#w.O9LKL#wJwJLcp(L#xhpxALc(LL#`xLc9xLc9gD b'NhI xIgD xOIIgD I07xgD W`J (K xJgD xJJJ0K0ggD xx9:G(}F0xx9x 1 1  #9z9 9z9 ax!dz}` dz% z5zo$$o$OO@  ̸W#4 ̹W#̺W$dOW$dOW$g9O`#99`p9!$h 9!4:9 (9"9`9`9)1u4ug<4`v%wuuuu= M< 0FDn-nNMteu%uUwmumv%Sne]nn-]4u% ]gmmy%tg4ygtly%tt4ytt<4ve4o$q9d99ru$ueM$u]/1g;g;g;opqr;g D>  D>g< &o p&&p p&nD&fvjf.&f.&g&gv~&f1&v&f1&v&4^D^J^P^U^\^b^f^k^q^v^{^^^^^^^^^^^^^^^^^^^^^^^^^^^^__ ____#_(_-_1_8_>_B_G_N_S_X_^_d_e_k_0` 0`0ƃƐ`0˟`0Ъ`0Õ`0ӏ`0`0ʟ`0`0ҟ`0`0ж`0ʐ`0`0`0`0@n0҂а`0т`0ʐ`0`0×`0ц`0ӟ`0џ`0ŗ`0`0ʂ`0`0`0ۗ`0`0ƕ`0փ`0՘Θ`0ƕ`0`0`0öص`0І`0ǃ`0ǃ`0ˇ`0ɭ`0ǃǐ`0Ӑ`0ח`0`0՘`0@n0՘`0`0؃ǐ`0ǃˇ`0σϗ`0ǃח`0װ`0`0Ѓ`0ǐ`0׋`0Ѓǘ`0`0`m0Ɖ@n0@o0`0Nj@n0ب@n o0ؾ`0Ɖ@o0ѐ`0ß`0Ͱ@n0څ޾`0×`0ʂʐ`0ѐ`0`0ǁ@o0lj@o0`0ɗ`0dz`0ˆ@0Ɓ֗`0ƁΆΗ`0֨`0ո@>o0؁`0͐` o0Ѓ`0`0ب@n0ب@n0dz`0dz` `0՘`0@n0՘`0`0؃ǐ`0ǃˇ`0σϗ`0ǃח`0װ`0`0Ѓ`0ǐ`0׋`0Ѓǘ`0`0`m0Ɖ@n0@o0`0Nj@n0ب@n o0ؾ`0Ɖ@o0ѐ`0ß`0Ͱ@n0څ޾`0×`0ʂʐ`0ѐ`0`0ǁ@o0lj@o0`0ɗ`0dz`/* * warnock hidden line algorithm * version 4 * based on appendix from newman and sproull, * d.c. anderson * computer aided design and graphics laboratory * school of mechanical engineering * purdue university * west lafayette, indiana 47907 * (317) 493 9385 * * warnock [-t] [-d] [-nn] [input] * t: trace execution; * d: debug printout * nn: set resolution to nn (default 1024). * input: read raw data from input (default, si). */ int edgenum, pointnum, polynum; struct point { /* data points */ float x,y,z; /* in screen coords */ } *points; struct edge { /* polygon edges */ struct point *ed1,*ed2; /* pointers to edge endpoints */ struct edge *edlink; /* link to next edge */ } *edges; struct polygon { /* polygons */ float a,b,c,d; /* plane coeff's */ float xmin,ymin,zmin; /* minimum polygon box */ float xmax,ymax; /* max x & y */ struct edge *pedge; /* ptr to first edge */ struct polygon *plink; /* ptr to next polygon */ struct polygon *plist; /* ptr for algorithm lists */ int pnum; /* polygon number for history */ float z1,z2,z3,z4; /* for surrounders */ } *polygons; struct polygon *polyptr; /* polygon list header */ struct polygon *surrounders; /* surrounder list header */ struct polygon *intersectors; /* intersector list header */ struct polygon *hider; int penetrate; char *level0, *level, *limit; float wlx,wby,wrx,wty,zmin,zminmax,z1,z2,z3,z4,nx,ny,nz,px,py,pz; float xx1,xx2,yy1,yy2,zmin1,zmin3,zmin2,zmin4,zmax1,zmax2,zmax3,zmax4; int deltatheta,theta; int trace, debug; int outbuf[259]; int resolution 1024; main(argc,argv) int argc; char *argv[]; { register char *p; register i; extern fin; char *expand(); outbuf[0]=1; for(i=1; i= '0' && *p <= '9'){ if( (resolution=atoi(p))<2 || resolution > 10000) error("bad resolution\"); } else switch( *p ){ case 't': trace++; break; case 'd': debug++; break; default: error("bad switch"); } }else if( (fin=open(p,0)) < 0) error("input file?"); } readfile(); initpolygons(); level0=level= expand( 8*polynum ); for(p=level; px,p->y,p->z); printf("e\ted1\ted2\tedlink\n"); for( e=edges; e< &edges[edgenum]; e=+ sizeof edges[0]) printf("%o\t%o\t%o\t%o\n",e,e->ed1,e->ed2,e->edlink); printf("polyptr=%o\ng\tpedge\tplink\tplist\tpnum\tzmin\txmin\tymin\txmax\tymax\n",polyptr); for( g= polygons; g< &polygons[polynum]; g++){ printf("%o\t%o\t%o\t%o\t%d\t%.3f",g,g->pedge,g->plink,g->plist,g->pnum,g->zmin); printf("\t%.2f\t%.2f\t%.2f\t%.2f\n",g->xmin,g->ymin,g->xmax,g->ymax); } printf("history:\n +1 +2 +3 +4 +5 +6 +7 +8"); for( p=level0; p<= level; p=+ polynum){ e=p; for( cnt=0; cnt < polynum; cnt++){ if( (cnt&7) == 0) printf("\n%3d",cnt); printf("%3d",*e++); } } printf("\n"); } showdot(xa,ya) int xa,ya; { if( debug ) printf("dot(%d,%d)\n",xa,ya); else { putc('p',outbuf); putw(xa,outbuf); putw(ya,outbuf); } } showline(xa,ya,xb,yb) float xa,ya,xb,yb; { register i; if( debug ) printf("line(%d,%d,%d,%d)\n",i=xa,i=ya,i=xb,i=yb); else { putc('l',outbuf); putw(i=xa,outbuf); putw(i=ya,outbuf); putw(i=xb,outbuf); putw(i=yb,outbuf); } } int clip() { register c1,c2,a1; int a2,a3; float t; deltatheta=0; c1=wcode(xx1=nx,yy1=ny); c2=wcode(xx2=px,yy2=py); while( (c1+c2) ) { if( c1&c2 ){ a1=angle(nx,ny); a2=angle(xx1,yy1); a3=angle(px,py); if( (a1=-a2)>3 || a1< -3) if( a1<0) a1=+8; else a1=-8; if( (a2=-a3)>3 || a2< -3) if( a2<0) a2=+8; else a2=-8; deltatheta=a1+a2; return(0); /* invisible */ } if( c1==0) { a1=c1; c1=c2; c2=a1; t=xx1; xx1=xx2; xx2=t; t=yy1; yy1=yy2; yy2=t; } if( c1&1 ){ yy1=(yy2-yy1)*(wlx-xx1)/(xx2-xx1)+yy1; xx1=wlx; } else if( c1&2 ){ yy1=(yy2-yy1)*(wrx-xx1)/(xx2-xx1)+yy1; xx1=wrx; } else if( c1&4 ){ xx1=(xx2-xx1)*(wby-yy1)/(yy2-yy1)+xx1; yy1=wby; } else { xx1=(xx2-xx1)*(wty-yy1)/(yy2-yy1)+xx1; yy1=wty; } c1= wcode(xx1,yy1); } return(-1); /* visible */ } char *findedge() { int m; extern fin; register char *e,*p; char *expand(); scanf("d",&m); if( (--m)<0 || m >= edgenum) error("polygon edge def. ?"); e = &edges[m]; if( e->edlink == 0) return(e); p= expand( sizeof edges[0] ); p->ed1 = e->ed1; p->ed2 = e->ed2; return(p); } readfile() { extern fin; int t1,t2; int pnum; register char *p,*e,*g; char *expand(); scanf("d",&pointnum); scanf("d",&edgenum); scanf("d",&polynum); if( pointnum <=0 || edgenum<=0 || polynum <=0) error("bad input number(s)"); points= expand(pointnum * sizeof points[0]); edges = expand(edgenum * sizeof edges[0]); for( p= points; p< &points[pointnum]; p=+ sizeof points[0]){ scanf("fff",&p->x,&p->y,&p->z); if( p->z > 0.0) error("point z > 0?"); } for( e= edges; e< &edges[edgenum]; e=+ sizeof edges[0]){ scanf("dd",&t1,&t2); if( (--t1)<0 || t1>= pointnum || (--t2)<0 || t2>= pointnum) error("edge point no. ?"); e->ed1 = &points[t1]; e->ed2 = &points[t2]; e->edlink = 0; } polyptr= 0; pnum=0; polygons = expand(polynum * sizeof polygons[0]); for( g= polygons; g< &polygons[polynum]; g=+ sizeof polygons[0]){ g->plink = polyptr; polyptr = g; g->pnum = pnum++; scanf("d",&t1); g->pedge= e= findedge(); while( --t1 ) e= e->edlink= findedge(); e->edlink = 0; e= g->pedge; p = e->ed2; if( p!= (e->edlink)->ed1 && p != (e->edlink)->ed2){ p= e->ed1; e->ed1 = e->ed2; e->ed2=p; } for(; e != 0; e=p){ p= e->edlink; if( p!= 0 && e->ed2 != p->ed1){ e= p->ed1; p->ed1 = p->ed2; p->ed2 = e; } } } } initpolygons() { float x1,x2,x3,y1,y2,y3; float xmin,ymin,xmax,ymax; int change; register char *p, *j, *k; char *oldp; oldp= 0; for( p=polyptr; p!= 0; p=p->plink){ j= (p->pedge)->ed1; x1= j->x; y1= j->y; z1= j->z; j= (p->pedge)->edlink; x2= (j->ed1)->x -x1; y2= (j->ed1)->y -y1; z2= (j->ed1)->z -z1; x3= (j->ed2)->x -x1; y3= (j->ed2)->y -y1; z3= (j->ed2)->z -z1; p->a= y3*z2- y2*z3; p->b= x2*z3-x3*z2; p->c= x3*y2-x2*y3; p->d= -(p->a *x1 + p->b *y1 + p->c * z1); xmax=ymax=zmin=0.0; xmin=ymin=resolution; for( j=p->pedge; j!= 0; j= j->edlink){ k=j->ed1; if(k->x>xmax) xmax=k->x; else if(k->xx; if(k->y>ymax) ymax=k->y; else if(k->yy; if( k->zz; } p->zmin = zmin; p->xmin=xmin; p->xmax=xmax; p->ymin=ymin; p->ymax=ymax; if( p->c == 0.0){ if( oldp == 0) polyptr=p; else oldp->plink = p->plink; } else oldp=p; } /* sort polygons by increasing zmin */ do { oldp=change=0; for( p=polyptr; p;){ j= p->plink; if( j!= 0 && p->zmin > j->zmin){ if( oldp== 0 ) polyptr=j; else oldp->plink=j; p->plink = j->plink; j->plink = p; change++; oldp=j; } else { oldp=p; p = p->plink; } } } while ( change ); } warnock(left,bottom,size) int left,bottom,size; { register char *p,*j,*oldp; char *sbrk(); wlx = left; wrx = wlx+size-0.0001; wby = bottom; wty = wby+size-0.0001; if( trace ){ showline(wlx,wby,wrx,wby); showline(wrx,wby,wrx,wty); showline(wrx,wty,wlx,wty); showline(wlx,wty,wlx,wby); } p= level+polynum; for( oldp=level; oldp < level+polynum;) *p++ = *oldp++; surrounders = intersectors = 0; zminmax=0.0; /* looker */ for( p=polyptr; p != 0; p=p->plink){ if( p->zmin > zminmax) break; theta = level[p->pnum]; if( theta == -1){ theta=0; for( j=p->pedge; j!= 0; j= j->edlink){ px= (j->ed1)->x; py= (j->ed1)->y; pz=(j->ed1)->z; nx = (j->ed2)->x; ny= (j->ed2)->y; nz= (j->ed2)->z; if( clip() ) { p->plist= intersectors; intersectors=p; goto nextpoly; } theta=+ deltatheta; } (level+polynum)[p->pnum]=theta; } if( theta==8 || theta== -8){ p->plist = surrounders; surrounders=p; z1 = p->z1 = (-p->a*wlx - p->b*wby - p->d)/p->c; z2 = p->z2 = (-p->a*wlx - p->b*wty - p->d)/p->c; z3 = p->z3 = (-p->a*wrx - p->b*wby - p->d)/p->c; z4 = p->z4 = (-p->a*wrx - p->b*wty - p->d)/p->c; if( z2>z1 ) z1=z2; if( z3>z1 ) z1=z3; if( z4>z1 ) z1=z4; zminmax=z1; } nextpoly:; } /* thinker */ if( debug ){ printlist(surrounders,"surrounders"); printlist(intersectors,"intersectors"); } zmin1=zmin2=zmin3=zmin4=0.0; hider = penetrate = 0; for(p=surrounders; p!= 0; p= p->plist){ z1=p->z1; z2=p->z2; z3=p->z3; z4=p->z4; if( z1<=zmin1 && z2<=zmin2 && z3<=zmin3 && z4<=zmin4){ penetrate=0; hider=p; zmin1=zmax1=z1; zmin2=zmax2=z2; zmin3=zmax3=z3; zmin4=zmax4=z4; } else if( z1zmax1 ) zmax1=z1; if( z2>zmax2 ) zmax2=z2; if( z3>zmax3 ) zmax3=z3; if( z4>zmax4 ) zmax4=z4; } } if( debug ){ if(penetrate) printf("penetrate=%o\n",penetrate); if(hider ) printf("hider=%o\n",hider); } if( penetrate ) goto fail; oldp= 0; if( hider ) for( p=intersectors; p!= 0 ; p= p->plist){ z1 = (-p->a*wlx - p->b*wby - p->d)/p->c; z2 = (-p->a*wlx - p->b*wty - p->d)/p->c; z3 = (-p->a*wrx - p->b*wby - p->d)/p->c; z4 = (-p->a*wrx - p->b*wty - p->d)/p->c; if( z1>=zmax1 && z2>=zmax2 && z3>=zmax3 && z4>=zmax4 ){ j= p->plist; if( oldp== 0) intersectors=j; else oldp->plist = j; }else { oldp=p; if( z1>zmin1 || z2>zmin2 || z3>zmin3 || z4>zmin4 ) goto fail; } } if( (p=intersectors) == 0) return; /* if only 2 polygons intersected window, see if they are disjoint or just touching */ if( (j=p->plist) && j->plist==0) if( p->xmin>=j->xmax || j->xmin>=p->xmax || p->ymin>=j->ymax || j->ymin>=p->ymax) goto show; else goto fail; else if(j) goto fail; show: for(;p!=0; p=p->plist){ for( j=p->pedge; j!= 0; j=j->edlink){ px= (j->ed1)->x; py= (j->ed1)->y; pz=(j->ed1)->z; nx = (j->ed2)->x; ny= (j->ed2)->y; nz= (j->ed2)->z; if( clip() ) showline(xx1,yy1,xx2,yy2); } } return; fail: if( size < 2) showdot(left,bottom); else { size =/ 2; level =+ polynum; if( (level +(2*polynum)) > limit){ if( sbrk( (4*polynum+64)&(~077))== -1) error("history memory overflow"); limit = sbrk(0); } warnock(left,bottom,size); warnock(left+size,bottom,size); warnock(left,bottom+size,size); warnock(left+size,bottom+size,size); level =- polynum; } } /* * print poly list */ printlist(ap,as) int ap; char *as; { register char *p; int flag; flag=1; for( p=ap; p!= 0; p=p->plist){ if( flag ){ flag=0; printf("%s:\n",as); printf("p\tplink\tplist\tpnum\tzmin\n"); } printf("%o\t%o\t%o\t%d\t%f\n",p,p->plink,p->plist,p->pnum,p->zmin); } } /* * error message */ error(as) char *as; { register char *p; extern fout; putc('t',outbuf); for(p=as; *p; p++) putc(*p,outbuf); putc('\n',outbuf); fflush(outbuf); fout = 2; printf("warnock error: %s\n",as); dump(); exit(1); } char *expand(size) { register char *p; char *sbrk(); if( (p=sbrk(size))== -1) error("data memory overflow"); limit= sbrk(0); return(p); } ; printf("p\tplink\tplist\tpnum\tzmin\n"); } printf("%o\t%o\t%o\t%d\t%f\n",p,p->plink,p->plist,p->pnum,p->zmin); } } /* * error message */ error(as) char *as; { register char *p; extern fout; putc('t',outbuf); for(p=as; *p; p++) putc(*p,outbuf); putc('\n',outbuf); fflush(ou