[BACK]Return to ncr53cxxx.c CVS log [TXT][DIR] Up to [local] / sys / dev / microcode / ncr53cxxx

Annotation of sys/dev/microcode/ncr53cxxx/ncr53cxxx.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ncr53cxxx.c,v 1.4 2003/04/06 18:54:20 ho Exp $        */
                      2:
                      3: /*
                      4:  * Copyright (c) 1995 Michael L. Hitch
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *      This product includes software developed by Michael L. Hitch.
                     18:  * 4. The name of the author may not be used to endorse or promote products
                     19:  *    derived from this software without specific prior written permission
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     31:  */
                     32:
                     33: /*     scc.c   - SCSI SCRIPTS Compiler         */
                     34:
                     35: #include <stdio.h>
                     36: #include <stdlib.h>
                     37: #include <string.h>
                     38:
                     39: #ifndef AMIGA
                     40: #define strcmpi        strcasecmp
                     41: #endif
                     42:
                     43: #define        MAXTOKENS       16
                     44: #define        MAXINST         1024
                     45: #define        MAXSYMBOLS      128
                     46:
                     47: struct {
                     48:        long    type;
                     49:        char    *name;
                     50: } tokens[MAXTOKENS];
                     51: int    ntokens;
                     52: int    tokenix;
                     53:
                     54: void   f_proc (void);
                     55: void   f_pass (void);
                     56: void   f_list (void);          /* ENTRY, EXTERNAL label list */
                     57: void   f_define (void);        /* ABSOLUTE, RELATIVE label list */
                     58: void   f_move (void);
                     59: void   f_jump (void);
                     60: void   f_call (void);
                     61: void   f_return (void);
                     62: void   f_int (void);
                     63: void   f_select (void);
                     64: void   f_reselect (void);
                     65: void   f_wait (void);
                     66: void   f_disconnect (void);
                     67: void   f_set (void);
                     68: void   f_clear (void);
                     69: void   f_arch (void);
                     70:
                     71: struct {
                     72:        char    *name;
                     73:        void    (*func)(void);
                     74: } directives[] = {
                     75:        "PROC",         f_proc,
                     76:        "PASS",         f_pass,
                     77:        "ENTRY",        f_list,
                     78:        "ABSOLUTE",     f_define,
                     79:        "EXTERN",       f_list,
                     80:        "EXTERNAL",     f_list,
                     81:        "RELATIVE",     f_define,
                     82:        "MOVE",         f_move,
                     83:        "JUMP",         f_jump,
                     84:        "CALL",         f_call,
                     85:        "RETURN",       f_return,
                     86:        "INT",          f_int,
                     87:        "SELECT",       f_select,
                     88:        "RESELECT",     f_reselect,
                     89:        "WAIT",         f_wait,
                     90:        "DISCONNECT",   f_disconnect,
                     91:        "SET",          f_set,
                     92:        "CLEAR",        f_clear,
                     93:        "ARCH",         f_arch,
                     94:        NULL};
                     95:
                     96: unsigned long script[MAXINST];
                     97: int    dsps;
                     98: char   *script_name = "SCRIPT";
                     99: unsigned long  inst0, inst1, inst2;
                    100: unsigned long  ninsts;
                    101: unsigned long  npatches;
                    102:
                    103: struct patchlist {
                    104:        struct patchlist *next;
                    105:        unsigned        offset;
                    106: };
                    107:
                    108: #define        S_LABEL         0x0000
                    109: #define        S_ABSOLUTE      0x0001
                    110: #define        S_RELATIVE      0x0002
                    111: #define        S_EXTERNAL      0x0003
                    112: #define        F_DEFINED       0x0001
                    113: #define        F_ENTRY         0x0002
                    114: struct {
                    115:        short   type;
                    116:        short   flags;
                    117:        unsigned long value;
                    118:        struct patchlist *patchlist;
                    119:        char    *name;
                    120: } symbols[MAXSYMBOLS];
                    121: int nsymbols;
                    122:
                    123: char   *stypes[] = {"Label", "Absolute", "Relative", "External"};
                    124:
                    125: char   *phases[] = {
                    126:        "data_out", "data_in", "cmd", "status",
                    127:        "res4", "res5", "msg_out", "msg_in"
                    128: };
                    129:
                    130: char   *regs710[] = {
                    131:        "scntl0",       "scntl1",       "sdid",         "sien",
                    132:        "scid",         "sxfer",        "sodl",         "socl",
                    133:        "sfbr",         "sidl",         "sbdl",         "sbcl",
                    134:        "dstat",        "sstat0",       "sstat1",       "sstat2",
                    135:        "dsa0",         "dsa1",         "dsa2",         "dsa3",
                    136:        "ctest0",       "ctest1",       "ctest2",       "ctest3",
                    137:        "ctest4",       "ctest5",       "ctest6",       "ctest7",
                    138:        "temp0",        "temp1",        "temp2",        "temp3",
                    139:        "dfifo",        "istat",        "ctest8",       "lcrc",
                    140:        "dbc0",         "dbc1",         "dbc2",         "dcmd",
                    141:        "dnad0",        "dnad1",        "dnad2",        "dnad3",
                    142:        "dsp0",         "dsp1",         "dsp2",         "dsp3",
                    143:        "dsps0",        "dsps1",        "dsps2",        "dsps3",
                    144:        "scratch0",     "scratch1",     "scratch2",     "scratch3",
                    145:        "dmode",        "dien",         "dwt",          "dcntl",
                    146:        "addr0",        "addr1",        "addr2",        "addr3"
                    147: };
                    148:
                    149: char   *regs720[] = {
                    150:        "scntl0",       "scntl1",       "scntl2",       "scntl3",
                    151:        "scid",         "sxfer",        "sdid",         "gpreg",
                    152:        "sfbr",         "socl",         "ssid",         "sbcl",
                    153:        "dstat",        "sstat0",       "sstat1",       "sstat2",
                    154:        "dsa0",         "dsa1",         "dsa2",         "dsa3",
                    155:        "istat",        "",             "",             "",
                    156:        "ctest0",       "ctest1",       "ctest2",       "ctest3",
                    157:        "temp0",        "temp1",        "temp2",        "temp3",
                    158:        "dfifo",        "ctest4",       "ctest5",       "ctest6",
                    159:        "dbc0",         "dbc1",         "dbc2",         "dcmd",
                    160:        "dnad0",        "dnad1",        "dnad2",        "dnad3",
                    161:        "dsp0",         "dsp1",         "dsp2",         "dsp3",
                    162:        "dsps0",        "dsps1",        "dsps2",        "dsps3",
                    163:        "scratcha0",    "scratcha1",    "scratcha2",    "scratcha3",
                    164:        "dmode",        "dien",         "dwt",          "dcntl",
                    165:        "addr0",        "addr1",        "addr2",        "addr3",
                    166:        "sien0",        "sien1",        "sist0",        "sist1",
                    167:        "slpar",        "swide",        "macntl",       "gpcntl",
                    168:        "stime0",       "stime1",       "respid0",      "respid1",
                    169:        "stest0",       "stest1",       "stest2",       "stest3",
                    170:        "sidl0",        "sidl1",        "",             "",
                    171:        "sodl0",        "sodl1",        "",             "",
                    172:        "sbdl0",        "sbdl1",        "",             "",
                    173:        "scratchb0",    "scratchb1",    "scratchb2",    "scratchb3",
                    174: };
                    175:
                    176: int    lineno;
                    177: int    err_listed;
                    178: int    arch;
                    179:
                    180: char   inbuf[128];
                    181:
                    182: char   *sourcefile;
                    183: char   *outputfile;
                    184: char   *listfile;
                    185: char   *errorfile;
                    186:
                    187: FILE   *infp;
                    188: FILE   *outfp;
                    189: FILE   *listfp;
                    190: FILE   *errfp;
                    191:
                    192: void   parse (void);
                    193: void   process (void);
                    194: void   emit_symbols (void);
                    195: void   list_symbols (void);
                    196: void   errout (char *);
                    197: void   define_symbol (char *, unsigned long, short, short);
                    198: void   close_script (void);
                    199: void   new_script (char *);
                    200: void   store_inst (void);
                    201: int    expression (int *);
                    202: int    evaluate (int);
                    203: int    number (char *);
                    204: int    lookup (char *);
                    205: int    reserved (char *, int);
                    206: int    CheckPhase (int);
                    207: int    CheckRegister (int);
                    208: void   transfer (int, int);
                    209: void   select_reselect (int);
                    210: void   set_clear (unsigned long);
                    211: void   block_move (void);
                    212: void   register_write (void);
                    213: void   memory_to_memory (void);
                    214: void   error_line(void);
                    215: char   *makefn(char *, char *);
                    216: void   usage(void);
                    217:
                    218: main (int argc, char *argv[])
                    219: {
                    220:        int     i;
                    221:
                    222:        if (argc < 2 || argv[1][0] == '-')
                    223:                usage();
                    224:        sourcefile = argv[1];
                    225:        infp = fopen (sourcefile, "r");
                    226:        if (infp == NULL) {
                    227:                perror ("open source");
                    228:                fprintf (stderr, "scc: error opening source file %s\n", argv[1]);
                    229:                exit (1);
                    230:        }
                    231:        /*
                    232:         * process options
                    233:         * -l [listfile]
                    234:         * -o [outputfile]
                    235:         * -z [debugfile]
                    236:         * -e [errorfile]
                    237:         * -a arch
                    238:         * -v
                    239:         * -u
                    240:         */
                    241:        for (i = 2; i < argc; ++i) {
                    242:                if (argv[i][0] != '-')
                    243:                        usage();
                    244:                switch (argv[i][1]) {
                    245:                case 'o':
                    246:                        if (i + 1 >= argc || argv[i + 1][0] == '-')
                    247:                                outputfile = makefn (sourcefile, "out");
                    248:                        else {
                    249:                                outputfile = argv[i + 1];
                    250:                                ++i;
                    251:                        }
                    252:                        break;
                    253:                case 'l':
                    254:                        if (i + 1 >= argc || argv[i + 1][0] == '-')
                    255:                                listfile = makefn (sourcefile, "lis");
                    256:                        else {
                    257:                                listfile = argv[i + 1];
                    258:                                ++i;
                    259:                        }
                    260:                        break;
                    261:                case 'e':
                    262:                        if (i + 1 >= argc || argv[i + 1][0] == '-')
                    263:                                errorfile = makefn (sourcefile, "err");
                    264:                        else {
                    265:                                errorfile = argv[i + 1];
                    266:                                ++i;
                    267:                        }
                    268:                        break;
                    269:                case 'a':
                    270:                        if (i + 1 == argc)
                    271:                                usage();
                    272:                        arch = 0;
                    273:                        arch = atoi(argv[i +1]);
                    274:                        if(arch != 720 && arch != 710) {
                    275:                                fprintf(stderr,"%s: bad arch '%s'\n",
                    276:                                        argv[0], argv[i +1]);
                    277:                                exit(1);
                    278:                        }
                    279:                        ++i;
                    280:                        break;
                    281:                default:
                    282:                        fprintf (stderr, "scc: unrecognized option '%c'\n",
                    283:                            argv[i][1]);
                    284:                        usage();
                    285:                }
                    286:        }
                    287:        if (outputfile)
                    288:                outfp = fopen (outputfile, "w");
                    289:        if (listfile)
                    290:                listfp = fopen (listfile, "w");
                    291:        if (errorfile)
                    292:                errfp = fopen (errorfile, "w");
                    293:        else
                    294:                errfp = stderr;
                    295:
                    296:        while (fgets (inbuf, sizeof (inbuf), infp)) {
                    297:                ++lineno;
                    298:                if (listfp)
                    299:                        fprintf (listfp, "%3d:  %s", lineno, inbuf);
                    300:                err_listed = 0;
                    301:                parse ();
                    302:                if (ntokens) {
                    303: #ifdef DUMP_TOKENS
                    304:                        int     i;
                    305:
                    306:                        fprintf (listfp, "      %d tokens\n", ntokens);
                    307:                        for (i = 0; i < ntokens; ++i) {
                    308:                                fprintf (listfp, "      %d: ", i);
                    309:                                if (tokens[i].type)
                    310:                                        fprintf (listfp,"'%c'\n", tokens[i].type);
                    311:                                else
                    312:                                        fprintf (listfp, "%s\n", tokens[i].name);
                    313:                        }
                    314: #endif
                    315:                        if (ntokens >= 2 && tokens[0].type == 0 &&
                    316:                            tokens[1].type == ':') {
                    317:                                define_symbol (tokens[0].name, dsps, S_LABEL, F_DEFINED);
                    318:                                tokenix += 2;
                    319:                        }
                    320:                        if (tokenix < ntokens)
                    321:                                process ();
                    322:                }
                    323:
                    324:        }
                    325:        close_script ();
                    326:        emit_symbols ();
                    327:        if (outfp) {
                    328:                fprintf (outfp, "\nunsigned long INSTRUCTIONS = 0x%08x;\n", ninsts);
                    329:                fprintf (outfp, "unsigned long PATCHES = 0x%08x;\n", npatches);
                    330:        }
                    331:        list_symbols ();
                    332: }
                    333:
                    334: void emit_symbols ()
                    335: {
                    336:        int     i;
                    337:        struct  patchlist *p;
                    338:
                    339:        if (nsymbols == 0 || outfp == NULL)
                    340:                return;
                    341:
                    342:        for (i = 0; i < nsymbols; ++i) {
                    343:                char    *code;
                    344:                if (symbols[i].type == S_ABSOLUTE)
                    345:                        code = "A_";
                    346:                else if (symbols[i].type == S_RELATIVE)
                    347:                        code = "R_";
                    348:                else if (symbols[i].type == S_EXTERNAL)
                    349:                        code = "E_";
                    350:                else if (symbols[i].flags & F_ENTRY)
                    351:                        code = "Ent_";
                    352:                else
                    353:                        continue;
                    354:                fprintf (outfp, "#define\t%s%s\t0x%08x\n", code, symbols[i].name,
                    355:                        symbols[i].value);
                    356:                if (symbols[i].flags & F_ENTRY || symbols[i].patchlist == NULL)
                    357:                        continue;
                    358:                fprintf (outfp, "unsigned long %s%s_Used[] = {\n", code, symbols[i].name);
                    359: #if 1
                    360:                p = symbols[i].patchlist;
                    361:                while (p) {
                    362:                        fprintf (outfp, "\t%08x,\n", p->offset / 4);
                    363:                        p = p->next;
                    364:                }
                    365: #endif
                    366:                fprintf (outfp, "};\n\n");
                    367:        }
                    368:        /* patches ? */
                    369: }
                    370:
                    371: void list_symbols ()
                    372: {
                    373:        int     i;
                    374:
                    375:        if (nsymbols == 0 || listfp == NULL)
                    376:                return;
                    377:        fprintf (listfp, "\n\nValue     Type     Symbol\n");
                    378:        for (i = 0; i < nsymbols; ++i) {
                    379:                fprintf (listfp, "%08x: %-8s %s\n", symbols[i].value,
                    380:                        stypes[symbols[i].type], symbols[i].name);
                    381:        }
                    382: }
                    383:
                    384: void errout (char *text)
                    385: {
                    386:        error_line();
                    387:        fprintf (errfp, "*** %s ***\n", text);
                    388: }
                    389:
                    390: void parse ()
                    391: {
                    392:        char *p = inbuf;
                    393:        char c;
                    394:        char string[64];
                    395:        char *s;
                    396:        size_t len;
                    397:
                    398:        ntokens = tokenix = 0;
                    399:        while (1) {
                    400:                while ((c = *p++) && c != '\n' && c <= ' ' || c == '\t')
                    401:                        ;
                    402:                if (c == '\n' || c == 0 || c == ';')
                    403:                        break;
                    404:                if (ntokens >= MAXTOKENS) {
                    405:                        errout ("Token table full");
                    406:                        break;
                    407:                }
                    408:                if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
                    409:                    (c >= 'A' && c <= 'Z') || c == '$' || c == '_') {
                    410:                        s = string;
                    411:                        *s++ = c;
                    412:                        while (((c = *p) >= '0' && c <= '9') ||
                    413:                            (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
                    414:                            c == '_' || c == '$') {
                    415:                                *s++ = *p++;
                    416:                        }
                    417:                        *s = 0;
                    418:                        len = strlen (string) + 1;
                    419:                        tokens[ntokens].name = malloc (len);
                    420:                        strlcpy (tokens[ntokens].name, string, len);
                    421:                        tokens[ntokens].type = 0;
                    422:                }
                    423:                else {
                    424:                        tokens[ntokens].type = c;
                    425:                }
                    426:                ++ntokens;
                    427:        }
                    428:        return;
                    429: }
                    430:
                    431: void   process ()
                    432: {
                    433:        int     i;
                    434:
                    435:        if (tokens[tokenix].type) {
                    436:                error_line();
                    437:                fprintf (errfp, "Error: expected directive, found '%c'\n",
                    438:                        tokens[tokenix].type);
                    439:                return;
                    440:        }
                    441:        for (i = 0; directives[i].name; ++i) {
                    442:                if (strcmpi (directives[i].name, tokens[tokenix].name) == 0)
                    443:                        break;
                    444:        }
                    445:        if (directives[i].name == NULL) {
                    446:                error_line();
                    447:                fprintf (errfp, "Error: expected directive, found \"%s\"\n",
                    448:                        tokens[tokenix].name);
                    449:                return;
                    450:        }
                    451:        if (directives[i].func == NULL) {
                    452:                error_line();
                    453:                fprintf (errfp, "No function for directive \"%s\"\n", tokens[tokenix].name);
                    454:        } else {
                    455: #if 0
                    456:                fprintf (listfp, "Processing directive \"%s\"\n", directives[i].name);
                    457: #endif
                    458:                ++tokenix;
                    459:                (*directives[i].func) ();
                    460:        }
                    461: }
                    462:
                    463: void define_symbol (char *name, unsigned long value, short type, short flags)
                    464: {
                    465:        int     i;
                    466:        struct patchlist *p;
                    467:        size_t  len;
                    468:
                    469:        for (i = 0; i < nsymbols; ++i) {
                    470:                if (symbols[i].type == type && strcmp (symbols[i].name, name) == 0) {
                    471:                        if (symbols[i].flags & F_DEFINED) {
                    472:                                error_line();
                    473:                                fprintf (errfp, "*** Symbol \"%s\" multiply defined\n",
                    474:                                        name);
                    475:                        } else {
                    476:                                symbols[i].flags |= flags;
                    477:                                symbols[i].value = value;
                    478:                                p = symbols[i].patchlist;
                    479:                                while (p) {
                    480:                                        if (p->offset > dsps)
                    481:                                                errout ("Whoops\007");
                    482:                                        else
                    483:                                                script[p->offset / 4] = dsps - p->offset - 4;
                    484:                                        p = p->next;
                    485:                                }
                    486:                        }
                    487:                        return;
                    488:                }
                    489:        }
                    490:        if (nsymbols >= MAXSYMBOLS) {
                    491:                errout ("Symbol table full");
                    492:                return;
                    493:        }
                    494:        symbols[nsymbols].type = type;
                    495:        symbols[nsymbols].flags = flags;
                    496:        symbols[nsymbols].value = value;
                    497:        symbols[nsymbols].patchlist = NULL;
                    498:        len = strlen (name) + 1;
                    499:        symbols[nsymbols].name = malloc (len);
                    500:        strlcpy (symbols[nsymbols].name, name, len);
                    501:        ++nsymbols;
                    502: }
                    503:
                    504: void close_script ()
                    505: {
                    506:        int     i;
                    507:
                    508:        if (dsps == 0)
                    509:                return;
                    510:        if (outfp) {
                    511:                fprintf (outfp, "unsigned long %s[] = {\n", script_name);
                    512:                for (i = 0; i < dsps / 4; i += 2) {
                    513:                        fprintf (outfp, "\t0x%08x, 0x%08x", script[i],
                    514:                                script[i + 1]);
                    515:                        /* check for memory move instruction */
                    516:                        if (script[i] >> 30 == 3)
                    517:                                fprintf (outfp, ", 0x%08x,", script[i + 2]);
                    518:                        else
                    519:                                if ((i + 2) <= dsps / 4) fprintf (outfp, ",\t\t");
                    520:                        fprintf (outfp, "\t/* %03x - %3d */\n", i * 4, i * 4);
                    521:                        if (script[i] >> 30 == 3)
                    522:                                ++i;
                    523:                }
                    524:                fprintf (outfp, "};\n\n");
                    525:        }
                    526:        dsps = 0;
                    527: }
                    528:
                    529: void new_script (char *name)
                    530: {
                    531:        size_t len = strlen (name) + 1;
                    532:
                    533:        close_script ();
                    534:        script_name = malloc (len);
                    535:        strlcpy (script_name, name, len);
                    536: }
                    537:
                    538: int    reserved (char *string, int t)
                    539: {
                    540:        if (tokens[t].type == 0 && strcmpi (tokens[t].name, string) == 0)
                    541:                return (1);
                    542:        return (0);
                    543: }
                    544:
                    545: int    CheckPhase (int t)
                    546: {
                    547:        int     i;
                    548:
                    549:        for (i = 0; i < 8; ++i) {
                    550:                if (reserved (phases[i], t)) {
                    551:                        inst0 |= i << 24;
                    552:                        return (1);
                    553:                }
                    554:        }
                    555:        return (0);
                    556: }
                    557:
                    558: int    CheckRegister (int t)
                    559: {
                    560:        int     i;
                    561:
                    562:        if(arch == 710) {
                    563:                for (i = 0; i < 64; ++i)
                    564:                        if (reserved (regs710[i], t))
                    565:                                return i;
                    566:        }
                    567:        else if (arch == 720) {
                    568:                for (i = 0; i < 96; ++i)
                    569:                        if (reserved (regs720[i], t))
                    570:                                return i;
                    571:        }
                    572:        else {
                    573:                errout("'ARCH' statement missing");
                    574:        }
                    575:        return (-1);
                    576: }
                    577:
                    578: int    expression (int *t)
                    579: {
                    580:        int     value;
                    581:        int     i = *t;
                    582:
                    583:        value = evaluate (i++);
                    584:        while (i < ntokens) {
                    585:                if (tokens[i].type == '+')
                    586:                        value += evaluate (i + 1);
                    587:                else if (tokens[i].type == '-')
                    588:                        value -= evaluate (i + 1);
                    589:                else
                    590:                        errout ("Unknown identifier");
                    591:                i += 2;
                    592:        }
                    593:        *t = i;
                    594:        return (value);
                    595: }
                    596:
                    597: int    evaluate (t)
                    598: {
                    599:        int     value;
                    600:        char    *name;
                    601:
                    602:        if (tokens[t].type) {
                    603:                errout ("Expected an identifier");
                    604:                return (0);
                    605:        }
                    606:        name = tokens[t].name;
                    607:        if (*name >= '0' && *name <= '9')
                    608:                value = number (name);
                    609:        else
                    610:                value = lookup (name);
                    611:        return (value);
                    612: }
                    613:
                    614: int    number (char *s)
                    615: {
                    616:        int     value;
                    617:        int     n;
                    618:        int     radix;
                    619:
                    620:        radix = 10;
                    621:        if (*s == '0') {
                    622:                ++s;
                    623:                radix = 8;
                    624:                switch (*s) {
                    625:                case 'x':
                    626:                case 'X':
                    627:                        radix = 16;
                    628:                        break;
                    629:                case 'b':
                    630:                case 'B':
                    631:                        radix = 2;
                    632:                }
                    633:                if (radix != 8)
                    634:                        ++s;
                    635:        }
                    636:        value = 0;
                    637:        while (*s) {
                    638:                n = *s++;
                    639:                if (n >= '0' && n <= '9')
                    640:                        n -= '0';
                    641:                else if (n >= 'a' && n <= 'f')
                    642:                        n -= 'a' - 10;
                    643:                else if (n >= 'A' && n <= 'F')
                    644:                        n -= 'A' - 10;
                    645:                else {
                    646:                        error_line();
                    647:                        fprintf (errfp, "*** Expected digit\n", n = 0);
                    648:                }
                    649:                if (n >= radix)
                    650:                        errout ("Expected digit");
                    651:                else
                    652:                        value = value * radix + n;
                    653:        }
                    654:        return (value);
                    655: }
                    656:
                    657: int    lookup (char *name)
                    658: {
                    659:        int     i;
                    660:        struct patchlist *p;
                    661:        size_t  len;
                    662:
                    663:        for (i = 0; i < nsymbols; ++i) {
                    664:                if (strcmp (name, symbols[i].name) == 0) {
                    665:                        if ((symbols[i].flags & F_DEFINED) == 0) {
                    666:                                p = (struct patchlist *) &symbols[i].patchlist;
                    667:                                while (p->next)
                    668:                                        p = p->next;
                    669:                                p->next = (struct patchlist *) malloc (sizeof (struct patchlist));
                    670:                                p = p->next;
                    671:                                p->next = NULL;
                    672:                                p->offset = dsps + 4;
                    673:                        }
                    674:                        return ((int) symbols[i].value);
                    675:                }
                    676:        }
                    677:        if (nsymbols >= MAXSYMBOLS) {
                    678:                errout ("Symbol table full");
                    679:                return (0);
                    680:        }
                    681:        symbols[nsymbols].type = S_LABEL;       /* assume forward reference */
                    682:        symbols[nsymbols].flags = 0;
                    683:        symbols[nsymbols].value = 0;
                    684:        p = (struct patchlist *) malloc (sizeof (struct patchlist));
                    685:        symbols[nsymbols].patchlist = p;
                    686:        p->next = NULL;
                    687:        p->offset = dsps + 4;
                    688:        len = strlen (name) + 1;
                    689:        symbols[nsymbols].name = malloc (len);
                    690:        strlcpy (symbols[nsymbols].name, name, len);
                    691:        ++nsymbols;
                    692:        return (0);
                    693: }
                    694:
                    695: void   f_arch (void)
                    696: {
                    697:        int i, archsave;
                    698:
                    699:        i = tokenix;
                    700:
                    701:        archsave = arch;
                    702:        arch = 0;
                    703:        arch = atoi(tokens[i].name);
                    704:        if( arch != 710 && arch != 720) {
                    705:                errout("Unrecognized ARCH");
                    706:                arch = archsave;
                    707:        }
                    708: }
                    709:
                    710: void   f_proc (void)
                    711: {
                    712:        if (tokens[tokenix].type != 0 || tokens[tokenix + 1].type != ':')
                    713:                errout ("Invalid PROC statement");
                    714:        else
                    715:                new_script (tokens[tokenix].name);
                    716: }
                    717:
                    718: void   f_pass (void)
                    719: {
                    720:        errout ("PASS option not implemented");
                    721: }
                    722:
                    723: /*
                    724:  *     f_list:  process list of symbols for the ENTRY and EXTERNAL directive
                    725:  */
                    726:
                    727: void   f_list (void)
                    728: {
                    729:        int     i;
                    730:        short   type;
                    731:        short   flags;
                    732:
                    733:        type = strcmpi (tokens[tokenix-1].name, "ENTRY") ? S_EXTERNAL : S_LABEL;
                    734:        flags = type == S_LABEL ? F_ENTRY : 0;
                    735:        for (i = tokenix; i < ntokens; ++i) {
                    736:                if (tokens[i].type != 0) {
                    737:                        errout ("Expected an identifier");
                    738:                        return;
                    739:                }
                    740:                define_symbol (tokens[i].name, 0, type, flags);
                    741:                if (i + 1 < ntokens) {
                    742:                        if (tokens[++i].type == ',')
                    743:                                continue;
                    744:                        errout ("Expected a separator");
                    745:                        return;
                    746:                }
                    747:        }
                    748: }
                    749:
                    750: /*
                    751:  *     f_define:       process list of definitions for ABSOLUTE and RELATIVE directive
                    752:  */
                    753:
                    754: void   f_define (void)
                    755: {
                    756:        int     i;
                    757:        char    *name;
                    758:        unsigned long value;
                    759:        int     type;
                    760:
                    761:        type = strcmpi (tokens[tokenix-1].name, "ABSOLUTE") ? S_RELATIVE : S_ABSOLUTE;
                    762:        i = tokenix;
                    763:        while (i < ntokens) {
                    764:                if (tokens[i].type) {
                    765:                        errout ("Expected an identifier");
                    766:                        return;
                    767:                }
                    768:                if (tokens[i + 1].type != '=') {
                    769:                        errout ("Expected a separator");
                    770:                        return;
                    771:                }
                    772:                name = tokens[i].name;
                    773:                i += 2;
                    774:                value = expression (&i);
                    775:                define_symbol (name, value, type, F_DEFINED);
                    776:        }
                    777: }
                    778:
                    779: void   store_inst ()
                    780: {
                    781:        int     i = dsps / 4;
                    782:        int     l = 8;
                    783:
                    784:        if ((inst0 & 0xc0000000) == 0xc0000000)
                    785:                l = 12;                 /* Memory to memory move is 12 bytes */
                    786:        if ((dsps + l) / 4 > MAXINST) {
                    787:                errout ("Instruction table overflow");
                    788:                return;
                    789:        }
                    790:        script[i++] = inst0;
                    791:        script[i++] = inst1;
                    792:        if (l == 12)
                    793:                script[i] = inst2;
                    794:        if (listfp) {
                    795:                fprintf (listfp, "\t%04x: %08x %08x", dsps, inst0, inst1);
                    796:                if (l == 12)
                    797:                        fprintf (listfp, " %08x", inst2);
                    798:                fprintf (listfp, "\n");
                    799:        }
                    800:        dsps += l;
                    801:        inst0 = inst1 = inst2 = 0;
                    802:        ++ninsts;
                    803: }
                    804:
                    805: void   f_move (void)
                    806: {
                    807:        if (reserved ("memory", tokenix))
                    808:                memory_to_memory ();
                    809:        else if (reserved ("from", tokenix) || tokens[tokenix+1].type == ',')
                    810:                block_move ();
                    811:        else
                    812:                register_write ();
                    813:        store_inst ();
                    814: }
                    815:
                    816: void   f_jump (void)
                    817: {
                    818:        transfer (0x80000000, 0);
                    819: }
                    820:
                    821: void   f_call (void)
                    822: {
                    823:        transfer (0x88000000, 0);
                    824: }
                    825:
                    826: void   f_return (void)
                    827: {
                    828:        transfer (0x90000000, 1);
                    829: }
                    830:
                    831: void   f_int (void)
                    832: {
                    833:        transfer (0x98000000, 2);
                    834: }
                    835:
                    836: void   f_select (void)
                    837: {
                    838:        int     t = tokenix;
                    839:
                    840:        if (reserved ("atn", t)) {
                    841:                inst0 = 0x01000000;
                    842:                ++t;
                    843:        }
                    844:        select_reselect (t);
                    845: }
                    846:
                    847: void   f_reselect (void)
                    848: {
                    849:        select_reselect (tokenix);
                    850: }
                    851:
                    852: void   f_wait (void)
                    853: {
                    854:        int     i = tokenix;
                    855:
                    856:        inst1 = 0;
                    857:        if (reserved ("disconnect", i)) {
                    858:                inst0 = 0x48000000;
                    859:        }
                    860:        else {
                    861:                if (reserved ("reselect", i))
                    862:                        inst0 = 0x50000000;
                    863:                else if (reserved ("select", i))
                    864:                        inst0 = 0x50000000;
                    865:                else
                    866:                        errout ("Expected SELECT or RESELECT");
                    867:                ++i;
                    868:                if (reserved ("rel", i)) {
                    869:                        i += 2;
                    870:                        inst1 = evaluate (i) - dsps - 8;
                    871:                        inst0 |= 0x04000000;
                    872:                }
                    873:                else
                    874:                        inst1 = evaluate (i);
                    875:        }
                    876:        store_inst ();
                    877: }
                    878:
                    879: void   f_disconnect (void)
                    880: {
                    881:        inst0 = 0x48000000;
                    882:        store_inst ();
                    883: }
                    884:
                    885: void   f_set (void)
                    886: {
                    887:        set_clear (0x58000000);
                    888: }
                    889:
                    890: void   f_clear (void)
                    891: {
                    892:        set_clear (0x60000000);
                    893: }
                    894:
                    895: void   transfer (int word0, int type)
                    896: {
                    897:        int     i;
                    898:
                    899:        i = tokenix;
                    900:        inst0 = word0;
                    901:        if (type == 0 && reserved ("rel", i)) {
                    902:                inst1 = evaluate (i + 2) - dsps - 8;
                    903:                i += 3;
                    904:                inst0 |= 0x00800000;
                    905:        }
                    906:        else if (type != 1) {
                    907:                inst1 = evaluate (i);
                    908:        }
                    909:        ++i;
                    910:        if (i >= ntokens) {
                    911:                inst0 |= 0x00080000;
                    912:                store_inst ();
                    913:                return;
                    914:        }
                    915:        if (tokens[i].type != ',')
                    916:                errout ("Expected a separator, ',' assumed");
                    917:        else
                    918:                ++i;
                    919:        if (reserved("when", i))
                    920:                inst0 |= 0x00010000;
                    921:        else if (reserved ("if", i) == 0) {
                    922:                errout ("Expected a reserved word");
                    923:                store_inst ();
                    924:                return;
                    925:        }
                    926:        if (reserved ("not", ++i))
                    927:                ++i;
                    928:        else
                    929:                inst0 |= 0x00080000;
                    930:        if (reserved ("atn", i)) {
                    931:                inst0 |= 0x00020000;
                    932:                ++i;
                    933:        } else if (CheckPhase (i)) {
                    934:                inst0 |= 0x00020000;
                    935:                ++i;
                    936:        }
                    937:        if (i < ntokens && tokens[i].type != ',') {
                    938:                if (inst0 & 0x00020000) {
                    939:                        if (inst0 & 0x00080000 && reserved ("and", i)) {
                    940:                                ++i;
                    941:                        }
                    942:                        else if ((inst0 & 0x00080000) == 0 && reserved ("or", i)) {
                    943:                                ++i;
                    944:                        }
                    945:                        else
                    946:                                errout ("Expected a reserved word");
                    947:                }
                    948:                inst0 |= 0x00040000 + (evaluate (i++) & 0xff);
                    949:        }
                    950:        if (i < ntokens) {
                    951:                if (tokens[i].type == ',')
                    952:                        ++i;
                    953:                else
                    954:                        errout ("Expected a separator, ',' assumed");
                    955:                if (reserved ("and", i) && reserved ("mask", i + 1))
                    956:                        inst0 |= ((evaluate (i + 2) & 0xff) << 8);
                    957:                else
                    958:                        errout ("Expected , AND MASK");
                    959:        }
                    960:        store_inst ();
                    961: }
                    962:
                    963: void   select_reselect (int t)
                    964: {
                    965:        inst0 |= 0x40000000;            /* ATN may be set from SELECT */
                    966:        if (reserved ("from", t)) {
                    967:                ++t;
                    968:                inst0 |= 0x02000000 | evaluate (t++);
                    969:        }
                    970:        else
                    971:                inst0 |= (evaluate (t++) & 0xff) << 16;
                    972:        if (tokens[t++].type == ',') {
                    973:                if (reserved ("rel", t)) {
                    974:                        inst0 |= 0x04000000;
                    975:                        inst1 = evaluate (t + 2) - dsps - 8;
                    976:                }
                    977:                else
                    978:                        inst1 = evaluate (t);
                    979:        }
                    980:        else
                    981:                errout ("Expected separator");
                    982:        store_inst ();
                    983: }
                    984:
                    985: void   set_clear (unsigned long code)
                    986: {
                    987:        int     i = tokenix;
                    988:        short   need_and = 0;
                    989:
                    990:        inst0 = code;
                    991:        while (i < ntokens) {
                    992:                if (need_and) {
                    993:                        if (reserved ("and", i))
                    994:                                ++i;
                    995:                        else
                    996:                                errout ("Expected AND");
                    997:                }
                    998:                if (reserved ("atn", i)) {
                    999:                        inst0 |= 0x0008;
                   1000:                        ++i;
                   1001:                }
                   1002:                else if (reserved ("ack", i)) {
                   1003:                        inst0 |= 0x0040;
                   1004:                        ++i;
                   1005:                }
                   1006:                else if (reserved ("target", i)) {
                   1007:                        inst0 |= 0x0200;
                   1008:                        ++i;
                   1009:                }
                   1010:                else
                   1011:                        errout ("Expected ATN, ACK, or TARGET");
                   1012:                need_and = 1;
                   1013:        }
                   1014:        store_inst ();
                   1015: }
                   1016:
                   1017: void   block_move ()
                   1018: {
                   1019:        int     t;
                   1020:
                   1021:        if (reserved ("from", tokenix)) {
                   1022:                inst1 = evaluate (tokenix+1);
                   1023:                inst0 |= 0x10000000 | inst1;    /*** ??? to match Zeus script */
                   1024:                tokenix += 2;
                   1025:        }
                   1026:        else {
                   1027:                inst0 |= evaluate (tokenix++);  /* count */
                   1028:                tokenix++;                      /* skip ',' */
                   1029:                if (reserved ("ptr", tokenix)) {
                   1030:                        ++ tokenix;
                   1031:                        inst0 |= 0x20000000;
                   1032:                }
                   1033:                inst1 = evaluate (tokenix++);   /* address */
                   1034:        }
                   1035:        if (tokens[tokenix].type != ',')
                   1036:                errout ("Expected separator");
                   1037:        if (reserved ("when", tokenix + 1)) {
                   1038:                inst0 |= 0x08000000;
                   1039:                CheckPhase (tokenix + 2);
                   1040:        }
                   1041:        else if (reserved ("with", tokenix + 1)) {
                   1042:                CheckPhase (tokenix + 2);
                   1043:        }
                   1044:        else
                   1045:                errout ("Expected WITH or WHEN");
                   1046: }
                   1047:
                   1048: void   register_write ()
                   1049: {
                   1050:        /*
                   1051:         * MOVE reg/data8 TO reg                        register write
                   1052:         * MOVE reg <op> data8 TO reg                   register write
                   1053:         */
                   1054:        int     op;
                   1055:        int     reg;
                   1056:        int     data;
                   1057:
                   1058:        if (reserved ("to", tokenix+1))
                   1059:                op = 0;
                   1060:        else if (tokens[tokenix+1].type == '|')
                   1061:                op = 1;
                   1062:        else if (tokens[tokenix+1].type == '&')
                   1063:                op = 2;
                   1064:        else if (tokens[tokenix+1].type == '+')
                   1065:                op = 3;
                   1066:        else if (tokens[tokenix+1].type == '-')
                   1067:                op = 4;
                   1068:        else
                   1069:                errout ("Unknown register operator");
                   1070:        if (op && reserved ("to", tokenix+3) == 0)
                   1071:                errout ("Register command expected TO");
                   1072:        reg = CheckRegister (tokenix);
                   1073:        if (reg < 0) {                  /* Not register, must be data */
                   1074:                data = evaluate (tokenix);
                   1075:                if (op)
                   1076:                        errout ("Register operator not move");
                   1077:                reg = CheckRegister (tokenix+2);
                   1078:                if (reg < 0)
                   1079:                        errout ("Expected register");
                   1080:                inst0 = 0x78000000 | (data << 8) | reg;
                   1081: #if 0
                   1082: fprintf (listfp, "Move data to register: %02x %d\n", data, reg);
                   1083: #endif
                   1084:        }
                   1085:        else if (op) {                  /* A register read/write operator */
                   1086:                data = evaluate (tokenix+2);
                   1087:                if (op == 4) {
                   1088:                        data = -data;
                   1089:                        op = 3;
                   1090:                }
                   1091:                inst0 = (data & 0xff) << 8;
                   1092:                data = CheckRegister (tokenix+4);
                   1093:                if (data < 0)
                   1094:                        errout ("Expected register");
                   1095:                if (reg != data && reg != 8 && data != 8)
                   1096:                        errout ("One register MUST be SBFR");
                   1097:                if (reg == data) {      /* A register read/modify/write */
                   1098: #if 0
                   1099: fprintf (listfp, "Read/modify register: %02x %d %d\n", inst0 >> 8, op, reg);
                   1100: #endif
                   1101:                        inst0 |= 0x78000000 | (op << 25) | (reg << 16);
                   1102:                }
                   1103:                else {                  /* A move to/from SFBR */
                   1104:                        if (reg == 8) { /* MOVE SFBR <> TO reg */
                   1105: #if 0
                   1106: fprintf (listfp, "Move SFBR to register: %02x %d %d\n", inst0 >> 8, op, data);
                   1107: #endif
                   1108:                                inst0 |= 0x68000000 | (op << 25) | (data << 16);
                   1109:                        }
                   1110:                        else {
                   1111: #if 0
                   1112: fprintf (listfp, "Move register to SFBR: %02x %d %d\n", inst0 >> 8, op, reg);
                   1113: #endif
                   1114:                                inst0 |= 0x70000000 | (op << 25) | (reg << 16);
                   1115:                        }
                   1116:                }
                   1117:        }
                   1118:        else {                          /* register to register */
                   1119:                data = CheckRegister (tokenix+2);
                   1120:                if (reg == 8)           /* move SFBR to reg */
                   1121:                        inst0 = 0x6a000000 | (data << 16);
                   1122:                else if (data == 8)     /* move reg to SFBR */
                   1123:                        inst0 = 0x72000000 | (reg << 16);
                   1124:                else
                   1125:                        errout ("One register must be SFBR");
                   1126:        }
                   1127: }
                   1128:
                   1129: void   memory_to_memory ()
                   1130: {
                   1131:        inst0 = 0xc0000000 + evaluate (tokenix+1);
                   1132:        inst1 = evaluate (tokenix+3);
                   1133:        inst2 = evaluate (tokenix+5);
                   1134: }
                   1135:
                   1136: void   error_line()
                   1137: {
                   1138:        if (errfp != listfp && errfp && err_listed == 0) {
                   1139:                fprintf (errfp, "%3d:  %s", lineno, inbuf);
                   1140:                err_listed = 1;
                   1141:        }
                   1142: }
                   1143:
                   1144: char * makefn (base, sub)
                   1145:        char *base;
                   1146:        char *sub;
                   1147: {
                   1148:        char *fn;
                   1149:        size_t len = strlen (base) + strlen (sub) + 2;
                   1150:
                   1151:        fn = malloc (len);
                   1152:        strlcpy (fn, base, len);
                   1153:        base = strrchr(fn, '.');
                   1154:        if (base)
                   1155:                *base = 0;
                   1156:        strlcat (fn, ".", len);
                   1157:        strlcat (fn, sub, len);
                   1158:        return (fn);
                   1159: }
                   1160:
                   1161: void   usage()
                   1162: {
                   1163:        fprintf (stderr, "usage: scc sourcfile [options]\n");
                   1164:        exit(1);
                   1165: }

CVSweb