home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / CROSSASM / 68ASMSIM.ZIP / asmsrc / directiv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-09-07  |  10.3 KB  |  446 lines

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