OpenCores
URL https://opencores.org/ocsvn/light8080/light8080/trunk

Subversion Repositories light8080

[/] [light8080/] [trunk/] [tools/] [c80/] [c80.c] - Blame information for rev 80

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 65 motilito
//************************************************
2
//
3
//              Small-C Compiler 
4
// 
5
//              by Ron Cain 
6
// 
7
//************************************************
8
 
9
// with minor mods by RDK 
10
#define BANNER  " <><><>   Small-C  V1.2  DOS--CP/M Cross Compiler   <><><>"
11
#define VERSION " <><><><><>   CP/M Large String Space Version   <><><><><>"
12
#define AUTHOR  " <><><><><><><><><><>   By Ron Cain   <><><><><><><><><><>"
13
#define TLINE   " <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>"
14
 
15
/*      Define system dependent parameters      */
16
/*      Stand-alone definitions                 */
17
/* INCLUDE THE LIBRARY TO COMPILE THE COMPILER (RDK) */
18
/* #include smallc.lib */ /* small-c library included in source now */
19
/* IN DOS USE THE SMALL-C OBJ LIBRARY RATHER THAN IN-LINE ASSEMBLER */
20
#define NULL 0
21
#define eol 10 /* was 13 */
22
 
23
#include "stdio.h"  /* was <stdio.h> */
24
 
25
/*      Define the symbol table parameters      */
26
#define symsiz          16
27
#define symtbsz         5760
28
#define numglbs         300
29
#define startglb        symtab
30
#define endglb          startglb+numglbs*symsiz
31
#define startloc        endglb+symsiz
32
#define endloc          symtab+symtbsz-symsiz
33
 
34
/*      Define symbol table entry format        */
35
#define name            0
36
#define ident           9
37
#define type            10
38
#define storage         11
39
#define offset          12
40
#define initptr         14
41
 
42
/*      System wide name size (for symbols)     */
43
#define namesize        9
44
#define namemax         8
45
 
46
/*      Define possible entries for "ident"     */
47
#define variable        1
48
#define array           2
49
#define pointer         3
50
#define function        4
51
 
52
/*      Define possible entries for "type"      */
53
#define cchar           1
54
#define cint            2
55
#define cport           3 
56
 
57
/*      Define possible entries for "storage"   */
58
#define statik          1
59
#define stkloc          2
60
 
61
/*      Define the "while" statement queue      */
62
#define wqtabsz         300
63
#define wqsiz           4
64
#define wqmax           wq+wqtabsz-wqsiz
65
 
66
/*      Define entry offsets in while queue     */
67
#define wqsym           0
68
#define wqsp            1
69
#define wqloop          2
70
#define wqlab           3
71
 
72
/*      Define the literal pool                 */
73
#define litabsz         8000
74
#define litmax          litabsz-1
75
 
76
/*      Define the input line                   */
77
#define linesize        256
78
#define linemax         linesize-1
79
#define mpmax           linemax
80
 
81
/*      Define the macro (define) pool          */
82
#define macqsize        3000
83
#define macmax          macqsize-1
84
 
85
/*      Define statement types (tokens)         */
86
#define stif            1
87
#define stwhile         2
88
#define streturn        3
89
#define stbreak         4
90
#define stcont          5
91
#define stasm           6
92
#define stexp           7
93
 
94
/* Define how to carve up a name too long for the assembler */
95
#define asmpref         7
96
#define asmsuff         7
97
 
98
// define the global variable init values que size 
99
#define initqsz         8192
100
 
101
/*      Now reserve some storage words          */
102
char    symtab[symtbsz];        /* symbol table */
103
char    *glbptr,*locptr;        /* ptrs to next entries */
104
 
105
int             wq[wqtabsz];            /* while queue */
106
int             *wqptr;                         /* ptr to next entry */
107
 
108
char    litq[litabsz];          /* literal pool */
109
int             litptr;                         /* ptr to next entry */
110
 
111
char    macq[macqsize];         /* macro string buffer */
112
int             macptr;                         /* and its index */
113
 
114
char    inittbq[initqsz];       // init value buffer 
115
int             inittbptr;                      // and its index 
116
 
117
char    line[linesize];         /* parsing buffer */
118
char    mline[linesize];        /* temp macro buffer */
119
int             lptr,mptr;                      /* ptrs into each */
120
 
121
/*      Misc storage    */
122
int     nxtlab,         /* next avail label # */
123
        litlab,         /* label # assigned to literal pool */
124
        Zsp,            /* compiler relative stk ptr */
125
        argstk,         /* function arg sp */
126
        ncmp,           /* # open compound statements */
127
        errcnt,         /* # errors in compilation */
128
        errstop,        /* stop on error                        gtf 7/17/80 */
129
        eof,            /* set non-zero on final input eof */
130
        input,          /* iob # for input file */
131
        output,         /* iob # for output file (if any) */
132
        outputv,        /* output valid flag */
133
        input2,         /* iob # for "include" file */
134
        glbflag,        /* non-zero if internal globals */
135
        ctext,          /* non-zero to intermix c-source */
136
        cmode,          /* non-zero while parsing c-code */
137
                        /* zero when passing assembly code */
138
        lastst,         /* last executed statement type */
139
        mainflg,        /* output is to be first asm file       gtf 4/9/80 */
140
        saveout,        /* holds output ptr when diverted to console       */
141
                        /*                                      gtf 7/16/80 */
142
        fnstart,        /* line# of start of current fn.        gtf 7/2/80 */
143
        lineno,         /* line# in current file                gtf 7/2/80 */
144
        infunc,         /* "inside function" flag               gtf 7/2/80 */
145
        savestart,      /* copy of fnstart "    "               gtf 7/16/80 */
146
        saveline,       /* copy of lineno  "    "               gtf 7/16/80 */
147
        saveinfn;       /* copy of infunc  "    "               gtf 7/16/80 */
148
 
149
char   *currfn,         /* ptr to symtab entry for current fn.  gtf 7/17/80 */
150
       *savecurr;       /* copy of currfn for #include          gtf 7/17/80 */
151
char    *cptr;          /* work ptr to any char buffer */
152
int     *iptr;          /* work ptr to any int buffer */
153
 
154
// interactive mode flag 
155
int intmode;
156
// pointer array to input files list from argv[] 
157
#define MAXINFILES              64
158
char *infiles[MAXINFILES];
159
int filesnum, filesidx;
160
// initial stack pointer value 
161
int stackptr;
162
 
163
/*      >>>>> start cc1 <<<<<<          */
164
 
165
/*                                      */
166
/*      Compiler begins execution here  */
167
/*                                      */
168
void main(int argc, char *argv[])
169
{
170
int argi, phelp;
171
 
172
        glbptr=startglb;        /* clear global symbols */
173
        locptr=startloc;        /* clear local symbols */
174
        wqptr=wq;0;              /* clear while queue */
175
        macptr=0;                /* clear the macro pool */
176
        litptr=0;                /* clear literal pool */
177
        Zsp =0;                  /* stack ptr (relative) */
178
        errcnt=0;                /* no errors */
179
        errstop=0;               /* keep going after an error            gtf 7/17/80 */
180
        eof=0;                   /* not eof yet */
181
        input=0;         /* no input file */
182
        input2=0;                /* or include file */
183
        output=0;                /* no open units */
184
        outputv=0;               /* output is not valid */
185
        saveout=0;               /* no diverted output */
186
        ncmp=0;                  /* no open compound states */
187
        lastst=0;                /* no last statement yet */
188
        mainflg=0;               /* not first file to asm                gtf 4/9/80 */
189
        fnstart=0;               /* current "function" started at line 0 gtf 7/2/80 */
190
        lineno=0;                /* no lines read from file              gtf 7/2/80 */
191
        infunc=0;                /* not in function now                  gtf 7/2/80 */
192
        currfn=NULL;    /* no function yet                      gtf 7/2/80 */
193
        cmode=1;                /* enable preprocessing */
194
        stackptr=0;              /* default value of stack pointer */
195
        inittbptr=0;     // clear pointer to init array 
196
 
197
        intmode = 1;    // default mode is interactive mode 
198
        filesnum = 0;    // no input files for now 
199
        filesidx = 0;
200
 
201
        // print original banner 
202
        printf("\n");
203
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
204
        printf(" <><><>   Small-C  V1.2  DOS--CP/M Cross Compiler   <><><>\n");
205
        printf(" <><><><><><><><><><>   By Ron Cain   <><><><><><><><><><>\n");
206
        printf(" <><><><><>   CP/M Large String Space Version   <><><><><>\n");
207
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
208
 
209
        // print adapted banner and usage 
210
        printf("\n");
211
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
212
        printf(" <><><>  Small-C adapted for embedded systems by  <><><><>\n");
213
        printf(" <><><><><><><><><>  Moti  Litochevski  <><><><><><><><><>\n");
214
        printf(" <><><><><><> Version 0.1 (February 20, 2012) <><><><><><>\n");
215
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
216
        printf("\n");
217
        // check if command line options where specified 
218
        if (argc <= 1) {
219
                printf(" command line mode usage:\n");
220
                printf("      c80 -s<hexvalue> -o<filename> <input files>\n");
221
                printf(" options:\n");
222
                printf("      -s<hexvalue>   Initial stack pointer value in hex value.\n");
223
                printf("                     Example: -s800 will init the stack pointer\n");
224
                printf("                     to 0x800.\n");
225
                printf("      -o<filename>   Compiler output filename including extension.\n");
226
                printf(" \n");
227
        }
228
 
229
        // start from the first valid argument 
230
        argi = 1;
231
        phelp = 0;
232
    // loop through input options 
233
    while (argi < argc) {
234
            // copy pointer of the current option to the work buffer 
235
            cptr = argv[argi];
236
            // loop through input options 
237
            if (cptr[0] == '-') {
238
                    // compiler options 
239
                    if (cptr[1] == 's') {
240
                            // stack pointer address value 
241
                            sscanf(&cptr[2], "%x", &stackptr);
242
                        } else if (cptr[1] == 'o') {
243
                                // copy the output filename to the line 
244
                                strcpy(line, &cptr[2]);
245
                                // open output file 
246
                                openout(0);
247
                        } else if ((cptr[1] == 'h') | (cptr[1] == '?')) {
248
                                // sign that only help should be printed 
249
                                phelp = 1;
250
                    } else {
251
                            printf("error: illegal option.\n");
252
                    }
253
                } else {
254
                        // after all other options the list of input files is given and 
255
                        // compiler is operated in non-interactive mode 
256
                        intmode = 0;
257
 
258
                        // copy the input files names pointers to the local array 
259
                        for (filesnum=0; (argi < argc) && (filesnum < MAXINFILES); filesnum++) {
260
                                infiles[filesnum] = argv[argi];
261
                                argi++;
262
                        }
263
                }
264
                // update argument index 
265
                argi++;
266
    }
267
 
268
    // check if compiler should be started 
269
    if (!phelp) {
270
            // announce interactive mode compiler 
271
                printf(" Starting compiler in interactive mode.\n\n");
272
                // compiler body 
273
                ask();                  /* get user options */
274
                if (outputv == 0) openout(1);            /* get an output file */
275
                openin();               /* and initial input file */
276
                header();               /* intro code */
277
                parse();                /* process ALL input */
278
                dumplits();             /* then dump literal pool */
279
                dumpglbs();             /* and all static memory */
280
                trailer();              /* follow-up code */
281
                closeout();             /* close the output (if any) */
282
                errorsummary();         /* summarize errors (on console!) */
283
        }
284
        return;                 /* then exit to system */
285
}
286
 
