[mod.sources] Small C compiler version C3.0R1.1

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