# HG changeset patch # User Shinji KONO # Date 1545876076 -32400 # Node ID 92ed427b7f7d0a7780c18fd538d58cc42a6146a2 # Parent ba0af2b8836b1505d460a71464bbac34be036395 add micro-c by mohta diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/COPYRIGHT --- /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. diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/MANIFEST --- /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) diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/NewsMess.j --- /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 + + 続きましてマイクロCです。さねをさん@京大に教えてもらったバグ +はとってありますが、もはや手近にFLEXの開発環境などないので、 +実際の動作テストはできていません。しかし、出力のアセンブラリスト +を見るかぎりは、大丈夫みたいです。 + + 単純にmakeとやると、FLEX用のmicro−Cのオブジェク +トコード”mc2.o”(Sフォーマット)ができますが、UNIX上 +での開発なら、mcというエクゼキュータを作れば十分です。 + + 詳しいマニュアルはありませんが(キャノワード用の5インチFDに +はいっているので、とりだしようがないのです)、工学社から1985 +年に出た「C言語と周辺制御」という本はマイクロCを題材にしている +ので、参考になると思います。 + + 太田 昌孝 + mohta@titcce.cc.titech.junet + +------------------------------------------------------------------- diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/README --- /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 '}') diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/alloc.txt --- /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); +} diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/c.txt --- /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 + diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/diff_to_mc2 --- /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 + + #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(ifcb = 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; diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/fileio.txt --- /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); +} diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/fileio2.txt --- /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); +} diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/makefile --- /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 + +#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<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(ifcb = 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(lfreesc = 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<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= 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); +} diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/scanf.txt --- /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; +} diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/stdio.txt --- /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; +} diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/stdio2.txt --- /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; +} diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/string.txt --- /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; + } +} diff -r ba0af2b8836b -r 92ed427b7f7d os9/mc09/uf.c --- /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 \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; +} +