287
/*                                      */
288
/*      Abort compilation               */
289
/*              gtf 7/17/80             */
290
zabort()
291
{
292
        if(input2)
293
                endinclude();
294
        if(input)
295
                fclose(input);
296
        closeout();
297
        toconsole();
298
        pl("Compilation aborted.");  nl();
299
        exit();
300
/* end zabort */}
301
 
302
/*                                      */
303
/*      Process all input text          */
304
/*                                      */
305
/* At this level, only static declarations, */
306
/*      defines, includes, and function */
307
/*      definitions are legal...        */
308
parse()
309
{
310
        while (eof==0)           /* do until no more input */
311
        {
312
                if(amatch("char",4)){declglb(cchar);ns();}
313
                else if(amatch("int",3)){declglb(cint);ns();}
314
                else if(amatch("port",4)){declglb(cport);ns();}
315
                else if(match("#asm"))doasm();
316
                else if(match("#include"))doinclude();
317
                else if(match("#define"))addmac();
318
                else newfunc();
319
                blanks();       /* force eof if pending */
320
        }
321
}
322
/*                                      */
323
/*      Dump the literal pool           */
324
/*                                      */
325
dumplits()
326
        {int j,k;
327
        if (litptr==0) return;   /* if nothing there, exit...*/
328
        printlabel(litlab);col();nl(); /* print literal label */
329
        k=0;                     /* init an index... */
330
        while (k<litptr)        /*      to loop with */
331
                {defbyte();     /* pseudo-op to define byte */
332
                j=10;           /* max bytes per line */
333
                while(j--)
334
                        {outdec((litq[k++]&127));
335
                        if ((j==0) | (k>=litptr))
336
                                {nl();          /* need <cr> */
337
                                break;
338
                                }
339
                        outbyte(',');   /* separate bytes */
340
                        }
341
                }
342
        }
343
/*                                      */
344
/*      Dump all static variables       */
345
/*                                      */
346
dumpglbs()
347
{
348
int j,dptr,idx;
349
 
350
        if (glbflag==0) return;  /* don't if user said no */
351
        cptr=startglb;
352
        while (cptr<glbptr) {
353
                if ((cptr[ident]!=function) && (cptr[type]!=cport)) {
354
                        // do if anything but function or port 
355
                        // output name as label ... 
356
                        outname(cptr);col();nl();
357
                        // calculate number of bytes 
358
                        j = ((cptr[offset]&255) + ((cptr[offset+1]&255)<<8));
359 67 motilito
                        if ((cptr[type]==cint) | (cptr[ident]==pointer))
360 65 motilito
                                j=j+j;  // 2 bytes for integer values 
361
                        // check if the global has an init value 
362
                        dptr = ((cptr[initptr]&255) + ((cptr[initptr+1]&255)<<8));
363
                        // the value below represent the -1 value 
364
                        if (dptr==0xffff) {
365
                                // no init value, use original storage definition 
366
                                // define storage 
367
                                defstorage();
368
                                outdec(j);      /* need that many */
369
                                nl();
370
                        }
371
                        else {
372
                                // define the data section 
373
                                defbyte();
374
                                // loop through init value 
375
                                idx=1;
376
                                while (j--) {
377
                                        // write the next byte 
378
                                        outdec(inittbq[dptr++]);
379
                                        if ((j==0) | (dptr>=inittbptr)) {
380
                                                nl();           /* need <cr> */
381
                                                break;
382
                                        }
383
                                        // every 10 values reopen the line 
384
                                        if (idx++ == 10) {
385
                                                // add <cr> and restart byte definition 
386
                                                nl();
387
                                                defbyte();
388
                                                idx=1;
389
                                        } else
390
                                                // separate bytes 
391
                                                outbyte(',');
392
                                }
393
                        }
394
                }
395
                cptr=cptr+symsiz;
396
        }
397
}
398
/*                                      */
399
/*      Report errors for user          */
400
/*                                      */
401
errorsummary()
402
{
403
        /* see if anything left hanging... */
404
        if (ncmp) error("missing closing bracket");
405
                /* open compound statement ... */
406
        printf("\nThere were %d errors in compilation.\n\n", errcnt);
407
}
408
 
409
/* Get options from user */
410
ask()
411
{
412
int k,num[1];
413
 
414
        kill();                 /* clear input line */
415
        // by default enabling C text in the output file in form of comments (for clarity) 
416
        ctext=1;        /* user said yes */
417
        // by default assuming all files are compiled together 
418
        glbflag=1;      /* define globals */
419
        mainflg=1;      /* first file to assembler */
420
        nxtlab =0;       /* start numbers at lowest possible */
421
        // compiler does noy pause on errors 
422
        errstop=0;
423
 
424
        litlab=getlabel();      /* first label=literal pool */
425
        kill();                 /* erase line */
426
}
427
 
428
/*                                      */
429
/*      Get output filename             */
430
/*                                      */
431
openout(char flag)
432
{
433
        if (flag) {
434
                kill();                 /* erase line */
435
                output=0;                /* start with none */
436
                pl("Output filename? "); /* ask...*/
437
                gets(line);     /* get a filename */
438
        }
439
        if(ch()==0)return;       /* none given... */
440
        /* if given, open */
441
        if((output=fopen(line,"w"))==NULL) {
442
                output=0;        /* can't open */
443
                error("Open failure!");
444
        } else
445
                outputv = 1;
446
        kill();                 /* erase line */
447
}
448
/*                                      */
449
/*      Get (next) input file           */
450
/*                                      */
451
openin()
452
{
453
        input=0;         /* none to start with */
454
        while (input==0) {       /* any above 1 allowed */
455
                kill();         /* clear line */
456
                // check if we are using interactive mode or not 
457
                if (intmode) {
458
                        // use the old style input file from the user 
459
                        if (eof) break; /* if user said none */
460
                        pl("Input filename? ");
461
                        gets(line);     /* get a name */
462
                        if (ch()==0)
463
                                {eof=1;break;} /* none given... */
464
                } else {
465
                        // copy the file names from the name array 
466
                        if (filesidx < filesnum) {
467
                                strcpy(line, infiles[filesidx]);
468
                                printf("Processing Input file %d: %s\n", filesidx, line);
469
                                filesidx++;
470
                        } else {
471
                                // no more files 
472
                                eof=1;
473
                                break;
474
                        }
475
                }
476
 
477
                if ((input=fopen(line,"r"))!=NULL)
478
                        newfile();                      /* gtf 7/16/80 */
479
                else {
480
                        input=0; /* can't open it */
481
                        pl("Open failure");
482
                }
483
        }
484
        kill();         /* erase line */
485
}
486
 
487
/*                                      */
488
/*      Reset line count, etc.          */
489
/*                      gtf 7/16/80     */
490
newfile()
491
{
492
        lineno  = 0;     /* no lines read */
493
        fnstart = 0;     /* no fn. start yet. */
494
        currfn  = NULL; /* because no fn. yet */
495
        infunc  = 0;     /* therefore not in fn. */
496
/* end newfile */}
497
 
498
/*                                      */
499
/*      Open an include file            */
500
/*                                      */
501
doinclude()
502
{
503
        blanks();       /* skip over to name */
504
 
505
        toconsole();                                    /* gtf 7/16/80 */
506
        outstr("#include "); outstr(line+lptr); nl();
507
        tofile();
508
 
509
        if(input2)                                      /* gtf 7/16/80 */
510
                error("Cannot nest include files");
511
        else if ((input2=fopen(line+lptr,"r"))==NULL) {
512
                input2=0;
513
                error("Open failure on include file");
514
        }
515
        else {
516
                saveline = lineno;
517
                savecurr = currfn;
518
                saveinfn = infunc;
519
                savestart= fnstart;
520
                newfile();
521
        }
522
        kill();         /* clear rest of line */
523
                        /* so next read will come from */
524
                        /* new file (if open */
525
}
526
 
527
/*                                      */
528
/*      Close an include file           */
529
/*                      gtf 7/16/80     */
530
endinclude()
531
{
532
        toconsole();
533
        outstr("#end include"); nl();
534
        tofile();
535
 
536
        input2  = 0;
537
        lineno  = saveline;
538
        currfn  = savecurr;
539
        infunc  = saveinfn;
540
        fnstart = savestart;
541
/* end endinclude */}
542
 
543
/*                                      */
544
/*      Close the output file           */
545
/*                                      */
546
closeout()
547
{
548
        tofile();       /* if diverted, return to file */
549
        if(output)fclose(output); /* if open, close it */
550
        output=0;                /* mark as closed */
551
}
552
/*                                      */
553
/*      Declare a static variable       */
554
/*        (i.e. define for use)         */
555
/*                                      */
556
/* makes an entry in the symbol table so subsequent */
557
/*  references can call symbol by name  */
558
declglb(typ)            /* typ is cchar or cint or cport (added by Moti Litchevski) */
559
        int typ;
