home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 363_02 / opparse.c < prev    next >
C/C++ Source or Header  |  1991-12-17  |  48KB  |  1,132 lines

  1. /***********************************************************************
  2.  *
  3.  *      OPPARSE.C
  4.  *      Operand Parser for 68000 Assembler
  5.  *
  6.  *    Function: isXreg()
  7.  *      Parses Index Register specification, inserts the upper byte flags
  8.  *      (see below) into extension word.
  9.  *
  10.  *    Function: opParse()
  11.  *      Parses an operand of the 68020 assembly language instruction and
  12.  *      attempts to recognize its addressing mode. The p argument points to
  13.  *      the string to be evaluated, and the function returns a pointer to the
  14.  *      first character beyond the end of the operand.
  15.  *      The function returns a description of the operands that it parses in
  16.  *      an opDescriptor structure. The fields of the operand descriptor are
  17.  *      filled in as appropriate for the mode of the operand that was found:
  18.  *
  19.  *      mode    returns the address mode (symbolic values defined in ASM.H)
  20.  *      data    returns the displacement or address or immediate value
  21.  *      reg     returns the address or data register number
  22.  *      size    returns the size of absolute address (WORD or LONG)
  23.  *      xtenWord returns the indexed operation first extension word. The
  24.  *              7 MSBits are filled in by isXreg(), the 9 LSBits - by opparse.
  25.  *      bfXtenWord bit field extension word
  26.  *      outDisp returns the outer displacement of an indexed operation
  27.  *      backRef TRUE if data is the value of an expression that contains only
  28.  *              constants and backwards references; FALSE otherwise.
  29.  *      odBackRef TRUE if outer displacement is the value of an expression
  30.  *              that contains only constants and backward references; FALSE
  31.  *              otherwise.
  32.  *
  33.  *      The argument errorPtr is used to return an error code via the standard
  34.  *      mechanism.
  35.  *
  36.  *   Usage: char *opParse(char *p, opDescriptor *d, int *errorPtr)
  37.  *
  38.  *      Author: Paul McKee
  39.  *      ECE492    North Carolina State University, 10/10/86
  40.  *
  41.  *    Revision: 10/26/87
  42.  *      Altered the immediate mode case to correctly flag
  43.  *      constructs such as "#$1000(A5)" as syntax errors.
  44.  *
  45.  *      Modified A.E. Romer. Version 1.0
  46.  *          17 March 1991 - converted to ANSI
  47.  *          21 March 1991 - .w and .l suffixes allowed in absolute addressing
  48.  *          May      1991 - isXreg() added.
  49.  *          Summer   1991 - conversion to 68020 format of indirection 
  50.  *                          instruction, index SCALE implementation, addition 
  51.  *                          of 68020 specific instructions
  52.  *
  53.  ************************************************************************/
  54.  
  55.  
  56. #include <stdio.h>
  57. #include <ctype.h>
  58. #include "asm.h"
  59.  
  60.  
  61. extern char pass2;
  62. extern long loc;
  63.  
  64.  
  65. #define isTerm(c)   (isspace(c)         /* operand field terminator */\
  66.                         || (c == ',')   /* source/destination separator */\
  67.                         || c == '{'     /* bit field specification start */\
  68.                         || c == '\0')   /* line terminator */
  69.  
  70. #define isRegNum(c) ((c >= '0') && (c <= '7'))
  71.  
  72.  
  73. char *isXreg(char *p, opDescriptor *d, int *errorPtr)
  74.     {
  75.     long scale;
  76.  
  77.     if ((p[0] == 'A' || p[0] == 'D') && isRegNum(p[1]))
  78.                         /* set index register field in the extension word */
  79.         {
  80.         d->xtenWord |= XREG_NUM(p[1] - '0');
  81.         if (p[0] == 'A')
  82.             d->xtenWord |= XREG_IS_An;
  83.  
  84. /* neither size nor scale specified */
  85.         if (p[2] == ')' || p[2] == ']' || p[2] ==',')
  86.             return p+2;             /* Default index register size
  87.                                      * and scale, null displacement */
  88.  
  89. /* size specified */
  90.         else if (p[2] == '.')
  91.             {
  92.             /* Determine size of index register */
  93.             if (p[3] == 'W')
  94.                 ;                   /* default */
  95.             else if (p[3] == 'L')
  96.                 d->xtenWord |= XSIZE_LONG;
  97.             else
  98.                 {
  99.                 NEWERROR(*errorPtr, SYNTAX);
  100.                 return NULL;
  101.                 }
  102.             if (p[4] == ')' || p[4] == ']' || p[4] == ',')
  103.                                                     /* no scale specified */
  104.                 return p+4;                         /* default scale is 1 */
  105.  
  106.             else if (p[4] == '*')                   /* scale specified */
  107.                 {
  108.                 p = eval(p+5, &scale, &d->backRef, errorPtr);
  109.                 if (*errorPtr > SEVERE)
  110.                     return NULL;
  111.                 else if (p[0] != ')' && p[0] != ']' && p[0] != ',')
  112.                                                     /* missing terminator */
  113.                     {
  114.                     NEWERROR(*errorPtr, SYNTAX);
  115.                     return NULL;
  116.                     }
  117.                 else
  118.                     switch (scale)
  119.                         {
  120.                         case 1: return p;
  121.                         case 2: d->xtenWord |= SCALE_TWO; return p;
  122.                         case 4: d->xtenWord |= SCALE_FOUR; return p;
  123.                         case 8: d->xtenWord |= SCALE_EIGHT; return p;
  124.                         default: NEWERROR(*errorPtr, SYNTAX); return NULL;
  125.                         }
  126.                 }
  127.             }
  128.  
  129.  /* size not specified, scale specified */
  130.         else if (p[2] == '*')
  131.             {
  132.             p = eval(p+3, &scale, &d->backRef, errorPtr);
  133.             if (*errorPtr > SEVERE)
  134.                 return NULL;
  135.             else if (p[0] != ')' && p[0] != ']')
  136.                 {
  137.                 NEWERROR(*errorPtr, SYNTAX);
  138.                 return NULL;
  139.                 }
  140.             else
  141.                 switch (scale)
  142.                     {
  143.                     case 1: return p;
  144.                     case 2: d->xtenWord |= SCALE_TWO; return p;
  145.                     case 4: d->xtenWord |= SCALE_FOUR; return p;
  146.                     case 8: d->xtenWord |= SCALE_EIGHT; return p;
  147.                     default: NEWERROR(*errorPtr, SYNTAX); return NULL;
  148.                     }
  149.             }
  150.  
  151.         else                    /* neither ')', nor '.', nor '*' follows Xn */
  152.             {
  153.             NEWERROR(*errorPtr, SYNTAX);
  154.             return NULL;
  155.             }
  156.         }
  157.     else                                    /* incorrect indexing syntax */
  158.         return NULL;
  159.     }
  160.  
  161.  
  162. char *opParse(char *p, opDescriptor *d, int *errorPtr)
  163.     {
  164.     char *t;                                        /* temporary pointers */
  165.     long value;
  166.     char ref;
  167.     int  error;
  168.  
  169.     d->xtenWord = 0;        /* initialize */
  170.  
  171.     /**********************************************************\
  172.      *****      data or address register direct:          *****
  173.      *****              "Dn" or "An"                      *****
  174.     \**********************************************************/
  175.  
  176.     if (isRegNum(p[1]) && isTerm(p[2]))
  177.         {
  178.         if (p[0] == 'D')
  179.             {
  180.             d->mode = DnDirect;
  181.             d->reg = p[1] - '0';
  182.             return (p + 2);
  183.             }
  184.         else if (p[0] == 'A')
  185.             {
  186.             d->mode = AnDirect;
  187.             d->reg = p[1] - '0';
  188.             return (p + 2);
  189.             }
  190.         }
  191.  
  192.     /**********************************************************\
  193.      *****          Stack Pointer (A7) direct:            *****
  194.      *****                  "SP"                          *****
  195.     \**********************************************************/
  196.  
  197.     if (p[0] == 'S' && p[1] == 'P' && isTerm(p[2]))
  198.         {
  199.         d->mode = AnDirect;
  200.         d->reg = 7;
  201.         return (p + 2);
  202.         }
  203.  
  204.     /**********************************************************\
  205.      *****          Address register indirect:            *****
  206.      *****      "(An)", "(An)+", "(SP)", or "(SP)+"       *****
  207.     \**********************************************************/
  208.  
  209.     if (p[0] == '('
  210.             && ((p[1] == 'A' && isRegNum(p[2]))
  211.                                 || (p[1] == 'S' && p[2] == 'P'))
  212.             && p[3] == ')')
  213.         {
  214.  
  215.         if (p[1] == 'S')
  216.             d->reg = 7;
  217.         else
  218.             d->reg = p[2] - '0';
  219.  
  220.         if (isTerm(p[4]))
  221.                         /* plain address register indirect: (An) or (SP) */
  222.             {
  223.             d->mode = AnInd;
  224.             return p+4;
  225.             }
  226.         else if (p[4] == '+' &&isTerm(p[5]))
  227.                                         /* postincrement: (An)+ or (SP)+ */
  228.             {
  229.             d->mode = AnIndPost;
  230.             return p+5;
  231.             }
  232.         else
  233.             {
  234.             NEWERROR(*errorPtr, SYNTAX);
  235.             return NULL;
  236.             }
  237.         }
  238.  
  239.     /**********************************************************\
  240.      *****  Address register indirect with predecrement:  *****
  241.      *****              "-(An)" or "-(SP)"                *****
  242.     \**********************************************************/
  243.     
  244.     if (p[0] == '-' && p[1] == '(' && p[4] == ')' && ((p[2] == 'A'
  245.             && isRegNum(p[3])) || (p[2] == 'S' && p[3] == 'P'))
  246.             && isTerm(p[5]))
  247.         {
  248.         if (p[2] == 'S')
  249.             d->reg = 7;
  250.         else
  251.             d->reg = p[3] - '0';
  252.         d->mode = AnIndPre;
  253.         return p+5;
  254.         }
  255.  
  256.     /********************************************************\
  257.      *****  Address register indirect with index        *****
  258.      *****          "(An,Xn.SIZE*SCALE)"                *****
  259.     \********************************************************/
  260.  
  261.     if (p[0] == '('
  262.             && ((p[1] == 'A' && isRegNum(p[2]))
  263.                                 || (p[1] == 'S' && p[2] == 'P'))
  264.             && p[3] == ','
  265.             && ((t = isXreg(p+4, d, errorPtr)) != NULL))
  266.         {
  267.         if (p[1] == 'S')
  268.             d->reg = 7;
  269.         else
  270.             d->reg = p[2] - '0';
  271.         p = t;
  272.         if (p[0] == ')' && isTerm(p[1]))
  273.             {
  274.             d->mode = AnIndIndex;
  275.             d->data = 0;                        /* Displacement is zero */
  276.             d->backRef = TRUE;
  277.             return p+1;
  278.             }
  279.         else
  280.             {
  281.             NEWERROR(*errorPtr, SYNTAX);
  282.             return NULL;
  283.             }
  284.         }
  285.  
  286.     /*****************************************************\
  287.      *****                PC relative:               *****
  288.      *****            "(PC,Xn.SIZE*SCALE)"           *****
  289.     \*****************************************************/
  290.  
  291.     if (p[0] == '(' && p[1] == 'P' && p[2] == 'C')
  292.         {
  293.         if (p[3] == ')' && isTerm(p[4]))            /* plain PC relative */
  294.             {
  295.             d->data = 0;
  296.             d->backRef = TRUE;
  297.             d->mode = PCDisp;
  298.             return p+4;
  299.             }
  300.  
  301.         else if (p[3] == ',' && (t = isXreg(p+4, d, errorPtr)) != NULL)
  302.             {
  303.             p = t;
  304.             if (p[0] == ')' && isTerm(p[1]))
  305.                 {
  306.                 d->mode = PCIndex;
  307.                 d->data = 0;                        /* Displacement is zero */
  308.                     /* displacement is zero by default in extension word */
  309.                 d->backRef = TRUE;
  310.                 return p+1;
  311.                 }
  312.             else
  313.                 {
  314.                 NEWERROR(*errorPtr, SYNTAX);
  315.                 return NULL;
  316.                 }
  317.             }
  318.         }
  319.  
  320.     /**********************************************************\
  321.      *****              Status Register direct:           *****
  322.      *****                      "SR"                      *****
  323.     \**********************************************************/
  324.  
  325.     if (p[0] == 'S' && p[1] == 'R' && isTerm(p[2]))
  326.         {
  327.         d->mode = SRDirect;
  328.         return p+2;
  329.         }
  330.  
  331.     /**********************************************************\
  332.      *****      Condition Code Register direct:           *****
  333.      *****                  "CCR"                         *****
  334.     \**********************************************************/
  335.  
  336.     if (p[0] == 'C' && p[1] == 'C' && p[2] == 'R' && isTerm(p[3]))
  337.         {
  338.         d->mode = CCRDirect;
  339.         return p+3;
  340.         }
  341.  
  342.     /**********************************************************\
  343.      *****          User Stack Pointer direct:            *****
  344.      *****                  "USP"                         *****
  345.     \**********************************************************/
  346.  
  347.     if (p[0] == 'U' && p[1] == 'S' && p[2] == 'P' && isTerm(p[3]))
  348.         {
  349.         d->mode = USPDirect;
  350.         return p+3;
  351.         }
  352.  
  353.     /**********************************************************\
  354.      *****  Source Function Code register direct (68010): *****
  355.      *****                  "SFC"                         *****
  356.     \**********************************************************/
  357.  
  358.     if (p[0] == 'S' && p[1] == 'F' && p[2] == 'C' && isTerm(p[3]))
  359.         {
  360.         d->mode = SFCDirect;
  361.         return p+3;
  362.         }
  363.  
  364.     /***************************************************************\
  365.      *****  Destination Function Code register direct (68010): *****
  366.      *****                      "DFC"                          *****
  367.     \***************************************************************/
  368.  
  369.     if (p[0] == 'D' && p[1] == 'F' && p[2] == 'C' && isTerm(p[3]))
  370.         {
  371.         d->mode = DFCDirect;
  372.         return p+3;
  373.         }
  374.  
  375.     /****************************************************************\
  376.      *****       Vector Base Register Direct (68010):           *****
  377.      *****                      "VBR"                               *****
  378.     \****************************************************************/
  379.  
  380.     if (p[0] == 'V' && p[1] == 'B' && p[2] == 'R' && isTerm(p[3]))
  381.         {
  382.         d->mode = VBRDirect;
  383.         return p+3;
  384.         }
  385.  
  386.     /****************************************************************\
  387.      *****       Cache Control Register Direct (68020):         *****
  388.      *****                      "CACR"                          *****
  389.     \****************************************************************/
  390.  
  391.     if (p[0] == 'C' && p[1] == 'A' && p[2] == 'C' && p[3] == 'R'
  392.                                                     && isTerm(p[4]))
  393.         {
  394.         d->mode = CACRDirect;
  395.         return p+4;
  396.         }
  397.  
  398.     /****************************************************************\
  399.      *****       Cache Address Register Direct (68020):         *****
  400.      *****                      "CAAR"                          *****
  401.     \****************************************************************/
  402.  
  403.     if (p[0] == 'C' && p[1] == 'A' && p[2] == 'A' && p[3] == 'R'
  404.                                                     && isTerm(p[4]))
  405.         {
  406.         d->mode = CAARDirect;
  407.         return p+4;
  408.         }
  409.  
  410.     /**********************************************************\
  411.      *****      Master Stack Pointer direct (68020):      *****
  412.      *****                      "MSP"                     *****
  413.     \**********************************************************/
  414.  
  415.     if (p[0] == 'M' && p[1] == 'S' && p[2] == 'P' && isTerm(p[3]))
  416.         {
  417.         d->mode = MSPDirect;
  418.         return p+3;
  419.         }
  420.  
  421.     /**********************************************************\
  422.      *****      Interrupt Stack Pointer direct (68020):   *****
  423.      *****                      "ISP"                     *****
  424.     \**********************************************************/
  425.  
  426.     if (p[0] == 'I' && p[1] == 'S' && p[2] == 'P' && isTerm(p[3]))
  427.         {
  428.         d->mode = ISPDirect;
  429.         return p+3;
  430.         }
  431.  
  432.     /************************************************************\
  433.      ************************************************************
  434.      *****      Memory (including Program Counter Memory)   *****
  435.      *****                  indirect modes                  *****
  436.      *****               All beginning with "(["            *****
  437.      ************************************************************
  438.     \************************************************************/
  439.  
  440.     if (p[0] == '(' && p[1] == '[')
  441.         {
  442.  
  443.         /************************************************************\
  444.          ************************************************************
  445.          *****      Memory (including Program Counter Memory)   *****
  446.          *****      indirect modes, no base displacement        *****
  447.          ************************************************************
  448.         \************************************************************/
  449.  
  450.         /************************************************************\
  451.          *****      memory indirect, all elements suppressed    *****
  452.          *****                  "([],,)", "([,],)"              *****
  453.         \************************************************************/
  454.  
  455.         /* not implemented */
  456.  
  457.         /****************************************************\
  458.          *****      memory indirect without index       *****
  459.          *****              "([An],)", "([An,],)"       *****
  460.         \****************************************************/
  461.  
  462.         /* not implemented */
  463.  
  464.  
  465.         /****************************************************\
  466.          *****  memory indirect without base register   *****
  467.          *****          "([],Xn)", "([,,Xn],)"          *****
  468.         \****************************************************/
  469.  
  470.         /* not implemented */
  471.  
  472.         /****************************************************************\
  473.          *****  memory indirect postindexed, no outer displacement  *****
  474.          *****                      "([An],Xn)"                     *****
  475.         \****************************************************************/
  476.  
  477.         if (p[2] == 'A' && isRegNum(p[3])
  478.                         && p[4] == ']' && p[5] == ','
  479.                         && (t = isXreg(p+6, d, errorPtr)) != NULL
  480.                         && t[0] == ')'&& isTerm(t[1]) )
  481.                         
  482.             {
  483.             d->reg = p[3] - '0';
  484.             d->mode = MemIndPostinx;
  485.             d->xtenWord |= FULL_FORMAT | BASE_NULL | OUTER_NULL | POST_X;
  486.             return t+1;
  487.             }
  488.  
  489.         /****************************************************************\
  490.          *****  memory indirect preindexed, no outer displacement   *****
  491.          *****                      "([An,Xn])"                     *****
  492.         \****************************************************************/
  493.  
  494.         if (p[2] == 'A' && isRegNum(p[3])
  495.                         && p[4] == ','
  496.                         && (t = isXreg(p+5, d, errorPtr)) != NULL
  497.                         && t[0] == ']' && t[1] == ')' && isTerm(t[2]))
  498.                         
  499.             {
  500.             d->reg = p[3] - '0';
  501.             d->mode = MemIndPreinx;
  502.             d->xtenWord |= FULL_FORMAT | BASE_NULL | OUTER_NULL;
  503.             return t+2;
  504.             }
  505.  
  506.         /************************************************\
  507.          *****      memory indirect postindexed     *****
  508.          *****          "([An],Xn,od)"              *****
  509.         \************************************************/
  510.  
  511.         if (p[2] == 'A' && isRegNum(p[3])
  512.                         && p[4] == ']' && p[5] == ','
  513.                         && (t = isXreg(p+6, d, errorPtr)) != NULL
  514.                         && t[0] == ',')
  515.             {
  516.             t = eval(++t, &d->outDisp, &d->odBackRef, errorPtr);
  517.             if (*errorPtr < SEVERE)
  518.                 if (t[0] == ')' && isTerm(t[1]))
  519.                     {
  520.                     d->reg = p[3] - '0';
  521.                     d->mode = MemIndPostinx;
  522.                     d->xtenWord |= FULL_FORMAT | BASE_NULL | POST_X;
  523.                     if (d->odBackRef
  524.                             && d->outDisp >= -32768 && d->outDisp <= 32767)
  525.                         d->xtenWord |=OUTER_WORD;
  526.                     else
  527.                         d->xtenWord |=OUTER_LONG;
  528.                     return t+1;
  529.                     }
  530.                 else
  531.                     {
  532.                     NEWERROR(*errorPtr, SYNTAX);
  533.                     return NULL;            /* outer displacement
  534.                                              * incorrectly terminated */
  535.                     }
  536.             else
  537.                 return NULL;                /* error in 'eval' */
  538.             }
  539.  
  540.         /************************************************\
  541.          *****      memory indirect preindexed      *****
  542.          *****          "([An,Xn],od)"              *****
  543.         \************************************************/
  544.  
  545.         if (p[2] == 'A' && isRegNum(p[3])
  546.                         && p[4] == ','
  547.                         && (t = isXreg(p+5, d, errorPtr)) != NULL
  548.                         && t[0] == ']' && t[1] == ',')
  549.             {
  550.             t = eval(t+2, &d->outDisp, &d->odBackRef, errorPtr);
  551.             if (*errorPtr < SEVERE)
  552.                 if (t[0] == ')' && isTerm(t[1]))
  553.                     {
  554.                     d->reg = p[3] - '0';
  555.                     d->mode = MemIndPreinx;
  556.                     d->xtenWord |= FULL_FORMAT | BASE_NULL;
  557.                     if (d->odBackRef
  558.                             && d->outDisp >= -32768 && d->outDisp <= 32767)
  559.                         d->xtenWord |=OUTER_WORD;
  560.                     else
  561.                         d->xtenWord |=OUTER_LONG;
  562.                     return t+1;
  563.                     }
  564.                 else
  565.                     {
  566.                     NEWERROR(*errorPtr, SYNTAX);
  567.                     return NULL;            /* outer displacement
  568.                                              * incorrectly terminated */
  569.                     }
  570.             else
  571.                 return NULL;                /* error in 'eval' */
  572.             }
  573.  
  574.         /****************************************************************\
  575.          *****      PC memory indirect, all elements suppressed     *****
  576.          *****                  "([ZPC],,)", "([ZPC,],)"            *****
  577.         \****************************************************************/
  578.  
  579.         /* not implemented */
  580.  
  581.         /********************************************************\
  582.          *****      PC memory indirect without index        *****
  583.          *****          "([PC],)", "([PC,],)"               *****
  584.         \********************************************************/
  585.  
  586.         /* not implemented */
  587.  
  588.         /****************************************************\
  589.          *****  memory indirect without base register   *****
  590.          *****          "([ZPC],Xn)", "([ZPC,Xn],)"         *****
  591.         \****************************************************/
  592.  
  593.         /* not implemented */
  594.  
  595.         /********************************************************************\
  596.          *****  PC memory indirect postindexed, no outer displacement   *****
  597.          *****                      "([PC],Xn)"                         *****
  598.         \********************************************************************/
  599.  
  600.         if (p[2] == 'P' && p[3] == 'C'
  601.                         && p[4] == ']' && p[5] == ','
  602.                         && (t = isXreg(p+6, d, errorPtr)) != NULL
  603.                         && t[0] == ')'&& isTerm(t[1]) )
  604.                         
  605.             {
  606.             d->reg = 3;
  607.             d->mode = PCMemIndPostinx;
  608.             d->xtenWord |= FULL_FORMAT | BASE_NULL | OUTER_NULL | POST_X;
  609.             return t+1;
  610.             }
  611.  
  612.         /********************************************************************\
  613.          *****  PC memory indirect preindexed, no outer displacement    *****
  614.          *****                      "([PC,Xn])"                         *****
  615.         \********************************************************************/
  616.  
  617.         if (p[2] == 'P' && p[3] == 'C'
  618.                         && p[4] == ','
  619.                         && (t = isXreg(p+5, d, errorPtr)) != NULL
  620.                         && t[0] == ')' && isTerm(t[1]))
  621.                         
  622.             {
  623.             d->reg = 3;
  624.             d->mode = PCMemIndPreinx;
  625.             d->xtenWord |= FULL_FORMAT | BASE_NULL | OUTER_NULL;
  626.             return t+1;
  627.             }
  628.  
  629.         /****************************************************\
  630.          *****      PC memory indirect postindexed      *****
  631.          *****              "([PC],Xn,od)"              *****
  632.         \****************************************************/
  633.  
  634.         if (p[2] == 'P' && p[3] == 'C'
  635.                         && p[4] == ']' && p[5] == ','
  636.                         && (t = isXreg(p+6, d, errorPtr)) != NULL
  637.                         && t[0] == ',')
  638.             {
  639.             t = eval(++t, &d->outDisp, &d->odBackRef, errorPtr);
  640.             if (*errorPtr < SEVERE)
  641.                 if (t[0] == ')' && isTerm(t[1]))
  642.                     {
  643.                     d->reg = 3;
  644.                     d->mode = PCMemIndPostinx;
  645.                     d->xtenWord |= FULL_FORMAT | BASE_NULL | POST_X;
  646.                     if (d->odBackRef
  647.                             && d->outDisp >= -32768 && d->outDisp <= 32767)
  648.                         d->xtenWord |=OUTER_WORD;
  649.                     else
  650.                         d->xtenWord |=OUTER_LONG;
  651.                     return t+1;
  652.                     }
  653.                 else
  654.                     {
  655.                     NEWERROR(*errorPtr, SYNTAX);
  656.                     return NULL;            /* outer displacement
  657.                                              * incorrectly terminated */
  658.                     }
  659.             else
  660.                 return NULL;                /* error in 'eval' */
  661.             }
  662.  
  663.         /****************************************************\
  664.          *****      PC memory indirect preindexed       *****
  665.          *****              "([PC,Xn],od)"              *****
  666.         \****************************************************/
  667.  
  668.         if (p[2] == 'P' && p[3] == 'C'
  669.                         && p[4] == ','
  670.                         && (t = isXreg(p+5, d, errorPtr)) != NULL
  671.                         && t[0] == ']' && t[1] == ',')
  672.             {
  673.             t = eval(++t, &d->outDisp, &d->odBackRef, errorPtr);
  674.             if (*errorPtr < SEVERE)
  675.                 if (t[0] == ')' && isTerm(t[1]))
  676.                     {
  677.                     d->reg = 3;
  678.                     d->mode = PCMemIndPreinx;
  679.                     d->xtenWord |= FULL_FORMAT | BASE_NULL;
  680.                     if (d->odBackRef
  681.                             && d->outDisp >= -32768 && d->outDisp <= 32767)
  682.                         d->xtenWord |=OUTER_WORD;
  683.                     else
  684.                         d->xtenWord |=OUTER_LONG;
  685.                     return t+1;
  686.                     }
  687.                 else
  688.                     {
  689.                     NEWERROR(*errorPtr, SYNTAX);
  690.                     return NULL;            /* outer displacement
  691.                                              * incorrectly terminated */
  692.                     }
  693.             else
  694.                 return NULL;                /* error in 'eval' */
  695.             }
  696.  
  697.     /************************************************************\
  698.      ************************************************************
  699.      *****      Memory (including Program Counter Memory)   *****
  700.      *****      indirect modes with base displacement       *****
  701.      *****            All beginning with "([<data>"         *****
  702.      ************************************************************
  703.     \************************************************************/
  704.  
  705.         p = eval(p+2, &d->data, &d->backRef, errorPtr);
  706.             if (*errorPtr < SEVERE)
  707.                 {
  708.  
  709.                 /************************************************\
  710.                  *****      memory indirect postindexed     *****
  711.                  *****          "([bd,An],Xn,od)"           *****
  712.                 \************************************************/
  713.  
  714.                 if (p[0] == ',' && p[1] == 'A' && isRegNum(p[2])
  715.                                 && p[3] == ']' && p[4] == ','
  716.                                 && (t = isXreg(p+5, d, errorPtr)) != NULL)
  717.                     {
  718.                     d->reg = p[2] - '0';
  719.                     p = t;
  720.                     d->mode = MemIndPostinx;
  721.                     d->xtenWord |= FULL_FORMAT | POST_X;
  722.                     if (d->backRef && d->data == 0)
  723.                         d->xtenWord |= BASE_NULL;
  724.                     else if (d->backRef && d->data >= -32768
  725.                                                         && d->data <= 32767)
  726.                         d->xtenWord |= BASE_WORD;
  727.                     else
  728.                         d->xtenWord |= BASE_LONG;
  729.                     if (p[0] == ')' && isTerm(p[1]))
  730.                                                 /* no outer displacement */
  731.                         {
  732.                         d->outDisp = 0;
  733.                         d->odBackRef = TRUE;
  734.                         d->xtenWord |= OUTER_NULL;
  735.                         return p+1;
  736.                         }
  737.                     else if (p[0] == ',')       /* outer displacement
  738.                                                  * specified */
  739.                         {
  740.                         p = eval(++p, &d->outDisp, &d->odBackRef, errorPtr);
  741.                         if (*errorPtr < SEVERE)
  742.                             if (p[0] == ')' && isTerm(p[1]))
  743.                                 {
  744.                                 if (d->odBackRef && d->outDisp == 0)
  745.                                     d->xtenWord |= OUTER_NULL;
  746.                                 else if (d->backRef && d->outDisp >= -32768
  747.                                                     && d->outDisp <= 32767)
  748.                                     d->xtenWord |= OUTER_WORD;
  749.                                 else
  750.                                     d->xtenWord |= OUTER_LONG;
  751.                                 return p+1;
  752.                                 }
  753.                             else                /* outer displacement
  754.                                                  * incorrectly terminated */
  755.                                 {
  756.                                 NEWERROR(*errorPtr, SYNTAX);
  757.                                 return NULL;
  758.                                 }
  759.                         else
  760.                             return NULL;        /* error in 'eval' */
  761.                         }
  762.                     else                        /* either ',' or ')' must
  763.                                                  * follow index register */
  764.                         {
  765.                         NEWERROR(*errorPtr, SYNTAX);
  766.                         return NULL;
  767.                         }
  768.                     }
  769.  
  770.                 /************************************************\
  771.                  *****      memory indirect preindexed      *****
  772.                  *****          "([bd,An,Xn],od)"           *****
  773.                 \************************************************/
  774.                 else if (p[0] == ',' && p[1] == 'A' && isRegNum(p[2])
  775.                         && p[3] == ','
  776.                         && (t = isXreg(p+4, d, errorPtr)) != NULL
  777.                         && t[0] == ']')
  778.                     {
  779.                     d->reg = p[2] - '0';
  780.                     d->mode = MemIndPreinx;
  781.                     d->xtenWord |= FULL_FORMAT;
  782.                     if (d->backRef && d->data == 0)
  783.                         d->xtenWord |= BASE_NULL;
  784.                     else if (d->backRef && d->data >= -32768
  785.                                                     && d->data <= 32767)
  786.                         d->xtenWord |= BASE_WORD;
  787.                     else
  788.                         d->xtenWord |= BASE_LONG;
  789.                     p = t;
  790.                     if (p[1] == ')' && isTerm(p[2]))
  791.                                                 /* no outer displacement */
  792.                         {
  793.                         d->outDisp = 0;
  794.                         d->odBackRef = TRUE;
  795.                         d->xtenWord |= OUTER_NULL;
  796.                         return p+2;
  797.                         }
  798.                     else if (p[1] == ',')       /* outer displacement
  799.                                                  * specified */
  800.                         {
  801.                         p = eval(p+2, &d->outDisp, &d->odBackRef, errorPtr);
  802.                         if (*errorPtr < SEVERE)
  803.                             if (p[0] == ')' && isTerm(p[1]))
  804.                                 {
  805.                                 if (d->odBackRef && d->outDisp == 0)
  806.                                     d->xtenWord |= OUTER_NULL;
  807.                                 else if (d->backRef && d->outDisp >= -32768
  808.                                                     && d->outDisp <= 32767)
  809.                                     d->xtenWord |= OUTER_WORD;
  810.                                 else
  811.                                     d->xtenWord |= OUTER_LONG;
  812.                                 return p+1;
  813.                                 }
  814.                             else
  815.                                 return NULL;    /* outer displacement
  816.                                                  * incorrectly terminated */
  817.                         else
  818.                             return NULL;        /* error in 'eval' */
  819.                         }
  820.                     else                        /* either ',' or ')' must
  821.                                                  * follow index register */
  822.                         {
  823.                         NEWERROR(*errorPtr, SYNTAX);
  824.                         return NULL;
  825.                         }
  826.                     }
  827.                 /****************************************************\
  828.                  *****      PC memory indirect postindexed      *****
  829.                  *****          "([bd,PC],Xn,od)"               *****
  830.                 \****************************************************/
  831.  
  832.                 if (p[0] == ',' && p[1] == 'P' && p[2] == 'C'
  833.                                 && p[3] == ']' && p[4] == ','
  834.                                 && (t = isXreg(p+5, d, errorPtr)) != NULL)
  835.                     {
  836.                     p = t;
  837.                     d->mode = PCMemIndPostinx;
  838.                     d->xtenWord |= FULL_FORMAT | POST_X;
  839.                     if (d->backRef && d->data == 0)
  840.                         d->xtenWord |= BASE_NULL;
  841.                     else if (d->backRef && d->data >= -32768
  842.                                                         && d->data <= 32767)
  843.                         d->xtenWord |= BASE_WORD;
  844.                     else
  845.                         d->xtenWord |= BASE_LONG;
  846.                     if (p[0] == ')' && isTerm(p[1]))
  847.                                                 /* no outer displacement */
  848.                         {
  849.                         d->outDisp = 0;
  850.                         d->odBackRef = TRUE;
  851.                         d->xtenWord |= OUTER_NULL;
  852.                         return p+1;
  853.                         }
  854.                     else if (p[0] == ',')       /* outer displacement
  855.                                                  * specified */
  856.                         {
  857.                         p = eval(++p, &d->outDisp, &d->odBackRef, errorPtr);
  858.                         if (*errorPtr < SEVERE)
  859.                             if (p[0] == ')' && isTerm(p[1]))
  860.                                 {
  861.                                 if (d->odBackRef && d->outDisp == 0)
  862.                                     d->xtenWord |= OUTER_NULL;
  863.                                 else if (d->backRef && d->outDisp >= -32768
  864.                                                     && d->outDisp <= 32767)
  865.                                     d->xtenWord |= OUTER_WORD;
  866.                                 else
  867.                                     d->xtenWord |= OUTER_LONG;
  868.                                 return p+1;
  869.                                 }
  870.                             else                /* outer displacement
  871.                                                  * incorrectly terminated */
  872.                                 {
  873.                                 NEWERROR(*errorPtr, SYNTAX);
  874.                                 return NULL;
  875.                                 }
  876.                         else
  877.                             return NULL;        /* error in 'eval' */
  878.                         }
  879.                     else                        /* either ',' or ')' must
  880.                                                  * follow index register */
  881.                         {
  882.                         NEWERROR(*errorPtr, SYNTAX);
  883.                         return NULL;
  884.                         }
  885.                     }
  886.  
  887.                 /****************************************************\
  888.                  *****      PC memory indirect preindexed       *****
  889.                  *****          "([bd,An,Xn],od)"               *****
  890.                 \****************************************************/
  891.                 else if (p[0] == ',' && p[1] == 'P' && p[2] == 'C'
  892.                         && p[3] == ','
  893.                         && (t = isXreg(p+4, d, errorPtr)) != NULL
  894.                         && t[0] == ']')
  895.                     {
  896.                     d->mode = PCMemIndPreinx;
  897.                     d->xtenWord |= FULL_FORMAT;
  898.                     if (d->backRef && d->data == 0)
  899.                         d->xtenWord |= BASE_NULL;
  900.                     else if (d->backRef && d->data >= -32768
  901.                                                     && d->data <= 32767)
  902.                         d->xtenWord |= BASE_WORD;
  903.                     else
  904.                         d->xtenWord |= BASE_LONG;
  905.                     p = t;
  906.                     if (p[1] == ')' && isTerm(p[2]))
  907.                                                 /* no outer displacement */
  908.                         {
  909.                         d->outDisp = 0;
  910.                         d->odBackRef = TRUE;
  911.                         d->xtenWord |= OUTER_NULL;
  912.                         return p+2;
  913.                         }
  914.                     else if (p[1] == ',')       /* outer displacement
  915.                                                  * specified */
  916.                         {
  917.                         p = eval(p+2, &d->outDisp, &d->odBackRef, errorPtr);
  918.                         if (*errorPtr < SEVERE)
  919.                             if (p[0] == ')' && isTerm(p[1]))
  920.                                 {
  921.                                 if (d->odBackRef && d->outDisp == 0)
  922.                                     d->xtenWord |= OUTER_NULL;
  923.                                 else if (d->backRef && d->outDisp >= -32768
  924.                                                     && d->outDisp <= 32767)
  925.                                     d->xtenWord |= OUTER_WORD;
  926.                                 else
  927.                                     d->xtenWord |= OUTER_LONG;
  928.                                 return p+1;
  929.                                 }
  930.                             else
  931.                                 return NULL;    /* outer displacement
  932.                                                  * incorrectly terminated */
  933.                         else
  934.                             return NULL;        /* error in 'eval' */
  935.                         }
  936.                     else                        /* either ',' or ')' must
  937.                                                  * follow index register */
  938.                         {
  939.                         NEWERROR(*errorPtr, SYNTAX);
  940.                         return NULL;
  941.                         }
  942.                     }
  943.                 }               /* end of all beginning with "([<data>" */
  944.             }                   /* end of all beginning with "([" */
  945.  
  946.     /****************************************************************\
  947.      *****                 All beginning with                   *****
  948.      *****                      "(<data>"                           *****
  949.     \****************************************************************/
  950.  
  951.     if (p[0] == '(')
  952.         {
  953.         p = eval(++p, &d->data, &d->backRef, errorPtr);
  954.         if (*errorPtr < SEVERE)
  955.             {
  956.  
  957.             /************************************************************\
  958.              *****      address register indirect, no index         *****
  959.              *****              (<data>,An)                         *****
  960.             \************************************************************/
  961.  
  962.             if (p[0] == ',' && ((p[1] == 'A' && isRegNum(p[2])) ||
  963.                     (p[1] == 'S' && p[2] == 'P')))
  964.                             /* address register indirect with displacement */
  965.                 {
  966.                 if (p[1] == 'S')
  967.                     d->reg = 7;
  968.                 else
  969.                     d->reg = p[2] - '0';
  970.  
  971.                 if (p[3] == ')' && isTerm(p[4]))
  972.                                             /* plain address register
  973.                                              * indirect with displacement */
  974.                     {
  975.                     d->mode = AnIndDisp;
  976.                     return p+4;
  977.                     }
  978.  
  979.                 /************************************************************\
  980.                  *****          address register indirect               *****
  981.                  *****          (<data>,An,Xn.SIZE*SCALE)               *****
  982.                 \************************************************************/
  983.  
  984.                 else if (p[3] == ',' && (t = isXreg(p+4, d, errorPtr)) != NULL)
  985.                                     /* address register indirect with index */
  986.                     {
  987.                     p = t;
  988.                     if (p[0] == ')' && isTerm(p[1]))
  989.                         {
  990.                         d->mode = AnIndIndex;
  991.                         if (d->backRef && d->data >= -128 && d->data <= 127)
  992.                             d->xtenWord |= d->data & 0xff;
  993.                         else if (d->backRef && d->data >= -32768
  994.                                                         && d->data <= 32767)
  995.                             d->xtenWord |= FULL_FORMAT | BASE_WORD
  996.                                                             | OUTER_NULL;
  997.                         else
  998.                             d->xtenWord |= FULL_FORMAT | BASE_LONG
  999.                                                             | OUTER_NULL;
  1000.                         return p+1;
  1001.                         }
  1002.                     else
  1003.                         {
  1004.                         NEWERROR(*errorPtr, SYNTAX);
  1005.                         return NULL;
  1006.                         }
  1007.                     }
  1008.                 }
  1009.  
  1010.             /****************************************************************\
  1011.              *****                  PC relative, no index               *****
  1012.              *****                      (<data>,PC)                     *****
  1013.             \****************************************************************/
  1014.  
  1015.             if (p[0] == ',' && p[1] == 'P' && p[2] == 'C')
  1016.                                         /* PC relative with displacement */
  1017.                 {
  1018.                 if (p[3] == ')' && isTerm(p[4]))    /* plain PC relative */
  1019.                     {
  1020.                     d->mode = PCDisp;
  1021.                     return p+4;
  1022.                     }
  1023.  
  1024.             /********************************************************\
  1025.              *****              PC relative                     *****
  1026.              *****          (<data>,PC,Xn.SIZE*SCALE)           *****
  1027.             \********************************************************/
  1028.  
  1029.                 else if (p[3] == ',' && (t = isXreg(p+4, d, errorPtr)) != NULL)
  1030.                                                 /* PC relative with index */
  1031.                     {
  1032.                     p = t;
  1033.                     if (p[0] == ')' && isTerm(p[1]))
  1034.                         {
  1035.                         d->mode = PCIndex;
  1036.                         d->data -= loc;     /* displacement referenced to
  1037.                                              * the current value of
  1038.                                              * program counter */
  1039.                         if (d->backRef && d->data >= -128 && d->data <= 127)
  1040.                             d->xtenWord |= d->data & 0xff;
  1041.                         else if (d->backRef && d->data >= -32768
  1042.                                                         && d->data <= 32767)
  1043.                             d->xtenWord |= FULL_FORMAT | BASE_WORD
  1044.                                                             | OUTER_NULL;
  1045.                         else
  1046.                             d->xtenWord |= FULL_FORMAT | BASE_LONG
  1047.                                                             | OUTER_NULL;
  1048.                         return p+1;
  1049.                         }
  1050.                     else
  1051.                         {
  1052.                         NEWERROR(*errorPtr, SYNTAX);
  1053.                         return NULL;
  1054.                         }
  1055.                     }
  1056.                 }
  1057.             }
  1058.         }                           /* end of all beginning with "(<data> */
  1059.  
  1060.     /********************************************\
  1061.      *****           absolute               *****
  1062.      *****            <data>                *****
  1063.     \********************************************/
  1064.  
  1065.     error = *errorPtr;                          /* save current value */
  1066.     t = eval(p, &d->data, &d->backRef, errorPtr);
  1067.                                             /* is the first token a value? */
  1068.     if (*errorPtr < SEVERE)
  1069.         {
  1070.         p = t;
  1071.         if (isTerm(p[0]))
  1072.                   /* Determine size of absolute address (must be long if
  1073.                      the symbol isn't defined or if the value is too big */
  1074.             {
  1075.             if (!d->backRef || d->data > 32767 || d->data < -32768)
  1076.                 d->mode = AbsLong;
  1077.             else
  1078.                 d->mode = AbsShort;
  1079.             return p;
  1080.             }
  1081.         if (p[0] == '.' && isTerm(p[2]))
  1082.             if (p[1] == 'W')
  1083.                 {
  1084.                 d->mode = AbsShort;
  1085.                 return p+2;
  1086.                 }
  1087.             else if (p[1] == 'L')
  1088.                 {
  1089.                 d->mode = AbsLong;
  1090.                 return p+2;
  1091.                 }
  1092.             else
  1093.                 {
  1094.                 NEWERROR(*errorPtr, SYNTAX);
  1095.                 return NULL;
  1096.                 }
  1097.         }
  1098.     else
  1099.         *errorPtr = error;              /* restore old value */
  1100.  
  1101.     /************************************************\
  1102.      *****         Immediate mode:              *****
  1103.      *****             #<data>                  *****
  1104.     \************************************************/
  1105.  
  1106.     if (p[0] == '#')
  1107.         {
  1108.         p = eval(++p, &d->data, &d->backRef, errorPtr);
  1109.  
  1110.         /* If expression evaluates OK, then return */
  1111.         if (*errorPtr < SEVERE)
  1112.             {
  1113.             if (isTerm(*p))
  1114.                 {
  1115.                 d->mode = Immediate;
  1116.                 return p;
  1117.                 }
  1118.             else
  1119.                 {
  1120.                 NEWERROR(*errorPtr, SYNTAX);
  1121.                 return NULL;
  1122.                 }
  1123.             }
  1124.         else
  1125.             return NULL;
  1126.         }
  1127.  
  1128.     /* If the operand doesn't match any pattern, return an error status */
  1129.     NEWERROR(*errorPtr, SYNTAX);
  1130.     return NULL;
  1131.     }
  1132.