# HG changeset patch # User Shinji KONO # Date 1549324987 -32400 # Node ID 1a30cd6e5973d88445da98e08f1e3fa7b8b3dca1 # Parent 1d574c5b33833e13c212c8403ee93ecfafe98429 move mc09 to top diff -r 1d574c5b3383 -r 1a30cd6e5973 mc09/COPYRIGHT --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/COPYRIGHT Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/MANIFEST --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/MANIFEST Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/NewsMess.j --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/NewsMess.j Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/README Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/alloc.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/alloc.txt Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/c.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/c.txt Tue Feb 05 09:03:07 2019 +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 + INCLUDE "c.out" include compilers output +* OPT NOL +* +* +* +_99999 EQU * global vars allocated here +* + END _00000 + diff -r 1d574c5b3383 -r 1a30cd6e5973 mc09/crtos9.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/crtos9.asm Tue Feb 05 09:03:07 2019 +0900 @@ -0,0 +1,275 @@ + +* * micro-C driver under FLEX * * 12-Dec-81 M.Ohta,H.Tezuka +* 12-Dec-2018 for OS-9 S.Kono * + +* +* micro-C user program +* +_tylg set Prgrm+Objct +_atrv set ReEnt+rev +_rev set $00 +_edition set 5 + ifp1 + use defsfile + endc + + +* OPT LIST + INCLUDE "c.out" include compilers output +* OPT NOL + +* x arguments pointer +* u global variable area +_start +_00000 + LEAS -256,S ALLOCATE WORK AREA + leay _name,pcr + pshs x,y POINT TO CONTENT OF ARGUMENT VECTOR + leay ,u + PSHS Y + +* allocate memory and change stack +* try to allocate maximum memory if not specified + ifndef __MEMSIZ + LDD #(1024*48) + else + LDD #__MEMSIZ + endif + pshs d +__0C004 + os9 F$Mem + bcc __0C005 + ldd ,s + subd #$1000 + lblo exit can't get any memroy + std ,s + bra __0C004 +__0C005 +* y is heap upper bound +* copy arg string + ldx 4,s +__0C007 tst ,x+ + bne __0C007 + clr ,-y +__0C008 lda ,-x + sta ,-y + cmpx 4,s + bne __0C008 + sty 4,s + leax ,y +* copy saved arg into new stack +* and change the stack + ldy 2,s + ldd 4,s + std ,--x + ldd 6,s + std ,--x + leas ,x +* clear globals on Y + LDD #_GLOBALS +_0C002 CLR D,Y + subd #1 + BNE _0C002 +_0C003 + tfr y,d + addd #_GLOBALS + std heapp,y + LBSR _INITIALIZE call initializer + LBSR _main +* exit clrb + os9 F$Exit + + +* +* run time support +* + +* +_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 +initheap + 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 +* +* +* +* + emod +_eom diff -r 1d574c5b3383 -r 1a30cd6e5973 mc09/defsfile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/defsfile Tue Feb 05 09:03:07 2019 +0900 @@ -0,0 +1,18 @@ +* Main defsfile for OS-9 Level One V1 +* +* +* OS-9 Level and Version equates +Level equ 1 +OS9Vrsn equ 1 +OS9Major equ 0 +OS9Minor equ 1 + +NOS9VER equ OS9Vrsn +NOS9MAJ equ OS9Major +NOS9MIN equ OS9Minor + + + use ../os9/nitros9-code/defs/os9.d + use ../os9/nitros9-code/defs/scf.d + use ../os9/nitros9-code/defs/rbf.d + diff -r 1d574c5b3383 -r 1a30cd6e5973 mc09/diff_to_mc2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/diff_to_mc2 Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/fileio.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/fileio.txt Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/fileio2.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/fileio2.txt Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/makefile Tue Feb 05 09:03:07 2019 +0900 @@ -0,0 +1,47 @@ +MCLIBS=alloc.txt c.txt fileio.txt fileio2.txt mclib.c scanf.txt\ + stdio.txt stdio2.txt string.txt + +MCUTILS=uf.c + +DESTDIR=../os9/level2 + +# CFLAGS = -m32 -O0 -g -Wno-return-type -Wno-implicit-int -Wno-implicit-function-declaration -Wno-parentheses +CFLAGS = -O0 -g -Wno-return-type -Wno-implicit-int -Wno-implicit-function-declaration -Wno-parentheses -Wno-format + +AS09 = ../src/a09 + +all: mc2 testcp + +mc: mc.c + cc $(CFLAGS) mc.c -o mc + +mc2: mc mc2.c mclibos9.c + ./mc -s -Mmc mc2.c + $(AS09) crtos9.asm -l mc2.lst -o mc2 + +# mc2.o: c.out +# $(AS09) c.txt -l c.lst -o mc2.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 + +/* to avoid conflict with stdio.h */ +#define getline getline1 +#define index index1 + +#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; +long 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; long dsp; } NMTBL; + +NMTBL ntable[GSYMS+LSYMS],*nptr,*gnptr,*decl0(),*decl1(),*lsearch(),*gsearch(); + +struct {int fd,ln;/*char fcb[320]*/FILE *fcb;} *filep,filestack[FILES]; + +long car(); +long cadr(); +long caddr(); +long cadddr(); +void leaxpcr(NMTBL *n); +long error(); +list2(long e1,long e2); +list3(long e1,long e2,long e3); +list4(long e1,long e2,long e3,long e4); + +main(argc,argv) +int argc; +char **argv; +{NMTBL *nptr; +int i; +char *ccout; +char *modname; + if(argc==1) exit(1); + lsrc = chk = asmf = 0; + ccout = "c.out"; + modname = "aout"; + 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 'M': case 'm': + modname = 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); + else { + /* we'l resize data area later */ + printf("\tmod _eom,_name,_tylg,_atrv,_start,1024\n"); /* os9 module header */ + printf("_name fcs /%s/\n\tfcb 0\n",modname); + } + } + init(); + while(1) + { for (nptr = &ntable[GSYMS],i=LSYMS; i--;) + (nptr++)->sc = EMPTY; + mode=TOP; + while(getsym()==SM); + mode=GDECL; + args=0; + decl(); + } +} +long +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",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); + return 0; +} +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,(long)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,(long)nptr)); + break; + } + default:error(UDERR); + } + break; + case STRING: + e1=list3(STRING,(long)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; +{long 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\t*+5,PCR\n\tBRA\t_%d\n",lb); + else + printf("\tLEAX\t*+6,PCR\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; +{long 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); +} +void +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 = (long)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 = 2; lineno--; glineno--; + chptr = ";;"; + } + else if (macroeq("endasm")) + { if (!asmf) error(MCERR); + asmf = 0; + } + else if (macroeq(" ")) + getline(); + else error(MCERR); + } + if (asmf==2) asmf=1; /* return ";" to get correct macro alignment */ + else if (asmf==1) { + while (asmf) + { printf("%s",linebuf); + getline(); + } + } +} + +macroeq(s) +char *s; +{char *p; + for (p = chptr; *s;) if (*s++ != *p++) return 0; + chptr = p; + return 1; +} + +long +car(e) +int e; +{ return heap[e]; +} +long +cadr(e) +int e; +{ return heap[e+1]; +} +long +caddr(e) +int e; +{ return heap[e+2]; +} +long +cadddr(e) +int e; +{ return heap[e+3]; +} +list2(e1,e2) +long e1,e2; +{int e; + e=getfree(2); + heap[e]=e1; + heap[e+1]=e2; + return e; +} +list3(e1,e2,e3) +long 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) +long 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",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\t*+5,PCR\n\tBRA\t_%d\n",lb); + else + printf("\tLEAX\t*+6,PCR\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 = 2; lineno--; glineno--; + chptr = ";;"; + } + else if (macroeq("endasm")) + { if (!asmf) error(MCERR); + asmf = 0; + } + else if (macroeq(" ")) + getline(); + else error(MCERR); + } + if (asmf==2) asmf=1; /* return ";" to get correct macro alignment */ + else if (asmf==1) { + while (asmf) + { printf("%s",linebuf); + getline(); + } + } + +} + +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 1d574c5b3383 -r 1a30cd6e5973 mc09/mclibos9.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/mclibos9.c Tue Feb 05 09:03:07 2019 +0900 @@ -0,0 +1,617 @@ +/* os9 driver */ + + +int errno = 0; + +typedef struct { + int fd; /* 0 */ + int fmode; /* 2 */ + int length; /* 4 */ + char *fname; /* 6 */ + char *ptr; /* 8 */ + char *buf; /* 10 */ + } FILE ; + +#define FCBSIZE (sizeof(FILE)) +#define BUFSIZ 256 + +#define NFILES 8 + +#define NULL 0 +#define EOF (-1) + +#define stdin _fcbtbl[0] +#define stdout _fcbtbl[1] +#define stderr _fcbtbl[2] + +FILE *_fcbtbl[NFILES]; + +FILE _s0[3]; + +_main(prog,args) +char *prog; +char *args; +{int i; + char **argv,*p,*q; + int argc,n,quote,c; + initheap(); + stdin = (FILE*) malloc(sizeof(FILE)); initfp(stdin,0); + stdout = (FILE*) malloc(sizeof(FILE)); initfp(stdout,1); + stderr = (FILE*) malloc(sizeof(FILE)); initfp(stderr,2); + for ( i = 3; i < NFILES; i++ ) _fcbtbl[i] = NULL; + /* create argv here */ + argc = 0; + argv = 0; + for( i = 0; i < 2 ; i++ ) { + q = p = args; + if (i==1) { + argv = (char**)malloc(sizeof(char*)*(argc+1)); + argv[0] = prog; + } + n = 1; + quote = 0; + if (i==1) argv[n] = args; + while((c = *p) && c!='\r') { + if (c=='\'') { + if (!quote) { + p++; + quote = 1; + } else { + p++; + if (i==1) *q=0; + quote = 0; + } + } else if (c=='\\') { + p++; + } else if (c==' ') { + if (!quote) { + if (i==1) { + *q = 0; argv[++n] = q+1; + } + } + } + if (i==1) *q = *p; + q++; p++; + } + if (i==1&&p!=args) { *q = 0; argv[++n] = q+1; } + argc = n; + } + argv[n]=0; + exit(main(argc,argv)); +} + + +exit(e) +int e; +{ + int i; + for ( i = 3; i < NFILES; i++ ) { + if (_fcbtbl[i]) + fclose(_fcbtbl[i]); + } +#asm + ldb 4,u + os9 F$Exit +#endasm +} + +initfp(fp,d) +FILE *fp; +int fd; +{ + fp->fd = d; + fp->buf = (char*)malloc(BUFSIZ+1); + fp->ptr = fp->buf; + fp->fname = fp->length = fp->fmode = 0; +} + +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; cm |= 1; break; + case 'w': + wt = 1; cm |= 3; break; + case 'c': /* charcter mode */ + 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; +#asm + pshs x,y,u + ldx -2,u + lda 7,u mode + ldx 6,x name + os9 I$Open + bcs _LC0001 + ldx -2,u + tfr a,b + clra + std ,x + bra _LC0002 +_LC0001 + ldx -2,u + tfr a,b + clra + std 2,x err code + ldd #-1 + std ,x +_LC0002 + puls x,y,u +#endasm + if (fcbp->fd < 0 ) { errno = fcbp->fmode ; *mfree(fcbp); return NULL; } + initfp(fcbp,i); + fcbp->fmode = cm; + 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; +#asm + pshs x,y,u + ldx -2,u + lda 7,u mode + ldb #3 + ldx 6,x name + os9 I$Create + bcs _LC0003 + ldx -2,u + tfr a,b + clra + std ,x + bra _LC0004 +_LC0003 + ldx -2,u + tfr a,b + clra + stD 2,x err code + ldd #-1 + std ,x +_LC0004 + puls x,y,u +#endasm + if (fcbp->fd < 0 ) { errno = fcbp->fmode ; mfree(fcbp); return NULL; } + initfp(fcbp,i); + fcbp->fmode = cm; + 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; + if ((fcbp->fmode&3) && fcbp->ptr!=fcbp->buf) { + fflush(fcbp); + } +#asm + pshs x,y,u + ldx 4,u + lda 1,x + os9 I$Close + puls x,y,u +#endasm + _fcbtbl[i] = NULL; + if (fcbp->buf) mfree(fcbp->buf); + mfree(fcbp); + return 0; +} + +_setname(name,fcbp) +char *name; FILE *fcbp; +{ + fcbp->fname = name; + return 1; +} + + +getc(fcbp) +FILE *fcbp; +{ + int len; + char *buff; + if (fcbp->buf) { + if (fcbp->ptr < fcbp->buf+fcbp->length) { + return (*fcbp->ptr++)&0xff; + } + len = BUFSIZ; fcbp->ptr = buff = fcbp->buf; + } else { + len = 1 ; fcbp->ptr = buff = &len; + } +#asm + pshs y + ldx 4,u FILE + lda 1,x file descriptor + ldx -4,u buf + ldy -2,u len + os9 I$Read + sty -2,u len + puls y +#endasm + if (len<=0) { fcbp->length=0; return -1; } + fcbp->length=len; + return (*fcbp->ptr++)&0xff; +} + +fflush(fcbp) +FILE *fcbp; +{ + int len; + char *buff; + if (fcbp->buf==0) + return; + len = fcbp->ptr - fcbp->buf; + if (len==0) return; + buff = fcbp->buf; +#asm + pshs y + ldx 4,u FILE + lda 1,x file descriptor + ldx -4,u + ldy -2,u + os9 I$Write + sty -2,u + puls y +#endasm + fcbp->ptr = fcbp->buf; +} + +putc(c,fcbp) +char c; FILE *fcbp; +{ + int len; + if (!fcbp->buf) { + fcbp->buf=&c; fcbp->ptr=fcbp->buf+1; + fflush(fcbp); + fcbp->buf = 0; + return; + } else if (fcbp->ptr >= fcbp->buf+BUFSIZ) { + fflush(fcbp); + } + *fcbp->ptr++ = 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 + 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 + +#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 1d574c5b3383 -r 1a30cd6e5973 mc09/scanf.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/scanf.txt Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/stdio.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/stdio.txt Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/stdio2.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/stdio2.txt Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/string.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/string.txt Tue Feb 05 09:03:07 2019 +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 1d574c5b3383 -r 1a30cd6e5973 mc09/test/cp.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/test/cp.c Tue Feb 05 09:03:07 2019 +0900 @@ -0,0 +1,22 @@ +#include "mclibos9.c" + +int +main(argc,argv) +int argc;char *argv[]; { + FILE *input ; + FILE *output ; + int c; + int i; + + input = stdin; + output = stdout; + + i = 1; + if (argv[i]) { input = fopen(argv[i++],"r"); } + if (argv[i]) { output = fopen(argv[i++],"w"); } + if (input==0 || output==0) return 0; + while( (c = getc(input) ) != -1) { + putc(c,output); + } + return 1; +} diff -r 1d574c5b3383 -r 1a30cd6e5973 mc09/uf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc09/uf.c Tue Feb 05 09:03:07 2019 +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; +} + diff -r 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/COPYRIGHT --- a/os9/mc09/COPYRIGHT Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/MANIFEST --- a/os9/mc09/MANIFEST Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/NewsMess.j --- a/os9/mc09/NewsMess.j Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ ->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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/README --- a/os9/mc09/README Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/alloc.txt --- a/os9/mc09/alloc.txt Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ - -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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/c.txt --- a/os9/mc09/c.txt Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,386 +0,0 @@ - -* -* 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 - INCLUDE "c.out" include compilers output -* OPT NOL -* -* -* -_99999 EQU * global vars allocated here -* - END _00000 - diff -r 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/crtos9.asm --- a/os9/mc09/crtos9.asm Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,275 +0,0 @@ - -* * micro-C driver under FLEX * * 12-Dec-81 M.Ohta,H.Tezuka -* 12-Dec-2018 for OS-9 S.Kono * - -* -* micro-C user program -* -_tylg set Prgrm+Objct -_atrv set ReEnt+rev -_rev set $00 -_edition set 5 - ifp1 - use defsfile - endc - - -* OPT LIST - INCLUDE "c.out" include compilers output -* OPT NOL - -* x arguments pointer -* u global variable area -_start -_00000 - LEAS -256,S ALLOCATE WORK AREA - leay _name,pcr - pshs x,y POINT TO CONTENT OF ARGUMENT VECTOR - leay ,u - PSHS Y - -* allocate memory and change stack -* try to allocate maximum memory if not specified - ifndef __MEMSIZ - LDD #(1024*48) - else - LDD #__MEMSIZ - endif - pshs d -__0C004 - os9 F$Mem - bcc __0C005 - ldd ,s - subd #$1000 - lblo exit can't get any memroy - std ,s - bra __0C004 -__0C005 -* y is heap upper bound -* copy arg string - ldx 4,s -__0C007 tst ,x+ - bne __0C007 - clr ,-y -__0C008 lda ,-x - sta ,-y - cmpx 4,s - bne __0C008 - sty 4,s - leax ,y -* copy saved arg into new stack -* and change the stack - ldy 2,s - ldd 4,s - std ,--x - ldd 6,s - std ,--x - leas ,x -* clear globals on Y - LDD #_GLOBALS -_0C002 CLR D,Y - subd #1 - BNE _0C002 -_0C003 - tfr y,d - addd #_GLOBALS - std heapp,y - LBSR _INITIALIZE call initializer - LBSR _main -* exit clrb - os9 F$Exit - - -* -* run time support -* - -* -_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 -initheap - 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 -* -* -* -* - emod -_eom diff -r 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/defsfile --- a/os9/mc09/defsfile Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -* Main defsfile for OS-9 Level One V1 -* -* -* OS-9 Level and Version equates -Level equ 1 -OS9Vrsn equ 1 -OS9Major equ 0 -OS9Minor equ 1 - -NOS9VER equ OS9Vrsn -NOS9MAJ equ OS9Major -NOS9MIN equ OS9Minor - - - use ../nitros9-code/defs/os9.d - use ../nitros9-code/defs/scf.d - use ../nitros9-code/defs/rbf.d - diff -r 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/diff_to_mc2 --- a/os9/mc09/diff_to_mc2 Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -*** 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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/fileio.txt --- a/os9/mc09/fileio.txt Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/fileio2.txt --- a/os9/mc09/fileio2.txt Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/makefile --- a/os9/mc09/makefile Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -MCLIBS=alloc.txt c.txt fileio.txt fileio2.txt mclib.c scanf.txt\ - stdio.txt stdio2.txt string.txt - -MCUTILS=uf.c - -DESTDIR=../level2 - -# CFLAGS = -m32 -O0 -g -Wno-return-type -Wno-implicit-int -Wno-implicit-function-declaration -Wno-parentheses -CFLAGS = -O0 -g -Wno-return-type -Wno-implicit-int -Wno-implicit-function-declaration -Wno-parentheses -Wno-format - -AS09 = ../../src/a09 - -all: mc2 testcp - -mc: mc.c - cc $(CFLAGS) mc.c -o mc - -mc2: mc mc2.c mclibos9.c - ./mc -s -Mmc mc2.c - $(AS09) crtos9.asm -l mc2.lst -o mc2 - -# mc2.o: c.out -# $(AS09) c.txt -l c.lst -o mc2.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 - -/* to avoid conflict with stdio.h */ -#define getline getline1 -#define index index1 - -#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; -long 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; long dsp; } NMTBL; - -NMTBL ntable[GSYMS+LSYMS],*nptr,*gnptr,*decl0(),*decl1(),*lsearch(),*gsearch(); - -struct {int fd,ln;/*char fcb[320]*/FILE *fcb;} *filep,filestack[FILES]; - -long car(); -long cadr(); -long caddr(); -long cadddr(); -void leaxpcr(NMTBL *n); -long error(); -list2(long e1,long e2); -list3(long e1,long e2,long e3); -list4(long e1,long e2,long e3,long e4); - -main(argc,argv) -int argc; -char **argv; -{NMTBL *nptr; -int i; -char *ccout; -char *modname; - if(argc==1) exit(1); - lsrc = chk = asmf = 0; - ccout = "c.out"; - modname = "aout"; - 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 'M': case 'm': - modname = 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); - else { - /* we'l resize data area later */ - printf("\tmod _eom,_name,_tylg,_atrv,_start,1024\n"); /* os9 module header */ - printf("_name fcs /%s/\n\tfcb 0\n",modname); - } - } - init(); - while(1) - { for (nptr = &ntable[GSYMS],i=LSYMS; i--;) - (nptr++)->sc = EMPTY; - mode=TOP; - while(getsym()==SM); - mode=GDECL; - args=0; - decl(); - } -} -long -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",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); - return 0; -} -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,(long)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,(long)nptr)); - break; - } - default:error(UDERR); - } - break; - case STRING: - e1=list3(STRING,(long)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; -{long 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\t*+5,PCR\n\tBRA\t_%d\n",lb); - else - printf("\tLEAX\t*+6,PCR\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; -{long 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); -} -void -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 = (long)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 = 2; lineno--; glineno--; - chptr = ";;"; - } - else if (macroeq("endasm")) - { if (!asmf) error(MCERR); - asmf = 0; - } - else if (macroeq(" ")) - getline(); - else error(MCERR); - } - if (asmf==2) asmf=1; /* return ";" to get correct macro alignment */ - else if (asmf==1) { - while (asmf) - { printf("%s",linebuf); - getline(); - } - } -} - -macroeq(s) -char *s; -{char *p; - for (p = chptr; *s;) if (*s++ != *p++) return 0; - chptr = p; - return 1; -} - -long -car(e) -int e; -{ return heap[e]; -} -long -cadr(e) -int e; -{ return heap[e+1]; -} -long -caddr(e) -int e; -{ return heap[e+2]; -} -long -cadddr(e) -int e; -{ return heap[e+3]; -} -list2(e1,e2) -long e1,e2; -{int e; - e=getfree(2); - heap[e]=e1; - heap[e+1]=e2; - return e; -} -list3(e1,e2,e3) -long 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) -long 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",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\t*+5,PCR\n\tBRA\t_%d\n",lb); - else - printf("\tLEAX\t*+6,PCR\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 = 2; lineno--; glineno--; - chptr = ";;"; - } - else if (macroeq("endasm")) - { if (!asmf) error(MCERR); - asmf = 0; - } - else if (macroeq(" ")) - getline(); - else error(MCERR); - } - if (asmf==2) asmf=1; /* return ";" to get correct macro alignment */ - else if (asmf==1) { - while (asmf) - { printf("%s",linebuf); - getline(); - } - } - -} - -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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/mclibos9.c --- a/os9/mc09/mclibos9.c Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,617 +0,0 @@ -/* os9 driver */ - - -int errno = 0; - -typedef struct { - int fd; /* 0 */ - int fmode; /* 2 */ - int length; /* 4 */ - char *fname; /* 6 */ - char *ptr; /* 8 */ - char *buf; /* 10 */ - } FILE ; - -#define FCBSIZE (sizeof(FILE)) -#define BUFSIZ 256 - -#define NFILES 8 - -#define NULL 0 -#define EOF (-1) - -#define stdin _fcbtbl[0] -#define stdout _fcbtbl[1] -#define stderr _fcbtbl[2] - -FILE *_fcbtbl[NFILES]; - -FILE _s0[3]; - -_main(prog,args) -char *prog; -char *args; -{int i; - char **argv,*p,*q; - int argc,n,quote,c; - initheap(); - stdin = (FILE*) malloc(sizeof(FILE)); initfp(stdin,0); - stdout = (FILE*) malloc(sizeof(FILE)); initfp(stdout,1); - stderr = (FILE*) malloc(sizeof(FILE)); initfp(stderr,2); - for ( i = 3; i < NFILES; i++ ) _fcbtbl[i] = NULL; - /* create argv here */ - argc = 0; - argv = 0; - for( i = 0; i < 2 ; i++ ) { - q = p = args; - if (i==1) { - argv = (char**)malloc(sizeof(char*)*(argc+1)); - argv[0] = prog; - } - n = 1; - quote = 0; - if (i==1) argv[n] = args; - while((c = *p) && c!='\r') { - if (c=='\'') { - if (!quote) { - p++; - quote = 1; - } else { - p++; - if (i==1) *q=0; - quote = 0; - } - } else if (c=='\\') { - p++; - } else if (c==' ') { - if (!quote) { - if (i==1) { - *q = 0; argv[++n] = q+1; - } - } - } - if (i==1) *q = *p; - q++; p++; - } - if (i==1&&p!=args) { *q = 0; argv[++n] = q+1; } - argc = n; - } - argv[n]=0; - exit(main(argc,argv)); -} - - -exit(e) -int e; -{ - int i; - for ( i = 3; i < NFILES; i++ ) { - if (_fcbtbl[i]) - fclose(_fcbtbl[i]); - } -#asm - ldb 4,u - os9 F$Exit -#endasm -} - -initfp(fp,d) -FILE *fp; -int fd; -{ - fp->fd = d; - fp->buf = (char*)malloc(BUFSIZ+1); - fp->ptr = fp->buf; - fp->fname = fp->length = fp->fmode = 0; -} - -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; cm |= 1; break; - case 'w': - wt = 1; cm |= 3; break; - case 'c': /* charcter mode */ - 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; -#asm - pshs x,y,u - ldx -2,u - lda 7,u mode - ldx 6,x name - os9 I$Open - bcs _LC0001 - ldx -2,u - tfr a,b - clra - std ,x - bra _LC0002 -_LC0001 - ldx -2,u - tfr a,b - clra - std 2,x err code - ldd #-1 - std ,x -_LC0002 - puls x,y,u -#endasm - if (fcbp->fd < 0 ) { errno = fcbp->fmode ; *mfree(fcbp); return NULL; } - initfp(fcbp,i); - fcbp->fmode = cm; - 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; -#asm - pshs x,y,u - ldx -2,u - lda 7,u mode - ldb #3 - ldx 6,x name - os9 I$Create - bcs _LC0003 - ldx -2,u - tfr a,b - clra - std ,x - bra _LC0004 -_LC0003 - ldx -2,u - tfr a,b - clra - stD 2,x err code - ldd #-1 - std ,x -_LC0004 - puls x,y,u -#endasm - if (fcbp->fd < 0 ) { errno = fcbp->fmode ; mfree(fcbp); return NULL; } - initfp(fcbp,i); - fcbp->fmode = cm; - 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; - if ((fcbp->fmode&3) && fcbp->ptr!=fcbp->buf) { - fflush(fcbp); - } -#asm - pshs x,y,u - ldx 4,u - lda 1,x - os9 I$Close - puls x,y,u -#endasm - _fcbtbl[i] = NULL; - if (fcbp->buf) mfree(fcbp->buf); - mfree(fcbp); - return 0; -} - -_setname(name,fcbp) -char *name; FILE *fcbp; -{ - fcbp->fname = name; - return 1; -} - - -getc(fcbp) -FILE *fcbp; -{ - int len; - char *buff; - if (fcbp->buf) { - if (fcbp->ptr < fcbp->buf+fcbp->length) { - return (*fcbp->ptr++)&0xff; - } - len = BUFSIZ; fcbp->ptr = buff = fcbp->buf; - } else { - len = 1 ; fcbp->ptr = buff = &len; - } -#asm - pshs y - ldx 4,u FILE - lda 1,x file descriptor - ldx -4,u buf - ldy -2,u len - os9 I$Read - sty -2,u len - puls y -#endasm - if (len<=0) { fcbp->length=0; return -1; } - fcbp->length=len; - return (*fcbp->ptr++)&0xff; -} - -fflush(fcbp) -FILE *fcbp; -{ - int len; - char *buff; - if (fcbp->buf==0) - return; - len = fcbp->ptr - fcbp->buf; - if (len==0) return; - buff = fcbp->buf; -#asm - pshs y - ldx 4,u FILE - lda 1,x file descriptor - ldx -4,u - ldy -2,u - os9 I$Write - sty -2,u - puls y -#endasm - fcbp->ptr = fcbp->buf; -} - -putc(c,fcbp) -char c; FILE *fcbp; -{ - int len; - if (!fcbp->buf) { - fcbp->buf=&c; fcbp->ptr=fcbp->buf+1; - fflush(fcbp); - fcbp->buf = 0; - return; - } else if (fcbp->ptr >= fcbp->buf+BUFSIZ) { - fflush(fcbp); - } - *fcbp->ptr++ = 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 - 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 - -#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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/scanf.txt --- a/os9/mc09/scanf.txt Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ - -_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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/stdio.txt --- a/os9/mc09/stdio.txt Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,290 +0,0 @@ - - -#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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/stdio2.txt --- a/os9/mc09/stdio2.txt Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,296 +0,0 @@ - - -#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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/string.txt --- a/os9/mc09/string.txt Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ - -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 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/test/cp.c --- a/os9/mc09/test/cp.c Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -#include "mclibos9.c" - -int -main(argc,argv) -int argc;char *argv[]; { - FILE *input ; - FILE *output ; - int c; - int i; - - input = stdin; - output = stdout; - - i = 1; - if (argv[i]) { input = fopen(argv[i++],"r"); } - if (argv[i]) { output = fopen(argv[i++],"w"); } - if (input==0 || output==0) return 0; - while( (c = getc(input) ) != -1) { - putc(c,output); - } - return 1; -} diff -r 1d574c5b3383 -r 1a30cd6e5973 os9/mc09/uf.c --- a/os9/mc09/uf.c Mon Jan 21 10:43:25 2019 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,176 +0,0 @@ -#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; -} - diff -r 1d574c5b3383 -r 1a30cd6e5973 src/Makefile --- a/src/Makefile Mon Jan 21 10:43:25 2019 +0900 +++ b/src/Makefile Tue Feb 05 09:03:07 2019 +0900 @@ -15,7 +15,7 @@ # CFLAGS=-g -DTERM_CONTROL \ # -std=c99 -D_POSIX_C_SOURCE=1 -D_XOPEN_SOURCE=1 -D_POSIX_SOURCE=200809L -D_GNU_SOURCE=1 \ # -Dd_namlen=d_reclen -CFLAGS=-g -DTERM_CONTROL +CFLAGS=-g -DTERM_CONTROL V09FLAGS= -DUSE_TERMIOS # -DNOFMEMOPEN -DBIG_ENDIAN