home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 042.lha / assembler / A68kmain.c < prev    next >
C/C++ Source or Header  |  1987-06-25  |  15KB  |  498 lines

  1. /*------------------------------------------------------------------*/
  2. /*                                    */
  3. /*              MC68000 Cross Assembler                */
  4. /*                                    */
  5. /*           Copyright (c) 1985 by Brian R. Anderson            */
  6. /*                                    */
  7. /*            Main program - June    18, 1987            */
  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 (c) 1987 by Charlie Gibbs.    */
  20. /*                                    */
  21. /*------------------------------------------------------------------*/
  22.  
  23. char Version[] = "1.00 - June 18, 1987";
  24.  
  25.  
  26. #include <stdio.h>
  27. #define    PRIMARY
  28. #include "a68kdef.h"
  29. #include "a68kglb.h"
  30.  
  31.  
  32.  
  33. /********************************************************************/
  34. /*                                    */
  35. /*     NOTE: the following line, plus any additional references        */
  36. /*     to _fmode, is inserted to make this program work    under        */
  37. /*     the MS-DOS version of Lattice C.     It is not necessary        */
  38. /*     for the Amiga version, but does no harm if left in.        */
  39. /*                                    */
  40. /********************************************************************/
  41. int _fmode = 0;        /* File    mode - 0x8000 for binary */
  42.  
  43.  
  44.  
  45. /* Functions */
  46. extern int  LineParts(), GetField(), Instructions(), ObjDir();
  47. extern int  GetSize(), GetInstModeSize(), GetMultReg();
  48. extern int  ReadSymTab(), GetArgs(), GetAReg(),    OpenIncl();
  49. extern long AddrBndW(),    AddrBndL(), GetValue(),    CalcValue();
  50. #ifdef AZTEC_C
  51. extern char *lmalloc();
  52. #else
  53. extern char *malloc();
  54. #endif
  55. extern FILE *fopen();
  56.  
  57.  
  58.  
  59. main(argc,argv)    int argc; char *argv[];
  60. {
  61.     char ListFN[MAXFN],    SrecFN[MAXFN];    /* File    names */
  62.     int     endfile;            /* End-of-file flag */
  63.     long maxheap, maxheap2;        /* Maximum heap    sizes */
  64.     int     cmderror, i, j, dummy;
  65.     long templong;
  66.  
  67.     cmderror = FALSE;        /* Clear command-line error flag */
  68.     SourceFN[0]    = '\0';                 /* Don't have source name yet */
  69.     ListFN[0] =    SrecFN[0] = '\0';       /* Indicate default file names */
  70.     InclList[0]    = '\0';         /* Clear the include directory list */
  71.     IdntName[0]    = '\0';         /* Clear program unit name */
  72.     LnMax = 60;
  73.     XrefList = DumpSym = GotEqur = FALSE;
  74.     SuppList = TRUE;        /* Default to no listing file */
  75.     maxheap  = DEFHEAP;        /* Primary heap    size default */
  76.     maxheap2 = DEFHEAP2;    /* Secondary heap size default */
  77.  
  78.     printf ("\n68000 Cross Assembler\n");
  79.     printf ("Copyright (c) 1985 by Brian R. Anderson\n\n");
  80.     printf ("AmigaDOS conversion copyright (c) 1987 by Charlie Gibbs.\n");
  81.     printf ("Version %s\n\n", Version);
  82.  
  83.     for    (i = 1;    i < argc; i++) {    /* Analyze command line    */
  84.     if (argv[i][0] != '-') {
  85.         if (SourceFN[0] == '\0')
  86.         strcpy (SourceFN, argv[i]);    /* Source file name */
  87.         else if (SrecFN[0] == '\0')
  88.         strcpy (SrecFN,    argv[i]);    /* Object file name */
  89.         else if (ListFN[0] == '\0')
  90.         strcpy (ListFN,    argv[i]);    /* Listing file    name */
  91.         else {
  92.         printf ("Too many file names.\n");
  93.         cmderror = TRUE;
  94.         }
  95.     } else {
  96.         switch (argv[i][1])    {
  97.         case 'D':
  98.         case 'd':
  99.         DumpSym     = TRUE;
  100.         if (argv[i][2])    {
  101.             printf ("Invalid symbol table dump switch.\n");
  102.             cmderror = TRUE;
  103.         }
  104.         break;
  105.         case 'I':                           /* Include directories */
  106.         case 'i':
  107.         if (argv[i][2])    {
  108.             if (InclList[0])
  109.             strcat (InclList, ","); /* Add to previous list */
  110.             strcat (InclList, &argv[i][2]);
  111.         } else {
  112.             printf ("Include directory list is missing.\n");
  113.             cmderror = TRUE;
  114.         }
  115.         break;
  116.         case 'L':                           /* Listing file name */
  117.         case 'l':
  118.         SuppList = FALSE;        /* Produce a listing */
  119.         if (ListFN[0]) {
  120.             printf ("List file is declared more than once.\n");
  121.             cmderror = TRUE;
  122.         } else if (argv[i][2])
  123.             strcpy (ListFN, &argv[i][2]);
  124.         break;
  125.         case 'O':                           /* Object file name */
  126.         case 'o':
  127.         if (SrecFN[0]) {
  128.             printf ("Object file is declared more than once.\n");
  129.             cmderror = TRUE;
  130.         } else if (argv[i][2]) {
  131.             strcpy (SrecFN, &argv[i][2]);
  132.         } else {
  133.             printf ("Object file name is missing\n");
  134.             cmderror = TRUE;
  135.         }
  136.         break;
  137.         case 'P':
  138.         case 'p':
  139.         if ((LnMax = CalcValue(&argv[i][2], 0))    < 10) {
  140.             printf ("Invalid page depth.\n");
  141.             cmderror = TRUE;
  142.         }
  143.         break;
  144.         case 'S':
  145.         case 's':
  146.         SFormat     = TRUE;
  147.         if (argv[i][2])    {
  148.             printf ("Invalid S-format switch.\n");
  149.             cmderror = TRUE;
  150.         }
  151.         break;
  152.         case 'W':
  153.         case 'w':
  154.         if (argv[i][2] != ',') {
  155.             maxheap = CalcValue(&argv[i][2], 0);
  156.             if (maxheap    < MAXLINE)
  157.             maxheap    = MAXLINE;    /* Minimum heap    size */
  158.             maxheap &= ~3L;        /* Long-word alignment */
  159.         }
  160.         for (j = 2; argv[i][j];    j++) {
  161.             if (argv[i][j] == ',') {    /* Find secondary size */
  162.             maxheap2 = CalcValue(&argv[i][j+1], 0);
  163.             if (maxheap2 < MAXLINE)    {
  164.                 maxheap2 = MAXLINE;
  165.             }
  166.             maxheap2 &= ~3L;
  167.             break;
  168.             }
  169.         }
  170.         break;
  171.         case 'X':
  172.         case 'x':
  173.         XrefList  = TRUE;
  174.         SuppList = FALSE;    /* We must want    a listing */
  175.         if (argv[i][2])    {
  176.             printf ("Invalid cross-reference switch.\n");
  177.             cmderror = TRUE;
  178.         }
  179.         break;
  180.         default:
  181.         printf ("Unrecognized switch.\n");
  182.         cmderror = TRUE;
  183.         break;
  184.         }
  185.     }
  186.     }
  187.  
  188.     if (SourceFN[0] == '\0') {          /* Default list file name */
  189.     printf ("Source file name is missing.\n");
  190.     cmderror = TRUE;
  191.     }
  192.  
  193.     if (ListFN[0] == '\0') {            /* Default list file name */
  194.     strcpy (ListFN,    SourceFN);
  195.     i = strlen(ListFN);
  196.     while (--i > 0)    {
  197.         if (ListFN[i] == '.') {
  198.         ListFN[i] = '\0';       /* Chop off name extension */
  199.         break;
  200.         }
  201.     }
  202.     strcat (ListFN,    ".lst");        /* List file name extension */
  203.     }
  204.  
  205.     if (SrecFN[0] == '\0') {            /* Default object file name */
  206.     strcpy (SrecFN,    SourceFN);
  207.     i = strlen(SrecFN);
  208.     while (--i > 0)    {
  209.         if (SrecFN[i] == '.') {
  210.         SrecFN[i] = '\0';       /* Chop off name extension */
  211.         break;
  212.         }
  213.     }
  214.     if (SFormat)
  215.         strcat (SrecFN, ".s");      /* S-format name extension */
  216.     else
  217.         strcat (SrecFN, ".o");      /* AmigaDOS format extension */
  218.     }
  219.  
  220.     if (strcmp (SourceFN, ListFN) == 0)    {
  221.     printf ("Source and listing file names are the same.\n");
  222.     cmderror = TRUE;
  223.     }
  224.     if (strcmp (SourceFN, SrecFN) == 0)    {
  225.     printf ("Source and object file names are the same.\n");
  226.     cmderror = TRUE;
  227.     }
  228.     if (strcmp (ListFN,    SrecFN)    == 0) {
  229.     printf ("Listing and object file names are the same.\n");
  230.     cmderror = TRUE;
  231.     }
  232.  
  233. /*    Open Files.    */
  234.  
  235.     _fmode = 0x8000;            /******    MS-DOS only ******/
  236.     if (!cmderror) {
  237.     if ((InFile = fopen (SourceFN, "r")) == NULL) {
  238.         printf ("Unable to open source file.\n");
  239.         cmderror = TRUE;
  240.     }
  241.     }
  242.     _fmode = 0;                /******    MS-DOS only ******/
  243.     if (!cmderror && !SuppList)    {
  244.     if ((List = fopen (ListFN, "w")) == NULL) {
  245.         printf ("Unable to open listing file.\n");
  246.         cmderror = TRUE;
  247.     }
  248.     }
  249.     if (!SFormat) _fmode = 0x8000;    /******    MS-DOS only ******/
  250.     if (!cmderror) {
  251.     if ((Srec = fopen (SrecFN, "w")) == NULL ) {
  252.         printf ("Unable to open object code file.\n");
  253.         cmderror = TRUE;
  254.     }
  255.     }
  256.  
  257.     if (cmderror) {
  258.     printf ("\n");
  259.     printf ("Usage: a68k <source file>\n");
  260.     printf ("            [-o<object file>]\n");
  261.     printf ("            [-l<listing file>]\n");
  262.     printf ("            [-i<include dirlist>]\n");
  263.     printf ("            [-p<page depth>]\n");
  264.     printf ("            [-w[<heap size>][,<heap size>]]\n");
  265.     printf ("            [-d] [-s] [-x]\n\n");
  266.     printf ("Command-line arguments can appear in any order.\n");
  267.     printf ("Heap size default (bytes):  -w");
  268.     printf ("%ld,%ld\n", (long) DEFHEAP, (long) DEFHEAP2);
  269.     printf ("\n");
  270.     exit(20);
  271.     }
  272.  
  273. #ifdef AZTEC_C
  274.     Heap = lmalloc (maxheap);
  275. #else
  276.     Heap = malloc ((unsigned) maxheap);
  277. #endif
  278.     if (Heap ==    NULL) {
  279.     printf ("Unable to allocate primary heap!\n");
  280.     exit(20);
  281.     }
  282.     HeapLim = Heap;        /* Heap    limit (start out empty)    */
  283.     LowHeap = (Heap + maxheap);
  284.     SymStart = (struct SymTab *) (LowHeap);    /* Symbol table    */
  285.  
  286. #ifdef AZTEC_C
  287.     Heap2 = lmalloc (maxheap2);
  288. #else
  289.     Heap2 = malloc ((unsigned) maxheap2);
  290. #endif
  291.     if (Heap2 == NULL) {
  292.     printf ("Unable to allocate secondary heap!\n");
  293.     exit(20);
  294.     }
  295.     NextFNS = Heap2;
  296.     InF    = (struct InFCtl *) (Heap2 + maxheap2);
  297.     LowInF = --InF;
  298.     InFNum = OuterMac =    SkipNest = InF->Pos = InF->MCnt    = 0;
  299.     InF->Line =    0;
  300.     InF->UPtr =    0;
  301.     InF->NPtr =    NextFNS;
  302.     InF->NArg =    -1;
  303.     strcpy (NextFNS, SourceFN);
  304.     NextFNS += strlen (SourceFN) + 1;
  305.     High2 = NextFNS;
  306.     Low2  = (char *) LowInF;
  307.  
  308.     _fmode = 0x8000;            /******    MS-DOS only ******/
  309.     printf ("\nAssembling %s\n\n\n", SourceFN);
  310.  
  311. /*-------------------------------------------------------------------
  312.  
  313.     Begin Pass 1.
  314.                                    */
  315.     printf ("PASS 1\n");
  316.     LineCount =    LabLine    = MacCount = ErrorCount    = NumSyms = 0;
  317.     AddrCnt = SectStart    = 0L;    /* Assume ORG =    0 to start */
  318.     CurrHunk = NextHunk    = 0L;    /* Start in hunk zero */
  319.     HunkType = HunkNone;    /* We're not in a hunk yet */
  320.     HunkFlags =    SectLine = 0;
  321.     endfile = ListOff =    Pass2 =    FALSE;
  322.  
  323.     while (!endfile && (strcmp (OpCode,    "END") != 0)) {
  324.     PrevDir    = Dir;            /* Save    previous directive */
  325.     endfile    = LineParts (dummy);    /* Get a statement */
  326.     Dir = ObjDir (Srec);        /* Process directives */
  327.     GetObjectCode (dummy);        /* Length if executable    */
  328.  
  329.     if ((HunkType == HunkNone) && (AddrAdv != 0)) {
  330.         Sym    = SymStart;    /* Insert at head of table */
  331.         templong = (long) HunkCode << 16;
  332.         AddSymTab ("  ", 0L, templong, LineCount, 16);
  333.         Sect = Sym;        /* Create an unnamed section */
  334.         HunkType = HunkCode;
  335.         SectLine = LineCount;
  336.         NextHunk++;
  337.     }
  338.     if ((Label[0] != '\0')
  339.     && (Dir    != Set)    && (Dir    != Equr) && (Dir != Reg)) {
  340.         if (!ReadSymTab (Label)) {        /* Make    a new entry */
  341.         AddSymTab (Label, AddrCnt, CurrHunk, LineCount,    0);
  342.         } else if ((Sym->Flags & 1)        /* If dup., ignore */
  343.         || (Sym->Defn == 0)) {        /* else    fill in    */
  344.         Sym->Val = AddrCnt;        /* Current loc.    */
  345.         Sym->Hunk = CurrHunk;        /* Hunk    number */
  346.         Sym->Defn = LineCount;        /* Statement number */
  347.         Sym->Flags &= ~1;        /* Clear XREF flag */
  348.         }
  349.         if (Dir == Equ) {
  350.         Sym->Val = ObjSrc;        /* Equated value */
  351.         Sym->Hunk = Src.Hunk;        /* Hunk    number */
  352.         }
  353.     }
  354.     AddrCnt    += AddrAdv;    /* Advance location counter */
  355.     }
  356.  
  357.  
  358. /*----------------------------------------------------------------
  359.  
  360.     Begin Pass 2.
  361.                                    */
  362.     printf ("PASS 2\n");
  363.     InF    = (struct InFCtl *) (Heap2 + maxheap2);
  364.     InF--;
  365.     InFNum = OuterMac =    SkipNest = InF->Pos = InF->MCnt    = 0;
  366.     InF->Line =    0;
  367.     InF->UPtr =    0;
  368.     InF->NPtr =    Heap2;
  369.     InF->NArg =    -1;
  370.     fclose (InFile);            /* "Rewind" the source file */
  371.     InFile = fopen (SourceFN, "r");
  372.     NextFNS = Heap2 + strlen (SourceFN)    + 1;
  373.     Pass2 = TRUE;
  374.     LineCount =    LabLine    = MacCount = ErrorCount    = 0;
  375.     AddrCnt = CurrHunk = SectStart = EndAddr = 0L;
  376.     HunkType = HunkNone;
  377.     HunkFlags =    SectLine = 0;
  378.     endfile = ListOff =    FALSE;
  379.     if ((Sym = SymStart) < (struct SymTab *) (Heap + maxheap)) {
  380.     while (Sym->Flags & 16)    {
  381.         Sym->Val = 0L;    /* Back    to start of all    sections */
  382.         Sym++;
  383.     }
  384.     }
  385.     TTLstring[0] = '\0';        /* Clear title string */
  386.     if ((templong = (HeapLim - Heap) & 3L) != 0)
  387.     HeapLim    += 4 - templong;
  388.     HighHeap = HeapLim;        /* High-water mark in heap */
  389.     RelStart = (struct RelTab *) HeapLim;    /* Relocation table */
  390.     RefStart = (struct Ref *) SymStart;    /* Cross-reference table */
  391.  
  392. /* Sign    on messages for    listing    file */
  393.     LnCnt = 999;
  394.     PgCnt = 0;
  395.     TTLstring[0] = '\0';
  396.     if (!SuppList) {
  397.     CheckPage (List, FALSE);            /* Print headings */
  398.     fprintf    (List, "68000 Cross Assembler\n");
  399.     fprintf    (List, "Copyright (c) 1985 by Brian R. Anderson\n\n");
  400.     fprintf    (List, "AmigaDOS conversion copyright (c) 1987");
  401.     fprintf    (List, " by Charlie Gibbs.\n");
  402.     fprintf    (List, "Version %s\n\n", Version);
  403.     LnCnt += 6;
  404.     }
  405.  
  406.     StartSrec (Srec, IdntName);        /* Write object    header record */
  407.  
  408. /*    Process    the second pass.    */
  409.  
  410.     OpCode[0] =    '\0';                   /* Kill "END" from pass 1! */
  411.     while (!endfile && (strcmp(OpCode,"END") != 0)) {
  412.     PrevDir    = Dir;            /* Save    previous directive */
  413.     endfile    = LineParts (dummy);    /* Get a statement */
  414.     if (!endfile) {
  415.         Dir    = ObjDir (Srec);    /* Process directives */
  416.         GetObjectCode (dummy);    /* Executable object code */
  417.         if (strlen (Label) != 0) {    /* If statement    is labeled, */
  418.         ReadSymTab (Label);    /*  check for duplicate    defn. */
  419.         if (Sym->Defn != LineCount) {
  420.             AddRef (LineCount);    /* Got one - flag as reference */
  421.             if (Sym->Flags & 4)    {
  422.             if (Dir    != Set)
  423.                 Error (0, SymDup);
  424.             } else {
  425.             if (Dir    == Set)
  426.                 Error (0, SymDup);
  427.             }
  428.         } else {
  429.             if ((Dir !=    Equ) &&    (Dir !=    Set)
  430.             && (Dir != Equr) &&    (Dir !=    Reg))
  431.             if (Sym->Val !=    AddrCnt)
  432.                 Error (0, Phase);    /* Assembler error */
  433.         }
  434.         }
  435.         if (!SuppList)
  436.         WriteListLine (List);
  437.         WriteSrecLine (Srec);
  438.         AddrCnt += AddrAdv;        /* Advance location counter */
  439.     } else {
  440.         Error (0, EndErr);        /* END statement is missing */
  441.         if (!SuppList)
  442.         WriteListLine (List);
  443.     }
  444.     }
  445.  
  446. /*---------------------------------------------------------------------
  447.  
  448.     Clean up.
  449.                                 */
  450.  
  451.     fclose (InFile);        /* Finished with source    file */
  452.  
  453.     EndSdata (Srec, EndAddr);    /* Write remaining data    and end    record */
  454.     fclose(Srec);        /* Finished with object    file */
  455.  
  456.     if (!SuppList)
  457.     WriteSymTab (List);    /* List    the symbol table */
  458.  
  459. /* Write error count to    console    and listing file. */
  460.     printf ("    \n\nEnd of assembly - ");
  461.     if (!SuppList)
  462.     fprintf    (List, "\n\nEnd of assembly - ");
  463.     if (ErrorCount == 0) {
  464.     printf ("no errors were found.\n\n");
  465.     if (!SuppList)
  466.         fprintf (List, "no errors were found.\n\n");
  467.     } else if (ErrorCount == 1)    {
  468.     printf ("1 error was found.\n\n");
  469.     if (!SuppList)
  470.         fprintf (List, "1 error was found.\n\n");
  471.     } else {
  472.     printf ("%d errors were found.\n\n", ErrorCount);
  473.     if (!SuppList)
  474.         fprintf (List, "%d errors were found.\n\n", ErrorCount);
  475.     }
  476.     templong = (long) (HighHeap    - Heap);
  477.     if (LowHeap    < (char    *) RefStart)
  478.     templong += (long) (Heap + maxheap - LowHeap);
  479.     else
  480.     templong += (long) (Heap + maxheap - (char *) RefStart);
  481.     printf ("Heap usage (bytes):  -w%ld", templong);
  482.     if (!SuppList)
  483.     fprintf    (List, "Heap usage (bytes):  -w%ld", templong);
  484.     templong = (long) (High2 - Heap2);
  485.     if (Low2 < (char *)    LowInF)
  486.     templong += (long) (Heap2 + maxheap2 - Low2);
  487.     else
  488.     templong += (long) (Heap2 + maxheap2 - (char *)    LowInF);
  489.     printf (",%ld\n\n", templong);
  490.     if (!SuppList) {
  491.     fprintf    (List, ",%ld\n\f", templong);   /* One last page eject */
  492.     fclose (List);        /* Finished with listing file */
  493.     }
  494.     free (Heap);        /* Release heap    space */
  495.     free (Heap2);
  496.     exit (ErrorCount ? 10 : 0);    /* All done */
  497. }
  498.