root/dev/microcode/ncr53cxxx/ncr53cxxx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. main
  2. emit_symbols
  3. list_symbols
  4. errout
  5. parse
  6. process
  7. define_symbol
  8. close_script
  9. new_script
  10. reserved
  11. CheckPhase
  12. CheckRegister
  13. expression
  14. evaluate
  15. number
  16. lookup
  17. f_arch
  18. f_proc
  19. f_pass
  20. f_list
  21. f_define
  22. store_inst
  23. f_move
  24. f_jump
  25. f_call
  26. f_return
  27. f_int
  28. f_select
  29. f_reselect
  30. f_wait
  31. f_disconnect
  32. f_set
  33. f_clear
  34. transfer
  35. select_reselect
  36. set_clear
  37. block_move
  38. register_write
  39. memory_to_memory
  40. error_line
  41. makefn
  42. usage

    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 }

/* [<][>][^][v][top][bottom][index][help] */