sources-request@panda.UUCP (05/19/86)
Mod.sources: Volume 5, Issue 7 Submitted by: genrad!linus!mnetor!clewis (Chris Lewis) There've been quite a few requests for this via net.micro.cpm, so's I thought I'd post it thru mod.sources. This is Ron Cain's original Small C compiler, but highly extended. Included are code generators for 8080, 6809, 68000, and VAX, as well as run-time support for 8080 CPM, VAX BSD4.1, and a FLEX 6809 environment. See the README for a description of Small C's limitations. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README # M_README # Makefile # Makefile.bsd # code8080.c # codeas09.c # codem68k.c # codevax.c # data.c # data.h # This archive created: Sun May 18 18:28:42 1986 export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(2959 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else cat << \SHAR_EOF > 'README' Small C version C3.0R1.1 (SCC3) Chris Lewis This directory contains the source for a version of Ron Cain's Small C compiler that I have heavily modified - beyond the Small-C V2.0 later published in Dr. Dobbs. This compiler generates assembler source code that needs to be assembled and linked to make a running program. Small C is a public domain compiler for a subset of C. The main things lacking are "#if", structs/unions, doubles/floats/longs and more than one level of indirection. Even so, it's powerful enough to be able to compile itself. It's also lots of fun to play around with. It could use lots of more work (eg: a real scanner), but what the heck... Retargetting the compiler requires only relinking the frontend with a new code generator. Code generators for 6809 (MIT UNIX-like assembler), M68K (Motorola V/68 UNIX assembler), VAX (BSD 4.1 assembler), and 8080 (RMAC assembler) are provided. Users having access to System V make should be able to use the Makefile without any modification except for INCDIR and LIBDIR (where you'd like to put the compiler itself). Users not having access to System V will probably have to rewrite the Makefile. [ I have provided a Makefile that seems to work with bsd systems - mod] WARNING: you will probably see a great deal of compilation warnings when you compile this compiler with a "real" UNIX C. Don't worry - this is *perfectly* normal - Small C is a subset of real C, and in order to keep the compiler in this subset you have to bend the rules somewhat. The only time where this might cause a problem is where pointers are "different" from ints (ie: different length or on non-byte-addressible machines). Small C assumes that ints are the same as pointers. Invocation: scc<6809|vax|m68k|8080> filename There are other options available - see main.c for details. The code generated by these compilers need a run-time support library for two things: operations that are "hard" on a particular processor (eg: 16 bit multiply on an 8080), or O/S interface (vax is BSD 4.1, 6809 is FLEX, 8080 is CPM, never had one for M68k). Status: the 6809, VAX and 8080 versions work last I checked - a problem or two may have crept in during the implementation of the compile/assemble/and link code for machines that support it. The M68k version has never been tested. I don't have a Pyramid version because Pyrcorp seems reluctant to publish instruction set information. So you want to write a new coder do you? Well, it's easy - read the comments in one of the coders. You should not have to modify *any* of the existing files, just write a new codexxx.c file. Please contact me if you run into trouble. I would be greatly interested in any new coders or bug reports in the compilers. As far as I am aware, the major restriction on porting this thing for different targets is that pointers and integers *must* be the same length, alignment, and be interchangeable. SHAR_EOF if test 2959 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 2959 characters)' fi fi echo shar: extracting "'M_README'" '(550 characters)' if test -f 'M_README' then echo shar: will not over-write existing file "'M_README'" else cat << \SHAR_EOF > 'M_README' *** Moderator's README *** This directory contains the base source code for the smallC compiler (actually three versions: the 8080, 6809 and vax code generators are here also.) The "includes" directory contains headers which are intended to be included in user programs - the place where these files reside should be set in the Makefile as INCDIR. The directories "6809", "8080", and "vax" contain runtime support for the respective compilers. The directory "lib" contains the source code for some common C library functions (portable ones). SHAR_EOF if test 550 -ne "`wc -c < 'M_README'`" then echo shar: error transmitting "'M_README'" '(should have been 550 characters)' fi fi echo shar: extracting "'Makefile'" '(1429 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else cat << \SHAR_EOF > 'Makefile' # Requires System V make # @(#)Makefile 1.5 86/05/13 .SUFFIXES: .o .c .c~ .h .h~ .PRECIOUS: scclib.a # You'll probabably want to change these. These are used by the compilers# to figure out where the include files should go. TARGDIR = /u/clewis/lib INCDIR = "/u/clewis/src/scc/include/" INSTFLAGS = -DINCDIR=$(INCDIR) CFLAGS = '$(INSTFLAGS)' -O AR = ar ARFLAGS = rv LIB = scclib.a FE = $(LIB)(data.o) \ $(LIB)(error.o) \ $(LIB)(expr.o) \ $(LIB)(function.o) \ $(LIB)(gen.o) \ $(LIB)(io.o) \ $(LIB)(lex.o) \ $(LIB)(main.o) \ $(LIB)(preproc.o) \ $(LIB)(primary.o) \ $(LIB)(stmt.o) \ $(LIB)(sym.o) \ $(LIB)(while.o) all: scc8080 sccas09 sccvax sccm68k $(FE) code8080.o codeas09.o codevax.o codem68k.o: defs.h data.h install: all mv sccvax scc8080 sccas09 sccm68k $(TARGDIR) #Alternately, you may have to do an lorder $(LIB): $(FE) -ranlib $(LIB) -ucb ranlib $(LIB) scc8080: code8080.o $(LIB) $(CC) -o scc8080 $(CFLAGS) $(LIB) code8080.o sccas09: codeas09.o $(LIB) $(CC) -o sccas09 $(CFLAGS) $(LIB) codeas09.o sccvax: codevax.o $(LIB) $(CC) -o sccvax $(CFLAGS) $(LIB) codevax.o sccm68k: codem68k.o $(LIB) $(CC) -o sccm68k $(CFLAGS) $(LIB) codem68k.o print: pr -n defs.h data.h data.c error.c expr.c function.c gen.c \ io.c lex.c main.c preproc.c primary.c stmt.c \ sym.c while.c code*.c | lp clean: rm -f $(LIB) code8080.o codeas09.o codevax.o codem68k.o \ sccvax scc8080 sccas09 sccm68k SHAR_EOF if test 1429 -ne "`wc -c < 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 1429 characters)' fi fi echo shar: extracting "'Makefile.bsd'" '(1359 characters)' if test -f 'Makefile.bsd' then echo shar: will not over-write existing file "'Makefile.bsd'" else cat << \SHAR_EOF > 'Makefile.bsd' # I couldn't get the supplied makefile to work, so I wrote one for # BSD systems - John Nelson, moderator, mod.sources # # You'll probabably want to change these. These are used by the compilers# to figure out where the include files should go. TARGDIR = /u/clewis/lib INCDIR = "/u/clewis/src/scc/include/" INSTFLAGS = -DINCDIR=$(INCDIR) CFLAGS = '$(INSTFLAGS)' -O AR = ar ARFLAGS = rv LIB = scclib.a FE = data.o \ error.o \ expr.o \ function.o \ gen.o \ io.o \ lex.o \ main.o \ preproc.o \ primary.o \ stmt.o \ sym.o \ while.o all: scc8080 sccas09 sccvax sccm68k $(FE) code8080.o codeas09.o codevax.o codem68k.o: defs.h data.h install: all mv sccvax scc8080 sccas09 sccm68k $(TARGDIR) #Alternately, you may have to do an lorder $(LIB): $(FE) -rm $@ ar q $@ $(FE) -ranlib $(LIB) scc8080: code8080.o $(LIB) $(CC) -o scc8080 $(CFLAGS) $(LIB) code8080.o sccas09: codeas09.o $(LIB) $(CC) -o sccas09 $(CFLAGS) $(LIB) codeas09.o sccvax: codevax.o $(LIB) $(CC) -o sccvax $(CFLAGS) $(LIB) codevax.o sccm68k: codem68k.o $(LIB) $(CC) -o sccm68k $(CFLAGS) $(LIB) codem68k.o print: pr -n defs.h data.h data.c error.c expr.c function.c gen.c \ io.c lex.c main.c preproc.c primary.c stmt.c \ sym.c while.c code*.c | lp clean: rm -f $(LIB) code8080.o codeas09.o codevax.o codem68k.o \ sccvax scc8080 sccas09 sccm68k SHAR_EOF if test 1359 -ne "`wc -c < 'Makefile.bsd'`" then echo shar: error transmitting "'Makefile.bsd'" '(should have been 1359 characters)' fi fi echo shar: extracting "'code8080.c'" '(9671 characters)' if test -f 'code8080.c' then echo shar: will not over-write existing file "'code8080.c'" else cat << \SHAR_EOF > 'code8080.c' /* File code8080.c: 2.2 (84/08/31,10:05:09) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* Define ASNM and LDNM to the names of the assembler and linker respectively */ /* * Some predefinitions: * * INTSIZE is the size of an integer in the target machine * BYTEOFF is the offset of an byte within an integer on the * target machine. (ie: 8080,pdp11 = 0, 6809 = 1, * 360 = 3) * This compiler assumes that an integer is the SAME length as * a pointer - in fact, the compiler uses INTSIZE for both. */ #define INTSIZE 2 #define BYTEOFF 0 /* * print all assembler info before any code is generated * */ header () { outstr ("; Small C 8080;\n;\tCoder (2.4,84/11/27)\n;"); FEvers(); nl (); ol ("extrn ?gchar,?gint,?pchar,?pint,?bool"); ol ("extrn ?sxt"); ol ("extrn ?or,?and,?xor"); ol ("extrn ?eq,?ne,?gt,?le,?ge,?lt,?uge,?ult,?ugt,?ule"); ol ("extrn ?asr,?asl"); ol ("extrn ?sub,?neg,?com,?lneg,?mul,?div"); ol ("extrn ?case"); } nl () { outbyte (EOL); } initmac() { defmac("cpm\t1"); defmac("I8080\t1"); defmac("RMAC\t1"); defmac("smallc\t1"); } galign(t) int t; { return(t); } /* * return size of an integer */ intsize() { return(INTSIZE); } /* * return offset of ls byte within word * (ie: 8080 & pdp11 is 0, 6809 is 1, 360 is 3) */ byteoff() { return(BYTEOFF); } /* * Output internal generated label prefix */ olprfix() { outbyte('?'); } /* * Output a label definition terminator */ col () { outbyte (58); } /* * begin a comment line for the assembler * */ comment () { outbyte (';'); } /* * Emit user label prefix */ prefix () { } /* * print any assembler stuff needed after all code * */ trailer () { ol ("end"); } /* * function prologue */ prologue () { } /* * text (code) segment */ gtext () { ol ("cseg"); } /* * data segment */ gdata () { ol ("dseg"); } /* * Output the variable symbol at scptr as an extrn or a public */ ppubext(scptr) char *scptr; { if (cptr[STORAGE] == STATIC) return; ot (scptr[STORAGE] == EXTERN ? "extrn\t" : "public\t"); prefix (); outstr (scptr); nl(); } /* * Output the function symbol at scptr as an extrn or a public */ fpubext(scptr) char *scptr; { if (scptr[STORAGE] == STATIC) return; ot (scptr[OFFSET] == FUNCTION ? "public\t" : "extrn\t"); prefix (); outstr (scptr); nl (); } /* * Output a decimal number to the assembler file */ onum(num) int num; { outdec(num); /* pdp11 needs a "." here */ } /* * fetch a static memory cell into the primary register */ getmem (sym) char *sym; { if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) { ot ("lda\t"); outstr (sym + NAME); nl (); gcall ("?sxt"); } else { ot ("lhld\t"); outstr (sym + NAME); nl (); } } /* * fetch the address of the specified symbol into the primary register * */ getloc (sym) char *sym; { immed (); if (sym[STORAGE] == LSTATIC) { printlabel(glint(sym)); nl(); } else { outdec (glint(sym) - stkp); nl (); ol ("dad\tsp"); } } /* * store the primary register into the specified static memory cell * */ putmem (sym) char *sym; { if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) { ol ("mov\ta,l"); ot ("sta\t"); } else ot ("shld\t"); outstr (sym + NAME); nl (); } /* * store the specified object type in the primary register * at the address on the top of the stack * */ putstk (typeobj) char typeobj; { gpop (); if (typeobj == CCHAR) gcall ("?pchar"); else gcall ("?pint"); } /* * fetch the specified object type indirect through the primary * register into the primary register * */ indirect (typeobj) char typeobj; { if (typeobj == CCHAR) gcall ("?gchar"); else gcall ("?gint"); } /* * swap the primary and secondary registers * */ swap () { ol ("xchg"); } /* * print partial instruction to get an immediate value into * the primary register * */ immed () { ot ("lxi\th,"); } /* * push the primary register onto the stack * */ gpush () { ol ("push\th"); stkp = stkp - INTSIZE; } /* * pop the top of the stack into the secondary register * */ gpop () { ol ("pop\td"); stkp = stkp + INTSIZE; } /* * swap the primary register and the top of the stack * */ swapstk () { ol ("xthl"); } /* * call the specified subroutine name * */ gcall (sname) char *sname; { ot ("call\t"); outstr (sname); nl (); } /* * return from subroutine * */ gret () { ol ("ret"); } /* * perform subroutine call to value on top of stack * */ callstk () { immed (); outstr ("$+5"); nl (); swapstk (); ol ("pchl"); stkp = stkp + INTSIZE; } /* * jump to specified internal label number * */ jump (label) int label; { ot ("jmp\t"); printlabel (label); nl (); } /* * test the primary register and jump if false to label * */ testjump (label, ft) int label, ft; { ol ("mov\ta,h"); ol ("ora\tl"); if (ft) ot ("jnz\t"); else ot ("jz\t"); printlabel (label); nl (); } /* * print pseudo-op to define a byte * */ defbyte () { ot ("db\t"); } /* * print pseudo-op to define storage * */ defstorage () { ot ("ds\t"); } /* * print pseudo-op to define a word * */ defword () { ot ("dw\t"); } /* * modify the stack pointer to the new value indicated * */ modstk (newstkp) int newstkp; { int k; k = galign(newstkp - stkp); if (k == 0) return (newstkp); if (k > 0) { if (k < 7) { if (k & 1) { ol ("inx\tsp"); k--; } while (k) { ol ("pop\tb"); k = k - INTSIZE; } return (newstkp); } } else { if (k > -7) { if (k & 1) { ol ("dcx\tsp"); k++; } while (k) { ol ("push\tb"); k = k + INTSIZE; } return (newstkp); } } swap (); immed (); outdec (k); nl (); ol ("dad\tsp"); ol ("sphl"); swap (); return (newstkp); } /* * multiply the primary register by INTSIZE */ gaslint () { ol ("dad\th"); } /* * divide the primary register by INTSIZE */ gasrint() { gpush(); /* push primary in prep for gasr */ immed (); onum (1); nl (); gasr (); /* divide by two */ } /* * Case jump instruction */ gjcase() { ot ("jmp\t?case"); nl (); } /* * add the primary and secondary registers * if lval2 is int pointer and lval is not, scale lval */ gadd (lval,lval2) int *lval,*lval2; { gpop (); if (dbltest (lval2, lval)) { swap (); gaslint (); swap (); } ol ("dad\td"); } /* * subtract the primary register from the secondary * */ gsub () { gpop (); gcall ("?sub"); } /* * multiply the primary and secondary registers * (result in primary) * */ gmult () { gpop(); gcall ("?mul"); } /* * divide the secondary register by the primary * (quotient in primary, remainder in secondary) * */ gdiv () { gpop(); gcall ("?div"); } /* * compute the remainder (mod) of the secondary register * divided by the primary register * (remainder in primary, quotient in secondary) * */ gmod () { gdiv (); swap (); } /* * inclusive 'or' the primary and secondary registers * */ gor () { gpop(); gcall ("?or"); } /* * exclusive 'or' the primary and secondary registers * */ gxor () { gpop(); gcall ("?xor"); } /* * 'and' the primary and secondary registers * */ gand () { gpop(); gcall ("?and"); } /* * arithmetic shift right the secondary register the number of * times in the primary register * (results in primary register) * */ gasr () { gpop(); gcall ("?asr"); } /* * arithmetic shift left the secondary register the number of * times in the primary register * (results in primary register) * */ gasl () { gpop (); gcall ("?asl"); } /* * two's complement of primary register * */ gneg () { gcall ("?neg"); } /* * logical complement of primary register * */ glneg () { gcall ("?lneg"); } /* * one's complement of primary register * */ gcom () { gcall ("?com"); } /* * Convert primary value into logical value (0 if 0, 1 otherwise) * */ gbool () { gcall ("?bool"); } /* * increment the primary register by 1 if char, INTSIZE if * int */ ginc (lval) int lval[]; { ol ("inx\th"); if (lval[2] == CINT) ol ("inx\th"); } /* * decrement the primary register by one if char, INTSIZE if * int */ gdec (lval) int lval[]; { ol ("dcx\th"); if (lval[2] == CINT) ol("dcx\th"); } /* * following are the conditional operators. * they compare the secondary register against the primary register * and put a literl 1 in the primary if the condition is true, * otherwise they clear the primary register * */ /* * equal * */ geq () { gpop(); gcall ("?eq"); } /* * not equal * */ gne () { gpop(); gcall ("?ne"); } /* * less than (signed) * */ glt () { gpop(); gcall ("?lt"); } /* * less than or equal (signed) * */ gle () { gpop(); gcall ("?le"); } /* * greater than (signed) * */ ggt () { gpop(); gcall ("?gt"); } /* * greater than or equal (signed) * */ gge () { gpop(); gcall ("?ge"); } /* * less than (unsigned) * */ gult () { gpop(); gcall ("?ult"); } /* * less than or equal (unsigned) * */ gule () { gpop(); gcall ("?ule"); } /* * greater than (unsigned) * */ gugt () { gpop(); gcall ("?ugt"); } /* * greater than or equal (unsigned) * */ guge () { gpop(); gcall ("?uge"); } inclib() { #ifdef cpm return("B:"); #endif #ifdef unix return(INCDIR); #endif } /* Squirrel away argument count in a register that modstk doesn't touch. */ gnargs(d) int d; { ot ("mvi\ta,"); onum(d); nl (); } assemble(s) char *s; { #ifdef ASNM char buf[100]; strcpy(buf, ASNM); strcat(buf, " "); strcat(buf, s); buf[strlen(buf)-1] = 's'; return(system(buf)); #else return(0); #endif } link() { #ifdef LDNM fputs("I don't know how to link files yet\n", stderr); #else return(0); #endif } SHAR_EOF if test 9671 -ne "`wc -c < 'code8080.c'`" then echo shar: error transmitting "'code8080.c'" '(should have been 9671 characters)' fi fi echo shar: extracting "'codeas09.c'" '(9534 characters)' if test -f 'codeas09.c' then echo shar: will not over-write existing file "'codeas09.c'" else cat << \SHAR_EOF > 'codeas09.c' /* File codeas09.c: 2.2 (84/08/31,10:05:13) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* Define ASNM and LDNM to the names of the assembler and linker respectively */ /* * Some predefinitions: * * INTSIZE is the size of an integer in the target machine * BYTEOFF is the offset of an byte within an integer on the * target machine. (ie: 8080,pdp11 = 0, 6809 = 1, * 360 = 3) * This compiler assumes that an integer is the SAME length as * a pointer - in fact, the compiler uses INTSIZE for both. */ #define INTSIZE 2 #define BYTEOFF 1 /* * print all assembler info before any code is generated * */ header () { outstr("|\tSmall C MC6809\n|\tCoder (2.4,84/11/27)\n|"); FEvers(); nl (); ol (".globl\tsmul,sdiv,smod,asr,asl,neg,lneg,case"); ol (".globl\teq,ne,lt,le,gt,ge,ult,ule,ugt,uge,bool"); } nl () { outbyte (EOL); } initmac() { defmac("mc6809\t1"); defmac("mitas09\t1"); defmac("smallc\t1"); } galign(t) int t; { return (t); } /* * return size of an integer */ intsize() { return(INTSIZE); } /* * return offset of ls byte within word * (ie: 8080 & pdp11 is 0, 6809 is 1, 360 is 3) */ byteoff() { return(BYTEOFF); } /* * Output internal generated label prefix */ olprfix() { outstr("LL"); } /* * Output a label definition terminator */ col () { outstr ("=.\n"); } /* * begin a comment line for the assembler * */ comment () { outbyte ('|'); } /* * Output a prefix in front of user labels */ prefix () { outbyte ('_'); } /* * print any assembler stuff needed after all code * */ trailer () { ol (".end"); } /* * function prologue */ prologue () { } /* * text (code) segment */ gtext () { ol (".text"); } /* * data segment */ gdata () { ol (".data"); } /* * Output the variable symbol at scptr as an extrn or a public */ ppubext(scptr) char *scptr; { if (scptr[STORAGE] == STATIC) return; ot (".globl\t"); prefix (); outstr (scptr); nl(); } /* * Output the function symbol at scptr as an extrn or a public */ fpubext(scptr) char *scptr; { ppubext(scptr); } /* * Output a decimal number to the assembler file */ onum(num) int num; { outdec(num); /* pdp11 needs a "." here */ outbyte('.'); } /* * fetch a static memory cell into the primary register */ getmem (sym) char *sym; { if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) { ot ("ldb\t"); prefix (); outstr (sym + NAME); nl (); ot ("sex"); nl (); } else { ot ("ldd\t"); prefix (); outstr (sym + NAME); nl (); } } /* * fetch the address of the specified symbol into the primary register * */ getloc (sym) char *sym; { if (sym[STORAGE] == LSTATIC) { immed(); printlabel(glint(sym)); nl(); } else { ot ("leay\t"); onum (glint(sym) - stkp); outstr ("(s)\n\ttfr\ty,d\n"); } } /* * store the primary register into the specified static memory cell * */ putmem (sym) char *sym; { if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) { ot ("stb\t"); } else ot ("std\t"); prefix (); outstr (sym + NAME); nl (); } /* * store the specified object type in the primary register * at the address on the top of the stack * */ putstk (typeobj) char typeobj; { if (typeobj == CCHAR) ol ("stb\t@(s)++"); else ol ("std\t@(s)++"); stkp = stkp + INTSIZE; } /* * fetch the specified object type indirect through the primary * register into the primary register * */ indirect (typeobj) char typeobj; { ol("tfr\td,y"); if (typeobj == CCHAR) ol ("ldb\t(y)\n\tsex"); else ol ("ldd\t(y)"); } /* * swap the primary and secondary registers * */ swap () { ol ("exg\td,x"); } /* * print partial instruction to get an immediate value into * the primary register * */ immed () { ot ("ldd\t#"); } /* * push the primary register onto the stack * */ gpush () { ol ("pshs\td"); stkp = stkp - INTSIZE; } /* * pop the top of the stack into the secondary register * */ gpop () { ol ("puls\td"); stkp = stkp + INTSIZE; } /* * swap the primary register and the top of the stack * */ swapstk () { ol ("ldy\t(s)\nstd\t(s)\n\ttfr\ty,d"); } /* * call the specified subroutine name * */ gcall (sname) char *sname; { ot ("jsr\t"); if (*sname == '^') outstr (++sname); else { prefix (); outstr (sname); } nl (); } /* * return from subroutine * */ gret () { ol ("rts"); } /* * perform subroutine call to value on top of stack * */ callstk () { gpop(); ol ("jsr\t(x)"); } /* * jump to specified internal label number * */ jump (label) int label; { ot ("lbra\t"); printlabel (label); nl (); } /* * test the primary register and jump if false to label * */ testjump (label, ft) int label, ft; { ol ("cmpd\t#0"); if (ft) ot ("lbne\t"); else ot ("lbeq\t"); printlabel (label); nl (); } /* * print pseudo-op to define a byte * */ defbyte () { ot (".byte\t"); } /* * print pseudo-op to define storage * */ defstorage () { ot (".blkb\t"); } /* * print pseudo-op to define a word * */ defword () { ot (".word\t"); } /* * modify the stack pointer to the new value indicated * */ modstk (newstkp) int newstkp; { int k; k = galign(newstkp - stkp); if (k == 0) return (newstkp); ot ("leas\t"); onum (k); outstr ("(s)\n"); return (newstkp); } /* * multiply the primary register by INTSIZE */ gaslint () { ol ("aslb\n\trola"); } /* * divide the primary register by INTSIZE */ gasrint() { ol ("asra\n\trorb"); } /* * Case jump instruction */ gjcase() { ot ("jmp\tcase"); nl (); } /* * add the primary and secondary registers * if lval2 is int pointer and lval is int, scale lval */ gadd (lval, lval2) int *lval, *lval2; { if (dbltest (lval2, lval)) { ol ("asl\t1(s)\n\trol\t(s)"); } ol ("addd\t(s)++"); stkp = stkp + INTSIZE; } /* * subtract the primary register from the secondary * */ gsub () { ol ("subd\t(s)++\n\tcoma\n\tcomb\n\taddd\t#1"); stkp = stkp + INTSIZE; } /* * multiply the primary and secondary registers * (result in primary) * */ gmult () { gcall ("^smul"); stkp = stkp + INTSIZE; } /* * divide the secondary register by the primary * (quotient in primary, remainder in secondary) * */ gdiv () { gcall ("^sdiv"); stkp = stkp + INTSIZE; } /* * compute the remainder (mod) of the secondary register * divided by the primary register * (remainder in primary, quotient in secondary) * */ gmod () { gcall ("^smod"); stkp = stkp + INTSIZE; } /* * inclusive 'or' the primary and secondary registers * */ gor () { ol ("ora\t(s)+\n\torb\t(s)+"); stkp = stkp + INTSIZE; } /* * exclusive 'or' the primary and secondary registers * */ gxor () { ol ("eora\t(s)+\n\teorb\t(s)+"); stkp = stkp + INTSIZE; } /* * 'and' the primary and secondary registers * */ gand () { ol ("anda\t(s)+\n\tandb\t(s)+"); stkp = stkp + INTSIZE; } /* * arithmetic shift right the secondary register the number of * times in the primary register * (results in primary register) * */ gasr () { gcall ("^asr"); stkp = stkp + INTSIZE; } /* * arithmetic shift left the secondary register the number of * times in the primary register * (results in primary register) * */ gasl () { gcall ("^asl"); stkp = stkp + INTSIZE; } /* * two's complement of primary register * */ gneg () { gcall ("^neg"); } /* * logical complement of primary register * */ glneg () { gcall ("^lneg"); } /* * one's complement of primary register * */ gcom () { ol ("coma\n\tcomb"); } /* * convert primary register into logical value * */ gbool () { gcall ("^bool"); } /* * increment the primary register by 1 if char, INTSIZE if * int */ ginc (lval) int lval[]; { if (lval[2] == CINT) ol ("addd\t#2"); else ol ("addd\t#1"); } /* * decrement the primary register by one if char, INTSIZE if * int */ gdec (lval) int lval[]; { if (lval[2] == CINT) ol ("subd\t#2"); else ol ("subd\t#1"); } /* * following are the conditional operators. * they compare the secondary register against the primary register * and put a literl 1 in the primary if the condition is true, * otherwise they clear the primary register * */ /* * equal * */ geq () { gcall ("^eq"); stkp = stkp + INTSIZE; } /* * not equal * */ gne () { gcall ("^ne"); stkp = stkp + INTSIZE; } /* * less than (signed) * */ glt () { gcall ("^lt"); stkp = stkp + INTSIZE; } /* * less than or equal (signed) * */ gle () { gcall ("^le"); stkp = stkp + INTSIZE; } /* * greater than (signed) * */ ggt () { gcall ("^gt"); stkp = stkp + INTSIZE; } /* * greater than or equal (signed) * */ gge () { gcall ("^ge"); stkp = stkp + INTSIZE; } /* * less than (unsigned) * */ gult () { gcall ("^ult"); stkp = stkp + INTSIZE; } /* * less than or equal (unsigned) * */ gule () { gcall ("^ule"); stkp = stkp + INTSIZE; } /* * greater than (unsigned) * */ gugt () { gcall ("^ugt"); stkp = stkp + INTSIZE; } /* * greater than or equal (unsigned) * */ guge () { gcall ("^uge"); stkp = stkp + INTSIZE; } inclib() { #ifdef flex return("B."); #endif #ifdef unix return(INCDIR); #endif #ifdef cpm return("B:"); #endif } /* Squirrel away argument count in a register that modstk/getloc/stloc doesn't touch. */ gnargs(d) int d; { ot ("ldu\t#"); onum(d); nl (); } assemble(s) char *s; { #ifdef ASNM char buf[100]; strcpy(buf, ASNM); strcat(buf, " "); strcat(buf, s); buf[strlen(buf)-1] = 's'; return(system(buf)); #else return(0); #endif } link() { #ifdef LDNM fputs("I don't know how to link files yet\n", stderr); #else return(0); #endif } SHAR_EOF if test 9534 -ne "`wc -c < 'codeas09.c'`" then echo shar: error transmitting "'codeas09.c'" '(should have been 9534 characters)' fi fi echo shar: extracting "'codem68k.c'" '(11259 characters)' if test -f 'codem68k.c' then echo shar: will not over-write existing file "'codem68k.c'" else cat << \SHAR_EOF > 'codem68k.c' /* File codem68k.c: 1.2 (84/11/28,10:15:09) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" #ifdef unix #ifdef m68k #define ASNM "as -o " #define LDNM "ld -o a.out /lib/crt0.o " #endif #ifdef pyr #define ASNM "/u1/cx/bin/m68kas -o " #define LDNM "/u1/cx/bin/m68kld -o a.out /u1/cx/lib/m68kcrt0.o " #endif #endif int needr0; int needh; /* * Some predefinitions: * * INTSIZE is the size of an integer in the target machine * BYTEOFF is the offset of an byte within an integer on the * target machine. (ie: 8080,pdp11 = 0, 6809 = 1, * 360 = 3) * This compiler assumes that an integer is the SAME length as * a pointer - in fact, the compiler uses INTSIZE for both. */ #define INTSIZE 4 #define BYTEOFF 3 /* * print all assembler info before any code is generated * */ header () { outstr("#\tSmall C M68000\n#\tCoder (1.2,84/11/28)\n#"); FEvers(); nl (); ol ("global\tTlneg"); ol ("global\tTcase"); ol ("global\tTeq"); ol ("global\tTne"); ol ("global\tTlt"); ol ("global\tTle"); ol ("global\tTgt"); ol ("global\tTge"); ol ("global\tTult"); ol ("global\tTule"); ol ("global\tTugt"); ol ("global\tTuge"); ol ("global\tTbool"); ol ("global\tTmult"); ol ("global\tTdiv"); ol ("global\tTmod"); } nl() { if (needh) { ol ("word\t0"); needh = 0; } if (needr0) { needr0 = 0; outstr(",%d0"); } outbyte(EOL); } initmac() { defmac("m68k\t1"); defmac("unix\t1"); defmac("smallc\t1"); } galign(t) int t; { int sign; if (t < 0) { sign = 1; t = -t; } else sign = 0; t = (t + INTSIZE - 1) & ~(INTSIZE - 1); t = sign? -t: t; return (t); } /* * return size of an integer */ intsize() { return(INTSIZE); } /* * return offset of ls byte within word * (ie: 8080 & pdp11 is 0, 6809 is 1, 360 is 3) */ byteoff() { return(BYTEOFF); } /* * Output internal generated label prefix */ olprfix() { outstr("LL"); } /* * Output a label definition terminator */ col () { outstr (":\n"); } /* * begin a comment line for the assembler * */ comment () { outbyte ('#'); } /* * Output a prefix in front of user labels */ prefix () { /* outbyte ('_'); */ } /* * print any assembler stuff needed after all code * */ trailer () { } /* * function prologue */ prologue () { /* this is where we'd put splimit stuff */ } /* * text (code) segment */ gtext () { ol ("text"); } /* * data segment */ gdata () { ol ("data"); } /* * Output the variable symbol at scptr as an extrn or a public */ ppubext(scptr) char *scptr; { if (scptr[STORAGE] == STATIC) return; ot ("global\t"); prefix (); outstr (scptr); nl(); } /* * Output the function symbol at scptr as an extrn or a public */ fpubext(scptr) char *scptr; { ppubext(scptr); } /* * Output a decimal number to the assembler file */ onum(num) int num; { outdec(num); /* pdp11 needs a "." here */ } /* * fetch a static memory cell into the primary register */ getmem (sym) char *sym; { int ischr; if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) { ischr = 1; ot ("mov.b\t"); prefix (); outstr (sym + NAME); } else { ischr = 0; ot ("mov.l\t"); prefix (); outstr (sym + NAME); } outstr(",%d0\n"); if (ischr) ol ("ext.b\t%d0"); } /* * fetch the address of the specified symbol into the primary register * */ getloc (sym) char *sym; { if (sym[STORAGE] == LSTATIC) { immed(); printlabel(glint(sym)); nl(); } else { ot ("lea.l\t"); onum (glint(sym) - stkp); outstr (",%a0\n"); ol ("mov.l\t%a0,%d0"); } } /* * store the primary register into the specified static memory cell * */ putmem (sym) char *sym; { if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) { ot ("mov.b\t%d0,"); } else ot ("mov.l\t%d0,"); prefix (); outstr (sym + NAME); nl (); } /* * store the specified object type in the primary register * at the address on the top of the stack * */ putstk (typeobj) char typeobj; { ol ("mov.l\t(%sp)+,%a0"); if (typeobj == CCHAR) ol ("mov.b\t%d0,(%a0)"); else ol ("mov.l\t%d0,(%a0)"); stkp = stkp + INTSIZE; } /* * fetch the specified object type indirect through the primary * register into the primary register * */ indirect (typeobj) char typeobj; { ol ("mov.l\t%d0,%a0"); if (typeobj == CCHAR) ol ("mov.b\t(%a0),%d0"); else ol ("mov.l\t(%a0),%d0"); } /* * swap the primary and secondary registers * */ swap () { ol ("mov.l\t%d0,%d2\n\tmov.l\t%d1,%d0\n\tmov.l\t%d2,%d1"); } /* * print partial instruction to get an immediate value into * the primary register * */ immed () { ot ("mov.l\t&"); needr0 = 1; } /* * push the primary register onto the stack * */ gpush () { ol ("mov.l\t%d0,-(%sp)"); stkp = stkp - INTSIZE; } /* * pop the top of the stack into the secondary register * */ gpop () { ol ("mov.l\t(%sp)+,%d1"); stkp = stkp + INTSIZE; } /* * swap the primary register and the top of the stack * */ swapstk () { ol ("mov.l\t(%sp)+,%d2\nmov.l\t%d0,-(%sp)\nmov.l\t%d2,%d0"); } /* * call the specified subroutine name * */ gcall (sname) char *sname; { if (*sname == '^') { ot ("jsr\tT"); outstr (++sname); } else { ot ("jsr\t"); prefix (); outstr (sname); } nl (); } /* * return from subroutine * */ gret () { ol ("rts"); } /* * perform subroutine call to value on top of stack * */ callstk () { ol ("jsr\t(%sp)+"); stkp = stkp + INTSIZE; } /* * jump to specified internal label number * */ jump (label) int label; { ot ("jmp\t"); printlabel (label); nl (); } /* * test the primary register and jump if false to label * */ testjump (label, ft) int label, ft; { ol ("cmp.l\t%d0,&0"); if (ft) ot ("beq\t"); else ot ("bne\t"); printlabel (label); nl (); } /* * print pseudo-op to define a byte * */ defbyte () { ot ("byte\t"); } /* * print pseudo-op to define storage * */ defstorage () { ot ("space\t"); } /* * print pseudo-op to define a word * */ defword () { ot ("long\t"); } /* * modify the stack pointer to the new value indicated * */ modstk (newstkp) int newstkp; { int k; k = newstkp - stkp; if (k % INTSIZE) error("Bad stack alignment (compiler error)"); if (k == 0) return (newstkp); ot ("add.l\t&"); onum (k); outstr (",sp"); nl(); return (newstkp); } /* * multiply the primary register by INTSIZE */ gaslint () { ol ("asl.l\t&2,%d0"); } /* * divide the primary register by INTSIZE */ gasrint() { ol ("asr.l\t&2,%d0"); } /* * Case jump instruction */ gjcase() { gcall ("^case"); } /* * add the primary and secondary registers * if lval2 is int pointer and lval is int, scale lval */ gadd (lval, lval2) int *lval, *lval2; { if (dbltest (lval2, lval)) { ol ("asl.l\t&2,(%sp)"); } ol ("add.l\t(%sp)+,%d0"); stkp = stkp + INTSIZE; } /* * subtract the primary register from the secondary * */ gsub () { ol ("mov.l\t(%sp)+,%d2"); ol ("sub.l\t%d0,%d2"); ol ("mov.l\t%d2,%d0"); stkp = stkp + INTSIZE; } /* * multiply the primary and secondary registers * (result in primary) * */ gmult () { gcall ("^mult"); stkp = stkp + INTSIZE; } /* * divide the secondary register by the primary * (quotient in primary, remainder in secondary) * */ gdiv () { gcall ("^div"); stkp = stkp + INTSIZE; } /* * compute the remainder (mod) of the secondary register * divided by the primary register * (remainder in primary, quotient in secondary) * */ gmod () { gcall ("^mod"); stkp = stkp + INTSIZE; } /* * inclusive 'or' the primary and secondary registers * */ gor () { ol ("or.l\t(%sp)+,%d0"); stkp = stkp + INTSIZE; } /* * exclusive 'or' the primary and secondary registers * */ gxor () { ol ("mov.l\t(%sp)+,%d1"); ol ("eor.l\t%d1,%d0"); stkp = stkp + INTSIZE; } /* * 'and' the primary and secondary registers * */ gand () { ol ("and.l\t(%sp)+,%d0"); stkp = stkp + INTSIZE; } /* * arithmetic shift right the secondary register the number of * times in the primary register * (results in primary register) * */ gasr () { ol ("mov.l\t(%sp)+,%d1"); ol ("asr.l\t%d0,%d1"); ol ("mov.l\t%d1,%d0"); stkp = stkp + INTSIZE; } /* * arithmetic shift left the secondary register the number of * times in the primary register * (results in primary register) * */ gasl () { ol ("mov.l\t(%sp)+,%d1"); ol ("asl.l\t%d0,%d1"); ol ("mov.l\t%d1,%d0"); stkp = stkp + INTSIZE; } /* * two's complement of primary register * */ gneg () { ol ("neg.l\t%d0"); } /* * logical complement of primary register * */ glneg () { gcall ("^lneg"); } /* * one's complement of primary register * */ gcom () { ol ("not\t%d0"); } /* * convert primary register into logical value * */ gbool () { gcall ("^bool"); } /* * increment the primary register by 1 if char, INTSIZE if * int */ ginc (lval) int lval[]; { if (lval[2] == CINT) ol ("addq.l\t&4,%d0"); else ol ("addq.l\t&1,%d0"); } /* * decrement the primary register by one if char, INTSIZE if * int */ gdec (lval) int lval[]; { if (lval[2] == CINT) ol ("subq.l\t&4,%d0"); else ol ("subq.l\t&1,%d0"); } /* * following are the conditional operators. * they compare the secondary register against the primary register * and put a literl 1 in the primary if the condition is true, * otherwise they clear the primary register * */ /* * equal * */ geq () { gcall ("^eq"); stkp = stkp + INTSIZE; } /* * not equal * */ gne () { gcall ("^ne"); stkp = stkp + INTSIZE; } /* * less than (signed) * */ glt () { gcall ("^lt"); stkp = stkp + INTSIZE; } /* * less than or equal (signed) * */ gle () { gcall ("^le"); stkp = stkp + INTSIZE; } /* * greater than (signed) * */ ggt () { gcall ("^gt"); stkp = stkp + INTSIZE; } /* * greater than or equal (signed) * */ gge () { gcall ("^ge"); stkp = stkp + INTSIZE; } /* * less than (unsigned) * */ gult () { gcall ("^ult"); stkp = stkp + INTSIZE; } /* * less than or equal (unsigned) * */ gule () { gcall ("^ule"); stkp = stkp + INTSIZE; } /* * greater than (unsigned) * */ gugt () { gcall ("^ugt"); stkp = stkp + INTSIZE; } /* * greater than or equal (unsigned) * */ guge () { gcall ("^uge"); stkp = stkp + INTSIZE; } inclib() { #ifdef flex return("B."); #endif #ifdef unix return(INCDIR); #endif #ifdef cpm return("B:"); #endif } /* Squirrel away argument count in a register that modstk/getloc/stloc doesn't touch. */ gnargs(d) int d; { ot ("mov.l\t&"); onum(d); outstr(",%d3\n"); } #ifndef NOASLD char assems[400]; int assinit; assemble(s) char *s; { #ifdef ASNM char cmd[100],buf[100]; char *p; int ex, rc, delaft; #ifdef unix p = strrchr(s, '/'); if (p) strcat(buf, p+1); else #endif strcat(buf, s); p = buf + strlen(buf) - 1; rc = typeof(s); delaft = (rc == 'c'); if (rc == 'c' || rc == 's') { ex = 0; *p = 'o'; } else ex = 1; if (!assinit) { strcat(assems, LDNM); assinit = 1; } strcat(assems, buf); strcat(assems, " "); if (ex) return(0); strcpy(cmd, ASNM); strcat(cmd, buf); strcat(cmd, " "); *p = 's'; strcat(cmd, buf); rc = system(cmd); if (!rc && delaft) unlink(buf); return(rc); #else return(0); #endif } link() { #ifdef LDNM #ifdef unix #ifdef m68k strcat(assems, " -lc"); #else strcat(assems, " /u1/cx/lib/libc.a"); #endif #endif return(system(assems)); #else return(0); #endif } #endif SHAR_EOF if test 11259 -ne "`wc -c < 'codem68k.c'`" then echo shar: error transmitting "'codem68k.c'" '(should have been 11259 characters)' fi fi echo shar: extracting "'codevax.c'" '(10274 characters)' if test -f 'codevax.c' then echo shar: will not over-write existing file "'codevax.c'" else cat << \SHAR_EOF > 'codevax.c' /* File codevax.c: 2.2 (84/08/31,10:05:16) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" #ifdef vax #define ASNM "/bin/as" #define LDNM "/bin/ld" #endif /* Define ASNM and LDNM to the names of the assembler and linker respectively */ int needr0; int needh; /* * Some predefinitions: * * INTSIZE is the size of an integer in the target machine * BYTEOFF is the offset of an byte within an integer on the * target machine. (ie: 8080,pdp11 = 0, 6809 = 1, * 360 = 3) * This compiler assumes that an integer is the SAME length as * a pointer - in fact, the compiler uses INTSIZE for both. */ #define INTSIZE 4 #define BYTEOFF 0 /* * print all assembler info before any code is generated * */ header () { outstr("#\tSmall C VAX\n#\tCoder (2.4,84/11/27)\n#"); FEvers(); nl (); ol (".globl\tlneg"); ol (".globl\tcase"); ol (".globl\teq"); ol (".globl\tne"); ol (".globl\tlt"); ol (".globl\tle"); ol (".globl\tgt"); ol (".globl\tge"); ol (".globl\tult"); ol (".globl\tule"); ol (".globl\tugt"); ol (".globl\tuge"); ol (".globl\tbool"); } nl() { if (needh) { ol (".word\t0"); needh = 0; } if (needr0) { needr0 = 0; outstr(",r0"); } outbyte(EOL); } initmac() { defmac("vax\t1"); defmac("unix\t1"); defmac("smallc\t1"); } galign(t) int t; { int sign; if (t < 0) { sign = 1; t = -t; } else sign = 0; t = (t + INTSIZE - 1) & ~(INTSIZE - 1); t = sign? -t: t; return (t); } /* * return size of an integer */ intsize() { return(INTSIZE); } /* * return offset of ls byte within word * (ie: 8080 & pdp11 is 0, 6809 is 1, 360 is 3) */ byteoff() { return(BYTEOFF); } /* * Output internal generated label prefix */ olprfix() { outstr("LL"); } /* * Output a label definition terminator */ col () { outstr (":\n"); } /* * begin a comment line for the assembler * */ comment () { outbyte ('#'); } /* * Output a prefix in front of user labels */ prefix () { outbyte ('_'); } /* * print any assembler stuff needed after all code * */ trailer () { } /* * function prologue */ prologue () { ol (".align\t1"); } /* * text (code) segment */ gtext () { ol (".text"); } /* * data segment */ gdata () { ol (".data"); } /* * Output the variable symbol at scptr as an extrn or a public */ ppubext(scptr) char *scptr; { if (scptr[STORAGE] == STATIC) return; ot (".globl\t"); prefix (); outstr (scptr); nl(); } /* * Output the function symbol at scptr as an extrn or a public */ fpubext(scptr) char *scptr; { ppubext(scptr); } /* * Output a decimal number to the assembler file */ onum(num) int num; { outdec(num); /* pdp11 needs a "." here */ } /* * fetch a static memory cell into the primary register */ getmem (sym) char *sym; { if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) { ot ("cvtbl\t"); prefix (); outstr (sym + NAME); } else { ot ("movl\t"); prefix (); outstr (sym + NAME); } outstr(",r0\n"); } /* * fetch the address of the specified symbol into the primary register * */ getloc (sym) char *sym; { if (sym[STORAGE] == LSTATIC) { immed(); printlabel(glint(sym)); nl(); } else { ot ("moval\t"); onum (glint(sym) - stkp); outstr ("(sp),r0\n"); } } /* * store the primary register into the specified static memory cell * */ putmem (sym) char *sym; { if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) { ot ("cvtlb\tr0,"); } else ot ("movl\tr0,"); prefix (); outstr (sym + NAME); nl (); } /* * store the specified object type in the primary register * at the address on the top of the stack * */ putstk (typeobj) char typeobj; { if (typeobj == CCHAR) ol ("cvtlb\tr0,*(sp)+"); else ol ("movl\tr0,*(sp)+"); stkp = stkp + INTSIZE; } /* * fetch the specified object type indirect through the primary * register into the primary register * */ indirect (typeobj) char typeobj; { if (typeobj == CCHAR) ol ("cvtbl\t(r0),r0"); else ol ("movl\t(r0),r0"); } /* * swap the primary and secondary registers * */ swap () { ol ("movl\tr0,r2\n\tmovl\tr1,r0\n\tmovl\tr2,r1"); } /* * print partial instruction to get an immediate value into * the primary register * */ immed () { ot ("movl\t$"); needr0 = 1; } /* * push the primary register onto the stack * */ gpush () { ol ("pushl\tr0"); stkp = stkp - INTSIZE; } /* * pop the top of the stack into the secondary register * */ gpop () { ol ("movl\t(sp)+,r1"); stkp = stkp + INTSIZE; } /* * swap the primary register and the top of the stack * */ swapstk () { ol ("popl\tr2\npushl\tr0\nmovl\tr2,r0"); } /* * call the specified subroutine name * */ gcall (sname) char *sname; { if (*sname == '^') { ot ("jsb\t"); outstr (++sname); } else { ot ("jsb\t"); prefix (); outstr (sname); } nl (); } /* * return from subroutine * */ gret () { ol ("rsb"); } /* * perform subroutine call to value on top of stack * */ callstk () { ol ("jsb\t(sp)+"); stkp = stkp + INTSIZE; } /* * jump to specified internal label number * */ jump (label) int label; { ot ("jmp\t"); printlabel (label); nl (); } /* * test the primary register and jump if false to label * */ testjump (label, ft) int label, ft; { ol ("cmpl\tr0,$0"); if (ft) ot ("jneq\t"); else ot ("jeql\t"); printlabel (label); nl (); } /* * print pseudo-op to define a byte * */ defbyte () { ot (".byte\t"); } /* * print pseudo-op to define storage * */ defstorage () { ot (".space\t"); } /* * print pseudo-op to define a word * */ defword () { ot (".long\t"); } /* * modify the stack pointer to the new value indicated * */ modstk (newstkp) int newstkp; { int k; k = newstkp - stkp; if (k % INTSIZE) error("Bad stack alignment (compiler error)"); if (k == 0) return (newstkp); ot ("addl2\t$"); onum (k); outstr (",sp"); nl(); return (newstkp); } /* * multiply the primary register by INTSIZE */ gaslint () { ol ("ashl\t$2,r0,r0"); } /* * divide the primary register by INTSIZE */ gasrint() { ol ("ashl\t$-2,r0,r0"); } /* * Case jump instruction */ gjcase() { ot ("jmp\tcase"); nl (); } /* * add the primary and secondary registers * if lval2 is int pointer and lval is int, scale lval */ gadd (lval, lval2) int *lval, *lval2; { if (dbltest (lval2, lval)) { ol ("ashl\t$2,(sp),(sp)"); } ol ("addl2\t(sp)+,r0"); stkp = stkp + INTSIZE; } /* * subtract the primary register from the secondary * */ gsub () { ol ("subl3\tr0,(sp)+,r0"); stkp = stkp + INTSIZE; } /* * multiply the primary and secondary registers * (result in primary) * */ gmult () { ol ("mull2\t(sp)+,r0"); stkp = stkp + INTSIZE; } /* * divide the secondary register by the primary * (quotient in primary, remainder in secondary) * */ gdiv () { ol ("divl3\tr0,(sp)+,r0"); stkp = stkp + INTSIZE; } /* * compute the remainder (mod) of the secondary register * divided by the primary register * (remainder in primary, quotient in secondary) * */ gmod () { ol ("movl\t(sp)+,r2\n\tmovl\t$0,r3\nediv\tr0,r2,r1,r0"); stkp = stkp + INTSIZE; } /* * inclusive 'or' the primary and secondary registers * */ gor () { ol ("bisl2\t(sp)+,r0"); stkp = stkp + INTSIZE; } /* * exclusive 'or' the primary and secondary registers * */ gxor () { ol ("xorl2\t(sp)+,r0"); stkp = stkp + INTSIZE; } /* * 'and' the primary and secondary registers * */ gand () { ol ("mcoml\t(sp)+,r1\n\tbicl2\tr1,r0"); stkp = stkp + INTSIZE; } /* * arithmetic shift right the secondary register the number of * times in the primary register * (results in primary register) * */ gasr () { ol("mnegl\tr0,r0\n\tashl\tr0,(sp)+,r0"); stkp = stkp + INTSIZE; } /* * arithmetic shift left the secondary register the number of * times in the primary register * (results in primary register) * */ gasl () { ol ("ashl\tr0,(sp)+,r0"); stkp = stkp + INTSIZE; } /* * two's complement of primary register * */ gneg () { ol ("mnegl\tr0,r0"); } /* * logical complement of primary register * */ glneg () { gcall ("^lneg"); } /* * one's complement of primary register * */ gcom () { ol ("mcoml\tr0,r0"); } /* * convert primary register into logical value * */ gbool () { gcall ("^bool"); } /* * increment the primary register by 1 if char, INTSIZE if * int */ ginc (lval) int lval[]; { if (lval[2] == CINT) ol ("addl2\t$4,r0"); else ol ("incl\tr0"); } /* * decrement the primary register by one if char, INTSIZE if * int */ gdec (lval) int lval[]; { if (lval[2] == CINT) ol ("subl2\t$4,r0"); else ol ("decl\tr0"); } /* * following are the conditional operators. * they compare the secondary register against the primary register * and put a literl 1 in the primary if the condition is true, * otherwise they clear the primary register * */ /* * equal * */ geq () { gcall ("^eq"); stkp = stkp + INTSIZE; } /* * not equal * */ gne () { gcall ("^ne"); stkp = stkp + INTSIZE; } /* * less than (signed) * */ glt () { gcall ("^lt"); stkp = stkp + INTSIZE; } /* * less than or equal (signed) * */ gle () { gcall ("^le"); stkp = stkp + INTSIZE; } /* * greater than (signed) * */ ggt () { gcall ("^gt"); stkp = stkp + INTSIZE; } /* * greater than or equal (signed) * */ gge () { gcall ("^ge"); stkp = stkp + INTSIZE; } /* * less than (unsigned) * */ gult () { gcall ("^ult"); stkp = stkp + INTSIZE; } /* * less than or equal (unsigned) * */ gule () { gcall ("^ule"); stkp = stkp + INTSIZE; } /* * greater than (unsigned) * */ gugt () { gcall ("^ugt"); stkp = stkp + INTSIZE; } /* * greater than or equal (unsigned) * */ guge () { gcall ("^uge"); stkp = stkp + INTSIZE; } /* Squirrel away argument count in a register that modstk doesn't touch. */ gnargs(d) int d; { ot ("movl\t$"); onum(d); outstr (",r6\n"); } inclib() { #ifdef flex return("B."); #endif #ifdef unix return(INCDIR); #endif #ifdef cpm return("B:"); #endif } assemble(s) char *s; { #ifdef ASNM char buf[100]; strcpy(buf, ASNM); strcat(buf, " -o "); strcat(buf, s); buf[strlen(buf)-1] = 'o'; strcat(buf, " "); strcat(buf, s); buf[strlen(buf)-1] = 's'; return(system(buf)); #else return(0); #endif } link() { #ifdef LDNM fputs("I don't know how to link files yet\n", stderr); #else return(0); #endif } SHAR_EOF if test 10274 -ne "`wc -c < 'codevax.c'`" then echo shar: error transmitting "'codevax.c'" '(should have been 10274 characters)' fi fi echo shar: extracting "'data.c'" '(722 characters)' if test -f 'data.c' then echo shar: will not over-write existing file "'data.c'" else cat << \SHAR_EOF > 'data.c' /* File data.c: 2.2 (84/11/27,16:26:13) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" /* storage words */ char symtab[SYMTBSZ]; char *glbptr, *rglbptr, *locptr; int ws[WSTABSZ]; int *wsptr; int swstcase[SWSTSZ]; int swstlab[SWSTSZ]; int swstp; char litq[LITABSZ]; int litptr; char macq[MACQSIZE]; int macptr; char line[LINESIZE]; char mline[LINESIZE]; int lptr, mptr; /* miscellaneous storage */ int nxtlab, litlab, stkp, argstk, ncmp, errcnt, glbflag, ctext, cmode, lastst; FILE *input, *input2, *output; FILE *inclstk[INCLSIZ]; int inclsp; char fname[20]; char quote[2]; char *cptr; int *iptr; int fexitlab; int iflevel, skiplevel; int errfile; int sflag; int cflag; int errs; int aflag; SHAR_EOF if test 722 -ne "`wc -c < 'data.c'`" then echo shar: error transmitting "'data.c'" '(should have been 722 characters)' fi fi echo shar: extracting "'data.h'" '(807 characters)' if test -f 'data.h' then echo shar: will not over-write existing file "'data.h'" else cat << \SHAR_EOF > 'data.h' /* File data.h: 2.2 (84/11/27,16:26:11) */ /* storage words */ extern char symtab[]; extern char *glbptr, *rglbptr, *locptr; extern int ws[]; extern int *wsptr; extern int swstcase[]; extern int swstlab[]; extern int swstp; extern char litq[]; extern int litptr; extern char macq[]; extern int macptr; extern char line[]; extern char mline[]; extern int lptr, mptr; /* miscellaneous storage */ extern int nxtlab, litlab, stkp, argstk, ncmp, errcnt, glbflag, ctext, cmode, lastst; extern FILE *input, *input2, *output; extern FILE *inclstk[]; extern int inclsp; extern char fname[]; extern char quote[]; extern char *cptr; extern int *iptr; extern int fexitlab; extern int iflevel, skiplevel; extern int errfile; extern int sflag; extern int cflag; extern int errs; extern int aflag; SHAR_EOF if test 807 -ne "`wc -c < 'data.h'`" then echo shar: error transmitting "'data.h'" '(should have been 807 characters)' fi fi exit 0 # End of shell archive
sources-request@panda.UUCP (05/20/86)
Mod.sources: Volume 5, Issue 8 Submitted by: genrad!linus!mnetor!clewis (Chris Lewis) #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # defs.h # error.c # expr.c # function.c # gen.c # io.c # lex.c # main.c # preproc.c # primary.c # stmt.c # sym.c # while.c # This archive created: Sun May 18 18:17:13 1986 export PATH; PATH=/bin:$PATH echo shar: extracting "'defs.h'" '(1982 characters)' if test -f 'defs.h' then echo shar: will not over-write existing file "'defs.h'" else cat << \SHAR_EOF > 'defs.h' /* File defs.h: 2.1 (83/03/21,02:07:20) */ #define FOREVER for(;;) #define FALSE 0 #define TRUE 1 #define NO 0 #define YES 1 /* miscellaneous */ #define EOS 0 #define EOL 10 #define BKSP 8 #define CR 13 #define FFEED 12 #define TAB 9 /* symbol table parameters */ #define SYMSIZ 14 #define SYMTBSZ 2800 #define NUMGLBS 150 #define STARTGLB symtab #define ENDGLB (STARTGLB+NUMGLBS*SYMSIZ) #define STARTLOC (ENDGLB+SYMSIZ) #define ENDLOC (symtab+SYMTBSZ-SYMSIZ) /* symbol table entry format */ #define NAME 0 #define IDENT 9 #define TYPE 10 #define STORAGE 11 #define OFFSET 12 /* system-wide name size (for symbols) */ #define NAMESIZE 9 #define NAMEMAX 8 /* possible entries for "ident" */ #define VARIABLE 1 #define ARRAY 2 #define POINTER 3 #define FUNCTION 4 /* possible entries for "type" */ #define CCHAR 1 #define CINT 2 /* possible entries for storage */ #define PUBLIC 1 #define AUTO 2 #define EXTERN 3 #define STATIC 4 #define LSTATIC 5 #define DEFAUTO 6 /* "do"/"for"/"while"/"switch" statement stack */ #define WSTABSZ 100 #define WSSIZ 7 #define WSMAX ws+WSTABSZ-WSSIZ /* entry offsets in "do"/"for"/"while"/"switch" stack */ #define WSSYM 0 #define WSSP 1 #define WSTYP 2 #define WSCASEP 3 #define WSTEST 3 #define WSINCR 4 #define WSDEF 4 #define WSBODY 5 #define WSTAB 5 #define WSEXIT 6 /* possible entries for "wstyp" */ #define WSWHILE 0 #define WSFOR 1 #define WSDO 2 #define WSSWITCH 3 /* "switch" label stack */ #define SWSTSZ 100 /* literal pool */ #define LITABSZ 2000 #define LITMAX LITABSZ-1 /* input line */ #define LINESIZE 150 #define LINEMAX (LINESIZE-1) #define MPMAX LINEMAX /* macro (define) pool */ #define MACQSIZE 1000 #define MACMAX (MACQSIZE-1) /* "include" stack */ #define INCLSIZ 3 /* statement types (tokens) */ #define STIF 1 #define STWHILE 2 #define STRETURN 3 #define STBREAK 4 #define STCONT 5 #define STASM 6 #define STEXP 7 #define STDO 8 #define STFOR 9 #define STSWITCH 10 #define DEFLIB inclib() SHAR_EOF if test 1982 -ne "`wc -c < 'defs.h'`" then echo shar: error transmitting "'defs.h'" '(should have been 1982 characters)' fi fi echo shar: extracting "'error.c'" '(552 characters)' if test -f 'error.c' then echo shar: will not over-write existing file "'error.c'" else cat << \SHAR_EOF > 'error.c' /* File error.c: 2.1 (83/03/20,16:02:00) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" error (ptr) char ptr[]; { FILE *tempfile; tempfile = output; output = stdout; doerror(ptr); output = tempfile; doerror(ptr); errcnt++; } doerror(ptr) char *ptr; { int k; comment (); outstr (line); nl (); comment (); k = 0; while (k < lptr) { if (line[k] == 9) tab (); else outbyte (' '); k++; } outbyte ('^'); nl (); comment (); outstr ("****** "); outstr (ptr); outstr (" ******"); nl (); } SHAR_EOF if test 552 -ne "`wc -c < 'error.c'`" then echo shar: error transmitting "'error.c'" '(should have been 552 characters)' fi fi echo shar: extracting "'expr.c'" '(10028 characters)' if test -f 'expr.c' then echo shar: will not over-write existing file "'expr.c'" else cat << \SHAR_EOF > 'expr.c' /* File expr.c: 2.2 (83/06/21,11:24:26) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * lval[0] - symbol table address, else 0 for constant * lval[1] - type indirect object to fetch, else 0 for static object * lval[2] - type pointer or array, else 0 */ expression (comma) int comma; { int lval[3]; do { if (heir1 (lval)) rvalue (lval); if (!comma) return; } while (match (",")); } heir1 (lval) int lval[]; { int k, lval2[3]; char fc; k = heir1a (lval); if (match ("=")) { if (k == 0) { needlval (); return (0); } if (lval[1]) gpush (); if (heir1 (lval2)) rvalue (lval2); store (lval); return (0); } else { fc = ch(); if (match ("-=") || match ("+=") || match ("*=") || match ("/=") || match ("%=") || match (">>=") || match ("<<=") || match ("&=") || match ("^=") || match ("|=")) { if (k == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); gpush (); if (heir1 (lval2)) rvalue (lval2); switch (fc) { case '-': { if (dbltest(lval,lval2)) gaslint(); gsub(); result (lval, lval2); break; } case '+': { if (dbltest(lval,lval2)) gaslint(); gadd (lval,lval2); result(lval,lval2); break; } case '*': gmult (); break; case '/': gdiv (); break; case '%': gmod (); break; case '>': gasr (); break; case '<': gasl (); break; case '&': gand (); break; case '^': gxor (); break; case '|': gor (); break; } store (lval); return (0); } else return (k); } } heir1a (lval) int lval[]; { int k, lval2[3], lab1, lab2; k = heir1b (lval); blanks (); if (ch () != '?') return (k); if (k) rvalue (lval); FOREVER if (match ("?")) { testjump (lab1 = getlabel (), FALSE); if (heir1b (lval2)) rvalue (lval2); jump (lab2 = getlabel ()); printlabel (lab1); col (); nl (); blanks (); if (!match (":")) { error ("missing colon"); return (0); } if (heir1b (lval2)) rvalue (lval2); printlabel (lab2); col (); nl (); } else return (0); } heir1b (lval) int lval[]; { int k, lval2[3], lab; k = heir1c (lval); blanks (); if (!sstreq ("||")) return (k); if (k) rvalue (lval); FOREVER if (match ("||")) { testjump (lab = getlabel (), TRUE); if (heir1c (lval2)) rvalue (lval2); printlabel (lab); col (); nl (); gbool(); } else return (0); } heir1c (lval) int lval[]; { int k, lval2[3], lab; k = heir2 (lval); blanks (); if (!sstreq ("&&")) return (k); if (k) rvalue (lval); FOREVER if (match ("&&")) { testjump (lab = getlabel (), FALSE); if (heir2 (lval2)) rvalue (lval2); printlabel (lab); col (); nl (); gbool(); } else return (0); } heir2 (lval) int lval[]; { int k, lval2[3]; k = heir3 (lval); blanks (); if ((ch() != '|') | (nch() == '|') | (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if ((ch() == '|') & (nch() != '|') & (nch() != '=')) { inbyte (); gpush (); if (heir3 (lval2)) rvalue (lval2); gor (); blanks(); } else return (0); } } heir3 (lval) int lval[]; { int k, lval2[3]; k = heir4 (lval); blanks (); if ((ch () != '^') | (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if ((ch() == '^') & (nch() != '=')){ inbyte (); gpush (); if (heir4 (lval2)) rvalue (lval2); gxor (); blanks(); } else return (0); } } heir4 (lval) int lval[]; { int k, lval2[3]; k = heir5 (lval); blanks (); if ((ch() != '&') | (nch() == '|') | (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if ((ch() == '&') & (nch() != '&') & (nch() != '=')) { inbyte (); gpush (); if (heir5 (lval2)) rvalue (lval2); gand (); blanks(); } else return (0); } } heir5 (lval) int lval[]; { int k, lval2[3]; k = heir6 (lval); blanks (); if (!sstreq ("==") & !sstreq ("!=")) return (k); if (k) rvalue (lval); FOREVER { if (match ("==")) { gpush (); if (heir6 (lval2)) rvalue (lval2); geq (); } else if (match ("!=")) { gpush (); if (heir6 (lval2)) rvalue (lval2); gne (); } else return (0); } } heir6 (lval) int lval[]; { int k, lval2[3]; k = heir7 (lval); blanks (); if (!sstreq ("<") && !sstreq ("<=") && !sstreq (">=") && !sstreq (">")) return (k); if (sstreq ("<<") || sstreq (">>")) return (k); if (k) rvalue (lval); FOREVER { if (match ("<=")) { gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { gule (); continue; } gle (); } else if (match (">=")) { gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { guge (); continue; } gge (); } else if ((sstreq ("<")) && !sstreq ("<<")) { inbyte (); gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { gult (); continue; } glt (); } else if ((sstreq (">")) && !sstreq (">>")) { inbyte (); gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { gugt (); continue; } ggt (); } else return (0); blanks (); } } heir7 (lval) int lval[]; { int k, lval2[3]; k = heir8 (lval); blanks (); if (!sstreq (">>") && !sstreq ("<<") || sstreq(">>=") || sstreq("<<=")) return (k); if (k) rvalue (lval); FOREVER { if (sstreq(">>") && ! sstreq(">>=")) { inbyte(); inbyte(); gpush (); if (heir8 (lval2)) rvalue (lval2); gasr (); } else if (sstreq("<<") && ! sstreq("<<=")) { inbyte(); inbyte(); gpush (); if (heir8 (lval2)) rvalue (lval2); gasl (); } else return (0); blanks(); } } heir8 (lval) int lval[]; { int k, lval2[3]; k = heir9 (lval); blanks (); if ((ch () != '+') & (ch () != '-') | nch() == '=') return (k); if (k) rvalue (lval); FOREVER { if (match ("+")) { gpush (); if (heir9 (lval2)) rvalue (lval2); /* if left is pointer and right is int, scale right */ if (dbltest (lval, lval2)) gaslint (); /* will scale left if right int pointer and left int */ gadd (lval,lval2); result (lval, lval2); } else if (match ("-")) { gpush (); if (heir9 (lval2)) rvalue (lval2); /* if dbl, can only be: pointer - int, or pointer - pointer, thus, in first case, int is scaled up, in second, result is scaled down. */ if (dbltest (lval, lval2)) gaslint (); gsub (); /* if both pointers, scale result */ if ((lval[2] == CINT) && (lval2[2] == CINT)) { gasrint(); /* divide by intsize */ } result (lval, lval2); } else return (0); } } heir9 (lval) int lval[]; { int k, lval2[3]; k = heir10 (lval); blanks (); if (((ch () != '*') && (ch () != '/') && (ch () != '%')) || (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if (match ("*")) { gpush (); if (heir10 (lval2)) rvalue (lval2); gmult (); } else if (match ("/")) { gpush (); if (heir10 (lval2)) rvalue (lval2); gdiv (); } else if (match ("%")) { gpush (); if (heir10 (lval2)) rvalue (lval2); gmod (); } else return (0); } } heir10 (lval) int lval[]; { int k; char *ptr; if (match ("++")) { if ((k = heir10 (lval)) == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); ginc (lval); store (lval); return (0); } else if (match ("--")) { if ((k = heir10 (lval)) == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); gdec (lval); store (lval); return (0); } else if (match ("-")) { k = heir10 (lval); if (k) rvalue (lval); gneg (); return (0); } else if (match ("~")) { k = heir10 (lval); if (k) rvalue (lval); gcom (); return (0); } else if (match ("!")) { k = heir10 (lval); if (k) rvalue (lval); glneg (); return (0); } else if (ch()=='*' && nch() != '=') { inbyte(); k = heir10 (lval); if (k) rvalue (lval); if (ptr = lval[0]) lval[1] = ptr[TYPE]; else lval[1] = CINT; lval[2] = 0; /* flag as not pointer or array */ return (1); } else if (ch()=='&' && nch()!='&' && nch()!='=') { inbyte(); k = heir10 (lval); if (k == 0) { error ("illegal address"); return (0); } ptr = lval[0]; lval[2] = ptr[TYPE]; if (lval[1]) return (0); /* global and non-array */ immed (); prefix (); outstr (ptr = lval[0]); nl (); lval[1] = ptr[TYPE]; return (0); } else { k = heir11 (lval); if (match ("++")) { if (k == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); ginc (lval); store (lval); gdec (lval); return (0); } else if (match ("--")) { if (k == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); gdec (lval); store (lval); ginc (lval); return (0); } else return (k); } } heir11 (lval) int *lval; { int k; char *ptr; k = primary (lval); ptr = lval[0]; blanks (); if ((ch () == '[') | (ch () == '(')) FOREVER { if (match ("[")) { if (ptr == 0) { error ("can't subscript"); junk (); needbrack ("]"); return (0); } else if (ptr[IDENT] == POINTER) rvalue (lval); else if (ptr[IDENT] != ARRAY) { error ("can't subscript"); k = 0; } gpush (); expression (YES); needbrack ("]"); if (ptr[TYPE] == CINT) gaslint (); gadd (NULL,NULL); lval[0] = 0; lval[1] = ptr[TYPE]; k = 1; } else if (match ("(")) { if (ptr == 0) callfunction (0); else if (ptr[IDENT] != FUNCTION) { rvalue (lval); callfunction (0); } else callfunction (ptr); k = lval[0] = 0; } else return (k); } if (ptr == 0) return (k); if (ptr[IDENT] == FUNCTION) { immed (); prefix (); outstr (ptr); nl (); return (0); } return (k); } SHAR_EOF if test 10028 -ne "`wc -c < 'expr.c'`" then echo shar: error transmitting "'expr.c'" '(should have been 10028 characters)' fi fi echo shar: extracting "'function.c'" '(2643 characters)' if test -f 'function.c' then echo shar: will not over-write existing file "'function.c'" else cat << \SHAR_EOF > 'function.c' /* File function.c: 2.1 (83/03/20,16:02:04) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * begin a function * * called from "parse", this routine tries to make a function out * of what follows * modified version. p.l. woods * */ int argtop; newfunc () { char n[NAMESIZE], *ptr; fexitlab = getlabel(); if (!symname (n) ) { error ("illegal function or declaration"); kill (); return; } if (ptr = findglb (n)) { if (ptr[IDENT] != FUNCTION) multidef (n); else if (ptr[OFFSET] == FUNCTION) multidef (n); else ptr[OFFSET] = FUNCTION; } else addglb (n, FUNCTION, CINT, FUNCTION, PUBLIC); prologue (); if (!match ("(")) error ("missing open paren"); prefix (); outstr (n); col (); nl (); locptr = STARTLOC; argstk = 0; while (!match (")")) { if (symname (n)) { if (findloc (n)) multidef (n); else { addloc (n, 0, 0, argstk, AUTO); argstk = argstk + intsize(); } } else { error ("illegal argument name"); junk (); } blanks (); if (!streq (line + lptr, ")")) { if (!match (",")) error ("expected comma"); } if (endst ()) break; } stkp = 0; argtop = argstk; while (argstk) { if (amatch ("register", 8)) { if (amatch("char", 4)) getarg(CCHAR); else if (amatch ("int", 3)) getarg(CINT); else getarg(CINT); ns(); } else if (amatch ("char", 4)) { getarg (CCHAR); ns (); } else if (amatch ("int", 3)) { getarg (CINT); ns (); } else { error ("wrong number args"); break; } } statement(YES); printlabel(fexitlab); col(); nl(); modstk (0); gret (); stkp = 0; locptr = STARTLOC; } /* * declare argument types * * called from "newfunc", this routine add an entry in the local * symbol table for each named argument * completely rewritten version. p.l. woods * */ getarg (t) int t; { int j, legalname, address; char n[NAMESIZE], c, *argptr; FOREVER { if (argstk == 0) return; if (match ("*")) j = POINTER; else j = VARIABLE; if (!(legalname = symname (n))) illname (); if (match ("[")) { while (inbyte () != ']') if (endst ()) break; j = POINTER; } if (legalname) { if (argptr = findloc (n)) { argptr[IDENT] = j; argptr[TYPE] = t; address = argtop - glint(argptr); if (t == CCHAR && j == VARIABLE) address = address + byteoff(); argptr[OFFSET] = (address) & 0xff; argptr[OFFSET + 1] = (address >> 8) & 0xff; } else error ("expecting argument name"); } argstk = argstk - intsize(); if (endst ()) return; if (!match (",")) error ("expected comma"); } } SHAR_EOF if test 2643 -ne "`wc -c < 'function.c'`" then echo shar: error transmitting "'function.c'" '(should have been 2643 characters)' fi fi echo shar: extracting "'gen.c'" '(1495 characters)' if test -f 'gen.c' then echo shar: will not over-write existing file "'gen.c'" else cat << \SHAR_EOF > 'gen.c' /* File gen.c: 2.1 (83/03/20,16:02:06) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * return next available internal label number * */ getlabel () { return (nxtlab++); } /* * print specified number as label */ printlabel (label) int label; { olprfix (); outdec (label); } /* * glabel - generate label */ glabel (lab) char *lab; { prefix (); outstr (lab); col (); nl (); } /* * gnlabel - generate numeric label */ gnlabel (nlab) int nlab; { printlabel (nlab); col (); nl (); } outbyte (c) char c; { if (c == 0) return (0); fputc (c, output); return (c); } outstr (ptr) char ptr[]; { int k; k = 0; while (outbyte (ptr[k++])); } tab () { outbyte (9); } ol (ptr) char ptr[]; { ot (ptr); nl (); } ot (ptr) char ptr[]; { tab (); outstr (ptr); } outdec (number) int number; { int k, zs; char c; if (number == -32768) { outstr ("-32768"); return; } zs = 0; k = 10000; if (number < 0) { number = (-number); outbyte ('-'); } while (k >= 1) { c = number / k + '0'; if ((c != '0' | (k == 1) | zs)) { zs = 1; outbyte (c); } number = number % k; k = k / 10; } } store (lval) int *lval; { if (lval[1] == 0) putmem (lval[0]); else putstk (lval[1]); } rvalue (lval) int *lval; { if ((lval[0] != 0) & (lval[1] == 0)) getmem (lval[0]); else indirect (lval[1]); } test (label, ft) int label, ft; { needbrack ("("); expression (YES); needbrack (")"); testjump (label, ft); } SHAR_EOF if test 1495 -ne "`wc -c < 'gen.c'`" then echo shar: error transmitting "'gen.c'" '(should have been 1495 characters)' fi fi echo shar: extracting "'io.c'" '(2032 characters)' if test -f 'io.c' then echo shar: will not over-write existing file "'io.c'" else cat << \SHAR_EOF > 'io.c' /* File io.c: 2.1 (83/03/20,16:02:07) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * open input file */ openin (p) char *p; { strcpy(fname, p); fixname (fname); if (!checkname (fname)) return (NO); if ((input = fopen (fname, "r")) == NULL) { pl ("Open failure\n"); return (NO); } kill (); return (YES); } /* * open output file */ openout () { outfname (fname); if ((output = fopen (fname, "w")) == NULL) { pl ("Open failure"); return (NO); } kill (); return (YES); } /* * change input filename to output filename */ outfname (s) char *s; { while (*s) s++; *--s = 's'; } /* * remove NL from filenames * */ fixname (s) char *s; { while (*s && *s++ != EOL); if (!*s) return; *(--s) = 0; } /* * check that filename is "*.c" */ checkname (s) char *s; { while (*s) s++; if (*--s != 'c') return (NO); if (*--s != '.') return (NO); return (YES); } kill () { lptr = 0; line[lptr] = 0; } inline () { int k; FILE *unit; FOREVER { if (feof (input)) return; if ((unit = input2) == NULL) unit = input; kill (); while ((k = fgetc (unit)) != EOF) { if ((k == EOL) | (lptr >= LINEMAX)) break; line[lptr++] = k; } line[lptr] = 0; if (k <= 0) if (input2 != NULL) { input2 = inclstk[--inclsp]; fclose (unit); } if (lptr) { if ((ctext) & (cmode)) { comment (); outstr (line); nl (); } lptr = 0; return; } } } inbyte () { while (ch () == 0) { if (feof (input)) return (0); preprocess (); } return (gch ()); } inchar () { if (ch () == 0) inline (); if (feof (input)) return (0); return (gch ()); } gch () { if (ch () == 0) return (0); else return (line[lptr++] & 127); } nch () { if (ch () == 0) return (0); else return (line[lptr + 1] & 127); } ch () { return (line[lptr] & 127); } /* * print a carriage return and a string only to console * */ pl (str) char *str; { int k; k = 0; putchar (EOL); while (str[k]) putchar (str[k++]); } SHAR_EOF if test 2032 -ne "`wc -c < 'io.c'`" then echo shar: error transmitting "'io.c'" '(should have been 2032 characters)' fi fi echo shar: extracting "'lex.c'" '(2029 characters)' if test -f 'lex.c' then echo shar: will not over-write existing file "'lex.c'" else cat << \SHAR_EOF > 'lex.c' /* File lex.c: 2.1 (83/03/20,16:02:09) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * semicolon enforcer * * called whenever syntax requires a semicolon * */ ns () { if (!match (";")) error ("missing semicolon"); } junk () { if (an (inbyte ())) while (an (ch ())) gch (); else while (an (ch ())) { if (ch () == 0) break; gch (); } blanks (); } endst () { blanks (); return ((streq (line + lptr, ";") | (ch () == 0))); } needbrack (str) char *str; { if (!match (str)) { error ("missing bracket"); comment (); outstr (str); nl (); } } /* * test if given character is alpha * */ alpha (c) char c; { c = c & 127; return (((c >= 'a') & (c <= 'z')) | ((c >= 'A') & (c <= 'Z')) | (c == '_')); } /* * test if given character is numeric * */ numeric (c) char c; { c = c & 127; return ((c >= '0') & (c <= '9')); } /* * test if given character is alphanumeric * */ an (c) char c; { return ((alpha (c)) | (numeric (c))); } sstreq (str1) char *str1; { return (streq(line + lptr, str1)); } streq (str1, str2) char str1[], str2[]; { int k; k = 0; while (str2[k]) { if ((str1[k] != str2[k])) return (0); k++; } return (k); } astreq (str1, str2, len) char str1[], str2[]; int len; { int k; k = 0; while (k < len) { if ((str1[k] != str2[k])) break; if (str1[k] == 0) break; if (str2[k] == 0) break; k++; } if (an (str1[k])) return (0); if (an (str2[k])) return (0); return (k); } match (lit) char *lit; { int k; blanks (); if (k = streq (line + lptr, lit)) { lptr = lptr + k; return (1); } return (0); } amatch (lit, len) char *lit; int len; { int k; blanks (); if (k = astreq (line + lptr, lit, len)) { lptr = lptr + k; while (an (ch ())) inbyte (); return (1); } return (0); } blanks () { FOREVER { while (ch () == 0) { preprocess (); if (feof (input)) break; } if (ch () == ' ') gch (); else if (ch () == 9) gch (); else return; } } SHAR_EOF if test 2029 -ne "`wc -c < 'lex.c'`" then echo shar: error transmitting "'lex.c'" '(should have been 2029 characters)' fi fi echo shar: extracting "'main.c'" '(4283 characters)' if test -f 'main.c' then echo shar: will not over-write existing file "'main.c'" else cat << \SHAR_EOF > 'main.c' /* File main.c: 2.7 (84/11/28,10:14:56) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" main (argc, argv) int argc, *argv; { char *p,*bp; int smacptr; macptr = 0; ctext = 0; argc--; argv++; errs = 0; aflag = 1; while (p = *argv++) if (*p == '-') while (*++p) switch(*p) { case 't': case 'T': ctext = 1; break; case 's': case 'S': sflag = 1; break; case 'c': case 'C': cflag = 1; break; case 'a': case 'A': aflag = 0; break; case 'd': case 'D': bp = ++p; if (!*p) usage(); while (*p && *p != '=') p++; if (*p == '=') *p = '\t'; while (*p) p++; p--; defmac(bp); break; default: usage(); } else break; smacptr = macptr; if (!p) usage(); while (p) { errfile = 0; if (typeof(p) == 'c') { glbptr = STARTGLB; locptr = STARTLOC; wsptr = ws; inclsp = iflevel = skiplevel = swstp = litptr = stkp = errcnt = ncmp = lastst = quote[1] = 0; macptr = smacptr; input2 = NULL; quote[0] = '"'; cmode = 1; glbflag = 1; nxtlab = 0; litlab = getlabel (); defmac("end\tmemory"); addglb("memory", ARRAY, CCHAR, 0, EXTERN); addglb("stack", ARRAY, CCHAR, 0, EXTERN); rglbptr = glbptr; addglb ("etext", ARRAY, CCHAR, 0, EXTERN); addglb ("edata", ARRAY, CCHAR, 0, EXTERN); defmac("short\tint"); initmac(); /* * compiler body */ if (!openin (p)) return; if (!openout ()) return; header (); gtext (); parse (); fclose (input); gdata (); dumplits (); dumpglbs (); errorsummary (); trailer (); fclose (output); pl (""); errs = errs || errfile; #ifndef NOASLD } if (!errfile && !sflag) errs = errs || assemble(p); #else } else { fputs("Don't understand file ", stderr); fputs(p, stderr); errs = 1; } #endif p = *argv++; } #ifndef NOASLD if (!errs && !sflag && !cflag) errs = errs || link(); #endif exit(errs != 0); } FEvers() { outstr("\tFront End (2.7,84/11/28)"); } usage() { fputs("usage: sccXXXX [-tcsa] [-dSYM[=VALUE]] files\n", stderr); exit(1); } /* * process all input text * * at this level, only static declarations, defines, includes, * and function definitions are legal. * */ parse () { while (!feof (input)) { if (amatch ("extern", 6)) dodcls(EXTERN); else if (amatch ("static",6)) dodcls(STATIC); else if (dodcls(PUBLIC)) ; else if (match ("#asm")) doasm (); else if (match ("#include")) doinclude (); else if (match ("#define")) dodefine(); else if (match ("#undef")) doundef(); else newfunc (); blanks (); } } /* * parse top level declarations */ dodcls(stclass) int stclass; { blanks(); if (amatch("char", 4)) declglb(CCHAR, stclass); else if (amatch("int", 3)) declglb(CINT, stclass); else if (stclass == PUBLIC) return(0); else declglb(CINT, stclass); ns (); return(1); } /* * dump the literal pool */ dumplits () { int j, k; if (litptr == 0) return; printlabel (litlab); col (); k = 0; while (k < litptr) { defbyte (); j = 8; while (j--) { onum (litq[k++] & 127); if ((j == 0) | (k >= litptr)) { nl (); break; } outbyte (','); } } } /* * dump all static variables */ dumpglbs () { int j; if (!glbflag) return; cptr = rglbptr; while (cptr < glbptr) { if (cptr[IDENT] != FUNCTION) { ppubext(cptr); if (cptr[STORAGE] != EXTERN) { prefix (); outstr (cptr); col (); defstorage (); j = glint(cptr); if ((cptr[TYPE] == CINT) || (cptr[IDENT] == POINTER)) j = j * intsize(); onum (j); nl (); } } else { fpubext(cptr); } cptr = cptr + SYMSIZ; } } /* * report errors */ errorsummary () { if (ncmp) error ("missing closing bracket"); nl (); comment (); outdec (errcnt); if (errcnt) errfile = YES; outstr (" error(s) in compilation"); nl (); comment(); ot("literal pool:"); outdec(litptr); nl(); comment(); ot("global pool:"); outdec(glbptr-rglbptr); nl(); comment(); ot("Macro pool:"); outdec(macptr); nl(); pl (errcnt ? "Error(s)" : "No errors"); } typeof(s) char *s; { s += strlen(s) - 2; if (*s == '.') return(*(s+1)); return(' '); } SHAR_EOF if test 4283 -ne "`wc -c < 'main.c'`" then echo shar: error transmitting "'main.c'" '(should have been 4283 characters)' fi fi echo shar: extracting "'preproc.c'" '(5137 characters)' if test -f 'preproc.c' then echo shar: will not over-write existing file "'preproc.c'" else cat << \SHAR_EOF > 'preproc.c' /* File preproc.c: 2.3 (84/11/27,11:47:40) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * open an include file */ doinclude () { char *p; FILE *inp2; blanks (); if (inp2 = fixiname ()) if (inclsp < INCLSIZ) { inclstk[inclsp++] = input2; input2 = inp2; } else { fclose (inp2); error ("too many nested includes"); } else { error ("Could not open include file"); } kill (); } /* * fixiname - remove "brackets" around include file name */ fixiname () { char c1, c2, *p, *ibp; char buf[20]; FILE *fp; char buf2[100]; ibp = &buf[0]; if ((c1 = gch ()) != '"' && c1 != '<') return (NULL); for (p = line + lptr; *p ;) *ibp++ = *p++; c2 = *(--p); if (c1 == '"' ? (c2 != '"') : (c2 != '>')) { error ("incorrect delimiter"); return (NULL); } *(--ibp) = 0; fp = NULL; if (c1 == '<' || !(fp = fopen(buf, "r"))) { strcpy(buf2, DEFLIB); strcat(buf2, buf); fp = fopen(buf2, "r"); } return(fp); } /* * "asm" pseudo-statement * * enters mode where assembly language statements are passed * intact through parser * */ doasm () { cmode = 0; FOREVER { inline (); if (match ("#endasm")) break; if (feof (input)) break; outstr (line); nl (); } kill (); cmode = 1; } dodefine () { addmac(); } doundef () { int mp; char sname[NAMESIZE]; if (!symname(sname)) { illname(); kill(); return; } if (mp = findmac(sname)) delmac(mp); kill(); } preprocess () { if (ifline()) return; while (cpp()); } doifdef (ifdef) int ifdef; { char sname[NAMESIZE]; int k; blanks(); ++iflevel; if (skiplevel) return; k = symname(sname) && findmac(sname); if (k != ifdef) skiplevel = iflevel; } ifline() { FOREVER { inline(); if (feof(input)) return(1); if (match("#ifdef")) { doifdef(YES); continue; } else if (match("#ifndef")) { doifdef(NO); continue; } else if (match("#else")) { if (iflevel) { if (skiplevel == iflevel) skiplevel = 0; else if (skiplevel == 0) skiplevel = iflevel; } else noiferr(); continue; } else if (match("#endif")) { if (iflevel) { if (skiplevel == iflevel) skiplevel = 0; --iflevel; } else noiferr(); continue; } if (!skiplevel) return(0); } } noiferr() { error("no matching #if..."); } cpp () { int k; char c, sname[NAMESIZE]; int tog; int cpped; /* non-zero if something expanded */ cpped = 0; /* don't expand lines with preprocessor commands in them */ if (!cmode || line[0] == '#') return(0); mptr = lptr = 0; while (ch ()) { if ((ch () == ' ') | (ch () == 9)) { keepch (' '); while ((ch () == ' ') | (ch () == 9)) gch (); } else if (ch () == '"') { keepch (ch ()); gch (); while (ch () != '"') { if (ch () == 0) { error ("missing quote"); break; } if (ch() == '\\') keepch(gch()); keepch (gch ()); } gch (); keepch ('"'); } else if (ch () == 39) { keepch (39); gch (); while (ch () != 39) { if (ch () == 0) { error ("missing apostrophe"); break; } if (ch() == '\\') keepch(gch()); keepch (gch ()); } gch (); keepch (39); } else if ((ch () == '/') & (nch () == '*')) { inchar (); inchar (); while ((((c = ch ()) == '*') & (nch () == '/')) == 0) if (c == '$') { inchar (); tog = TRUE; if (ch () == '-') { tog = FALSE; inchar (); } if (alpha (c = ch ())) { inchar (); toggle (c, tog); } } else { if (ch () == 0) inline (); else inchar (); if (feof (input)) break; } inchar (); inchar (); } else if (an (ch ())) { k = 0; while (an (ch ())) { if (k < NAMEMAX) sname[k++] = ch (); gch (); } sname[k] = 0; if (k = findmac (sname)) { cpped = 1; while (c = macq[k++]) keepch (c); } else { k = 0; while (c = sname[k++]) keepch (c); } } else keepch (gch ()); } keepch (0); if (mptr >= MPMAX) error ("line too long"); lptr = mptr = 0; while (line[lptr++] = mline[mptr++]); lptr = 0; return(cpped); } keepch (c) char c; { mline[mptr] = c; if (mptr < MPMAX) mptr++; return (c); } defmac(s) char *s; { kill(); strcpy(line, s); addmac(); } addmac () { char sname[NAMESIZE]; int k; int mp; if (!symname (sname)) { illname (); kill (); return; } if (mp = findmac(sname)) { error("Duplicate define"); delmac(mp); } k = 0; while (putmac (sname[k++])); while (ch () == ' ' | ch () == 9) gch (); while (putmac (gch ())); if (macptr >= MACMAX) error ("macro table full"); } delmac(mp) int mp; { --mp; --mp; /* step over previous null */ while (mp >= 0 && macq[mp]) macq[mp--] = '%'; } putmac (c) char c; { macq[macptr] = c; if (macptr < MACMAX) macptr++; return (c); } findmac (sname) char *sname; { int k; k = 0; while (k < macptr) { if (astreq (sname, macq + k, NAMEMAX)) { while (macq[k++]); return (k); } while (macq[k++]); while (macq[k++]); } return (0); } toggle (name, onoff) char name; int onoff; { switch (name) { case 'C': ctext = onoff; break; } } SHAR_EOF if test 5137 -ne "`wc -c < 'preproc.c'`" then echo shar: error transmitting "'preproc.c'" '(should have been 5137 characters)' fi fi echo shar: extracting "'primary.c'" '(4818 characters)' if test -f 'primary.c' then echo shar: will not over-write existing file "'primary.c'" else cat << \SHAR_EOF > 'primary.c' /* File primary.c: 2.4 (84/11/27,16:26:07) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" primary (lval) int *lval; { char *ptr, sname[NAMESIZE]; int num[1]; int k; lval[2] = 0; /* clear pointer/array type */ if (match ("(")) { k = heir1 (lval); needbrack (")"); return (k); } if (amatch("sizeof", 6)) { needbrack("("); immed(); if (amatch("int", 3)) onum(intsize()); else if (amatch("char", 4)) onum(1); else if (symname(sname)) { if ((ptr = findloc(sname)) || (ptr = findglb(sname))) { if (ptr[STORAGE] == LSTATIC) error("sizeof local static"); k = glint(ptr); if ((ptr[TYPE] == CINT) || (ptr[IDENT] == POINTER)) k *= intsize(); onum(k); } else { error("sizeof undeclared variable"); onum(0); } } else { error("sizeof only on type or variable"); } needbrack(")"); nl(); return(lval[0] = lval[1] = 0); } if (symname (sname)) { if (ptr = findloc (sname)) { getloc (ptr); lval[0] = ptr; lval[1] = ptr[TYPE]; if (ptr[IDENT] == POINTER) { lval[1] = CINT; lval[2] = ptr[TYPE]; } if (ptr[IDENT] == ARRAY) { lval[2] = ptr[TYPE]; lval[2] = 0; return (0); } else return (1); } if (ptr = findglb (sname)) if (ptr[IDENT] != FUNCTION) { lval[0] = ptr; lval[1] = 0; if (ptr[IDENT] != ARRAY) { if (ptr[IDENT] == POINTER) lval[2] = ptr[TYPE]; return (1); } immed (); prefix (); outstr (ptr); nl (); lval[1] = lval[2] = ptr[TYPE]; lval[2] = 0; return (0); } blanks (); if (ch() != '(') error("undeclared variable"); ptr = addglb (sname, FUNCTION, CINT, 0, PUBLIC); lval[0] = ptr; lval[1] = 0; return (0); } if (constant (num)) return (lval[0] = lval[1] = 0); else { error ("invalid expression"); immed (); onum (0); nl (); junk (); return (0); } } /* * true if val1 -> int pointer or int array and val2 not pointer or array */ dbltest (val1, val2) int val1[], val2[]; { if (val1 == NULL) return (FALSE); if (val1[2] != CINT) return (FALSE); if (val2[2]) return (FALSE); return (TRUE); } /* * determine type of binary operation */ result (lval, lval2) int lval[], lval2[]; { if (lval[2] && lval2[2]) lval[2] = 0; else if (lval2[2]) { lval[0] = lval2[0]; lval[1] = lval2[1]; lval[2] = lval2[2]; } } constant (val) int val[]; { if (number (val)) immed (); else if (pstr (val)) immed (); else if (qstr (val)) { immed (); printlabel (litlab); outbyte ('+'); } else return (0); onum (val[0]); nl (); return (1); } number (val) int val[]; { int k, minus, base; char c; k = minus = 1; while (k) { k = 0; if (match ("+")) k = 1; if (match ("-")) { minus = (-minus); k = 1; } } if (!numeric (c = ch ())) return (0); if (match ("0x") || match ("0X")) while (numeric (c = ch ()) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { inbyte (); k = k * 16 + (numeric (c) ? (c - '0') : ((c & 07) + 9)); } else { base = (c == '0') ? 8 : 10; while (numeric (ch ())) { c = inbyte (); k = k * base + (c - '0'); } } if (minus < 0) k = (-k); val[0] = k; return (1); } pstr (val) int val[]; { int k; char c; k = 0; if (!match ("'")) return (0); while ((c = gch ()) != 39) { c = (c == '\\') ? spechar(): c; k = (k & 255) * 256 + (c & 255); } val[0] = k; return (1); } qstr (val) int val[]; { char c; if (!match (quote)) return (0); val[0] = litptr; while (ch () != '"') { if (ch () == 0) break; if (litptr >= LITMAX) { error ("string space exhausted"); while (!match (quote)) if (gch () == 0) break; return (1); } c = gch(); litq[litptr++] = (c == '\\') ? spechar(): c; } gch (); litq[litptr++] = 0; return (1); } /* * decode special characters (preceeded by back slashes) */ spechar() { char c; c = ch(); if (c == 'n') c = EOL; else if (c == 't') c = TAB; else if (c == 'r') c = CR; else if (c == 'f') c = FFEED; else if (c == 'b') c = BKSP; else if (c == '0') c = EOS; else if (c == EOS) return; gch(); return (c); } /* * perform a function call * * called from "heir11", this routine will either call the named * function, or if the supplied ptr is zero, will call the contents * of HL * */ callfunction (ptr) char *ptr; { int nargs; nargs = 0; blanks (); if (ptr == 0) gpush (); while (!streq (line + lptr, ")")) { if (endst ()) break; expression (NO); if (ptr == 0) swapstk (); gpush (); nargs = nargs + intsize(); if (!match (",")) break; } needbrack (")"); if (aflag) gnargs(nargs / intsize()); if (ptr) gcall (ptr); else callstk (); stkp = modstk (stkp + nargs); } needlval () { error ("must be lvalue"); } SHAR_EOF if test 4818 -ne "`wc -c < 'primary.c'`" then echo shar: error transmitting "'primary.c'" '(should have been 4818 characters)' fi fi echo shar: extracting "'stmt.c'" '(6668 characters)' if test -f 'stmt.c' then echo shar: will not over-write existing file "'stmt.c'" else cat << \SHAR_EOF > 'stmt.c' /* File stmt.c: 2.1 (83/03/20,16:02:17) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * statement parser * * called whenever syntax requires a statement. this routine * performs that statement and returns a number telling which one * * 'func' is true if we require a "function_statement", which * must be compound, and must contain "statement_list" (even if * "declaration_list" is omitted) */ statement (func) int func; { if ((ch () == 0) & feof (input)) return (0); lastst = 0; if (func) if (match ("{")) { compound (YES); return (lastst); } else error ("function requires compound statement"); if (match ("{")) compound (NO); else stst (); return (lastst); } /* * declaration */ stdecl () { if (amatch("register", 8)) doldcls(DEFAUTO); else if (amatch("auto", 4)) doldcls(DEFAUTO); else if (amatch("static", 6)) doldcls(LSTATIC); else if (doldcls(AUTO)) ; else return (NO); return (YES); } doldcls(stclass) int stclass; { blanks(); if (amatch("char", 4)) declloc(CCHAR, stclass); else if (amatch("int", 3)) declloc(CINT, stclass); else if (stclass == LSTATIC || stclass == DEFAUTO) declloc(CINT, stclass); else return(0); ns(); return(1); } /* * non-declaration statement */ stst () { if (amatch ("if", 2)) { doif (); lastst = STIF; } else if (amatch ("while", 5)) { dowhile (); lastst = STWHILE; } else if (amatch ("switch", 6)) { doswitch (); lastst = STSWITCH; } else if (amatch ("do", 2)) { dodo (); ns (); lastst = STDO; } else if (amatch ("for", 3)) { dofor (); lastst = STFOR; } else if (amatch ("return", 6)) { doreturn (); ns (); lastst = STRETURN; } else if (amatch ("break", 5)) { dobreak (); ns (); lastst = STBREAK; } else if (amatch ("continue", 8)) { docont (); ns (); lastst = STCONT; } else if (match (";")) ; else if (amatch ("case", 4)) { docase (); lastst = statement (NO); } else if (amatch ("default", 7)) { dodefault (); lastst = statement (NO); } else if (match ("#asm")) { doasm (); lastst = STASM; } else if (match ("{")) compound (NO); else { expression (YES); /* if (match (":")) { dolabel (); lastst = statement (NO); } else { */ ns (); lastst = STEXP; /* } */ } } /* * compound statement * * allow any number of statements to fall between "{" and "}" * * 'func' is true if we are in a "function_statement", which * must contain "statement_list" */ compound (func) int func; { int decls; decls = YES; ncmp++; while (!match ("}")) { if (feof (input)) return; if (decls) { if (!stdecl ()) decls = NO; } else stst (); } ncmp--; } /* * "if" statement */ doif () { int fstkp, flab1, flab2; char *flev; flev = locptr; fstkp = stkp; flab1 = getlabel (); test (flab1, FALSE); statement (NO); stkp = modstk (fstkp); locptr = flev; if (!amatch ("else", 4)) { gnlabel (flab1); return; } jump (flab2 = getlabel ()); gnlabel (flab1); statement (NO); stkp = modstk (fstkp); locptr = flev; gnlabel (flab2); } /* * "while" statement */ dowhile () { int ws[7]; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSWHILE; ws[WSTEST] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); gnlabel (ws[WSTEST]); test (ws[WSEXIT], FALSE); statement (NO); jump (ws[WSTEST]); gnlabel (ws[WSEXIT]); locptr = ws[WSSYM]; stkp = modstk (ws[WSSP]); delwhile (); } /* * "do" statement */ dodo () { int ws[7]; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSDO; ws[WSBODY] = getlabel (); ws[WSTEST] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); gnlabel (ws[WSBODY]); statement (NO); if (!match ("while")) { error ("missing while"); return; } gnlabel (ws[WSTEST]); test (ws[WSBODY], TRUE); gnlabel (ws[WSEXIT]); locptr = ws[WSSYM]; stkp = modstk (ws[WSSP]); delwhile (); } /* * "for" statement */ dofor () { int ws[7], *pws; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSFOR; ws[WSTEST] = getlabel (); ws[WSINCR] = getlabel (); ws[WSBODY] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); pws = readwhile (); needbrack ("("); if (!match (";")) { expression (YES); ns (); } gnlabel (pws[WSTEST]); if (!match (";")) { expression (YES); testjump (pws[WSBODY], TRUE); jump (pws[WSEXIT]); ns (); } else pws[WSTEST] = pws[WSBODY]; gnlabel (pws[WSINCR]); if (!match (")")) { expression (YES); needbrack (")"); jump (pws[WSTEST]); } else pws[WSINCR] = pws[WSTEST]; gnlabel (pws[WSBODY]); statement (NO); jump (pws[WSINCR]); gnlabel (pws[WSEXIT]); locptr = pws[WSSYM]; stkp = modstk (pws[WSSP]); delwhile (); } /* * "switch" statement */ doswitch () { int ws[7]; int *ptr; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSSWITCH; ws[WSCASEP] = swstp; ws[WSTAB] = getlabel (); ws[WSDEF] = ws[WSEXIT] = getlabel (); addwhile (ws); immed (); printlabel (ws[WSTAB]); nl (); gpush (); needbrack ("("); expression (YES); needbrack (")"); stkp = stkp + intsize(); /* '?case' will adjust the stack */ gjcase (); statement (NO); ptr = readswitch (); jump (ptr[WSEXIT]); dumpsw (ptr); gnlabel (ptr[WSEXIT]); locptr = ptr[WSSYM]; stkp = modstk (ptr[WSSP]); swstp = ptr[WSCASEP]; delwhile (); } /* * "case" label */ docase () { int val; val = 0; if (readswitch ()) { if (!number (&val)) if (!pstr (&val)) error ("bad case label"); addcase (val); if (!match (":")) error ("missing colon"); } else error ("no active switch"); } /* * "default" label */ dodefault () { int *ptr, lab; if (ptr = readswitch ()) { ptr[WSDEF] = lab = getlabel (); gnlabel (lab); if (!match (":")) error ("missing colon"); } else error ("no active switch"); } /* * "return" statement */ doreturn () { if (endst () == 0) expression (YES); jump(fexitlab); } /* * "break" statement */ dobreak () { int *ptr; if ((ptr = readwhile ()) == 0) return; modstk (ptr[WSSP]); jump (ptr[WSEXIT]); } /* * "continue" statement */ docont () { int *ptr; if ((ptr = findwhile ()) == 0) return; modstk (ptr[WSSP]); if (ptr[WSTYP] == WSFOR) jump (ptr[WSINCR]); else jump (ptr[WSTEST]); } /* * dump switch table */ dumpsw (ws) int ws[]; { int i,j; gdata (); gnlabel (ws[WSTAB]); if (ws[WSCASEP] != swstp) { j = ws[WSCASEP]; while (j < swstp) { defword (); i = 4; while (i--) { onum (swstcase[j]); outbyte (','); printlabel (swstlab[j++]); if ((i == 0) | (j >= swstp)) { nl (); break; } outbyte (','); } } } defword (); printlabel (ws[WSDEF]); outstr (",0"); nl (); gtext (); } SHAR_EOF if test 6668 -ne "`wc -c < 'stmt.c'`" then echo shar: error transmitting "'stmt.c'" '(should have been 6668 characters)' fi fi echo shar: extracting "'sym.c'" '(3849 characters)' if test -f 'sym.c' then echo shar: will not over-write existing file "'sym.c'" else cat << \SHAR_EOF > 'sym.c' /* File sym.c: 2.1 (83/03/20,16:02:19) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * declare a static variable */ declglb (typ, stor) int typ, stor; { int k, j; char sname[NAMESIZE]; FOREVER { FOREVER { if (endst ()) return; k = 1; if (match ("*")) j = POINTER; else j = VARIABLE; if (!symname (sname)) illname (); if (findglb (sname)) multidef (sname); if (match ("[")) { k = needsub (); if (k || stor == EXTERN) j = ARRAY; else j = POINTER; } addglb (sname, j, typ, k, stor); break; } if (!match (",")) return; } } /* * declare local variables * * works just like "declglb", but modifies machine stack and adds * symbol table entry with appropriate stack offset to find it again */ declloc (typ, stclass) int typ, stclass; { int k, j; char sname[NAMESIZE]; FOREVER { FOREVER { if (endst ()) return; if (match ("*")) j = POINTER; else j = VARIABLE; if (!symname (sname)) illname (); if (findloc (sname)) multidef (sname); if (match ("[")) { k = needsub (); if (k) { j = ARRAY; if (typ == CINT) k = k * intsize(); } else { j = POINTER; k = intsize(); } } else if ((typ == CCHAR) & (j != POINTER)) k = 1; else k = intsize(); if (stclass != LSTATIC) { k = galign(k); stkp = modstk (stkp - k); addloc (sname, j, typ, stkp, AUTO); } else addloc( sname, j, typ, k, LSTATIC); break; } if (!match (",")) return; } } /* * get required array size */ needsub () { int num[1]; if (match ("]")) return (0); if (!number (num)) { error ("must be constant"); num[0] = 1; } if (num[0] < 0) { error ("negative size illegal"); num[0] = (-num[0]); } needbrack ("]"); return (num[0]); } findglb (sname) char *sname; { char *ptr; ptr = STARTGLB; while (ptr != glbptr) { if (astreq (sname, ptr, NAMEMAX)) return (ptr); ptr = ptr + SYMSIZ; } return (0); } findloc (sname) char *sname; { char *ptr; ptr = locptr; while (ptr != STARTLOC) { ptr = ptr - SYMSIZ; if (astreq (sname, ptr, NAMEMAX)) return (ptr); } return (0); } addglb (sname, id, typ, value, stor) char *sname, id, typ; int value, stor; { char *ptr; if (cptr = findglb (sname)) return (cptr); if (glbptr >= ENDGLB) { error ("global symbol table overflow"); return (0); } cptr = ptr = glbptr; while (an (*ptr++ = *sname++)); cptr[IDENT] = id; cptr[TYPE] = typ; cptr[STORAGE] = stor; cptr[OFFSET] = value & 0xff; cptr[OFFSET+1] = (value >> 8) & 0xff; glbptr = glbptr + SYMSIZ; return (cptr); } addloc (sname, id, typ, value, stclass) char *sname, id, typ; int value, stclass; { char *ptr; int k; if (cptr = findloc (sname)) return (cptr); if (locptr >= ENDLOC) { error ("local symbol table overflow"); return (0); } cptr = ptr = locptr; while (an (*ptr++ = *sname++)); cptr[IDENT] = id; cptr[TYPE] = typ; cptr[STORAGE] = stclass; if (stclass == LSTATIC) { gdata(); printlabel(k = getlabel()); col(); defstorage(); onum(value); nl(); gtext(); value = k; } else value = galign(value); cptr[OFFSET] = value & 0xff; cptr[OFFSET+1] = (value >> 8) & 0xff; locptr = locptr + SYMSIZ; return (cptr); } /* * test if next input string is legal symbol name * */ symname (sname) char *sname; { int k; char c; blanks (); if (!alpha (ch ())) return (0); k = 0; while (an (ch ())) sname[k++] = gch (); sname[k] = 0; return (1); } illname () { error ("illegal symbol name"); } multidef (sname) char *sname; { error ("already defined"); comment (); outstr (sname); nl (); } glint(syment) char *syment; { int l,u,r; l = syment[OFFSET]; u = syment[OFFSET+1]; r = (l & 0xff) + ((u << 8) & ~0x00ff); return (r); } SHAR_EOF if test 3849 -ne "`wc -c < 'sym.c'`" then echo shar: error transmitting "'sym.c'" '(should have been 3849 characters)' fi fi echo shar: extracting "'while.c'" '(980 characters)' if test -f 'while.c' then echo shar: will not over-write existing file "'while.c'" else cat << \SHAR_EOF > 'while.c' /* File while.c: 2.1 (83/03/20,16:02:22) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" addwhile (ptr) int ptr[]; { int k; if (wsptr == WSMAX) { error ("too many active whiles"); return; } k = 0; while (k < WSSIZ) *wsptr++ = ptr[k++]; } delwhile () { if (readwhile ()) wsptr = wsptr - WSSIZ; } readwhile () { if (wsptr == ws) { error ("no active do/for/while/switch"); return (0); } else return (wsptr-WSSIZ); } findwhile () { int *ptr; for (ptr = wsptr; ptr != ws;) { ptr = ptr - WSSIZ; if (ptr[WSTYP] != WSSWITCH) return (ptr); } error ("no active do/for/while"); return (0); } readswitch () { int *ptr; if (ptr = readwhile ()) if (ptr[WSTYP] == WSSWITCH) return (ptr); return (0); } addcase (val) int val; { int lab; if (swstp == SWSTSZ) error ("too many case labels"); else { swstcase[swstp] = val; swstlab[swstp++] = lab = getlabel (); printlabel (lab); col (); nl (); } } SHAR_EOF if test 980 -ne "`wc -c < 'while.c'`" then echo shar: error transmitting "'while.c'" '(should have been 980 characters)' fi fi exit 0 # End of shell archive
sources-request@panda.UUCP (05/20/86)
Mod.sources: Volume 5, Issue 9 Submitted by: genrad!linus!mnetor!clewis (Chris Lewis) #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # includes # 6809 # 8080 # vax # lib # This archive created: Sun May 18 18:20:19 1986 export PATH; PATH=/bin:$PATH if test ! -d 'includes' then echo shar: creating directory "'includes'" mkdir 'includes' fi echo shar: extracting "'includes/ctype.h'" '(34 characters)' if test -f 'includes/ctype.h' then echo shar: will not over-write existing file "'includes/ctype.h'" else cat << \SHAR_EOF > 'includes/ctype.h' /* Nothing needed in this file */ SHAR_EOF if test 34 -ne "`wc -c < 'includes/ctype.h'`" then echo shar: error transmitting "'includes/ctype.h'" '(should have been 34 characters)' fi fi echo shar: extracting "'includes/stdio.h'" '(100 characters)' if test -f 'includes/stdio.h' then echo shar: will not over-write existing file "'includes/stdio.h'" else cat << \SHAR_EOF > 'includes/stdio.h' #define stdin 0 #define stdout 1 #define stderr 2 #define NULL 0 #define EOF (-1) #define FILE char SHAR_EOF if test 100 -ne "`wc -c < 'includes/stdio.h'`" then echo shar: error transmitting "'includes/stdio.h'" '(should have been 100 characters)' fi fi echo shar: done with directory "'includes'" if test ! -d '6809' then echo shar: creating directory "'6809'" mkdir '6809' fi echo shar: extracting "'6809/ccstart.u'" '(373 characters)' if test -f '6809/ccstart.u' then echo shar: will not over-write existing file "'6809/ccstart.u'" else cat << \SHAR_EOF > '6809/ccstart.u' | Run-time start off for ccv1 on the Physics 6809 .globl _edata .globl _main | Initialize stack lds #/1000 ldx #_edata | clear all of memory l2: clr (x)+ cmpx #/0fff bne l2 | Circumvent EPROM bug ldx #/ff3b ldb #6 l1: pshs x decb bne l1 | clear everything so that start conds are | always same clra clrb tfr a,dp tfr d,x tfr d,y tfr d,u jsr _main jmp /fc00 SHAR_EOF if test 373 -ne "`wc -c < '6809/ccstart.u'`" then echo shar: error transmitting "'6809/ccstart.u'" '(should have been 373 characters)' fi fi echo shar: extracting "'6809/crunas09.u'" '(884 characters)' if test -f '6809/crunas09.u' then echo shar: will not over-write existing file "'6809/crunas09.u'" else cat << \SHAR_EOF > '6809/crunas09.u' | csa09 Small C v1 comparison support | All are dyadic except for lneg. .globl eq .globl ne .globl lt .globl le .globl gt .globl ge .globl ult .globl ule .globl ugt .globl uge .globl lneg .globl bool .globl _eend,_edata,_etext .globl _Xstktop,_brkend eq: cmpd 2(s) lbeq true lbra false ne: cmpd 2(s) lbne true lbra false lt: cmpd 2(s) bgt true bra false le: cmpd 2(s) bge true bra false gt: cmpd 2(s) blt true bra false ge: cmpd 2(s) ble true bra false ult: cmpd 2(s) bhi true bra false ule: cmpd 2(s) bhs true bra false ugt: cmpd 2(s) blo true bra false uge: cmpd 2(s) bls true bra false lneg: cmpd #0 beq ltrue ldd #0 rts ltrue: ldd #1 rts bool: bsr lneg bra lneg true: ldd #1 ldx (s) leas 4(s) jmp (x) false: clra clrb ldx (s) leas 4(s) jmp (x) _Xstktop: tfr s,d rts _etext = . .bss _eend = . .data _brkend: .wval _eend _edata = . SHAR_EOF if test 884 -ne "`wc -c < '6809/crunas09.u'`" then echo shar: error transmitting "'6809/crunas09.u'" '(should have been 884 characters)' fi fi echo shar: extracting "'6809/exit.u'" '(75 characters)' if test -f '6809/exit.u' then echo shar: will not over-write existing file "'6809/exit.u'" else cat << \SHAR_EOF > '6809/exit.u' | Small C v1 exit routine (physics computer) .globl _exit _exit: jmp /fc00 SHAR_EOF if test 75 -ne "`wc -c < '6809/exit.u'`" then echo shar: error transmitting "'6809/exit.u'" '(should have been 75 characters)' fi fi echo shar: extracting "'6809/faults.u'" '(205 characters)' if test -f '6809/faults.u' then echo shar: will not over-write existing file "'6809/faults.u'" else cat << \SHAR_EOF > '6809/faults.u' | MC6809 Concurrent Euclid fault codes ASSERTFAIL = 0 RANGECHECK = 1 CASERANGE = 2 | fault codes for runtime routines OUTOFSPACE = 20 .globl ASSERTFAIL .globl RANGECHECK .globl CASERANGE .globl OUTOFSPACE SHAR_EOF if test 205 -ne "`wc -c < '6809/faults.u'`" then echo shar: error transmitting "'6809/faults.u'" '(should have been 205 characters)' fi fi echo shar: extracting "'6809/io.u'" '(334 characters)' if test -f '6809/io.u' then echo shar: will not over-write existing file "'6809/io.u'" else cat << \SHAR_EOF > '6809/io.u' | Small C v1 io (putchar) for physics machine .globl _putchar _putchar=. lda /9000 bita #2 beq _putchar lda 3(s) sta /9001 cmpa #10. bne out ldd #13. pshs d lbsr _putchar leas 2(s) out: rts .globl _getchar _getchar=. lda /9000 bita #1 beq _getchar ldb /9001 clra andb #/7F cmpb #04 bne noteot ldd #-1 noteot: rts SHAR_EOF if test 334 -ne "`wc -c < '6809/io.u'`" then echo shar: error transmitting "'6809/io.u'" '(should have been 334 characters)' fi fi echo shar: extracting "'6809/mrabs.u'" '(422 characters)' if test -f '6809/mrabs.u' then echo shar: will not over-write existing file "'6809/mrabs.u'" else cat << \SHAR_EOF > '6809/mrabs.u' | mrabs. converts both args to unsigned, and | remembers result sign as the sign of the left | argument. (for signed modulo) | result d contains right, sign is non-zero | if result (from mod) should be negative. | | .globl mrabs left=8. right=4. sign=3. mrabs: clr sign(s) ldd left(s) bge tryr nega negb sbca #0 std left(s) inc sign(s) tryr: ldd right(s) bge done nega negb sbca #0 std right(s) done: rts SHAR_EOF if test 422 -ne "`wc -c < '6809/mrabs.u'`" then echo shar: error transmitting "'6809/mrabs.u'" '(should have been 422 characters)' fi fi echo shar: extracting "'6809/prabs.u'" '(432 characters)' if test -f '6809/prabs.u' then echo shar: will not over-write existing file "'6809/prabs.u'" else cat << \SHAR_EOF > '6809/prabs.u' | prabs. converts both args to unsigned, and | remembers result sign as sign a eor sign b | used only by divide support | result d contains right, sign is non-zero | if result (from divide) should be negative. | | .globl prabs left=8. right=4. sign=3. prabs: clr sign(s) ldd left(s) bge tryr nega negb sbca #0 std left(s) inc sign(s) tryr: ldd right(s) bge done nega negb sbca #0 dec sign(s) std right(s) done: rts SHAR_EOF if test 432 -ne "`wc -c < '6809/prabs.u'`" then echo shar: error transmitting "'6809/prabs.u'" '(should have been 432 characters)' fi fi echo shar: extracting "'6809/sdiv.u'" '(812 characters)' if test -f '6809/sdiv.u' then echo shar: will not over-write existing file "'6809/sdiv.u'" else cat << \SHAR_EOF > '6809/sdiv.u' | signed divide | calling: (left / right) | push left | ldd right | jsr sdiv | result in d, arg popped. | left=6 right=2 sign=1 count=0 return=4 CARRY=1 .globl sdiv,div,ASSERTFAIL .globl prabs sdiv: leas -4(s) std right(s) bne nozero swi2 .byte ASSERTFAIL nozero: jsr prabs div: clr count(s) | prescale divisor inc count(s) mscl: inc count(s) aslb rola bpl mscl std right(s) ldd left(s) clr left(s) clr left+1(s) div1: subd right(s) | check subtract bcc div2 addd right(s) andcc #~CARRY bra div3 div2: orcc #CARRY div3: rol left+1(s) | roll in carry rol left(s) lsr right(s) ror right+1(s) dec count(s) bne div1 ldd left(s) tst sign(s) | sign fiddle beq nochg nega negb sbca #0 nochg: std right(s) | move return addr ldd return(s) std left(s) ldd right(s) leas 6(s) rts SHAR_EOF if test 812 -ne "`wc -c < '6809/sdiv.u'`" then echo shar: error transmitting "'6809/sdiv.u'" '(should have been 812 characters)' fi fi echo shar: extracting "'6809/shift.u'" '(317 characters)' if test -f '6809/shift.u' then echo shar: will not over-write existing file "'6809/shift.u'" else cat << \SHAR_EOF > '6809/shift.u' | Shift support for Small C v1 sa09 .globl asr asr: tstb bge okr negb bra asl okr: incb pshs b ldd 3(s) asrl: dec (s) beq return asra rorb bra asrl .globl asl asl: tstb bge okl negb bra asr okl: incb pshs b ldd 3(s) asll: dec (s) beq return aslb rola bra asll return: ldx 1(s) leas 5(s) jmp (x) SHAR_EOF if test 317 -ne "`wc -c < '6809/shift.u'`" then echo shar: error transmitting "'6809/shift.u'" '(should have been 317 characters)' fi fi echo shar: extracting "'6809/smod.u'" '(796 characters)' if test -f '6809/smod.u' then echo shar: will not over-write existing file "'6809/smod.u'" else cat << \SHAR_EOF > '6809/smod.u' | signed mod | calling: (left / right) | push left | ldd right | jsr smod | result in d, arg popped. | left=6 right=2 sign=1 count=0 return=4 CARRY=1 .globl smod,mod,ASSERTFAIL .globl mrabs smod: leas -4(s) std right(s) bne nozero swi2 .byte ASSERTFAIL nozero: jsr mrabs mod: clr count(s) | prescale divisor inc count(s) mscl: inc count(s) aslb rola bpl mscl std right(s) ldd left(s) clr left(s) clr left+1(s) mod1: subd right(s) | check subtract bcc mod2 addd right(s) andcc #~CARRY bra mod3 mod2: orcc #CARRY mod3: rol left+1(s) | roll in carry rol left(s) lsr right(s) ror right+1(s) dec count(s) bne mod1 tst sign(s) | sign fiddle beq nochg nega negb sbca #0 nochg: std right(s) | move return addr ldd return(s) std left(s) ldd right(s) leas 6(s) rts SHAR_EOF if test 796 -ne "`wc -c < '6809/smod.u'`" then echo shar: error transmitting "'6809/smod.u'" '(should have been 796 characters)' fi fi echo shar: extracting "'6809/sumul.u'" '(591 characters)' if test -f '6809/sumul.u' then echo shar: will not over-write existing file "'6809/sumul.u'" else cat << \SHAR_EOF > '6809/sumul.u' | signed/unsigned multiply | calling (left * right) | push left | ldd right | jsr [u|s]mul (same entry point) | result in d, stack is popped .globl smul,umul smul=. umul: pshs d lda 2+2(s) mul | left msb * right lsb pshs b | save high order ldb -1+3(s) | right lsb lda 3+3(s) | left lsb mul pshs d lda 3+5(s) | left lsb ldb -2+5(s) | right msb beq small | is zero? mul | no, gotta do it too tfr b,a clrb addd (s)++ | partial prod bra big small: puls d | aha! don't need third mul big: adda (s)+ pshs d ldd 4(s) | rearrange return address std 6(s) puls d leas 4(s) rts SHAR_EOF if test 591 -ne "`wc -c < '6809/sumul.u'`" then echo shar: error transmitting "'6809/sumul.u'" '(should have been 591 characters)' fi fi echo shar: done with directory "'6809'" if test ! -d '8080' then echo shar: creating directory "'8080'" mkdir '8080' fi echo shar: extracting "'8080/Makefile'" '(129 characters)' if test -f '8080/Makefile' then echo shar: will not over-write existing file "'8080/Makefile'" else cat << \SHAR_EOF > '8080/Makefile' .SUFFIXES: .o .c .asm ASSEMS = bdos.asm bdos1.asm chio8080.asm exit.asm io8080.asm sbrk.asm .c.asm: tscc $*.c all: $(ASSEMS) SHAR_EOF if test 129 -ne "`wc -c < '8080/Makefile'`" then echo shar: error transmitting "'8080/Makefile'" '(should have been 129 characters)' fi fi echo shar: extracting "'8080/arglist.c'" '(667 characters)' if test -f '8080/arglist.c' then echo shar: will not over-write existing file "'8080/arglist.c'" else cat << \SHAR_EOF > '8080/arglist.c' /* Interpret CPM argument list to produce C style argc/argv default dma buffer has it, form: --------------------------------- |count|characters ... | --------------------------------- */ int Xargc; int Xargv[30]; Xarglist(ap) char *ap; { char qc; Xargc = 0; ap[(*ap)+1] = '\0'; ap++; while (isspace(*ap)) ap++; Xargv[Xargc++] = "arg0"; if (*ap) do { if (*ap == '\'' || *ap == '\"') { qc = *ap; Xargv[Xargc++] = ++ap; while (*ap&&*ap != qc) ap++; } else { Xargv[Xargc++] = ap; while (*ap&&!isspace(*ap)) ap++; } if (!*ap) break; *ap++='\0'; while (isspace(*ap)) ap++; } while(*ap); Xargv[Xargc] = 0; } SHAR_EOF if test 667 -ne "`wc -c < '8080/arglist.c'`" then echo shar: error transmitting "'8080/arglist.c'" '(should have been 667 characters)' fi fi echo shar: extracting "'8080/bdos.c'" '(279 characters)' if test -f '8080/bdos.c' then echo shar: will not over-write existing file "'8080/bdos.c'" else cat << \SHAR_EOF > '8080/bdos.c' bdos (c, de) int c, de; { #asm ; CP/M support routine ; bdos(C,DE); ; char *DE; int C; ; returns H=B,L=A per CPM standard pop h ; hold return address pop d ; get bdos function number pop b ; get DE register argument push d push b push h call 5 mov h,b mov l,a #endasm } SHAR_EOF if test 279 -ne "`wc -c < '8080/bdos.c'`" then echo shar: error transmitting "'8080/bdos.c'" '(should have been 279 characters)' fi fi echo shar: extracting "'8080/bdos1.c'" '(105 characters)' if test -f '8080/bdos1.c' then echo shar: will not over-write existing file "'8080/bdos1.c'" else cat << \SHAR_EOF > '8080/bdos1.c' bdos1(c, de) int c, de; { /* returns only single byte (top half is 0) */ return (255 & bdos(c, de)); } SHAR_EOF if test 105 -ne "`wc -c < '8080/bdos1.c'`" then echo shar: error transmitting "'8080/bdos1.c'" '(should have been 105 characters)' fi fi echo shar: extracting "'8080/chio8080.c'" '(125 characters)' if test -f '8080/chio8080.c' then echo shar: will not over-write existing file "'8080/chio8080.c'" else cat << \SHAR_EOF > '8080/chio8080.c' #define EOL 10 getchar() { return (bdos(1,1)); } putchar (c) char c; { if (c == EOL) bdos(2,13); bdos(2,c); return c; } SHAR_EOF if test 125 -ne "`wc -c < '8080/chio8080.c'`" then echo shar: error transmitting "'8080/chio8080.c'" '(should have been 125 characters)' fi fi echo shar: extracting "'8080/exit.c'" '(51 characters)' if test -f '8080/exit.c' then echo shar: will not over-write existing file "'8080/exit.c'" else cat << \SHAR_EOF > '8080/exit.c' exit(retcode) int retcode; { #asm jmp 0 #endasm } SHAR_EOF if test 51 -ne "`wc -c < '8080/exit.c'`" then echo shar: error transmitting "'8080/exit.c'" '(should have been 51 characters)' fi fi echo shar: extracting "'8080/inout.c'" '(257 characters)' if test -f '8080/inout.c' then echo shar: will not over-write existing file "'8080/inout.c'" else cat << \SHAR_EOF > '8080/inout.c' inp(pno) char pno; { pno; #asm mov a,l sta ininst+1 ininst in 0 ; self modifying code... mov l,a xra a mov h,a ret #endasm } outp(pno, val) char pno, val; { pno; #asm mov a,l sta outinst+1 #endasm val; #asm mov a,l outinst out 0 ret #endasm } SHAR_EOF if test 257 -ne "`wc -c < '8080/inout.c'`" then echo shar: error transmitting "'8080/inout.c'" '(should have been 257 characters)' fi fi echo shar: extracting "'8080/io8080.c'" '(6129 characters)' if test -f '8080/io8080.c' then echo shar: will not over-write existing file "'8080/io8080.c'" else cat << \SHAR_EOF > '8080/io8080.c' /* Basic CP/M file I/O: fopen,fclose,fgetc,fputc,feof Original: Paul Tarvydas Fixed by: Chris Lewis */ #include <stdio.h> #define EOL 10 #define EOL2 13 #define CPMEOF 26 #define CPMERR 255 #define UNIT_OFFSET 3 #define CPMCIN 1 #define CPMCOUT 2 #define READ_EOF 3 #define SETDMA 26 #define DEFAULT_DMA 128 #define CPMREAD 20 #define CPMWR 21 #define WRITE 2 #define READ 1 #define FREE 0 #define NBUFFS 4 #define BUFSIZ 512 #define FCBSIZ 33 #define ALLBUFFS 2048 #define ALLFCBS 132 #define CPMERA 19 #define CPMCREAT 22 #define CPMOPEN 15 #define NBLOCKS 4 #define BLKSIZ 128 #define BKSP 8 #define CTRLU 21 #define FWSP ' ' #define CPMCLOSE 16 char buffs[ALLBUFFS], /* disk buffers */ fcbs[ALLFCBS]; /* fcbs for buffers */ int bptr[NBUFFS]; /* ptrs into buffers */ int modes[NBUFFS]; /* mode for each open file */ int eptr[NBUFFS]; /* buffers' ends */ char eofstdin; /* flag end of file on stdin */ fgetc(unit) int unit; { int c; while ((c = Xfgetc(unit)) == EOL2); return c; } Xfgetc(unit) int unit; { int i; int c; char *buff; char *fcba; if ((unit == stdin) & !eofstdin) { c = bdos1(CPMCIN, 0); if (c == 4) { eofstdin = 1; return (EOF); } else if (c == 3) exit (1); else { if (c == EOL2) { c = EOL; bdos (CPMCOUT, EOL); } return (c); } } if (modes[unit = unit - UNIT_OFFSET] == READ) { if (bptr[unit] >= eptr[unit]) { fcba = fcbaddr(unit); /* fill da buffer again */ i = 0; /* block counter */ buff = buffaddr(unit); /* dma ptr */ /* if buffer wasn't totally filled last time, we already eof */ if (eptr[unit] == buffaddr(unit + 1)) do { bdos(SETDMA, buff); if (0!=bdos1(CPMREAD, fcba)) break; buff = buff + BLKSIZ; } while (++i<NBLOCKS); bdos(SETDMA, DEFAULT_DMA); /* if i still 0, no blocks read =>eof*/ if (i==0) { modes[unit] = READ_EOF; return EOF; } /* o.k. set start & end ptrs */ eptr[unit] = (bptr[unit]=buffaddr(unit)) + (i * BLKSIZ); } c = (*(bptr[unit]++)) & 0xff; if (c == CPMEOF) { c = EOF; modes[unit] = READ_EOF; } return c; } return EOF; } fclose(unit) int unit; { int i; if ((unit==stdin)|(unit==stdout)|(unit==stderr)) return NULL; if (modes[unit = unit - UNIT_OFFSET] != FREE) { if (modes[unit] == WRITE) fflush(unit + UNIT_OFFSET); modes[unit] = FREE; return bdos1(CPMCLOSE, fcbaddr(unit)); } return EOF; } fflush(unit) int unit; { char *buffa; char *fcba; if ((unit!=stdin)|(unit!=stdout)|(unit!=stderr)) { /* put an eof at end of file */ fputc(CPMEOF, unit); if (bptr[unit = unit - UNIT_OFFSET] != (buffa = buffaddr(unit))) { /* some chars in buffer - flush them */ fcba = fcbaddr(unit); do { bdos(SETDMA, buffa); if (0 != bdos1(CPMWR, fcba)) return (EOF); } while (bptr[unit] > (buffa=buffa+BLKSIZ)); bdos(SETDMA, DEFAULT_DMA); } } return NULL; } fputc(c, unit) char c; int unit; { char *buffa; char *fcba; if (c == EOL) fputc(EOL2, unit); if ((unit == stdout) | (unit == stderr)) { bdos(CPMCOUT, c); return c; } if (WRITE == modes[unit = unit - UNIT_OFFSET]) { if (bptr[unit] >= eptr[unit]) { /* no room - dump buffer */ fcba = fcbaddr(unit); buffa=buffaddr(unit); while (buffa < eptr[unit]) { bdos(SETDMA, buffa); if (0 != bdos1(CPMWR, fcba)) break; buffa = buffa + BLKSIZ; } bdos(SETDMA, DEFAULT_DMA); bptr[unit] = buffaddr(unit); if (buffa < eptr[unit]) return EOF; } *(bptr[unit]++) = c; return c; } return EOF; } allocunitno() { int i; /* returns # of first free buffer, EOF if none */ /* buffer is not reserved (ie. mode remains FREE) */ for (i = 0; i < NBUFFS; ++i) if (modes[i] == FREE) break; if (i >= NBUFFS) return EOF; else return (i + UNIT_OFFSET); } fopen(name, mode) char *name, *mode; { int fileno, fno2; if (EOF != (fileno = allocunitno())) { /* internal file # excludes units 0,1 & 2 since there's no buffers associated with these units */ movname(clearfcb(fcbaddr(fno2 = fileno - UNIT_OFFSET)), name); if ('r' == *mode) { if (bdos1(CPMOPEN, fcbaddr(fno2)) != CPMERR) { modes[fno2] = READ; /* ptr>bufsiz => buffer empty*/ eptr[fno2] = bptr[fno2] = buffaddr(fno2+1); return fileno; } } else if ('w' == *mode) { bdos(CPMERA, fcbaddr(fno2)); if (bdos1(CPMCREAT, fcbaddr(fno2)) != CPMERR){ modes[fno2] = WRITE; bptr[fno2] = buffaddr(fno2); eptr[fno2] = buffaddr(fno2+1); return fileno; } } } return NULL; } clearfcb(fcb) char fcb[]; { int i; for (i=0; i<FCBSIZ; fcb[i++] = 0); /* blank out name field */ for (i=1; i<12; fcb[i++] = ' '); return fcb; } movname(fcb, str) char fcb[], *str; { int i; char c; i = 1; /* first char of name @ pos 1 */ *fcb = 0; if (':' == str[1]) { c = toupper(str[0]); if (('A' <= c) & ('B' >= c)) { *fcb = (c - 'A' + 1); str++; str++; } } while ((NULL != *str) & (i<9)) { /* up to 8 chars into file name field */ if ('.' == *str) break; fcb[i++] = toupper(*str++); } /* strip off excess chars - up to '.' (beginning of extension name ) */ while ((NULL != *str) & ((*str) != '.')) ++str; if (*str) /* '.' is first char of *str now */ /* copy 3 chars of ext. if there */ for ( /* first char of ext @ pos 9 (8+1)*/ i = 8; /* '.' is stripped by ++ 1st time */ /* around */ (NULL != *++str) & (12 > ++i); fcb[i] = toupper(*str) ); return fcb; } stdioinit() { int i; eofstdin = 0; for (i=0; i<NBUFFS; modes[i++] = FREE); } fcbaddr(unit) int unit; { /* returns address of fcb associated with given unit - unit taken with origin 0 (ie. std's not included) */ return &fcbs[unit * FCBSIZ]; } buffaddr(unit) int unit; { return &buffs[unit * BUFSIZ]; } feof (unit) FILE *unit; { if ((unit == stdin) & eofstdin) return 1; if (modes[unit - UNIT_OFFSET] == READ_EOF) return 1; return 0; } SHAR_EOF if test 6129 -ne "`wc -c < '8080/io8080.c'`" then echo shar: error transmitting "'8080/io8080.c'" '(should have been 6129 characters)' fi fi echo shar: extracting "'8080/cret.asm'" '(478 characters)' if test -f '8080/cret.asm' then echo shar: will not over-write existing file "'8080/cret.asm'" else cat << \SHAR_EOF > '8080/cret.asm' ; Run time start off for Small C. cseg sphl ; save the stack pointer shld ?stksav lhld 6 ; pick up core top lxi d,-10 ; decrease by 10 for safety dad d sphl ; set stack pointer call stdioinit ; initialize stdio call Xarglist lhld Xargc push h lxi h,Xargv push h call main ; call main program pop d pop d lhld ?stksav ; restore stack pointer ret ; go back to CCP dseg ?stksav ds 2 extrn stdioinit extrn Xarglist extrn Xargc extrn Xargv extrn main end SHAR_EOF if test 478 -ne "`wc -c < '8080/cret.asm'`" then echo shar: error transmitting "'8080/cret.asm'" '(should have been 478 characters)' fi fi echo shar: extracting "'8080/crun.asm'" '(4286 characters)' if test -f '8080/crun.asm' then echo shar: will not over-write existing file "'8080/crun.asm'" else cat << \SHAR_EOF > '8080/crun.asm' ; ;***************************************************** ; * ; runtime library for small C compiler * ; * ; c.s - runtime routine for basic C code * ; * ; Ron Cain * ; * ;***************************************************** ; cseg ; public ?gchar,?gint,?pchar,?pint public ?sxt public ?or,?and,?xor public ?eq,?ne,?gt,?le,?ge,?lt,?uge,?ult,?ugt,?ule public ?asr,?asl public ?sub,?neg,?com,?lneg,?bool,?mul,?div public ?case,brkend,Xstktop public etext public edata ; ; fetch char from (HL) and sign extend into HL ?gchar: mov a,m ?sxt: mov l,a rlc sbb a mov h,a ret ; fetch int from (HL) ?gint: mov a,m inx h mov h,m mov l,a ret ; store char from HL into (DE) ?pchar: mov a,l stax d ret ; store int from HL into (DE) ?pint: mov a,l stax d inx d mov a,h stax d ret ; "or" HL and DE into HL ?or: mov a,l ora e mov l,a mov a,h ora d mov h,a ret ; "xor" HL and DE into HL ?xor: mov a,l xra e mov l,a mov a,h xra d mov h,a ret ; "and" HL and DE into HL ?and: mov a,l ana e mov l,a mov a,h ana d mov h,a ret ; ;......logical operations: HL set to 0 (false) or 1 (true) ; ; DE == HL ?eq: call ?cmp rz dcx h ret ; DE != HL ?ne: call ?cmp rnz dcx h ret ; DE > HL [signed] ?gt: xchg call ?cmp rc dcx h ret ; DE <= HL [signed] ?le: call ?cmp rz rc dcx h ret ; DE >= HL [signed] ?ge: call ?cmp rnc dcx h ret ; DE < HL [signed] ?lt: call ?cmp rc dcx h ret ; DE >= HL [unsigned] ?uge: call ?ucmp rnc dcx h ret ; DE < HL [unsigned] ?ult: call ?ucmp rc dcx h ret ; DE > HL [unsigned] ?ugt: xchg call ?ucmp rc dcx h ret ; DE <= HL [unsigned] ?ule: call ?ucmp rz rc dcx h ret ; signed compare of DE and HL ; carry is sign of difference [set => DE < HL] ; zero is zero/non-zero ?cmp: mov a,e sub l mov e,a mov a,d sbb h lxi h,1 ;preset true jm ?cmp1 ora e ;resets carry ret ?cmp1: ora e stc ret ; unsigned compare of DE and HL ; carry is sign of difference [set => DE < HL] ; zero is zero/non-zero ?ucmp: mov a,d cmp h jnz ?ucmp1 mov a,e cmp l ?ucmp1: lxi h,1 ;preset true ret ; shift DE right arithmetically by HL, move to HL ?asr: xchg ?asr1: dcr e rm mov a,h ral mov a,h rar mov h,a mov a,l rar mov l,a jmp ?asr1 ; shift DE left arithmetically by HL, move to HL ?asl: xchg ?asl1: dcr e rm dad h jmp ?asl1 ; HL = DE - HL ?sub: mov a,e sub l mov l,a mov a,d sbb h mov h,a ret ; HL = -HL ?neg: call ?com inx h ret ; HL = ~HL ?com: mov a,h cma mov h,a mov a,l cma mov l,a ret ; HL = !HL ?lneg: mov a,h ora l jz ?lneg1 lxi h,0 ret ?lneg1: inx h ret ; HL = !!HL ?bool: call ?lneg jmp ?lneg ; ; HL = DE * HL [signed] ?mul: mov b,h mov c,l lxi h,0 ?mul1: mov a,c rrc jnc ?mul2 dad d ?mul2: xra a mov a,b rar mov b,a mov a,c rar mov c,a ora b rz xra a mov a,e ral mov e,a mov a,d ral mov d,a ora e rz jmp ?mul1 ; HL = DE / HL, DE = DE % HL ?div: mov b,h mov c,l mov a,d xra b push psw mov a,d ora a cm ?deneg mov a,b ora a cm ?bcneg mvi a,16 push psw xchg lxi d,0 ?div1: dad h call ?rdel jz ?div2 call ?cmpbd jm ?div2 mov a,l ori 1 mov l,a mov a,e sub c mov e,a mov a,d sbb b mov d,a ?div2: pop psw dcr a jz ?div3 push psw jmp ?div1 ?div3: pop psw rp call ?deneg xchg call ?deneg xchg ret ; {DE = -DE} ?deneg: mov a,d cma mov d,a mov a,e cma mov e,a inx d ret ; {BC = -BC} ?bcneg: mov a,b cma mov b,a mov a,c cma mov c,a inx b ret ; {DE <r<r 1} ?rdel: mov a,e ral mov e,a mov a,d ral mov d,a ora e ret ; {BC : DE} ?cmpbd: mov a,e sub c mov a,d sbb b ret ; case jump ?case: xchg ;switch value to DE pop h ;get table address ?case1: call ?case4 ;get case value mov a,e cmp c ;equal to switch value ? jnz ?case2 ;no mov a,d cmp b ;equal to switch value ? jnz ?case2 ;no call ?case4 ;get case label jz ?case3 ;end of table, go to default push b ret ;case jump ?case2: call ?case4 ;get case label jnz ?case1 ;next case ?case3: dcx h dcx h dcx h mov d,m dcx h mov e,m xchg pchl ;default jump ?case4: mov c,m inx h mov b,m inx h mov a,c ora b ret ; ; ; Xstktop: lxi h,0 ;return current stack pointer (for sbrk) dad sp ret cseg etext: dseg brkend: dw edata ;current "break" edata: ; ; ; end SHAR_EOF if test 4286 -ne "`wc -c < '8080/crun.asm'`" then echo shar: error transmitting "'8080/crun.asm'" '(should have been 4286 characters)' fi fi echo shar: done with directory "'8080'" if test ! -d 'vax' then echo shar: creating directory "'vax'" mkdir 'vax' fi echo shar: extracting "'vax/B2test.c'" '(655 characters)' if test -f 'vax/B2test.c' then echo shar: will not over-write existing file "'vax/B2test.c'" else cat << \SHAR_EOF > 'vax/B2test.c' #include <stdio.h> main () { FILE *infile; FILE *outfile; int c; puts("Starting input only"); if ((infile = fopen("b2test.dat","r")) == NULL ) { puts("could not open input file"); exit(1); } while (putchar(fgetc(infile)) != EOF); puts("end of input file"); fclose(infile); puts("starting copy"); if ((infile = fopen("b2test.dat","r")) == NULL) { puts("could not open input file for copy"); exit(1); } if ((outfile = fopen("b2test.out","w")) == NULL) { puts("could not open output file"); exit(1); } while ((c = fgetc(infile)) != EOF) { fputc(c, outfile); } puts("finished output file"); fclose(infile); fclose(outfile); } SHAR_EOF if test 655 -ne "`wc -c < 'vax/B2test.c'`" then echo shar: error transmitting "'vax/B2test.c'" '(should have been 655 characters)' fi fi echo shar: extracting "'vax/Makefile'" '(169 characters)' if test -f 'vax/Makefile' then echo shar: will not over-write existing file "'vax/Makefile'" else cat << \SHAR_EOF > 'vax/Makefile' .SUFFIXES: .o .c .c.o: /u/clewis/lib/sccvax -c $*.c as -o $*.o $*.s OBJ = crunvax.o chiovax.o iovax.o libl.a: $(OBJ) crt0.o ar ru libl.a $(OBJ) ucb ranlib libl.a SHAR_EOF if test 169 -ne "`wc -c < 'vax/Makefile'`" then echo shar: error transmitting "'vax/Makefile'" '(should have been 169 characters)' fi fi echo shar: extracting "'vax/b2test.dat'" '(12 characters)' if test -f 'vax/b2test.dat' then echo shar: will not over-write existing file "'vax/b2test.dat'" else cat << \SHAR_EOF > 'vax/b2test.dat' ehllo hello SHAR_EOF if test 12 -ne "`wc -c < 'vax/b2test.dat'`" then echo shar: error transmitting "'vax/b2test.dat'" '(should have been 12 characters)' fi fi echo shar: extracting "'vax/chiovax.c'" '(488 characters)' if test -f 'vax/chiovax.c' then echo shar: will not over-write existing file "'vax/chiovax.c'" else cat << \SHAR_EOF > 'vax/chiovax.c' #define EOL 10 getchar() { #asm movl $0,r0 pushl $1 pushal buff pushl $0 calls $3,Xread cvtbl buff,r0 .data buff: .space 1 .text #endasm } #asm .set read,3 Xread: .word 0x0000 chmk $read bcc noerror2 jmp cerror noerror2: ret cerror: bpt #endasm putchar (c) char c; { c; #asm cvtlb r0,buff pushl $1 pushal buff pushl $1 calls $3,Xwrite cvtbl buff,r0 #endasm } #asm .set write,4 Xwrite: .word 0x0000 chmk $write bcc noerror jmp cerror noerror: ret #endasm SHAR_EOF if test 488 -ne "`wc -c < 'vax/chiovax.c'`" then echo shar: error transmitting "'vax/chiovax.c'" '(should have been 488 characters)' fi fi echo shar: extracting "'vax/crt0.c'" '(362 characters)' if test -f 'vax/crt0.c' then echo shar: will not over-write existing file "'vax/crt0.c'" else cat << \SHAR_EOF > 'vax/crt0.c' #asm # C runtime startoff .set exit,1 .globl start .globl _main .globl _exit # # C language startup routine start: .word 0x0000 subl2 $8,sp movl 8(sp),4(sp) # argc movab 12(sp),r0 movl r0,(sp) # argv jsb _main addl2 $8,sp pushl r0 chmk $exit #endasm exit(x) int x; { x; #asm pushl r0 calls $1,exit2 exit2: .word 0x0000 chmk $exit #endasm } SHAR_EOF if test 362 -ne "`wc -c < 'vax/crt0.c'`" then echo shar: error transmitting "'vax/crt0.c'" '(should have been 362 characters)' fi fi echo shar: extracting "'vax/crt0.s'" '(760 characters)' if test -f 'vax/crt0.s' then echo shar: will not over-write existing file "'vax/crt0.s'" else cat << \SHAR_EOF > 'vax/crt0.s' # Small C VAX # Coder (2.1,83/04/05) # Front End (2.1,83/03/20) .globl lneg .globl case .globl eq .globl ne .globl lt .globl le .globl gt .globl ge .globl ult .globl ule .globl ugt .globl uge .globl bool .text ##asm # C runtime startoff .set exit,1 .globl start .globl _main .globl _exit # # C language startup routine start: .word 0x0000 subl2 $8,sp movl 8(sp),4(sp) # argc movab 12(sp),r0 movl r0,(sp) # argv jsb _main addl2 $8,sp pushl r0 chmk $exit #exit(x) int x; { .align 1 _exit: # x; moval 4(sp),r0 movl (r0),r0 ##asm pushl r0 calls $1,exit2 exit2: .word 0x0000 chmk $exit #} LL1: rsb .data .globl _etext .globl _edata .globl _exit #0 error(s) in compilation # literal pool:0 # global pool:42 # Macro pool:43 SHAR_EOF if test 760 -ne "`wc -c < 'vax/crt0.s'`" then echo shar: error transmitting "'vax/crt0.s'" '(should have been 760 characters)' fi fi echo shar: extracting "'vax/crunvax.c'" '(1268 characters)' if test -f 'vax/crunvax.c' then echo shar: will not over-write existing file "'vax/crunvax.c'" else cat << \SHAR_EOF > 'vax/crunvax.c' #asm # csa09 Small C v1 comparison support # All are dyadic except for lneg. .globl eq .globl ne .globl lt .globl le .globl gt .globl ge .globl ult .globl ule .globl ugt .globl uge .globl lneg .globl bool .globl case .globl _Xstktop eq: cmpl r0,4(sp) jeql true jbr false ne: cmpl r0,4(sp) jneq true jbr false lt: cmpl r0,4(sp) jgtr true jbr false le: cmpl r0,4(sp) jgeq true jbr false gt: cmpl r0,4(sp) jlss true jbr false ge: cmpl r0,4(sp) jleq true jbr false ult: cmpl r0,4(sp) jgtru true jbr false ule: cmpl r0,4(sp) jgequ true jbr false ugt: cmpl r0,4(sp) jlequ true jbr false uge: cmpl r0,4(sp) jlssu true jbr false lneg: cmpl r0,$0 jeql ltrue movl $0,r0 rsb ltrue: movl $1,r0 rsb bool: jsb lneg jbr lneg true: movl $1,r0 movl (sp),r3 addl2 $8,sp jmp (r3) false: movl $0,r0 movl (sp),r3 addl2 $8,sp jmp (r3) _Xstktop: movl sp,r0 rsb # Case jump, value is in r0, case table in (sp) case: movl (sp)+,r1 # pick up case pointer casl: movl (r1)+,r2 # pick up value. movl (r1)+,r3 # pick up label. bneq notdef # if not default, check it jmp (r2) # is default, go do it. notdef: cmpl r0,r2 # compare table value with switch value bneq casl # go for next table ent if not jmp (r3) # otherwise, jump to it. #endasm SHAR_EOF if test 1268 -ne "`wc -c < 'vax/crunvax.c'`" then echo shar: error transmitting "'vax/crunvax.c'" '(should have been 1268 characters)' fi fi echo shar: extracting "'vax/iovax.c'" '(1593 characters)' if test -f 'vax/iovax.c' then echo shar: will not over-write existing file "'vax/iovax.c'" else cat << \SHAR_EOF > 'vax/iovax.c' /* VAX fopen, fclose, fgetc, fputc, feof * gawd is this gross - no buffering! */ #include <stdio.h> static feofed[20]; static char charbuf[1]; static retcode; fopen(filnam, mod) char *filnam, *mod; { if (*mod == 'w') { filnam; #asm pushl r0 calls $1,zunlink #endasm filnam; #asm pushl $0644 pushl r0 calls $2,zcreat movl r0,_retcode #endasm if (retcode < 0) { return(NULL); } else return(retcode); } filnam; #asm pushl $0 # read mode pushl r0 calls $2,zopen movl r0,_retcode #endasm feofed[retcode] = 0; if (retcode < 0) return (NULL); else return(retcode); } fclose(unit) int unit; { unit; #asm pushl r0 calls $1,zclose #endasm } fgetc(unit) int unit; { unit; #asm pushl $1 pushl $_charbuf pushl r0 calls $3,zread movl r0,_retcode #endasm if (retcode <= 0) { feofed[unit] = 1; return(EOF); } else return(charbuf[0]); } fputc(c, unit) int c, unit; { charbuf[0] = c; unit; #asm pushl $1 pushl $_charbuf pushl r0 calls $3,zwrite #endasm return(c); } feof(unit) int unit; { if (feofed[unit]) return(1); else return(NULL); } /* Assembler assists */ #asm .set unlink,10 .set creat,8 .set open,5 .set close,6 .set read,3 .set write,4 zunlink: .word 0x0000 chmk $unlink bcc noerr jmp cerror zcreat: .word 0x0000 chmk $creat bcc noerr jmp cerror zopen: .word 0x0000 chmk $open bcc noerr jmp cerror zclose: .word 0x0000 chmk $close bcc noerr jmp cerror zread: .word 0x0000 chmk $read bcc noerr jmp cerror zwrite: .word 0x0000 chmk $write bcc noerr jmp cerror cerror: mnegl $1,r0 ret noerr: ret #endasm SHAR_EOF if test 1593 -ne "`wc -c < 'vax/iovax.c'`" then echo shar: error transmitting "'vax/iovax.c'" '(should have been 1593 characters)' fi fi echo shar: extracting "'vax/optest.c'" '(2294 characters)' if test -f 'vax/optest.c' then echo shar: will not over-write existing file "'vax/optest.c'" else cat << \SHAR_EOF > 'vax/optest.c' #include <stdio.h> #define chkstk 1 #define NOSUP 1 int address; int ret; int locaddr; int i; int *temp; #ifdef vax #define INTSIZE 4 #else #define INTSIZE 2 #endif int fred[30]; main(){ int x; puts("Starting test"); i = 1; address = &x; locaddr = 0; address = address + INTSIZE; temp = address; ret = *temp; fred[3] = 3; test(fred[3], 3, "fred[3] = 3"); test(INTSIZE, sizeof(int), "INTSIZE"); test(sizeof(char), 1, "sizeof char"); test(1 + 4, 1, "(should fail) 1+4"); test(1022 + 5, 1027, "1022 + 5"); test(4 + 5, 9, "4 + 5"); test(1022 * 3, 3066, "1022 * 3"); test(4 * - 1, -4, "4 * - 1"); test(4 * 5, 20, "4 * 5"); test(1000 - 999, 1, "1000 - 999"); test(1000 - 1200, -200, "1000 - 1200"); test(-1 - -1, 0, "-1 - -1"); test(4 >> 2, 1, "4 >> 2"); test(1234 >> 1, 617, "1234 >> 1"); test(4 << 2, 16, "4 << 2"); test(1000 << 1, 2000, "1000 << 1"); test(1001 % 10, 1, "1001 % 10"); test(3 % 10, 3, "3 % 10"); test(10 % 4, 2, "10 % 4"); test(1000 / 5, 200, "1000 / 5"); test(3 / 10, 0, "3 / 10"); test(10 / 3, 3, "10 / 3"); test(1000 == 32767, 0, "1000 == 32767"); test(1000 == 1000, 1, "1000 == 1000"); test(1 != 0, 1, "1 != 0"); test(1 < -1, 0, "1 < -1"); test(1 < 2, 1, "1 < 2"); test(1 != 1, 0, "1 != 1"); test(2 && 1, 1, "2 && 1"); test(0 && 1, 0, "0 && 1"); test(1 && 0, 0, "1 && 0"); test(0 && 0, 0, "0 && 0"); test(1000 || 1, 1, "1000 || 1"); test(1000 || 0, 1, "1000 || 0"); test(0 || 1, 1, "0 || 1"); test(0 || 0, 0, "0 || 0"); test(!2, 0, "!2"); test(!0, 1, "!0"); test(~1, -2, "~1"); test(2 ^ 1, 3, "2 ^ 1"); test(0 ^ 0, 0, "0 ^ 0"); test(1 ^ 1, 0, "1 ^ 1"); test(5 ^ 6, 3, "5 ^ 6"); test((0 < 1) ? 1 : 0, 1, "(0 < 1) ? 1 : 0"); test((1000 > 1000) ? 0: 1, 1, "(1000 > 1000) ? 0 : 1"); puts("ending test"); } test(t, real, testn) int t; char *testn; int real;{ if (t != real) { fputs(testn, stdout); fputs(" failed\n", stdout); fputs("Should be: ", stdout); printn(real, 10, stdout); fputs(" was: ", stdout); printn(t, 10, stdout); putchar('\n'); prompt(); } if (*temp != ret) { puts("retst"); prompt(); } #ifdef chkstk if (locaddr == 0) locaddr = &t; else if (locaddr != &t) { puts("locst during"); puts(testn); prompt(); } #endif } prompt() { puts("hit any key to continue"); getchar(); } SHAR_EOF if test 2294 -ne "`wc -c < 'vax/optest.c'`" then echo shar: error transmitting "'vax/optest.c'" '(should have been 2294 characters)' fi fi echo shar: extracting "'vax/vscc'" '(151 characters)' if test -f 'vax/vscc' then echo shar: will not over-write existing file "'vax/vscc'" else cat << \SHAR_EOF > 'vax/vscc' if ../src/sccvax -c $1.c then if as -o $1.o $1.s then rm $1.s ld -o $1 ../crunvax/crt0.o $1.o ../libc/vaxlibc.a ../crunvax/libl.a fi fi SHAR_EOF if test 151 -ne "`wc -c < 'vax/vscc'`" then echo shar: error transmitting "'vax/vscc'" '(should have been 151 characters)' fi fi echo shar: done with directory "'vax'" if test ! -d 'lib' then echo shar: creating directory "'lib'" mkdir 'lib' fi echo shar: extracting "'lib/Makefile'" '(815 characters)' if test -f 'lib/Makefile' then echo shar: will not over-write existing file "'lib/Makefile'" else cat << \SHAR_EOF > 'lib/Makefile' .SUFFIXES: .o .obj .c .asm .c.o: ../src/sccvax $*.c as -o $*.o $*.s rm $*.s ASSEMS =\ abs.asm atoi.asm binary.asm\ charclass.asm fgets.asm fputs.asm\ getchar.asm gets.asm index.asm\ itoa.asm printn.asm putchar.asm\ puts.asm reverse.asm shell.asm\ strcat.asm strcmp.asm strcpy.asm\ strlen.asm rand.asm \ strncat.asm strncmp.asm strncpy.asm OBJ =\ abs.o atoi.o binary.o\ charclass.o fgets.o fputs.o\ getchar.o gets.o index.o\ itoa.o printn.o putchar.o\ puts.o reverse.o shell.o\ strcat.o strcmp.o strcpy.o\ strlen.o rand.o \ strncat.o strncmp.o strncpy.o .c.asm: ../src/scc8080 $*.c mv $*.s $*.asm all: $(ASSEMS) vaxlibc.a: $(OBJ) ar ur vaxlibc.a $(OBJ) ranlib vaxlibc.a SHAR_EOF if test 815 -ne "`wc -c < 'lib/Makefile'`" then echo shar: error transmitting "'lib/Makefile'" '(should have been 815 characters)' fi fi echo shar: extracting "'lib/abs.c'" '(114 characters)' if test -f 'lib/abs.c' then echo shar: will not over-write existing file "'lib/abs.c'" else cat << \SHAR_EOF > 'lib/abs.c' /* abs (num) return absolute value */ abs(num) int num;{ if (num < 0) return (-num); else return (num); } SHAR_EOF if test 114 -ne "`wc -c < 'lib/abs.c'`" then echo shar: error transmitting "'lib/abs.c'" '(should have been 114 characters)' fi fi echo shar: extracting "'lib/atoi.c'" '(322 characters)' if test -f 'lib/atoi.c' then echo shar: will not over-write existing file "'lib/atoi.c'" else cat << \SHAR_EOF > 'lib/atoi.c' #include <stdio.h> #define EOL 10 atoi(s) char s[];{ int i,n,sign; for (i=0; (s[i] == ' ') | (s[i] == EOL) | (s[i] == '\t'); ++i) ; sign = 1; switch(s[i]){ case '-': sign = -1; /* and fall through */ case '+': ++i; break; } for(n = 0; isdigit(s[i]); ++i) n = 10 * n + s[i] - '0'; return (sign * n); } SHAR_EOF if test 322 -ne "`wc -c < 'lib/atoi.c'`" then echo shar: error transmitting "'lib/atoi.c'" '(should have been 322 characters)' fi fi echo shar: extracting "'lib/binary.c'" '(412 characters)' if test -f 'lib/binary.c' then echo shar: will not over-write existing file "'lib/binary.c'" else cat << \SHAR_EOF > 'lib/binary.c' /* binary search for string word in table[0] .. table[n-1] * reference CPL pg. 125 */ #include <stdio.h> binary(word, table, n) char *word; int table[]; int n;{ int low, high, mid, cond; low = 0; high = n - 1; while (low <= high){ mid = (low + high) / 2; if ((cond = strcmp(word, table[mid])) < 0) high = mid - 1; else if (cond > 0) low = mid + 1; else return (mid); } return (-1); } SHAR_EOF if test 412 -ne "`wc -c < 'lib/binary.c'`" then echo shar: error transmitting "'lib/binary.c'" '(should have been 412 characters)' fi fi echo shar: extracting "'lib/charclass.c'" '(588 characters)' if test -f 'lib/charclass.c' then echo shar: will not over-write existing file "'lib/charclass.c'" else cat << \SHAR_EOF > 'lib/charclass.c' isalpha(c) char c;{ if ((c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z')) return(1); else return(0); } isupper(c) char c;{ if (c >= 'A' & c <= 'Z') return(1); else return(0); } islower(c) char c;{ if (c >= 'a' & c <= 'z') return(1); else return(0); } isdigit(c) char c;{ if (c >= '0' & c <= '9') return(1); else return(0); } isspace(c) char c;{ if (c == ' ' | c == '\t' | c == '\n') return(1); else return(0); } toupper(c) char c;{ return ((c >= 'a' && c <= 'z') ? c - 32: c); } tolower(c) char c;{ return((c >= 'A' && c <= 'Z') ? c + 32: c); } SHAR_EOF if test 588 -ne "`wc -c < 'lib/charclass.c'`" then echo shar: error transmitting "'lib/charclass.c'" '(should have been 588 characters)' fi fi echo shar: extracting "'lib/fgets.c'" '(302 characters)' if test -f 'lib/fgets.c' then echo shar: will not over-write existing file "'lib/fgets.c'" else cat << \SHAR_EOF > 'lib/fgets.c' /* #include <stdio.h> */ #define NULL 0 #define FILE char fgets(s, n, iop) int n; char *s; register FILE *iop; { register c; register char *cs; cs = s; while (--n>0 && (c = fgetc(iop))>=0) { *cs++ = c; if (c=='\n') break; } if (c<0 && cs==s) return(NULL); *cs++ = '\0'; return(s); } SHAR_EOF if test 302 -ne "`wc -c < 'lib/fgets.c'`" then echo shar: error transmitting "'lib/fgets.c'" '(should have been 302 characters)' fi fi echo shar: extracting "'lib/fputs.c'" '(92 characters)' if test -f 'lib/fputs.c' then echo shar: will not over-write existing file "'lib/fputs.c'" else cat << \SHAR_EOF > 'lib/fputs.c' #include <stdio.h> fputs(str, fp) FILE *fp; char *str; { while(*str) fputc(*str++, fp); } SHAR_EOF if test 92 -ne "`wc -c < 'lib/fputs.c'`" then echo shar: error transmitting "'lib/fputs.c'" '(should have been 92 characters)' fi fi echo shar: extracting "'lib/getchar.c'" '(56 characters)' if test -f 'lib/getchar.c' then echo shar: will not over-write existing file "'lib/getchar.c'" else cat << \SHAR_EOF > 'lib/getchar.c' #include <stdio.h> getchar() { return(fgetc(stdin)); } SHAR_EOF if test 56 -ne "`wc -c < 'lib/getchar.c'`" then echo shar: error transmitting "'lib/getchar.c'" '(should have been 56 characters)' fi fi echo shar: extracting "'lib/gets.c'" '(451 characters)' if test -f 'lib/gets.c' then echo shar: will not over-write existing file "'lib/gets.c'" else cat << \SHAR_EOF > 'lib/gets.c' #include <stdio.h> #define EOL 10 #define BKSP 8 #define CTRLU 0x15 gets(s) char *s; { char c, *ts; ts = s; while ((c = getchar()) != EOL && (c != EOF)) { if (c == BKSP) { if (ts > s) { --ts; /* CPM already echoed */ putchar(' '); putchar(BKSP); } } else if (c == CTRLU) { ts = s; putchar(EOL); putchar('#'); } else (*ts++) = c; } if ((c == EOF) && (ts == s)) return NULL; (*ts) = NULL; return s; } SHAR_EOF if test 451 -ne "`wc -c < 'lib/gets.c'`" then echo shar: error transmitting "'lib/gets.c'" '(should have been 451 characters)' fi fi echo shar: extracting "'lib/index.c'" '(284 characters)' if test -f 'lib/index.c' then echo shar: will not over-write existing file "'lib/index.c'" else cat << \SHAR_EOF > 'lib/index.c' /* index - find index of string t in s * reference CPL 67. */ #include <stdio.h> #define EOS 0 index(s, t) char s[], t[];{ int i, j, k; for (i = 0; s[i] != EOS; i++){ k=0; for (j=i;t[k]!=EOS & s[j]==t[k]; i++) j++; ; if (t[k] == EOS) return(i); } return(-1); } SHAR_EOF if test 284 -ne "`wc -c < 'lib/index.c'`" then echo shar: error transmitting "'lib/index.c'" '(should have been 284 characters)' fi fi echo shar: extracting "'lib/itoa.c'" '(224 characters)' if test -f 'lib/itoa.c' then echo shar: will not over-write existing file "'lib/itoa.c'" else cat << \SHAR_EOF > 'lib/itoa.c' #include <stdio.h> #define EOS 0 itoa(n,s) char s[];int n;{ int i,sign; if((sign = n) < 0) n = -n; i = 0; do { s[i++] = n % 10 + '0'; }while ((n = n/10) > 0); if (sign < 0) s[i++] = '-'; s[i] = EOS; reverse(s); } SHAR_EOF if test 224 -ne "`wc -c < 'lib/itoa.c'`" then echo shar: error transmitting "'lib/itoa.c'" '(should have been 224 characters)' fi fi echo shar: extracting "'lib/lorder8080'" '(350 characters)' if test -f 'lib/lorder8080' then echo shar: will not over-write existing file "'lib/lorder8080'" else cat << \SHAR_EOF > 'lib/lorder8080' grep public $* | sed 's/: public// /?/d s?\([^ ]*\)[ ]*\(.*\)?\2 \1? s/\.asm//'> /tmp/symdef$$ grep extrn $* | sed 's/: extrn// s/\.asm// s?\([^ ]*\)[ ]*\(.*\)?\2 \1? /?/d' > /tmp/symref$$ sort /tmp/symdef$$ -o /tmp/symdef$$ sort /tmp/symref$$ -o /tmp/symref$$ join /tmp/symref$$ /tmp/symdef$$ | sed 's/[^ ]* *//' rm /tmp/symdef$$ /tmp/symref$$ SHAR_EOF if test 350 -ne "`wc -c < 'lib/lorder8080'`" then echo shar: error transmitting "'lib/lorder8080'" '(should have been 350 characters)' fi fi echo shar: extracting "'lib/printn.c'" '(371 characters)' if test -f 'lib/printn.c' then echo shar: will not over-write existing file "'lib/printn.c'" else cat << \SHAR_EOF > 'lib/printn.c' #include <stdio.h> /* print a number in any radish */ #define DIGARR "0123456789ABCDEF" printn(number, radix, file) int number, radix; FILE *file;{ int i; char *digitreps; if (number < 0 & radix == 10){ fputc('-', file); number = -number; } if ((i = number / radix) != 0) printn(i, radix, file); digitreps=DIGARR; fputc(digitreps[number % radix], file); } SHAR_EOF if test 371 -ne "`wc -c < 'lib/printn.c'`" then echo shar: error transmitting "'lib/printn.c'" '(should have been 371 characters)' fi fi echo shar: extracting "'lib/putchar.c'" '(68 characters)' if test -f 'lib/putchar.c' then echo shar: will not over-write existing file "'lib/putchar.c'" else cat << \SHAR_EOF > 'lib/putchar.c' #include <stdio.h> putchar(c) char c; { return fputc(c, stdout); } SHAR_EOF if test 68 -ne "`wc -c < 'lib/putchar.c'`" then echo shar: error transmitting "'lib/putchar.c'" '(should have been 68 characters)' fi fi echo shar: extracting "'lib/puts.c'" '(105 characters)' if test -f 'lib/puts.c' then echo shar: will not over-write existing file "'lib/puts.c'" else cat << \SHAR_EOF > 'lib/puts.c' #include <stdio.h> #define EOL 10 puts(str) char *str;{ while (*str) putchar(*str++); putchar(EOL); } SHAR_EOF if test 105 -ne "`wc -c < 'lib/puts.c'`" then echo shar: error transmitting "'lib/puts.c'" '(should have been 105 characters)' fi fi echo shar: extracting "'lib/rand.c'" '(216 characters)' if test -f 'lib/rand.c' then echo shar: will not over-write existing file "'lib/rand.c'" else cat << \SHAR_EOF > 'lib/rand.c' int xxseed; srand (x) int x; { xxseed = x; } rand () { xxseed = xxseed * 251 + 123; if (xxseed < 0) xxseed = - xxseed; return (xxseed); } getrand () { puts ("Type a character"); return (getchar() * 123); } SHAR_EOF if test 216 -ne "`wc -c < 'lib/rand.c'`" then echo shar: error transmitting "'lib/rand.c'" '(should have been 216 characters)' fi fi echo shar: extracting "'lib/reverse.c'" '(229 characters)' if test -f 'lib/reverse.c' then echo shar: will not over-write existing file "'lib/reverse.c'" else cat << \SHAR_EOF > 'lib/reverse.c' #include <stdio.h> /* Reverse a character string, reference CPL p 59 */ reverse(s) char *s;{ int i, j; char c; i = 0; j = strlen(s) - 1; while (i < j){ c = s[i]; s[i] = s[j]; s[j] = c; i++; j--; } return(s); } SHAR_EOF if test 229 -ne "`wc -c < 'lib/reverse.c'`" then echo shar: error transmitting "'lib/reverse.c'" '(should have been 229 characters)' fi fi echo shar: extracting "'lib/sbrk.c'" '(244 characters)' if test -f 'lib/sbrk.c' then echo shar: will not over-write existing file "'lib/sbrk.c'" else cat << \SHAR_EOF > 'lib/sbrk.c' extern char *brkend; sbrk (incr) char *incr; { char *stktop; stktop = Xstktop() - 200; /* do we have enough space? */ if (brkend + incr < stktop) { stktop = brkend; brkend = brkend + incr; return (stktop); } else return (-1); } SHAR_EOF if test 244 -ne "`wc -c < 'lib/sbrk.c'`" then echo shar: error transmitting "'lib/sbrk.c'" '(should have been 244 characters)' fi fi echo shar: extracting "'lib/shell.c'" '(395 characters)' if test -f 'lib/shell.c' then echo shar: will not over-write existing file "'lib/shell.c'" else cat << \SHAR_EOF > 'lib/shell.c' /* Shell sort of string v[0] .... v[n-1] into increasing * order. * Reference CPL pg. 108. */ shellsort(v, n) int v[]; int n; { int gap, i, j; char *temp; for (gap = n/2; gap > 0; gap = gap / 2) for (i = gap; i < n; i++) for (j = i - gap; j >= 0; j = j - gap){ if (strcmp(v[j], v[j+gap]) <= 0) break; temp = v[j]; v[j] = v[j + gap]; v[j + gap] = temp; } } SHAR_EOF if test 395 -ne "`wc -c < 'lib/shell.c'`" then echo shar: error transmitting "'lib/shell.c'" '(should have been 395 characters)' fi fi echo shar: extracting "'lib/strcat.c'" '(218 characters)' if test -f 'lib/strcat.c' then echo shar: will not over-write existing file "'lib/strcat.c'" else cat << \SHAR_EOF > 'lib/strcat.c' /* * Concatenate s2 on the end of s1. S1's space must be large enough. * Return s1. */ strcat(s1, s2) char *s1, *s2; { char *os1; os1 = s1; while (*s1++) ; *--s1; while (*s1++ = *s2++) ; return(os1); } SHAR_EOF if test 218 -ne "`wc -c < 'lib/strcat.c'`" then echo shar: error transmitting "'lib/strcat.c'" '(should have been 218 characters)' fi fi echo shar: extracting "'lib/strcmp.c'" '(174 characters)' if test -f 'lib/strcmp.c' then echo shar: will not over-write existing file "'lib/strcmp.c'" else cat << \SHAR_EOF > 'lib/strcmp.c' /* * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 */ strcmp(s1, s2) char *s1, *s2; { while (*s1 == *s2++) if (*s1++=='\0') return(0); return(*s1 - *--s2); } SHAR_EOF if test 174 -ne "`wc -c < 'lib/strcmp.c'`" then echo shar: error transmitting "'lib/strcmp.c'" '(should have been 174 characters)' fi fi echo shar: extracting "'lib/strcpy.c'" '(190 characters)' if test -f 'lib/strcpy.c' then echo shar: will not over-write existing file "'lib/strcpy.c'" else cat << \SHAR_EOF > 'lib/strcpy.c' #include <stdio.h> /* * Copy string s2 to s1. s1 must be large enough. * return s1 */ strcpy(s1, s2) char *s1, *s2; { char *os1; os1 = s1; while (*s1++ = *s2++) ; return(os1); } SHAR_EOF if test 190 -ne "`wc -c < 'lib/strcpy.c'`" then echo shar: error transmitting "'lib/strcpy.c'" '(should have been 190 characters)' fi fi echo shar: extracting "'lib/strlen.c'" '(140 characters)' if test -f 'lib/strlen.c' then echo shar: will not over-write existing file "'lib/strlen.c'" else cat << \SHAR_EOF > 'lib/strlen.c' #include <stdio.h> /* return length of string, reference CPL p 36 */ strlen(s) char *s;{ int i; i = 0; while (*s++) i++; return (i); } SHAR_EOF if test 140 -ne "`wc -c < 'lib/strlen.c'`" then echo shar: error transmitting "'lib/strlen.c'" '(should have been 140 characters)' fi fi echo shar: extracting "'lib/strncat.c'" '(330 characters)' if test -f 'lib/strncat.c' then echo shar: will not over-write existing file "'lib/strncat.c'" else cat << \SHAR_EOF > 'lib/strncat.c' /* * Concatenate s2 on the end of s1. S1's space must be large enough. * At most n characters are moved. * Return s1. */ strncat(s1, s2, n) register char *s1, *s2; register n; { register char *os1; os1 = s1; while (*s1++) ; --s1; while (*s1++ = *s2++) if (--n < 0) { *--s1 = '\0'; break; } return(os1); } SHAR_EOF if test 330 -ne "`wc -c < 'lib/strncat.c'`" then echo shar: error transmitting "'lib/strncat.c'" '(should have been 330 characters)' fi fi echo shar: extracting "'lib/strncmp.c'" '(226 characters)' if test -f 'lib/strncmp.c' then echo shar: will not over-write existing file "'lib/strncmp.c'" else cat << \SHAR_EOF > 'lib/strncmp.c' /* * Compare strings (at most n bytes): s1>s2: >0 s1==s2: 0 s1<s2: <0 */ strncmp(s1, s2, n) char *s1, *s2; int n; { while (--n >= 0 && *s1 == *s2++) if (*s1++ == '\0') return(0); return(n<0 ? 0 : *s1 - *--s2); } SHAR_EOF if test 226 -ne "`wc -c < 'lib/strncmp.c'`" then echo shar: error transmitting "'lib/strncmp.c'" '(should have been 226 characters)' fi fi echo shar: extracting "'lib/strncpy.c'" '(309 characters)' if test -f 'lib/strncpy.c' then echo shar: will not over-write existing file "'lib/strncpy.c'" else cat << \SHAR_EOF > 'lib/strncpy.c' /* * Copy s2 to s1, truncating or null-padding to always copy n bytes * return s1 */ strncpy(s1, s2, n) char *s1, *s2; int n; { register i; register char *os1; os1 = s1; for (i = 0; i < n; i++) if ((*s1++ = *s2++) == '\0') { while (++i < n) *s1++ = '\0'; return(os1); } return(os1); } SHAR_EOF if test 309 -ne "`wc -c < 'lib/strncpy.c'`" then echo shar: error transmitting "'lib/strncpy.c'" '(should have been 309 characters)' fi fi echo shar: done with directory "'lib'" exit 0 # End of shell archive