root/dev/microcode/siop/ncr53cxxx.c

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

DEFINITIONS

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

    1 /*      $OpenBSD: ncr53cxxx.c,v 1.7 2005/10/08 15:54:49 krw Exp $ */
    2 /*      $NetBSD: ncr53cxxx.c,v 1.14 2005/02/11 06:21:22 simonb Exp $    */
    3 
    4 /*
    5  * Copyright (c) 1995,1999 Michael L. Hitch
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Michael L. Hitch.
   19  * 4. The name of the author may not be used to endorse or promote products
   20  *    derived from this software without specific prior written permission
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 /*      ncr53cxxx.c     - SCSI SCRIPTS Assembler                */
   35 
   36 #include <stdio.h>
   37 #include <stdlib.h>
   38 #include <string.h>
   39 #include <time.h>
   40 
   41 #ifndef AMIGA
   42 #define strcmpi strcasecmp
   43 #endif
   44 
   45 #define MAXTOKENS       16
   46 #define MAXINST         1024
   47 #define MAXSYMBOLS      128
   48 
   49 struct {
   50         int     type;
   51         char    *name;
   52 } tokens[MAXTOKENS];
   53 int     ntokens;
   54 int     tokenix;
   55 
   56 void    f_proc (void);
   57 void    f_pass (void);
   58 void    f_list (void);          /* ENTRY, EXTERNAL label list */
   59 void    f_define (void);        /* ABSOLUTE, RELATIVE label list */
   60 void    f_move (void);
   61 void    f_jump (void);
   62 void    f_call (void);
   63 void    f_return (void);
   64 void    f_int (void);
   65 void    f_intfly (void);
   66 void    f_select (void);
   67 void    f_reselect (void);
   68 void    f_wait (void);
   69 void    f_disconnect (void);
   70 void    f_set (void);
   71 void    f_clear (void);
   72 void    f_load (void);
   73 void    f_store (void);
   74 void    f_nop (void);
   75 void    f_arch (void);
   76 
   77 struct {
   78         char    *name;
   79         void    (*func)(void);
   80 } directives[] = {
   81         {"PROC",        f_proc},
   82         {"PASS",        f_pass},
   83         {"ENTRY",       f_list},
   84         {"ABSOLUTE",    f_define},
   85         {"EXTERN",      f_list},
   86         {"EXTERNAL",    f_list},
   87         {"RELATIVE",    f_define},
   88         {"MOVE",        f_move},
   89         {"JUMP",        f_jump},
   90         {"CALL",        f_call},
   91         {"RETURN",      f_return},
   92         {"INT",         f_int},
   93         {"INTFLY",      f_intfly},
   94         {"SELECT",      f_select},
   95         {"RESELECT",    f_reselect},
   96         {"WAIT",        f_wait},
   97         {"DISCONNECT",  f_disconnect},
   98         {"SET",         f_set},
   99         {"CLEAR",       f_clear},
  100         {"LOAD",        f_load},
  101         {"STORE",       f_store},
  102         {"NOP",         f_nop},
  103         {"ARCH",        f_arch},
  104         {NULL, NULL}};
  105 
  106 u_int32_t script[MAXINST];
  107 int     dsps;
  108 char    *script_name = "SCRIPT";
  109 u_int32_t inst0, inst1, inst2;
  110 unsigned int    ninsts;
  111 unsigned int    npatches;
  112 
  113 struct patchlist {
  114         struct patchlist *next;
  115         unsigned        offset;
  116 } *patches;
  117 
  118 #define S_LABEL         0x0000
  119 #define S_ABSOLUTE      0x0001
  120 #define S_RELATIVE      0x0002
  121 #define S_EXTERNAL      0x0003
  122 #define F_DEFINED       0x0001
  123 #define F_ENTRY         0x0002
  124 struct {
  125         short   type;
  126         short   flags;
  127         u_int32_t value;
  128         struct patchlist *patchlist;
  129         char    *name;
  130 } symbols[MAXSYMBOLS];
  131 int nsymbols;
  132 
  133 char    *stypes[] = {"Label", "Absolute", "Relative", "External"};
  134 
  135 char    *phases[] = {
  136         "data_out", "data_in", "cmd", "status",
  137         "res4", "res5", "msg_out", "msg_in"
  138 };
  139 
  140 struct ncrregs {
  141         char *name;
  142         int addr[5];
  143 };
  144 #define ARCH700 1
  145 #define ARCH710 2
  146 #define ARCH720 3
  147 #define ARCH810 4
  148 #define ARCH825 5
  149 
  150 struct ncrregs  regs[] = {
  151         {"scntl0",      {0x00, 0x00, 0x00, 0x00, 0x00}},
  152         {"scntl1",      {0x01, 0x01, 0x01, 0x01, 0x01}},
  153         {"sdid",        {0x02, 0x02,   -1,   -1,   -1}},
  154         {"sien",        {0x03, 0x03,   -1,   -1,   -1}},
  155         {"scid",        {0x04, 0x04,   -1,   -1,   -1}},
  156         {"scntl2",      {  -1,   -1, 0x02, 0x02, 0x02}},
  157         {"scntl3",      {  -1,   -1, 0x03, 0x03, 0x03}},
  158         {"scid",        {  -1,   -1, 0x04, 0x04, 0x04}},
  159         {"sxfer",       {0x05, 0x05, 0x05, 0x05, 0x05}},
  160         {"sodl",        {0x06, 0x06,   -1,   -1,   -1}},
  161         {"socl",        {0x07, 0x07,   -1,   -1,   -1}},
  162         {"sdid",        {  -1,   -1, 0x06, 0x06, 0x06}},
  163         {"gpreg",       {  -1,   -1, 0x07, 0x07, 0x07}},
  164         {"sfbr",        {0x08, 0x08, 0x08, 0x08, 0x08}},
  165         {"sidl",        {0x09, 0x09,   -1,   -1,   -1}},
  166         {"sbdl",        {0x0a, 0x0a,   -1,   -1,   -1}},
  167         {"socl",        {  -1,   -1, 0x09, 0x09, 0x09}},
  168         {"ssid",        {  -1,   -1, 0x0a, 0x0a, 0x0a}},
  169         {"sbcl",        {0x0b, 0x0b, 0x0b, 0x0b, 0x0b}}, 
  170         {"dstat",       {0x0c, 0x0c, 0x0c, 0x0c, 0x0c}},
  171         {"sstat0",      {0x0d, 0x0d, 0x0d, 0x0d, 0x0d}},
  172         {"sstat1",      {0x0e, 0x0e, 0x0e, 0x0e, 0x0e}},
  173         {"sstat2",      {0x0f, 0x0f, 0x0f, 0x0f, 0x0f}},
  174         {"dsa0",        {  -1, 0x10, 0x10, 0x10, 0x10}},
  175         {"dsa1",        {  -1, 0x11, 0x11, 0x11, 0x11}},
  176         {"dsa2",        {  -1, 0x12, 0x12, 0x12, 0x12}},
  177         {"dsa3",        {  -1, 0x13, 0x13, 0x13, 0x13}},
  178         {"ctest0",      {0x14, 0x14, 0x18, 0x18, 0x18}},
  179         {"ctest1",      {0x15, 0x15, 0x19, 0x19, 0x19}},
  180         {"ctest2",      {0x16, 0x16, 0x1a, 0x1a, 0x1a}},
  181         {"ctest3",      {0x17, 0x17, 0x1b, 0x1b, 0x1b}},
  182         {"ctest4",      {0x18, 0x18, 0x21, 0x21, 0x21}},
  183         {"ctest5",      {0x19, 0x19, 0x22, 0x22, 0x22}},
  184         {"ctest6",      {0x1a, 0x1a, 0x23, 0x23, 0x23}},
  185         {"ctest7",      {0x1b, 0x1b,   -1,   -1,   -1}},
  186         {"temp0",       {0x1c, 0x1c, 0x1c, 0x1c, 0x1c}},
  187         {"temp1",       {0x1d, 0x1d, 0x1d, 0x1d, 0x1d}},
  188         {"temp2",       {0x1e, 0x1e, 0x1e, 0x1e, 0x1e}},
  189         {"temp3",       {0x1f, 0x1f, 0x1f, 0x1f, 0x1f}},
  190         {"dfifo",       {0x20, 0x20, 0x20, 0x20, 0x20}},
  191         {"istat",       {0x21, 0x21, 0x14, 0x14, 0x14}},
  192         {"ctest8",      {0x22, 0x22,   -1,   -1,   -1}},
  193         {"lcrc",        {  -1, 0x23,   -1,   -1,   -1}},
  194         {"ctest9",      {0x23,   -1,   -1,   -1,   -1}},
  195         {"dbc0",        {0x24, 0x24, 0x24, 0x24, 0x24}},
  196         {"dbc1",        {0x25, 0x25, 0x25, 0x25, 0x25}},
  197         {"dbc2",        {0x26, 0x26, 0x26, 0x26, 0x26}},
  198         {"dcmd",        {0x27, 0x27, 0x27, 0x27, 0x27}},
  199         {"dnad0",       {0x28, 0x28, 0x28, 0x28, 0x28}},
  200         {"dnad1",       {0x29, 0x29, 0x29, 0x29, 0x29}},
  201         {"dnad2",       {0x2a, 0x2a, 0x2a, 0x2a, 0x2a}},
  202         {"dnad3",       {0x2b, 0x2b, 0x2b, 0x2b, 0x2b}},
  203         {"dsp0",        {0x2c, 0x2c, 0x2c, 0x2c, 0x2c}},
  204         {"dsp1",        {0x2d, 0x2d, 0x2d, 0x2d, 0x2d}},
  205         {"dsp2",        {0x2e, 0x2e, 0x2e, 0x2e, 0x2e}},
  206         {"dsp3",        {0x2f, 0x2f, 0x2f, 0x2f, 0x2f}},
  207         {"dsps0",       {0x30, 0x30, 0x30, 0x30, 0x30}},
  208         {"dsps1",       {0x31, 0x31, 0x31, 0x31, 0x31}},
  209         {"dsps2",       {0x32, 0x32, 0x32, 0x32, 0x32}},
  210         {"dsps3",       {0x33, 0x33, 0x33, 0x33, 0x33}},
  211         {"scratch0",    {  -1, 0x34,   -1,   -1,   -1}},
  212         {"scratch1",    {  -1, 0x35,   -1,   -1,   -1}},
  213         {"scratch2",    {  -1, 0x36,   -1,   -1,   -1}},
  214         {"scratch3",    {  -1, 0x37,   -1,   -1,   -1}},
  215         {"scratcha0",   {0x10,   -1, 0x34, 0x34, 0x34}},
  216         {"scratcha1",   {0x11,   -1, 0x35, 0x35, 0x35}},
  217         {"scratcha2",   {0x12,   -1, 0x36, 0x36, 0x36}},
  218         {"scratcha3",   {0x13,   -1, 0x37, 0x37, 0x37}},
  219         {"dmode",       {0x34, 0x38, 0x38, 0x38, 0x38}},
  220         {"dien",        {0x39, 0x39, 0x39, 0x39, 0x39}},
  221         {"dwt",         {0x3a, 0x3a, 0x3a,   -1,   -1}},
  222         {"sbr",         {  -1,   -1,   -1, 0x3a, 0x3a}},
  223         {"dcntl",       {0x3b, 0x3b, 0x3b, 0x3b, 0x3b}},
  224         {"addr0",       {  -1, 0x3c, 0x3c, 0x3c, 0x3c}},
  225         {"addr1",       {  -1, 0x3d, 0x3d, 0x3d, 0x3d}},
  226         {"addr2",       {  -1, 0x3e, 0x3e, 0x3e, 0x3e}},
  227         {"addr3",       {  -1, 0x3f, 0x3f, 0x3f, 0x3f}},
  228         {"sien0",       {  -1,   -1, 0x40, 0x40, 0x40}},
  229         {"sien1",       {  -1,   -1, 0x41, 0x41, 0x41}},
  230         {"sist0",       {  -1,   -1, 0x42, 0x42, 0x42}},
  231         {"sist1",       {  -1,   -1, 0x43, 0x43, 0x43}},
  232         {"slpar",       {  -1,   -1, 0x44, 0x44, 0x44}},
  233         {"swide",       {  -1,   -1, 0x45,   -1, 0x45}},
  234         {"macntl",      {  -1,   -1, 0x46, 0x46, 0x46}},
  235         {"gpcntl",      {  -1,   -1, 0x47, 0x47, 0x47}},
  236         {"stime0",      {  -1,   -1, 0x48, 0x48, 0x48}},
  237         {"stime1",      {  -1,   -1, 0x49, 0x49, 0x49}},
  238         {"respid0",     {  -1,   -1, 0x4a, 0x4a, 0x4a}},
  239         {"respid1",     {  -1,   -1, 0x4b,   -1, 0x4b}},
  240         {"stest0",      {  -1,   -1, 0x4c, 0x4c, 0x4c}},
  241         {"stest1",      {  -1,   -1, 0x4d, 0x4d, 0x4d}},
  242         {"stest2",      {  -1,   -1, 0x4e, 0x4e, 0x4e}},
  243         {"stest3",      {  -1,   -1, 0x4f, 0x4f, 0x4f}},
  244         {"sidl0",       {  -1,   -1, 0x50, 0x50, 0x50}},
  245         {"sidl1",       {  -1,   -1, 0x51,   -1, 0x51}},
  246         {"sodl0",       {  -1,   -1, 0x54, 0x54, 0x54}},
  247         {"sodl1",       {  -1,   -1, 0x55,   -1, 0x55}},
  248         {"sbdl0",       {  -1,   -1, 0x58, 0x58, 0x58}},
  249         {"sbdl1",       {  -1,   -1, 0x59,   -1, 0x59}},
  250         {"scratchb0",   {0x3c,   -1, 0x5c, 0x5c, 0x5c}},
  251         {"scratchb1",   {0x3d,   -1, 0x5d, 0x5d, 0x5d}},
  252         {"scratchb2",   {0x3e,   -1, 0x5e, 0x5e, 0x5e}},
  253         {"scratchb3",   {0x3f,   -1, 0x5f, 0x5f, 0x5f}},
  254         {"scratchc0",   {  -1,   -1,   -1,   -1, 0x60}},
  255         {"scratchc1",   {  -1,   -1,   -1,   -1, 0x61}},
  256         {"scratchc2",   {  -1,   -1,   -1,   -1, 0x62}},
  257         {"scratchc3",   {  -1,   -1,   -1,   -1, 0x63}},
  258         {"scratchd0",   {  -1,   -1,   -1,   -1, 0x64}},
  259         {"scratchd1",   {  -1,   -1,   -1,   -1, 0x65}},
  260         {"scratchd2",   {  -1,   -1,   -1,   -1, 0x66}},
  261         {"scratchd3",   {  -1,   -1,   -1,   -1, 0x67}},
  262         {"scratche0",   {  -1,   -1,   -1,   -1, 0x68}},
  263         {"scratche1",   {  -1,   -1,   -1,   -1, 0x69}},
  264         {"scratche2",   {  -1,   -1,   -1,   -1, 0x6a}},
  265         {"scratche3",   {  -1,   -1,   -1,   -1, 0x6b}},
  266         {"scratchf0",   {  -1,   -1,   -1,   -1, 0x6c}},
  267         {"scratchf1",   {  -1,   -1,   -1,   -1, 0x6d}},
  268         {"scratchf2",   {  -1,   -1,   -1,   -1, 0x6e}},
  269         {"scratchf3",   {  -1,   -1,   -1,   -1, 0x6f}},
  270         {"scratchg0",   {  -1,   -1,   -1,   -1, 0x70}},
  271         {"scratchg1",   {  -1,   -1,   -1,   -1, 0x71}},
  272         {"scratchg2",   {  -1,   -1,   -1,   -1, 0x72}},
  273         {"scratchg3",   {  -1,   -1,   -1,   -1, 0x73}},
  274         {"scratchh0",   {  -1,   -1,   -1,   -1, 0x74}},
  275         {"scratchh1",   {  -1,   -1,   -1,   -1, 0x75}},
  276         {"scratchh2",   {  -1,   -1,   -1,   -1, 0x7e}},
  277         {"scratchh3",   {  -1,   -1,   -1,   -1, 0x77}},
  278         {"scratchi0",   {  -1,   -1,   -1,   -1, 0x78}},
  279         {"scratchi1",   {  -1,   -1,   -1,   -1, 0x79}},
  280         {"scratchi2",   {  -1,   -1,   -1,   -1, 0x7a}},
  281         {"scratchi3",   {  -1,   -1,   -1,   -1, 0x7b}},
  282         {"scratchj0",   {  -1,   -1,   -1,   -1, 0x7c}},
  283         {"scratchj1",   {  -1,   -1,   -1,   -1, 0x7d}},
  284         {"scratchj2",   {  -1,   -1,   -1,   -1, 0x7e}},
  285         {"scratchj3",   {  -1,   -1,   -1,   -1, 0x7f}},
  286 };
  287 
  288 int     lineno;
  289 int     err_listed;
  290 int     arch;
  291 int     partial_flag;
  292 
  293 char    inbuf[128];
  294 
  295 char    *sourcefile;
  296 char    *outputfile;
  297 char    *listfile;
  298 char    *errorfile;
  299 
  300 FILE    *infp;
  301 FILE    *outfp;
  302 FILE    *listfp;
  303 FILE    *errfp;
  304 
  305 void    setarch(char *);
  306 void    parse (void);
  307 void    process (void);
  308 void    emit_symbols (void);
  309 void    list_symbols (void);
  310 void    errout (char *);
  311 void    define_symbol (char *, u_int32_t, short, short);
  312 void    patch_label (void);
  313 void    close_script (void);
  314 void    new_script (char *);
  315 void    store_inst (void);
  316 int     expression (int *);
  317 int     evaluate (int);
  318 int     number (char *);
  319 int     lookup (char *);
  320 int     reserved (char *, int);
  321 int     CheckPhase (int);
  322 int     CheckRegister (int);
  323 void    transfer (int, int);
  324 void    select_reselect (int);
  325 void    set_clear (u_int32_t);
  326 void    block_move (void);
  327 void    register_write (void);
  328 void    memory_to_memory (void);
  329 void    loadstore (int);
  330 void    error_line(void);
  331 char    *makefn(char *, char *);
  332 void    usage(void);
  333 
  334 int
  335 main (int argc, char *argv[])
  336 {
  337         int     i;
  338         struct patchlist *p;
  339 
  340         if (argc < 2 || argv[1][0] == '-')
  341                 usage();
  342         sourcefile = argv[1];
  343         infp = fopen (sourcefile, "r");
  344         if (infp == NULL) {
  345                 perror ("open source");
  346                 fprintf (stderr, "scc: error opening source file %s\n", argv[1]);
  347                 exit (1);
  348         }
  349         /*
  350          * process options
  351          * -l [listfile]
  352          * -o [outputfile]
  353          * -p [outputfile]
  354          * -z [debugfile]
  355          * -e [errorfile]
  356          * -a arch
  357          * -v
  358          * -u
  359          */
  360         for (i = 2; i < argc; ++i) {
  361                 if (argv[i][0] != '-')
  362                         usage();
  363                 switch (argv[i][1]) {
  364                 case 'o':
  365                 case 'p':
  366                         partial_flag = argv[i][1] == 'p';
  367                         if (i + 1 >= argc || argv[i + 1][0] == '-')
  368                                 outputfile = makefn (sourcefile, "out");
  369                         else {
  370                                 outputfile = argv[i + 1];
  371                                 ++i;
  372                         }
  373                         break;
  374                 case 'l':
  375                         if (i + 1 >= argc || argv[i + 1][0] == '-')
  376                                 listfile = makefn (sourcefile, "lis");
  377                         else {
  378                                 listfile = argv[i + 1];
  379                                 ++i;
  380                         }
  381                         break;
  382                 case 'e':
  383                         if (i + 1 >= argc || argv[i + 1][0] == '-')
  384                                 errorfile = makefn (sourcefile, "err");
  385                         else {
  386                                 errorfile = argv[i + 1];
  387                                 ++i;
  388                         }
  389                         break;
  390                 case 'a':
  391                         if (i + 1 == argc)
  392                                 usage();
  393                         setarch(argv[i +1]);
  394                         if (arch == 0) {
  395                                 fprintf(stderr,"%s: bad arch '%s'\n",
  396                                         argv[0], argv[i +1]);
  397                                 exit(1);
  398                         }
  399                         ++i;
  400                         break;
  401                 default:
  402                         fprintf (stderr, "scc: unrecognized option '%c'\n",
  403                             argv[i][1]);
  404                         usage();
  405                 }
  406         }
  407         if (outputfile)
  408                 outfp = fopen (outputfile, "w");
  409         if (listfile)
  410                 listfp = fopen (listfile, "w");
  411         if (errorfile)
  412                 errfp = fopen (errorfile, "w");
  413         else
  414                 errfp = stderr;
  415 
  416         if (outfp) {
  417                 time_t cur_time;
  418 
  419                 fprintf(outfp, "/*\t$OpenBSD: ncr53cxxx.c,v 1.7 2005/10/08 15:54:49 krw Exp $\t*/\n");
  420                 fprintf(outfp, "/*\n");
  421                 fprintf(outfp, " *\tDO NOT EDIT - this file is automatically generated.\n");
  422                 time(&cur_time);
  423                 fprintf(outfp, " *\tcreated from %s on %s", sourcefile, ctime(&cur_time));
  424                 fprintf(outfp, " */\n");
  425         }
  426 
  427         while (fgets (inbuf, sizeof (inbuf), infp)) {
  428                 ++lineno;
  429                 if (listfp)
  430                         fprintf (listfp, "%3d:  %s", lineno, inbuf);
  431                 err_listed = 0;
  432                 parse ();
  433                 if (ntokens) {
  434 #ifdef DUMP_TOKENS
  435                         int     i;
  436 
  437                         fprintf (listfp, "      %d tokens\n", ntokens);
  438                         for (i = 0; i < ntokens; ++i) {
  439                                 fprintf (listfp, "      %d: ", i);
  440                                 if (tokens[i].type)
  441                                         fprintf (listfp,"'%c'\n", tokens[i].type);
  442                                 else
  443                                         fprintf (listfp, "%s\n", tokens[i].name);
  444                         }
  445 #endif
  446                         if (ntokens >= 2 && tokens[0].type == 0 &&
  447                             tokens[1].type == ':') {
  448                                 define_symbol (tokens[0].name, dsps, S_LABEL, F_DEFINED);
  449                                 tokenix += 2;
  450                         }
  451                         if (tokenix < ntokens)
  452                                 process ();
  453                 }
  454 
  455         }
  456         close_script ();
  457         emit_symbols ();
  458         if (outfp && !partial_flag) {
  459                 fprintf (outfp, "\nu_int32_t INSTRUCTIONS = 0x%08x;\n", ninsts);
  460                 fprintf (outfp, "u_int32_t PATCHES = 0x%08x;\n", npatches);
  461                 fprintf (outfp, "u_int32_t LABELPATCHES[] = {\n");
  462                 p = patches;
  463                 while (p) {
  464                         fprintf (outfp, "\t0x%08x,\n", p->offset / 4);
  465                         p = p->next;
  466                 }
  467                 fprintf (outfp, "};\n\n");
  468         }
  469         list_symbols ();
  470         exit(0);
  471 }
  472 
  473 void setarch(char *val)
  474 {
  475         switch (atoi(val)) {
  476         case 700:
  477                 arch = ARCH700;
  478                 break;
  479         case 710:
  480                 arch = ARCH710;
  481                 break;
  482         case 720:
  483                 arch = ARCH720;
  484                 break;
  485         case 810:
  486                 arch = ARCH810;
  487                 break;
  488         case 825:
  489                 arch = ARCH825;
  490                 break;
  491         default:
  492                 arch = 0;
  493         }
  494 }
  495 
  496 void emit_symbols ()
  497 {
  498         int     i;
  499         struct  patchlist *p;
  500 
  501         if (nsymbols == 0 || outfp == NULL)
  502                 return;
  503 
  504         for (i = 0; i < nsymbols; ++i) {
  505                 char    *code;
  506                 if ((symbols[i].flags & F_DEFINED) == 0 &&
  507                     symbols[i].type != S_EXTERNAL) {
  508                         fprintf(stderr, "warning: symbol %s undefined\n",
  509                             symbols[i].name);
  510                 }
  511                 if (symbols[i].type == S_ABSOLUTE)
  512                         code = "A_";
  513                 else if (symbols[i].type == S_RELATIVE)
  514                         code = "R_";
  515                 else if (symbols[i].type == S_EXTERNAL)
  516                         code = "E_";
  517                 else if (symbols[i].flags & F_ENTRY)
  518                         code = "Ent_";
  519                 else
  520                         continue;
  521                 fprintf (outfp, "#define\t%s%s\t0x%08x\n", code, symbols[i].name,
  522                         symbols[i].value);
  523                 if (symbols[i].flags & F_ENTRY || symbols[i].patchlist == NULL)
  524                         continue;
  525                 fprintf (outfp, "u_int32_t %s%s_Used[] = {\n", code, symbols[i].name);
  526 #if 1
  527                 p = symbols[i].patchlist;
  528                 while (p) {
  529                         fprintf (outfp, "\t0x%08x,\n", p->offset / 4);
  530                         p = p->next;
  531                 }
  532 #endif
  533                 fprintf (outfp, "};\n\n");
  534         }
  535         /* patches ? */
  536 }
  537 
  538 void list_symbols ()
  539 {
  540         int     i;
  541 
  542         if (nsymbols == 0 || listfp == NULL)
  543                 return;
  544         fprintf (listfp, "\n\nValue     Type     Symbol\n");
  545         for (i = 0; i < nsymbols; ++i) {
  546                 fprintf (listfp, "%08x: %-8s %s\n", symbols[i].value,
  547                         stypes[symbols[i].type], symbols[i].name);
  548         }
  549 }
  550 
  551 void errout (char *text)
  552 {
  553         error_line();
  554         fprintf (errfp, "*** %s ***\n", text);
  555 }
  556 
  557 void parse ()
  558 {
  559         char *p = inbuf;
  560         char c;
  561         char string[64];
  562         char *s;
  563         size_t len;
  564 
  565         ntokens = tokenix = 0;
  566         while (1) {
  567                 while ((c = *p++) && c != '\n' && (c <= ' ' || c == '\t'))
  568                         ;
  569                 if (c == '\n' || c == 0 || c == ';')
  570                         break;
  571                 if (ntokens >= MAXTOKENS) {
  572                         errout ("Token table full");
  573                         break;
  574                 }
  575                 if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
  576                     (c >= 'A' && c <= 'Z') || c == '$' || c == '_') {
  577                         s = string;
  578                         *s++ = c;
  579                         while (((c = *p) >= '0' && c <= '9') ||
  580                             (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
  581                             c == '_' || c == '$') {
  582                                 *s++ = *p++;
  583                         }
  584                         *s = 0;
  585                         len = strlen (string) + 1;
  586                         tokens[ntokens].name = malloc (len);
  587                         strlcpy (tokens[ntokens].name, string, len);
  588                         tokens[ntokens].type = 0;
  589                 }
  590                 else {
  591                         tokens[ntokens].type = c;
  592                 }
  593                 ++ntokens;
  594         }
  595         return;
  596 }
  597 
  598 void    process ()
  599 {
  600         int     i;
  601 
  602         if (tokens[tokenix].type) {
  603                 error_line();
  604                 fprintf (errfp, "Error: expected directive, found '%c'\n",
  605                         tokens[tokenix].type);
  606                 return;
  607         }
  608         for (i = 0; directives[i].name; ++i) {
  609                 if (strcmpi (directives[i].name, tokens[tokenix].name) == 0)
  610                         break;
  611         }
  612         if (directives[i].name == NULL) {
  613                 error_line();
  614                 fprintf (errfp, "Error: expected directive, found \"%s\"\n",
  615                         tokens[tokenix].name);
  616                 return;
  617         }
  618         if (directives[i].func == NULL) {
  619                 error_line();
  620                 fprintf (errfp, "No function for directive \"%s\"\n", tokens[tokenix].name);
  621         } else {
  622 #if 0
  623                 fprintf (listfp, "Processing directive \"%s\"\n", directives[i].name);
  624 #endif
  625                 ++tokenix;
  626                 (*directives[i].func) ();
  627         }
  628 }
  629 
  630 void define_symbol (char *name, u_int32_t value, short type, short flags)
  631 {
  632         int     i;
  633         struct patchlist *p;
  634         size_t  len;
  635 
  636         for (i = 0; i < nsymbols; ++i) {
  637                 if (symbols[i].type == type && strcmp (symbols[i].name, name) == 0) {
  638                         if (symbols[i].flags & F_DEFINED) {
  639                                 error_line();
  640                                 fprintf (errfp, "*** Symbol \"%s\" multiply defined\n",
  641                                         name);
  642                         } else {
  643                                 symbols[i].flags |= flags;
  644                                 symbols[i].value = value;
  645                                 p = symbols[i].patchlist;
  646                                 while (p) {
  647                                         if (p->offset > dsps)
  648                                                 errout ("Whoops\007");
  649                                         else
  650                                                 script[p->offset / 4] += dsps;
  651                                         p = p->next;
  652                                 }
  653                         }
  654                         return;
  655                 }
  656         }
  657         if (nsymbols >= MAXSYMBOLS) {
  658                 errout ("Symbol table full");
  659                 return;
  660         }
  661         symbols[nsymbols].type = type;
  662         symbols[nsymbols].flags = flags;
  663         symbols[nsymbols].value = value;
  664         symbols[nsymbols].patchlist = NULL;
  665         len = strlen (name) + 1;
  666         symbols[nsymbols].name = malloc (len);
  667         strlcpy (symbols[nsymbols].name, name, len);
  668         ++nsymbols;
  669 }
  670 
  671 void patch_label (void)
  672 {
  673         struct patchlist *p, **h;
  674 
  675         h = &patches;
  676         while(*h)
  677                 h = &(*h)->next;
  678         p = (struct patchlist *) malloc (sizeof (struct patchlist));
  679         *h = p;
  680         p->next = NULL;
  681         p->offset = dsps + 4;
  682         npatches++;
  683 }
  684 
  685 void close_script ()
  686 {
  687         int     i;
  688 
  689         if (dsps == 0)
  690                 return;
  691         if (outfp) {
  692                 fprintf (outfp, "const u_int32_t %s[] = {\n", script_name);
  693                 for (i = 0; i < dsps / 4; i += 2) {
  694                         fprintf (outfp, "\t0x%08x, 0x%08x", script[i],
  695                                 script[i + 1]);
  696                         /* check for memory move instruction */
  697                         if ((script[i] & 0xe0000000) == 0xc0000000)
  698                                 fprintf (outfp, ", 0x%08x,", script[i + 2]);
  699                         else
  700                                 if ((i + 2) <= dsps / 4) fprintf (outfp, ",\t\t");
  701                         fprintf (outfp, "\t/* %03x - %3d */\n", i * 4, i * 4);
  702                         if ((script[i] & 0xe0000000) == 0xc0000000)
  703                                 ++i;
  704                 }
  705                 fprintf (outfp, "};\n\n");
  706         }
  707         dsps = 0;
  708 }
  709 
  710 void new_script (char *name)
  711 {
  712         size_t len = strlen (name) + 1;
  713 
  714         close_script ();
  715         script_name = malloc (len);
  716         strlcpy (script_name, name, len);
  717 }
  718 
  719 int     reserved (char *string, int t)
  720 {
  721         if (tokens[t].type == 0 && strcmpi (tokens[t].name, string) == 0)
  722                 return (1);
  723         return (0);
  724 }
  725 
  726 int     CheckPhase (int t)
  727 {
  728         int     i;
  729 
  730         for (i = 0; i < 8; ++i) {
  731                 if (reserved (phases[i], t)) {
  732                         inst0 |= i << 24;
  733                         return (1);
  734                 }
  735         }
  736         return (0);
  737 }
  738 
  739 int     CheckRegister (int t)
  740 {
  741         int     i;
  742 
  743         if (arch <= 0) {
  744                 errout("'ARCH' statement missing");
  745                 return -1;
  746         }
  747         for (i = 0; i < (sizeof(regs) / sizeof(regs[0])); i++) {
  748                 if (regs[i].addr[arch - 1] >= 0 && reserved(regs[i].name, t))
  749                         return regs[i].addr[arch-1];
  750         }
  751         return (-1);
  752 }
  753 
  754 int     expression (int *t)
  755 {
  756         int     value;
  757         int     i = *t;
  758 
  759         value = evaluate (i++);
  760         while (i < ntokens) {
  761                 if (tokens[i].type == '+')
  762                         value += evaluate (i + 1);
  763                 else if (tokens[i].type == '-')
  764                         value -= evaluate (i + 1);
  765                 else
  766                         errout ("Unknown identifier");
  767                 i += 2;
  768         }
  769         *t = i;
  770         return (value);
  771 }
  772 
  773 int     evaluate (t)
  774 {
  775         int     value;
  776         char    *name;
  777 
  778         if (tokens[t].type) {
  779                 errout ("Expected an identifier");
  780                 return (0);
  781         }
  782         name = tokens[t].name;
  783         if (*name >= '0' && *name <= '9')
  784                 value = number (name);
  785         else
  786                 value = lookup (name);
  787         return (value);
  788 }
  789 
  790 int     number (char *s)
  791 {
  792         int     value;
  793         int     n;
  794         int     radix;
  795 
  796         radix = 10;
  797         if (*s == '0') {
  798                 ++s;
  799                 radix = 8;
  800                 switch (*s) {
  801                 case 'x':
  802                 case 'X':
  803                         radix = 16;
  804                         break;
  805                 case 'b':
  806                 case 'B':
  807                         radix = 2;
  808                 }
  809                 if (radix != 8)
  810                         ++s;
  811         }
  812         value = 0;
  813         while (*s) {
  814                 n = *s++;
  815                 if (n >= '0' && n <= '9')
  816                         n -= '0';
  817                 else if (n >= 'a' && n <= 'f')
  818                         n -= 'a' - 10;
  819                 else if (n >= 'A' && n <= 'F')
  820                         n -= 'A' - 10;
  821                 else {
  822                         error_line();
  823                         fprintf (errfp, "*** Expected digit\n");
  824                         n = 0;
  825                 }
  826                 if (n >= radix)
  827                         errout ("Expected digit");
  828                 else
  829                         value = value * radix + n;
  830         }
  831         return (value);
  832 }
  833 
  834 int     lookup (char *name)
  835 {
  836         int     i;
  837         struct patchlist *p;
  838         size_t  len;
  839 
  840         for (i = 0; i < nsymbols; ++i) {
  841                 if (strcmp (name, symbols[i].name) == 0) {
  842                         if ((symbols[i].flags & F_DEFINED) == 0) {
  843                                 p = (struct patchlist *) &symbols[i].patchlist;
  844                                 while (p->next)
  845                                         p = p->next;
  846                                 p->next = (struct patchlist *) malloc (sizeof (struct patchlist));
  847                                 p = p->next;
  848                                 p->next = NULL;
  849                                 p->offset = dsps + 4;
  850                         }
  851                         return ((int) symbols[i].value);
  852                 }
  853         }
  854         if (nsymbols >= MAXSYMBOLS) {
  855                 errout ("Symbol table full");
  856                 return (0);
  857         }
  858         symbols[nsymbols].type = S_LABEL;       /* assume forward reference */
  859         symbols[nsymbols].flags = 0;
  860         symbols[nsymbols].value = 0;
  861         p = (struct patchlist *) malloc (sizeof (struct patchlist));
  862         symbols[nsymbols].patchlist = p;
  863         p->next = NULL;
  864         p->offset = dsps + 4;
  865         len = strlen (name) + 1;
  866         symbols[nsymbols].name = malloc (len);
  867         strlcpy (symbols[nsymbols].name, name, len);
  868         ++nsymbols;
  869         return (0);
  870 }
  871 
  872 void    f_arch (void)
  873 {
  874         int i, archsave;
  875 
  876         i = tokenix;
  877 
  878         archsave = arch;
  879         setarch(tokens[i].name);
  880         if( arch == 0) {
  881                 errout("Unrecognized ARCH");
  882                 arch = archsave;
  883         }
  884 }
  885 
  886 void    f_proc (void)
  887 {
  888         if (tokens[tokenix].type != 0 || tokens[tokenix + 1].type != ':')
  889                 errout ("Invalid PROC statement");
  890         else
  891                 new_script (tokens[tokenix].name);
  892 }
  893 
  894 void    f_pass (void)
  895 {
  896         errout ("PASS option not implemented");
  897 }
  898 
  899 /*
  900  *      f_list:  process list of symbols for the ENTRY and EXTERNAL directive
  901  */
  902 
  903 void    f_list (void)
  904 {
  905         int     i;
  906         short   type;
  907         short   flags;
  908 
  909         type = strcmpi (tokens[tokenix-1].name, "ENTRY") ? S_EXTERNAL : S_LABEL;
  910         flags = type == S_LABEL ? F_ENTRY : 0;
  911         for (i = tokenix; i < ntokens; ++i) {
  912                 if (tokens[i].type != 0) {
  913                         errout ("Expected an identifier");
  914                         return;
  915                 }
  916                 define_symbol (tokens[i].name, 0, type, flags);
  917                 if (i + 1 < ntokens) {
  918                         if (tokens[++i].type == ',')
  919                                 continue;
  920                         errout ("Expected a separator");
  921                         return;
  922                 }
  923         }
  924 }
  925 
  926 /*
  927  *      f_define:       process list of definitions for ABSOLUTE and RELATIVE directive
  928  */
  929 
  930 void    f_define (void)
  931 {
  932         int     i;
  933         char    *name;
  934         u_int32_t value;
  935         int     type;
  936 
  937         type = strcmpi (tokens[tokenix-1].name, "ABSOLUTE") ? S_RELATIVE : S_ABSOLUTE;
  938         i = tokenix;
  939         while (i < ntokens) {
  940                 if (tokens[i].type) {
  941                         errout ("Expected an identifier");
  942                         return;
  943                 }
  944                 if (tokens[i + 1].type != '=') {
  945                         errout ("Expected a separator");
  946                         return;
  947                 }
  948                 name = tokens[i].name;
  949                 i += 2;
  950                 value = expression (&i);
  951                 define_symbol (name, value, type, F_DEFINED);
  952         }
  953 }
  954 
  955 void    store_inst ()
  956 {
  957         int     i = dsps / 4;
  958         int     l = 8;
  959 
  960         if ((inst0 & 0xe0000000) == 0xc0000000)
  961                 l = 12;                 /* Memory to memory move is 12 bytes */
  962         if ((dsps + l) / 4 > MAXINST) {
  963                 errout ("Instruction table overflow");
  964                 return;
  965         }
  966         script[i++] = inst0;
  967         script[i++] = inst1;
  968         if (l == 12)
  969                 script[i++] = inst2;
  970         if (listfp) {
  971                 fprintf (listfp, "\t%04x: %08x %08x", dsps, inst0, inst1);
  972                 if (l == 12)
  973                         fprintf (listfp, " %08x", inst2);
  974                 fprintf (listfp, "\n");
  975         }
  976         dsps += l;
  977         inst0 = inst1 = inst2 = 0;
  978         ++ninsts;
  979 }
  980 
  981 void    f_move (void)
  982 {
  983         if (reserved ("memory", tokenix))
  984                 memory_to_memory ();
  985         else if (reserved ("from", tokenix) || tokens[tokenix+1].type == ',')
  986                 block_move ();
  987         else
  988                 register_write ();
  989         store_inst ();
  990 }
  991 
  992 void    f_jump (void)
  993 {
  994         transfer (0x80000000, 0);
  995 }
  996 
  997 void    f_call (void)
  998 {
  999         transfer (0x88000000, 0);
 1000 }
 1001 
 1002 void    f_return (void)
 1003 {
 1004         transfer (0x90000000, 1);
 1005 }
 1006 
 1007 void    f_int (void)
 1008 {
 1009         transfer (0x98000000, 2);
 1010 }
 1011 
 1012 void    f_intfly (void)
 1013 {
 1014         transfer (0x98100000, 2);
 1015 }
 1016 
 1017 void    f_select (void)
 1018 {
 1019         int     t = tokenix;
 1020 
 1021         if (reserved ("atn", t)) {
 1022                 inst0 = 0x01000000;
 1023                 ++t;
 1024         }
 1025         select_reselect (t);
 1026 }
 1027 
 1028 void    f_reselect (void)
 1029 {
 1030         select_reselect (tokenix);
 1031 }
 1032 
 1033 void    f_wait (void)
 1034 {
 1035         int     i = tokenix;
 1036 
 1037         inst1 = 0;
 1038         if (reserved ("disconnect", i)) {
 1039                 inst0 = 0x48000000;
 1040         }
 1041         else {
 1042                 if (reserved ("reselect", i))
 1043                         inst0 = 0x50000000;
 1044                 else if (reserved ("select", i))
 1045                         inst0 = 0x50000000;
 1046                 else
 1047                         errout ("Expected SELECT or RESELECT");
 1048                 ++i;
 1049                 if (reserved ("rel", i)) {
 1050 #if 0 /* driver will fix relative dsps to absolute */
 1051                         if (arch < ARCH710) {
 1052                                 errout ("Wrong arch for relative dsps");
 1053                         }
 1054 #endif
 1055                         i += 2;
 1056                         inst1 = evaluate (i) - dsps - 8;
 1057                         inst0 |= 0x04000000;
 1058                 }
 1059                 else {
 1060                         inst1 = evaluate (i);
 1061                         patch_label();
 1062                 }
 1063         }
 1064         store_inst ();
 1065 }
 1066 
 1067 void    f_disconnect (void)
 1068 {
 1069         inst0 = 0x48000000;
 1070         store_inst ();
 1071 }
 1072 
 1073 void    f_set (void)
 1074 {
 1075         set_clear (0x58000000);
 1076 }
 1077 
 1078 void    f_clear (void)
 1079 {
 1080         set_clear (0x60000000);
 1081 }
 1082 
 1083 void    f_load (void)
 1084 {
 1085         inst0 = 0xe1000000;
 1086         if (arch < ARCH810) {
 1087                 errout ("Wrong arch for load/store");
 1088                 return;
 1089         }
 1090         loadstore(tokenix);
 1091 }
 1092 
 1093 void    f_store (void)
 1094 {
 1095         int i;
 1096         inst0 = 0xe0000000;
 1097         if (arch < ARCH810) {
 1098                 errout ("Wrong arch for load/store");
 1099                 return;
 1100         }
 1101         i = tokenix;
 1102         if (reserved("noflush", i)) {
 1103                 inst0 |= 0x2000000;
 1104                 i++;
 1105         }
 1106         loadstore(i);
 1107 }
 1108 
 1109 void    f_nop (void)
 1110 {
 1111         inst0 = 0x80000000;
 1112         inst1 = 0x00000000;
 1113         store_inst ();
 1114 }
 1115 
 1116 void loadstore(int i)
 1117 {
 1118         int reg, size;
 1119 
 1120         reg = CheckRegister(i);
 1121         if (reg < 0)    
 1122                 errout ("Expected register");
 1123         else
 1124                 inst0 |= reg <<  16;
 1125         if (reg == 8)
 1126                 errout ("Register can't be SFBR");
 1127         i++;
 1128         if (tokens[i].type == ',')
 1129                 i++;
 1130         else
 1131                 errout ("expected ','");
 1132         size = evaluate(i);
 1133         if (i < 1 || i > 4)
 1134                 errout("wrong size");
 1135         if ((reg & 0x3) + size > 4)
 1136                 errout("size too big for register");
 1137         inst0 |= size;
 1138         i++;
 1139         if (tokens[i].type == ',')
 1140                 i++;
 1141         else
 1142                 errout ("expected ','");
 1143         if (reserved("from", i) || reserved("dsarel", i)) {
 1144                 if (arch < ARCH710) {
 1145                         errout ("Wrong arch for table indirect");
 1146                         return;
 1147                 }
 1148                 i++;
 1149                 inst0 |= 0x10000000;
 1150         }
 1151         inst1 = evaluate(i);
 1152         store_inst ();
 1153 }
 1154 
 1155 void    transfer (int word0, int type)
 1156 {
 1157         int     i;
 1158 
 1159         i = tokenix;
 1160         inst0 = word0;
 1161         if (type == 0 && reserved ("rel", i)) {
 1162 #if 0 /* driver will fix relative dsps to absolute */
 1163                 if (arch < ARCH710) {
 1164                         errout ("Wrong arch for relative dsps");
 1165                 }
 1166 #endif
 1167                 inst1 = evaluate (i + 2) - dsps - 8;
 1168                 i += 4;
 1169                 inst0 |= 0x00800000;
 1170         }
 1171         else if (type != 1) {
 1172                 inst1 = evaluate (i);
 1173                 ++i;
 1174                 if (type == 0)
 1175                         patch_label();
 1176         }
 1177         if (i >= ntokens) {
 1178                 inst0 |= 0x00080000;
 1179                 store_inst ();
 1180                 return;
 1181         }
 1182         if (tokens[i].type != ',')
 1183                 errout ("Expected a separator, ',' assumed");
 1184         else
 1185                 ++i;
 1186         if (reserved("when", i))
 1187                 inst0 |= 0x00010000;
 1188         else if (reserved ("if", i) == 0) {
 1189                 errout ("Expected a reserved word");
 1190                 store_inst ();
 1191                 return;
 1192         }
 1193         i++;
 1194         if (reserved("false", i)) {
 1195                 store_inst ();
 1196                 return;
 1197         }
 1198         if (reserved ("not", i))
 1199                 ++i;
 1200         else
 1201                 inst0 |= 0x00080000;
 1202         if (reserved ("atn", i)) {
 1203                 inst0 |= 0x00020000;
 1204                 ++i;
 1205         } else if (CheckPhase (i)) {
 1206                 inst0 |= 0x00020000;
 1207                 ++i;
 1208         }
 1209         if (i < ntokens && tokens[i].type != ',') {
 1210                 if (inst0 & 0x00020000) {
 1211                         if (inst0 & 0x00080000 && reserved ("and", i)) {
 1212                                 ++i;
 1213                         }
 1214                         else if ((inst0 & 0x00080000) == 0 && reserved ("or", i)) {
 1215                                 ++i;
 1216                         }
 1217                         else
 1218                                 errout ("Expected a reserved word");
 1219                 }
 1220                 inst0 |= 0x00040000 + (evaluate (i++) & 0xff);
 1221         }
 1222         if (i < ntokens) {
 1223                 if (tokens[i].type == ',')
 1224                         ++i;
 1225                 else
 1226                         errout ("Expected a separator, ',' assumed");
 1227                 if (reserved ("and", i) && reserved ("mask", i + 1))
 1228                         inst0 |= ((evaluate (i + 2) & 0xff) << 8);
 1229                 else
 1230                         errout ("Expected , AND MASK");
 1231         }
 1232         store_inst ();
 1233 }
 1234 
 1235 void    select_reselect (int t)
 1236 {
 1237         inst0 |= 0x40000000;            /* ATN may be set from SELECT */
 1238         if (reserved ("from", t)) {
 1239                 if (arch < ARCH710) {
 1240                         errout ("Wrong arch for table indirect");
 1241                         return;
 1242                 }
 1243                 ++t;
 1244                 inst0 |= 0x02000000 | evaluate (t++);
 1245         }
 1246         else
 1247                 inst0 |= (evaluate (t++) & 0xff) << 16;
 1248         if (tokens[t++].type == ',') {
 1249                 if (reserved ("rel", t)) {
 1250 #if 0 /* driver will fix relative dsps to absolute */
 1251                         if (arch < ARCH710) {
 1252                                 errout ("Wrong arch for relative dsps");
 1253                         }
 1254 #endif
 1255                         inst0 |= 0x04000000;
 1256                         inst1 = evaluate (t + 2) - dsps - 8;
 1257                 }
 1258                 else {
 1259                         inst1 = evaluate (t);
 1260                         patch_label();
 1261                 }
 1262         }
 1263         else
 1264                 errout ("Expected separator");
 1265         store_inst ();
 1266 }
 1267 
 1268 void    set_clear (u_int32_t code)
 1269 {
 1270         int     i = tokenix;
 1271         short   need_and = 0;
 1272 
 1273         inst0 = code;
 1274         while (i < ntokens) {
 1275                 if (need_and) {
 1276                         if (reserved ("and", i))
 1277                                 ++i;
 1278                         else
 1279                                 errout ("Expected AND");
 1280                 }
 1281                 if (reserved ("atn", i)) {
 1282                         inst0 |= 0x0008;
 1283                         ++i;
 1284                 }
 1285                 else if (reserved ("ack", i)) {
 1286                         inst0 |= 0x0040;
 1287                         ++i;
 1288                 }
 1289                 else if (reserved ("target", i)) {
 1290                         inst0 |= 0x0200;
 1291                         ++i;
 1292                 }
 1293                 else if (reserved ("carry", i)) {
 1294                         inst0 |= 0x0400;
 1295                         ++i;
 1296                 }
 1297                 else
 1298                         errout ("Expected ATN, ACK, TARGET or CARRY");
 1299                 need_and = 1;
 1300         }
 1301         store_inst ();
 1302 }
 1303 
 1304 void    block_move ()
 1305 {
 1306         if (reserved ("from", tokenix)) {
 1307                 if (arch < ARCH710) {
 1308                         errout ("Wrong arch for table indirect");
 1309                         return;
 1310                 }
 1311                 inst1 = evaluate (tokenix+1);
 1312                 inst0 |= 0x10000000 | inst1;    /*** ??? to match Zeus script */
 1313                 tokenix += 2;
 1314         }
 1315         else {
 1316                 inst0 |= evaluate (tokenix++);  /* count */
 1317                 tokenix++;                      /* skip ',' */
 1318                 if (reserved ("ptr", tokenix)) {
 1319                         ++tokenix;
 1320                         inst0 |= 0x20000000;
 1321                 }
 1322                 inst1 = evaluate (tokenix++);   /* address */
 1323         }
 1324         if (tokens[tokenix].type != ',')
 1325                 errout ("Expected separator");
 1326         if (reserved ("when", tokenix + 1)) {
 1327                 inst0 |= 0x08000000;
 1328                 CheckPhase (tokenix + 2);
 1329         }
 1330         else if (reserved ("with", tokenix + 1)) {
 1331                 CheckPhase (tokenix + 2);
 1332         }
 1333         else
 1334                 errout ("Expected WITH or WHEN");
 1335 }
 1336 
 1337 void    register_write ()
 1338 {
 1339         /*
 1340          * MOVE reg/data8 TO reg                        register write
 1341          * MOVE reg <op> data8 TO reg                   register write
 1342          * MOVE reg + data8 TO reg WITH CARRY           register write
 1343          */
 1344         int     op;
 1345         int     reg;
 1346         int     data;
 1347 
 1348         if (reserved ("to", tokenix+1))
 1349                 op = 0;
 1350         else if (reserved ("shl", tokenix+1))
 1351                 op = 1;
 1352         else if (reserved ("shr", tokenix+1))
 1353                 op = 5;
 1354         else if (tokens[tokenix+1].type == '|')
 1355                 op = 2;
 1356         else if (reserved ("xor", tokenix+1))
 1357                 op = 3;
 1358         else if (tokens[tokenix+1].type == '&')
 1359                 op = 4;
 1360         else if (tokens[tokenix+1].type == '+')
 1361                 op = 6;
 1362         else if (tokens[tokenix+1].type == '-')
 1363                 op = 8;
 1364         else
 1365                 errout ("Unknown register operator");
 1366         switch (op) {
 1367         case 2:
 1368         case 3:
 1369         case 4:
 1370         case 6:
 1371         case 8:
 1372                 if (reserved ("to", tokenix+3) == 0)
 1373                         errout ("Register command expected TO");
 1374         }
 1375         reg = CheckRegister (tokenix);
 1376         if (reg < 0) {                  /* Not register, must be data */
 1377                 data = evaluate (tokenix);
 1378                 if (op)
 1379                         errout ("Register operator not move");
 1380                 reg = CheckRegister (tokenix+2);
 1381                 if (reg < 0)
 1382                         errout ("Expected register");
 1383                 inst0 = 0x78000000 | (data << 8) | reg << 16;
 1384 #if 0
 1385 fprintf (listfp, "Move data to register: %02x %d\n", data, reg);
 1386 #endif
 1387         } else if (op) {
 1388                 switch (op) {
 1389                 case 2:
 1390                 case 3:
 1391                 case 4:
 1392                 case 6:
 1393                 case 8:
 1394                         inst0 = 0;
 1395                         /* A register read/write operator */
 1396                         if (reserved("sfbr", tokenix+2)) {
 1397                                 if (arch < ARCH825)
 1398                                         errout("wrong arch for add with SFBR");
 1399                                 if (op == 8)
 1400                                         errout("can't substract SFBR");
 1401                                 inst0 |= 0x00800000;
 1402                                 data = 0;
 1403                         } else
 1404                                 data = evaluate (tokenix+2);
 1405                         if (tokenix+5 < ntokens) {
 1406                                 if (!reserved("with", tokenix+5) ||
 1407                                     !reserved("carry", tokenix+6)) {
 1408                                         errout("Expected 'WITH CARRY'");
 1409                                 } else if (op != 6) {
 1410                                         errout("'WITH CARRY' only valide "
 1411                                             "with '+'");
 1412                                 }
 1413                                 op = 7;
 1414                         }
 1415                         if (op == 8) {
 1416                                 data = -data;
 1417                                 op = 6;
 1418                         }
 1419                         inst0 |= (data & 0xff) << 8;
 1420                         data = CheckRegister (tokenix+4);
 1421                         break;
 1422                 default:
 1423                         data = CheckRegister (tokenix+2);
 1424                         break;
 1425                 }
 1426                 if (data < 0)
 1427                         errout ("Expected register");
 1428                 if (reg != data && reg != 8 && data != 8)
 1429                         errout ("One register MUST be SBFR");
 1430                 if (reg == data) {      /* A register read/modify/write */
 1431 #if 0
 1432 fprintf (listfp, "Read/modify register: %02x %d %d\n", inst0 >> 8, op, reg);
 1433 #endif
 1434                         inst0 |= 0x78000000 | (op << 24) | (reg << 16);
 1435                 }
 1436                 else {                  /* A move to/from SFBR */
 1437                         if (reg == 8) { /* MOVE SFBR <> TO reg */
 1438 #if 0
 1439 fprintf (listfp, "Move SFBR to register: %02x %d %d\n", inst0 >> 8, op, data);
 1440 #endif
 1441                                 inst0 |= 0x68000000 | (op << 24) | (data << 16);
 1442                         }
 1443                         else {
 1444 #if 0
 1445 fprintf (listfp, "Move register to SFBR: %02x %d %d\n", inst0 >> 8, op, reg);
 1446 #endif
 1447                                 inst0 |= 0x70000000 | (op << 24) | (reg << 16);
 1448                         }
 1449                 }
 1450         } else {                                /* register to register */
 1451                 data = CheckRegister (tokenix+2);
 1452                 if (data < 0)
 1453                         errout ("Expected register");
 1454                 if (reg == 8)           /* move SFBR to reg */
 1455                         inst0 = 0x6a000000 | (data << 16);
 1456                 else if (data == 8)     /* move reg to SFBR */
 1457                         inst0 = 0x72000000 | (reg << 16);
 1458                 else
 1459                         errout ("One register must be SFBR");
 1460         }
 1461 }
 1462 
 1463 void    memory_to_memory ()
 1464 {
 1465         inst0 = 0xc0000000 + evaluate (tokenix+1);
 1466         inst1 = evaluate (tokenix+3);
 1467         /*
 1468          * need to hack dsps, otherwise patch offset will be wrong for
 1469          * second pointer
 1470          */
 1471         dsps += 4;
 1472         inst2 = evaluate (tokenix+5);
 1473         dsps -= 4;
 1474 }
 1475 
 1476 void    error_line()
 1477 {
 1478         if (errfp != listfp && errfp && err_listed == 0) {
 1479                 fprintf (errfp, "%3d:  %s", lineno, inbuf);
 1480                 err_listed = 1;
 1481         }
 1482 }
 1483 
 1484 char *  makefn (base, sub)
 1485         char *base;
 1486         char *sub;
 1487 {
 1488         char *fn;
 1489         size_t len = strlen (base) + strlen (sub) + 2; 
 1490 
 1491         fn = malloc (len);
 1492         strlcpy (fn, base, len);
 1493         base = strrchr(fn, '.');
 1494         if (base)
 1495                 *base = 0;
 1496         strlcat (fn, ".", len);
 1497         strlcat (fn, sub, len);
 1498         return (fn);
 1499 }
 1500 
 1501 void    usage()
 1502 {
 1503         fprintf (stderr, "usage: scc sourcfile [options]\n");
 1504         exit(1);
 1505 }

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