home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 529a.lha / A68k_v2.71 / Adirect.c < prev    next >
C/C++ Source or Header  |  1991-07-02  |  25KB  |  868 lines

  1. /*------------------------------------------------------------------*/
  2. /*                                    */
  3. /*            MC68000 Cross Assembler                */
  4. /*                                    */
  5. /*                Copyright 1985 by Brian R. Anderson            */
  6. /*                                    */
  7. /*          Assembler directive processing - April 16, 1991        */
  8. /*                                    */
  9. /*   This program may be copied for personal, non-commercial use    */
  10. /*   only, provided that the above copyright notice is included        */
  11. /*   on all copies of the source code.  Copying for any other use   */
  12. /*   without the consent of the author is prohibited.            */
  13. /*                                    */
  14. /*------------------------------------------------------------------*/
  15. /*                                    */
  16. /*        Originally published (in Modula-2) in            */
  17. /*        Dr. Dobb's Journal, April, May, and June 1986.          */
  18. /*                                    */
  19. /*     AmigaDOS conversion copyright 1991 by Charlie Gibbs.        */
  20. /*                                    */
  21. /*------------------------------------------------------------------*/
  22.  
  23. #include "A68kdef.h"
  24. #include "A68kglb.h"
  25.  
  26.  
  27.  
  28. int ObjDir (dummy) int dummy;
  29. /* Generates Object Code for Assembler Directives. */
  30. {
  31.     register char *s, *t;
  32.     register int i, j;
  33.     int  oploc;
  34.     long templong;
  35.     char tempop[MAXLINE], delim;
  36.     struct SetFixup *sf;
  37.  
  38.     switch (Dir) {
  39.  
  40.     case Org:                        /* ORG, RORG */
  41.     PrntAddr = MakeHunk = TRUE;
  42.     FwdLim1     = FwdBranch;    /* Clear forward branch controls. */
  43.     FwdFixLimit = FwdBranchFix;
  44.     templong = GetValue (SrcOp, SrcLoc);
  45.     if (DefLine2 >= LineCount) {
  46.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  47.         break;
  48.     }
  49.     if (OpCode[0] == 'R') {                /* RORG */
  50.         if (Hunk2 != ABSHUNK) {
  51.         Error (SrcLoc, RelErr);    /* RORG needs an absolute value. */
  52.         break;
  53.         }
  54.     } else if ((!SFormat && (Hunk2 != CurrHunk))
  55.     || (SFormat && (Hunk2 != ABSHUNK))) {
  56.         Error (SrcLoc, RelErr);    /* We can't ORG out of a hunk. */
  57.         break;
  58.     }
  59.  
  60.     if ((!Pass2 || (HunkType == HunkBSS))
  61.     && (templong < AddrCnt)    /* If we're ORGing to a lower address  */
  62.     && (AddrCnt > OrgHigh))    /*  and this is the highest we've been */
  63.         OrgHigh = AddrCnt;    /*  remember how far we got.           */
  64.  
  65.     AddrCnt = templong;    /* Update the location counter. */
  66.     OrgFlag = TRUE;        /* Indicate object fixups are needed. */
  67.     if (HunkType == HunkNone) {
  68.         DoSection ("", 0, "", 0, "", 0);    /* Start unnamed CODE section. */
  69.         MakeHunk = TRUE;
  70.     }
  71.     break;
  72.  
  73.     case Equ:                        /* EQU */
  74.     if (Label[0] == '\0')
  75.         Error (0, NeedLab);        /* We need a label. */
  76.     ObjSrc = GetValue (SrcOp, SrcLoc);
  77.     if (DefLine2 >= LineCount)
  78.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  79.     Src.Hunk = Hunk2;
  80.     PrntAddr = MakeHunk = TRUE;
  81.     break;
  82.  
  83.     case DC:                        /* DC */
  84.     if ((Size == Word) || (Size == Long))
  85.         AddrCnt = AddrBndW (AddrCnt);
  86.     s = Line + SrcLoc;
  87.     while (!isspace(*s) && (*s != '\0') && (*s != ';')) {
  88.         oploc = s - Line;
  89.         if (((*s == '\'') || (*s == '"'))    /* String */
  90.         && (Size == Byte)) {
  91.         delim = *s++;            /* Get the delimiter. */
  92.         while (1) {
  93.             if (*s == '\0') {        /* No closing delimiter */
  94.             Error (s-Line, NoStrEnd);
  95.             break;
  96.             }
  97.             if (*s == delim) {        /* End of string? */
  98.             if (*(++s) != delim)    /* Check next character. */
  99.                 break;        /* End of string */
  100.             }    /* Otherwise it's an apostrophe in the string. */
  101.             Src.Hunk = ABSHUNK;        /* Absolute value */
  102.             ObjString[nX++] = *s++;    /* Current character */
  103.         }
  104.         } else {            /* It's not a string constant. */
  105.         s = GetField (s, SrcOp);
  106.         ObjSrc = GetValue (SrcOp, oploc);    /* Value */
  107.         if ((Src.Hunk = Hunk2) != ABSHUNK) {    /* Hunk number */
  108.             templong = AddrCnt + nX;        /* Relocatable */
  109.             PutRel (templong, Hunk2, Size);
  110.         }
  111.         if (Size == 4) {
  112.             ObjString[nX++] = (ObjSrc >> 24) & 0x00FF;
  113.             ObjString[nX++] = (ObjSrc >> 16) & 0x00FF;
  114.         }
  115.         if (Size >= 2)
  116.             ObjString[nX++] = (ObjSrc >> 8) & 0x00FF;
  117.         ObjString[nX++] = ObjSrc & 0x00FF;
  118.         if (Size == 2)
  119.             templong = 0xFFFF0000L;
  120.         else if (Size == 1)
  121.             templong = 0xFFFFFF00L;
  122.         if (Size < 4)
  123.             if (((ObjSrc & templong) != 0)
  124.             && ((ObjSrc & templong) != templong))
  125.             Error (s-Line, SizeErr);
  126.         }
  127.         if (*s == ',')
  128.         s++;            /* Skip over separator. */
  129.     }
  130.     if ((!isspace(*s) && (*s != '\0') && (*s != ';'))
  131.     || (SrcLoc == 0))
  132.         Error (s-Line, OperErr);    /* Statement didn't end properly. */
  133.     AddrAdv = InstSize = nX;
  134.     PrntAddr = MakeHunk = TRUE;
  135.     break;
  136.  
  137.     case DS:                        /* DS */
  138.     if (DestLoc != 0) {
  139.         Error (DestLoc, OperErr);    /* Only one operand is allowed. */
  140.         PrntAddr = MakeHunk = TRUE;
  141.         break;
  142.     }
  143.     AddrAdv = GetValue (SrcOp, SrcLoc);
  144.     if (DefLine2 >= LineCount) {
  145.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  146.         AddrAdv = 0;
  147.     }
  148.     if (Hunk2 != ABSHUNK)
  149.         Error (SrcLoc, AbsReq);    /* Count must be absolute. */
  150.  
  151.     if (Size == Word) {        /* Words */
  152.         AddrCnt = AddrBndW (AddrCnt);
  153.         AddrAdv <<= 1;
  154.     }
  155.     if (Size == Long) {        /* Long words */
  156.         AddrCnt = AddrBndW (AddrCnt);
  157.         AddrAdv <<= 2;
  158.     }
  159.     if (Pass2 && (HunkType != HunkBSS)) {    /* If this isn't      */
  160.         templong = AddrAdv;            /*  a BSS hunk,       */
  161.         while (templong >= 4) {        /*  generate zeros    */
  162.         AppendSdata (0L, 4);        /*  to fill the area. */
  163.         templong -= 4;
  164.         }
  165.         if (templong > 0) {
  166.         i = templong;
  167.         AppendSdata (0L, i);
  168.         }
  169.     }
  170.     PrntAddr = MakeHunk = TRUE;
  171.     break;
  172.  
  173.     case Even:                        /* EVEN */
  174.     FwdLim1     = FwdBranch;    /* Clear forward branch controls. */
  175.     FwdFixLimit = FwdBranchFix;
  176.     AddrCnt = AddrBndW (AddrCnt);
  177.     PrntAddr = MakeHunk = TRUE;
  178.     break;
  179.  
  180.     case End:                        /* END */
  181.     if (Pass2)
  182.         if (SrcOp[0] != '\0')
  183.         EndAddr = GetValue (SrcOp, SrcLoc);
  184.         else
  185.         EndAddr = 0;
  186.     PrntAddr = MakeHunk = TRUE;
  187.     break;
  188.  
  189.     case Xdef:                        /* XDEF */
  190.     case Public:                    /* PUBLIC */
  191.     if (SFormat)
  192.         Error (OpLoc, NotSFmt);        /* Not in S-format */
  193.     s = Line + SrcLoc;
  194.     while (!isspace(*s) && (*s != '\0') && (*s != ';')) {
  195.         oploc = s - Line;
  196.         s = GetField (s, SrcOp);        /* Get a symbol. */
  197.         if (ReadSymTab (SrcOp)) {
  198.         if (!Pass2) {
  199.             if ((Sym->Flags & 0x61) == 0) {
  200.             Sym->Flags |= 2;    /* Set XDEF flag. */
  201.             if (OpCode[0] == 'P') {
  202.                 Sym->Flags |= 0x80;    /* It's defined as PUBLIC. */
  203.             }
  204.             }
  205.         } else {
  206.             if (Sym->Defn != LineCount)    /* If not PUBLIC->XREF */
  207.             AddRef (LineCount);    /*  it's a reference.  */
  208.             if (Sym->Defn == NODEF)
  209.             Error (oploc, Undef);    /* It never got defined. */
  210.             else if (Sym->Flags & 0x60)
  211.             Error (oploc, AddrErr);    /* Can't XDEF a register. */
  212.         }
  213.         } else if (!Pass2) {        /* It's not yet defined. */
  214.         if (OpCode[0] == 'P') {        /* Treat PUBLIC as XREF. */
  215.             AddSymTab (SrcOp, 0L, 0L ,LineCount, 0x81);
  216.             Sym->Hunk = ~((long) Sym->Nam);
  217.         } else {
  218.             AddSymTab (SrcOp, 0L, CurrHunk, NODEF, 2);    /* XDEF */
  219.         }
  220.         }
  221.         if (*s == ',')
  222.         s++;                /* Skip over separator. */
  223.     }
  224.     break;
  225.  
  226.     case Xref:                        /* XREF */
  227.     if (SFormat)
  228.         Error (OpLoc, NotSFmt);        /* Not in S-format */
  229.     s = Line + SrcLoc;
  230.     while (!isspace(*s) && (*s != '\0') && (*s != ';')) {
  231.         oploc = s - Line;
  232.         s = GetField (s, SrcOp);
  233.         if (Pass2) {
  234.         if (ReadSymTab (SrcOp)) {
  235.             if (Sym->Defn != LineCount) {
  236.             AddRef (LineCount);    /* Ignore extraneous XREF. */
  237.             }
  238.         }
  239.         } else {
  240.         if (!ReadSymTab    (SrcOp)) {    /* Only if not defined */
  241.             AddSymTab (SrcOp, 0L, 0L, LineCount, 1);
  242.             Sym->Hunk = ~((long) Sym->Nam);
  243.         }
  244.         }
  245.         if (*s == ',')
  246.         s++;            /* Skip over separator. */
  247.     }
  248.     break;
  249.  
  250.     case Page:                        /* PAGE */
  251.     if (Pass2 && (LineCount > 1))    /* Ignore PAGE at start of file. */
  252.         LnCnt = LnMax;        /* Resume on a new page. */
  253.     break;
  254.  
  255.     case DoList:                    /* LIST */
  256.     ListOff = FALSE;
  257.     if (!Pass2 && !SuppList && (IncStart != 0)) {
  258.         IncStart = 0;            /* We can't      */
  259.         if (SkipLim->Set1 != NULL) {    /*  skip this    */
  260.         SetFixLim = SkipLim->Set1;    /*  INCLUDE file */
  261.         SetFixLim++;            /*  in pass 2    */
  262.         }                    /*  (we must     */
  263.     }                    /*  list it).    */
  264.     break;
  265.  
  266.     case NoList:                    /* NOLIST */
  267.     ListOff = TRUE;
  268.     break;
  269.  
  270.     case Space:                        /* SPC */
  271.     if (Pass2 && !ListOff && !SuppList) {
  272.         if (SrcOp[0] != '\0')
  273.         j = GetValue (SrcOp, SrcLoc);    /* Amount to space */
  274.         else
  275.         j = 1;                /* Default to one line. */
  276.         for (i = 0; i < j; i++) {
  277.         if (LnCnt >= LnMax)
  278.             break;            /* Page overflow */
  279.         xputs (&List, "\n");        /* Space one line. */
  280.         }
  281.     }
  282.     break;
  283.  
  284.     case Title:                        /* TTL */
  285.     s = Line + SrcLoc;
  286.     t = TTLstring;
  287.     while (*s && (s < (TTLstring+MAXLINE)))
  288.         *t++ = *s++;        /* Get title string. */
  289.     *t = '\0';
  290.     if (LineCount > 1) {
  291.         LnCnt = LnMax;        /* Skip to a new page. */
  292.     } else {
  293.         if (Pass2) {
  294.         xputs (&List, TTLstring);
  295.         xputs (&List, "\n\n");
  296.         }
  297.         LnCnt += 2;            /* Don't skip at start of file. */
  298.     }
  299.     break;
  300.  
  301.     case Cnop:                        /* CNOP */
  302.     FwdLim1     = FwdBranch;    /* Clear forward branch controls. */
  303.     FwdFixLimit = FwdBranchFix;
  304.     i = TRUE;            /* "Error-free" flag */
  305.  
  306.     ObjSrc = GetValue (SrcOp, SrcLoc);
  307.     if (DefLine2 >= LineCount) {
  308.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  309.         i = FALSE;
  310.     }
  311.     if (Hunk2 != ABSHUNK) {
  312.         Error (SrcLoc, AbsReq);    /* Must be absolute! */
  313.         i = FALSE;
  314.     }
  315.  
  316.     ObjDest = GetValue (DestOp, DestLoc);
  317.     if (DefLine2 >= LineCount) {
  318.         Error (DestLoc, FwdRef);    /* Illegal forward reference */
  319.         i = FALSE;
  320.     }
  321.     if (Hunk2 != ABSHUNK) {
  322.         Error (DestLoc, AbsReq);    /* Must be absolute! */
  323.         i = FALSE;
  324.     }
  325.  
  326.     templong = ObjDest;
  327.     while ((templong > 0) && ((templong & 1) == 0))
  328.         templong >>= 1;        /* Shift out low-order zeros. */
  329.     if ((templong != 1) || (ObjDest == 1)) {
  330.         Error (DestLoc, OperErr);    /* DestOp must be a power of 2. */
  331.         i = FALSE;
  332.     }
  333.     if ((ObjSrc & 1) || (ObjSrc >= ObjDest)) {
  334.         Error (SrcLoc, OperErr);    /* SrcOp is odd or out of range. */
  335.         i = FALSE;
  336.     }
  337.  
  338.     if (i) {            /* If no errors so far... */
  339.         AddrCnt = AddrBndW (AddrCnt);
  340.         templong = (AddrCnt & ~(ObjDest-1)) + ObjSrc;
  341.         if (templong < AddrCnt)
  342.         templong += ObjDest;    /* We must advance to here. */
  343.         if ((templong - AddrCnt) < MAXLINE) {
  344.         nX = templong - AddrCnt;
  345.         for (j = 0; j < nX; ) {
  346.             ObjString[j++] = NOP / 256;
  347.             ObjString[j++] = NOP & 255;
  348.         }
  349.         AddrAdv = InstSize = nX;    /* Generate NOPs. */
  350.         PrntAddr = MakeHunk = TRUE;
  351.         } else {
  352.         Error (DestLoc, OperErr);    /* Too many NOPs */
  353.         }
  354.     }
  355.     break;
  356.  
  357.     case Include:                    /* INCLUDE */
  358.     case Incbin:                    /* INCBIN */
  359.     if (Pass2 && (Dir == Include)        /* If we can skip */
  360.     && (SkipIdx < SkipLim)            /*  this INCLUDE  */
  361.     && (LineCount == SkipIdx->Start)) {    /*  file in pass  */
  362.         LineCount = SkipIdx->Finish;    /*  2, do so.     */
  363.         MacCount = SkipIdx->MCount;
  364.         if ((sf = SkipIdx->Set1) != NULL) {
  365.         while ((sf >= SetFixLim) && (sf->Sym != NULL)) {
  366.             (sf->Sym)->Val  = sf->Val;    /* Fix up SET symbols. */
  367.             (sf->Sym)->Hunk = sf->Hunk;
  368.             sf--;
  369.         }
  370.         }
  371.         SkipIdx++;
  372.         break;
  373.     }
  374.     if ((Quiet < 0) && (InF->UPtr == 0) && (Dir == Include))
  375.         ShowLine (InF->Line);    /* Show where we are. */
  376.     s = Line + SrcLoc;
  377.     if ((*s == '"') || (*s == '\''))
  378.         s++;            /* Ignore quotes. */
  379.     t = tempop;
  380.     while (!isspace(*s)
  381.     && (*s != '"')
  382.     && (*s != '\'')
  383.     && (*s != '\0'))
  384.         *t++ = *s++;
  385.     *t = '\0';
  386.  
  387.     if (!OpenIncl (tempop, InclList)) {
  388.         Error (SrcLoc, NoIncl);    /* We couldn't open file. */
  389.         InclErrs = TRUE;
  390.         break;            /* Return to outer file. */
  391.     }
  392.     if (Dir == Incbin) {
  393.         while ((t = In.Buf + read (In.fd, In.Buf, BUFFSIZE)) > In.Buf) {
  394.         for (s = In.Buf; s < t; s++) {
  395.             templong = *s;
  396.             AppendSdata (templong, 1);    /* Copy INCBIN file to output. */
  397.             AddrAdv++;            /* Bump location counter. */
  398.         }
  399.         }
  400.         close (In.fd);            /* Close INCBIN file. */
  401.         In.fd = NULL;
  402.         if (InF->UPtr == 0) {
  403.         In.fd = open (InF->NPtr, 0);    /* Re-open the outer file. */
  404.         lseek (In.fd, InF->Pos, 0);    /* Restore position in file. */
  405.         In.Ptr = In.Lim = In.Buf;
  406.         }
  407.         break;
  408.     }
  409.     InFNum++;            /* Bump nesting level. */
  410.     if (--InF < LowInF)
  411.         LowInF = InF;
  412.     InF->UPtr = 0;            /* It's not a user macro. */
  413.     InF->NPtr = NextFNS;        /* New stack pointer */
  414.     InF->Line = 0;            /* Clear line counter. */
  415.     InF->MCnt = MacCount;
  416.     Heap2Space (strlen(tempop)+1);    /* Check for space. */
  417.     strcpy (NextFNS, tempop);    /* File name */
  418.     NextFNS    += strlen (tempop) + 1;    /* Next available space */
  419.     if (NextFNS > High2)
  420.         High2 = NextFNS;        /* Set high-water mark. */
  421.     InF->NArg = -1;            /* Indicate it's not a macro. */
  422.  
  423.     if (!Pass2 && (SuppList || ListOff) && (IncStart == 0)) {
  424.         s = (char *) SkipLim + sizeof (struct SkipEnt);
  425.         if (s <= (char *) SetFixLim) {
  426.         SkipLim->Set1 = NULL;    /* Save starting position */
  427.         IncStart = LineCount;    /*  in case we can skip   */
  428.         IncPtr = InF;        /*  this file in pass 2.  */
  429.         }
  430.     }
  431.     break;
  432.  
  433.     case Set:                        /* SET */
  434.     if (Label[0] == '\0')
  435.         Error (0, NeedLab);        /* Need a label */
  436.     ObjSrc = GetValue (SrcOp, SrcLoc);
  437.     if (DefLine2 >= LineCount)
  438.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  439.     Src.Hunk = Hunk2;
  440.     if (!ReadSymTab (Label))        /* Make a new entry. */
  441.         AddSymTab (Label, ObjSrc, Src.Hunk, LineCount, 4);
  442.     else if (Sym->Flags & 4) {        /* Re-SET the symbol. */
  443.         Sym->Val = ObjSrc;            /* SET value */
  444.         Sym->Hunk = Src.Hunk;        /* Hunk number */
  445.         Sym->Defn = LineCount;        /* Statement number */
  446.     }
  447.     PrntAddr = MakeHunk = TRUE;
  448.  
  449.     if (!Pass2 && (IncStart != 0)) {
  450.         if ((sf = SkipLim->Set1) != NULL) {
  451.         while (sf >= SetFixLim) {
  452.             if (sf->Sym != Sym) {
  453.             sf--;
  454.             } else {
  455.             sf->Val  = Sym->Val;    /* Update an        */
  456.             sf->Hunk = Sym->Hunk;    /*  existing entry. */
  457.             return (Set);
  458.             }
  459.         }
  460.         }
  461.         sf = SetFixLim;
  462.         sf--;
  463.         s = (char *) SkipLim + sizeof (struct SkipEnt);
  464.         if (s > (char *) sf) {
  465.         IncStart = 0;        /* There's no room for set symbol. */
  466.         if (SkipLim->Set1 != NULL) {
  467.             SetFixLim = SkipLim->Set1;
  468.             SetFixLim++;
  469.         }
  470.         } else {
  471.         if (SkipLim->Set1 == NULL)
  472.             SkipLim->Set1 = sf;    /* First SET symbol in INCLUDE */
  473.         sf->Sym  = Sym;
  474.         sf->Val  = Sym->Val;    /* Save SET symbol value */
  475.         sf->Hunk = Sym->Hunk;    /*  and hunk.            */
  476.         SetFixLim = sf;
  477.         }
  478.     }
  479.     break;
  480.  
  481.     case Macro:                        /* MACRO */
  482.     if (Label[0] == '\0')
  483.         Error (0, NeedLab);        /* Need a label */
  484.  
  485.     s = Label;
  486.     t = tempop;
  487.     *t++ = ' ';            /* Prepend name with a */
  488.     while (*s) {            /*  blank and convert  */
  489.         *t++ = toupper (*s);    /*  it to upper case.  */
  490.         s++;
  491.     }
  492.     *t = '\0';
  493.  
  494.     if (!Pass2) {            /* Pass 1 */
  495.         if (!ReadSymTab (tempop))        /* Save MACRO name. */
  496.         AddSymTab (tempop, 0L, 0L, LineCount, 8);
  497.         Sym->Hunk = (long) AddName(Line,1);    /* Save MACRO stmt. */
  498.     } else {            /* Pass 2 */
  499.         ReadSymTab (tempop);
  500.         if (Sym->Defn != LineCount) {
  501.         Error (LabLoc, DupMac);        /* Duplicate MACRO */
  502.         AddRef (LineCount);
  503.         }
  504.         WriteListLine (&List);        /* Echo MACRO. */
  505.     }
  506.  
  507.     i = 0;                /* IF nest counter */
  508.     while (1) {            /* Process macro body. */
  509.         if (LineParts (dummy)) {
  510.         Error (OpLoc, NoENDM);    /* Premature EOF */
  511.         i = 0;
  512.         break;
  513.         }
  514.         if ((i += CountNest (OpCode)) < 0) {
  515.         Error (OpLoc,ManyENDC);    /* Unmatched ENDC */
  516.         i = 0;
  517.         }
  518.         if (!Pass2)
  519.         AddName (Line, 2);    /* Store a line. */
  520.         if (strcmp (OpCode, "ENDM") == 0)
  521.         break;            /* Main program echoes ENDM. */
  522.         if (Pass2)
  523.         WriteListLine (&List);    /* Echo a line. */
  524.     }
  525.     if (i > 0)
  526.         Error (OpLoc, NoENDC);    /* ENDC is missing! */
  527.  
  528.     break;
  529.  
  530.     case IfEQ:                        /* IFEQ */
  531.     ObjSrc = GetValue (SrcOp, SrcLoc);
  532.     if (ObjSrc != 0)
  533.         SkipNest++;            /* Skip to the next ENDC. */
  534.     break;
  535.  
  536.     case IfNE:                        /* IFNE */
  537.     ObjSrc = GetValue (SrcOp, SrcLoc);
  538.     if (ObjSrc == 0)
  539.         SkipNest++;
  540.     break;
  541.  
  542.     case IfGT:                        /* IFGT */
  543.     ObjSrc = GetValue (SrcOp, SrcLoc);
  544.     if (ObjSrc <= 0)
  545.         SkipNest++;
  546.     break;
  547.  
  548.     case IfGE:                        /* IFGE */
  549.     ObjSrc = GetValue (SrcOp, SrcLoc);
  550.     if (ObjSrc < 0)
  551.         SkipNest++;
  552.     break;
  553.  
  554.     case IfLT:                        /* IFLT */
  555.     ObjSrc = GetValue (SrcOp, SrcLoc);
  556.     if (ObjSrc >= 0)
  557.         SkipNest++;
  558.     break;
  559.  
  560.     case IfLE:                        /* IFLE */
  561.     ObjSrc = GetValue (SrcOp, SrcLoc);
  562.     if (ObjSrc > 0)
  563.         SkipNest++;
  564.     break;
  565.  
  566.     case IfC:                        /* IFC */
  567.     if (strcmp (SrcOp, DestOp) != 0)
  568.         SkipNest++;
  569.     break;
  570.  
  571.     case IfNC:                        /* IFNC */
  572.     if (strcmp (SrcOp, DestOp) == 0)
  573.         SkipNest++;
  574.     break;
  575.  
  576.     case IfD:                        /* IFD */
  577.     if (ReadSymTab (SrcOp))
  578.         AddRef (LineCount);
  579.     if (DefLine2 > LineCount)
  580.         SkipNest++;
  581.     break;
  582.  
  583.     case IfND:                        /* IFND */
  584.     if (ReadSymTab (SrcOp))
  585.         AddRef (LineCount);
  586.     if (DefLine2 <= LineCount)
  587.         SkipNest++;
  588.     break;
  589.  
  590.     case EndC:                        /* ENDC */
  591.     break;                /* LineParts will take care of it. */
  592.  
  593.     case Section:                    /* SECTION */
  594.     if (SFormat)
  595.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  596.     tempop[0] = '\0';
  597.     s = Line + DestLoc + strlen (DestOp);    /* Check for flags. */
  598.     if (*s == ',') {
  599.         s++;
  600.         GetField (s, tempop);    /* Get specification. */
  601.     }
  602.     DoSection (SrcOp, SrcLoc, DestOp, DestLoc, tempop, j);
  603.     break;
  604.  
  605.     case CSeg:                        /* CODE */
  606.     if (SFormat)
  607.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  608.     DoSection (SrcOp, SrcLoc, "CODE", OpLoc, DestOp, DestLoc);
  609.     break;                /* Treat as SECTION. */
  610.  
  611.     case DSeg:                        /* DATA */
  612.     if (SFormat)
  613.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  614.     DoSection (SrcOp, SrcLoc, "DATA", OpLoc, DestOp, DestLoc);
  615.     break;                /* Treat as SECTION. */
  616.  
  617.     case BSS:                        /* BSS */
  618.     if (SFormat)
  619.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  620.     DoSection (SrcOp, SrcLoc, "BSS", OpLoc, DestOp, DestLoc);
  621.     break;                /* Treat as SECTION. */
  622.  
  623.     case Idnt:                        /* IDNT */
  624.     s = Line + SrcLoc;
  625.     if ((*s == '"') || (*s == '\''))
  626.         s++;            /* Ignore quotes. */
  627.     t = IdntName;
  628.     while (!isspace(*s)
  629.     && (*s != '"')
  630.     && (*s != '\'')
  631.     && (*s != '\0'))
  632.         *t++ = *s++;
  633.     *t = '\0';
  634.     break;
  635.  
  636.     case DCB:                        /* DCB */
  637.     if ((Size == Word) || (Size == Long))
  638.         AddrCnt = AddrBndW (AddrCnt);
  639.     DupFact = GetValue (SrcOp, SrcLoc);    /* Replication factor */
  640.     if (DefLine2 >= LineCount) {
  641.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  642.         DupFact = 0;
  643.     }
  644.     if (Hunk2 != ABSHUNK) {
  645.         Error (SrcLoc, AbsReq);    /* Must be absolute! */
  646.         DupFact = 0;
  647.     }
  648.     ObjDest = GetValue (DestOp, DestLoc);    /* Value to replicate */
  649.     Dest.Hunk = Hunk2;
  650.     if (Size == 4) {
  651.         ObjString[nX++] = (ObjDest >> 24) & 0x00FF;
  652.         ObjString[nX++] = (ObjDest >> 16) & 0x00FF;
  653.     }
  654.     if (Size >= 2)
  655.         ObjString[nX++] = (ObjDest >> 8) & 0x00FF;
  656.     ObjString[nX++] = ObjDest & 0x00FF;
  657.  
  658.     AddrAdv = InstSize = nX;
  659.     if (Dest.Hunk != ABSHUNK) {        /* Relocatable */
  660.         templong = AddrCnt;
  661.         for (i = 0; i < DupFact; i++) {
  662.         PutRel (templong, Hunk2, Size);    /* Generate a relocation     */
  663.         templong += nX;            /*  entry for each constant. */
  664.         }
  665.     }
  666.     PrntAddr = MakeHunk = TRUE;
  667.     break;
  668.  
  669.     case Equr:                        /* EQUR */
  670.     if ((i = IsRegister (SrcOp, strlen (SrcOp))) < 0)
  671.         Error (SrcLoc, AddrErr);    /* Not a valid register. */
  672.     if (Label[0] == '\0')
  673.         Error (0, NeedLab);        /* Need a label */
  674.     else {
  675.         if (!ReadSymTab (Label))    /* Make a new entry. */
  676.         AddSymTab (Label, (long) i, 0L, LineCount, 0x20);
  677.         GotEqur = TRUE;        /* We have at least one EQUR. */
  678.     }
  679.     break;
  680.  
  681.     case Reg:                        /* REG */
  682.     if (Label[0] == '\0')
  683.         Error (0, NeedLab);        /* Need a label */
  684.     else {
  685.         if ((i = GetMultReg (SrcOp, SrcLoc)) == 0) {
  686.         Error (SrcLoc, OperErr);
  687.         } else {
  688.         if (!ReadSymTab    (Label)) {    /* Make a new entry. */
  689.             AddSymTab (Label, (long) i, 0L, LineCount, 0x40);
  690.             GotEqur = TRUE;        /* We have at least one EQUR. */
  691.         }
  692.         }
  693.     }
  694.     break;
  695.  
  696.     case Near:                        /* NEAR */
  697.     if (SrcOp[0] == '\0') {
  698.         SmallData = 4;        /* Default to register A4. */
  699.     } else {            /* Get register specification. */
  700.         SmallData = IsRegister (SrcOp, strlen (SrcOp)) - 8;
  701.         if ((SmallData < 0) || (SmallData > 6)) {
  702.         Error (SrcLoc,AddrErr);    /* It's not a valid register. */
  703.         SmallData = -1;        /* Disable small-data model. */
  704.         }
  705.     }
  706.     AnyNear    = TRUE;    /* Remember that we use small data somewhere. */
  707.     break;
  708.  
  709.     case Far:                        /* FAR */
  710.     SmallData = -1;        /* Reset small-data model flag. */
  711.     break;
  712.  
  713.     default:
  714.     break;
  715.     }
  716.  
  717.     return (Dir);
  718. }
  719.  
  720.  
  721.  
  722. void DoSection (name, nameloc, type, typeloc, flags, flagloc)
  723. char *name, *type, *flags;
  724. int nameloc, typeloc, flagloc;
  725. /* Processes SECTION directive or equivalent. */
  726. {
  727.     static long HunkPos;    /* Seek address of start of section */
  728.     register char *s, *t;
  729.     long newflags, templong;
  730.     char tempop[MAXLINE];
  731.  
  732.     PrntAddr = TRUE;
  733.  
  734.     if (HunkType != HunkNone) {
  735.     FwdLim1     = FwdBranch;    /* Clear forward branch controls. */
  736.     FwdFixLimit = FwdBranchFix;
  737.     }
  738.  
  739.     for (s = type; *s; s++)        /* Convert section type */
  740.     *s = toupper (*s);        /*  to upper case. */
  741.     if ((type[0] == '\0') || (strcmp (type, "CODE") == 0))
  742.     newflags = HunkCode;        /* Code section */
  743.     else if (strcmp (type, "DATA") == 0)
  744.     newflags = HunkData;        /* Data section */
  745.     else if (strcmp (type, "BSS") == 0)
  746.     newflags = HunkBSS;        /* BSS section */
  747.     else {
  748.     Error (typeloc, OperErr);    /* Invalid type */
  749.     strcpy (type, "CODE");
  750.     newflags = HunkCode;        /* Make it CODE. */
  751.     }
  752.     newflags <<= 16;    /* Shift to high-order 16 bits. */
  753.  
  754.     if (flags[0]) {
  755.     for (s = flags; *s; s++)        /* Convert flags */
  756.         *s = toupper (*s);            /*  to upper case. */
  757.     if (strcmp (flags, "CHIP") == 0)
  758.         newflags |= MEMF_CHIP;        /* CHIP memory */
  759.     else if (strcmp (flags, "FAST") == 0)
  760.         newflags |= MEMF_FAST;        /* FAST memory */
  761.     else
  762.         Error (flagloc, OperErr);        /* Invalid - ignore. */
  763.     }
  764.  
  765.     sprintf (tempop,"  %4x",HunkSeq++);    /* Make section name unique. */
  766.     s = name;
  767.     if ((*s == '"') || (*s == '\''))
  768.     s++;                /* Ignore quotes. */
  769.     t = tempop + 6;
  770.     while (!isspace(*s)
  771.     && (*s != '"')
  772.     && (*s != '\'')
  773.     && (*s != '\0'))
  774.     *t++ = *s++;            /* Concatenate section name. */
  775.     *t = '\0';
  776.  
  777.     if (ReadSymTab (tempop)) {        /* Scan for section name. */
  778.     if (HunkType == HunkNone) {
  779.         SectLine = 1;        /* Start of first section */
  780.     } else {
  781.         if (Pass2) {
  782.         AddRef (LineCount);
  783.         DumpSdata (&Srec);    /* Finish the previous hunk. */
  784.         if (!MakeHunk) {    /* If it was a null hunk, */
  785.             xwrite (&Srec);    /* overwrite it.  */
  786.             lseek (Srec.fd, HunkPos, 0);
  787.             Srec.Ptr = Srec.Buf;
  788.         }
  789.         } else {
  790.         AddrCnt = AddrBndL (AddrCnt);    /* Finish on long word. */
  791.         }
  792.         if (AddrCnt > OrgHigh)
  793.         Sect->Val = AddrCnt;    /* End of old section */
  794.         else
  795.         Sect->Val = OrgHigh;    /* We've ORGed higher. */
  796.         SectLine = LineCount;    /* Start of new section */
  797.     }
  798.     Sect = Sym;            /* Point to new section. */
  799.     if (Dir != Org)
  800.         AddrCnt = Sym->Val;        /* Continuation */
  801.     SectStart = OrgHigh = AddrCnt;
  802.     OrgFlag = FALSE;
  803.     TempAddr = StartAddr = AddrCnt;
  804.     if (SFormat)
  805.         CurrHunk = ABSHUNK;        /* S-format is absolute. */
  806.     else
  807.         CurrHunk = Sym->Hunk & 0x0000FFFFL;    /* Hunk number */
  808.     HunkType = (Sym->Hunk & 0x3FFF0000L) >> 16;    /* Type */
  809.     HunkFlags = Sym->Hunk & 0xC0000000L;        /* Flags */
  810.     if (Pass2 && !SFormat) {        /* Start a new hunk. */
  811.         HunkPos = lseek (Srec.fd, 0L, 1);
  812.         HunkPos += Srec.Ptr - Srec.Buf;    /* It starts here. */
  813.         templong = HunkName;
  814.         xputl (&Srec, templong);
  815.         if (tempop[6])
  816.         DumpName (&Srec, &tempop[6], 0L);    /* Hunk name */
  817.         else
  818.         DumpName (&Srec, " ", 0L);
  819.         xputl (&Srec, HunkType | HunkFlags);    /* Hunk type */
  820.         LenPtr = Srec.Ptr;        /* Pointer to hunk length */
  821.         LenPos = lseek (Srec.fd, 0L, 1);
  822.         LenPos += LenPtr-Srec.Buf;    /* Hunk length goes here. */
  823.         xputl (&Srec, 0L);        /* For now, set it to zero. */
  824.     }
  825.     MakeHunk = FALSE;        /* We don't have anything yet. */
  826.     if (AnyNear && (CurrHunk > 1))
  827.         Error (OpLoc, ManySect);    /* Too many hunks for small data! */
  828.     return;
  829.     }
  830.  
  831.     AddrCnt = AddrBndL (AddrCnt);    /* Finish on long word bounary. */
  832.  
  833.     if (Pass2) {
  834.     Error (OpLoc, ManySect);    /* Table overflowed in pass 1! */
  835.     return;
  836.     }
  837.     if (NextHunk >= ABSHUNK)        /* Set up a new table entry. */
  838.     return;                /* Section table overflow */
  839.  
  840.     if (HunkType != HunkNone) {
  841.     if (AddrCnt > OrgHigh)
  842.         Sect->Val = AddrCnt;    /* End of old section */
  843.     else
  844.         Sect->Val = OrgHigh;    /* We've ORGed higher. */
  845.     SectLine = LineCount;        /* Starting line number */
  846.     } else {
  847.     SectLine = 1;            /* Start of first section */
  848.     }
  849.     if (Dir != Org)
  850.     AddrCnt = 0L;            /* Reset location counter. */
  851.     SectStart = OrgHigh = AddrCnt;
  852.     OrgFlag = FALSE;
  853.     TempAddr = StartAddr = AddrCnt;
  854.     HunkType = (newflags & 0x3FFF0000L) >> 16;    /* Type */
  855.     HunkFlags = newflags & 0xC0000000L;        /* Flags */
  856.     if (SFormat)
  857.     CurrHunk = ABSHUNK;        /* S-format is absolute. */
  858.     else
  859.     CurrHunk = NextHunk++;        /* Bump next hunk number. */
  860.     newflags |= CurrHunk;        /* Add hunk number to flags. */
  861.     AddSymTab (tempop, AddrCnt, newflags, LineCount, 16);    /* New entry */
  862.     Sect = Sym;                /* Pointer to new entry */
  863.     MakeHunk = FALSE;            /* We don't have anything yet. */
  864.     if (AnyNear && (CurrHunk > 1))
  865.     Error (OpLoc, ManySect);    /* Too many hunks for small data! */
  866.     return;
  867. }
  868.