home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d186 / a68k.lha / A68k / Adirect.c < prev    next >
C/C++ Source or Header  |  1989-02-26  |  24KB  |  836 lines

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