560
{
561
int k,j,iptr,idx,num[1];
562
char sname[namesize];
563
 
564
        while (1) {
565
                while (1) {
566
                        if(endst())return;      /* do line */
567
                        k=1;            /* assume 1 element */
568
                        if(match("*"))  /* pointer ? */
569
                                j=pointer;      /* yes */
570
                        else
571
                                j=variable; /* no */
572
 
573
                        // added by Moti Litochevski 
574
                        if (match("(")) {
575
                                // make sure this option is only used for port definition 
576
                                if (typ != cport)
577
                                        error("port address definition is only used for port type");
578
                                // get port address 
579
                                k=portadr();
580
                                k=k&0xff;
581
                        } else if (typ == cport) {
582
                                error("port definition syntax error, need to define port address in brackets");
583
                        }
584
 
585
                        if (symname(sname)==0) /* name ok? */
586
                                illname(); /* no... */
587
                        if(findglb(sname)) /* already there? */
588
                                multidef(sname);
589
                        if (match("[")) {       /* array? */
590
                                if (typ==cport) error("port cannot be defined as an array");
591
                                k=needsub();    /* get size */
592
                                if(k)j=array;   /* !0=array */
593
                                else j=pointer; /* 0=ptr */
594
                        }
595
 
596
                        // check if the declared global has a default value 
597
                        if (match("=")) {
598
                                // check if variable type supports init 
599
                                if ((typ!=cchar) & (typ!=cint))
600
                                        error("variable type does not support init value");
601
 
602
                                // set the init pointer to the current init pointer 
603
                                iptr=inittbptr;
604
                                idx=0;
605
 
606
                                // new defined variable has a default init value 
607
                                // check if the variable is defined as string, list of values {} or a 
608
                                // single value
609
                                if (match("\"")) {
610
                                        // init value is defined as a string 
611
                                        // copy the string values to the init buffer 
612
                                        while (idx++ < k) {
613
                                                // check if new value is valid 
614
                                                if ((ch() != '"') & (ch() != 0))
615
                                                        inittbq[inittbptr++] = gch();
616
                                                else
617
                                                        inittbq[inittbptr++] = 0;
618
 
619
                                                // check that init buffer is full 
620
                                                if (inittbptr == initqsz) {
621
                                                        // clear the variable init pointer and print error message 
622
                                                        iptr=0xffff;
623
                                                        error("init buffer is full, variable will not be initialized");
624
                                                        // sign that init is done 
625
                                                        idx=k;
626
                                                }
627
                                        }
628
                                        // look for matching quote mark 
629
                                        if (match("\"")==0) {
630
                                                error("end of string expected");
631
                                        }
632
                                }
633
                                else if (match("{")) {
634
                                        // init value is defined as a list of values 
635
                                        // copy the list of values to the init buffer 
636
                                        while (idx++ < k) {
637
                                                // check if new value is valid 
638
                                                if ((ch() != '}') & (ch() != 0)) {
639
                                                        // make sure that the next value is a number 
640
                                                        if (!number(num) & !pstr(num))
641
                                                                error("could not find valid value in initialization list");
642
                                                }
643
                                                else
644
                                                        // use zero value as init 
645
                                                        num[0]=0;
646
 
647
                                                // save the values according to array type 
648
                                                if (typ==cint) {
649
                                                        inittbq[inittbptr++] = (char)(num[0]&255);
650
                                                        inittbq[inittbptr++] = (char)((num[0]>>8)&255);
651
                                                }
652
                                                else
653
                                                        inittbq[inittbptr++] = (char)(num[0]&255);
654
 
655
                                                // check that init buffer is full 
656
                                                if (inittbptr == initqsz) {
657
                                                        // clear the variable init pointer and print error message 
658
                                                        iptr=0xffff;
659
                                                        error("init buffer is full, variable will not be initialized");
660
                                                        // sign that init is done 
661
                                                        idx=k;
662
                                                }
663
                                                // remove comma if it is there 
664
                                                match(",");
665
                                        }
666
                                        // look for ending brackets 
667
                                        if (match("}")==0) {
668
                                                error("end of initialization list expected");
669
                                        }
670
                                }
671
                                else {
672
                                        // expecting a single input value 
673
                                        if (!number(num) & !pstr(num))
674
                                                error("could not find initialization value");
675
 
676
                                        // save the values according to variable type 
677
                                        if (typ==cint) {
678
                                                inittbq[inittbptr++] = (char)(num[0]&255);
679 67 motilito
                                                inittbq[inittbptr++] = (char)((num[0]>>8)&255);
680 65 motilito
                                        }
681
                                        else
682
                                                inittbq[inittbptr++] = (char)(num[0]&255);
683
                                        // update index 
684
                                        idx=1;
685
 
686
                                        // init to end of array is more than one 
687
                                        while (idx++ < k) {
688 67 motilito
                                                // fill the rest of the init list with zeros 
689 65 motilito
                                                if (typ==cint) {
690
                                                        inittbq[inittbptr++] = 0;
691
                                                        inittbq[inittbptr++] = 0;
692
                                                }
693
                                                else
694
                                                        inittbq[inittbptr++] = 0;
695
 
696
                                                // check that init buffer is full 
697
                                                if (inittbptr == initqsz) {
698
                                                        // clear the variable init pointer and print error message 
699
                                                        iptr=0xffff;
700
                                                        error("init buffer is full, variable will not be initialized");
701
                                                        // sign that init is done 
702
                                                        idx=k;
703
                                                }
704
                                        }
705
                                }
706
                        } else {
707
                                // no default value point init pointer to null 
708
                                iptr=0xffff;
709
                        }
710
                        // add symbol 
711
                        addglb(sname,j,typ,k,iptr);
712
                        break;
713
                }
714
                if (match(",")==0) return; /* more? */
715
        }
716
}
717
/*                                      */
718
/*      Declare local variables         */
719
/*      (i.e. define for use)           */
720
/*                                      */
721
/* works just like "declglb" but modifies machine stack */
722
/*      and adds symbol table entry with appropriate */
723
/*      stack offset to find it again                   */
724
declloc(typ)            /* typ is cchar or cint */
725
        int typ;
726
        {
727
        int k,j;char sname[namesize];
728
        while(1)
729
                {while(1)
730
                        {if(endst())return;
731
                        if(match("*"))
732
                                j=pointer;
733
                                else j=variable;
734
                        if (symname(sname)==0)
735
                                illname();
736
                        if(findloc(sname))
737
                                multidef(sname);
738
                        if (match("["))
739
                                {k=needsub();
740
                                if(k)
741
                                        {j=array;
742
                                        if(typ==cint)k=k+k;
743
                                        }
744
                                else
745
                                        {j=pointer;
746
                                        k=2;
747
                                        }
748
                                }
749
                        else
750
                                if((typ==cchar)
751
                                        &(j!=pointer))
752
                                        k=1;else k=2;
753
                        /* change machine stack */
754
                        Zsp=modstk(Zsp-k);
755
                        addloc(sname,j,typ,Zsp);
756
                        break;
757
                        }
758
                if (match(",")==0) return;
759
                }
760
        }
761
/*      >>>>>> start of cc2 <<<<<<<<    */
762
 
763
/*                                      */
764
/*      Get required array size         */
765
/*                                      */
766
/* invoked when declared variable is followed by "[" */
767
/*      this routine makes subscript the absolute */
768
/*      size of the array. */
769
needsub()
770
{
771
int num[1];
772
 
773
        if(match("]"))return 0;  /* null size */
774
        if (number(num)==0)      /* go after a number */
775
                {error("must be constant");     /* it isn't */
776
                num[0]=1;                /* so force one */
777
                }
778
        if (num[0]<0)
779
                {error("negative size illegal");
780
                num[0]=(-num[0]);
781
                }
782
        needbrack("]");         /* force single dimension */
783
        return num[0];           /* and return size */
784
}
785
//
786
// get array size function changed to get a port address 
787
//
788
portadr()
789
{
790
int num[1];
791
 
792
        if(match(")")) {
793
                error("port address value must be defined");
794
                return 0;        /* null size */
795
        }
796
        if (number(num)==0) {    /* go after a number */
797
                error("port address must be constant"); /* it isn't */
798
                num[0]=1;                /* so force one */
799
        }
800
        if (num[0]<0) {
801
                error("negative port address illegal");
802
                num[0]=(-num[0]);
803
        }
804
        needbrack(")");         /* force single dimension */
805
        return num[0];           /* and return size */
806
}
807
 
808
/*                                      */
809
/*      Begin a function                */
810
/*                                      */
811
/* Called from "parse" this routine tries to make a function */
812
/*      out of what follows.    */
813
newfunc()
814
        {
815
        char n[namesize];       /* ptr => currfn,  gtf 7/16/80 */
816
        if (symname(n)==0)
817
                {error("illegal function or declaration");
818
                kill(); /* invalidate line */
819
                return;
820
                }
821
        fnstart=lineno;         /* remember where fn began      gtf 7/2/80 */
822
        infunc=1;               /* note, in function now.       gtf 7/16/80 */
823
        if(currfn=findglb(n))   /* already in symbol table ? */
824
                {if(currfn[ident]!=function)multidef(n);
825
                        /* already variable by that name */
826
                else if(currfn[offset]==function)multidef(n);
827
                        /* already function by that name */
828
                else currfn[offset]=function;
829
                        /* otherwise we have what was earlier*/
830
                        /*  assumed to be a function */
831
                }
832
        /* if not in table, define as a function now */
833
        else currfn=addglb(n,function,cint,function,-1);
834
 
835
        toconsole();                                    /* gtf 7/16/80 */
836
        outstr("====== "); outstr(currfn+name); outstr("()"); nl();
837
        tofile();
838
 
839
        /* we had better see open paren for args... */
840
        if(match("(")==0)error("missing open paren");
841
        outname(n);col();nl();  /* print function name */
842
        argstk=0;                /* init arg count */
843
        while(match(")")==0)     /* then count args */
844
                /* any legal name bumps arg count */
845
                {if(symname(n))argstk=argstk+2;
846
                else{error("illegal argument name");junk();}
847
                blanks();
848
                /* if not closing paren, should be comma */
849
                if(streq(line+lptr,")")==0)
850
                        {if(match(",")==0)
851
                        error("expected comma");
852
                        }
853
                if(endst())break;
854
                }
855
        locptr=startloc;        /* "clear" local symbol table*/
856
        Zsp=0;                   /* preset stack ptr */
857
        while(argstk)
858
                /* now let user declare what types of things */
859
                /*      those arguments were */
860
                {if(amatch("char",4)){getarg(cchar);ns();}
861
                else if(amatch("int",3)){getarg(cint);ns();}
862
                else{error("wrong number args");break;}
863
                }
864
        if(statement()!=streturn) /* do a statement, but if */
865
                                /* it's a return, skip */
866
                                /* cleaning up the stack */
867
                {modstk(0);
868
                zret();
869
                }
870
        Zsp=0;                   /* reset stack ptr again */
871
        locptr=startloc;        /* deallocate all locals */
872
        infunc=0;                /* not in fn. any more          gtf 7/2/80 */
873
        }
874
/*                                      */
875
/*      Declare argument types          */
876
/*                                      */
877
/* called from "newfunc" this routine adds an entry in the */
878
/*      local symbol table for each named argument */
879
getarg(t)               /* t = cchar or cint */
880
        int t;
881
        {
882
        char n[namesize],c;int j;
883
        while(1)
884
                {if(argstk==0)return;    /* no more args */
885
                if(match("*"))j=pointer;
886
                        else j=variable;
887
                if(symname(n)==0) illname();
888
                if(findloc(n))multidef(n);
889
                if(match("["))  /* pointer ? */
890
                /* it is a pointer, so skip all */
891
                /* stuff between "[]" */
892
                        {while(inbyte()!=']')
893
                                if(endst())break;
894
                        j=pointer;
895
                        /* add entry as pointer */
896
                        }
897
                addloc(n,j,t,argstk);
898
                argstk=argstk-2;        /* cnt down */
899
                if(endst())return;
900
                if(match(",")==0)error("expected comma");
901
                }
902
        }
