home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / CROSSASM / 68ASMSIM.ZIP / asmsrc / assemble.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-09  |  6.1 KB  |  232 lines

  1. /***********************************************************************
  2.  *
  3.  *        ASSEMBLE.C
  4.  *        Assembly Routines for 68000 Assembler
  5.  *
  6.  *    Function: processFile()
  7.  *        Assembles the input file. For each pass, the function
  8.  *        passes each line of the input file to assemble() to be 
  9.  *        assembled. The routine also makes sure that errors are 
  10.  *        printed on the screen and listed in the listing file 
  11.  *        and keeps track of the error counts and the line 
  12.  *        number.
  13.  *
  14.  *        assemble()
  15.  *        Assembles one line of assembly code. The line argument
  16.  *        points to the line to be assembled, and the errorPtr 
  17.  *        argument is used to return an error code via the 
  18.  *        standard mechanism. The routine first determines if the
  19.  *        line contains a label and saves the label for later
  20.  *        use. It then calls instLookup() to look up the
  21.  *        instruction (or directive) in the instruction table. If
  22.  *        this search is successful and the parseFlag for that
  23.  *        instruction is TRUE, it defines the label and parses
  24.  *        the source and destination operands of the instruction
  25.  *        (if appropriate) and searches the flavor list for the
  26.  *        instruction, calling the proper routine if a match is
  27.  *        found. If parseFlag is FALSE, it passes pointers to the
  28.  *        label and operands to the specified routine for
  29.  *        processing. 
  30.  *
  31.  *     Usage: processFile()
  32.  *
  33.  *        assemble(line, errorPtr)
  34.  *        char *line;
  35.  *        int *errorPtr;
  36.  *
  37.  *      Author: Paul McKee
  38.  *        ECE492    North Carolina State University
  39.  *
  40.  *        Date:    12/13/86
  41.  *
  42.  ************************************************************************/
  43.  
  44.  
  45. #include <stdio.h>
  46. #include <ctype.h>
  47. #include "asm.h"
  48.  
  49.  
  50. extern long    loc;            /* The assembler's location counter */
  51. extern char pass2;        /* Flag set during second pass */
  52. extern char endFlag;        /* Flag set when the END directive is encountered */
  53. extern char continuation;    /* TRUE if the listing line is a continuation */
  54.  
  55. extern int lineNum;
  56. extern int errorCount, warningCount;
  57.  
  58. extern char line[256];        /* Source line */
  59. extern FILE *inFile;        /* Input file */
  60. extern FILE *listFile;        /* Listing file */
  61. extern char listFlag;
  62.  
  63.  
  64. int    processFile()
  65. {
  66. char capLine[256];
  67. int error;
  68. char pass;
  69.  
  70.     pass2 = FALSE;
  71.     for (pass = 0; pass < 2; pass++) {
  72.         loc = 0;
  73.         lineNum = 1;
  74.         endFlag = FALSE;
  75.         errorCount = warningCount = 0;
  76.         while(!endFlag && fgets(line, 256, inFile)) {
  77.             strcap(capLine, line);
  78.             error = OK;
  79.             continuation = FALSE;
  80.             if (pass2 && listFlag)
  81.                 listLoc();
  82.             assemble(capLine, &error);
  83.             if (pass2) {
  84.                 if (error > MINOR)
  85.                     errorCount++;
  86.                 else if (error > WARNING)
  87.                     warningCount++;
  88.                 if (listFlag) {
  89.                     listLine();
  90.                     printError(listFile, error, -1);
  91.                     }
  92.                 printError(stderr, error, lineNum);
  93.                 }
  94.             lineNum++;
  95.             }
  96.         if (!pass2) {
  97.             pass2 = TRUE;
  98. /*            puts("************************************************************");
  99.             puts("********************  STARTING PASS 2  *********************");
  100.             puts("************************************************************"); */
  101.             }
  102.         rewind(inFile);
  103.         }
  104.  
  105.     return NORMAL;
  106.  
  107. }
  108.  
  109.  
  110. int    assemble(line, errorPtr)
  111. char *line;
  112. int *errorPtr;
  113. {
  114. instruction *tablePtr;
  115. flavor *flavorPtr;
  116. opDescriptor source, dest;
  117. char *p, *start, label[SIGCHARS+1], size, f, sourceParsed, destParsed;
  118. unsigned short mask, i;
  119.  
  120.     p = start = skipSpace(line);
  121.     if (*p && *p != '*') {
  122.         i = 0;
  123.         do {
  124.             if (i < SIGCHARS)
  125.                 label[i++] = *p;
  126.             p++;
  127.         } while (isalnum(*p) || *p == '.' || *p == '_' || *p == '$');
  128.         label[i] = '\0';
  129.         if ((isspace(*p) && start == line) || *p == ':') {
  130.             if (*p == ':')
  131.                 p++;
  132.             p = skipSpace(p);
  133.             if (*p == '*' || !*p) {
  134.                 define(label, loc, pass2, errorPtr);
  135.                 return NORMAL;
  136.                 }
  137.             }
  138.         else {
  139.             p = start;
  140.             label[0] = '\0';
  141.             }
  142.         p = instLookup(p, &tablePtr, &size, errorPtr);
  143.         if (*errorPtr > SEVERE)
  144.             return NORMAL;
  145.         p = skipSpace(p);
  146.         if (tablePtr->parseFlag) {
  147.             /* Move location counter to a word boundary and fix
  148.                the listing before assembling an instruction */
  149.             if (loc & 1) {
  150.                 loc++;
  151.                 listLoc();
  152.                 }
  153.             if (*label)
  154.                 define(label, loc, pass2, errorPtr);
  155.             if (*errorPtr > SEVERE)
  156.                 return NORMAL;
  157.             sourceParsed = destParsed = FALSE;
  158.             flavorPtr = tablePtr->flavorPtr;
  159.             for (f = 0; (f < tablePtr->flavorCount); f++, flavorPtr++) {
  160.                 if (!sourceParsed && flavorPtr->source) {
  161.                     p = opParse(p, &source, errorPtr);
  162.                     if (*errorPtr > SEVERE)
  163.                         return NORMAL;
  164.                     sourceParsed = TRUE;
  165.                     }
  166.                 if (!destParsed && flavorPtr->dest) {
  167.                     if (*p != ',') {
  168.                         NEWERROR(*errorPtr, SYNTAX);
  169.                         return NORMAL;
  170.                         }
  171.                     p = opParse(p+1, &dest, errorPtr);
  172.                     if (*errorPtr > SEVERE)
  173.                         return NORMAL;
  174.                     if (!isspace(*p) && *p) {
  175.                         NEWERROR(*errorPtr, SYNTAX);
  176.                         return NORMAL;
  177.                         }
  178.                     destParsed = TRUE;
  179.                     }
  180.                 if (!flavorPtr->source) {
  181.                     mask = pickMask( (int) size, flavorPtr, errorPtr);
  182.                     (*flavorPtr->exec)(mask, (int) size, &source, &dest, errorPtr);
  183.                     return NORMAL;
  184.                     }
  185.                 else if ((source.mode & flavorPtr->source) && !flavorPtr->dest) {
  186.                     if (!isspace(*p) && *p) {
  187.                         NEWERROR(*errorPtr, SYNTAX);
  188.                         return NORMAL;
  189.                         }
  190.                     mask = pickMask( (int) size, flavorPtr, errorPtr);
  191.                     (*flavorPtr->exec)(mask, (int) size, &source, &dest, errorPtr);
  192.                     return NORMAL;
  193.                     }
  194.                 else if (source.mode & flavorPtr->source
  195.                      && dest.mode & flavorPtr->dest) {
  196.                     mask = pickMask( (int) size, flavorPtr, errorPtr);
  197.                     (*flavorPtr->exec)(mask, (int) size, &source, &dest, errorPtr);
  198.                     return NORMAL;
  199.                     }
  200.                 }
  201.             NEWERROR(*errorPtr, INV_ADDR_MODE);
  202.             }
  203.         else {
  204.             (*tablePtr->exec)( (int) size, label, p, errorPtr);
  205.             return NORMAL;
  206.             }
  207.         }
  208.  
  209.     return NORMAL;
  210.  
  211. }
  212.  
  213.  
  214. int pickMask(size, flavorPtr, errorPtr)
  215. int size;
  216. flavor *flavorPtr;
  217. int *errorPtr;
  218. {
  219.     if (!size || size & flavorPtr->sizes)
  220.         if (size & (BYTE | SHORT))
  221.             return flavorPtr->bytemask;
  222.         else if (!size || size == WORD)
  223.             return flavorPtr->wordmask;
  224.         else
  225.             return flavorPtr->longmask;
  226.     NEWERROR(*errorPtr, INV_SIZE_CODE);
  227.     return flavorPtr->wordmask;
  228.  
  229. }
  230.  
  231.  
  232.