changeset 99:92ed427b7f7d

add micro-c by mohta
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 27 Dec 2018 11:01:16 +0900
parents ba0af2b8836b
children 990add11e9f8
files os9/mc09/COPYRIGHT os9/mc09/MANIFEST os9/mc09/NewsMess.j os9/mc09/README os9/mc09/alloc.txt os9/mc09/c.txt os9/mc09/diff_to_mc2 os9/mc09/fileio.txt os9/mc09/fileio2.txt os9/mc09/makefile os9/mc09/mc.c os9/mc09/mc2.c os9/mc09/mclib.c os9/mc09/scanf.txt os9/mc09/stdio.txt os9/mc09/stdio2.txt os9/mc09/string.txt os9/mc09/uf.c
diffstat 18 files changed, 8222 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/COPYRIGHT	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,5 @@
+COPYRIGHT (c) 1981, 1987 Masataka Ohta, Hiroshi Tezuka
+
+No rights reserved. Everyone is permitted to do anything
+on this program including copying, transplanting,
+debugging, and modifying.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/MANIFEST	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,16 @@
+COPYRIGHT	copyright notice
+MANIFESTO	this file
+README		general instruction on micro-C
+alloc.txt	malloc library for FLEX
+c.txt		runtime library for FLEX
+diff_to_mc2	diff from mc.c to mc2.c (micro-c for flex)
+fileio.txt	basic io library for FLEX
+fileio2.txt	basic io library 2 for FLEX (I've forgotten the difference)
+makefile	makefile
+mc.c		micro-c for UNIX
+mclib.c		simplified library for mc2.c on FLEX
+scanf.txt	scanf library for FLEX
+stdio.txt	standard io library for FLEX
+stdio2.txt	standard io library 2 for FLEX (I've forgotten the difference)
+string.txt	string library for FLEX
+uf.c		terminal emulator/file transfer for FLEX (hardware sensitive)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/NewsMess.j	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,29 @@
+>From: mohta@necom830.cc.titech.junet (Masataka Ohta)
+Newsgroups: fj.sources
+Subject: micro-C (part 1 of 2)
+Message-ID: <1042@titcce.cc.titech.JUNET>
+Date: 30 Nov 87 11:57:49 GMT
+Sender: nobody@titcce.cc.titech.JUNET
+Reply-To: mohta@necom830.cc.titech.JUNET (Masataka Ohta)
+Distribution: fj
+Organization: Tokyo Institute of Technology
+Lines: 2546
+
+$@!!B3$-$^$7$F%^%$%/%m#C$G$9!#$5$M$r$5$s!w5~Bg$K65$($F$b$i$C$?%P%0(B
+$@$O$H$C$F$"$j$^$9$,!"$b$O$d<j6a$K#F#L#E#X$N3+H/4D6-$J$I$J$$$N$G!"(B
+$@<B:]$NF0:n%F%9%H$O$G$-$F$$$^$;$s!#$7$+$7!"=PNO$N%"%;%s%V%i%j%9%H(B
+$@$r8+$k$+$.$j$O!"Bg>fIW$_$?$$$G$9!#(B
+
+$@!!C1=c$K#m#a#k#e$H$d$k$H!"#F#L#E#XMQ$N#m#i#c#r#o!]#C$N%*%V%8%'%/(B
+$@%H%3!<%I!I#m#c#2!%#o!I!J#S%U%)!<%^%C%H!K$,$G$-$^$9$,!"#U#N#I#X>e(B
+$@$G$N3+H/$J$i!"#m#c$H$$$&%(%/%<%-%e!<%?$r:n$l$P==J,$G$9!#(B
+
+$@!!>\$7$$%^%K%e%"%k$O$"$j$^$;$s$,!J%-%c%N%o!<%IMQ$N#5%$%s%A#F#D$K(B
+$@$O$$$C$F$$$k$N$G!"$H$j$@$7$h$&$,$J$$$N$G$9!K!"9)3X<R$+$i#1#9#8#5(B
+$@G/$K=P$?!V#C8@8l$H<~JU@)8f!W$H$$$&K\$O%^%$%/%m#C$rBj:`$K$7$F$$$k(B
+$@$N$G!";29M$K$J$k$H;W$$$^$9!#(B
+
+					$@B@ED!!>;9'(B
+					mohta@titcce.cc.titech.junet
+
+-------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/README	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,11 @@
+Micro-C is a subset of C compiler. It compiles everything
+in 1 pass.
+
+Major limitations compared to standard C compilers are:
+	1) no float or double
+	2) no bit field
+	3) limited pre-processor capability (use 'cpp' of UNIX if necessary)
+	4) no real long (long is only 2 bytes long)
+
+Non standard features:
+	1) #asm and #endasm construction (dangerous, use only after ';' or '}')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/alloc.txt	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,118 @@
+
+typedef struct header
+		{	struct header *ptr;
+			unsigned size;
+		} HEADER;
+
+HEADER base,*allocp,*heap;
+
+char *malloc(s)
+unsigned s;
+{HEADER *p,*q;
+ int nunits;
+	nunits = 1 + (s + sizeof(HEADER) - 1) / sizeof(HEADER);
+	if ((q = allocp) == NULL)
+	{	base.ptr = allocp = q = &base;
+		base.size = 0;
+	}
+	for (p = q->ptr; ; q = p,p = p->ptr)
+	{	if (p->size >= nunits)
+		{	if (p->size == nunits)
+				q->ptr = p->ptr;
+			else
+			{	p->size -= nunits;
+				p += p->size;
+				p->size = nunits;
+			}
+			allocp = q;
+			clearblock(p);
+			return ((char *)(p + 1));
+		}
+		if (p == allocp)
+			if ((p = morecore(nunits)) == NULL)
+				return(NULL);
+	}
+}
+
+clearblock(p)
+HEADER *p;
+{char *s,*t;
+	s = (char *)(p + 1);
+	t = (char *)(p + p->size);
+	while (s < t) *s++ = 0;
+}
+
+#define NALLOC 128
+
+HEADER *morecore(nu)
+unsigned nu;
+{char *cp;
+ HEADER *up;
+ int rnu;
+	rnu = NALLOC * ((nu + NALLOC - 1) / NALLOC);
+	cp = sbrk(rnu * sizeof(HEADER));
+	if ((int)cp == -1) return NULL;
+	up = (HEADER *) cp;
+	up->size = rnu;
+	mfree((char *)(up+1));
+	return allocp;
+}
+
+#asm
+sbrk	PSHS	U
+	LEAU	,S
+	
+	LDD	heap,Y
+	BNE	_mc0
+	BSR	initheap
+_mc0	PSHS	D
+	TFR	S,D
+	SUBD	,S++
+	CMPD	4,U
+	BCC	_mc1
+	LDD	#-1
+	LEAS	,U
+	PULS	U,PC
+	
+_mc1	LDD	4,U
+	LDX	heap,Y
+	LEAX	D,X
+	LDD	heap,Y
+	STX	heap,Y
+	LEAS	,U
+	PULS	U,PC
+
+initheap
+	PSHS	U
+	LEAU	,S
+	TFR	Y,D
+	ADDD	#_GLOBALS
+	STD	heap,Y
+	LEAS	,U
+	PULS	U,PC
+#endasm
+
+mfree(ap)
+char *ap;
+{HEADER *p,*q;
+	p = (HEADER *)ap - 1;
+	for (q = allocp; !(p > q && p < q->ptr); q = q->ptr)
+		if (q >= q->ptr && (p > q || p < q->ptr)) break;
+	if (p + p->size == q->ptr)
+	{	p->size += q->ptr->size;
+		p->ptr = q->ptr->ptr;
+	}
+	else p->ptr = q->ptr;
+	if (q + q->size == p)
+	{	q->size += p->size;
+		q->ptr = p->ptr;
+	}
+	else q->ptr = p;
+	allocp = q;
+}
+
+unsigned freesize()
+{int i;
+	if (!heap) initheap();
+	return ((char *)&i - (char *)heap);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/c.txt	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,386 @@
+
+*
+* micro-C driver under FLEX
+*
+*	12-Dec-81	M.Ohta,H.Tezuka
+*
+
+	ORG	$100
+
+_00000
+	LDX	$CC2B		LOAD MEM END
+	LEAS	1,X
+	
+	JSR	$CD24		CR/LF
+	
+	LEAS	-256,S		ALLOCATE WORK AREA
+	LEAU	128,S		POINT TO CONTENT OF ARGUMENT VECTOR
+
+	STU	,S
+	BSR	_0C004		GET ARGV[0]
+	CLRA			ARGC*2
+_0C000	ADDA	#2		INCREMENT ARGC
+	STU	A,S
+	PSHS	A
+	BSR	_0C009		GET NEXT ARGV
+	PULS	A
+	CMPU	#-1
+	BNE	_0C000
+	STU	A,S
+
+	LEAU	128,S
+	TFR	A,B
+_0C001	LDX	A,S
+	PSHU	X
+	SUBA	#2
+	BNE	_0C001
+	LDX	,S
+	PSHU	X
+	LEAS	,U
+	LSRB
+	CLRA
+	PSHS	D,U		push argc,argv
+	LEAY	_99999,PCR	clear globals
+	LDX	#_GLOBALS
+_0C002	BEQ	_0C003
+	CLR	,Y+
+	LEAX	-1,X
+	BRA	_0C002
+
+_0C003	LEAY	_99999,PCR
+	LBSR	_INITIALIZE	call initializer
+	LBSR	_main
+exit	JSR	$D403		FMS close
+	JMP	$CD03		WARMS
+
+_0C004	LDX	$CC14
+_0C005	CMPX	#$C080
+	BEQ	_0C007
+	LDB	,-X
+	CMPB	#$0D
+	BEQ	_0C006
+	CMPB	$CC02
+	BNE	_0C005
+_0C006	LEAX	1,X
+_0C007	LDB	,X+
+	CMPB	#' 
+	BEQ	_0C008
+	STB	,U+
+	CMPX	#$CC02
+	BLO	_0C007
+_0C008	CLR	,U+
+	RTS
+
+_0C009	JSR	$CD27
+	CMPA	#' 
+	BEQ	_0C009
+	CMPA	#$0D
+	BEQ	_0C013
+	CMPA	$CC02
+	BEQ	_0C013
+_0C010	CMPA	#'"
+	BEQ	_0C014
+	CMPA	#''
+	BEQ	_0C014
+	CMPA	#' 
+	BEQ	_0C012
+	CMPA	#$0D
+	BEQ	_0C012
+	CMPA	$CC02
+	BEQ	_0C012
+	STA	,U+
+_0C011	JSR	$CD27
+	BRA	_0C010
+
+_0C012	CLR	,U+
+	RTS
+
+_0C013	LDU	#-1
+	RTS
+
+_0C014	PSHS	A
+	LDX	$CC14
+_0C015
+	LDA	,X+
+	CMPA	#$0D
+	BEQ	_0C016
+	CMPA	,S
+	BEQ	_0C017
+	STA	,U+
+	BRA	_0C015
+
+_0C016	LEAX	-1,X
+_0C017	STX	$CC14
+	PULS	A
+	BRA	_0C011
+
+*
+* run time support
+*
+
+FMS	LDX	2,S
+	LDA	5,S
+	STA	,X
+	LDA	7,S
+	TST	59,X
+	BMI	_FMS1
+	CMPA	#$0A
+	BNE	_FMS0
+	LDA	#$0D
+_FMS0	CMPA	#$09
+	BNE	_FMS1
+	LDA	#$20
+_FMS1	JSR	$D406
+	BNE	_FMSERR
+	TFR	A,B
+	TST	59,X
+	BMI	_FMS9
+	CMPB	#$0D
+	BNE	_FMS8
+	LDB	#$0A
+_FMS8	CMPB	#$09
+	BNE	_FMS9
+	LDB	#$20
+_FMS9	CLRA
+	RTS
+	
+_FMSERR LDD	#-1
+	RTS
+	
+GETCH	PSHS	X,Y,U
+	JSR	$CD15		get character
+	TFR	A,B
+	ANDB	#$7F
+	CMPB	#26		control-Z ?
+	BNE	_0G001
+	LDD	#-1
+	PULS	X,Y,U,PC
+
+_0G001	CMPB	#$0D
+	BNE	_0G002
+	LDB	#$0A
+_0G002	CLRA
+	PULS	X,Y,U,PC
+*
+PUTCH	LDD	2,S
+	PSHS	D,X,Y,U
+	TFR	B,A
+	CMPA	#$09
+	BNE	_0P001
+	LDA	#$20
+_0P001	CMPA	#$0A
+	BNE	_0P002
+	JSR	$CD24		put CR/LF
+	PULS	D,X,Y,U,PC
+
+_0P002	JSR	$CD18		put character
+	PULS	D,X,Y,U,PC
+*
+PUTCH2	LDD	2,S
+	PSHS	D
+	LDA	$CC22
+	PSHS	A
+	LDA	#$FF
+	STA	$CC22
+	LDD	1,S
+	PSHS	D
+	BSR	PUTCH
+	LEAS	2,S
+	PULS	A
+	STA	$CC22
+	PULS	D,PC
+*
+_00001	PSHS	D,X,Y		multiply
+	
+	LDA	,S
+	LDB	3,S
+	MUL
+	STB	4,S
+	
+	LDD	1,S
+	MUL
+	STB	5,S
+	
+	LDA	1,S
+	LDB	3,S
+	MUL
+	ADDA	4,S
+	ADDA	5,S
+	
+	LEAS	6,S
+	RTS
+*
+_00002	CLR	,-S		signed divide
+	
+	CMPX	#0
+	BPL	_02000
+	
+	COM	,S
+	
+	EXG	D,X
+	LBSR	_00020
+	EXG	D,X
+
+_02000	TSTA
+	BPL	_02001
+	
+	COM	,S
+	
+	LBSR	_00020
+	
+_02001	LBSR	_00010
+	TFR	X,D
+	TST	,S+
+	BPL	_02002
+	
+	LBSR	_00020
+	
+_02002	RTS
+*
+_00003	LBSR	_00010		unsigned divide
+	TFR	X,D
+	RTS
+*
+_00004	CLR	,-S		signed modulous
+	
+	CMPX	#0
+	BPL	_04000
+	
+	EXG	D,X
+	BSR	_00020
+	EXG	D,X
+
+_04000	TSTA
+	BPL	_04001
+	
+	COM	,S
+	BSR	_00020
+	
+_04001	BSR	_00010
+	
+	TST	,S+
+	BPL	_04002
+	
+	BSR	_00020
+	
+_04002	RTS
+*
+_00005	BSR	_00010		unsigned modulous
+
+	RTS
+*
+_00006	CMPX	#0		signed left shift
+	BMI	_06001
+ 
+_06000	BEQ	_06009
+	LSLB
+	ROLA
+	LEAX	-1,X
+	BRA	_06000
+	
+_06001	BEQ	_06009
+	ASRA
+	RORB
+	LEAX	1,X
+	BRA	_06001
+	
+_06009	RTS
+*
+_00007	CMPX	#0		unsined left shift
+	BMI	_07001
+	
+_07000	BEQ	_07009
+	LSLB
+	ROLA
+	LEAX	-1,X
+	BRA	_07000
+	
+_07001	BEQ	_07009
+	LSRA
+	RORB
+	LEAX	1,X
+	BRA	_07001
+	
+_07009	RTS
+*
+_00008	CMPX	#0		sined right shift
+	BMI	_08001
+	
+_08000	BEQ	_08009
+	ASRA
+	RORB
+	LEAX	-1,X
+	BRA	_08000
+	
+_08001	BEQ	_08009
+	LSLB
+	ROLA
+	LEAX	1,X
+	BRA	_08001
+	
+_08009	RTS
+*
+_00009	CMPX	#0		unsined right shift
+	BMI	_09001
+	
+_09000	BEQ	_09009
+	LSRA
+	RORB
+	LEAX	-1,X
+	BRA	_09000
+	
+_09001	BEQ	_09009
+	LSLB
+	ROLA
+	LEAX	1,X
+	BRA	_09001
+	
+_09009	RTS
+*
+_00020	NEGA			negate D reg
+	NEGB
+	SBCA	#0
+	RTS
+*
+_00010	PSHS	D,X		divide subroutine
+	
+	CLRA
+	CLRB
+	
+	LDX	#17
+	
+_00011	SUBD	2,S
+	BCC	_00012
+	
+	ADDD	2,S
+	
+_00012	ROL	1,S
+	ROL	,S
+	ROLB
+	ROLA
+	
+	LEAX	-1,X
+	BNE	_00011
+	
+	RORA
+	RORB
+	
+	COM	1,S
+	COM	,S
+	PULS	X
+	
+	LEAS	2,S
+	RTS
+*
+* micro-C user program
+*
+*	OPT	LIST
+	LIB	c.out		include compilers output
+*	OPT	NOL
+*
+*
+*
+_99999	EQU	*		global vars allocated here
+*
+	END	_00000
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/diff_to_mc2	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,120 @@
+*** mc.c	Tue Nov 24 18:58:43 1987
+--- mc2.c	Tue Nov 24 18:51:22 1987
+***************
+*** 1,9 ****
+  
+  #define DEBUG	error(-1)
+  
+! /*#include "CCLIB.TXT"
+! */
+! #include <stdio.h>
+  
+  #define INT	(-1)
+  #define CHAR	(-2)
+--- 1,7 ----
+  
+  #define DEBUG	error(-1)
+  
+! #include "mclib.c"
+  
+  #define INT	(-1)
+  #define CHAR	(-2)
+***************
+*** 147,153 ****
+  #define GSYMS	450
+  #define LSYMS	50
+  
+! #define HEAPSIZE	1000
+  #define CHEAPSIZE	3000
+  #define LBUFSIZE	256
+  
+--- 145,151 ----
+  #define GSYMS	450
+  #define LSYMS	50
+  
+! #define HEAPSIZE	700
+  #define CHEAPSIZE	3000
+  #define LBUFSIZE	256
+  
+***************
+*** 181,187 ****
+  char *ccout;
+  	if(argc==1) exit(1);
+  	lsrc = chk = asmf = 0;
+! 	ccout = "c.out";
+  	ac=argc;
+  	av=argv;
+  	for (ac2=1; (ac2 < ac) && (*av[ac2] == '-'); ++ac2)
+--- 179,185 ----
+  char *ccout;
+  	if(argc==1) exit(1);
+  	lsrc = chk = asmf = 0;
+! 	ccout = "C.OUT";
+  	ac=argc;
+  	av=argv;
+  	for (ac2=1; (ac2 < ac) && (*av[ac2] == '-'); ++ac2)
+***************
+*** 201,207 ****
+  		}
+  	fclose(stdout);
+  	if (!chk)
+! 		if ( (obuf = fopen(ccout,"w")) == NULL ) error(FILERR);
+  	init();
+  	while(1)
+  	{	for (nptr = &ntable[GSYMS],i=LSYMS; i--;)
+--- 199,205 ----
+  		}
+  	fclose(stdout);
+  	if (!chk)
+! 		if ( (obuf = fopen(ccout,"wc")) == NULL ) error(FILERR);
+  	init();
+  	while(1)
+  	{	for (nptr = &ntable[GSYMS],i=LSYMS; i--;)
+***************
+*** 322,328 ****
+  newfile()
+  {	lineno=0;
+  	fprintf(stderr,"%s:\n",av[ac2]);
+! 	if ( (filep->fcb = fopen(av[ac2++],"r")) == NULL ) error(FILERR);
+  }
+  reserve(s,d)
+  char *s;
+--- 320,326 ----
+  newfile()
+  {	lineno=0;
+  	fprintf(stderr,"%s:\n",av[ac2]);
+! 	if ( (filep->fcb = fopen(av[ac2++],"rc")) == NULL ) error(FILERR);
+  }
+  reserve(s,d)
+  char *s;
+***************
+*** 2749,2762 ****
+  }
+  FILE *getfname()
+  {int i;
+! char name[LBUFSIZE];
+  	getch();
+  	if(skipspc()!='"') error(INCERR);
+  	for(i=0;(getch()!='"' && ch!='\n');)
+! 		if(i<LBUFSIZE-1) name[i++]=ch;
+  	if(ch=='\n') error(INCERR);
+  	name[i]=0;
+! 	return ( (filep+1)->fcb = fopen(name,"r") );
+  }
+  getline()
+  {int i;
+--- 2747,2760 ----
+  }
+  FILE *getfname()
+  {int i;
+! char name[14];
+  	getch();
+  	if(skipspc()!='"') error(INCERR);
+  	for(i=0;(getch()!='"' && ch!='\n');)
+! 		if(i<13) name[i++]=ch;
+  	if(ch=='\n') error(INCERR);
+  	name[i]=0;
+! 	return ( (filep+1)->fcb = fopen(name,"rc") );
+  }
+  getline()
+  {int i;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/fileio.txt	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,116 @@
+FILE *fopen(name,mode)
+char *name,*mode;
+{FILE *fcbp;
+ char *p;
+ int rd,wt,cm;
+	rd = wt = cm = 0;
+	for ( p = mode; *p; p++ ) {
+		switch ( *p ) {
+		case 'r':
+			rd = 1; break;
+		case 'w':
+			wt = 1; break;
+		case 'c':
+			cm = 1; break;
+		default:
+			return NULL;
+		}
+	}
+	if ( !(rd ^ wt) ) return NULL;
+	if ( rd ) return _open(name,cm);
+	else return _create(name,cm);
+}
+
+FILE *_open(name,cm)
+char *name;
+int cm;
+{FILE *fcbp;
+ int i;
+	for ( i = 0; i < NFILES; i++)
+		if ( _fcbtbl[i] == NULL ) break;
+	if ( i >= NFILES) return NULL;
+	if ( (fcbp = malloc(FCBSIZE)) == NULL ) return NULL;
+	if ( _setname(name,fcbp) == 0 ) return NULL;
+	if ( FMS(fcbp,1) < 0 ) return NULL;
+	fcbp[59] = cm ? 0 : 0xff;
+	fcbp[60] = 0;
+	return (_fcbtbl[i] = fcbp);
+}
+
+FILE *_create(name,cm)
+char *name;
+int cm;
+{FILE *fcbp;
+ int i;
+	for ( i = 0; i < NFILES; i++)
+		if ( _fcbtbl[i] == NULL ) break;
+	if ( i >= NFILES) return NULL;
+	if ( (fcbp = malloc(FCBSIZE)) == NULL ) return NULL;
+	if ( _setname(name,fcbp) == 0 ) return NULL;
+	if ( FMS(fcbp,2) < 0 )
+	{	if ( (fcbp[1] != 3) || (FMS(fcbp,12) < 0) ) return NULL;
+		_setname(name,fcbp);
+		if (FMS(fcbp,2) < 0) return NULL;
+	}
+	fcbp[15] = 0;
+	fcbp[59] = cm ? 0 : 0xff;
+	fcbp[60] = 0;
+	return (_fcbtbl[i] = fcbp);
+}
+
+fclose(fcbp)
+FILE *fcbp;
+{int i;
+	for ( i = 0; i < NFILES; i++ )
+		if ( fcbp == _fcbtbl[i] ) break;
+	if ( i >= NFILES ) return EOF;
+	_fcbtbl[i] = NULL;
+	if ( (fcbp == STDIN) || (fcbp == STDOUT) || (fcbp == STDERR) ) return 0;
+	if ( FMS(fcbp,4) < 0 ) return EOF;
+	mfree(fcbp);
+	return 0;
+}
+
+_setname(name,fcbp)
+char *name;
+FILE *fcbp;
+{int i;
+	while(isspace(*name)) ++name;
+	if (isdigit(*name))
+	{	fcbp[3] = *name++ - '0';
+		if (*name++ != '.') return 0;
+	}
+	else fcbp[3] = 0xff;
+	for (i = 4; i < 15; ++i) fcbp[i] = 0;
+	if (!isalpha(*name)) return -1;
+	for (i = 4; i < 12; ++i)
+	{	if (!*name || (*name == '.')) break;
+		fcbp[i] = *name++;
+	}
+	while (*name && (*name != '.')) ++name;
+	if (*name == '.')
+	{	++name;
+		for (i = 12; i < 15; ++i)
+		{	if (!*name) break;
+			fcbp[i] = *name++;
+		}
+	}
+	return 1;
+}
+
+fflush(fp)
+FILE *fp;
+{       return 0;
+}
+
+unlink(fname)
+char *fname;
+{char p[320];
+        return ((_setname(fname,p) || FMS(p,12) < 0) ? -1 : 0);
+}
+        
+rename(s,t)
+char *s,*t;
+{char p[320];
+        return ((_setname(s,p) || _setname(t,p+49) || FMS(p,13) < 0) ? -1 : 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/fileio2.txt	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,122 @@
+FILE *fopen(name,mode)
+char *name,*mode;
+{char *p;
+ int rd,wt,cm;
+	rd = wt = cm = 0;
+	for ( p = mode; *p; p++ ) {
+		switch ( *p ) {
+		case 'r':
+			rd = 1; break;
+		case 'w':
+			wt = 1; break;
+		case 'c':
+			cm = 1; break;
+		default:
+			return NULL;
+		}
+	}
+	if ( !(rd ^ wt) ) return NULL;
+	if ( rd ) return _open(name,cm);
+	else return _create(name,cm);
+}
+
+FILE *_open(name,cm)
+char *name;
+int cm;
+{FILE *fp;
+ int i;
+	for ( i = 0; i < NFILES; i++)
+		if ( _fptbl[i] == NULL ) break;
+	if ( i >= NFILES) return NULL;
+	if ( (fp = malloc(FBSIZE)) == NULL ) return NULL;
+	if ( _setname(name,fp->_fcb) == 0 ) return NULL;
+	if ( FMS(fp->_fcb,1) < 0 ) return NULL;
+	fp->_fcb[59] = cm ? 0 : 0xff;
+	fp->_fcb[60] = 0;
+	return (_fptbl[i] = fp);
+}
+
+FILE *_create(name,cm)
+char *name;
+int cm;
+{FILE *fp;
+ int i;
+	for ( i = 0; i < NFILES; i++)
+		if ( _fptbl[i] == NULL ) break;
+	if ( i >= NFILES) return NULL;
+	if ( (fp = malloc(FBSIZE)) == NULL ) return NULL;
+	if ( _setname(name,fp->_fcb) == 0 ) return NULL;
+	if ( FMS(fp->_fcb,2) < 0 )
+	{	if ( (fp[1] != 3) || (FMS(fp->_fcb,12) < 0) ) return NULL;
+		_setname(name,fp->_fcb);
+		if (FMS(fp->_fcb,2) < 0) return NULL;
+	}
+	fp->_fcb[15] = 0;
+	fp->_fcb[59] = cm ? 0 : 0xff;
+	fp->_fcb[60] = 0;
+	return (_fptbl[i] = fp);
+}
+
+fclose(fp)
+FILE *fp;
+{int i;
+	for ( i = 0; i < NFILES; i++ )
+		if ( fp == _fptbl[i] ) break;
+	if ( i >= NFILES ) return EOF;
+	_fptbl[i] = NULL;
+	if ( (fp == STDIN) || (fp == STDOUT) || (fp == STDERR) ) return 0;
+	if ( fp->_fcb[2] == 2 ) fflush(fp);
+	if ( FMS(fp->_fcb,4) < 0 ) return EOF;
+	mfree(fp);
+	return 0;
+}
+
+_setname(name,fcbp)
+char *name;
+char *fcbp;
+{int i;
+	while(isspace(*name)) ++name;
+	if (isdigit(*name))
+	{	fcbp[3] = *name++ - '0';
+		if (*name++ != '.') return 0;
+	}
+	else fcbp[3] = 0xff;
+	for (i = 4; i < 15; ++i) fcbp[i] = 0;
+	if (!isalpha(*name)) return -1;
+	for (i = 4; i < 12; ++i)
+	{	if (!*name || (*name == '.')) break;
+		fcbp[i] = *name++;
+	}
+	while (*name && (*name != '.')) ++name;
+	if (*name == '.')
+	{	++name;
+		for (i = 12; i < 15; ++i)
+		{	if (!*name) break;
+			fcbp[i] = *name++;
+		}
+	}
+	return 1;
+}
+
+fflush(fp)
+FILE *fp;
+{int i;
+	if ( fp == STDIN ) return EOF;
+	if ( fp == STDOUT || fp == STDERR ) return 0;
+	if ( fp->_fcb[2] != 2 ) return EOF;
+	for ( i = 0; i < fp->_fbp; i++ ) FMS(fp->_fcb,0,fp->fcb[i]);
+	fp->_fbp = 0;
+	return 0;
+}
+
+unlink(fname)
+char *fname;
+{char p[320];
+        return ((_setname(fname,p) || FMS(p,12) < 0) ? -1 : 0);
+}
+        
+rename(s,t)
+char *s,*t;
+{char p[320];
+        return ((_setname(s,p) || _setname(t,p+49) || FMS(p,13) < 0) ? -1 : 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/makefile	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,36 @@
+MCLIBS=alloc.txt c.txt fileio.txt fileio2.txt mclib.c scanf.txt\
+	stdio.txt stdio2.txt string.txt
+
+MCUTILS=uf.c
+
+DESTDIR=/usr/local/bin
+
+all:	mc2.o
+
+mc: mc.c
+	cc mc.c -o mc
+
+c.out:	mc mc2.c mclib.c
+	mc mc2.c
+
+mc2.o:	c.out
+	as09 c.txt -o mc2.o -v -O
+
+lint: mc.c
+	lint mc.c >lint
+
+shar: diff_to_mc2
+	shar COPYRIGHT README MANIFEST makefile $(MCLIBS) $(MCUTILS) diff_to_mc2 >mc.shar.0
+	shar mc.c >mc.shar.1
+
+diff_to_mc2: mc.c mc2.c
+	-diff -c mc.c mc2.c >diff_to_mc2
+
+mc2.c:
+	patch <diff_to_mc2 -o mc2.c
+
+clean:
+	rm -f mc c.out mc2.o lint
+
+install: mc
+	cp mc $(DESTDIR)/mc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/mc.c	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,2898 @@
+
+#define DEBUG	error(-1)
+
+/*#include "CCLIB.TXT"
+*/
+#include <stdio.h>
+
+#define INT	(-1)
+#define CHAR	(-2)
+#define UNSIGNED	(-3)
+#define POINTER (-4)
+#define ARRAY	(-5)
+#define STRUCT	(-6)
+#define UNION	(-7)
+#define FUNCTION	(-8)
+#define EMPTY	(-9)
+
+#define STATIC	(-10)
+#define GOTO	(-11)
+#define RETURN	(-12)
+#define BREAK	(-13)
+#define CONTINUE	(-14)
+#define IF	(-15)
+#define ELSE	(-16)
+#define FOR	(-17)
+#define DO	(-18)
+#define WHILE	(-19)
+#define SWITCH	(-20)
+#define CASE	(-21)
+#define DEFAULT (-22)
+#define RESERVE (-23)
+#define TAG	(-24)
+#define FIELD	(-25)
+#define IDENT	(-26)
+#define STRING	(-27)
+#define MACRO	(-28)
+#define BLABEL	(-29)
+#define FLABEL	(-30)
+#define TYPEDEF (-31)
+#define SIZEOF	(-32)
+#define TYPE	(-33)
+#define LONG	(-34)
+#define SHORT	(-35)
+
+#define TOP	0
+#define GDECL	1
+#define GSDECL	2
+#define GUDECL	3
+#define ADECL	4
+#define LDECL	5
+#define LSDECL	6
+#define LUDECL	7
+#define STADECL 8
+#define STAT	9
+#define GTDECL	10
+#define LTDECL	11
+
+#define GVAR	1
+#define RGVAR	2
+#define CRGVAR	3
+#define LVAR	4
+#define RLVAR	5
+#define CRLVAR	6
+#define CONST	7
+#define FNAME	8
+#define INDIRECT	9
+#define RINDIRECT	10
+#define CRINDIRECT	11
+#define ADDRESS 12
+#define MINUS	13
+#define LNOT	14
+#define BNOT	15
+#define INC	16
+#define POSTINC 17
+#define PREINC	18
+#define CPOSTINC	19
+#define CPREINC 20
+#define DEC	21
+#define CPOSTDEC	22
+#define CPREDEC 23
+#define MUL	24
+#define UMUL	25
+#define DIV	26
+#define UDIV	27
+#define MOD	28
+#define UMOD	29
+#define ADD	30
+#define SUB	31
+#define RSHIFT	32
+#define URSHIFT 33
+#define LSHIFT	34
+#define ULSHIFT 35
+#define GT	36
+#define UGT	37
+#define GE	38
+#define UGE	39
+#define LT	40
+#define ULT	41
+#define LE	42
+#define ULE	43
+#define EQ	44
+#define NEQ	45
+#define BAND	46
+#define EOR	47
+#define BOR	48
+#define LAND	49
+#define LOR	50
+#define COND	51
+#define ASS	52
+#define CASS	53
+#define ASSOP	54
+#define CASSOP	55
+#define COMMA	56
+#define LPAR	57
+#define RPAR	58
+#define LBRA	59
+#define RBRA	60
+#define LC	61
+#define RC	62
+#define COLON	63
+#define SM	64
+#define PERIOD	65
+#define ARROW	66
+
+#define US	1
+#define AS	100
+
+#define FILERR	1
+#define DCERR	2
+#define STERR	3
+#define EXERR	4
+#define CNERR	5
+#define CHERR	6
+#define GSERR	7
+#define LSERR	8
+#define STRERR	9
+#define LNERR	10
+#define EOFERR	11
+#define MCERR	12
+#define INCERR	13
+#define HPERR	14
+#define TYERR	15
+#define LVERR	16
+#define UDERR	17
+#define OPTION	18
+
+#define GSYMS	450
+#define LSYMS	50
+
+#define HEAPSIZE	1000
+#define CHEAPSIZE	3000
+#define LBUFSIZE	256
+
+#define FILES 3
+
+int sym,ch,chsave,type,mode,gfree,lfree,mflag,lineno,glineno;
+int labelno,gpc,lvar,disp;
+int symval,args,heap[HEAPSIZE];
+int blabel,clabel,dlabel,cslabel,ilabel,control,ac,ac2,lsrc,chk,asmf;
+
+unsigned hash;
+
+char linebuf[LBUFSIZE],cheap[CHEAPSIZE],*chptr,*chptrsave;
+char name[9],*cheapp,**av,/*obuf[320],*/*sptr,escape();
+
+FILE *obuf;
+
+typedef struct nametable {
+	char nm[9];
+	int sc,ty,dsp; } NMTBL;
+
+NMTBL ntable[GSYMS+LSYMS],*nptr,*gnptr,*decl0(),*decl1(),*lsearch(),*gsearch();
+
+struct {int fd,ln;/*char fcb[320]*/FILE *fcb;} *filep,filestack[FILES];
+
+main(argc,argv)
+int argc;
+char **argv;
+{NMTBL *nptr;
+int i;
+char *ccout;
+	if(argc==1) exit(1);
+	lsrc = chk = asmf = 0;
+	ccout = "c.out";
+	ac=argc;
+	av=argv;
+	for (ac2=1; (ac2 < ac) && (*av[ac2] == '-'); ++ac2)
+		switch (*(av[ac2]+1))
+		{case 'S': case 's':
+			lsrc = 1;
+			break;
+		case 'O': case 'o':
+			ccout = av[ac2]+2;
+			break;
+		case 'C': case 'c':
+			chk = 1;
+			break;
+		default:
+			error(OPTION);
+			exit(1);
+		}
+	fclose(stdout);
+	if (!chk)
+		if ( (obuf = fopen(ccout,"w")) == NULL ) error(FILERR);
+	init();
+	while(1)
+	{	for (nptr = &ntable[GSYMS],i=LSYMS; i--;)
+			(nptr++)->sc = EMPTY;
+		mode=TOP;
+		while(getsym()==SM);
+		mode=GDECL;
+		args=0;
+		decl();
+	}
+}
+error(n)
+int n;
+{	if(n == EOFERR)
+		if(filep!=filestack)
+		{	lineno=filep->ln;
+			fclose(filep->fcb);
+			fprintf(stderr,"End of inclusion.\n");
+			--filep;
+			return;
+		}
+		else if(ac2!=ac)
+		{	fclose(filep->fcb);
+			newfile();
+			return;
+		}
+		else if(mode == TOP)
+		{	fprintf(stderr,"\nCompiled %u lines.\n",glineno-1);
+			if (!chk) fprintf(stderr,
+				"Total internal labels	: %u.\n",labelno-1);
+			fprintf(stderr,
+				"Total global variables : %u bytes.\n\n",gpc);
+			printf("_%d\tRTS\n_INITIALIZE\tEQU\t_1\n",ilabel);
+			printf("_GLOBALS\tEQU\t%u\n\tEND\n",gpc);
+			exit(0);
+		}
+	fprintf(stderr,"%5d:%s.\n",lineno,
+		(n==FILERR) ? "Can't open specified file" :
+		(n==DCERR) ? "Declaration syntax" :
+		(n==STERR) ? "Statement syntax" :
+		(n==EXERR) ? "Expression syntax" :
+		(n==CNERR) ? "Constant required" :
+		(n==CHERR) ? "Illegal character" :
+		(n==GSERR) ? "Too many global symbols" :
+		(n==LSERR) ? "Too many local symbols" :
+		(n==STRERR) ? "Too many strings or macros" :
+		(n==LNERR) ? "Line too long" :
+		(n==EOFERR) ? "Unexpected end of file" :
+		(n==MCERR) ? "Macro syntax" :
+		(n==INCERR) ? "Include syntax" :
+		(n==HPERR) ? "Too long expression" :
+		(n==TYERR) ? "Type mismatch" :
+		(n==LVERR) ? "Lvalue required" :
+		(n==UDERR) ? "Undeclared identifier" :
+		(n==OPTION) ? "Illegal option" :
+		"Bug of compiler");
+	errmsg();
+	exit(1);
+}
+errmsg()
+{char *p,*lim;
+	if(lineno==0) return;
+	fprintf(stderr,"%s",linebuf);
+	lim=(mflag?chptrsave:chptr);
+	for (p=linebuf; p < lim;)
+		fprintf(stderr,(*p++ == '\t') ? "\t" : " ");
+	fprintf (stderr,"^\n");
+}
+checksym(s)
+int s;
+{char *p;
+	if (sym != s)
+	{	p=(s==RPAR) ? "')'": (s==RBRA) ? "']'": (s==SM) ? "';'":
+		  (s==LPAR) ? "'('": (s==WHILE) ? "'while'":
+		  (s==COLON) ? "':'": "Identifier";
+		fprintf(stderr,"%d:%s expected.\n",lineno,p);
+		errmsg();
+	}
+	else getsym();
+}
+init()
+{NMTBL *nptr;
+int i;
+	for(nptr = ntable,i = GSYMS; i--;) (nptr++)->sc = EMPTY;
+	reserve("int",INT);
+	reserve("void",INT);
+	reserve("char",CHAR);
+	reserve("struct",STRUCT);
+	reserve("union",UNION);
+	reserve("unsigned",UNSIGNED);
+	reserve("static",STATIC);
+	reserve("goto",GOTO);
+	reserve("return",RETURN);
+	reserve("break",BREAK);
+	reserve("continue",CONTINUE);
+	reserve("if",IF);
+	reserve("else",ELSE);
+	reserve("for",FOR);
+	reserve("do",DO);
+	reserve("while",WHILE);
+	reserve("switch",SWITCH);
+	reserve("case",CASE);
+	reserve("default",DEFAULT);
+	reserve("typedef",TYPEDEF);
+	reserve("sizeof",SIZEOF);
+	reserve("long",LONG);
+	reserve("short",SHORT);
+	gpc=glineno=mflag=0;
+	gfree=ilabel=1;
+	labelno=2;
+	cheapp=cheap;
+	lfree=HEAPSIZE;
+	filep=filestack;
+	newfile();
+	getline();
+	getch();
+}
+newfile()
+{	lineno=0;
+	fprintf(stderr,"%s:\n",av[ac2]);
+	if ( (filep->fcb = fopen(av[ac2++],"r")) == NULL ) error(FILERR);
+}
+reserve(s,d)
+char *s;
+int d;
+{NMTBL *nptr;
+char *t;
+	hash=0;
+	t=name;
+	while(*t++ = *s) hash=7*(hash+*s++);
+	(nptr = gsearch())->sc = RESERVE;
+	nptr->dsp = d;
+}
+
+decl()
+{NMTBL *n;
+int t;
+	if(sym==STATIC)
+		if(mode==LDECL)
+		{	getsym();
+			mode=STADECL;
+		}
+		else error(DCERR);
+	else if(sym==TYPEDEF)
+		if(mode==GDECL)
+		{	getsym();
+			mode=GTDECL;
+		}
+		else if(mode==LDECL)
+		{	getsym();
+			mode=LTDECL;
+		}
+		else error(DCERR);
+	if((t=typespec())==0) return;
+	if(sym==SM) return;
+	type=t;
+	n=decl0();
+	reverse(t);
+	if(args||sym==LC) {fdecl(n);return;}
+	def(n);
+	while(sym==COMMA)
+	{	getsym();
+		type=t;
+		n=decl0();
+		reverse(t);
+		if(args) error(DCERR);
+		def(n);
+	}
+	if(sym!=SM) error(DCERR);
+	if(mode==GTDECL) mode=GDECL;
+	if(mode==STADECL||mode==LTDECL) mode=LDECL;
+}
+typespec()
+{int t;
+	switch(sym)
+	{case INT:
+	case CHAR:
+		t= sym;
+		getsym();
+		break;
+	case STRUCT:
+	case UNION:
+		t=sdecl(sym);
+		break;
+	case UNSIGNED:
+		t = UNSIGNED;
+		if(getsym()==INT) getsym();
+		break;
+	case SHORT:
+		t=CHAR;
+		if(getsym()==INT) getsym();
+		break;
+	case LONG:
+		t=INT;
+		if(getsym()==INT) getsym();
+		break;
+	default:
+		if(sym==IDENT)
+			if(nptr->sc==TYPE)
+			{	t=nptr->ty;
+				getsym();
+				break;
+			}
+			else if(nptr->sc==EMPTY && gnptr->sc==TYPE)
+			{	t=gnptr->ty;
+				getsym();
+				break;
+			}
+		if(mode==LDECL) return 0;
+		t= INT;
+	}
+	return t;
+}
+struct nametable *decl0()
+{NMTBL *n;
+	if(sym==MUL)
+	{	getsym();
+		n=decl0();
+		type=list2(POINTER,type);
+		return n;
+	}
+	return decl1();
+}
+NMTBL *decl1()
+{NMTBL *n;
+int i,t;
+	if(sym==LPAR)
+	{	getsym();
+		n=decl0();
+		checksym(RPAR);
+	}
+	else if (sym == IDENT)
+	{	n=nptr;
+		getsym();
+	}
+	else error(DCERR);
+	while(1)
+		if(sym==LBRA)
+			if(getsym()==RBRA)
+			{	getsym();
+				if(mode!=ADECL) error(DCERR);
+				t=type;
+				type=list2(POINTER,type);
+			}
+			else
+			{	t=type;
+				i=cexpr(expr());
+				checksym(RBRA);
+				type=list3(ARRAY,t,i);
+			}
+		else if(sym==LPAR)
+		{	if(mode==GDECL) {mode=ADECL;getsym();mode=GDECL;}
+			else getsym();
+			if(sym==RPAR) getsym();
+			else
+			{	n->sc=FUNCTION;
+				adecl();
+				n->sc=EMPTY;
+			}
+			type=list2(FUNCTION,type);
+		}
+		else return n;
+}
+adecl()
+{	if(mode!=GDECL) error(DCERR);
+	mode=ADECL;
+	args= 2;
+	while(1)
+	{	if(sym!=IDENT) error(DCERR);
+		nptr->ty = INT;
+		nptr->sc = LVAR;
+		nptr->dsp = (args += 2);
+		if(getsym()!=COMMA) break;
+		getsym();
+	}
+	checksym(RPAR);
+	mode=GDECL;
+	return;
+}
+reverse(t1)
+int t1;
+{int t2,t3;
+	t2=t1;
+	while(type!=t1)
+	{	t3=cadr(type);
+		rplacad(type,t2);
+		t2=type;
+		type=t3;
+	}
+	type=t2;
+}
+size(t)
+int t;
+{	if(t==CHAR) return 1;
+	if(scalar(t)) return 2;
+	if(car(t)==STRUCT||car(t)==UNION)
+	{	if(cadr(t)==-1) error(DCERR);
+		return(cadr(t));
+	}
+	if(car(t)==ARRAY) return(size(cadr(t))*caddr(t));
+	else error(DCERR);
+	/*NOTREACHED*/
+}
+def(n)
+NMTBL *n;
+{int sz,nsc,ndsp,slfree,l,t,e;
+	if(car(type)==FUNCTION)
+	{	fcheck(n);
+		return;
+	}
+	if (n->sc!=EMPTY &&
+	    (mode!=ADECL || n->sc!=LVAR || n->ty!=INT) &&
+	    (mode!=GSDECL&&mode!=LSDECL || n->sc!=FIELD || n->dsp!=disp) &&
+	    (mode!=GUDECL&&mode!=LUDECL || n->sc!=FIELD || n->dsp!=0) )
+		 error(DCERR);
+	sz = size(n->ty = type);
+	switch(mode)
+	{case GDECL:
+		printf("%s\tEQU\t%u\n",n->nm,gpc);
+	case STADECL:
+		nsc = GVAR;
+		ndsp = gpc;
+		if(sym==ASS)
+		{	t=type;
+			if(!scalar(t))
+				error(TYERR);
+			if(mode==STADECL) printf("\tBRA\t_%d\n",l=fwdlabel());
+			fwddef(ilabel);
+			getsym();
+			slfree=lfree;
+			e=expr1();
+			if(car(e)==CONST)
+			{	lddim(cadr(e));
+				indexy(t==CHAR?"STB":"STD",gpc);
+			}
+			else if(t!=CHAR)
+			{	if(car(e)==ADDRESS&&car(cadr(e))==GVAR)
+					leaxy(cadr(cadr(e)));
+				else if(car(e)==FNAME)
+					leaxpcr((NMTBL *)cadr(e));
+				else error(TYERR);
+				stxy(gpc);
+			}
+			else error(TYERR);
+			lfree=slfree;
+			jmp(ilabel=fwdlabel());
+			if(mode==STADECL) fwddef(l);
+			type=t;
+		}
+		gpc +=sz;
+		break;
+	case GSDECL:
+		nsc = FIELD;
+		ndsp = disp;
+		disp += sz;
+		break;
+	case GUDECL:
+		nsc = FIELD;
+		ndsp = 0;
+		if (disp < sz) disp = sz;
+		break;
+	case GTDECL:
+		nsc = TYPE;
+		break;
+	case ADECL:
+		if(type==CHAR) ++(n->dsp);
+		else if (!scalar(type)) error(TYERR);
+		return;
+	case LDECL:
+		nsc = LVAR;
+		ndsp = (disp -= sz);
+		break;
+	case LSDECL:
+		nsc = FIELD;
+		ndsp = disp;
+		disp += sz;
+		break;
+	case LUDECL:
+		nsc = FIELD;
+		ndsp = 0;
+		if (disp < sz) disp = sz;
+		break;
+	case LTDECL:
+		nsc = TYPE;
+		break;
+	default:
+		error(DCERR);
+	}
+	n->sc = nsc;
+	n->dsp = ndsp;
+}
+sdecl(s)
+int s;
+{int smode,sdisp,type;
+NMTBL *nptr0;
+	smode=mode;
+	if (mode==GDECL || mode==GSDECL || mode==GUDECL || mode==GTDECL)
+		mode=(s==STRUCT?GSDECL:GUDECL);
+	else mode=(s==STRUCT?LSDECL:LUDECL);
+	sdisp=disp;
+	disp=0;
+	if (getsym() == IDENT)
+	{	nptr0 = nptr;
+		if (getsym() == LC)
+		{	if (nptr0->sc != EMPTY) error(DCERR);
+			nptr0->sc = TAG;
+			nptr0->ty = list2(s,-1);
+			while (getsym() != RC) decl();
+			getsym();
+			rplacad(type = nptr0->ty,disp);
+		}
+		else
+		{	if(nptr0->sc == EMPTY) nptr0=gnptr;
+			if(nptr0->sc == EMPTY) error(UDERR);
+			if(nptr0->sc != TAG) error(TYERR);
+			type = nptr0->ty;
+		}
+	}
+	else if(sym==LC)
+	{	while(getsym() != RC) decl();
+		getsym();
+		type = list2(s,disp);
+	}
+	else error(DCERR);
+	disp=sdisp;
+	mode=smode;
+	return type;
+}
+fdecl(n)
+NMTBL *n;
+{	args=0;
+	fcheck(n);
+	mode=ADECL;
+	lfree= HEAPSIZE;
+	while (sym!=LC) {decl(); getsym();}
+	disp=0;
+	mode=STAT;
+	while (typeid(getsym()) || sym==STATIC || sym==TYPEDEF)
+	{	mode=LDECL;
+		decl();
+		mode=STAT;
+	}
+	control=1;
+	printf("%s\n\tPSHS\tU\n\tLEAU\t,S\n",n->nm);
+	if(disp) printf("\tLEAS\t%d,S\n",disp);
+	lvar= -disp;
+	while(sym!=RC) statement();
+	if (control) return2();
+}
+fcheck(n)
+NMTBL *n;
+{	if(mode!=GDECL||car(type)!=FUNCTION) error(DCERR);
+	if(n->sc==FUNCTION) compatible(n->ty,cadr(type));
+	else if(n->sc!=EMPTY) error(DCERR);
+	n->sc=FUNCTION;
+	n->ty=cadr(type);
+}
+compatible(t1,t2)
+int t1,t2;
+{	if(integral(t1))
+	{	if(t1!=t2) error(TYERR);
+	}
+	else if(car(t1)!=car(t2)) error(TYERR);
+	else if((car(t1)==STRUCT || car(t1)==UNION) && cadr(t1)!=cadr(t2))
+		error(TYERR);
+	else if(car(t1)==POINTER || car(t1)==ARRAY ||car(t1)==FUNCTION)
+		compatible(cadr(t1),cadr(t2));
+}
+scalar(t)
+int t;
+{	return(integral(t)||car(t)==POINTER);
+}
+integral(t)
+int t;
+{	return(t==INT||t==CHAR||t==UNSIGNED);
+}
+
+statement()
+{int slfree;
+	switch(sym)
+	{case IF:
+		doif();
+		return;
+	case WHILE:
+		dowhile();
+		return;
+	case DO:
+		dodo();
+		return;
+	case FOR:
+		dofor();
+		return;
+	case SWITCH:
+		doswitch();
+		return;
+	case LC:
+		docomp();
+		return;
+	case BREAK:
+		jmp(blabel);
+		getsym();
+		checksym(SM);
+		return;
+	case CONTINUE:
+		jmp(clabel);
+		getsym();
+		checksym(SM);
+		return;
+	case CASE:
+		docase();
+		statement();
+		return;
+	case DEFAULT:
+		dodefault();
+		statement();
+		return;
+	case RETURN:
+		doreturn();
+		return;
+	case GOTO:
+		dogoto();
+		return;
+	case SM:
+		getsym();
+		return;
+	default:if(sym==IDENT&&skipspc()==':')
+		{	dolabel();
+			statement();
+		}
+		else
+		{	slfree=lfree;
+			gexpr(expr());
+			lfree=slfree;
+			checksym(SM);
+		}
+	}
+}
+doif()
+{int l1,l2,slfree;
+	getsym();
+	checksym(LPAR);
+	slfree=lfree;
+	bexpr(expr(),0,l1=fwdlabel());
+	lfree=slfree;
+	checksym(RPAR);
+	statement();
+	if(sym==ELSE)
+	{	if (l2 = control) jmp(l2=fwdlabel());
+		fwddef(l1);
+		getsym();
+		statement();
+		if (l2) fwddef(l2);
+	}
+	else fwddef(l1);
+}
+dowhile()
+{int sbreak,scontinue,slfree,e;
+	sbreak=blabel;
+	scontinue=clabel;
+	blabel=fwdlabel();
+	clabel=backdef();
+	getsym();
+	checksym(LPAR);
+	slfree=lfree;
+	e=expr();
+	checksym(RPAR);
+	if(sym==SM)
+	{	bexpr(e,1,clabel);
+		lfree=slfree;
+		getsym();
+	}
+	else
+	{	bexpr(e,0,blabel);
+		lfree=slfree;
+		statement();
+		jmp(clabel);
+	}
+	fwddef(blabel);
+	clabel=scontinue;
+	blabel=sbreak;
+}
+dodo()
+{int sbreak,scontinue,l,slfree;
+	sbreak=blabel;
+	scontinue=clabel;
+	blabel=fwdlabel();
+	clabel=fwdlabel();
+	l=backdef();
+	getsym();
+	statement();
+	fwddef(clabel);
+	checksym(WHILE);
+	checksym(LPAR);
+	slfree=lfree;
+	bexpr(expr(),1,l);
+	lfree=slfree;
+	checksym(RPAR);
+	checksym(SM);
+	fwddef(blabel);
+	clabel=scontinue;
+	blabel=sbreak;
+}
+dofor()
+{int sbreak,scontinue,l,e,slfree;
+	sbreak=blabel;
+	scontinue=clabel;
+	blabel=fwdlabel();
+	getsym();
+	checksym(LPAR);
+	slfree=lfree;
+	if(sym!=SM)
+	{	gexpr(expr());
+		checksym(SM);
+	}
+	else getsym();
+	lfree=slfree;
+	l=backdef();
+	if(sym!=SM)
+	{	bexpr(expr(),0,blabel);
+		checksym(SM);
+	}
+	else getsym();
+	lfree=slfree;
+	if(sym==RPAR)
+	{	clabel=l;
+		getsym();
+		statement();
+	}
+	else
+	{	clabel=fwdlabel();
+		e=expr();
+		checksym(RPAR);
+		statement();
+		fwddef(clabel);
+		gexpr(e);
+		lfree=slfree;
+	}
+	jmp(l);
+	fwddef(blabel);
+	clabel=scontinue;
+	blabel=sbreak;
+}
+doswitch()
+{int sbreak,scase,sdefault,slfree;
+	sbreak=blabel;
+	blabel=fwdlabel();
+	sdefault=dlabel;
+	dlabel=0;
+	scase=cslabel;
+	getsym();
+	checksym(LPAR);
+	slfree=lfree;
+	gexpr(expr());
+	lfree=slfree;
+	checksym(RPAR);
+	cslabel = control = 0;
+	statement();
+	if(dlabel) printf("_%d\tEQU\t_%d\n",cslabel,dlabel);
+	else fwddef(cslabel);
+	cslabel=scase;
+	dlabel=sdefault;
+	fwddef(blabel);
+	blabel=sbreak;
+}
+docomp()
+{	getsym();
+	while(sym!=RC) statement();
+	getsym();
+}
+docase()
+{int c,n,l,slfree;
+	c=0;
+	n=2;
+	slfree=lfree;
+	while(sym==CASE)
+	{	getsym();
+		c=list2(cexpr(expr()),c);
+		n+=6;
+		checksym(COLON);
+	}
+	l=fwdlabel();
+	if (control)
+	{	control=0;
+		if (n>127) jmp(l);
+		else printf("\tBRA\t_%d\n",l);
+	}
+	if (cslabel) fwddef(cslabel);
+	while(cadr(c))
+	{	cmpdimm(car(c));
+		if((n-=6)>127) jcond(l,0);
+		else printf("\tBEQ\t_%d\n",l);
+		c=cadr(c);
+	}
+	lfree=slfree;
+	cmpdimm(car(c));
+	jcond(cslabel=fwdlabel(),1);
+	fwddef(l);
+}
+dodefault()
+{	getsym();
+	checksym(COLON);
+	if (dlabel) error(STERR);
+	if (!cslabel) jmp(cslabel = fwdlabel());
+	dlabel = backdef();
+}
+doreturn()
+{int slfree;
+	if(getsym()==SM)
+	{	getsym();
+		return2();
+		return;
+	}
+	slfree=lfree;
+	gexpr(expr());
+	lfree=slfree;
+	checksym(SM);
+	control=0;
+	switch(lvar)
+	{case 0:
+		ret("");
+		return;
+	case 2:
+		ret("X,");
+		return;
+	default:unlink();
+		return;
+	}
+}
+return2()
+{	control=0;
+	switch(lvar)
+	{case 0:
+		ret("");
+		return;
+	case 1:
+		ret("A,");
+		return;
+	case 2:
+		ret("D,");
+		return;
+	case 3:
+		ret("A,X,");
+		return;
+	case 4:
+		ret("D,X,");
+		return;
+	default:unlink();
+		return;
+	}
+}
+ret(reg)
+char *reg;
+{	printf("\tPULS\t%sU,PC\n",reg);
+}
+unlink()
+{	printf("\tLEAS\t,U\n");
+	ret("");
+}
+dogoto()
+{NMTBL *nptr0;
+	getsym();
+	nptr0=nptr;
+	checksym(IDENT);
+	if(nptr0->sc == BLABEL || nptr0->sc == FLABEL) jmp(nptr0->dsp);
+	else if(nptr0->sc == EMPTY)
+	{	nptr0->sc = FLABEL;
+		jmp(nptr0->dsp = fwdlabel());
+	}
+	else error(STERR);
+	checksym(SM);
+}
+dolabel()
+{	if(nptr->sc == FLABEL) fwddef(nptr->dsp);
+	else if(nptr->sc != EMPTY) error(TYERR);
+	nptr->sc = BLABEL;
+	nptr->dsp = backdef();
+	getsym();
+	checksym(COLON);
+}
+
+expr()
+{	return(rvalue(expr0()));
+}
+expr0()
+{int e;
+	e=expr1();
+	while(sym==COMMA) {getsym();e=list3(COMMA,e,rvalue(expr1()));}
+	return e;
+}
+expr1()
+{int e1,e2,t,op;
+	e1=expr2();
+	switch (sym)
+	{case ASS:
+		lcheck(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr1());
+		if(t==CHAR) {type= INT;return(list3(CASS,e1,e2));}
+		type=t;
+		return(list3(ASS,e1,e2));
+	case ADD+AS: case SUB+AS: case MUL+AS: case DIV+AS: case MOD+AS:
+	case RSHIFT+AS: case LSHIFT+AS: case BAND+AS: case EOR+AS: case BOR+AS:
+		op = sym-AS;
+		lcheck(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr1());
+		if(!integral(type)) error(TYERR);
+		if((t==UNSIGNED||type==UNSIGNED)&&
+			(op==MUL||op==DIV||op==MOD||op==RSHIFT||op==LSHIFT))
+			op=op+US;
+		if(t==CHAR)
+		{	type= INT;
+			return(list4(CASSOP,e1,e2,op));
+		}
+		type=t;
+		if(integral(t)) return(list4(ASSOP,e1,e2,op));
+		if((op!=ADD&&op!=SUB)||car(t)!=POINTER) error(TYERR);
+		e2=binop(MUL,e2,list2(CONST,size(cadr(t))),INT,UNSIGNED);
+		type=t;
+		return list4(ASSOP,e1,e2,op);
+	default:
+		return(e1);
+	}
+}
+expr2()
+{int e1,e2,e3,t;
+	e1=expr3();
+	if(sym==COND)
+	{	e1=rvalue(e1);
+		getsym();
+		e2=rvalue(expr2());
+		t=type;
+		checksym(COLON);
+		e3=rvalue(expr2());
+		if(car(e1)==CONST)
+			if(cadr(e1)) {type=t;return e2;}
+			else return e3;
+		if(type==INT||t!=INT&&type==UNSIGNED) type=t;
+		return(list4(COND,e1,e2,e3));
+	}
+	return(e1);
+}
+expr3()
+{int e;
+	e=expr4();
+	while(sym==LOR)
+	{	e=rvalue(e);
+		getsym();
+		e=list3(LOR,e,rvalue(expr4()));
+		type= INT;
+	}
+	return(e);
+}
+expr4()
+{int e;
+	e=expr5();
+	while(sym==LAND)
+	{	e=rvalue(e);
+		getsym();
+		e=list3(LAND,e,rvalue(expr5()));
+		type= INT;
+	}
+	return(e);
+}
+expr5()
+{int e1,e2,t;
+	e1=expr6();
+	while(sym==BOR)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr6());
+		e1=binop(BOR,e1,e2,t,type);
+	}
+	return(e1);
+}
+expr6()
+{int e1,e2,t;
+	e1=expr7();
+	while(sym==EOR)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr7());
+		e1=binop(EOR,e1,e2,t,type);
+	}
+	return(e1);
+}
+expr7()
+{int e1,e2,t;
+	e1=expr8();
+	while(sym==BAND)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr8());
+		e1=binop(BAND,e1,e2,t,type);
+	}
+	return(e1);
+}
+expr8()
+{int e,op;
+	e=expr9();
+	while((op=sym)==EQ||op==NEQ)
+	{	e=rvalue(e);
+		getsym();
+		e=list3(op,e,rvalue(expr9()));
+		type= INT;
+	}
+	return e;
+}
+expr9()
+{int e1,e2,t,op;
+	e1=expr10();
+	while((op=sym)==GT||op==GE||op==LT||op==LE)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr10());
+		if(t==INT&&type==INT) e1=list3(op,e1,e2);
+		else e1=list3(op+US,e1,e2);
+		type= INT;
+	}
+	return e1;
+}
+expr10()
+{int e1,e2,t,op;
+	e1=expr11();
+	while((op=sym)==RSHIFT||op==LSHIFT)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr11());
+		e1=binop(op,e1,e2,t,type);
+	}
+	return e1;
+}
+expr11()
+{int e1,e2,t,op;
+	e1=expr12();
+	while((op=sym)==ADD||op==SUB)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr12());
+		e1=binop(op,e1,e2,t,type);
+	}
+	return e1;
+}
+expr12()
+{int e1,e2,t,op;
+	e1=expr13();
+	while((op=sym)==MUL||op==DIV||op==MOD)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr13());
+		e1=binop(op,e1,e2,t,type);
+	}
+	return e1;
+}
+expr13()
+{int e,op;
+	switch (op = sym)
+	{case INC: case DEC:
+		getsym();
+		lcheck(e=expr13());
+		if(type==CHAR)
+		{	type= INT;
+			return(list2(op==INC?CPREINC:CPREDEC,e));
+		}
+		if(integral(type))
+			return(list3(PREINC,e,op==INC?1:-1));
+		if(car(type)!=POINTER) error(TYERR);
+		return(list3(PREINC,e,
+			op==INC?size(cadr(type)):-size(cadr(type)) ));
+	case MUL:
+		getsym();
+		e=rvalue(expr13());
+		return(indop(e));
+	case BAND:
+		getsym();
+		switch(car(e=expr13()))
+		{case INDIRECT:
+			e=cadr(e);
+			break;
+		case GVAR:
+		case LVAR:
+			e=list2(ADDRESS,e);
+			break;
+		case FNAME:
+			return e;
+		default:error(LVERR);
+		}
+		type=list2(POINTER,type);
+		return e;
+	case SUB:
+		getsym();
+		e=rvalue(expr13());
+		if(!integral(type)) error(TYERR);
+		return(car(e)==CONST?list2(CONST,-cadr(e)):list2(MINUS,e));
+	case BNOT:
+		getsym();
+		e=rvalue(expr13());
+		if(!integral(type)) error(TYERR);
+		return(car(e)==CONST?list2(CONST,~cadr(e)):list2(BNOT,e));
+	case LNOT:
+		getsym();
+		return(list2(LNOT,rvalue(expr13())));
+	case SIZEOF:
+		if(getsym()==LPAR)
+			if(typeid(getsym()))
+			{	e=list2(CONST,size(typename()));
+				type=INT;
+				checksym(RPAR);
+				return e;
+			}
+			else
+			{	e=expr0();
+				checksym(RPAR);
+				expr16(e);
+				if(sym==INC||sym==DEC)
+				{	getsym();
+					if(type==CHAR) type=INT;
+					else if(!scalar(type))
+						error(TYERR);
+				}
+			}
+		else expr13();
+		e=list2(CONST,size(type));
+		type=INT;
+		return e;
+	}
+	e=expr14();
+	if((op=sym)==INC||op==DEC)
+	{	lcheck(e);
+		getsym();
+		if(type==CHAR)
+		{	type= INT;
+			return(list2(op==INC?CPOSTINC:CPOSTDEC,e));
+		}
+		if(integral(type))
+			return(list3(POSTINC,e,op==INC?1:-1));
+		if(car(type)!=POINTER) error(TYERR);
+		return (list3(POSTINC,e,
+			op == INC ? size(cadr(type)): -size(cadr(type)) ));
+	}
+	return e;
+}
+expr14()
+{int e1,t;
+	switch(sym)
+	{case IDENT:
+		switch(nptr->sc)
+		{case GVAR:
+			e1=list2(GVAR,nptr->dsp);
+			type=nptr->ty;
+			getsym();
+			break;
+		case LVAR:
+			e1=list2(LVAR,nptr->dsp);
+			type=nptr->ty;
+			getsym();
+			break;
+		case FUNCTION:
+			e1=list2(FNAME,(int)nptr);
+			type=list2(FUNCTION,nptr->ty);
+			getsym();
+			break;
+		case EMPTY:
+			if(getsym()==LPAR)
+			{	nptr->sc = FUNCTION;
+				nptr->ty= INT;
+				type= list2(FUNCTION,INT);
+				e1=expr15(list2(FNAME,(int)nptr));
+				break;
+			}
+		default:error(UDERR);
+		}
+		break;
+	case STRING:
+		e1=list3(STRING,(int)sptr,symval);
+		type=list3(ARRAY,CHAR,symval);
+		getsym();
+		break;
+	case CONST:
+		type= INT;
+		e1=list2(CONST,symval);
+		getsym();
+		break;
+	case LPAR:
+		if(typeid(getsym()))
+		{	t=typename();
+			checksym(RPAR);
+			e1=expr13();
+			type=t;
+			return e1;
+		}
+		e1=expr0();
+		checksym(RPAR);
+		break;
+	default:error(EXERR);
+	}
+	return expr16(e1);
+}
+expr16(e1)
+int e1;
+{int e2,t;
+	while(1)
+		if(sym==LBRA)
+		{	e1=rvalue(e1);
+			t=type;
+			getsym();
+			e2=rvalue(expr0());
+			checksym(RBRA);
+			e1=binop(ADD,e1,e2,t,type);
+			e1=indop(e1);
+		}
+		else if(sym==LPAR) e1=expr15(e1);
+		else if(sym==PERIOD) e1=strop(e1);
+		else if(sym==ARROW) e1=strop(indop(rvalue(e1)));
+		else break;
+	if(car(e1)==FNAME) type=list2(POINTER,type);
+	return e1;
+}
+rvalue(e)
+int e;
+{	if(type==CHAR)
+	{	type= INT;
+		switch(car(e))
+		{case GVAR:
+			return(list2(CRGVAR,cadr(e)));
+		case LVAR:
+			return(list2(CRLVAR,cadr(e)));
+		case INDIRECT:
+			return(list2(CRINDIRECT,cadr(e)));
+		default:return(e);
+		}
+	}
+	if(!integral(type))
+		if(car(type)==ARRAY)
+		{	type=list2(POINTER,cadr(type));
+			if(car(e)==INDIRECT) return cadr(e);
+			return list2(ADDRESS,e);
+		}
+		else if(car(type)!=POINTER) error(TYERR);
+	switch(car(e))
+	{case GVAR:
+		return(list2(RGVAR,cadr(e)));
+	case LVAR:
+		return(list2(RLVAR,cadr(e)));
+	case INDIRECT:
+		return(list2(RINDIRECT,cadr(e)));
+	default:return(e);
+	}
+}
+lcheck(e)
+int e;
+{	if(!scalar(type)||car(e)!=GVAR&&car(e)!=LVAR&&car(e)!=INDIRECT)
+		error(LVERR);
+}
+indop(e)
+int e;
+{	if(type!=INT&&type!=UNSIGNED)
+		if(car(type)==POINTER) type=cadr(type);
+		else error(TYERR);
+	else type= CHAR;
+	if(car(e)==ADDRESS) return(cadr(e));
+	return(list2(INDIRECT,e));
+}
+strop(e)
+{	getsym();
+	if (sym!=IDENT||nptr->sc!=FIELD) error(TYERR);
+	if (integral(type)||car(type)!=STRUCT && car(type)!=UNION)
+		e=rvalue(e);
+	type = nptr->ty;
+	switch(car(e))
+	{case GVAR:
+	case LVAR:
+		e=list2(car(e),cadr(e) + nptr->dsp);
+		break;
+	case INDIRECT:
+		if(!nptr->dsp) break;
+		e=list2(INDIRECT,list3(ADD,cadr(e),list2(CONST,nptr->dsp)));
+		break;
+	default:
+		e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp)));
+	}
+	getsym();
+	return e;
+}
+binop(op,e1,e2,t1,t2)
+int op,e1,e2,t1,t2;
+{int e;
+	if(car(e1)==CONST&&car(e2)==CONST)
+	{	e1=cadr(e1);
+		e2=cadr(e2);
+		type= INT;
+		switch(op)
+		{case BOR:
+			e=e1|e2;break;
+		case EOR:
+			e=e1^e2;break;
+		case BAND:
+			e=e1&e2;break;
+		case ADD:
+			if(integral(t1))
+			{	if(integral(t2))
+					e=e1+e2;
+				else
+				{	if(car(t2)!=POINTER) error(TYERR);
+					e=size(cadr(t2))*e1+e2;
+					type=t2;
+				}
+			}
+			else
+			{	if(car(t1)!=POINTER) error(TYERR);
+				e=e1+size(cadr(t1))*e2;
+				type=t1;
+			}
+			break;
+		case SUB:
+			if(integral(t1))
+				e=e1-e2;
+			else
+			{	if(car(t1)!=POINTER) error(TYERR);
+				e=e1-size(cadr(t1))*e2;
+				type=t1;
+			}
+			break;
+		case MUL:
+			e=e1*e2;break;
+		case DIV:
+			if(!e2) error(EXERR);e=e1/e2;break;
+		case MOD:
+			if(!e2) error(EXERR);e=e1%e2;break;
+		case RSHIFT:
+			e=e1>>e2;break;
+		case LSHIFT:
+			e=e1<<e2;
+		}
+		return list2(CONST,e);
+	}
+	if((op==ADD||op==MUL||op==BOR||op==EOR||op==BAND)&&
+		(car(e1)==CONST||car(e2)!=CONST&&
+		(car(e1)==RGVAR||car(e1)==RLVAR)))
+		{e=e1;e1=e2;e2=e;e=t1;t1=t2;t2=e;}
+	if(op==ADD)
+	{	if(integral(t1))
+		{	if(integral(t2))
+			{	if(t1==INT) type=t2;else type=t1;
+				return(list3(ADD,e1,e2));
+			}
+			if(car(t2)!=POINTER) error(TYERR);
+			e=binop(MUL,e1,list2(CONST,size(cadr(t2))),t1,INT);
+			type=t2;
+			return(list3(ADD,e,e2));
+		}
+		if(car(t1)!=POINTER||!integral(t2)) error(TYERR);
+		e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT);
+		type=t1;
+		if(car(e1)==ADDRESS&&car(e)==CONST)
+			return(list2(ADDRESS,list2(car(cadr(e1)),
+				cadr(cadr(e1))+cadr(e))));
+		return(list3(ADD,e1,e));
+	}
+	if(op==SUB)
+	{	if(integral(t1))
+		{	if(!integral(t2)) error(TYERR);
+			if(t1==INT) type=t2;else type=t1;
+			return(list3(SUB,e1,e2));
+		}
+		if(car(t1)!=POINTER) error(TYERR);
+		if(integral(t2))
+		{	e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT);
+			type=t1;
+			return(list3(SUB,e1,e));
+		}
+		if(car(t2)!=POINTER)
+			error(TYERR);
+		compatible(t1,t2);
+		e=list3(SUB,e1,e2);
+		e=binop(DIV,e,list2(CONST,size(cadr(t1))),UNSIGNED,INT);
+		type= INT;
+		return e;
+	}
+	if(!integral(t1)||!integral(t2)) error(TYERR);
+	if(t1==INT) type=t2;else type=t1;
+	if((op==MUL||op==DIV)&&car(e2)==CONST&&cadr(e2)==1) return e1;
+	if(op==BOR||op==EOR||op==BAND) return(list3(op,e1,e2));
+	return(list3(type==UNSIGNED?op+US:op,e1,e2));
+}
+expr15(e1)
+int e1;
+{int t,args;
+	t=type;
+	if(integral(t)||car(t)!=FUNCTION)
+		error(TYERR);
+	t=cadr(t);
+	getsym();
+	args=0;
+	while(sym!=RPAR)
+	{	args=list2(rvalue(expr1()),args);
+		if(sym!=COMMA) break;
+		getsym();
+	}
+	checksym(RPAR);
+	if(t==CHAR) type= INT;else type=t;
+	return list3(FUNCTION,e1,args);
+}
+typeid(s)
+int s;
+{	return (integral(s) || s==SHORT || s==LONG || s==STRUCT || s==UNION ||
+		(s==IDENT && nptr->sc==TYPE));
+}
+typename()
+{int t;
+	type=t=typespec();
+	ndecl0();
+	reverse(t);
+	return type;
+}
+ndecl0()
+{	if(sym==MUL)
+	{	getsym();
+		return type=list2(POINTER,ndecl0());
+	}
+	return ndecl1();
+}
+ndecl1()
+{int i,t;
+	if(sym==LPAR)
+		if(getsym()==RPAR) {type=list2(FUNCTION,type); getsym();}
+		else
+		{	ndecl0();
+			checksym(RPAR);
+		}
+	while(1)
+		if(sym==LBRA)
+		{	getsym();
+			t=type;
+			i=cexpr(expr());
+			checksym(RBRA);
+			type=list3(ARRAY,t,i);
+		}
+		else if(sym==LPAR)
+		{	getsym();
+			checksym(RPAR);
+			type=list2(FUNCTION,type);
+		}
+		else return type;
+}
+
+bexpr(e1,cond,l1)
+int e1,l1;
+char cond;
+{int e2,l2;
+	if (chk) return;
+	e2=cadr(e1);
+	switch(car(e1))
+	{case LNOT:
+		bexpr(e2,!cond,l1);
+		return;
+	case GT:
+		rexpr(e1,l1,cond?"GT":"LE");
+		return;
+	case UGT:
+		rexpr(e1,l1,cond?"HI":"LS");
+		return;
+	case GE:
+		rexpr(e1,l1,cond?"GE":"LT");
+		return;
+	case UGE:
+		rexpr(e1,l1,cond?"HS":"LO");
+		return;
+	case LT:
+		rexpr(e1,l1,cond?"LT":"GE");
+		return;
+	case ULT:
+		rexpr(e1,l1,cond?"LO":"HS");
+		return;
+	case LE:
+		rexpr(e1,l1,cond?"LE":"GT");
+		return;
+	case ULE:
+		rexpr(e1,l1,cond?"LS":"HI");
+		return;
+	case EQ:
+		rexpr(e1,l1,cond?"EQ":"NE");
+		return;
+	case NEQ:
+		rexpr(e1,l1,cond?"NE":"EQ");
+		return;
+	case LAND:
+		bexpr(e2,0,cond?(l2=fwdlabel()):l1);
+		bexpr(caddr(e1),cond,l1);
+		if(cond) fwddef(l2);
+		return;
+	case LOR:
+		bexpr(e2,1,cond?l1:(l2=fwdlabel()));
+		bexpr(caddr(e1),cond,l1);
+		if(!cond) fwddef(l2);
+		return;
+	case CRGVAR:
+		ldby(e2);
+		jcond(l1,cond);
+		return;
+	case CRLVAR:
+		ldbu(e2);
+		jcond(l1,cond);
+		return;
+	case CONST:
+		if(cond&&e2||!cond&&!e2) jmp(l1);
+		return;
+	case RGVAR:
+	case RLVAR:
+	case CRINDIRECT:
+		gexpr(e1);
+		jcond(l1,cond);
+		return;
+	default:gexpr(e1);
+		subdim(0);
+		jcond(l1,cond);
+		return;
+	}
+}
+rexpr(e1,l1,s)
+int e1,l1;
+char *s;
+{	gexpr(list3(SUB,cadr(e1),caddr(e1)));
+	printf("\tLB%s\t_%d\n",s,l1);
+}
+jcond(l,cond)
+int l;
+char cond;
+{	printf("\tLB%s\t_%d\n",cond?"NE":"EQ",l);
+}
+jmp(l)
+int l;
+{	control=0;
+	printf("\tLBRA\t_%d\n",l);
+}
+fwdlabel()
+{	return labelno++;
+}
+fwddef(l)
+int l;
+{	control=1;
+	printf("_%d\n",l);
+}
+backdef()
+{	control=1;
+	printf("_%d\n",labelno);
+	return labelno++;
+}
+
+gexpr(e1)
+int e1;
+{int e2,e3;
+	if (chk) return;
+	e2 = cadr(e1);
+	switch (car(e1))
+	{case GVAR:
+		leaxy(e2);
+		return;
+	case RGVAR:
+		lddy(e2);
+		return;
+	case CRGVAR:
+		ldby(e2);
+		sex();
+		return;
+	case LVAR:
+		leaxu(e2);
+		return;
+	case RLVAR:
+		lddu(e2);
+		return;
+	case CRLVAR:
+		ldbu(e2);
+		sex();
+		return;
+	case FNAME:
+		leaxpcr((NMTBL *)e2);
+		tfrxd();
+		return;
+	case CONST:
+		if (e2) lddim(e2);
+		else clrd();
+		return;
+	case STRING:
+		string(e1);
+		return;
+	case FUNCTION:
+		function(e1);
+		return;
+	case INDIRECT:
+		indirect(e1);
+		return;
+	case RINDIRECT: case CRINDIRECT:
+		rindirect(e1);
+		return;
+	case ADDRESS:
+		gexpr(e2);
+		tfrxd();
+		return;
+	case MINUS:
+		gexpr(e2);
+		printf("\tNEGA\n\tNEGB\n\tSBCA\t#0\n");
+		return;
+	case BNOT:
+		gexpr(e2);
+		printf("\tCOMA\n\tCOMB\n");
+		return;
+	case PREINC:
+		switch (car(e2))
+		{case GVAR: case LVAR:
+			ldd(e2);
+			adddim(caddr(e1));
+			std(e2);
+			return;
+		default:
+			gexpr(e2);
+			lddx();
+			adddim(caddr(e1));
+			stdx();
+			return;
+		}
+	case POSTINC:
+		switch (car(e2))
+		{case GVAR: case LVAR:
+			ldd(e2);
+			adddim(e3 = caddr(e1));
+			std(e2);
+			subdim(e3);
+			return;
+		default:
+			gexpr(e2);
+			lddx();
+			adddim(e3=caddr(e1));
+			stdx();
+			subdim(e3);
+			return;
+		}
+	case CPOSTINC:
+		gexpr(e2);
+		ldbx();
+		incx();
+		sex();
+		return;
+	case CPREINC:
+		gexpr(e2);
+		incx();
+		ldbx();
+		sex();
+		return;
+	case CPOSTDEC:
+		gexpr(e2);
+		ldbx();
+		decx();
+		sex();
+		return;
+	case CPREDEC:
+		gexpr(e2);
+		decx();
+		ldbx();
+		sex();
+		return;
+	case MUL: case UMUL:
+		if (car(e3=caddr(e1)) == CONST)
+		{	if (0 < (e3 = cadr(e3)) && e3 <= 10)
+			{	gexpr(e2);
+				switch (e3)
+				{case 8:
+					asld();
+				case 4:
+					asld();
+				case 2:
+					asld();
+				case 1:
+					return;
+				case 10:
+					asld();
+				case 5:
+					pushd();
+					asld();
+					asld();
+					addds();
+					return;
+				case 6:
+					asld();
+				case 3:
+					pushd();
+					asld();
+					addds();
+					return;
+				case 9: case 7:
+					pushd();
+					asld();
+					asld();
+					asld();
+					if (e3 == 9) addds(); else subds();
+					return;
+				}
+			}
+		}
+	case DIV:    case UDIV:	   case MOD:	case UMOD:
+	case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT:
+		binexpr(e1);
+		return;
+	case ADD: case SUB: case BAND: case EOR: case BOR:
+		machinop(e1);
+		return;
+	case COND:
+		e2=fwdlabel();
+		bexpr(cadr(e1),0,e2);
+		gexpr(caddr(e1));
+		jmp(e3=fwdlabel());
+		fwddef(e2);
+		gexpr(cadddr(e1));
+		fwddef(e3);
+		return;
+	case ASS: case CASS:
+		assign(e1);
+		return;
+	case ASSOP: case CASSOP:
+		assop(e1);
+		return;
+	case COMMA:
+		gexpr(e2);
+		gexpr(caddr(e1));
+		return;
+	default:
+		bexpr(e1,1,e2=fwdlabel());
+		clrd();
+		printf("\tBRA\t*+5\n");
+		fwddef(e2);
+		lddim(1);
+	}
+}
+string(e1)
+int e1;
+{char *s;
+int i,l,lb;
+	s=(char *)cadr(e1);
+	lb=fwdlabel();
+	if ((l = caddr(e1)) < 128)
+		printf("\tLEAX\t2,PC\n\tBRA\t_%d\n",lb);
+	else
+		printf("\tLEAX\t3,PC\n\tLBRA\t_%d\n",lb);
+	do
+	{	printf("\tFCB\t%d",*s++);
+		for (i=8; --l && --i;) printf(",%d",*s++);
+		printf("\n");
+	}
+	while (l);
+	fwddef(lb);
+}
+function(e1)
+int e1;
+{int e2,e3,e4,e5,nargs;
+NMTBL *n;
+	e2 = cadr(e1);
+	nargs = 0;
+	for (e3 = caddr(e1); e3; e3 = cadr(e3))
+	{	n=(NMTBL *)(e5=(cadr(e4 = car(e3))));
+		switch(car(e4))
+		{case FNAME:
+			leaxpcr(n);
+			pushx();
+			break;
+		case ADDRESS:
+			gexpr(e5);
+			pushx();
+			break;
+		default:gexpr(e4);
+			pushd();
+		}
+		++nargs;
+	}
+	if (car(e2) == FNAME)
+	{	n=(NMTBL *)cadr(e2);
+		printf("\tLBSR\t%s\n",n->nm);
+	}
+	else
+	{	gexpr(e2);
+		printf("\tJSR\t,X\n");
+	}
+	if (nargs) printf("\tLEAS\t%d,S\n",2*nargs);
+}
+indirect(e1)
+int e1;
+{int e2,e3,e4;
+	e3 = cadr(e2 = cadr(e1));
+	switch(car(e2))
+	{case RGVAR: case RLVAR:
+		ldx(e2);
+		return;
+	case ADD:
+		if(car(e3)==ADDRESS)
+		{	gexpr(caddr(e2));
+			gexpr(cadr(e3));
+			opdx("LEAX");
+			return;
+		}
+		switch(car(e4 = caddr(e2)))
+		{case RGVAR: case RLVAR:
+			gexpr(e3);
+			ldx(e4);
+			opdx("LEAX");
+			return;
+		}
+	default:
+		gexpr(e2);
+		tfrdx();
+	}
+}
+
+machinop(e1)
+int e1;
+{int e2,e3;
+	e2 = cadr(e1);
+	switch (car(e3 = caddr(e1)))
+	{case RGVAR: case RLVAR: case CONST:
+		gexpr(e2);
+		oprt(car(e1),e3);
+		return;
+	default:
+		gexpr(e3);
+		pushd();
+		gexpr(e2);
+		tosop(car(e1));
+		return;
+	}
+}
+
+rindirect(e1)
+int e1;
+{char *op;
+int e2,e3,e4,byte,l;
+	op = ((byte = (car(e1) == CRINDIRECT)) ? "LDB" : "LDD");
+	e3 = cadr(e2 = cadr(e1));
+	switch (car(e2))
+	{case RGVAR: case RLVAR:
+		indir(op,e2);
+		sextend(byte);
+		return;
+	case ADD:
+		if(car(e3)==ADDRESS)
+		{	gexpr(caddr(e2));
+			gexpr(cadr(e3));
+			opdx(op);
+			sextend(byte);
+			return;
+		}
+		switch(car(e4=caddr(e2)))
+		{case RGVAR: case RLVAR:
+			gexpr(e3);
+			ldx(e4);
+			opdx(op);
+			sextend(byte);
+			return;
+		case CONST:
+			switch (car(e3))
+			{case RGVAR: case RLVAR:
+				ldx(e3);
+				indexx(op,cadr(e4));
+				sextend(byte);
+				return;
+			}
+		default:
+			gexpr(e3);
+			pushd();
+			gexpr(e4);
+			pulx();
+			opdx(op);
+			sextend(byte);
+			return;
+		}
+	case PREINC:
+		if ((l = caddr(e2)) == -1 || l == -2)
+			switch (car(e3))
+			{case GVAR: case LVAR:
+				ldx(e3);
+				predecx(op,l);
+				stx(e3);
+				sextend(byte);
+				return;
+			}
+		break;
+	case POSTINC:
+		if ((l = caddr(e2)) == 1 || l == 2)
+			switch (car(e3))
+			{case GVAR: case LVAR:
+				ldx(e3);
+				postincx(op,l);
+				stx(e3);
+				sextend(byte);
+				return;
+			}
+		break;
+	}
+	gexpr(e2);
+	tfrdx();
+	indexx(op,0);
+	sextend(byte);
+}
+assign(e1)
+int e1;
+{char *op;
+int e2,e3,e4,e5,l;
+	op = (car(e1) == CASS ? "STB" : "STD");
+	e3 = cadr(e2 = cadr(e1));
+	e4 = caddr(e1);
+	switch(car(e2))
+	{case GVAR: case LVAR:
+		gexpr(e4);
+		index(op,e2);
+		return;
+	case INDIRECT:
+		switch(car(e3))
+		{case RGVAR: case RLVAR:
+			gexpr(e4);
+			indir(op,e3);
+			return;
+		case ADD:
+			if (car(caddr(e3)) == CONST)
+				switch (car(e5=cadr(e3)))
+				{case RGVAR: case RLVAR:
+					gexpr(e4);
+					ldx(e5);
+					indexx(op,cadr(caddr(e3)));
+					return;
+				}
+			break;
+		case PREINC:
+			if ((l = caddr(e3)) == -1 || l == -2)
+				switch (car(e5=cadr(e3)))
+				{case GVAR: case LVAR:
+					gexpr(e4);
+					ldx(e5);
+					predecx(op,l);
+					stx(e5);
+					return;
+				}
+			break;
+		case POSTINC:
+			if ((l = caddr(e3)) == 1 || l == 2)
+				switch (car(e5=cadr(e3)))
+				{case GVAR: case LVAR:
+					gexpr(e4);
+					ldx(e5);
+					postincx(op,l);
+					stx(e5);
+					return;
+				}
+			break;
+		}
+	}
+	switch (car(e4))
+	{case RGVAR: case CRGVAR: case RLVAR: case CRLVAR: case CONST:
+		gexpr(e2);
+		gexpr(e4);
+		break;
+	default:
+		gexpr(e4);
+		pushd();
+		gexpr(e2);
+		pulld();
+	}
+	indexx(op,0);
+	return;
+}
+assop(e1)
+int e1;
+{int e2,e3,byte,op;
+char *ldop,*stop;
+	ldop = ((byte = (car(e1) == CASSOP)) ? "LDB" : "LDD");
+	stop = (byte ? "STB" : "STD");
+	e2 = cadr(e1);
+	e3 = caddr(e1);
+	op = cadddr(e1);
+	switch (car(e2))
+	{case GVAR: case LVAR:
+		switch (car(e3))
+		{case RGVAR: case RLVAR: case CONST:
+			if (simpop(op))
+			{	index(ldop,e2);
+				sextend(byte);
+				oprt(op,e3);
+				index(stop,e2);
+				return;
+			}
+		default:
+			gexpr(e3);
+			pushd();
+			index(ldop,e2);
+			sextend(byte);
+			tosop(op);
+			index(stop,e2);
+			return;
+		}
+	default:
+		switch (car(e3))
+		{case RGVAR: case RLVAR: case CONST:
+			if (simpop(op))
+			{	gexpr(e2);
+				indexx(ldop,0);
+				sextend(byte);
+				oprt(op,e3);
+				indexx(stop,0);
+				return;
+			}
+		default:
+			gexpr(e3);
+			pushd();
+			gexpr(e2);
+			indexx(ldop,0);
+			sextend(byte);
+			tosop(op);
+			indexx(stop,0);
+			return;
+		}
+	}
+}
+simpop(op)
+int op;
+{	return (op == ADD || op == SUB ||
+		op == BAND || op == EOR || op == BOR);
+}
+oprt(op,e1)
+int op,e1;
+{int e2;
+	e2 = cadr(e1);
+	switch (car(e1))
+	{case RGVAR:
+		oprt1(op,"Y",e2);
+		return;
+	case RLVAR:
+		oprt1(op,"U",e2);
+		return;
+	case CONST:
+		oprtc(op,e2);
+		return;
+	}
+}
+oprt1(op,index,n)
+int op,n;
+char *index;
+{	switch (op)
+	{case ADD:
+		printf("\tADDD\t%d,%s\n",n,index);
+		return;
+	case SUB:
+		printf("\tSUBD\t%d,%s\n",n,index);
+		return;
+	case BAND: case EOR: case BOR:
+		dualop(op,index,n);
+		return;
+	}
+}
+dualop(op,index,n)
+int op;
+char *index;
+int n;
+{char *ops;
+	ops =  ((op == BAND) ? "AND" :
+		(op == EOR)  ? "EOR" :
+		(op == BOR)  ? "OR"  : (char *)DEBUG);
+	printf("\t%sA\t%d,%s\n\t%sB\t%d+1,%s\n",ops,n,index,ops,n,index);
+}
+
+oprtc(op,n)
+int op,n;
+{	switch (op)
+	{case ADD:
+		adddim(n);
+		return;
+	case SUB:
+		subdim(n);
+		return;
+	case BAND: case EOR: case BOR:
+		dualc(op,n);
+		return;
+	}
+}
+dualc(op,n)
+int op;
+int n;
+{char *ops;
+	ops =  ((op == BAND) ? "AND" :
+		(op == EOR)  ? "EOR" :
+		(op == BOR)  ? "OR"  : (char *)DEBUG);
+	printf("\t%sA\t#%d\n\t%sB\t#%d\n",ops,(n >> 8) & 0xff,ops,n & 0xff);
+}
+tosop(op)
+int op;
+{	switch (op)
+	{case ADD:
+		addds();
+		return;
+	case SUB:
+		subds();
+		return;
+	case BAND: case EOR: case BOR:
+		dualtosop(op);
+		return;
+	default:
+		pulx();
+		library(op);
+	}
+}
+dualtosop(op)
+int op;
+{char *ops;
+	ops =  ((op == BAND) ? "AND" :
+		(op == EOR)  ? "EOR" :
+		(op == BOR)  ? "OR"  : (char *)DEBUG);
+	printf("\t%sA\t,S+\n\t%sB\t,S+\n",ops,ops);
+}
+pushd()
+{	printf("\tPSHS\tD\n");
+}
+pushx()
+{	printf("\tPSHS\tX\n");
+}
+pulld()
+{	printf("\tPULS\tD\n");
+}
+pulx()
+{	printf("\tPULS\tX\n");
+}
+tfrdx()
+{	printf("\tTFR\tD,X\n");
+}
+tfrxd()
+{	printf("\tTFR\tX,D\n");
+}
+/*
+exgdx()
+{	printf("\tEXG\tD,X\n");
+}
+*/
+asld()
+{	printf("\tASLB\n\tROLA\n");
+}
+adddim(n)
+{	printf("\tADDD\t#%d\n",n);
+}
+subdim(n)
+{	printf("\tSUBD\t#%d\n",n);
+}
+cmpdimm(n)
+int n;
+{	printf("\tCMPD\t#%d\n",n);
+}
+addds()
+{	printf("\tADDD\t,S++\n");
+}
+subds()
+{	printf("\tSUBD\t,S++\n");
+}
+clrd()
+{	printf("\tCLRA\n\tCLRB\n");
+}
+lddim(n)
+int n;
+{	printf("\tLDD\t#%d\n",n);
+}
+
+ldd(e)
+int e;
+{	switch (car(e))
+	{case GVAR:
+		lddy(cadr(e));
+		return;
+	case LVAR:
+		lddu(cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+
+lddx()
+{	printf("\tLDD\t,X\n");
+}
+lddy(n)
+int n;
+{	printf("\tLDD\t%d,Y\n",n);
+}
+lddu(n)
+int n;
+{	printf("\tLDD\t%d,U\n",n);
+}
+
+std(e)
+int e;
+{	switch (car(e))
+	{case GVAR:
+		stdy(cadr(e));
+		return;
+	case LVAR:
+		stdu(cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+stdx()
+{	printf("\tSTD\t,X\n");
+}
+stdy(n)
+int n;
+{	printf("\tSTD\t%d,Y\n",n);
+}
+stdu(n)
+int n;
+{	printf("\tSTD\t%d,U\n",n);
+}
+
+ldbx()
+{	printf("\tLDB\t,X\n");
+}
+/*
+stbx()
+{	printf("\tSTB\t,X\n");
+}
+*/
+ldby(n)
+int n;
+{	printf("\tLDB\t%d,Y\n",n);
+}
+ldbu(n)
+int n;
+{	printf("\tLDB\t%d,U\n",n);
+}
+predecx(op,l)
+char *op;
+int l;
+{	printf("\t%s\t,%sX\n",op,(l == -1 ? "-" : "--"));
+}
+postincx(op,l)
+char *op;
+int l;
+{	printf("\t%s\t,X%s\n",op,(l == 1 ? "+" : "++"));
+}
+leaxy(n)
+int n;
+{	printf("\tLEAX\t%d,Y\n",n);
+}
+leaxu(n)
+int n;
+{	printf("\tLEAX\t%d,U\n",n);
+}
+leaxpcr(n)
+NMTBL *n;
+{	printf("\tLEAX\t%s,PCR\n",n->nm);
+}
+
+ldx(e)
+int e;
+{	switch (car(e))
+	{case GVAR: case RGVAR:
+		ldxy(cadr(e));
+		return;
+	case LVAR: case RLVAR:
+		ldxu(cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+
+ldxy(n)
+int n;
+{	printf("\tLDX\t%d,Y\n",n);
+}
+ldxu(n)
+int n;
+{	printf("\tLDX\t%d,U\n",n);
+}
+/*
+ldxi(n)
+int n;
+{	printf("\tLDX\t#%d\n",n);
+}
+*/
+stx(e)
+int e;
+{	switch (car(e))
+	{case GVAR:
+		stxy(cadr(e));
+		return;
+	case LVAR:
+		stxu(cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+
+stxy(n)
+int n;
+{	printf("\tSTX\t%d,Y\n",n);
+}
+stxu(n)
+int n;
+{	printf("\tSTX\t%d,U\n",n);
+}
+
+sex()
+{	printf("\tSEX\n");
+}
+incx()
+{	printf("\tINC\t,X\n");
+}
+decx()
+{	printf("\tDEC\t,X\n");
+}
+opdx(op)
+char *op;
+{	printf("\t%s\tD,X\n",op);
+}
+indexx(op,n)
+char *op;
+int n;
+{	printf("\t%s\t%d,X\n",op,n);
+}
+
+index(op,e)
+char *op;
+int e;
+{	switch (car(e))
+	{case GVAR:
+		indexy(op,cadr(e));
+		return;
+	case LVAR:
+		indexu(op,cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+
+indexy(op,n)
+char *op;
+int n;
+{	printf("\t%s\t%d,Y\n",op,n);
+}
+indexu(op,n)
+char *op;
+int n;
+{	printf("\t%s\t%d,U\n",op,n);
+}
+
+
+indir(op,e)
+char *op;
+int e;
+{	switch (car(e))
+	{case RGVAR:
+		indiry(op,cadr(e));
+		return;
+	case RLVAR:
+		indiru(op,cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+
+indiry(op,n)
+char *op;
+int n;
+{	printf("\t%s\t[%d,Y]\n",op,n);
+}
+indiru(op,n)
+char *op;
+int n;
+{	printf("\t%s\t[%d,U]\n",op,n);
+}
+sextend(byte)
+int byte;
+{	if (byte) sex();
+}
+binexpr(e1)
+int e1;
+{	gexpr(caddr(e1));
+	pushd();
+	gexpr(cadr(e1));
+	pulx();
+	library(car(e1));
+}
+library(op)
+int op;
+{	printf("\tLBSR\t_0000%d\n",
+	       ((op == MUL || op == UMUL) ? 1 :
+		(op == DIV)	? 2 :
+		(op == UDIV)	? 3 :
+		(op == MOD)	? 4 :
+		(op == UMOD)	? 5 :
+		(op == LSHIFT)	? 6 :
+		(op == ULSHIFT) ? 7 :
+		(op == RSHIFT)	? 8 :
+		(op == URSHIFT) ? 9 : DEBUG));
+}
+cexpr(e)
+int e;
+{	if (car(e) != CONST) error(CNERR);
+	return (cadr(e));
+}
+
+getsym()
+{NMTBL *nptr0,*nptr1;
+int i;
+char c;
+	if (alpha(skipspc()))
+	{	i = hash = 0;
+		while (alpha(ch) || digit(ch))
+		{	if (i <= 7) hash=7*(hash+(name[i++]=ch));
+			getch();
+		}
+		name[i] = '\0';
+		nptr0 = gsearch();
+		if (nptr0->sc == RESERVE) return sym = nptr0->dsp;
+		if (nptr0->sc == MACRO && !mflag)
+		{	mflag++;
+			chsave = ch;
+			chptrsave = chptr;
+			chptr = (char *)nptr0->dsp;
+			getch();
+			return getsym();
+		}
+		sym = IDENT;
+		gnptr=nptr=nptr0;
+		if (mode==GDECL || mode==GSDECL || mode==GUDECL ||
+		    mode==GTDECL || mode==TOP)
+			return sym;
+		nptr1=lsearch();
+		if (mode==STAT)
+			if (nptr1->sc == EMPTY) return sym;
+			else { nptr=nptr1; return sym;}
+		nptr=nptr1;
+		return sym;
+	}
+	else if (digit(ch))
+	{	symval=0;
+		if (ch == '0')
+		{	if (getch() == 'x' || ch == 'X')
+				while(1)
+					if(digit(getch()))
+						symval=symval*16+ch-'0';
+					else if('a'<=ch&&ch<='f')
+						symval=symval*16+ch-'a'+10;
+					else if('A'<=ch&&ch<='F')
+						symval=symval*16+ch-'A'+10;
+					else break;
+			else while (digit(ch)) {symval=symval*8+ch-'0';getch();}
+		}
+		else while(digit(ch)) {symval=symval*10+ch-'0';getch();}
+		return sym=CONST;
+	}
+	else if(ch=='\'')
+	{	getch();
+		symval=escape();
+		if(ch!='\'') error(CHERR);
+		getch();
+		return sym=CONST;
+	}
+	else if(ch=='"')
+	{	getstring();
+		return sym= STRING;
+	}
+	c=ch;
+	getch();
+	switch(c)
+	{case '*':
+		return postequ(MUL,MUL+AS);
+	case '&':
+		if(ch=='&') {getch();return sym=LAND;}
+		return postequ(BAND,BAND+AS);
+	case '-':
+		if(ch=='>') {getch();return sym=ARROW;}
+		if(ch=='-') {getch();return sym=DEC;}
+		return postequ(SUB,SUB+AS);
+	case '!':
+		return postequ(LNOT,NEQ);
+	case '~':
+		return sym=BNOT;
+	case '+':
+		if(ch=='+') {getch();return sym=INC;}
+		return postequ(ADD,ADD+AS);
+	case '%':
+		return postequ(MOD,MOD+AS);
+	case '^':
+		return postequ(EOR,EOR+AS);
+	case '|':
+		if(ch=='|') {getch();return sym=LOR;}
+		return postequ(BOR,BOR+AS);
+	case '=':
+		return postequ(ASS,EQ);
+	case '>':
+		if(ch=='>') {getch();return postequ(RSHIFT,RSHIFT+AS);}
+		return postequ(GT,GE);
+	case '<':
+		if(ch=='<') {getch();return postequ(LSHIFT,LSHIFT+AS);}
+		return postequ(LT,LE);
+	case '(':
+		return sym=LPAR;
+	case ')':
+		return sym=RPAR;
+	case '[':
+		return sym=LBRA;
+	case ']':
+		return sym=RBRA;
+	case '{':
+		return sym=LC;
+	case '}':
+		return sym=RC;
+	case ',':
+		return sym=COMMA;
+	case ';':
+		return sym=SM;
+	case ':':
+		return sym=COLON;
+	case '?':
+		return sym=COND;
+	case '.':
+		return sym=PERIOD;
+	case '/':
+		if(ch!='*') return postequ(DIV,DIV+AS);
+		getch();
+		while(ch=='*'?getch()!='/':getch());
+		getch();
+		return getsym();
+	default:
+		error(CHERR);
+		return getsym();
+	}
+}
+postequ(s1,s2)
+int s1,s2;
+{	if(ch=='=') {getch();return sym=s2;}
+	return sym=s1;
+}
+alpha(c)
+char c;
+{	return('a'<=c&&c<='z'||'A'<=c&&c<='Z'||c=='_');
+}
+digit(c)
+char c;
+{	return('0'<=c&&c<='9');
+}
+NMTBL *gsearch()
+{NMTBL *nptr,*iptr;
+	iptr=nptr= &ntable[hash % GSYMS];
+	while(nptr->sc!=EMPTY && neqname(nptr->nm))
+	{	if (++nptr== &ntable[GSYMS]) nptr=ntable;
+		if (nptr==iptr) error(GSERR);
+	}
+	if (nptr->sc == EMPTY) copy(nptr->nm);
+	return nptr;
+}
+NMTBL *lsearch()
+{NMTBL *nptr,*iptr;
+	iptr=nptr= &ntable[hash%LSYMS+GSYMS];
+	while(nptr->sc!=EMPTY && neqname(nptr->nm))
+	{	if (++nptr== &ntable[LSYMS+GSYMS]) nptr= &ntable[GSYMS];
+		if (nptr==iptr) error(LSERR);
+	}
+	if (nptr->sc == EMPTY) copy(nptr->nm);
+	return nptr;
+}
+neqname(p)
+char *p;
+{char *q;
+	q=name;
+	while(*p) if(*p++ != *q++) return 1;
+	return *q!=0;
+}
+copy(p)
+char *p;
+{char *q;
+	q=name;
+	while(*p++= *q++);
+}
+getstring()
+{	getch();
+	symval = 0;
+	sptr = cheapp;
+	while (ch != '"')
+	{	*cheapp++ = escape();
+		symval++;
+		if (cheapp >= cheap+CHEAPSIZE) error(STRERR);
+	}
+	getch();
+	*cheapp++ = '\0';
+	symval++;
+}
+skipspc()
+{	while(ch=='\t'||ch=='\n'||ch==' '||ch=='\r') getch();
+	return ch;
+}
+getch()
+{	if(*chptr) return ch= *chptr++;
+	if(mflag) {mflag=0;chptr=chptrsave;return ch=chsave;}
+	getline();
+	return getch();
+}
+char escape()
+{char c;
+	if ((c=ch) == '\\')
+	{	if (digit(c=getch()))
+		{	c = ch-'0';
+			if (digit(getch()))
+			{	c = c*8+ch-'0';
+				if (digit(getch())) {c=c*8+ch-'0';getch();}
+			}
+			return c;
+		}
+		getch();
+		switch(c)
+		{case 'n':
+			return '\n';
+		case 't':
+			return '\t';
+		case 'b':
+			return '\b';
+		case 'r':
+			return '\r';
+		case 'f':
+			return '\f';
+		case '\n':
+			return escape();
+		default:
+			return c;
+		}
+	}
+	if (c == '\n') error(EXERR);
+	getch();
+	return c;
+}
+FILE *getfname()
+{int i;
+char name[LBUFSIZE];
+	getch();
+	if(skipspc()!='"') error(INCERR);
+	for(i=0;(getch()!='"' && ch!='\n');)
+		if(i<LBUFSIZE-1) name[i++]=ch;
+	if(ch=='\n') error(INCERR);
+	name[i]=0;
+	return ( (filep+1)->fcb = fopen(name,"r") );
+}
+getline()
+{int i;
+int c;
+	lineno++;
+	glineno++;
+	chptr=linebuf;
+	i=0;
+	while ((*chptr++ = c = getc(filep->fcb)) != '\n')
+	{	if (++i > LBUFSIZE-2) error(LNERR);
+		if (c==EOF)
+		{	error(EOFERR);
+			--chptr;
+		}
+	}
+	*chptr = '\0';
+	if (lsrc && !asmf) printf("* %s",linebuf);
+	if (*(chptr = linebuf) == '#')
+	{	++chptr;
+		if (macroeq("define"))
+		{	i=mode;
+			mode=GDECL;
+			ch= *chptr;
+			if (getsym() == IDENT)
+			{	if (nptr->sc == EMPTY)
+				{	nptr->sc = MACRO;
+					nptr->dsp = (int)cheapp;
+					while ((*cheapp++ = c = *chptr++)
+							&& c != '\n');
+					*cheapp++ = '\0';
+					if (cheapp >= cheap+CHEAPSIZE)
+						error(STRERR);
+					if (!c) error(EOFERR);
+				}
+				else error(MCERR);
+			}
+			else error(MCERR);
+			mode=i;
+			*(chptr = linebuf) = '\0';
+		}
+		else if (macroeq("include"))
+		{	fprintf(stderr,"%s",linebuf);
+			if(filep+1 >= filestack + FILES) error(FILERR);
+			if ( ((filep+1)->fcb=getfname()) == NULL) error(FILERR);
+			(filep+1)->ln=lineno;
+			lineno=0;
+			++filep;
+			*(chptr = linebuf) = '\0';
+		}
+		else if (macroeq("asm"))
+		{	if (asmf) error(MCERR);
+			asmf = 1;
+			getline();
+			while (asmf)
+			{	printf("%s",linebuf);
+				getline();
+			}
+		}
+		else if (macroeq("endasm"))
+		{	if (!asmf) error(MCERR);
+			asmf = 0;
+		}
+		else if (macroeq(" "))
+			getline();
+		else error(MCERR);
+	}
+}
+
+macroeq(s)
+char *s;
+{char *p;
+	for (p = chptr; *s;) if (*s++ != *p++) return 0;
+	chptr = p;
+	return 1;
+}
+
+car(e)
+int e;
+{	return heap[e];
+}
+cadr(e)
+int e;
+{	return heap[e+1];
+}
+caddr(e)
+int e;
+{	return heap[e+2];
+}
+cadddr(e)
+int e;
+{	return heap[e+3];
+}
+list2(e1,e2)
+int e1,e2;
+{int e;
+	e=getfree(2);
+	heap[e]=e1;
+	heap[e+1]=e2;
+	return e;
+}
+list3(e1,e2,e3)
+int e1,e2,e3;
+{int e;
+	e=getfree(3);
+	heap[e]=e1;
+	heap[e+1]=e2;
+	heap[e+2]=e3;
+	return e;
+}
+list4(e1,e2,e3,e4)
+int e1,e2,e3,e4;
+{int e;
+	e=getfree(4);
+	heap[e]=e1;
+	heap[e+1]=e2;
+	heap[e+2]=e3;
+	heap[e+3]=e4;
+	return e;
+}
+getfree(n)
+int n;
+{int e;
+	switch (mode)
+	{case GDECL: case GSDECL: case GUDECL: case GTDECL:
+		e=gfree;
+		gfree+=n;
+		break;
+	default:
+		lfree-=n;
+		e=lfree;
+	}
+	if(lfree<gfree) error(HPERR);
+	return e;
+}
+rplacad(e,n)
+int e,n;
+{	heap[e+1]=n;
+	return e;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/mc2.c	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,2896 @@
+
+#define DEBUG	error(-1)
+
+#include "mclib.c"
+
+#define INT	(-1)
+#define CHAR	(-2)
+#define UNSIGNED	(-3)
+#define POINTER (-4)
+#define ARRAY	(-5)
+#define STRUCT	(-6)
+#define UNION	(-7)
+#define FUNCTION	(-8)
+#define EMPTY	(-9)
+
+#define STATIC	(-10)
+#define GOTO	(-11)
+#define RETURN	(-12)
+#define BREAK	(-13)
+#define CONTINUE	(-14)
+#define IF	(-15)
+#define ELSE	(-16)
+#define FOR	(-17)
+#define DO	(-18)
+#define WHILE	(-19)
+#define SWITCH	(-20)
+#define CASE	(-21)
+#define DEFAULT (-22)
+#define RESERVE (-23)
+#define TAG	(-24)
+#define FIELD	(-25)
+#define IDENT	(-26)
+#define STRING	(-27)
+#define MACRO	(-28)
+#define BLABEL	(-29)
+#define FLABEL	(-30)
+#define TYPEDEF (-31)
+#define SIZEOF	(-32)
+#define TYPE	(-33)
+#define LONG	(-34)
+#define SHORT	(-35)
+
+#define TOP	0
+#define GDECL	1
+#define GSDECL	2
+#define GUDECL	3
+#define ADECL	4
+#define LDECL	5
+#define LSDECL	6
+#define LUDECL	7
+#define STADECL 8
+#define STAT	9
+#define GTDECL	10
+#define LTDECL	11
+
+#define GVAR	1
+#define RGVAR	2
+#define CRGVAR	3
+#define LVAR	4
+#define RLVAR	5
+#define CRLVAR	6
+#define CONST	7
+#define FNAME	8
+#define INDIRECT	9
+#define RINDIRECT	10
+#define CRINDIRECT	11
+#define ADDRESS 12
+#define MINUS	13
+#define LNOT	14
+#define BNOT	15
+#define INC	16
+#define POSTINC 17
+#define PREINC	18
+#define CPOSTINC	19
+#define CPREINC 20
+#define DEC	21
+#define CPOSTDEC	22
+#define CPREDEC 23
+#define MUL	24
+#define UMUL	25
+#define DIV	26
+#define UDIV	27
+#define MOD	28
+#define UMOD	29
+#define ADD	30
+#define SUB	31
+#define RSHIFT	32
+#define URSHIFT 33
+#define LSHIFT	34
+#define ULSHIFT 35
+#define GT	36
+#define UGT	37
+#define GE	38
+#define UGE	39
+#define LT	40
+#define ULT	41
+#define LE	42
+#define ULE	43
+#define EQ	44
+#define NEQ	45
+#define BAND	46
+#define EOR	47
+#define BOR	48
+#define LAND	49
+#define LOR	50
+#define COND	51
+#define ASS	52
+#define CASS	53
+#define ASSOP	54
+#define CASSOP	55
+#define COMMA	56
+#define LPAR	57
+#define RPAR	58
+#define LBRA	59
+#define RBRA	60
+#define LC	61
+#define RC	62
+#define COLON	63
+#define SM	64
+#define PERIOD	65
+#define ARROW	66
+
+#define US	1
+#define AS	100
+
+#define FILERR	1
+#define DCERR	2
+#define STERR	3
+#define EXERR	4
+#define CNERR	5
+#define CHERR	6
+#define GSERR	7
+#define LSERR	8
+#define STRERR	9
+#define LNERR	10
+#define EOFERR	11
+#define MCERR	12
+#define INCERR	13
+#define HPERR	14
+#define TYERR	15
+#define LVERR	16
+#define UDERR	17
+#define OPTION	18
+
+#define GSYMS	450
+#define LSYMS	50
+
+#define HEAPSIZE	700
+#define CHEAPSIZE	3000
+#define LBUFSIZE	256
+
+#define FILES 3
+
+int sym,ch,chsave,type,mode,gfree,lfree,mflag,lineno,glineno;
+int labelno,gpc,lvar,disp;
+int symval,args,heap[HEAPSIZE];
+int blabel,clabel,dlabel,cslabel,ilabel,control,ac,ac2,lsrc,chk,asmf;
+
+unsigned hash;
+
+char linebuf[LBUFSIZE],cheap[CHEAPSIZE],*chptr,*chptrsave;
+char name[9],*cheapp,**av,/*obuf[320],*/*sptr,escape();
+
+FILE *obuf;
+
+typedef struct nametable {
+	char nm[9];
+	int sc,ty,dsp; } NMTBL;
+
+NMTBL ntable[GSYMS+LSYMS],*nptr,*gnptr,*decl0(),*decl1(),*lsearch(),*gsearch();
+
+struct {int fd,ln;/*char fcb[320]*/FILE *fcb;} *filep,filestack[FILES];
+
+main(argc,argv)
+int argc;
+char **argv;
+{NMTBL *nptr;
+int i;
+char *ccout;
+	if(argc==1) exit(1);
+	lsrc = chk = asmf = 0;
+	ccout = "C.OUT";
+	ac=argc;
+	av=argv;
+	for (ac2=1; (ac2 < ac) && (*av[ac2] == '-'); ++ac2)
+		switch (*(av[ac2]+1))
+		{case 'S': case 's':
+			lsrc = 1;
+			break;
+		case 'O': case 'o':
+			ccout = av[ac2]+2;
+			break;
+		case 'C': case 'c':
+			chk = 1;
+			break;
+		default:
+			error(OPTION);
+			exit(1);
+		}
+	fclose(stdout);
+	if (!chk)
+		if ( (obuf = fopen(ccout,"wc")) == NULL ) error(FILERR);
+	init();
+	while(1)
+	{	for (nptr = &ntable[GSYMS],i=LSYMS; i--;)
+			(nptr++)->sc = EMPTY;
+		mode=TOP;
+		while(getsym()==SM);
+		mode=GDECL;
+		args=0;
+		decl();
+	}
+}
+error(n)
+int n;
+{	if(n == EOFERR)
+		if(filep!=filestack)
+		{	lineno=filep->ln;
+			fclose(filep->fcb);
+			fprintf(stderr,"End of inclusion.\n");
+			--filep;
+			return;
+		}
+		else if(ac2!=ac)
+		{	fclose(filep->fcb);
+			newfile();
+			return;
+		}
+		else if(mode == TOP)
+		{	fprintf(stderr,"\nCompiled %u lines.\n",glineno-1);
+			if (!chk) fprintf(stderr,
+				"Total internal labels	: %u.\n",labelno-1);
+			fprintf(stderr,
+				"Total global variables : %u bytes.\n\n",gpc);
+			printf("_%d\tRTS\n_INITIALIZE\tEQU\t_1\n",ilabel);
+			printf("_GLOBALS\tEQU\t%u\n\tEND\n",gpc);
+			exit(0);
+		}
+	fprintf(stderr,"%5d:%s.\n",lineno,
+		(n==FILERR) ? "Can't open specified file" :
+		(n==DCERR) ? "Declaration syntax" :
+		(n==STERR) ? "Statement syntax" :
+		(n==EXERR) ? "Expression syntax" :
+		(n==CNERR) ? "Constant required" :
+		(n==CHERR) ? "Illegal character" :
+		(n==GSERR) ? "Too many global symbols" :
+		(n==LSERR) ? "Too many local symbols" :
+		(n==STRERR) ? "Too many strings or macros" :
+		(n==LNERR) ? "Line too long" :
+		(n==EOFERR) ? "Unexpected end of file" :
+		(n==MCERR) ? "Macro syntax" :
+		(n==INCERR) ? "Include syntax" :
+		(n==HPERR) ? "Too long expression" :
+		(n==TYERR) ? "Type mismatch" :
+		(n==LVERR) ? "Lvalue required" :
+		(n==UDERR) ? "Undeclared identifier" :
+		(n==OPTION) ? "Illegal option" :
+		"Bug of compiler");
+	errmsg();
+	exit(1);
+}
+errmsg()
+{char *p,*lim;
+	if(lineno==0) return;
+	fprintf(stderr,"%s",linebuf);
+	lim=(mflag?chptrsave:chptr);
+	for (p=linebuf; p < lim;)
+		fprintf(stderr,(*p++ == '\t') ? "\t" : " ");
+	fprintf (stderr,"^\n");
+}
+checksym(s)
+int s;
+{char *p;
+	if (sym != s)
+	{	p=(s==RPAR) ? "')'": (s==RBRA) ? "']'": (s==SM) ? "';'":
+		  (s==LPAR) ? "'('": (s==WHILE) ? "'while'":
+		  (s==COLON) ? "':'": "Identifier";
+		fprintf(stderr,"%d:%s expected.\n",lineno,p);
+		errmsg();
+	}
+	else getsym();
+}
+init()
+{NMTBL *nptr;
+int i;
+	for(nptr = ntable,i = GSYMS; i--;) (nptr++)->sc = EMPTY;
+	reserve("int",INT);
+	reserve("void",INT);
+	reserve("char",CHAR);
+	reserve("struct",STRUCT);
+	reserve("union",UNION);
+	reserve("unsigned",UNSIGNED);
+	reserve("static",STATIC);
+	reserve("goto",GOTO);
+	reserve("return",RETURN);
+	reserve("break",BREAK);
+	reserve("continue",CONTINUE);
+	reserve("if",IF);
+	reserve("else",ELSE);
+	reserve("for",FOR);
+	reserve("do",DO);
+	reserve("while",WHILE);
+	reserve("switch",SWITCH);
+	reserve("case",CASE);
+	reserve("default",DEFAULT);
+	reserve("typedef",TYPEDEF);
+	reserve("sizeof",SIZEOF);
+	reserve("long",LONG);
+	reserve("short",SHORT);
+	gpc=glineno=mflag=0;
+	gfree=ilabel=1;
+	labelno=2;
+	cheapp=cheap;
+	lfree=HEAPSIZE;
+	filep=filestack;
+	newfile();
+	getline();
+	getch();
+}
+newfile()
+{	lineno=0;
+	fprintf(stderr,"%s:\n",av[ac2]);
+	if ( (filep->fcb = fopen(av[ac2++],"rc")) == NULL ) error(FILERR);
+}
+reserve(s,d)
+char *s;
+int d;
+{NMTBL *nptr;
+char *t;
+	hash=0;
+	t=name;
+	while(*t++ = *s) hash=7*(hash+*s++);
+	(nptr = gsearch())->sc = RESERVE;
+	nptr->dsp = d;
+}
+
+decl()
+{NMTBL *n;
+int t;
+	if(sym==STATIC)
+		if(mode==LDECL)
+		{	getsym();
+			mode=STADECL;
+		}
+		else error(DCERR);
+	else if(sym==TYPEDEF)
+		if(mode==GDECL)
+		{	getsym();
+			mode=GTDECL;
+		}
+		else if(mode==LDECL)
+		{	getsym();
+			mode=LTDECL;
+		}
+		else error(DCERR);
+	if((t=typespec())==0) return;
+	if(sym==SM) return;
+	type=t;
+	n=decl0();
+	reverse(t);
+	if(args||sym==LC) {fdecl(n);return;}
+	def(n);
+	while(sym==COMMA)
+	{	getsym();
+		type=t;
+		n=decl0();
+		reverse(t);
+		if(args) error(DCERR);
+		def(n);
+	}
+	if(sym!=SM) error(DCERR);
+	if(mode==GTDECL) mode=GDECL;
+	if(mode==STADECL||mode==LTDECL) mode=LDECL;
+}
+typespec()
+{int t;
+	switch(sym)
+	{case INT:
+	case CHAR:
+		t= sym;
+		getsym();
+		break;
+	case STRUCT:
+	case UNION:
+		t=sdecl(sym);
+		break;
+	case UNSIGNED:
+		t = UNSIGNED;
+		if(getsym()==INT) getsym();
+		break;
+	case SHORT:
+		t=CHAR;
+		if(getsym()==INT) getsym();
+		break;
+	case LONG:
+		t=INT;
+		if(getsym()==INT) getsym();
+		break;
+	default:
+		if(sym==IDENT)
+			if(nptr->sc==TYPE)
+			{	t=nptr->ty;
+				getsym();
+				break;
+			}
+			else if(nptr->sc==EMPTY && gnptr->sc==TYPE)
+			{	t=gnptr->ty;
+				getsym();
+				break;
+			}
+		if(mode==LDECL) return 0;
+		t= INT;
+	}
+	return t;
+}
+struct nametable *decl0()
+{NMTBL *n;
+	if(sym==MUL)
+	{	getsym();
+		n=decl0();
+		type=list2(POINTER,type);
+		return n;
+	}
+	return decl1();
+}
+NMTBL *decl1()
+{NMTBL *n;
+int i,t;
+	if(sym==LPAR)
+	{	getsym();
+		n=decl0();
+		checksym(RPAR);
+	}
+	else if (sym == IDENT)
+	{	n=nptr;
+		getsym();
+	}
+	else error(DCERR);
+	while(1)
+		if(sym==LBRA)
+			if(getsym()==RBRA)
+			{	getsym();
+				if(mode!=ADECL) error(DCERR);
+				t=type;
+				type=list2(POINTER,type);
+			}
+			else
+			{	t=type;
+				i=cexpr(expr());
+				checksym(RBRA);
+				type=list3(ARRAY,t,i);
+			}
+		else if(sym==LPAR)
+		{	if(mode==GDECL) {mode=ADECL;getsym();mode=GDECL;}
+			else getsym();
+			if(sym==RPAR) getsym();
+			else
+			{	n->sc=FUNCTION;
+				adecl();
+				n->sc=EMPTY;
+			}
+			type=list2(FUNCTION,type);
+		}
+		else return n;
+}
+adecl()
+{	if(mode!=GDECL) error(DCERR);
+	mode=ADECL;
+	args= 2;
+	while(1)
+	{	if(sym!=IDENT) error(DCERR);
+		nptr->ty = INT;
+		nptr->sc = LVAR;
+		nptr->dsp = (args += 2);
+		if(getsym()!=COMMA) break;
+		getsym();
+	}
+	checksym(RPAR);
+	mode=GDECL;
+	return;
+}
+reverse(t1)
+int t1;
+{int t2,t3;
+	t2=t1;
+	while(type!=t1)
+	{	t3=cadr(type);
+		rplacad(type,t2);
+		t2=type;
+		type=t3;
+	}
+	type=t2;
+}
+size(t)
+int t;
+{	if(t==CHAR) return 1;
+	if(scalar(t)) return 2;
+	if(car(t)==STRUCT||car(t)==UNION)
+	{	if(cadr(t)==-1) error(DCERR);
+		return(cadr(t));
+	}
+	if(car(t)==ARRAY) return(size(cadr(t))*caddr(t));
+	else error(DCERR);
+	/*NOTREACHED*/
+}
+def(n)
+NMTBL *n;
+{int sz,nsc,ndsp,slfree,l,t,e;
+	if(car(type)==FUNCTION)
+	{	fcheck(n);
+		return;
+	}
+	if (n->sc!=EMPTY &&
+	    (mode!=ADECL || n->sc!=LVAR || n->ty!=INT) &&
+	    (mode!=GSDECL&&mode!=LSDECL || n->sc!=FIELD || n->dsp!=disp) &&
+	    (mode!=GUDECL&&mode!=LUDECL || n->sc!=FIELD || n->dsp!=0) )
+		 error(DCERR);
+	sz = size(n->ty = type);
+	switch(mode)
+	{case GDECL:
+		printf("%s\tEQU\t%u\n",n->nm,gpc);
+	case STADECL:
+		nsc = GVAR;
+		ndsp = gpc;
+		if(sym==ASS)
+		{	t=type;
+			if(!scalar(t))
+				error(TYERR);
+			if(mode==STADECL) printf("\tBRA\t_%d\n",l=fwdlabel());
+			fwddef(ilabel);
+			getsym();
+			slfree=lfree;
+			e=expr1();
+			if(car(e)==CONST)
+			{	lddim(cadr(e));
+				indexy(t==CHAR?"STB":"STD",gpc);
+			}
+			else if(t!=CHAR)
+			{	if(car(e)==ADDRESS&&car(cadr(e))==GVAR)
+					leaxy(cadr(cadr(e)));
+				else if(car(e)==FNAME)
+					leaxpcr((NMTBL *)cadr(e));
+				else error(TYERR);
+				stxy(gpc);
+			}
+			else error(TYERR);
+			lfree=slfree;
+			jmp(ilabel=fwdlabel());
+			if(mode==STADECL) fwddef(l);
+			type=t;
+		}
+		gpc +=sz;
+		break;
+	case GSDECL:
+		nsc = FIELD;
+		ndsp = disp;
+		disp += sz;
+		break;
+	case GUDECL:
+		nsc = FIELD;
+		ndsp = 0;
+		if (disp < sz) disp = sz;
+		break;
+	case GTDECL:
+		nsc = TYPE;
+		break;
+	case ADECL:
+		if(type==CHAR) ++(n->dsp);
+		else if (!scalar(type)) error(TYERR);
+		return;
+	case LDECL:
+		nsc = LVAR;
+		ndsp = (disp -= sz);
+		break;
+	case LSDECL:
+		nsc = FIELD;
+		ndsp = disp;
+		disp += sz;
+		break;
+	case LUDECL:
+		nsc = FIELD;
+		ndsp = 0;
+		if (disp < sz) disp = sz;
+		break;
+	case LTDECL:
+		nsc = TYPE;
+		break;
+	default:
+		error(DCERR);
+	}
+	n->sc = nsc;
+	n->dsp = ndsp;
+}
+sdecl(s)
+int s;
+{int smode,sdisp,type;
+NMTBL *nptr0;
+	smode=mode;
+	if (mode==GDECL || mode==GSDECL || mode==GUDECL || mode==GTDECL)
+		mode=(s==STRUCT?GSDECL:GUDECL);
+	else mode=(s==STRUCT?LSDECL:LUDECL);
+	sdisp=disp;
+	disp=0;
+	if (getsym() == IDENT)
+	{	nptr0 = nptr;
+		if (getsym() == LC)
+		{	if (nptr0->sc != EMPTY) error(DCERR);
+			nptr0->sc = TAG;
+			nptr0->ty = list2(s,-1);
+			while (getsym() != RC) decl();
+			getsym();
+			rplacad(type = nptr0->ty,disp);
+		}
+		else
+		{	if(nptr0->sc == EMPTY) nptr0=gnptr;
+			if(nptr0->sc == EMPTY) error(UDERR);
+			if(nptr0->sc != TAG) error(TYERR);
+			type = nptr0->ty;
+		}
+	}
+	else if(sym==LC)
+	{	while(getsym() != RC) decl();
+		getsym();
+		type = list2(s,disp);
+	}
+	else error(DCERR);
+	disp=sdisp;
+	mode=smode;
+	return type;
+}
+fdecl(n)
+NMTBL *n;
+{	args=0;
+	fcheck(n);
+	mode=ADECL;
+	lfree= HEAPSIZE;
+	while (sym!=LC) {decl(); getsym();}
+	disp=0;
+	mode=STAT;
+	while (typeid(getsym()) || sym==STATIC || sym==TYPEDEF)
+	{	mode=LDECL;
+		decl();
+		mode=STAT;
+	}
+	control=1;
+	printf("%s\n\tPSHS\tU\n\tLEAU\t,S\n",n->nm);
+	if(disp) printf("\tLEAS\t%d,S\n",disp);
+	lvar= -disp;
+	while(sym!=RC) statement();
+	if (control) return2();
+}
+fcheck(n)
+NMTBL *n;
+{	if(mode!=GDECL||car(type)!=FUNCTION) error(DCERR);
+	if(n->sc==FUNCTION) compatible(n->ty,cadr(type));
+	else if(n->sc!=EMPTY) error(DCERR);
+	n->sc=FUNCTION;
+	n->ty=cadr(type);
+}
+compatible(t1,t2)
+int t1,t2;
+{	if(integral(t1))
+	{	if(t1!=t2) error(TYERR);
+	}
+	else if(car(t1)!=car(t2)) error(TYERR);
+	else if((car(t1)==STRUCT || car(t1)==UNION) && cadr(t1)!=cadr(t2))
+		error(TYERR);
+	else if(car(t1)==POINTER || car(t1)==ARRAY ||car(t1)==FUNCTION)
+		compatible(cadr(t1),cadr(t2));
+}
+scalar(t)
+int t;
+{	return(integral(t)||car(t)==POINTER);
+}
+integral(t)
+int t;
+{	return(t==INT||t==CHAR||t==UNSIGNED);
+}
+
+statement()
+{int slfree;
+	switch(sym)
+	{case IF:
+		doif();
+		return;
+	case WHILE:
+		dowhile();
+		return;
+	case DO:
+		dodo();
+		return;
+	case FOR:
+		dofor();
+		return;
+	case SWITCH:
+		doswitch();
+		return;
+	case LC:
+		docomp();
+		return;
+	case BREAK:
+		jmp(blabel);
+		getsym();
+		checksym(SM);
+		return;
+	case CONTINUE:
+		jmp(clabel);
+		getsym();
+		checksym(SM);
+		return;
+	case CASE:
+		docase();
+		statement();
+		return;
+	case DEFAULT:
+		dodefault();
+		statement();
+		return;
+	case RETURN:
+		doreturn();
+		return;
+	case GOTO:
+		dogoto();
+		return;
+	case SM:
+		getsym();
+		return;
+	default:if(sym==IDENT&&skipspc()==':')
+		{	dolabel();
+			statement();
+		}
+		else
+		{	slfree=lfree;
+			gexpr(expr());
+			lfree=slfree;
+			checksym(SM);
+		}
+	}
+}
+doif()
+{int l1,l2,slfree;
+	getsym();
+	checksym(LPAR);
+	slfree=lfree;
+	bexpr(expr(),0,l1=fwdlabel());
+	lfree=slfree;
+	checksym(RPAR);
+	statement();
+	if(sym==ELSE)
+	{	if (l2 = control) jmp(l2=fwdlabel());
+		fwddef(l1);
+		getsym();
+		statement();
+		if (l2) fwddef(l2);
+	}
+	else fwddef(l1);
+}
+dowhile()
+{int sbreak,scontinue,slfree,e;
+	sbreak=blabel;
+	scontinue=clabel;
+	blabel=fwdlabel();
+	clabel=backdef();
+	getsym();
+	checksym(LPAR);
+	slfree=lfree;
+	e=expr();
+	checksym(RPAR);
+	if(sym==SM)
+	{	bexpr(e,1,clabel);
+		lfree=slfree;
+		getsym();
+	}
+	else
+	{	bexpr(e,0,blabel);
+		lfree=slfree;
+		statement();
+		jmp(clabel);
+	}
+	fwddef(blabel);
+	clabel=scontinue;
+	blabel=sbreak;
+}
+dodo()
+{int sbreak,scontinue,l,slfree;
+	sbreak=blabel;
+	scontinue=clabel;
+	blabel=fwdlabel();
+	clabel=fwdlabel();
+	l=backdef();
+	getsym();
+	statement();
+	fwddef(clabel);
+	checksym(WHILE);
+	checksym(LPAR);
+	slfree=lfree;
+	bexpr(expr(),1,l);
+	lfree=slfree;
+	checksym(RPAR);
+	checksym(SM);
+	fwddef(blabel);
+	clabel=scontinue;
+	blabel=sbreak;
+}
+dofor()
+{int sbreak,scontinue,l,e,slfree;
+	sbreak=blabel;
+	scontinue=clabel;
+	blabel=fwdlabel();
+	getsym();
+	checksym(LPAR);
+	slfree=lfree;
+	if(sym!=SM)
+	{	gexpr(expr());
+		checksym(SM);
+	}
+	else getsym();
+	lfree=slfree;
+	l=backdef();
+	if(sym!=SM)
+	{	bexpr(expr(),0,blabel);
+		checksym(SM);
+	}
+	else getsym();
+	lfree=slfree;
+	if(sym==RPAR)
+	{	clabel=l;
+		getsym();
+		statement();
+	}
+	else
+	{	clabel=fwdlabel();
+		e=expr();
+		checksym(RPAR);
+		statement();
+		fwddef(clabel);
+		gexpr(e);
+		lfree=slfree;
+	}
+	jmp(l);
+	fwddef(blabel);
+	clabel=scontinue;
+	blabel=sbreak;
+}
+doswitch()
+{int sbreak,scase,sdefault,slfree;
+	sbreak=blabel;
+	blabel=fwdlabel();
+	sdefault=dlabel;
+	dlabel=0;
+	scase=cslabel;
+	getsym();
+	checksym(LPAR);
+	slfree=lfree;
+	gexpr(expr());
+	lfree=slfree;
+	checksym(RPAR);
+	cslabel = control = 0;
+	statement();
+	if(dlabel) printf("_%d\tEQU\t_%d\n",cslabel,dlabel);
+	else fwddef(cslabel);
+	cslabel=scase;
+	dlabel=sdefault;
+	fwddef(blabel);
+	blabel=sbreak;
+}
+docomp()
+{	getsym();
+	while(sym!=RC) statement();
+	getsym();
+}
+docase()
+{int c,n,l,slfree;
+	c=0;
+	n=2;
+	slfree=lfree;
+	while(sym==CASE)
+	{	getsym();
+		c=list2(cexpr(expr()),c);
+		n+=6;
+		checksym(COLON);
+	}
+	l=fwdlabel();
+	if (control)
+	{	control=0;
+		if (n>127) jmp(l);
+		else printf("\tBRA\t_%d\n",l);
+	}
+	if (cslabel) fwddef(cslabel);
+	while(cadr(c))
+	{	cmpdimm(car(c));
+		if((n-=6)>127) jcond(l,0);
+		else printf("\tBEQ\t_%d\n",l);
+		c=cadr(c);
+	}
+	lfree=slfree;
+	cmpdimm(car(c));
+	jcond(cslabel=fwdlabel(),1);
+	fwddef(l);
+}
+dodefault()
+{	getsym();
+	checksym(COLON);
+	if (dlabel) error(STERR);
+	if (!cslabel) jmp(cslabel = fwdlabel());
+	dlabel = backdef();
+}
+doreturn()
+{int slfree;
+	if(getsym()==SM)
+	{	getsym();
+		return2();
+		return;
+	}
+	slfree=lfree;
+	gexpr(expr());
+	lfree=slfree;
+	checksym(SM);
+	control=0;
+	switch(lvar)
+	{case 0:
+		ret("");
+		return;
+	case 2:
+		ret("X,");
+		return;
+	default:unlink();
+		return;
+	}
+}
+return2()
+{	control=0;
+	switch(lvar)
+	{case 0:
+		ret("");
+		return;
+	case 1:
+		ret("A,");
+		return;
+	case 2:
+		ret("D,");
+		return;
+	case 3:
+		ret("A,X,");
+		return;
+	case 4:
+		ret("D,X,");
+		return;
+	default:unlink();
+		return;
+	}
+}
+ret(reg)
+char *reg;
+{	printf("\tPULS\t%sU,PC\n",reg);
+}
+unlink()
+{	printf("\tLEAS\t,U\n");
+	ret("");
+}
+dogoto()
+{NMTBL *nptr0;
+	getsym();
+	nptr0=nptr;
+	checksym(IDENT);
+	if(nptr0->sc == BLABEL || nptr0->sc == FLABEL) jmp(nptr0->dsp);
+	else if(nptr0->sc == EMPTY)
+	{	nptr0->sc = FLABEL;
+		jmp(nptr0->dsp = fwdlabel());
+	}
+	else error(STERR);
+	checksym(SM);
+}
+dolabel()
+{	if(nptr->sc == FLABEL) fwddef(nptr->dsp);
+	else if(nptr->sc != EMPTY) error(TYERR);
+	nptr->sc = BLABEL;
+	nptr->dsp = backdef();
+	getsym();
+	checksym(COLON);
+}
+
+expr()
+{	return(rvalue(expr0()));
+}
+expr0()
+{int e;
+	e=expr1();
+	while(sym==COMMA) {getsym();e=list3(COMMA,e,rvalue(expr1()));}
+	return e;
+}
+expr1()
+{int e1,e2,t,op;
+	e1=expr2();
+	switch (sym)
+	{case ASS:
+		lcheck(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr1());
+		if(t==CHAR) {type= INT;return(list3(CASS,e1,e2));}
+		type=t;
+		return(list3(ASS,e1,e2));
+	case ADD+AS: case SUB+AS: case MUL+AS: case DIV+AS: case MOD+AS:
+	case RSHIFT+AS: case LSHIFT+AS: case BAND+AS: case EOR+AS: case BOR+AS:
+		op = sym-AS;
+		lcheck(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr1());
+		if(!integral(type)) error(TYERR);
+		if((t==UNSIGNED||type==UNSIGNED)&&
+			(op==MUL||op==DIV||op==MOD||op==RSHIFT||op==LSHIFT))
+			op=op+US;
+		if(t==CHAR)
+		{	type= INT;
+			return(list4(CASSOP,e1,e2,op));
+		}
+		type=t;
+		if(integral(t)) return(list4(ASSOP,e1,e2,op));
+		if((op!=ADD&&op!=SUB)||car(t)!=POINTER) error(TYERR);
+		e2=binop(MUL,e2,list2(CONST,size(cadr(t))),INT,UNSIGNED);
+		type=t;
+		return list4(ASSOP,e1,e2,op);
+	default:
+		return(e1);
+	}
+}
+expr2()
+{int e1,e2,e3,t;
+	e1=expr3();
+	if(sym==COND)
+	{	e1=rvalue(e1);
+		getsym();
+		e2=rvalue(expr2());
+		t=type;
+		checksym(COLON);
+		e3=rvalue(expr2());
+		if(car(e1)==CONST)
+			if(cadr(e1)) {type=t;return e2;}
+			else return e3;
+		if(type==INT||t!=INT&&type==UNSIGNED) type=t;
+		return(list4(COND,e1,e2,e3));
+	}
+	return(e1);
+}
+expr3()
+{int e;
+	e=expr4();
+	while(sym==LOR)
+	{	e=rvalue(e);
+		getsym();
+		e=list3(LOR,e,rvalue(expr4()));
+		type= INT;
+	}
+	return(e);
+}
+expr4()
+{int e;
+	e=expr5();
+	while(sym==LAND)
+	{	e=rvalue(e);
+		getsym();
+		e=list3(LAND,e,rvalue(expr5()));
+		type= INT;
+	}
+	return(e);
+}
+expr5()
+{int e1,e2,t;
+	e1=expr6();
+	while(sym==BOR)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr6());
+		e1=binop(BOR,e1,e2,t,type);
+	}
+	return(e1);
+}
+expr6()
+{int e1,e2,t;
+	e1=expr7();
+	while(sym==EOR)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr7());
+		e1=binop(EOR,e1,e2,t,type);
+	}
+	return(e1);
+}
+expr7()
+{int e1,e2,t;
+	e1=expr8();
+	while(sym==BAND)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr8());
+		e1=binop(BAND,e1,e2,t,type);
+	}
+	return(e1);
+}
+expr8()
+{int e,op;
+	e=expr9();
+	while((op=sym)==EQ||op==NEQ)
+	{	e=rvalue(e);
+		getsym();
+		e=list3(op,e,rvalue(expr9()));
+		type= INT;
+	}
+	return e;
+}
+expr9()
+{int e1,e2,t,op;
+	e1=expr10();
+	while((op=sym)==GT||op==GE||op==LT||op==LE)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr10());
+		if(t==INT&&type==INT) e1=list3(op,e1,e2);
+		else e1=list3(op+US,e1,e2);
+		type= INT;
+	}
+	return e1;
+}
+expr10()
+{int e1,e2,t,op;
+	e1=expr11();
+	while((op=sym)==RSHIFT||op==LSHIFT)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr11());
+		e1=binop(op,e1,e2,t,type);
+	}
+	return e1;
+}
+expr11()
+{int e1,e2,t,op;
+	e1=expr12();
+	while((op=sym)==ADD||op==SUB)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr12());
+		e1=binop(op,e1,e2,t,type);
+	}
+	return e1;
+}
+expr12()
+{int e1,e2,t,op;
+	e1=expr13();
+	while((op=sym)==MUL||op==DIV||op==MOD)
+	{	e1=rvalue(e1);
+		t=type;
+		getsym();
+		e2=rvalue(expr13());
+		e1=binop(op,e1,e2,t,type);
+	}
+	return e1;
+}
+expr13()
+{int e,op;
+	switch (op = sym)
+	{case INC: case DEC:
+		getsym();
+		lcheck(e=expr13());
+		if(type==CHAR)
+		{	type= INT;
+			return(list2(op==INC?CPREINC:CPREDEC,e));
+		}
+		if(integral(type))
+			return(list3(PREINC,e,op==INC?1:-1));
+		if(car(type)!=POINTER) error(TYERR);
+		return(list3(PREINC,e,
+			op==INC?size(cadr(type)):-size(cadr(type)) ));
+	case MUL:
+		getsym();
+		e=rvalue(expr13());
+		return(indop(e));
+	case BAND:
+		getsym();
+		switch(car(e=expr13()))
+		{case INDIRECT:
+			e=cadr(e);
+			break;
+		case GVAR:
+		case LVAR:
+			e=list2(ADDRESS,e);
+			break;
+		case FNAME:
+			return e;
+		default:error(LVERR);
+		}
+		type=list2(POINTER,type);
+		return e;
+	case SUB:
+		getsym();
+		e=rvalue(expr13());
+		if(!integral(type)) error(TYERR);
+		return(car(e)==CONST?list2(CONST,-cadr(e)):list2(MINUS,e));
+	case BNOT:
+		getsym();
+		e=rvalue(expr13());
+		if(!integral(type)) error(TYERR);
+		return(car(e)==CONST?list2(CONST,~cadr(e)):list2(BNOT,e));
+	case LNOT:
+		getsym();
+		return(list2(LNOT,rvalue(expr13())));
+	case SIZEOF:
+		if(getsym()==LPAR)
+			if(typeid(getsym()))
+			{	e=list2(CONST,size(typename()));
+				type=INT;
+				checksym(RPAR);
+				return e;
+			}
+			else
+			{	e=expr0();
+				checksym(RPAR);
+				expr16(e);
+				if(sym==INC||sym==DEC)
+				{	getsym();
+					if(type==CHAR) type=INT;
+					else if(!scalar(type))
+						error(TYERR);
+				}
+			}
+		else expr13();
+		e=list2(CONST,size(type));
+		type=INT;
+		return e;
+	}
+	e=expr14();
+	if((op=sym)==INC||op==DEC)
+	{	lcheck(e);
+		getsym();
+		if(type==CHAR)
+		{	type= INT;
+			return(list2(op==INC?CPOSTINC:CPOSTDEC,e));
+		}
+		if(integral(type))
+			return(list3(POSTINC,e,op==INC?1:-1));
+		if(car(type)!=POINTER) error(TYERR);
+		return (list3(POSTINC,e,
+			op == INC ? size(cadr(type)): -size(cadr(type)) ));
+	}
+	return e;
+}
+expr14()
+{int e1,t;
+	switch(sym)
+	{case IDENT:
+		switch(nptr->sc)
+		{case GVAR:
+			e1=list2(GVAR,nptr->dsp);
+			type=nptr->ty;
+			getsym();
+			break;
+		case LVAR:
+			e1=list2(LVAR,nptr->dsp);
+			type=nptr->ty;
+			getsym();
+			break;
+		case FUNCTION:
+			e1=list2(FNAME,(int)nptr);
+			type=list2(FUNCTION,nptr->ty);
+			getsym();
+			break;
+		case EMPTY:
+			if(getsym()==LPAR)
+			{	nptr->sc = FUNCTION;
+				nptr->ty= INT;
+				type= list2(FUNCTION,INT);
+				e1=expr15(list2(FNAME,(int)nptr));
+				break;
+			}
+		default:error(UDERR);
+		}
+		break;
+	case STRING:
+		e1=list3(STRING,(int)sptr,symval);
+		type=list3(ARRAY,CHAR,symval);
+		getsym();
+		break;
+	case CONST:
+		type= INT;
+		e1=list2(CONST,symval);
+		getsym();
+		break;
+	case LPAR:
+		if(typeid(getsym()))
+		{	t=typename();
+			checksym(RPAR);
+			e1=expr13();
+			type=t;
+			return e1;
+		}
+		e1=expr0();
+		checksym(RPAR);
+		break;
+	default:error(EXERR);
+	}
+	return expr16(e1);
+}
+expr16(e1)
+int e1;
+{int e2,t;
+	while(1)
+		if(sym==LBRA)
+		{	e1=rvalue(e1);
+			t=type;
+			getsym();
+			e2=rvalue(expr0());
+			checksym(RBRA);
+			e1=binop(ADD,e1,e2,t,type);
+			e1=indop(e1);
+		}
+		else if(sym==LPAR) e1=expr15(e1);
+		else if(sym==PERIOD) e1=strop(e1);
+		else if(sym==ARROW) e1=strop(indop(rvalue(e1)));
+		else break;
+	if(car(e1)==FNAME) type=list2(POINTER,type);
+	return e1;
+}
+rvalue(e)
+int e;
+{	if(type==CHAR)
+	{	type= INT;
+		switch(car(e))
+		{case GVAR:
+			return(list2(CRGVAR,cadr(e)));
+		case LVAR:
+			return(list2(CRLVAR,cadr(e)));
+		case INDIRECT:
+			return(list2(CRINDIRECT,cadr(e)));
+		default:return(e);
+		}
+	}
+	if(!integral(type))
+		if(car(type)==ARRAY)
+		{	type=list2(POINTER,cadr(type));
+			if(car(e)==INDIRECT) return cadr(e);
+			return list2(ADDRESS,e);
+		}
+		else if(car(type)!=POINTER) error(TYERR);
+	switch(car(e))
+	{case GVAR:
+		return(list2(RGVAR,cadr(e)));
+	case LVAR:
+		return(list2(RLVAR,cadr(e)));
+	case INDIRECT:
+		return(list2(RINDIRECT,cadr(e)));
+	default:return(e);
+	}
+}
+lcheck(e)
+int e;
+{	if(!scalar(type)||car(e)!=GVAR&&car(e)!=LVAR&&car(e)!=INDIRECT)
+		error(LVERR);
+}
+indop(e)
+int e;
+{	if(type!=INT&&type!=UNSIGNED)
+		if(car(type)==POINTER) type=cadr(type);
+		else error(TYERR);
+	else type= CHAR;
+	if(car(e)==ADDRESS) return(cadr(e));
+	return(list2(INDIRECT,e));
+}
+strop(e)
+{	getsym();
+	if (sym!=IDENT||nptr->sc!=FIELD) error(TYERR);
+	if (integral(type)||car(type)!=STRUCT && car(type)!=UNION)
+		e=rvalue(e);
+	type = nptr->ty;
+	switch(car(e))
+	{case GVAR:
+	case LVAR:
+		e=list2(car(e),cadr(e) + nptr->dsp);
+		break;
+	case INDIRECT:
+		if(!nptr->dsp) break;
+		e=list2(INDIRECT,list3(ADD,cadr(e),list2(CONST,nptr->dsp)));
+		break;
+	default:
+		e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp)));
+	}
+	getsym();
+	return e;
+}
+binop(op,e1,e2,t1,t2)
+int op,e1,e2,t1,t2;
+{int e;
+	if(car(e1)==CONST&&car(e2)==CONST)
+	{	e1=cadr(e1);
+		e2=cadr(e2);
+		type= INT;
+		switch(op)
+		{case BOR:
+			e=e1|e2;break;
+		case EOR:
+			e=e1^e2;break;
+		case BAND:
+			e=e1&e2;break;
+		case ADD:
+			if(integral(t1))
+			{	if(integral(t2))
+					e=e1+e2;
+				else
+				{	if(car(t2)!=POINTER) error(TYERR);
+					e=size(cadr(t2))*e1+e2;
+					type=t2;
+				}
+			}
+			else
+			{	if(car(t1)!=POINTER) error(TYERR);
+				e=e1+size(cadr(t1))*e2;
+				type=t1;
+			}
+			break;
+		case SUB:
+			if(integral(t1))
+				e=e1-e2;
+			else
+			{	if(car(t1)!=POINTER) error(TYERR);
+				e=e1-size(cadr(t1))*e2;
+				type=t1;
+			}
+			break;
+		case MUL:
+			e=e1*e2;break;
+		case DIV:
+			if(!e2) error(EXERR);e=e1/e2;break;
+		case MOD:
+			if(!e2) error(EXERR);e=e1%e2;break;
+		case RSHIFT:
+			e=e1>>e2;break;
+		case LSHIFT:
+			e=e1<<e2;
+		}
+		return list2(CONST,e);
+	}
+	if((op==ADD||op==MUL||op==BOR||op==EOR||op==BAND)&&
+		(car(e1)==CONST||car(e2)!=CONST&&
+		(car(e1)==RGVAR||car(e1)==RLVAR)))
+		{e=e1;e1=e2;e2=e;e=t1;t1=t2;t2=e;}
+	if(op==ADD)
+	{	if(integral(t1))
+		{	if(integral(t2))
+			{	if(t1==INT) type=t2;else type=t1;
+				return(list3(ADD,e1,e2));
+			}
+			if(car(t2)!=POINTER) error(TYERR);
+			e=binop(MUL,e1,list2(CONST,size(cadr(t2))),t1,INT);
+			type=t2;
+			return(list3(ADD,e,e2));
+		}
+		if(car(t1)!=POINTER||!integral(t2)) error(TYERR);
+		e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT);
+		type=t1;
+		if(car(e1)==ADDRESS&&car(e)==CONST)
+			return(list2(ADDRESS,list2(car(cadr(e1)),
+				cadr(cadr(e1))+cadr(e))));
+		return(list3(ADD,e1,e));
+	}
+	if(op==SUB)
+	{	if(integral(t1))
+		{	if(!integral(t2)) error(TYERR);
+			if(t1==INT) type=t2;else type=t1;
+			return(list3(SUB,e1,e2));
+		}
+		if(car(t1)!=POINTER) error(TYERR);
+		if(integral(t2))
+		{	e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT);
+			type=t1;
+			return(list3(SUB,e1,e));
+		}
+		if(car(t2)!=POINTER)
+			error(TYERR);
+		compatible(t1,t2);
+		e=list3(SUB,e1,e2);
+		e=binop(DIV,e,list2(CONST,size(cadr(t1))),UNSIGNED,INT);
+		type= INT;
+		return e;
+	}
+	if(!integral(t1)||!integral(t2)) error(TYERR);
+	if(t1==INT) type=t2;else type=t1;
+	if((op==MUL||op==DIV)&&car(e2)==CONST&&cadr(e2)==1) return e1;
+	if(op==BOR||op==EOR||op==BAND) return(list3(op,e1,e2));
+	return(list3(type==UNSIGNED?op+US:op,e1,e2));
+}
+expr15(e1)
+int e1;
+{int t,args;
+	t=type;
+	if(integral(t)||car(t)!=FUNCTION)
+		error(TYERR);
+	t=cadr(t);
+	getsym();
+	args=0;
+	while(sym!=RPAR)
+	{	args=list2(rvalue(expr1()),args);
+		if(sym!=COMMA) break;
+		getsym();
+	}
+	checksym(RPAR);
+	if(t==CHAR) type= INT;else type=t;
+	return list3(FUNCTION,e1,args);
+}
+typeid(s)
+int s;
+{	return (integral(s) || s==SHORT || s==LONG || s==STRUCT || s==UNION ||
+		(s==IDENT && nptr->sc==TYPE));
+}
+typename()
+{int t;
+	type=t=typespec();
+	ndecl0();
+	reverse(t);
+	return type;
+}
+ndecl0()
+{	if(sym==MUL)
+	{	getsym();
+		return type=list2(POINTER,ndecl0());
+	}
+	return ndecl1();
+}
+ndecl1()
+{int i,t;
+	if(sym==LPAR)
+		if(getsym()==RPAR) {type=list2(FUNCTION,type); getsym();}
+		else
+		{	ndecl0();
+			checksym(RPAR);
+		}
+	while(1)
+		if(sym==LBRA)
+		{	getsym();
+			t=type;
+			i=cexpr(expr());
+			checksym(RBRA);
+			type=list3(ARRAY,t,i);
+		}
+		else if(sym==LPAR)
+		{	getsym();
+			checksym(RPAR);
+			type=list2(FUNCTION,type);
+		}
+		else return type;
+}
+
+bexpr(e1,cond,l1)
+int e1,l1;
+char cond;
+{int e2,l2;
+	if (chk) return;
+	e2=cadr(e1);
+	switch(car(e1))
+	{case LNOT:
+		bexpr(e2,!cond,l1);
+		return;
+	case GT:
+		rexpr(e1,l1,cond?"GT":"LE");
+		return;
+	case UGT:
+		rexpr(e1,l1,cond?"HI":"LS");
+		return;
+	case GE:
+		rexpr(e1,l1,cond?"GE":"LT");
+		return;
+	case UGE:
+		rexpr(e1,l1,cond?"HS":"LO");
+		return;
+	case LT:
+		rexpr(e1,l1,cond?"LT":"GE");
+		return;
+	case ULT:
+		rexpr(e1,l1,cond?"LO":"HS");
+		return;
+	case LE:
+		rexpr(e1,l1,cond?"LE":"GT");
+		return;
+	case ULE:
+		rexpr(e1,l1,cond?"LS":"HI");
+		return;
+	case EQ:
+		rexpr(e1,l1,cond?"EQ":"NE");
+		return;
+	case NEQ:
+		rexpr(e1,l1,cond?"NE":"EQ");
+		return;
+	case LAND:
+		bexpr(e2,0,cond?(l2=fwdlabel()):l1);
+		bexpr(caddr(e1),cond,l1);
+		if(cond) fwddef(l2);
+		return;
+	case LOR:
+		bexpr(e2,1,cond?l1:(l2=fwdlabel()));
+		bexpr(caddr(e1),cond,l1);
+		if(!cond) fwddef(l2);
+		return;
+	case CRGVAR:
+		ldby(e2);
+		jcond(l1,cond);
+		return;
+	case CRLVAR:
+		ldbu(e2);
+		jcond(l1,cond);
+		return;
+	case CONST:
+		if(cond&&e2||!cond&&!e2) jmp(l1);
+		return;
+	case RGVAR:
+	case RLVAR:
+	case CRINDIRECT:
+		gexpr(e1);
+		jcond(l1,cond);
+		return;
+	default:gexpr(e1);
+		subdim(0);
+		jcond(l1,cond);
+		return;
+	}
+}
+rexpr(e1,l1,s)
+int e1,l1;
+char *s;
+{	gexpr(list3(SUB,cadr(e1),caddr(e1)));
+	printf("\tLB%s\t_%d\n",s,l1);
+}
+jcond(l,cond)
+int l;
+char cond;
+{	printf("\tLB%s\t_%d\n",cond?"NE":"EQ",l);
+}
+jmp(l)
+int l;
+{	control=0;
+	printf("\tLBRA\t_%d\n",l);
+}
+fwdlabel()
+{	return labelno++;
+}
+fwddef(l)
+int l;
+{	control=1;
+	printf("_%d\n",l);
+}
+backdef()
+{	control=1;
+	printf("_%d\n",labelno);
+	return labelno++;
+}
+
+gexpr(e1)
+int e1;
+{int e2,e3;
+	if (chk) return;
+	e2 = cadr(e1);
+	switch (car(e1))
+	{case GVAR:
+		leaxy(e2);
+		return;
+	case RGVAR:
+		lddy(e2);
+		return;
+	case CRGVAR:
+		ldby(e2);
+		sex();
+		return;
+	case LVAR:
+		leaxu(e2);
+		return;
+	case RLVAR:
+		lddu(e2);
+		return;
+	case CRLVAR:
+		ldbu(e2);
+		sex();
+		return;
+	case FNAME:
+		leaxpcr((NMTBL *)e2);
+		tfrxd();
+		return;
+	case CONST:
+		if (e2) lddim(e2);
+		else clrd();
+		return;
+	case STRING:
+		string(e1);
+		return;
+	case FUNCTION:
+		function(e1);
+		return;
+	case INDIRECT:
+		indirect(e1);
+		return;
+	case RINDIRECT: case CRINDIRECT:
+		rindirect(e1);
+		return;
+	case ADDRESS:
+		gexpr(e2);
+		tfrxd();
+		return;
+	case MINUS:
+		gexpr(e2);
+		printf("\tNEGA\n\tNEGB\n\tSBCA\t#0\n");
+		return;
+	case BNOT:
+		gexpr(e2);
+		printf("\tCOMA\n\tCOMB\n");
+		return;
+	case PREINC:
+		switch (car(e2))
+		{case GVAR: case LVAR:
+			ldd(e2);
+			adddim(caddr(e1));
+			std(e2);
+			return;
+		default:
+			gexpr(e2);
+			lddx();
+			adddim(caddr(e1));
+			stdx();
+			return;
+		}
+	case POSTINC:
+		switch (car(e2))
+		{case GVAR: case LVAR:
+			ldd(e2);
+			adddim(e3 = caddr(e1));
+			std(e2);
+			subdim(e3);
+			return;
+		default:
+			gexpr(e2);
+			lddx();
+			adddim(e3=caddr(e1));
+			stdx();
+			subdim(e3);
+			return;
+		}
+	case CPOSTINC:
+		gexpr(e2);
+		ldbx();
+		incx();
+		sex();
+		return;
+	case CPREINC:
+		gexpr(e2);
+		incx();
+		ldbx();
+		sex();
+		return;
+	case CPOSTDEC:
+		gexpr(e2);
+		ldbx();
+		decx();
+		sex();
+		return;
+	case CPREDEC:
+		gexpr(e2);
+		decx();
+		ldbx();
+		sex();
+		return;
+	case MUL: case UMUL:
+		if (car(e3=caddr(e1)) == CONST)
+		{	if (0 < (e3 = cadr(e3)) && e3 <= 10)
+			{	gexpr(e2);
+				switch (e3)
+				{case 8:
+					asld();
+				case 4:
+					asld();
+				case 2:
+					asld();
+				case 1:
+					return;
+				case 10:
+					asld();
+				case 5:
+					pushd();
+					asld();
+					asld();
+					addds();
+					return;
+				case 6:
+					asld();
+				case 3:
+					pushd();
+					asld();
+					addds();
+					return;
+				case 9: case 7:
+					pushd();
+					asld();
+					asld();
+					asld();
+					if (e3 == 9) addds(); else subds();
+					return;
+				}
+			}
+		}
+	case DIV:    case UDIV:	   case MOD:	case UMOD:
+	case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT:
+		binexpr(e1);
+		return;
+	case ADD: case SUB: case BAND: case EOR: case BOR:
+		machinop(e1);
+		return;
+	case COND:
+		e2=fwdlabel();
+		bexpr(cadr(e1),0,e2);
+		gexpr(caddr(e1));
+		jmp(e3=fwdlabel());
+		fwddef(e2);
+		gexpr(cadddr(e1));
+		fwddef(e3);
+		return;
+	case ASS: case CASS:
+		assign(e1);
+		return;
+	case ASSOP: case CASSOP:
+		assop(e1);
+		return;
+	case COMMA:
+		gexpr(e2);
+		gexpr(caddr(e1));
+		return;
+	default:
+		bexpr(e1,1,e2=fwdlabel());
+		clrd();
+		printf("\tBRA\t*+5\n");
+		fwddef(e2);
+		lddim(1);
+	}
+}
+string(e1)
+int e1;
+{char *s;
+int i,l,lb;
+	s=(char *)cadr(e1);
+	lb=fwdlabel();
+	if ((l = caddr(e1)) < 128)
+		printf("\tLEAX\t2,PC\n\tBRA\t_%d\n",lb);
+	else
+		printf("\tLEAX\t3,PC\n\tLBRA\t_%d\n",lb);
+	do
+	{	printf("\tFCB\t%d",*s++);
+		for (i=8; --l && --i;) printf(",%d",*s++);
+		printf("\n");
+	}
+	while (l);
+	fwddef(lb);
+}
+function(e1)
+int e1;
+{int e2,e3,e4,e5,nargs;
+NMTBL *n;
+	e2 = cadr(e1);
+	nargs = 0;
+	for (e3 = caddr(e1); e3; e3 = cadr(e3))
+	{	n=(NMTBL *)(e5=(cadr(e4 = car(e3))));
+		switch(car(e4))
+		{case FNAME:
+			leaxpcr(n);
+			pushx();
+			break;
+		case ADDRESS:
+			gexpr(e5);
+			pushx();
+			break;
+		default:gexpr(e4);
+			pushd();
+		}
+		++nargs;
+	}
+	if (car(e2) == FNAME)
+	{	n=(NMTBL *)cadr(e2);
+		printf("\tLBSR\t%s\n",n->nm);
+	}
+	else
+	{	gexpr(e2);
+		printf("\tJSR\t,X\n");
+	}
+	if (nargs) printf("\tLEAS\t%d,S\n",2*nargs);
+}
+indirect(e1)
+int e1;
+{int e2,e3,e4;
+	e3 = cadr(e2 = cadr(e1));
+	switch(car(e2))
+	{case RGVAR: case RLVAR:
+		ldx(e2);
+		return;
+	case ADD:
+		if(car(e3)==ADDRESS)
+		{	gexpr(caddr(e2));
+			gexpr(cadr(e3));
+			opdx("LEAX");
+			return;
+		}
+		switch(car(e4 = caddr(e2)))
+		{case RGVAR: case RLVAR:
+			gexpr(e3);
+			ldx(e4);
+			opdx("LEAX");
+			return;
+		}
+	default:
+		gexpr(e2);
+		tfrdx();
+	}
+}
+
+machinop(e1)
+int e1;
+{int e2,e3;
+	e2 = cadr(e1);
+	switch (car(e3 = caddr(e1)))
+	{case RGVAR: case RLVAR: case CONST:
+		gexpr(e2);
+		oprt(car(e1),e3);
+		return;
+	default:
+		gexpr(e3);
+		pushd();
+		gexpr(e2);
+		tosop(car(e1));
+		return;
+	}
+}
+
+rindirect(e1)
+int e1;
+{char *op;
+int e2,e3,e4,byte,l;
+	op = ((byte = (car(e1) == CRINDIRECT)) ? "LDB" : "LDD");
+	e3 = cadr(e2 = cadr(e1));
+	switch (car(e2))
+	{case RGVAR: case RLVAR:
+		indir(op,e2);
+		sextend(byte);
+		return;
+	case ADD:
+		if(car(e3)==ADDRESS)
+		{	gexpr(caddr(e2));
+			gexpr(cadr(e3));
+			opdx(op);
+			sextend(byte);
+			return;
+		}
+		switch(car(e4=caddr(e2)))
+		{case RGVAR: case RLVAR:
+			gexpr(e3);
+			ldx(e4);
+			opdx(op);
+			sextend(byte);
+			return;
+		case CONST:
+			switch (car(e3))
+			{case RGVAR: case RLVAR:
+				ldx(e3);
+				indexx(op,cadr(e4));
+				sextend(byte);
+				return;
+			}
+		default:
+			gexpr(e3);
+			pushd();
+			gexpr(e4);
+			pulx();
+			opdx(op);
+			sextend(byte);
+			return;
+		}
+	case PREINC:
+		if ((l = caddr(e2)) == -1 || l == -2)
+			switch (car(e3))
+			{case GVAR: case LVAR:
+				ldx(e3);
+				predecx(op,l);
+				stx(e3);
+				sextend(byte);
+				return;
+			}
+		break;
+	case POSTINC:
+		if ((l = caddr(e2)) == 1 || l == 2)
+			switch (car(e3))
+			{case GVAR: case LVAR:
+				ldx(e3);
+				postincx(op,l);
+				stx(e3);
+				sextend(byte);
+				return;
+			}
+		break;
+	}
+	gexpr(e2);
+	tfrdx();
+	indexx(op,0);
+	sextend(byte);
+}
+assign(e1)
+int e1;
+{char *op;
+int e2,e3,e4,e5,l;
+	op = (car(e1) == CASS ? "STB" : "STD");
+	e3 = cadr(e2 = cadr(e1));
+	e4 = caddr(e1);
+	switch(car(e2))
+	{case GVAR: case LVAR:
+		gexpr(e4);
+		index(op,e2);
+		return;
+	case INDIRECT:
+		switch(car(e3))
+		{case RGVAR: case RLVAR:
+			gexpr(e4);
+			indir(op,e3);
+			return;
+		case ADD:
+			if (car(caddr(e3)) == CONST)
+				switch (car(e5=cadr(e3)))
+				{case RGVAR: case RLVAR:
+					gexpr(e4);
+					ldx(e5);
+					indexx(op,cadr(caddr(e3)));
+					return;
+				}
+			break;
+		case PREINC:
+			if ((l = caddr(e3)) == -1 || l == -2)
+				switch (car(e5=cadr(e3)))
+				{case GVAR: case LVAR:
+					gexpr(e4);
+					ldx(e5);
+					predecx(op,l);
+					stx(e5);
+					return;
+				}
+			break;
+		case POSTINC:
+			if ((l = caddr(e3)) == 1 || l == 2)
+				switch (car(e5=cadr(e3)))
+				{case GVAR: case LVAR:
+					gexpr(e4);
+					ldx(e5);
+					postincx(op,l);
+					stx(e5);
+					return;
+				}
+			break;
+		}
+	}
+	switch (car(e4))
+	{case RGVAR: case CRGVAR: case RLVAR: case CRLVAR: case CONST:
+		gexpr(e2);
+		gexpr(e4);
+		break;
+	default:
+		gexpr(e4);
+		pushd();
+		gexpr(e2);
+		pulld();
+	}
+	indexx(op,0);
+	return;
+}
+assop(e1)
+int e1;
+{int e2,e3,byte,op;
+char *ldop,*stop;
+	ldop = ((byte = (car(e1) == CASSOP)) ? "LDB" : "LDD");
+	stop = (byte ? "STB" : "STD");
+	e2 = cadr(e1);
+	e3 = caddr(e1);
+	op = cadddr(e1);
+	switch (car(e2))
+	{case GVAR: case LVAR:
+		switch (car(e3))
+		{case RGVAR: case RLVAR: case CONST:
+			if (simpop(op))
+			{	index(ldop,e2);
+				sextend(byte);
+				oprt(op,e3);
+				index(stop,e2);
+				return;
+			}
+		default:
+			gexpr(e3);
+			pushd();
+			index(ldop,e2);
+			sextend(byte);
+			tosop(op);
+			index(stop,e2);
+			return;
+		}
+	default:
+		switch (car(e3))
+		{case RGVAR: case RLVAR: case CONST:
+			if (simpop(op))
+			{	gexpr(e2);
+				indexx(ldop,0);
+				sextend(byte);
+				oprt(op,e3);
+				indexx(stop,0);
+				return;
+			}
+		default:
+			gexpr(e3);
+			pushd();
+			gexpr(e2);
+			indexx(ldop,0);
+			sextend(byte);
+			tosop(op);
+			indexx(stop,0);
+			return;
+		}
+	}
+}
+simpop(op)
+int op;
+{	return (op == ADD || op == SUB ||
+		op == BAND || op == EOR || op == BOR);
+}
+oprt(op,e1)
+int op,e1;
+{int e2;
+	e2 = cadr(e1);
+	switch (car(e1))
+	{case RGVAR:
+		oprt1(op,"Y",e2);
+		return;
+	case RLVAR:
+		oprt1(op,"U",e2);
+		return;
+	case CONST:
+		oprtc(op,e2);
+		return;
+	}
+}
+oprt1(op,index,n)
+int op,n;
+char *index;
+{	switch (op)
+	{case ADD:
+		printf("\tADDD\t%d,%s\n",n,index);
+		return;
+	case SUB:
+		printf("\tSUBD\t%d,%s\n",n,index);
+		return;
+	case BAND: case EOR: case BOR:
+		dualop(op,index,n);
+		return;
+	}
+}
+dualop(op,index,n)
+int op;
+char *index;
+int n;
+{char *ops;
+	ops =  ((op == BAND) ? "AND" :
+		(op == EOR)  ? "EOR" :
+		(op == BOR)  ? "OR"  : (char *)DEBUG);
+	printf("\t%sA\t%d,%s\n\t%sB\t%d+1,%s\n",ops,n,index,ops,n,index);
+}
+
+oprtc(op,n)
+int op,n;
+{	switch (op)
+	{case ADD:
+		adddim(n);
+		return;
+	case SUB:
+		subdim(n);
+		return;
+	case BAND: case EOR: case BOR:
+		dualc(op,n);
+		return;
+	}
+}
+dualc(op,n)
+int op;
+int n;
+{char *ops;
+	ops =  ((op == BAND) ? "AND" :
+		(op == EOR)  ? "EOR" :
+		(op == BOR)  ? "OR"  : (char *)DEBUG);
+	printf("\t%sA\t#%d\n\t%sB\t#%d\n",ops,(n >> 8) & 0xff,ops,n & 0xff);
+}
+tosop(op)
+int op;
+{	switch (op)
+	{case ADD:
+		addds();
+		return;
+	case SUB:
+		subds();
+		return;
+	case BAND: case EOR: case BOR:
+		dualtosop(op);
+		return;
+	default:
+		pulx();
+		library(op);
+	}
+}
+dualtosop(op)
+int op;
+{char *ops;
+	ops =  ((op == BAND) ? "AND" :
+		(op == EOR)  ? "EOR" :
+		(op == BOR)  ? "OR"  : (char *)DEBUG);
+	printf("\t%sA\t,S+\n\t%sB\t,S+\n",ops,ops);
+}
+pushd()
+{	printf("\tPSHS\tD\n");
+}
+pushx()
+{	printf("\tPSHS\tX\n");
+}
+pulld()
+{	printf("\tPULS\tD\n");
+}
+pulx()
+{	printf("\tPULS\tX\n");
+}
+tfrdx()
+{	printf("\tTFR\tD,X\n");
+}
+tfrxd()
+{	printf("\tTFR\tX,D\n");
+}
+/*
+exgdx()
+{	printf("\tEXG\tD,X\n");
+}
+*/
+asld()
+{	printf("\tASLB\n\tROLA\n");
+}
+adddim(n)
+{	printf("\tADDD\t#%d\n",n);
+}
+subdim(n)
+{	printf("\tSUBD\t#%d\n",n);
+}
+cmpdimm(n)
+int n;
+{	printf("\tCMPD\t#%d\n",n);
+}
+addds()
+{	printf("\tADDD\t,S++\n");
+}
+subds()
+{	printf("\tSUBD\t,S++\n");
+}
+clrd()
+{	printf("\tCLRA\n\tCLRB\n");
+}
+lddim(n)
+int n;
+{	printf("\tLDD\t#%d\n",n);
+}
+
+ldd(e)
+int e;
+{	switch (car(e))
+	{case GVAR:
+		lddy(cadr(e));
+		return;
+	case LVAR:
+		lddu(cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+
+lddx()
+{	printf("\tLDD\t,X\n");
+}
+lddy(n)
+int n;
+{	printf("\tLDD\t%d,Y\n",n);
+}
+lddu(n)
+int n;
+{	printf("\tLDD\t%d,U\n",n);
+}
+
+std(e)
+int e;
+{	switch (car(e))
+	{case GVAR:
+		stdy(cadr(e));
+		return;
+	case LVAR:
+		stdu(cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+stdx()
+{	printf("\tSTD\t,X\n");
+}
+stdy(n)
+int n;
+{	printf("\tSTD\t%d,Y\n",n);
+}
+stdu(n)
+int n;
+{	printf("\tSTD\t%d,U\n",n);
+}
+
+ldbx()
+{	printf("\tLDB\t,X\n");
+}
+/*
+stbx()
+{	printf("\tSTB\t,X\n");
+}
+*/
+ldby(n)
+int n;
+{	printf("\tLDB\t%d,Y\n",n);
+}
+ldbu(n)
+int n;
+{	printf("\tLDB\t%d,U\n",n);
+}
+predecx(op,l)
+char *op;
+int l;
+{	printf("\t%s\t,%sX\n",op,(l == -1 ? "-" : "--"));
+}
+postincx(op,l)
+char *op;
+int l;
+{	printf("\t%s\t,X%s\n",op,(l == 1 ? "+" : "++"));
+}
+leaxy(n)
+int n;
+{	printf("\tLEAX\t%d,Y\n",n);
+}
+leaxu(n)
+int n;
+{	printf("\tLEAX\t%d,U\n",n);
+}
+leaxpcr(n)
+NMTBL *n;
+{	printf("\tLEAX\t%s,PCR\n",n->nm);
+}
+
+ldx(e)
+int e;
+{	switch (car(e))
+	{case GVAR: case RGVAR:
+		ldxy(cadr(e));
+		return;
+	case LVAR: case RLVAR:
+		ldxu(cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+
+ldxy(n)
+int n;
+{	printf("\tLDX\t%d,Y\n",n);
+}
+ldxu(n)
+int n;
+{	printf("\tLDX\t%d,U\n",n);
+}
+/*
+ldxi(n)
+int n;
+{	printf("\tLDX\t#%d\n",n);
+}
+*/
+stx(e)
+int e;
+{	switch (car(e))
+	{case GVAR:
+		stxy(cadr(e));
+		return;
+	case LVAR:
+		stxu(cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+
+stxy(n)
+int n;
+{	printf("\tSTX\t%d,Y\n",n);
+}
+stxu(n)
+int n;
+{	printf("\tSTX\t%d,U\n",n);
+}
+
+sex()
+{	printf("\tSEX\n");
+}
+incx()
+{	printf("\tINC\t,X\n");
+}
+decx()
+{	printf("\tDEC\t,X\n");
+}
+opdx(op)
+char *op;
+{	printf("\t%s\tD,X\n",op);
+}
+indexx(op,n)
+char *op;
+int n;
+{	printf("\t%s\t%d,X\n",op,n);
+}
+
+index(op,e)
+char *op;
+int e;
+{	switch (car(e))
+	{case GVAR:
+		indexy(op,cadr(e));
+		return;
+	case LVAR:
+		indexu(op,cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+
+indexy(op,n)
+char *op;
+int n;
+{	printf("\t%s\t%d,Y\n",op,n);
+}
+indexu(op,n)
+char *op;
+int n;
+{	printf("\t%s\t%d,U\n",op,n);
+}
+
+
+indir(op,e)
+char *op;
+int e;
+{	switch (car(e))
+	{case RGVAR:
+		indiry(op,cadr(e));
+		return;
+	case RLVAR:
+		indiru(op,cadr(e));
+		return;
+	default:
+		DEBUG;
+	}
+}
+
+indiry(op,n)
+char *op;
+int n;
+{	printf("\t%s\t[%d,Y]\n",op,n);
+}
+indiru(op,n)
+char *op;
+int n;
+{	printf("\t%s\t[%d,U]\n",op,n);
+}
+sextend(byte)
+int byte;
+{	if (byte) sex();
+}
+binexpr(e1)
+int e1;
+{	gexpr(caddr(e1));
+	pushd();
+	gexpr(cadr(e1));
+	pulx();
+	library(car(e1));
+}
+library(op)
+int op;
+{	printf("\tLBSR\t_0000%d\n",
+	       ((op == MUL || op == UMUL) ? 1 :
+		(op == DIV)	? 2 :
+		(op == UDIV)	? 3 :
+		(op == MOD)	? 4 :
+		(op == UMOD)	? 5 :
+		(op == LSHIFT)	? 6 :
+		(op == ULSHIFT) ? 7 :
+		(op == RSHIFT)	? 8 :
+		(op == URSHIFT) ? 9 : DEBUG));
+}
+cexpr(e)
+int e;
+{	if (car(e) != CONST) error(CNERR);
+	return (cadr(e));
+}
+
+getsym()
+{NMTBL *nptr0,*nptr1;
+int i;
+char c;
+	if (alpha(skipspc()))
+	{	i = hash = 0;
+		while (alpha(ch) || digit(ch))
+		{	if (i <= 7) hash=7*(hash+(name[i++]=ch));
+			getch();
+		}
+		name[i] = '\0';
+		nptr0 = gsearch();
+		if (nptr0->sc == RESERVE) return sym = nptr0->dsp;
+		if (nptr0->sc == MACRO && !mflag)
+		{	mflag++;
+			chsave = ch;
+			chptrsave = chptr;
+			chptr = (char *)nptr0->dsp;
+			getch();
+			return getsym();
+		}
+		sym = IDENT;
+		gnptr=nptr=nptr0;
+		if (mode==GDECL || mode==GSDECL || mode==GUDECL ||
+		    mode==GTDECL || mode==TOP)
+			return sym;
+		nptr1=lsearch();
+		if (mode==STAT)
+			if (nptr1->sc == EMPTY) return sym;
+			else { nptr=nptr1; return sym;}
+		nptr=nptr1;
+		return sym;
+	}
+	else if (digit(ch))
+	{	symval=0;
+		if (ch == '0')
+		{	if (getch() == 'x' || ch == 'X')
+				while(1)
+					if(digit(getch()))
+						symval=symval*16+ch-'0';
+					else if('a'<=ch&&ch<='f')
+						symval=symval*16+ch-'a'+10;
+					else if('A'<=ch&&ch<='F')
+						symval=symval*16+ch-'A'+10;
+					else break;
+			else while (digit(ch)) {symval=symval*8+ch-'0';getch();}
+		}
+		else while(digit(ch)) {symval=symval*10+ch-'0';getch();}
+		return sym=CONST;
+	}
+	else if(ch=='\'')
+	{	getch();
+		symval=escape();
+		if(ch!='\'') error(CHERR);
+		getch();
+		return sym=CONST;
+	}
+	else if(ch=='"')
+	{	getstring();
+		return sym= STRING;
+	}
+	c=ch;
+	getch();
+	switch(c)
+	{case '*':
+		return postequ(MUL,MUL+AS);
+	case '&':
+		if(ch=='&') {getch();return sym=LAND;}
+		return postequ(BAND,BAND+AS);
+	case '-':
+		if(ch=='>') {getch();return sym=ARROW;}
+		if(ch=='-') {getch();return sym=DEC;}
+		return postequ(SUB,SUB+AS);
+	case '!':
+		return postequ(LNOT,NEQ);
+	case '~':
+		return sym=BNOT;
+	case '+':
+		if(ch=='+') {getch();return sym=INC;}
+		return postequ(ADD,ADD+AS);
+	case '%':
+		return postequ(MOD,MOD+AS);
+	case '^':
+		return postequ(EOR,EOR+AS);
+	case '|':
+		if(ch=='|') {getch();return sym=LOR;}
+		return postequ(BOR,BOR+AS);
+	case '=':
+		return postequ(ASS,EQ);
+	case '>':
+		if(ch=='>') {getch();return postequ(RSHIFT,RSHIFT+AS);}
+		return postequ(GT,GE);
+	case '<':
+		if(ch=='<') {getch();return postequ(LSHIFT,LSHIFT+AS);}
+		return postequ(LT,LE);
+	case '(':
+		return sym=LPAR;
+	case ')':
+		return sym=RPAR;
+	case '[':
+		return sym=LBRA;
+	case ']':
+		return sym=RBRA;
+	case '{':
+		return sym=LC;
+	case '}':
+		return sym=RC;
+	case ',':
+		return sym=COMMA;
+	case ';':
+		return sym=SM;
+	case ':':
+		return sym=COLON;
+	case '?':
+		return sym=COND;
+	case '.':
+		return sym=PERIOD;
+	case '/':
+		if(ch!='*') return postequ(DIV,DIV+AS);
+		getch();
+		while(ch=='*'?getch()!='/':getch());
+		getch();
+		return getsym();
+	default:
+		error(CHERR);
+		return getsym();
+	}
+}
+postequ(s1,s2)
+int s1,s2;
+{	if(ch=='=') {getch();return sym=s2;}
+	return sym=s1;
+}
+alpha(c)
+char c;
+{	return('a'<=c&&c<='z'||'A'<=c&&c<='Z'||c=='_');
+}
+digit(c)
+char c;
+{	return('0'<=c&&c<='9');
+}
+NMTBL *gsearch()
+{NMTBL *nptr,*iptr;
+	iptr=nptr= &ntable[hash % GSYMS];
+	while(nptr->sc!=EMPTY && neqname(nptr->nm))
+	{	if (++nptr== &ntable[GSYMS]) nptr=ntable;
+		if (nptr==iptr) error(GSERR);
+	}
+	if (nptr->sc == EMPTY) copy(nptr->nm);
+	return nptr;
+}
+NMTBL *lsearch()
+{NMTBL *nptr,*iptr;
+	iptr=nptr= &ntable[hash%LSYMS+GSYMS];
+	while(nptr->sc!=EMPTY && neqname(nptr->nm))
+	{	if (++nptr== &ntable[LSYMS+GSYMS]) nptr= &ntable[GSYMS];
+		if (nptr==iptr) error(LSERR);
+	}
+	if (nptr->sc == EMPTY) copy(nptr->nm);
+	return nptr;
+}
+neqname(p)
+char *p;
+{char *q;
+	q=name;
+	while(*p) if(*p++ != *q++) return 1;
+	return *q!=0;
+}
+copy(p)
+char *p;
+{char *q;
+	q=name;
+	while(*p++= *q++);
+}
+getstring()
+{	getch();
+	symval = 0;
+	sptr = cheapp;
+	while (ch != '"')
+	{	*cheapp++ = escape();
+		symval++;
+		if (cheapp >= cheap+CHEAPSIZE) error(STRERR);
+	}
+	getch();
+	*cheapp++ = '\0';
+	symval++;
+}
+skipspc()
+{	while(ch=='\t'||ch=='\n'||ch==' '||ch=='\r') getch();
+	return ch;
+}
+getch()
+{	if(*chptr) return ch= *chptr++;
+	if(mflag) {mflag=0;chptr=chptrsave;return ch=chsave;}
+	getline();
+	return getch();
+}
+char escape()
+{char c;
+	if ((c=ch) == '\\')
+	{	if (digit(c=getch()))
+		{	c = ch-'0';
+			if (digit(getch()))
+			{	c = c*8+ch-'0';
+				if (digit(getch())) {c=c*8+ch-'0';getch();}
+			}
+			return c;
+		}
+		getch();
+		switch(c)
+		{case 'n':
+			return '\n';
+		case 't':
+			return '\t';
+		case 'b':
+			return '\b';
+		case 'r':
+			return '\r';
+		case 'f':
+			return '\f';
+		case '\n':
+			return escape();
+		default:
+			return c;
+		}
+	}
+	if (c == '\n') error(EXERR);
+	getch();
+	return c;
+}
+FILE *getfname()
+{int i;
+char name[14];
+	getch();
+	if(skipspc()!='"') error(INCERR);
+	for(i=0;(getch()!='"' && ch!='\n');)
+		if(i<13) name[i++]=ch;
+	if(ch=='\n') error(INCERR);
+	name[i]=0;
+	return ( (filep+1)->fcb = fopen(name,"rc") );
+}
+getline()
+{int i;
+int c;
+	lineno++;
+	glineno++;
+	chptr=linebuf;
+	i=0;
+	while ((*chptr++ = c = getc(filep->fcb)) != '\n')
+	{	if (++i > LBUFSIZE-2) error(LNERR);
+		if (c==EOF)
+		{	error(EOFERR);
+			--chptr;
+		}
+	}
+	*chptr = '\0';
+	if (lsrc && !asmf) printf("* %s",linebuf);
+	if (*(chptr = linebuf) == '#')
+	{	++chptr;
+		if (macroeq("define"))
+		{	i=mode;
+			mode=GDECL;
+			ch= *chptr;
+			if (getsym() == IDENT)
+			{	if (nptr->sc == EMPTY)
+				{	nptr->sc = MACRO;
+					nptr->dsp = (int)cheapp;
+					while ((*cheapp++ = c = *chptr++)
+							&& c != '\n');
+					*cheapp++ = '\0';
+					if (cheapp >= cheap+CHEAPSIZE)
+						error(STRERR);
+					if (!c) error(EOFERR);
+				}
+				else error(MCERR);
+			}
+			else error(MCERR);
+			mode=i;
+			*(chptr = linebuf) = '\0';
+		}
+		else if (macroeq("include"))
+		{	fprintf(stderr,"%s",linebuf);
+			if(filep+1 >= filestack + FILES) error(FILERR);
+			if ( ((filep+1)->fcb=getfname()) == NULL) error(FILERR);
+			(filep+1)->ln=lineno;
+			lineno=0;
+			++filep;
+			*(chptr = linebuf) = '\0';
+		}
+		else if (macroeq("asm"))
+		{	if (asmf) error(MCERR);
+			asmf = 1;
+			getline();
+			while (asmf)
+			{	printf("%s",linebuf);
+				getline();
+			}
+		}
+		else if (macroeq("endasm"))
+		{	if (!asmf) error(MCERR);
+			asmf = 0;
+		}
+		else if (macroeq(" "))
+			getline();
+		else error(MCERR);
+	}
+}
+
+macroeq(s)
+char *s;
+{char *p;
+	for (p = chptr; *s;) if (*s++ != *p++) return 0;
+	chptr = p;
+	return 1;
+}
+
+car(e)
+int e;
+{	return heap[e];
+}
+cadr(e)
+int e;
+{	return heap[e+1];
+}
+caddr(e)
+int e;
+{	return heap[e+2];
+}
+cadddr(e)
+int e;
+{	return heap[e+3];
+}
+list2(e1,e2)
+int e1,e2;
+{int e;
+	e=getfree(2);
+	heap[e]=e1;
+	heap[e+1]=e2;
+	return e;
+}
+list3(e1,e2,e3)
+int e1,e2,e3;
+{int e;
+	e=getfree(3);
+	heap[e]=e1;
+	heap[e+1]=e2;
+	heap[e+2]=e3;
+	return e;
+}
+list4(e1,e2,e3,e4)
+int e1,e2,e3,e4;
+{int e;
+	e=getfree(4);
+	heap[e]=e1;
+	heap[e+1]=e2;
+	heap[e+2]=e3;
+	heap[e+3]=e4;
+	return e;
+}
+getfree(n)
+int n;
+{int e;
+	switch (mode)
+	{case GDECL: case GSDECL: case GUDECL: case GTDECL:
+		e=gfree;
+		gfree+=n;
+		break;
+	default:
+		lfree-=n;
+		e=lfree;
+	}
+	if(lfree<gfree) error(HPERR);
+	return e;
+}
+rplacad(e,n)
+int e,n;
+{	heap[e+1]=n;
+	return e;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/mclib.c	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,486 @@
+#define	FILE	char
+#define	FCBSIZE	320
+#define	NFILES	8
+
+#define	NULL	0
+#define EOF	(-1)
+
+#define	stdin	_fcbtbl[0]
+#define	stdout	_fcbtbl[1]
+#define	stderr	_fcbtbl[2]
+
+#define	STDIN	0xffff
+#define	STDOUT	0xfffe
+#define	STDERR	0xfffd
+
+FILE *_fcbtbl[NFILES];
+
+_main(argc,argv)
+int argc;
+char **argv;
+{int i;
+	stdin = STDIN;
+	stdout = STDOUT;
+	stderr = STDERR;
+	initheap();
+	for ( i = 3; i < NFILES; i++ ) _fcbtbl[i] = NULL;
+	main(argc,argv);
+}
+
+FILE *fopen(name,mode)
+char *name,*mode;
+{FILE *fcbp;
+ char *p;
+ int rd,wt,cm;
+	rd = wt = cm = 0;
+	for ( p = mode; *p; p++ ) {
+		switch ( *p ) {
+		case 'r':
+			rd = 1; break;
+		case 'w':
+			wt = 1; break;
+		case 'c':
+			cm = 1; break;
+		default:
+			return NULL;
+		}
+	}
+	if ( !(rd ^ wt) ) return NULL;
+	if ( rd ) return _open(name,cm);
+	else return _create(name,cm);
+}
+
+FILE *_open(name,cm)
+char *name;
+int cm;
+{FILE *fcbp;
+ int i;
+	for ( i = 0; i < NFILES; i++)
+		if ( _fcbtbl[i] == NULL ) break;
+	if ( i >= NFILES) return NULL;
+	if ( (fcbp = malloc(FCBSIZE)) == NULL ) return NULL;
+	if ( _setname(name,fcbp) == 0 ) return NULL;
+	if ( FMS(fcbp,1) < 0 ) return NULL;
+	fcbp[59] = cm ? 0 : 0xff;
+	fcbp[60] = 0;
+	return (_fcbtbl[i] = fcbp);
+}
+
+FILE *_create(name,cm)
+char *name;
+int cm;
+{FILE *fcbp;
+ int i;
+	for ( i = 0; i < NFILES; i++)
+		if ( _fcbtbl[i] == NULL ) break;
+	if ( i >= NFILES) return NULL;
+	if ( (fcbp = malloc(FCBSIZE)) == NULL ) return NULL;
+	if ( _setname(name,fcbp) == 0 ) return NULL;
+	if ( FMS(fcbp,2) < 0 )
+	{	if ( (fcbp[1] != 3) || (FMS(fcbp,12) < 0) ) return NULL;
+		_setname(name,fcbp);
+		if (FMS(fcbp,2) < 0) return NULL;
+	}
+	fcbp[15] = 0;
+	fcbp[59] = cm ? 0 : 0xff;
+	fcbp[60] = 0;
+	return (_fcbtbl[i] = fcbp);
+}
+
+fclose(fcbp)
+FILE *fcbp;
+{int i;
+	for ( i = 0; i < NFILES; i++ )
+		if ( fcbp == _fcbtbl[i] ) break;
+	if ( i >= NFILES ) return EOF;
+	_fcbtbl[i] = NULL;
+	if ( (fcbp == STDIN) || (fcbp == STDOUT) || (fcbp == STDERR) ) return 0;
+	if ( FMS(fcbp,4) < 0 ) return EOF;
+	mfree(fcbp);
+	return 0;
+}
+
+_setname(name,fcbp)
+char *name,*fcbp;
+{int i;
+	while(isspace(*name)) ++name;
+	if (isdigit(*name))
+	{	fcbp[3] = *name++ - '0';
+		if (*name++ != '.') return 0;
+	}
+	else fcbp[3] = 0xff;
+	for (i = 4; i < 15; ++i) fcbp[i] = 0;
+	if (!isalpha(*name)) return -1;
+	for (i = 4; i < 12; ++i)
+	{	if (!*name || (*name == '.')) break;
+		fcbp[i] = *name++;
+	}
+	while (*name && (*name != '.')) ++name;
+	if (*name == '.')
+	{	++name;
+		for (i = 12; i < 15; ++i)
+		{	if (!*name) break;
+			fcbp[i] = *name++;
+		}
+	}
+	return 1;
+}
+
+
+getc(fcbp)
+char *fcbp;
+{
+	switch (fcbp)
+	{case STDIN:
+		return GETCH();
+	case STDOUT:
+	case STDERR:
+		return EOF;
+	default:
+		if (fcbp[2] != 1) return EOF;
+		return FMS(fcbp,0);
+	}
+}
+
+putc(c,fcbp)
+char c,*fcbp;
+{	if ( c == '\t' ) c = ' ';
+	switch (fcbp)
+	{case STDIN:
+		return EOF;
+	case STDOUT:
+		return PUTCH(c);
+	case STDERR:
+		return PUTCH2(c);
+	default:
+		if (fcbp[2] != 2) return EOF;
+		if (FMS(fcbp,0,c) < 0) return EOF;
+		return c;
+	}
+}
+
+getchar()
+{	return getc(stdin);
+}
+
+putchar(c)
+char c;
+{	return putc(c,stdout);
+}
+
+printf(s)
+char *s;
+{	_fprintf(stdout,s,(int *)&s+1);
+}
+
+fprintf(f,s)
+char *f,*s;
+{	_fprintf(f,s,(int *)&s+1);
+}
+
+_fprintf(f,s,p)
+char *f,*s;
+int *p;
+{int l,m,n;
+ char c,buf[8];
+	while(c = *s++)
+		if (c != '%') putc(c,f);
+		else
+		{	if (l=(*s == '-')) ++s;
+			if (isdigit(*s)) s += _getint(&m,s);
+			else m = 0;
+			if (*s == '.') ++s;
+			if (isdigit(*s)) s += _getint(&n,s);
+			else n = 32767;
+			switch(*s++)
+			{case 'd':
+				itoa(*p++,buf);
+				break;
+			case 'o':
+				itooa(*p++,buf);
+				break;
+			case 'x':
+				itoxa(*p++,buf);
+				break;
+			case 'u':
+				itoua(*p++,buf);
+				break;
+			case 'c':
+				ctos(*p++,buf);
+				break;
+			case 's':
+				_putstr(f,*p++,l,m,n);
+				continue;
+			case '\0':
+				return;
+			default:
+				ctos(c,buf);
+				break;
+			}
+			_putstr(f,buf,l,m,n);
+		}
+}
+
+_getint(p,s)
+int *p;
+char *s;
+{int i;
+	for(*p=i=0; isdigit(*s); ++i) *p = *p * 10 + *s++ - '0';
+	return i;
+}
+
+_putstr(f,s,l,m,n)
+char *f,*s;
+int l,m,n;
+{int k;
+	k = (strlen(s) < n ? strlen(s) : n);
+	m = (k < m ? m-k : 0);
+	if (l)
+	{	_putsn(f,s,n);
+		_putspc(f,m);
+	}
+	else
+	{	_putspc(f,m);
+		_putsn(f,s,n);
+	}
+}
+	
+_putsn(f,s,n)
+char *f,*s;
+int n;
+{	while(*s)
+		if (--n >= 0) putc(*s++,f);
+		else break;
+}
+
+_putspc(f,n)
+char *f;
+int n;
+{	while(--n >= 0) putc(' ',f);
+}
+
+puts(s)
+char *s;
+{	while(*s) putchar(*s++);
+}
+
+itoa(n,s)
+int n;
+char *s;
+{	if (n < 0)
+	{	*s++ = '-';
+		return (itoua(-n,s)+1);
+	}
+	return itoua(n,s);
+}
+
+itoua(n,s)
+int n;
+char *s;
+{	return _itoda(n,s,10);
+}
+
+itooa(n,s)
+int n;
+char *s;
+{	return _itoda(n,s,8);
+}
+
+itoxa(n,s)
+int n;
+char *s;
+{	return _itoda(n,s,16);
+}
+
+_itoac(n)
+int n;
+{	return (n + ((n < 10) ? '0' : ('A'-10)));
+}
+
+_itoda(n,s,r)
+unsigned n;
+int r;
+char *s;
+{int i;
+ char t[8],*u;
+	u = t;
+	*u++ = '\0';
+	do *u++ = _itoac(n % r); while(n /= r);
+	for (i=0; *s++ = *--u; ++i);
+	return i;
+}
+
+char *ctos(c,s)
+char c,*s;
+{	s[0] = c;
+	s[1] = '\0';
+	return s;
+}
+
+strlen(s)
+char *s;
+{int i;
+	for(i = 0; *s++; ++i);
+	return i;
+}
+
+isdigit(c)
+char c;
+{	return '0' <= c && c <= '9';
+}
+
+isspace(c)
+char c;
+{	return (c == ' ' || c == '\t' || c == '\n');
+}
+
+isalpha(c)
+char c;
+{	return (isupper(c) || islower(c) || c == '_');
+}
+
+isupper(c)
+char c;
+{	return ('A' <= c && c <= 'Z');
+}
+
+islower(c)
+char c;
+{	return ('a' <= c && c <= 'z');
+}
+
+toupper(c)
+char c;
+{	return (islower(c) ? c + ('A'-'a') : c);
+}
+
+tolower(c)
+char c;
+{	return (isupper(c) ? c + ('a'-'A') : c);
+}
+
+atoi(s)
+char *s;
+{int i;
+	while (isspace(*s)) ++s;
+	for (i = 0; isdigit(*s);) i = i * 10 + *s++ - '0';
+	return i;
+}
+
+typedef struct header
+		{	struct header *bptr;
+			unsigned bsize;
+		} HEADER;
+
+HEADER base,*allocp,*heapp;
+
+char *malloc(s)
+unsigned s;
+{HEADER *p,*q;
+ int nunits;
+	nunits = 1 + (s + sizeof(HEADER) - 1) / sizeof(HEADER);
+	if ((q = allocp) == NULL)
+	{	base.bptr = allocp = q = &base;
+		base.bsize = 0;
+	}
+	for (p = q->bptr; ; q = p,p = p->bptr)
+	{	if (p->bsize >= nunits)
+		{	if (p->bsize == nunits)
+				q->bptr = p->bptr;
+			else
+			{	p->bsize -= nunits;
+				p += p->bsize;
+				p->bsize = nunits;
+			}
+			allocp = q;
+			clearblock(p);
+			return ((char *)(p + 1));
+		}
+		if (p == allocp)
+			if ((p = morecore(nunits)) == NULL)
+				return(NULL);
+	}
+}
+
+clearblock(p)
+HEADER *p;
+{char *s,*t;
+	s = (char *)(p + 1);
+	t = (char *)(p + p->bsize);
+	while (s < t) *s++ = 0;
+}
+
+#define NALLOC 128
+
+HEADER *morecore(nu)
+unsigned nu;
+{char *cp;
+ HEADER *up;
+ int rnu;
+	rnu = NALLOC * ((nu + NALLOC - 1) / NALLOC);
+	cp = sbrk(rnu * sizeof(HEADER));
+	if ((int)cp == -1) return NULL;
+	up = (HEADER *) cp;
+	up->bsize = rnu;
+	mfree((char *)(up+1));
+	return allocp;
+}
+
+#asm
+sbrk	PSHS	U
+	LEAU	,S
+	
+	LDD	heapp,Y
+	BNE	_mc0
+	BSR	initheap
+_mc0	PSHS	D
+	TFR	S,D
+	SUBD	,S++
+	CMPD	4,U
+	BCC	_mc1
+	LDD	#-1
+	LEAS	,U
+	PULS	U,PC
+	
+_mc1	LDD	4,U
+	LDX	heapp,Y
+	LEAX	D,X
+	LDD	heapp,Y
+	STX	heapp,Y
+	LEAS	,U
+	PULS	U,PC
+
+initheap
+	PSHS	U
+	LEAU	,S
+	TFR	Y,D
+	ADDD	#_GLOBALS
+	STD	heapp,Y
+	LEAS	,U
+	PULS	U,PC
+#endasm
+
+mfree(ap)
+char *ap;
+{HEADER *p,*q;
+	p = (HEADER *)ap - 1;
+	for (q = allocp; !(p > q && p < q->bptr); q = q->bptr)
+		if (q >= q->bptr && (p > q || p < q->bptr)) break;
+	if (p + p->bsize == q->bptr)
+	{	p->bsize += q->bptr->bsize;
+		p->bptr = q->bptr->bptr;
+	}
+	else p->bptr = q->bptr;
+	if (q + q->bsize == p)
+	{	q->bsize += p->bsize;
+		q->bptr = p->bptr;
+	}
+	else q->bptr = p;
+	allocp = q;
+}
+
+unsigned freesize()
+{int i;
+	if (!heapp) initheap();
+	return ((char *)&i - (char *)heapp);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/scanf.txt	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,157 @@
+
+_fskipspc(fp)
+FILE *fp;
+{char c;
+        while (_isspace(c = getc(fp)));
+        return c;
+}
+
+_isspace(c)
+char c;
+{       return ((c == ' ') || (c == '\t'));
+}
+
+scanf(s)
+char *s;
+{int i;
+        i = _fscanf(stdin,s,(int *)&s+1);
+        if (_fch && ((_ch == EOF) || (_ch == '\n'))) _fch = 0;
+        return i;
+}
+
+fscanf(fp,s)
+FILE *fp;
+char *s;
+{       return _fscanf(fp,s,(int *)&s+1);
+}
+
+_fscanf(fp,s,p)
+FILE *fp;
+char *s;
+int *p;
+{char c,ch;
+ int m,n,r,x;
+        n = 0;
+        while(c = *s++)
+                if (!_isspace(c))
+                if (c != '%')
+                {       if ((ch = _fskipspc(fp)) == EOF) return EOF;
+                        if (ch != c) return n;
+                }
+                else
+                {       if (x = (*s == '*')) ++s;
+                        if (isdigit(*s)) s += _getint(&m,s);
+                        else m = 32767;
+                        switch(c = *s++)
+                        {case 'd' :
+                                r = _atoin(fp,*p++,m,x);
+                                break;
+                        case 'o' :
+                                r = _otoin(fp,*p++,m,x);
+                                break;
+                        case 'x' :
+                                r = _xtoin(fp,*p++,m,x);
+                                break;
+                        case 'c' :
+                                r = _fgetc(fp,*p++,x);
+                                break;
+                        case 's' :
+                                r = _getstrn(fp,*p++,m,x);
+                                break;
+                        case '\0':
+                                return n;
+                        default:
+                                if ((ch = _fskipspc(fp)) == EOF) return EOF;
+                                if (ch != c) return n;
+                                continue;
+                        }
+                        if (!x) ++n;
+                        if (r == EOF) return EOF;
+                        if (r) return n;
+                }
+        return n;
+}
+
+_atoin(fp,p,m,x)
+FILE *fp;
+int *p,m,x;
+{int i,s;
+ char c;
+        if (isdigit(c = _fskipspc(fp)) || (c == '-'))
+        {       if (s = (c == '-')) c = getc(fp);
+                for (i = 0; isdigit(c) && --m >= 0; c = getc(fp))
+                                                i = i * 10 + c - '0';
+                ungetc(c,fp);
+                if (!x) *p = (s ? -i : i);
+                return 0;
+        }
+        return ((c == EOF) ? EOF : 1);
+}
+
+_otoin(fp,p,m,x)
+FILE *fp;
+int *p,m,x;
+{int i;
+ char c;
+        if (isoct(c = _fskipspc(fp)))
+        {       for (i = 0; isoct(c) && --m >= 0; c = getc(fp))
+                                                i = i * 8 + c -'0';
+                ungetc(c,fp);
+                if (!x) *p = i;
+                return 0;
+        }
+        return ((c == EOF) ? EOF : 1);
+}
+
+isoct(c)
+char c;
+{       return ('0' <= c && c <= '7');
+}
+
+_xtoin(fp,p,m,x)
+FILE *fp;
+int *p,m,x;
+{int i;
+ char c;
+        if (ishex(c = _fskipspc(fp)))
+        {       for (i = 0; ishex(c) && --m >= 0; c = getc(fp))
+                        if (isdigit(c)) i = i * 16 + c - '0';
+                        else if ('A' <= (c = toupper(c)) && c <= 'F')
+                                        i = i * 16 + c - ('A'-10);
+                ungetc(c,fp);
+                if (!x) *p = i;
+                return 0;
+        }
+        return ((c == EOF) ? EOF : 1);
+}
+
+ishex(c)
+char c;
+{       return (isdigit(c) || ('A' <= (c = toupper(c)) && c <= 'F'));
+}
+
+_fgetc(fp,p,x)
+FILE *fp;
+char *p;
+int x;
+{char c;
+        if ((c = getc(fp)) == EOF) return EOF;
+        if (!x) *p = c;
+        return 0;
+}
+
+_getstrn(fp,p,m,x)
+FILE *fp;
+char *p;
+int m,x;
+{char c,*q;
+        if (((c = _fskipspc(fp)) == EOF) || (c == '\n')) return EOF;
+        for (q = p; !_isspace(c) && --m >= 0; c = getc(fp))
+        {       if ((c == EOF) || (c == '\n')) break;
+                if ((c == '\b') && (q != p)) --q;
+                else if (!x) *q++ = c;
+        }
+        ungetc(c,fp);
+        if (!x) *q = '\0';
+        return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/stdio.txt	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,290 @@
+
+
+#define	FILE	char
+#define	FCBSIZE	320
+#define	NFILES	16
+
+#define	NULL	0
+#define EOF	(-1)
+
+#define	stdin	_fcbtbl[0]
+#define	stdout	_fcbtbl[1]
+#define	stderr	_fcbtbl[2]
+
+#define	STDIN	0xffff
+#define	STDOUT	0xfffe
+#define	STDERR	0xfffd
+
+FILE *_fcbtbl[NFILES];
+
+char _ch;
+int _fch = 0;
+
+_main(argc,argv)
+int argc;
+char **argv;
+{int i;
+	initheap();
+        stdin = STDIN;
+        stdout = STDOUT;
+        stderr = STDERR;
+        for (i = 3; i < NFILES; ++i) _fcbtbl[i] = NULL;
+        main(argc,argv);
+}
+
+ungetc(c,fp)
+char c;
+FILE *fp;
+{       if (fp == STDIN)
+        {       _fch = 1;
+                return _ch = c;
+        }
+        fp[62] = 1;
+        return fp[61] = c;
+}
+
+getc(fp)
+FILE *fp;
+{
+        switch ( fp ) {
+        case STDIN:
+                if (_fch) { _fch = 0; return _ch; }
+                return GETCH();
+        case STDOUT:
+        case STDERR:
+                return EOF;
+        default:
+                if (fp[2] != 1) return -1;
+                if (fp[62]) { fp[62] = 0; return fp[61]; }
+                return FMS(fp,0);
+        }
+}
+
+putc(c,fp)
+char c;
+FILE *fp;
+{       switch ( fp ) {
+        case STDIN:
+                return EOF;
+        case STDOUT:
+                return PUTCH(c);
+        case STDERR:
+                return PUTCH2(c);
+        default:
+                if (fp[2] != 2) return EOF;
+                if (FMS(fp,0,c) < 0) return EOF;
+                return c;
+        }
+}
+
+ugetch(c)
+char c;
+{       return ungetc(c,stdin);
+}
+
+getchar()
+{       return getc(stdin);
+}
+
+putchar(c)
+char c;
+{       return putc(c,stdout);
+}
+
+printf(s)
+char *s;
+{       _fprintf(stdout,s,(int *)&s+1);
+}
+
+fprintf(fp,s)
+FILE *fp;
+char *s;
+{       _fprintf(fp,s,(int *)&s+1);
+}
+
+_fprintf(fp,s,p)
+FILE *fp;
+char *s;
+int *p;
+{int l,m,n;
+ char c,buf[8];
+        while(c = *s++)
+                if (c != '%') putc(c,fp);
+                else
+                {       if (l=(*s == '-')) ++s;
+                        if (isdigit(*s)) s += _getint(&m,s);
+                        else m = 0;
+                        if (*s == '.') ++s;
+                        if (isdigit(*s)) s += _getint(&n,s);
+                        else n = 32767;
+                        switch(c = *s++)
+                        {case 'd':
+                                itoa(*p++,buf);
+                                break;
+                        case 'o':
+                                itooa(*p++,buf);
+                                break;
+                        case 'x':
+                                itoxa(*p++,buf);
+                                break;
+                        case 'u':
+                                itoua(*p++,buf);
+                                break;
+                        case 'c':
+                                ctos(*p++,buf);
+                                break;
+                        case 's':
+                                _putstr(fp,*p++,l,m,n);
+                                continue;
+                        case '\0':
+                                return;
+                        default:
+                                ctos(c,buf);
+                                break;
+                        }
+                        _putstr(fp,buf,l,m,n);
+                }
+}
+
+_getint(p,s)
+int *p;
+char *s;
+{int i;
+        for(*p = i = 0; isdigit(*s); ++i) *p = *p * 10 + *s++ - '0';
+        return i;
+}
+
+_putstr(fp,s,l,m,n)
+FILE fp;
+char *s;
+int l,m,n;
+{int k;
+        k = (strlen(s) < n ? strlen(s) : n);
+        m = (k < m ? m - k : 0);
+        if (l)
+        {       _putsn(fp,s,n);
+                _putspc(fp,m);
+        }
+        else
+        {       _putspc(fp,m);
+                _putsn(fp,s,n);
+        }
+}
+        
+_putsn(fp,s,n)
+FILE fp;
+char *s;
+int n;
+{       while(*s)
+                if (--n >= 0) putc(*s++,fp);
+                else break;
+}
+
+_putspc(fp,n)
+FILE *fp;
+int n;
+{       while(--n >= 0) putc(' ',fp);
+}
+
+itoa(n,s)
+int n;
+char *s;
+{       if (n < 0)
+        {       *s++ = '-';
+                return (itoua(-n,s) + 1);
+        }
+        return itoua(n,s);
+}
+
+itoua(n,s)
+int n;
+char *s;
+{       return _itoda(n,s,10);
+}
+
+ctos(c,s)
+char c,*s;
+{       s[0] = c;
+        s[1] = '\0';
+        return s;
+}
+
+itooa(n,s)
+int n;
+char *s;
+{       return _itoda(n,s,8);
+}
+
+itoxa(n,s)
+int n;
+char *s;
+{       return _itoda(n,s,16);
+}
+
+_itoac(n);
+int n;
+{       return (n + ((n < 10) ? '0' : ('A'-10)));
+}
+
+_itoda(n,s,r)
+unsigned n;
+int r;
+char *s;
+{int i;
+ char t[8],*u;
+        u = t;
+        *u++ = '\0';
+        do *u++ = _itoac(n % r); while(n /= r);
+        for (i=0; *s++ = *--u; ++i);
+        return i;
+}
+
+isdigit(c)
+char c;
+{       return ('0' <= c && c <= '9');
+}
+
+isspace(c)
+char c;
+{       return (c == ' ' || c == '\t' || c == '\n');
+}
+
+isalpha(c)
+char c;
+{       return (isupper(c) || islower(c) || c == '_');
+}
+
+isupper(c)
+char c;
+{       return ('A' <= c && c <= 'Z');
+}
+
+islower(c)
+char c;
+{       return ('a' <= c && c <= 'z');
+}
+
+toupper(c)
+char c;
+{       return (islower(c) ? c + ('A'-'a') : c);
+}
+
+tolower(c)
+char c;
+{       return (isupper(c) ? c + ('a'-'A') : c);
+}
+
+atoi(s)
+char *s;
+{int i,m;
+        while (isspace(*s)) ++s;
+        if (m = (*s == '-')) ++s;
+        for (i = 0; isdigit(*s);) i = i * 10 + *s++ - '0';
+        return (m ? -i : i);
+}
+strlen(s)
+char *s;
+{int i;
+        for (i = 0; *s++; ++i);
+        return i;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/stdio2.txt	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,296 @@
+
+
+#define	FBSIZE	sizeof(FILE)
+#define	NFILES	16
+
+#define	NULL	0
+#define EOF	(-1)
+
+#define	stdin	_fptbl[0]
+#define	stdout	_fptbl[1]
+#define	stderr	_fptbl[2]
+
+#define	STDIN	0xffff
+#define	STDOUT	0xfffe
+#define	STDERR	0xfffd
+
+typedef struct {
+	int _fcb[FCBSIZE];
+	int _fbp;
+	char _fbuf[1024];
+	} FILE;
+
+FILE *_fptbl[NFILES];
+
+char _ch;
+int _fch = 0;
+
+_main(argc,argv)
+int argc;
+char **argv;
+{int i;
+	initheap();
+        stdin = STDIN;
+        stdout = STDOUT;
+        stderr = STDERR;
+        for (i = 3; i < NFILES; ++i) _fptbl[i] = NULL;
+        main(argc,argv);
+	for (i = 0; i < NFILES; ++i) fflush(_fptbl[i]);
+}
+
+ungetc(c,fp)
+char c;
+FILE *fp;
+{       if (fp == STDIN)
+        {       _fch = 1;
+                return _ch = c;
+        }
+        fp->_fcb[62] = 1;
+        return fp->_fcb[61] = c;
+}
+
+getc(fp)
+FILE *fp;
+{
+        switch ( fp ) {
+        case STDIN:
+                if (_fch) { _fch = 0; return _ch; }
+                return GETCH();
+        case STDOUT:
+        case STDERR:
+                return EOF;
+        default:
+                if (fp->_fcb[2] != 1) return EOF;
+                if (fp->_fcb[62]) { fp->_fcb[62] = 0; return fp->_fcb[61]; }
+                return FMS(fp->_fcb,0);
+        }
+}
+
+putc(c,fp)
+char c;
+FILE *fp;
+{       switch ( fp ) {
+        case STDIN:
+                return EOF;
+        case STDOUT:
+                return PUTCH(c);
+        case STDERR:
+                return PUTCH2(c);
+        default:
+                if (fp->_fcb[2] != 2) return EOF;
+                if (FMS(fp->_fcb,0,c) < 0) return EOF;
+                return c;
+        }
+}
+
+ugetch(c)
+char c;
+{       return ungetc(c,stdin);
+}
+
+getchar()
+{       return getc(stdin);
+}
+
+putchar(c)
+char c;
+{       return putc(c,stdout);
+}
+
+printf(s)
+char *s;
+{       _fprintf(stdout,s,(int *)&s+1);
+}
+
+fprintf(fp,s)
+FILE *fp;
+char *s;
+{       _fprintf(fp,s,(int *)&s+1);
+}
+
+_fprintf(fp,s,p)
+FILE *fp;
+char *s;
+int *p;
+{int l,m,n;
+ char c,buf[8];
+        while(c = *s++)
+                if (c != '%') putc(c,fp);
+                else
+                {       if (l=(*s == '-')) ++s;
+                        if (isdigit(*s)) s += _getint(&m,s);
+                        else m = 0;
+                        if (*s == '.') ++s;
+                        if (isdigit(*s)) s += _getint(&n,s);
+                        else n = 32767;
+                        switch(c = *s++)
+                        {case 'd':
+                                itoa(*p++,buf);
+                                break;
+                        case 'o':
+                                itooa(*p++,buf);
+                                break;
+                        case 'x':
+                                itoxa(*p++,buf);
+                                break;
+                        case 'u':
+                                itoua(*p++,buf);
+                                break;
+                        case 'c':
+                                ctos(*p++,buf);
+                                break;
+                        case 's':
+                                _putstr(fp,*p++,l,m,n);
+                                continue;
+                        case '\0':
+                                return;
+                        default:
+                                ctos(c,buf);
+                                break;
+                        }
+                        _putstr(fp,buf,l,m,n);
+                }
+}
+
+_getint(p,s)
+int *p;
+char *s;
+{int i;
+        for(*p = i = 0; isdigit(*s); ++i) *p = *p * 10 + *s++ - '0';
+        return i;
+}
+
+_putstr(fp,s,l,m,n)
+FILE fp;
+char *s;
+int l,m,n;
+{int k;
+        k = (strlen(s) < n ? strlen(s) : n);
+        m = (k < m ? m - k : 0);
+        if (l)
+        {       _putsn(fp,s,n);
+                _putspc(fp,m);
+        }
+        else
+        {       _putspc(fp,m);
+                _putsn(fp,s,n);
+        }
+}
+        
+_putsn(fp,s,n)
+FILE fp;
+char *s;
+int n;
+{       while(*s)
+                if (--n >= 0) putc(*s++,fp);
+                else break;
+}
+
+_putspc(fp,n)
+FILE *fp;
+int n;
+{       while(--n >= 0) putc(' ',fp);
+}
+
+itoa(n,s)
+int n;
+char *s;
+{       if (n < 0)
+        {       *s++ = '-';
+                return (itoua(-n,s) + 1);
+        }
+        return itoua(n,s);
+}
+
+itoua(n,s)
+int n;
+char *s;
+{       return _itoda(n,s,10);
+}
+
+ctos(c,s)
+char c,*s;
+{       s[0] = c;
+        s[1] = '\0';
+        return s;
+}
+
+itooa(n,s)
+int n;
+char *s;
+{       return _itoda(n,s,8);
+}
+
+itoxa(n,s)
+int n;
+char *s;
+{       return _itoda(n,s,16);
+}
+
+_itoac(n);
+int n;
+{       return (n + ((n < 10) ? '0' : ('A'-10)));
+}
+
+_itoda(n,s,r)
+unsigned n;
+int r;
+char *s;
+{int i;
+ char t[8],*u;
+        u = t;
+        *u++ = '\0';
+        do *u++ = _itoac(n % r); while(n /= r);
+        for (i=0; *s++ = *--u; ++i);
+        return i;
+}
+
+isdigit(c)
+char c;
+{       return ('0' <= c && c <= '9');
+}
+
+isspace(c)
+char c;
+{       return (c == ' ' || c == '\t' || c == '\n');
+}
+
+isalpha(c)
+char c;
+{       return (isupper(c) || islower(c) || c == '_');
+}
+
+isupper(c)
+char c;
+{       return ('A' <= c && c <= 'Z');
+}
+
+islower(c)
+char c;
+{       return ('a' <= c && c <= 'z');
+}
+
+toupper(c)
+char c;
+{       return (islower(c) ? c + ('A'-'a') : c);
+}
+
+tolower(c)
+char c;
+{       return (isupper(c) ? c + ('a'-'A') : c);
+}
+
+atoi(s)
+char *s;
+{int i,m;
+        while (isspace(*s)) ++s;
+        if (m = (*s == '-')) ++s;
+        for (i = 0; isdigit(*s);) i = i * 10 + *s++ - '0';
+        return (m ? -i : i);
+}
+strlen(s)
+char *s;
+{int i;
+        for (i = 0; *s++; ++i);
+        return i;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/string.txt	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,64 @@
+
+strcat(s,t)
+char *s,*t;
+{       while (*s) ++s;
+        strcpy(s,t);
+}
+
+strcmp(s,t)
+char *s,*t;
+{       for (; *s == *t; ++s,++t) if (!*s) break;
+        return (*s - *t);
+}
+
+strcpy(s,t)
+char *s,*t;
+{       while (*s++ = *t++);
+}
+
+char *gets(s,n)
+char *s;
+int n;
+{       return fgets(s,n,stdin);
+}
+
+puts(s)
+char *s;
+{       return fputs(s,stdout);
+}
+
+char *fgets(s,n,f)
+char *s,*f;
+int n;
+{char c,*t;
+        t = s;
+        while (--n > 0)
+        {       if ((c = getc(f)) == EOF) break;
+                if ((*s++ = c) == '\n') break;
+        }
+        *s = '\0';
+        return ((c == EOF && s == t) ? NULL : s);
+
+}
+
+fputs(s,f)
+char *s,*f;
+{       while (*s) putc(*s++,f);
+}
+
+match(p,s)
+char *p,*s;
+{       switch (*p)
+        {case '*':
+                if (!*(p+1)) return 1;
+                while (!match(p+1,s)) if (!*s++) return 0;
+                return 1;
+         case '?':
+                return (*s ? match(p+1,s+1) : 0);
+         case '\0':
+                return (!*s);
+         default:
+                if (*p == *s) return match(p+1,s+1);
+                return 0;
+        }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/mc09/uf.c	Thu Dec 27 11:01:16 2018 +0900
@@ -0,0 +1,176 @@
+#include "STDIO.TXT"
+#include "STRING.TXT"
+#include "FILEIO.TXT"
+#include "ALLOC.TXT"
+
+#define CONSTAT *0xff80
+#define CONDATA *0xff81
+#define REMSTAT *0xff90
+#define REMDATA *0xff91
+
+#define RXRDY   0x01
+#define TXRDY   0x02
+
+#define BREAK   0x00
+#define EOT     0x04
+#define ESC     0x1b
+
+main()
+{       printf("Terminal emulator\n");
+        reminit();
+        while (1)
+        {       printf("\nT(erm , F(ile , E(xit : ");
+                switch ( toupper(getchar()) )
+                {       case 'T' : term(); break;
+                        case 'F' : filer(); break;
+                        case 'E' : exit();
+                }
+        }
+}
+
+term()
+{char c;
+        printf("\n>>> enter terminal mode <ctl-@ to exit>\n");
+#asm
+        ORCC    #$50    disable interrupt
+#endasm
+        while (1)
+        {       if ( remstat() ) conwrite(remread());
+                if ( constat() )
+                {       if ( (c = conread()) == BREAK ) break;
+                        remwrite(c);
+                }
+        }
+        ;
+#asm
+        ANDCC   #$AF    restore interrupt mask
+#endasm
+}
+
+filer()
+{       printf("\n>>> enter file transfer mode\n");
+        while (1)
+        {       printf("\nDirection F(lex->unix , U(nix->flex , E(xit : ");
+                switch ( toupper(getchar()) )
+                {       case 'F' : flex_unix(); break;
+                        case 'U' : unix_flex(); break;
+                        case 'E' : return;
+                }
+        }
+}
+
+flex_unix()
+{char   fn0[80],fn1[80],c;
+ FILE *fp;
+        printf("\nFLEX to UNIX file transfer\n");
+        printf("FLEX file name : ");
+        gets(fn0,80);
+        printf("\n");
+        toupstr(fn0);
+        if ( (fp = fopen(fn0,"rc")) < 0 )
+        {       printf("Can't open %s\n",fn0);
+                return;
+        }
+        printf("UNIX file name : ");
+        gets(fn1,80);
+        printf("\n");
+        tx_str("cat /dev/tty >");
+        tx_str(fn1);
+        tx_char('\n');
+        while ( (c = getc(fp)) != EOF ) tx_char(c);
+        remwrite(EOT);
+        fclose(fp);
+}
+
+unix_flex()
+{char   fn0[80],fn1[80],c;
+ FILE *fp;
+ int    i;
+ char linebuf[256];
+        printf("\nUNIX to FLEX file transfer\n");
+        printf("UNIX file name : ");
+        gets(fn0,80);
+        printf("\nFLEX file name : ");
+        gets(fn1,80);
+        printf("\n");
+        toupstr(fn1);
+        if ( (fp = fopen(fn1,"wc")) < 0 )
+        {       printf("Can't create %s\n",fn1);
+                return;
+        }
+        tx_str("/mnt/sys/tezuka/unix_flex/unix_flex ");
+        tx_str(fn0);
+        tx_char('\n');
+        while ( 1 ) {
+                i = 0;
+                while ( (c = remread()) != '\n' ) {
+                        if ( c == ESC ) {
+                                fclose(fp);
+                                return;
+                        }
+                        linebuf[i++] = c;
+                }
+                linebuf[i++] = '\n';
+                linebuf[i] = '\0';
+                for ( i = 0; linebuf[i]; i++ ) putc(linebuf[i],fp);
+                remwrite(ESC);
+                putchar('.');
+        }
+}
+
+toupstr(s)
+char *s;
+{       while ( *s )
+        {       *s = toupper(*s);
+                ++s;
+        }
+}
+
+tx_str(s)
+char *s;
+{       while ( *s ) tx_char(*s++);
+}
+
+tx_char(c)
+char c;
+{       remwrite(c);
+        while ( c != remread() );
+/*    */putchar(c);
+}
+
+constat()
+{       return ( CONSTAT & RXRDY );
+}
+
+conread()
+{       while ( !constat() );
+        return ( CONDATA & 0x7f);
+}
+
+conwrite(ch)
+char ch;
+{       while ( !(CONSTAT & TXRDY) );
+        CONDATA = ch;
+}
+
+reminit()
+{
+        REMSTAT = 0x43;
+        REMSTAT = 0x15;
+}
+
+remstat()
+{       return ( REMSTAT & RXRDY );
+}
+
+remread()
+{       while ( !remstat() );
+        return ( REMDATA & 0x7f );
+}
+
+remwrite(ch)
+char ch;
+{       while ( !(REMSTAT & TXRDY) );
+        REMDATA = ch;
+}
+