903
/*                                      */
904
/*      Statement parser                */
905
/*                                      */
906
/* called whenever syntax requires      */
907
/*      a statement.                     */
908
/*  this routine performs that statement */
909
/*  and returns a number telling which one */
910
statement()
911
{
912
        /* NOTE (RDK) --- On DOS there is no CPM function so just try */
913
        /* commenting it out for the first test compilation to see if */
914
        /* the compiler basic framework works OK in the DOS environment */
915
        /* if(cpm(11,0) & 1)    /* check for ctrl-C gtf 7/17/80 */
916
                /* if(getchar()==3) */
917
                        /* zabort(); */
918
 
919
        if ((ch()==0) & (eof)) return;
920
        else if(amatch("char",4))
921
                {declloc(cchar);ns();}
922
        else if(amatch("int",3))
923
                {declloc(cint);ns();}
924
        else if(match("{"))compound();
925
        else if(amatch("if",2))
926
                {doif();lastst=stif;}
927
        else if(amatch("while",5))
928
                {dowhile();lastst=stwhile;}
929
        else if(amatch("return",6))
930
                {doreturn();ns();lastst=streturn;}
931
        else if(amatch("break",5))
932
                {dobreak();ns();lastst=stbreak;}
933
        else if(amatch("continue",8))
934
                {docont();ns();lastst=stcont;}
935
        else if(match(";"));
936
        else if(match("#asm"))
937
                {doasm();lastst=stasm;}
938
        /* if nothing else, assume it's an expression */
939
        else{expression();ns();lastst=stexp;}
940
        return lastst;
941
}
942
/*                                      */
943
/*      Semicolon enforcer              */
944
/*                                      */
945
/* called whenever syntax requires a semicolon */
946
ns()    {if(match(";")==0)error("missing semicolon");}
947
/*                                      */
948
/*      Compound statement              */
949
/*                                      */
950
/* allow any number of statements to fall between "{}" */
951
compound()
952
        {
953
        ++ncmp;         /* new level open */
954
        while (match("}")==0) statement(); /* do one */
955
        --ncmp;         /* close current level */
956
        }
957
/*                                      */
958
/*              "if" statement          */
959
/*                                      */
960
doif()
961
        {
962
        int flev,fsp,flab1,flab2;
963
        flev=locptr;    /* record current local level */
964
        fsp=Zsp;                /* record current stk ptr */
965
        flab1=getlabel(); /* get label for false branch */
966
        test(flab1);    /* get expression, and branch false */
967
        statement();    /* if true, do a statement */
968
        Zsp=modstk(fsp);        /* then clean up the stack */
969
        locptr=flev;    /* and deallocate any locals */
970
        if (amatch("else",4)==0) /* if...else ? */
971
                /* simple "if"...print false label */
972
                {printlabel(flab1);col();nl();
973
                return;         /* and exit */
974
                }
975
        /* an "if...else" statement. */
976
        jump(flab2=getlabel()); /* jump around false code */
977
        printlabel(flab1);col();nl();   /* print false label */
978
        statement();            /* and do "else" clause */
979
        Zsp=modstk(fsp);                /* then clean up stk ptr */
980
        locptr=flev;            /* and deallocate locals */
981
        printlabel(flab2);col();nl();   /* print true label */
982
        }
983
/*                                      */
984
/*      "while" statement               */
985
/*                                      */
986
dowhile()
987
        {
988
        int wq[4];              /* allocate local queue */
989
        wq[wqsym]=locptr;       /* record local level */
990
        wq[wqsp]=Zsp;           /* and stk ptr */
991
        wq[wqloop]=getlabel();  /* and looping label */
992
        wq[wqlab]=getlabel();   /* and exit label */
993
        addwhile(wq);           /* add entry to queue */
994
                                /* (for "break" statement) */
995
        printlabel(wq[wqloop]);col();nl(); /* loop label */
996
        test(wq[wqlab]);        /* see if true */
997
        statement();            /* if so, do a statement */
998
        Zsp = modstk(wq[wqsp]); /* zap local vars: 9/25/80 gtf */
999
        jump(wq[wqloop]);       /* loop to label */
1000
        printlabel(wq[wqlab]);col();nl(); /* exit label */
1001
        locptr=wq[wqsym];       /* deallocate locals */
1002
        delwhile();             /* delete queue entry */
1003
        }
1004
/*                                      */
1005
/*      "return" statement              */
1006
/*                                      */
1007
doreturn()
1008
        {
1009
        /* if not end of statement, get an expression */
1010
        if(endst()==0)expression();
1011
        modstk(0);       /* clean up stk */
1012
        zret();         /* and exit function */
1013
        }
1014
/*                                      */
1015
/*      "break" statement               */
1016
/*                                      */
1017
dobreak()
1018
        {
1019
        int *ptr;
1020
        /* see if any "whiles" are open */
1021
        if ((ptr=readwhile())==0) return;        /* no */
1022
        modstk((ptr[wqsp]));    /* else clean up stk ptr */
1023
        jump(ptr[wqlab]);       /* jump to exit label */
1024
        }
1025
/*                                      */
1026
/*      "continue" statement            */
1027
/*                                      */
1028
docont()
1029
        {
1030
        int *ptr;
1031
        /* see if any "whiles" are open */
1032
        if ((ptr=readwhile())==0) return;        /* no */
1033
        modstk((ptr[wqsp]));    /* else clean up stk ptr */
1034
        jump(ptr[wqloop]);      /* jump to loop label */
1035
        }
1036
/*                                      */
1037
/*      "asm" pseudo-statement          */
1038
/*                                      */
1039
/* enters mode where assembly language statement are */
1040
/*      passed intact through parser    */
1041
doasm()
1042
{
1043
        cmode=0;         /* mark mode as "asm" */
1044
        while (1) {
1045
                finline();      /* get and print lines */
1046
                if (match("#endasm")) break;    /* until... */
1047
                if(eof)break;
1048
                outstr(line);
1049
                nl();
1050
        }
1051
        kill();         /* invalidate line */
1052
        cmode=1;                /* then back to parse level */
1053
}
1054
/*      >>>>> start of cc3 <<<<<<<<<    */
1055
 
1056
/*                                      */
1057
/*      Perform a function call         */
1058
/*                                      */
1059
/* called from heir11, this routine will either call */
1060
/*      the named function, or if the supplied ptr is */
1061
/*      zero, will call the contents of HL              */
1062
callfunction(ptr)
1063
        char *ptr;      /* symbol table entry (or 0) */
1064
{       int nargs;
1065
        nargs=0;
1066
        blanks();       /* already saw open paren */
1067
        if(ptr==0)zpush();       /* calling HL */
1068
        while(streq(line+lptr,")")==0)
1069
                {if(endst())break;
1070
                expression();   /* get an argument */
1071
                if(ptr==0)swapstk(); /* don't push addr */
1072
                zpush();        /* push argument */
1073
                nargs=nargs+2;  /* count args*2 */
1074
                if (match(",")==0) break;
1075
                }
1076
        needbrack(")");
1077
        if(ptr)zcall(ptr);
1078
        else callstk();
1079
        Zsp=modstk(Zsp+nargs);  /* clean up arguments */
1080
}
1081
junk()
1082
{       if(an(inbyte()))
1083
                while(an(ch()))gch();
1084
        else while(an(ch())==0)
1085
                {if(ch()==0)break;
1086
                gch();
1087
                }
1088
        blanks();
1089
}
1090
endst()
1091
{       blanks();
1092
        return ((streq(line+lptr,";")|(ch()==0)));
1093
}
1094
illname()
1095
{       error("illegal symbol name");junk();}
1096
multidef(sname)
1097
        char *sname;
1098
{       error("already defined");
1099
        comment();
1100
        outstr(sname);nl();
1101
}
1102
needbrack(str)
1103
        char *str;
1104
{
1105
        if (match(str)==0) {
1106
                error("missing bracket");
1107
                comment();outstr(str);nl();
1108
        }
1109
}
1110
needlval()
1111
{       error("must be lvalue");
1112
}
1113
findglb(sname)
1114
        char *sname;
1115
{       char *ptr;
1116
        ptr=startglb;
1117
        while(ptr!=glbptr) {
1118
                if (astreq(sname,ptr,namemax)) return ptr;
1119
                ptr=ptr+symsiz;
1120
        }
1121
        return 0;
1122
}
1123
findloc(sname)
1124
        char *sname;
1125
{       char *ptr;
1126
        ptr=startloc;
1127
        while (ptr!=locptr) {
1128
                if(astreq(sname,ptr,namemax))return ptr;
1129
                ptr=ptr+symsiz;
1130
        }
1131
        return 0;
1132
}
1133
addglb(sname,id,typ,value,iptr)
1134
        char *sname,id,typ;
1135
        int value,iptr;
1136
{       char *ptr;
1137
        if(cptr=findglb(sname))return cptr;
1138
        if(glbptr>=endglb)
1139
                {error("global symbol table overflow");
1140
                return 0;
1141
                }
1142
        cptr=ptr=glbptr;
1143
        while (an(*ptr++ = *sname++));  /* copy name */
1144
        cptr[ident]=id;
1145
        cptr[type]=typ;
1146
        cptr[storage]=statik;
1147
        cptr[offset]=value;
1148
        cptr[offset+1]=value>>8;
1149
        cptr[initptr]=iptr&255;
1150
        cptr[initptr+1]=iptr>>8;
1151
        glbptr=glbptr+symsiz;
1152
        return cptr;
1153
}
1154
addloc(sname,id,typ,value)
1155
        char *sname,id,typ;
1156
        int value;
1157
{       char *ptr;
1158
        if(cptr=findloc(sname))return cptr;
1159
        if(locptr>=endloc)
1160
                {error("local symbol table overflow");
1161
                return 0;
1162
                }
1163
        cptr=ptr=locptr;
1164
        while(an(*ptr++ = *sname++));   /* copy name */
1165
        cptr[ident]=id;
1166
        cptr[type]=typ;
1167
        cptr[storage]=stkloc;
1168
        cptr[offset]=value;
1169
        cptr[offset+1]=value>>8;
1170
        locptr=locptr+symsiz;
1171
        return cptr;
1172
}
1173
/* Test if next input string is legal symbol name */
1174
symname(sname)
1175
        char *sname;
1176
{       int k;char c;
1177
        blanks();
1178
        if(alpha(ch())==0)return 0;
1179
        k=0;
1180
        while(an(ch()))sname[k++]=gch();
1181
        sname[k]=0;
1182
        return 1;
1183
        }
1184
/* Return next avail internal label number */
1185
getlabel()
1186
{       return(++nxtlab);
1187
}
1188
/* Print specified number as label */
1189
printlabel(label)
1190
        int label;
1191
{       outasm("cc");
1192
        outdec(label);
1193
}
1194
/* Test if given character is alpha */
1195
alpha(c)
1196
        char c;
