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

  1. /***********************************************************************
  2.  *
  3.  *      DIRECTIV.C
  4.  *      Directive Routines for 68020 Assembler
  5.  *
  6.  * Description: The functions in this file carry out the functions of
  7.  *      assembler directives. All the functions share the same
  8.  *      calling sequence: 
  9.  *
  10.  *          general_name(instruction *tablePtr, int size, char *label,
  11.  *                                              char *op, int *errorPtr)
  12.  *
  13.  *      The size argument contains the size code that was specified with the 
  14.  *      instruction (using the definitions in ASM.H) or 0 if no size code was 
  15.  *      specified. The label argument is a pointer to a string (which may be 
  16.  *      empty) containing the label from the line containing the directive. 
  17.  *      The op argument is a pointer to the first non-blank character after 
  18.  *      the name of the directive, i.e., the operand(s) of the directive. 
  19.  *      The errorPtr argument is used to return a status via the standard
  20.  *      mechanism.
  21.  *      Argument tablePtr is not used.
  22.  *
  23.  *      Author: Paul McKee
  24.  *      ECE492    North Carolina State University,  12/13/86
  25.  *
  26.  *      Modified A.E.Romer      16 March 1991.
  27.  *      Version 1.0
  28.  *
  29.  ************************************************************************/
  30.  
  31.  
  32. #include <stdio.h>
  33. #include <ctype.h>
  34. #include "asm.h"
  35.  
  36. extern long loc;
  37. extern char pass2, endFlag, listFlag, noOperand;
  38.  
  39. extern char *listPtr;   /* Pointer to buffer where listing line is assembled
  40.                (Used to put =XXXXXXXX in the listing for EQU's and SET's */
  41.  
  42.  
  43. /***********************************************************************
  44.  *
  45.  *  Function org implements the ORG directive.
  46.  *
  47.  ***********************************************************************/
  48.  
  49. int org(instruction *tablePtr, int size, char *label, char *op,
  50.                                                         int *errorPtr)
  51.     {
  52.     long newLoc;
  53.     char backRef;
  54.  
  55.     if (size)
  56.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  57.     if (!*op)
  58.         {
  59.         NEWERROR(*errorPtr, SYNTAX);
  60.         return NORMAL;
  61.         }
  62.     op = eval(op, &newLoc, &backRef, errorPtr);
  63.     if (*errorPtr < SEVERE && !backRef)
  64.         {
  65.         NEWERROR(*errorPtr, INV_FORWARD_REF);
  66.         }
  67.     else if (*errorPtr < ERROR)
  68.         {
  69.         if (isspace(*op) || !*op)
  70.             {
  71.             /* Check for an odd value, adjust to one higher */
  72.             if (newLoc & 1)
  73.                 {
  74.                 NEWERROR(*errorPtr, ODD_ADDRESS);
  75.                 newLoc++;
  76.                 }
  77.             loc = newLoc;
  78.             /* Define the label attached to this directive, if any */
  79.             if (*label)
  80.                 create(label, loc, errorPtr);
  81.             /* Show new location counter on listing */
  82.             listLoc();
  83.             }
  84.         else
  85.             NEWERROR(*errorPtr, SYNTAX);
  86.         }
  87.  
  88.     return NORMAL;
  89. }
  90.  
  91.  
  92. /***********************************************************************
  93.  *
  94.  *  Function end implements the END directive.
  95.  *
  96.  ***********************************************************************/
  97.  
  98. int funct_end(instruction *tablePtr, int size, char *label, char *op,
  99.                                                             int *errorPtr)
  100.     {
  101.     if (size)
  102.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  103.     endFlag = TRUE;
  104.     noOperand = TRUE;
  105.  
  106.     return NORMAL;
  107.     }
  108.  
  109.  
  110. /***********************************************************************
  111.  *
  112.  *  Function equ implements the EQU directive.
  113.  *
  114.  ***********************************************************************/
  115.  
  116. int equ(instruction *tablePtr, int size, char *label, char *op, int *errorPtr)
  117.     {
  118.     long value;
  119.     char backRef;
  120.  
  121.     if (size)
  122.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  123.     if (!*op)
  124.         {
  125.         NEWERROR(*errorPtr, SYNTAX);
  126.         return NORMAL;
  127.         }
  128.     op = eval(op, &value, &backRef, errorPtr);
  129.     if (*errorPtr < SEVERE && !backRef)
  130.         {
  131.         NEWERROR(*errorPtr, INV_FORWARD_REF);
  132.         }
  133.     else if (*errorPtr < ERROR)
  134.         if (isspace(*op) || !*op)
  135.             if (!*label)
  136.                 {
  137.                 NEWERROR(*errorPtr, LABEL_REQUIRED);
  138.                 }
  139.             else
  140.                 {       
  141.                 create(label, value, errorPtr);
  142.                 if (pass2 && listFlag && *errorPtr < MINOR)
  143.                     {
  144.                     sprintf(listPtr, "=%08lX ", value);
  145.                     listPtr += 10;
  146.                     }
  147.                 }
  148.         else
  149.             NEWERROR(*errorPtr, SYNTAX);
  150.  
  151.     return NORMAL;
  152.     }
  153.  
  154.  
  155. /***********************************************************************
  156.  *
  157.  *  Function set implements the SET directive.
  158.  *
  159.  ***********************************************************************/
  160.  
  161. int set(instruction *tablePtr, int size, char *label, char *op, int *errorPtr)
  162.     {
  163.     long value;
  164.     int error;
  165.     char backRef;
  166.     symbolDef *symbol;
  167.  
  168.     if (size)
  169.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  170.     if (!*op)
  171.         {
  172.         NEWERROR(*errorPtr, SYNTAX);
  173.         return NORMAL;
  174.         }
  175.     error = OK;
  176.     op = eval(op, &value, &backRef, errorPtr);
  177.     if (*errorPtr < SEVERE && !backRef)
  178.         NEWERROR(*errorPtr, INV_FORWARD_REF);
  179.     if (*errorPtr > ERROR)
  180.         if (isspace(*op) || !*op)
  181.             if (!*label)
  182.                 {
  183.                 NEWERROR(*errorPtr, LABEL_REQUIRED);
  184.                 }
  185.             else
  186.                 {
  187.                 error = OK;
  188.                 symbol = create(label, value, &error);
  189.                 if (error == MULTIPLE_DEFS)
  190.                     if (symbol->flags & REDEFINABLE)
  191.                         symbol->value = value;
  192.                     else
  193.                         {
  194.                         NEWERROR(*errorPtr, MULTIPLE_DEFS);
  195.                         return NORMAL;
  196.                         }
  197.                 symbol->flags |= REDEFINABLE;
  198.                 if (pass2 & listFlag)
  199.                     {
  200.                     sprintf(listPtr, "=%08lX ", value);
  201.                     listPtr += 10;
  202.                     }
  203.                 }
  204.         else
  205.             NEWERROR(*errorPtr, SYNTAX);
  206.  
  207.     return NORMAL;
  208.     }
  209.  
  210.  
  211. /**********************************************************************
  212.  *
  213.  *  Function collect parses strings for dc. Each output string
  214.  *  is padded with four nulls at the end.
  215.  *
  216.  **********************************************************************/
  217.  
  218. char *collect(char *s, char *d)
  219.     {
  220.     while (*s) {
  221.         if (*s == CHAR_DELIMITER)
  222.             if (*(s+1) == CHAR_DELIMITER)
  223.                 {
  224.                 *d++ = *s;
  225.                 s += 2;
  226.                 }
  227.             else
  228.                 {
  229.                 *d++ = '\0';
  230.                 *d++ = '\0';
  231.                 *d++ = '\0';
  232.                 *d++ = '\0';
  233.                 return ++s;
  234.                 }
  235.         else
  236.             *d++ = *s++;
  237.         }
  238.     return s;
  239. }
  240.  
  241.  
  242. /***********************************************************************
  243.  *
  244.  *  Function dc implements the DC directive.
  245.  *
  246.  ***********************************************************************/
  247.  
  248. int dc(instruction *tablePtr, int size, char *label, char *op, int *errorPtr)
  249.     {
  250.     long outVal;
  251.     char backRef;
  252.     char string[260], *p;
  253.  
  254.     if (size == SHORT)
  255.         {
  256.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  257.         size = WORD;
  258.         }
  259.     else if (!size)
  260.         size = WORD;
  261.     /* Move location counter to a word boundary and fix the listing if doing
  262.        DC.W or DC.L (but not if doing DC.B, so DC.B's can be contiguous) */
  263.     if ((size & (WORD | LONG)) && (loc & 1))
  264.         {
  265.         loc++;
  266.         listLoc();
  267.         }
  268.     /* Define the label attached to this directive, if any */
  269.     if (*label)
  270.         create(label, loc, errorPtr);
  271.     /* Check for the presence of the operand list */
  272.     if (!*op)
  273.         {
  274.         NEWERROR(*errorPtr, SYNTAX);
  275.         return NORMAL;
  276.         }
  277.     do
  278.         {
  279.         if (*op == CHAR_DELIMITER)
  280.             {
  281.             op = collect(++op, string);
  282.             if (!isspace(*op) && *op !=     ',')
  283.                 {
  284.                 NEWERROR(*errorPtr, SYNTAX);
  285.                 return NORMAL;
  286.                 }
  287.             p = string;
  288.             while (*p)
  289.                 {
  290.                 outVal = *p++;
  291.                 if (size > BYTE)
  292.                     outVal = (outVal << 8) + *p++;
  293.                 if (size > WORD)
  294.                     {
  295.                     outVal = (outVal << 16) + (*p++ << 8);
  296.                     outVal += *p++;
  297.                     }
  298.                 if (pass2)
  299.                     output(outVal, size);
  300.                 loc += size;
  301.                 }
  302.             }
  303.         else
  304.             {
  305.             op = eval(op, &outVal, &backRef, errorPtr);
  306.             if (*errorPtr > SEVERE)
  307.                 return NORMAL;
  308.             if (!isspace(*op) && *op != ',')
  309.                 {
  310.                 NEWERROR(*errorPtr, SYNTAX);
  311.                 return NORMAL;
  312.                 }
  313.             if (pass2)
  314.                 output(outVal, size);
  315.             loc += size;
  316.             if (size == BYTE && (outVal < -128 || outVal > 255))
  317.                 {
  318.                 NEWERROR(*errorPtr, INV_8_BIT_DATA);
  319.                 }
  320.             else if (size == WORD && (outVal < -32768 || outVal > 65535))
  321.                 NEWERROR(*errorPtr, INV_16_BIT_DATA);
  322.             }
  323.     } while (*op++ == ',');
  324.     --op;
  325.     if (!isspace(*op) && *op)
  326.         NEWERROR(*errorPtr, SYNTAX);
  327.  
  328.     return NORMAL;
  329.     }
  330.  
  331. /***********************************************************************
  332.  *
  333.  *  Function dcb implements the DCB directive.
  334.  *
  335.  ***********************************************************************/
  336.  
  337. int dcb(instruction *tablePtr, int size, char *label, char *op, int *errorPtr)
  338.     {
  339.     long blockSize, blockVal, i;
  340.     char backRef;
  341.  
  342.     if (size == SHORT)
  343.         {
  344.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  345.         size = WORD;
  346.         }
  347.     else if (!size)
  348.         size = WORD;
  349.     /* Move location counter to a word boundary and fix the listing if doing
  350.        DCB.W or DCB.L (but not if doing DCB.B, so DCB.B's can be contiguous)
  351.      */
  352.     if ((size & (WORD | LONG)) && (loc & 1))
  353.         {
  354.         loc++;
  355.         listLoc();
  356.         }
  357.     /* Define the label attached to this directive, if any */
  358.     if (*label)
  359.         create(label, loc, errorPtr);
  360.     /* Evaluate the size of the block (in bytes, words, or longwords) */
  361.     op = eval(op, &blockSize, &backRef, errorPtr);
  362.     if (*errorPtr < SEVERE && !backRef)
  363.         {
  364.         NEWERROR(*errorPtr, INV_FORWARD_REF);
  365.         return NORMAL;
  366.         }
  367.     if (*errorPtr > SEVERE)
  368.         return NORMAL;
  369.     if (*op != ',')
  370.         {
  371.         NEWERROR(*errorPtr, SYNTAX);
  372.         return NORMAL;
  373.         }
  374.     if (blockSize < 0) {
  375.         NEWERROR(*errorPtr, INV_LENGTH);
  376.         return NORMAL;
  377.         }
  378.     /* Evaluate the data to put in block */
  379.     op = eval(++op, &blockVal, &backRef, errorPtr);
  380.     if (*errorPtr < SEVERE)
  381.         {
  382.         if (!isspace(*op) && *op)
  383.             {
  384.             NEWERROR(*errorPtr, SYNTAX);
  385.             return NORMAL;
  386.             }
  387.         /* On pass 2, output the block of values directly
  388.            to the object file (without putting them in the listing) */
  389.         if (pass2)
  390.             for (i = 0; i < blockSize; i++)
  391.                 {
  392.                 outputObj(loc, blockVal, size);
  393.                 loc += size;
  394.                 }
  395.         else
  396.             loc += blockSize * size;
  397.         }
  398.  
  399.     return NORMAL;
  400.     }
  401.  
  402.  
  403. /***********************************************************************
  404.  *
  405.  *  Function ds implements the DS directive.
  406.  *
  407.  ***********************************************************************/
  408.  
  409. int ds(instruction *tablePtr, int size, char *label, char *op, int *errorPtr)
  410.     {
  411.     long blockSize;
  412.     char backRef;
  413.  
  414.     if (size == SHORT)
  415.         {
  416.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  417.         size = WORD;
  418.         }
  419.     else if (!size)
  420.         size = WORD;
  421.     /* Move location counter to a word boundary and fix the listing if doing
  422.        DS.W or DS.L (but not if doing DS.B, so DS.B's can be contiguous) */
  423.     if ((size & (WORD | LONG)) && (loc & 1))
  424.         {
  425.         loc++;
  426.         listLoc();
  427.         }
  428.     /* Define the label attached to this directive, if any */
  429.     if (*label)
  430.         create(label, loc, errorPtr);
  431.     /* Evaluate the size of the block (in bytes, words, or longwords) */
  432.     op = eval(op, &blockSize, &backRef, errorPtr);
  433.     if (*errorPtr < SEVERE && !backRef)
  434.         {
  435.         NEWERROR(*errorPtr, INV_FORWARD_REF);
  436.         return NORMAL;
  437.         }
  438.     if (*errorPtr > SEVERE)
  439.         return NORMAL;
  440.     if (!isspace(*op) && *op)
  441.         {
  442.         NEWERROR(*errorPtr, SYNTAX);
  443.         return NORMAL;
  444.         }
  445.     if (blockSize < 0)
  446.         {
  447.         NEWERROR(*errorPtr, INV_LENGTH);
  448.         return NORMAL;
  449.         }
  450.     loc += blockSize * size;
  451.  
  452.     return NORMAL;
  453.     }
  454.  
  455.