1197
{       c=c&127;
1198
        return(((c>='a')&(c<='z'))|
1199
                ((c>='A')&(c<='Z'))|
1200
                (c=='_'));
1201
}
1202
// Test if given character is numeric 
1203
numeric(c)
1204
        char c;
1205
{       c=c&127;
1206
        return ((c>='0')&(c<='9'));
1207
}
1208
// Test if given character is hexadecimal 
1209
hexnum(c)
1210
        char c;
1211
{       c=c&127;
1212
        return (((c>='0')&(c<='9')) | ((c>='a')&(c<='f')) | ((c>='A')&(c<='F')));
1213
}
1214
/* Test if given character is alphanumeric */
1215
an(c)
1216
        char c;
1217
{       return((alpha(c))|(numeric(c)));
1218
}
1219
/* Print a carriage return and a string only to console */
1220
pl(str)
1221
        char *str;
1222
{       int k;
1223
        k=0;
1224
        putchar(eol);
1225
        while(str[k])putchar(str[k++]);
1226
}
1227
addwhile(ptr)
1228
        int ptr[];
1229
 {
1230
        int k;
1231
        if (wqptr==wqmax)
1232
                {error("too many active whiles");return;}
1233
        k=0;
1234
        while (k<wqsiz)
1235
                {*wqptr++ = ptr[k++];}
1236
}
1237
delwhile()
1238
        {if(readwhile()) wqptr=wqptr-wqsiz;
1239
        }
1240
readwhile()
1241
 {
1242
        if (wqptr==wq){error("no active whiles");return 0;}
1243
        else return (wqptr-wqsiz);
1244
 }
1245
ch()
1246
{       return(line[lptr]&127);
1247
}
1248
nch()
1249
{       if(ch()==0)return 0;
1250
                else return(line[lptr+1]&127);
1251
}
1252
gch()
1253
{       if(ch()==0)return 0;
1254
                else return(line[lptr++]&127);
1255
}
1256
kill()
1257
{       lptr=0;
1258
        line[lptr]=0;
1259
}
1260
inbyte()
1261
{
1262
        while(ch()==0)
1263
                {if (eof) return 0;
1264
                finline();
1265
                preprocess();
1266
                }
1267
        return gch();
1268
}
1269
inchar()
1270
{
1271
        if(ch()==0)finline();
1272
        if(eof)return 0;
1273
        return(gch());
1274
}
1275
finline()
1276
{
1277
        int k,unit;
1278
        while(1)
1279
                {if (input==0)openin();
1280
                if(eof)return;
1281
                if((unit=input2)==0)unit=input;
1282
                kill();
1283
                while((k=getc(unit))>0)
1284
                        {if((k==eol)|(lptr>=linemax))break;
1285
                        line[lptr++]=k;
1286
                        }
1287
                line[lptr]=0;    /* append null */
1288
                lineno++;       /* read one more line           gtf 7/2/80 */
1289
                if(k<=0)
1290
                        {fclose(unit);
1291
                        if(input2)endinclude();         /* gtf 7/16/80 */
1292
                                else input=0;
1293
                        }
1294
                if(lptr)
1295
                        {if((ctext)&(cmode))
1296
                                {comment();
1297
                                outstr(line);
1298
                                nl();
1299
                                }
1300
                        lptr=0;
1301
                        return;
1302
                        }
1303
                }
1304
}
1305
/*      >>>>>> start of cc4 <<<<<<<     */
1306
 
1307
keepch(c)
1308
        char c;
1309
{       mline[mptr]=c;
1310
        if(mptr<mpmax)mptr++;
1311
        return c;
1312
}
1313
preprocess()
1314
{       int k;
1315
        char c,sname[namesize];
1316
        if(cmode==0)return;
1317
        mptr=lptr=0;
1318
        while(ch())
1319
                {if((ch()==' ')|(ch()==9))
1320
                        {keepch(' ');
1321
                        while((ch()==' ')|
1322
                                (ch()==9))
1323
                                gch();
1324
                        }
1325
                else if(ch()=='"')
1326
                        {keepch(ch());
1327
                        gch();
1328
                        while(ch()!='"')
1329
                                {if(ch()==0)
1330
                                  {error("missing quote");
1331
                                  break;
1332
                                  }
1333
                                keepch(gch());
1334
                                }
1335
                        gch();
1336
                        keepch('"');
1337
                        }
1338
                else if(ch()==39)
1339
                        {keepch(39);
1340
                        gch();
1341
                        while(ch()!=39)
1342
                                {if(ch()==0)
1343
                                  {error("missing apostrophe");
1344
                                  break;
1345
                                  }
1346
                                keepch(gch());
1347
                                }
1348
                        gch();
1349
                        keepch(39);
1350
                        }
1351
                else if((ch()=='/')&(nch()=='/')) {
1352
                        // delete the entire line 
1353
                        kill();
1354
                }
1355
                else if((ch()=='/')&(nch()=='*')) {
1356
                        inchar();inchar();
1357
                        while (((ch()=='*') & (nch()=='/'))==0) {
1358
                                if(ch()==0)finline();
1359
                                        else inchar();
1360
                                if(eof)break;
1361
                        }
1362
                        inchar();inchar();
1363
                }
1364
                else if(alpha(ch()))    /* from an(): 9/22/80 gtf */
1365
                        {k=0;
1366
                        while(an(ch()))
1367
                                {if(k<namemax)sname[k++]=ch();
1368
                                gch();
1369
                                }
1370
                        sname[k]=0;
1371
                        if(k=findmac(sname))
1372
                                while(c=macq[k++])
1373
                                        keepch(c);
1374
                        else
1375
                                {k=0;
1376
                                while(c=sname[k++])
1377
                                        keepch(c);
1378
                                }
1379
                        }
1380
                else keepch(gch());
1381
                }
1382
        keepch(0);
1383
        if(mptr>=mpmax)error("line too long");
1384
        lptr=mptr=0;
1385
        while(line[lptr++]=mline[mptr++]);
1386
        lptr=0;
1387
        }
1388
addmac()
1389
{
1390
char sname[namesize];
1391
int k;
1392
 
1393
        if (symname(sname)==0) {
1394
                illname();
1395
                kill();
1396
                return;
1397
        }
1398
        k=0;
1399
        while (putmac(sname[k++]));
1400
        while (ch()==' ' | ch()==9) gch();
1401
        while (putmac(gch()));
1402
        if (macptr>=macmax) error("macro table full");
1403
}
1404
putmac(c)
1405
        char c;
1406
{
1407
        macq[macptr]=c;
1408
        if(macptr<macmax)macptr++;
1409
        return c;
1410
}
1411
findmac(sname)
1412
        char *sname;
1413
{       int k;
1414
        k=0;
1415
        while (k<macptr) {
1416
                if (astreq(sname, macq+k, namemax)) {
1417
                        while(macq[k++]);
1418
                        return k;
1419
                        }
1420
                while(macq[k++]);
1421
                while(macq[k++]);
1422
        }
1423
        return 0;
1424
}
1425
/* direct output to console             gtf 7/16/80 */
1426
toconsole()
1427
{
1428
        saveout = output;
1429
        output = 0;
1430
/* end toconsole */}
1431
 
1432
/* direct output back to file           gtf 7/16/80 */
1433
tofile()
1434
{
1435
        if(saveout)
1436
                output = saveout;
1437
        saveout = 0;
1438
/* end tofile */}
1439
 
1440
outbyte(c)
1441
        char c;
1442
{
1443
        if(c==0)return 0;
1444
        if(output)
1445
                {if((putc(c,output))<=0)
1446
                        {closeout();
1447
                        error("Output file error");
1448
                        zabort();                       /* gtf 7/17/80 */
1449
                        }
1450
                }
1451
        else putchar(c);
1452
        return c;
1453
}
1454
outstr(ptr)
1455
        char ptr[];
1456
 {
1457
        int k;
1458
        k=0;
1459
        while(outbyte(ptr[k++]));
1460
 }
1461
 
1462
/* write text destined for the assembler to read */
1463
/* (i.e. stuff not in comments)                 */
1464
/*  gtf  6/26/80 */
1465
outasm(ptr)
1466
char *ptr;
1467
{
1468
        while(outbyte(lower(*ptr++)));
1469
/* end outasm */}
1470
 
1471
nl()
1472
        {outbyte(eol);}
1473
tab()
1474
        {outbyte(9);}
1475
col()
1476
        {outbyte(58);}
1477
bell()                          /* gtf 7/16/80 */
1478
        {outbyte(7);}
1479
/*                              replaced 7/2/80 gtf
1480
 * error(ptr)
1481
 *      char ptr[];
1482
 * {
1483
 *      int k;
1484
 *      comment();outstr(line);nl();comment();
1485
 *      k=0;
1486
 *      while(k<lptr)
1487
 *              {if(line[k]==9) tab();
1488
 *                      else outbyte(' ');
1489
 *              ++k;
1490
 *              }
1491
 *      outbyte('^');
1492
 *      nl();comment();outstr("******  ");
1493
 *      outstr(ptr);
1494
 *      outstr("  ******");
1495
 *      nl();
1496
 *      ++errcnt;
1497
 * }
1498
 */
1499
 
1500
error(ptr)
1501
char ptr[];
1502
{       int k;
1503
        char junk[81];
1504
 
1505
        toconsole();
1506
        bell();
1507
        outstr("Line "); outdec(lineno); outstr(", ");
1508
        if(infunc==0)
1509
                outbyte('(');
1510
        if(currfn==NULL)
1511
                outstr("start of file");
1512
        else    outstr(currfn+name);
1513
        if(infunc==0)
1514
                outbyte(')');
1515
        outstr(" + ");
1516
        outdec(lineno-fnstart);
1517
        outstr(": ");  outstr(ptr);  nl();
1518
 
1519
        outstr(line); nl();
1520
 
1521
        k=0;     /* skip to error position */
1522
        while(k<lptr){
1523
                if(line[k++]==9)
1524
                        tab();
1525
                else    outbyte(' ');
1526
                }
1527
        outbyte('^');  nl();
1528
        ++errcnt;
1529
 
1530
        if(errstop){
1531
                pl("Continue (Y,n,g) ? ");
1532
                gets(junk);
1533
                k=junk[0];
1534
                if((k=='N') | (k=='n'))
1535
                        zabort();
1536
                if((k=='G') | (k=='g'))
1537
                        errstop=0;
1538
                }
1539
        tofile();
1540
/* end error */}
1541
 
1542
ol(ptr)
1543
        char ptr[];
1544
{
1545
        ot(ptr);
1546
        nl();
1547
}
1548
ot(ptr)
1549
        char ptr[];
1550
{
1551
        tab();
1552
        outasm(ptr);
1553
}
1554
streq(str1,str2)
1555
        char str1[],str2[];
1556
{
1557
int k;
1558
 
1559
        k=0;
1560
        while (str2[k])
1561
                {if ((str1[k])!=(str2[k])) return 0;
1562
                k++;
1563
                }
1564
        return k;
1565
}
1566
astreq(str1,str2,len)
1567
        char str1[],str2[];int len;
1568
{
1569
int k;
1570
 
1571
        k=0;
1572
        while (k<len) {
1573
                if ((str1[k])!=(str2[k]))break;
1574
                if(str1[k]==0)break;
1575
                if(str2[k]==0)break;
1576
                k++;
1577
        }
1578
        if (an(str1[k]))return 0;
1579
        if (an(str2[k]))return 0;
1580
        return k;
1581
}
1582
match(lit)
1583
        char *lit;
1584
{
1585
        int k;
1586
        blanks();
1587
        if (k=streq(line+lptr,lit)) {
1588
                lptr=lptr+k;
1589
                return 1;
1590
        }
1591
        return 0;
1592
}
1593
amatch(lit,len)
1594
        char *lit;int len;
1595
 {
1596
        int k;
1597
        blanks();
1598
        if (k=astreq(line+lptr,lit,len))
1599
                {lptr=lptr+k;
1600
                while(an(ch())) inbyte();
1601
                return 1;
1602
                }
1603
        return 0;
1604
 }
1605
blanks()
1606
{
1607
        while (1) {
1608
                while (ch()==0) {
1609
                        finline();
1610
                        preprocess();
1611
                        if(eof)break;
1612
                }
1613
                if (ch()==' ') gch();
1614
                else if (ch()==9) gch();
1615
                else return;
1616
        }
1617
}
1618
/* output a decimal number - rewritten 4/1/81 gtf */
1619
outdec(n)
1620
int n;
1621
{
1622
        if(n<0)
1623
                outbyte('-');
1624
        else    n = -n;
1625
        outint(n);
1626
/* end outdec */}
1627
 
1628
outint(n)       /* added 4/1/81 */
1629
int n;
1630
{       int q;
1631
 
1632
        q = n/10;
1633
        if(q) outint(q);
1634
        outbyte('0'-(n-q*10));
1635
/* end outint */}
1636
 
1637
/* return the length of a string */
1638
/* gtf 4/8/80 */
1639
strlen(s)
1640
char *s;
1641
{       char *t;
1642
 
1643
        t = s;
1644
        while(*s) s++;
1645
        return(s-t);
1646
/* end strlen */}
1647
 
1648
/* convert lower case to upper */
1649
/* gtf 6/26/80 */
1650
raise(c)
1651
char c;
1652
{
1653
        if((c>='a') & (c<='z'))
1654
                c = c - 'a' + 'A';
1655
        return(c);
1656
/* end raise */}
1657
 
1658
/* convert upper case to lower */
1659
/* ml 28/2/2012 */
1660
lower(c)
1661
char c;
1662
{
1663
        if((c>='A') & (c<='Z'))
1664
                c = c - 'A' + 'a';
1665
        return(c);
1666
/* end raise */}
1667
 
1668
/* ------------------------------------------------------------- */
1669
 
1670
/*      >>>>>>> start of cc5 <<<<<<<    */
1671
 
1672
/* as of 5/5/81 rj */
1673
 
1674
expression()
1675
{
1676
        int lval[2];
1677
        if(heir1(lval))rvalue(lval);
1678
}
1679
heir1(lval)
1680
        int lval[];
1681
{
1682
        int k,lval2[2];
1683
        k=heir2(lval);
1684
        if (match("="))
1685
                {if(k==0){needlval();return 0;}
1686
                if (lval[1])zpush();
1687
                if(heir1(lval2))rvalue(lval2);
1688
                store(lval);
1689
                return 0;
1690
                }
1691
        else return k;
1692
}
1693
heir2(lval)
1694
        int lval[];
1695
{       int k,lval2[2];
1696
        k=heir3(lval);
1697
        blanks();
1698
        if(ch()!='|')return k;
1699
        if(k)rvalue(lval);
1700
        while(1)
1701
                {if (match("|"))
1702
                        {zpush();
1703
                        if(heir3(lval2)) rvalue(lval2);
1704
                        zpop();
1705
                        zor();
1706
                        }
1707
                else return 0;
1708
                }
1709
}
1710
heir3(lval)
1711
        int lval[];
1712
{       int k,lval2[2];
1713
        k=heir4(lval);
1714
        blanks();
1715
        if(ch()!='^')return k;
1716
        if(k)rvalue(lval);
1717
        while(1)
1718
                {if (match("^"))
1719
                        {zpush();
1720
                        if(heir4(lval2))rvalue(lval2);
1721
                        zpop();
1722
                        zxor();
1723
                        }
1724
                else return 0;
1725
                }
1726
}
1727
heir4(lval)
1728
        int lval[];
1729
{       int k,lval2[2];
1730
        k=heir5(lval);
1731
        blanks();
1732
        if(ch()!='&')return k;
1733
        if(k)rvalue(lval);
1734
        while(1)
1735
                {if (match("&"))
1736
                        {zpush();
1737
                        if(heir5(lval2))rvalue(lval2);
1738
                        zpop();
1739
                        zand();
1740
                        }
1741
                else return 0;
1742
                }
1743
}
1744
heir5(lval)
1745
        int lval[];
1746
{
1747
        int k,lval2[2];
1748
        k=heir6(lval);
1749
        blanks();
1750
        if((streq(line+lptr,"==")==0)&
1751
                (streq(line+lptr,"!=")==0))return k;
1752
        if(k)rvalue(lval);
1753
        while(1)
1754
                {if (match("=="))
1755
                        {zpush();
1756
                        if(heir6(lval2))rvalue(lval2);
1757
                        zpop();
1758
                        zeq();
1759
                        }
1760
                else if (match("!="))
1761
                        {zpush();
1762
                        if(heir6(lval2))rvalue(lval2);
1763
                        zpop();
1764
                        zne();
1765
                        }
1766
                else return 0;
1767
                }
1768
}
1769
heir6(lval)
1770
        int lval[];
1771
{
1772
        int k,lval2[2];
1773
        k=heir7(lval);
1774
        blanks();
1775
        if((streq(line+lptr,"<")==0)&
1776
                (streq(line+lptr,">")==0)&
1777
                (streq(line+lptr,"<=")==0)&
1778
                (streq(line+lptr,">=")==0))return k;
1779
                if(streq(line+lptr,">>"))return k;
1780
                if(streq(line+lptr,"<<"))return k;
1781
        if(k)rvalue(lval);
1782
        while(1)
1783
                {if (match("<="))
1784
                        {zpush();
1785
                        if(heir7(lval2))rvalue(lval2);
1786
                        zpop();
1787
                        if(cptr=lval[0])
1788
                                if(cptr[ident]==pointer)
1789
                                {ule();
1790
                                continue;
1791
                                }
1792
                        if(cptr=lval2[0])
1793
                                if(cptr[ident]==pointer)
1794
                                {ule();
1795
                                continue;
1796
                                }
1797
                        zle();
1798
                        }
1799
                else if (match(">="))
1800
                        {zpush();
1801
                        if(heir7(lval2))rvalue(lval2);
1802
                        zpop();
1803
                        if(cptr=lval[0])
1804
                                if(cptr[ident]==pointer)
1805
                                {uge();
1806
                                continue;
1807
                                }
1808
                        if(cptr=lval2[0])
1809
                                if(cptr[ident]==pointer)
1810
                                {uge();
1811
                                continue;
1812
                                }
1813
                        zge();
1814
                        }
1815
                else if((streq(line+lptr,"<"))&
1816
                        (streq(line+lptr,"<<")==0))
1817
                        {inbyte();
1818
                        zpush();
1819
                        if(heir7(lval2))rvalue(lval2);
1820
                        zpop();
1821
                        if(cptr=lval[0])
1822
                                if(cptr[ident]==pointer)
1823
                                {ult();
1824
                                continue;
1825
                                }
1826
                        if(cptr=lval2[0])
1827
                                if(cptr[ident]==pointer)
1828
                                {ult();
1829
                                continue;
1830
                                }
1831
                        zlt();
1832
                        }
1833
                else if((streq(line+lptr,">"))&
1834
                        (streq(line+lptr,">>")==0))
1835
                        {inbyte();
1836
                        zpush();
1837
                        if(heir7(lval2))rvalue(lval2);
1838
                        zpop();
1839
                        if(cptr=lval[0])
1840
                                if(cptr[ident]==pointer)
1841
                                {ugt();
1842
                                continue;
1843
                                }
1844
                        if(cptr=lval2[0])
1845
                                if(cptr[ident]==pointer)
1846
                                {ugt();
1847
                                continue;
1848
                                }
1849
                        zgt();
1850
                        }
1851
                else return 0;
1852
                }
1853
}
1854
/*      >>>>>> start of cc6 <<<<<<      */
1855
 
1856
heir7(lval)
1857
        int lval[];
1858
{
1859
        int k,lval2[2];
1860
        k=heir8(lval);
1861
        blanks();
1862
        if((streq(line+lptr,">>")==0)&
1863
                (streq(line+lptr,"<<")==0))return k;
1864
        if(k)rvalue(lval);
1865
        while(1)
1866
                {if (match(">>"))
1867
                        {zpush();
1868
                        if(heir8(lval2))rvalue(lval2);
1869
                        zpop();
1870
                        asr();
1871
                        }
1872
                else if (match("<<"))
1873
                        {zpush();
1874
                        if(heir8(lval2))rvalue(lval2);
1875
                        zpop();
1876
                        asl();
1877
                        }
1878
                else return 0;
1879
                }
1880
}
1881
heir8(lval)
1882
        int lval[];
1883
{
1884
        int k,lval2[2];
1885
        k=heir9(lval);
1886
        blanks();
1887
        if((ch()!='+')&(ch()!='-'))return k;
1888
        if(k)rvalue(lval);
1889
        while(1)
1890
                {if (match("+"))
1891
                        {zpush();
1892
                        if(heir9(lval2))rvalue(lval2);
1893
                        if(cptr=lval[0])
1894
                                if((cptr[ident]==pointer)&
1895
                                (cptr[type]==cint))
1896
                                doublereg();
1897
                        zpop();
1898
                        zadd();
1899
                        }
1900
                else if (match("-"))
1901
                        {zpush();
1902
                        if(heir9(lval2))rvalue(lval2);
1903
                        if(cptr=lval[0])
1904
                                if((cptr[ident]==pointer)&
1905
                                (cptr[type]==cint))
1906
                                doublereg();
1907
                        zpop();
1908
                        zsub();
1909
                        }
1910
                else return 0;
1911
                }
1912
}
1913
heir9(lval)
1914
        int lval[];
1915
{
1916
        int k,lval2[2];
1917
        k=heir10(lval);
1918
        blanks();
1919
        if((ch()!='*')&(ch()!='/')&
1920
                (ch()!='%'))return k;
1921
        if(k)rvalue(lval);
1922
        while(1)
1923
                {if (match("*"))
1924
                        {zpush();
1925
                        if(heir9(lval2))rvalue(lval2);
1926
                        zpop();
1927
                        mult();
1928
                        }
1929
                else if (match("/"))
1930
                        {zpush();
1931
                        if(heir10(lval2))rvalue(lval2);
1932
                        zpop();
1933
                        div();
1934
                        }
1935
                else if (match("%"))
1936
                        {zpush();
1937
                        if(heir10(lval2))rvalue(lval2);
1938
                        zpop();
1939
                        zmod();
1940
                        }
1941
                else return 0;
1942
                }
1943
}
1944
heir10(lval)
1945
        int lval[];
1946
{
1947
        int k;
1948
        char *ptr;
1949
        if(match("++"))
1950
                {if((k=heir10(lval))==0)
1951
                        {needlval();
1952
                        return 0;
1953
                        }
1954
                if(lval[1])zpush();
1955
                rvalue(lval);
1956
                inc();
1957
                ptr=lval[0];
1958
                if((ptr[ident]==pointer)&
1959
                        (ptr[type]==cint))
1960
                                inc();
1961
                store(lval);
1962
                return 0;
1963
                }
1964
        else if(match("--"))
1965
                {if((k=heir10(lval))==0)
1966
                        {needlval();
1967
                        return 0;
1968
                        }
1969
                if(lval[1])zpush();
1970
                rvalue(lval);
1971
                dec();
1972
                ptr=lval[0];
1973
                if((ptr[ident]==pointer)&
1974
                        (ptr[type]==cint))
1975
                                dec();
1976
                store(lval);
1977
                return 0;
1978
                }
1979
        else if (match("-"))
1980
                {k=heir10(lval);
1981
                if (k) rvalue(lval);
1982
                neg();
1983
                return 0;
1984
                }
1985
        else if(match("*"))
1986
                {k=heir10(lval);
1987
                if(k)rvalue(lval);
1988
                lval[1]=cint;
1989
                if(ptr=lval[0])lval[1]=ptr[type];
1990
                lval[0]=0;
1991
                return 1;
1992
                }
1993
        else if(match("&"))
1994
                {k=heir10(lval);
1995
                if(k==0)
1996
                        {error("illegal address");
1997
                        return 0;
1998
                        }
1999
                else if(lval[1])return 0;
2000
                else
2001
                        {immed();
2002
                        outname(ptr=lval[0]);
2003
                        nl();
2004
                        lval[1]=ptr[type];
2005
                        return 0;
2006
                        }
2007
                }
2008
        else
2009
                {k=heir11(lval);
2010
                if(match("++"))
2011
                        {if(k==0)
2012
                                {needlval();
2013
                                return 0;
2014
                                }
2015
                        if(lval[1])zpush();
2016
                        rvalue(lval);
2017
                        inc();
2018
                        ptr=lval[0];
2019
                        if((ptr[ident]==pointer)&
2020
                                (ptr[type]==cint))
2021
                                        inc();
2022
                        store(lval);
2023
                        dec();
2024
                        if((ptr[ident]==pointer)&
2025
                                (ptr[type]==cint))
2026
                                dec();
2027
                        return 0;
2028
                        }
2029
                else if(match("--"))
2030
                        {if(k==0)
2031
                                {needlval();
2032
                                return 0;
2033
                                }
2034
                        if(lval[1])zpush();
2035
                        rvalue(lval);
2036
                        dec();
2037
                        ptr=lval[0];
2038
                        if((ptr[ident]==pointer)&
2039
                                (ptr[type]==cint))
2040
                                        dec();
2041
                        store(lval);
2042
                        inc();
2043
                        if((ptr[ident]==pointer)&
2044
                                (ptr[type]==cint))
2045
                                inc();
2046
                        return 0;
2047
                        }
2048
                else return k;
2049
                }
2050
        }
2051
/*      >>>>>> start of cc7 <<<<<<      */
2052
 
2053
heir11(lval)
2054
        int *lval;
2055
{       int k;char *ptr;
2056
        k=primary(lval);
2057
        ptr=lval[0];
2058
        blanks();
2059
        if((ch()=='[')|(ch()=='('))
2060
        while(1)
2061
                {if(match("["))
2062
                        {if(ptr==0)
2063
                                {error("can't subscript");
2064
                                junk();
2065
                                needbrack("]");
2066
                                return 0;
2067
                                }
2068
                        else if(ptr[ident]==pointer)rvalue(lval);
2069
                        else if(ptr[ident]!=array)
2070
                                {error("can't subscript");
2071
                                k=0;
2072
                                }
2073
                        zpush();
2074
                        expression();
2075
                        needbrack("]");
2076
                        if(ptr[type]==cint)doublereg();
2077
                        zpop();
2078
                        zadd();
2079
                        lval[1]=ptr[type];
2080
                                /* 4/1/81 - after subscripting, not ptr anymore */
2081
                        lval[0]=0;
2082
                        k=1;
2083
                        }
2084
                else if(match("("))
2085
                        {if(ptr==0)
2086
                                {callfunction(0);
2087
                                }
2088
                        else if(ptr[ident]!=function)
2089
                                {rvalue(lval);
2090
                                callfunction(0);
2091
                                }
2092
                        else callfunction(ptr);
2093
                        k=lval[0]=0;
2094
                        }
2095
                else return k;
2096
                }
2097
        if(ptr==0)return k;
2098
        if(ptr[ident]==function)
2099
                {immed();
2100
                outname(ptr);
2101
                nl();
2102
                return 0;
2103
                }
2104
        return k;
2105
}
2106
primary(lval)
2107
        int *lval;
2108
{       char *ptr,sname[namesize];int num[1];
2109
        int k;
2110
        if(match("("))
2111
                {k=heir1(lval);
2112
                needbrack(")");
2113
                return k;
2114
                }
2115
        if(symname(sname))
2116
                {if(ptr=findloc(sname))
2117
                        {getloc(ptr);
2118
                        lval[0]=ptr;
2119
                        lval[1]=ptr[type];
2120
                        if(ptr[ident]==pointer)lval[1]=cint;
2121
                        if(ptr[ident]==array)return 0;
2122
                                else return 1;
2123
                        }
2124
                if(ptr=findglb(sname))
2125
                        if(ptr[ident]!=function)
2126
                        {lval[0]=ptr;
2127
                        lval[1]=0;
2128
                        if(ptr[ident]!=array)return 1;
2129
                        immed();
2130
                        outname(ptr);nl();
2131
                        lval[1]=ptr[type];
2132
                        return 0;
2133
                        }
2134
                ptr=addglb(sname,function,cint,0,-1);
2135
                lval[0]=ptr;
2136
                lval[1]=0;
2137
                return 0;
2138
                }
2139
        if(constant(num))
2140
                return(lval[0]=lval[1]=0);
2141
        else
2142
                {error("invalid expression");
2143
                immed();outdec(0);nl();
2144
                junk();
2145
                return 0;
2146
                }
2147
        }
2148
store(lval)
2149
        int *lval;
2150
{       if (lval[1]==0)putmem(lval[0]);
2151
        else putstk(lval[1]);
2152
}
2153
rvalue(lval)
2154
        int *lval;
2155
{       if((lval[0] != 0) & (lval[1] == 0))
2156
                getmem(lval[0]);
2157
                else indirect(lval[1]);
2158
}
2159
test(label)
2160
        int label;
2161
{
2162
        needbrack("(");
2163
        expression();
2164
        needbrack(")");
2165
        testjump(label);
2166
}
2167
constant(val)
2168
        int val[];
2169
{
2170
        if (number(val)) {
2171
                immed();
2172
                outdec(val[0]);
2173
        }
2174
        else if (pstr(val)) {
2175
                immed();
2176
                outdec(val[0]);
2177
        }
2178
        else if (qstr(val)) {
2179
                immed();
2180
                printlabel(litlab);
2181
                outbyte('+');
2182
                outdec(val[0]);
2183
        }
2184
        else
2185
                return 0;
2186
        nl();
2187
        return 1;
2188
}
2189
// get a numeric value from the source file 
2190
number(val)
2191
int val[];
2192
{
2193
int k,minus;
2194
char c;
2195
 
2196
        k=minus=1;
2197
        while (k) {
2198
                k=0;
2199
                if (match("+")) k=1;
2200
                if (match("-")) {
2201
                        minus=(-minus);
2202
                        k=1;
2203
                }
2204
        }
2205
        // check if hexadecimal value 
2206
        if ((ch()=='0') & (nch()=='x')) {
2207
                // remove first two characters ("0x") 
2208
                inchar();inchar();
2209
                // make sure the next value is legal 
2210
                if (hexnum(ch())==0) return 0;
2211
                // continue to read hexadecimal value 
2212
                while (hexnum(ch())) {
2213
                        c=raise(inbyte());
2214
                        if (numeric(c)!=0)
2215
                                k=k*16+(c-'0');
2216
                        else
2217
                                k=k*16+(c-'A')+10;
2218
                }
2219
                if (minus<0) k=(-k);
2220
                val[0]=k;
2221
                return 1;
2222
        }
2223
        // check if decimal value 
2224
        else if (numeric(ch())!=0) {
2225
                while (numeric(ch())) {
2226
                        c=inbyte();
2227
                        k=k*10+(c-'0');
2228
                }
2229
                if (minus<0) k=(-k);
2230
                val[0]=k;
2231
                return 1;
2232
        }
2233
        else
2234
                return 0;
2235
}
2236
pstr(val)
2237
int val[];
2238
{
2239
int k;
2240
char c;
2241
 
2242
        k=0;
2243
        if (match("'")==0) return 0;
2244
        while((c=gch())!=39)
2245
                k=(k&255)*256 + (c&127);
2246
        val[0]=k;
2247
        return 1;
2248
}
2249
qstr(val)
2250
int val[];
2251
{
2252
char c;
2253
 
2254
        if (match("\"")==0) return 0;
2255
        val[0]=litptr;
2256
        while (ch()!='"')
2257
                {if(ch()==0)break;
2258
                if(litptr>=litmax)
2259
                        {error("string space exhausted");
2260
                        while(match("\"")==0)
2261
                                if(gch()==0)break;
2262
                        return 1;
2263
                        }
2264
                litq[litptr++]=gch();
2265
                }
2266
        gch();
2267
        litq[litptr++]=0;
2268
        return 1;
2269
}
2270
/*      >>>>>> start of cc8 <<<<<<<     */
2271
 
2272
/* Begin a comment line for the assembler */
2273
comment()
2274
{       outbyte(';');
2275
}
2276
 
2277
/* Put out assembler info before any code is generated */
2278
header()
2279
{       comment();
2280
        outstr(BANNER);
2281
        nl();
2282
        comment();
2283
        outstr(VERSION);
2284
        nl();
2285
        comment();
2286
        outstr(AUTHOR);
2287
        nl();
2288
        comment();
2289
        nl();
2290
        if (mainflg) {          /* do stuff needed for first */
2291
                ol("code");
2292
                ol("org #0000"); /* assembler file. */
2293
                ot("ld hl,"); outdec(stackptr); nl();   /* set up stack */
2294
                ol("ld sp,hl");
2295
                zcall("main");  /* call the code generated by small-c */
2296
        }
2297
}
2298
/* Print any assembler stuff needed after all code */
2299
trailer()
2300
{       /* ol("END"); */        /*...note: commented out! */
2301
 
2302
        nl();                   /* 6 May 80 rj errorsummary() now goes to console */
2303
        comment();
2304
        outstr(" --- End of Compilation ---");
2305
        nl();
2306
}
2307
/* Print out a name such that it won't annoy the assembler */
2308
/*      (by matching anything reserved, like opcodes.) */
2309
/*      gtf 4/7/80 */
2310
outname(sname)
2311
char *sname;
2312
{       int len, i,j;
2313
 
2314
        outasm("__");
2315
        len = strlen(sname);
2316
        if (len>(asmpref+asmsuff)) {
2317
                i = asmpref;
2318
                len = len-asmpref-asmsuff;
2319
                while(i-- > 0)
2320
                        outbyte(lower(*sname++));
2321
                while(len-- > 0)
2322
                        sname++;
2323
                while(*sname)
2324
                        outbyte(lower(*sname++));
2325
                }
2326
        else    outasm(sname);
2327
/* end outname */}
2328
/* Fetch a static memory cell into the primary register */
2329
getmem(sym)
2330
        char *sym;
2331
{
2332
int padr;
2333
 
2334
        if ((sym[ident]!=pointer)&(sym[type]==cchar)) {
2335
                ot("ld a,(");
2336
                outname(sym+name);
2337
                outasm(")");
2338
                nl();
2339
                callrts("ccsxt");
2340
        } else if (sym[type]==cport) {
2341
                padr=sym[offset] & 0xff;
2342
                ot("in a,(");outdec(padr);outasm(")");nl();
2343
                callrts("ccsxt");
2344
        } else {
2345
                ot("ld hl,(");
2346
                outname(sym+name);
2347
                outasm(")");
2348
                nl();
2349
        }
2350
}
2351
/* Fetch the address of the specified symbol */
2352
/*      into the primary register */
2353
getloc(sym)
2354
        char *sym;
2355
{
2356
int off_val;
2357
 
2358
        immed();
2359
        off_val = ((sym[offset]&255)+((sym[offset+1]&255)<<8))-Zsp;
2360
        off_val &= 0xffff;
2361
        outdec(off_val);
2362
        nl();
2363
        ol("add hl,sp");
2364
}
2365
/* Store the primary register into the specified */
2366
/*      static memory cell */
2367
putmem(sym)
2368
        char *sym;
2369
{
2370
int padr;
2371
 
2372
        if((sym[ident]!=pointer)&(sym[type]==cchar)) {
2373
                ol("ld a,l");
2374
                ot("ld (");
2375
                outname(sym+name);
2376
                outasm("),a");
2377
        } else if (sym[type]==cport) {
2378
                padr=sym[offset] & 0xff;
2379
                ol("ld a,l");
2380
                ot("out (");outdec(padr);outasm("),a");nl();
2381
        } else {
2382
                ot("ld (");
2383
                outname(sym+name);
2384
                outasm("),hl");
2385
        }
2386
 
2387
        nl();
2388
        }
2389
/* Store the specified object type in the primary register */
2390
/*      at the address on the top of the stack */
2391
putstk(typeobj)
2392
char typeobj;
2393
{       zpop();
2394
        if(typeobj==cint)
2395
                callrts("ccpint");
2396
        else {  ol("ld a,l");           /* per Ron Cain: gtf 9/25/80 */
2397
                ol("ld (de),a");
2398
                }
2399
        }
2400
/* Fetch the specified object type indirect through the */
2401
/*      primary register into the primary register */
2402
indirect(typeobj)
2403
        char typeobj;
2404
{       if(typeobj==cchar)callrts("ccgchar");
2405
                else callrts("ccgint");
2406
}
2407
/* Swap the primary and secondary registers */
2408
swap()
2409 67 motilito
{       ol("ex de,hl");
2410 65 motilito
}
2411
/* Print partial instruction to get an immediate value */
2412
/*      into the primary register */
2413
immed()
2414
{       ot("ld hl,");
2415
}
2416
/* Push the primary register onto the stack */
2417
zpush()
2418
{       ol("push hl");
2419
        Zsp=Zsp-2;
2420
}
2421
/* Pop the top of the stack into the secondary register */
2422
zpop()
2423
{       ol("pop de");
2424
        Zsp=Zsp+2;
2425
}
2426
/* Swap the primary register and the top of the stack */
2427
swapstk()
2428
{       ol("ex (sp),hl");
2429
}
2430
/* Call the specified subroutine name */
2431
zcall(sname)
2432
        char *sname;
2433
{       ot("call ");
2434
        outname(sname);
2435
        nl();
2436
}
2437
/* Call a run-time library routine */
2438
callrts(sname)
2439
char *sname;
2440
{
2441
        ot("call ");
2442
        outasm(sname);
2443
        nl();
2444
/*end callrts*/}
2445
 
2446
/* Return from subroutine */
2447
zret()
2448 66 motilito
{       ol("ret");
2449 65 motilito
}
2450
/* Perform subroutine call to value on top of stack */
2451
callstk()
2452
{       immed();
2453
        outasm("$+5");
2454
        nl();
2455
        swapstk();
2456
        ol("jp (hl)");
2457
        Zsp=Zsp+2; /* corrected 5 May 81 rj */
2458
        }
2459
/* Jump to specified internal label number */
2460
jump(label)
2461
        int label;
2462
{       ot("jp ");
2463
        printlabel(label);
2464
        nl();
2465
        }
2466
/* Test the primary register and jump if false to label */
2467
testjump(label)
2468
        int label;
2469
{       ol("ld a,h");
2470
        ol("or l");
2471
        ot("jp z,");
2472
        printlabel(label);
2473
        nl();
2474
        }
2475
/* Print pseudo-op to define a byte */
2476
defbyte()
2477
{       ot("db ");
2478
}
2479
/*Print pseudo-op to define storage */
2480
defstorage()
2481
{       ot("ds ");
2482
}
2483
/* Print pseudo-op to define a word */
2484
defword()
2485
{       ot("dw ");
2486
}
2487
/* Modify the stack pointer to the new value indicated */
2488
modstk(newsp)
2489
        int newsp;
2490
 {      int k;
2491
        k=newsp-Zsp;
2492
        if(k==0)return newsp;
2493
        if(k>=0)
2494
                {if(k<7)
2495
                        {if(k&1)
2496
                                {ol("inc sp");
2497
                                k--;
2498
                                }
2499
                        while(k)
2500
                                {ol("pop bc");
2501
                                k=k-2;
2502
                                }
2503
                        return newsp;
2504
                        }
2505
                }
2506
        if(k<0)
2507
                {if(k>-7)
2508
                        {if(k&1)
2509
                                {ol("dec sp");
2510
                                k++;
2511
                                }
2512
                        while(k)
2513
                                {ol("push bc");
2514
                                k=k+2;
2515
                                }
2516
                        return newsp;
2517
                        }
2518
                }
2519
        swap();
2520
        immed();outdec(k);nl();
2521
        ol("add hl,sp");
2522
        ol("ld sp,hl");
2523
        swap();
2524
        return newsp;
2525
}
2526
/* Double the primary register */
2527
doublereg()
2528
{       ol("add hl,hl");
2529
}
2530
/* Add the primary and secondary registers */
2531
/*      (results in primary) */
2532
zadd()
2533
{       ol("add hl,de");
2534
}
2535
/* Subtract the primary register from the secondary */
2536
/*      (results in primary) */
2537
zsub()
2538
{       callrts("ccsub");
2539
}
2540
/* Multiply the primary and secondary registers */
2541
/*      (results in primary */
2542
mult()
2543
{       callrts("ccmult");
2544
}
2545
/* Divide the secondary register by the primary */
2546
/*      (quotient in primary, remainder in secondary) */
2547
div()
2548
{       callrts("ccdiv");
2549
}
2550
/* Compute remainder (mod) of secondary register divided */
2551
/*      by the primary */
2552
/*      (remainder in primary, quotient in secondary) */
2553
zmod()
2554
{       div();
2555
        swap();
2556
        }
2557
/* Inclusive 'or' the primary and the secondary registers */
2558
/*      (results in primary) */
2559
zor()
2560
        {callrts("ccor");}
2561
/* Exclusive 'or' the primary and seconday registers */
2562
/*      (results in primary) */
2563
zxor()
2564
        {callrts("ccxor");}
2565
/* 'And' the primary and secondary registers */
2566
/*      (results in primary) */
2567
zand()
2568
        {callrts("ccand");}
2569
/* Arithmetic shift right the secondary register number of */
2570
/*      times in primary (results in primary) */
2571
asr()
2572
        {callrts("ccasr");}
2573
/* Arithmetic left shift the secondary register number of */
2574
/*      times in primary (results in primary) */
2575
asl()
2576
        {callrts("ccasl");}
2577
/* Form two's complement of primary register */
2578
neg()
2579
        {callrts("ccneg");}
2580
/* Form one's complement of primary register */
2581
com()
2582
        {callrts("cccom");}
2583
/* Increment the primary register by one */
2584
inc()
2585
        {ol("inc hl");}
2586
/* Decrement the primary register by one */
2587
dec()
2588
        {ol("dec hl");}
2589
 
2590
/* Following are the conditional operators */
2591
/* They compare the secondary register against the primary */
2592
/* and put a literal 1 in the primary if the condition is */
2593
/* true, otherwise they clear the primary register */
2594
 
2595
/* Test for equal */
2596
zeq()
2597
        {callrts("cceq");}
2598
/* Test for not equal */
2599
zne()
2600
        {callrts("ccne");}
2601
/* Test for less than (signed) */
2602
zlt()
2603
        {callrts("cclt");}
2604
/* Test for less than or equal to (signed) */
2605
zle()
2606
        {callrts("ccle");}
2607
/* Test for greater than (signed) */
2608
zgt()
2609
        {callrts("ccgt");}
2610
/* Test for greater than or equal to (signed) */
2611
zge()
2612
        {callrts("ccge");}
2613
/* Test for less than (unsigned) */
2614
ult()
2615
        {callrts("ccult");}
2616
/* Test for less than or equal to (unsigned) */
2617
ule()
2618
        {callrts("ccule");}
2619
/* Test for greater than (unsigned) */
2620
ugt()
2621
        {callrts("ccugt");}
2622
/* Test for greater than or equal to (unsigned) */
2623
uge()
2624
        {callrts("ccuge");}
2625
 
2626
/*      <<<<<  End of small-c compiler  >>>>>   */
2627
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.