home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / language / asxsrc / asmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-10  |  10.0 KB  |  626 lines

  1. /* asmain.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <setjmp.h>
  14. #include "asm.h"
  15.  
  16.  
  17. VOID
  18. main(argc, argv)
  19. char *argv[];
  20. {
  21.     register char *p;
  22.     register c, i;
  23.     struct area *ap;
  24.     FILE *afile();
  25.  
  26.     inpfil = -1;
  27.     for (i=1; i<argc; ++i) {
  28.         p = argv[i];
  29.         if (*p == '-') {
  30.             ++p;
  31.             while (c = *p++)
  32.                 switch(c) {
  33.  
  34.                 case 'a':
  35.                 case 'A':
  36.                     ++aflag;
  37.                     break;
  38.  
  39.                 case 'g':
  40.                 case 'G':
  41.                     ++gflag;
  42.                     break;
  43.  
  44.                 case 'l':
  45.                 case 'L':
  46.                     ++lflag;
  47.                     break;
  48.  
  49.                 case 'o':
  50.                 case 'O':
  51.                     ++oflag;
  52.                     break;
  53.  
  54.                 case 's':
  55.                 case 'S':
  56.                     ++sflag;
  57.                     break;
  58.  
  59.                 case 'x':
  60.                 case 'X':
  61.                     xflag = 0;
  62.                     break;
  63.  
  64.                 case 'q':
  65.                 case 'Q':
  66.                     xflag = 1;
  67.                     break;
  68.  
  69.                 case 'd':
  70.                 case 'D':
  71.                     xflag = 2;
  72.                     break;
  73.  
  74.                 default:
  75.                     usage();
  76.                 }
  77.         } else {
  78.             if (++inpfil == MAXFIL) {
  79.                 fprintf(stderr, "too many input files\n");
  80.                 exit(1);
  81.             }
  82.             sfp[inpfil] = afile(p, "", 0);
  83.             if (inpfil == 0) {
  84.                 if (lflag)
  85.                     lfp = afile(p, "lst", 1);
  86.                 if (oflag)
  87.                     ofp = afile(p, "rel", 1);
  88.                 if (sflag)
  89.                     tfp = afile(p, "sym", 1);
  90.             }
  91.         }
  92.     }
  93.     if (inpfil < 0)
  94.         usage();
  95.     syminit();
  96.     for (pass=0; pass<3; ++pass) {
  97.         if (gflag && pass == 1)
  98.             symglob();
  99.         if (aflag && pass == 1)
  100.             allglob();
  101.         if (oflag && pass == 2)
  102.             outgsd();
  103.         flevel = 0;
  104.         tlevel = 0;
  105.         ifcnd[0] = 0;
  106.         iflvl[0] = 0;
  107.         radix = 10;
  108.         line = 0;
  109.         page = 0;
  110.         stb[0] = 0;
  111.         lop  = NLPP;
  112.         cfile = 0;
  113.         incfil = -1;
  114.         for (i = 0; i <= inpfil; i++)
  115.             rewind(sfp[i]);
  116.         ap = areap;
  117.         while (ap) {
  118.             ap->a_fuzz = 0;
  119.             ap->a_size = 0;
  120.             ap = ap->a_ap;
  121.         }
  122.         fuzz = 0;
  123.         dot->s_addr = 0;
  124.         dot->s_area = dca;
  125.         symp = dot;
  126.         minit();
  127.         while (getline()) {
  128.             ++line;
  129.             cp = cb;
  130.             ep = eb;
  131.             ip = ib;
  132.             if (setjmp(jump_env) == 0)
  133.                 asmbl();
  134.             if (pass == 2) {
  135.                 diag();
  136.                 list();
  137.             }
  138.         }
  139.         newdot(dot->s_area); /* Flush area info */
  140.         if (flevel || tlevel)
  141.             err('i');
  142.     }
  143.     if (oflag)
  144.         outchk(HUGE, HUGE);  /* Flush */
  145.     if (sflag) {
  146.         lstsym(tfp);
  147.     } else
  148.     if (lflag) {
  149.         lstsym(lfp);
  150.     }
  151. }
  152.  
  153. VOID
  154. asmbl()
  155. {
  156.     register struct mne *mp;
  157.     register struct sym *sp;
  158.     register struct tsym *tp;
  159.     register c;
  160.     struct area  *ap;
  161.     struct expr e1;
  162.     char id[NCPS];
  163.     char opt[NCPS];
  164.     char fn[FILSPC];
  165.     char *p;
  166.     int d, n, uaf, uf;
  167.  
  168.     laddr = dot->s_addr;
  169.     lmode = SLIST;
  170. loop:
  171.     if ((c=endline()) == 0) { return; }
  172.     if (ctype[c] == DIGIT) {
  173.         if (flevel)
  174.             return;
  175.         n = 0;
  176.         while ((d = digit(c, 10)) >= 0) {
  177.             n = 10*n + d;
  178.             c = get();
  179.         }
  180.         if (c != '$' || get() != ':')
  181.             qerr();
  182.         tp = symp->s_tsym;
  183.         if (pass == 0) {
  184.             while (tp) {
  185.                 if (n == tp->t_num) {
  186.                     tp->t_flg |= S_MDF;
  187.                     break;
  188.                 }
  189.                 tp = tp->t_lnk;
  190.             }
  191.             if (tp == NULL) {
  192.                 tp=(struct tsym *) new (sizeof(struct tsym));
  193.                 tp->t_lnk = symp->s_tsym;
  194.                 tp->t_num = n;
  195.                 tp->t_area = dot->s_area;
  196.                 tp->t_addr = dot->s_addr;
  197.                 symp->s_tsym = tp;
  198.             }
  199.         } else {
  200.             while (tp) {
  201.                 if (n == tp->t_num) {
  202.                     break;
  203.                 }
  204.                 tp = tp->t_lnk;
  205.             }
  206.             if (tp) {
  207.                 if (pass == 1) {
  208.                     fuzz = tp->t_addr - dot->s_addr;
  209.                     tp->t_area = dot->s_area;
  210.                     tp->t_addr = dot->s_addr;
  211.                 } else {
  212.                     phase(tp->t_area, tp->t_addr);
  213.                     if (tp->t_flg & S_MDF)
  214.                         err('m');
  215.                 }
  216.             } else {
  217.                 err('u');
  218.             }
  219.         }
  220.         goto loop;
  221.     }
  222.     if (ctype[c] != LETTER) 
  223.         if (flevel) {
  224.             return;
  225.         } else {
  226.             qerr();
  227.         }
  228.     getid(id, c);
  229.     c = getnb();
  230.     if (c == ':') {
  231.         if (flevel)
  232.             return;
  233.         if ((c = get()) != ':') {
  234.             unget(c);
  235.             c = 0;
  236.         }
  237.         symp = lookup(id);
  238.         if (symp == dot)
  239.             err('.');
  240.         if (pass == 0)
  241.             if (symp->s_type != S_NEW &&
  242.                (symp->s_flag & S_ASG) == 0)
  243.                 symp->s_flag |= S_MDF;
  244.         if (pass != 2) {
  245.             fuzz = symp->s_addr - dot->s_addr;
  246.             symp->s_type = S_USER;
  247.             symp->s_area = dot->s_area;
  248.             symp->s_addr = dot->s_addr;
  249.         } else {
  250.             if (symp->s_flag & S_MDF)
  251.                 err('m');
  252.             phase(symp->s_area, symp->s_addr);
  253.         }
  254.         if (c) {
  255.             symp->s_flag |= S_GBL;
  256.         }
  257.         lmode = ALIST;
  258.         goto loop;
  259.     }
  260.     if (c == '=') {
  261.         if (flevel)
  262.             return;
  263.         if ((c = get()) != '=') {
  264.             unget(c);
  265.             c = 0;
  266.         }
  267.         expr(&e1, 0);
  268.         sp = lookup(id);
  269.         if (sp == dot) {
  270.             outall();
  271.             if (e1.e_flag || e1.e_base.e_ap != dot->s_area)
  272.                 err('.');
  273.         } else
  274.         if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) {
  275.             err('m');
  276.         }
  277.         sp->s_type = S_USER;
  278.         sp->s_area = e1.e_base.e_ap;
  279.         sp->s_addr = laddr = e1.e_addr;
  280.         sp->s_flag |= S_ASG;
  281.         if (c) {
  282.             sp->s_flag |= S_GBL;
  283.         }
  284.         lmode = ALIST;
  285.         goto loop;
  286.     }
  287.     unget(c);
  288.     lmode = flevel ? SLIST : CLIST;
  289.     if ((mp = mlookup(id)) == NULL) {
  290.         if (!flevel)
  291.             err('o');
  292.         return;
  293.     }
  294.     switch (mp->m_type) {
  295.  
  296.     case S_IF:
  297.         n = absexpr();
  298.         if (tlevel < MAXIF) {
  299.             ++tlevel;
  300.             ifcnd[tlevel] = n;
  301.             iflvl[tlevel] = flevel;
  302.             if (n == 0) {
  303.                 ++flevel;
  304.             }
  305.         } else {
  306.             err('i');
  307.         }
  308.         lmode = ALIST;
  309.         laddr = n;
  310.         return;
  311.  
  312.     case S_ELSE:
  313.         if (ifcnd[tlevel]) {
  314.             if (++flevel > (iflvl[tlevel]+1)) {
  315.                 err('i');
  316.             }
  317.         } else {
  318.             if (--flevel < iflvl[tlevel]) {
  319.                 err('i');
  320.             }
  321.         }
  322.         lmode = SLIST;
  323.         return;
  324.  
  325.     case S_ENDIF:
  326.         if (tlevel) {
  327.             flevel = iflvl[tlevel--];
  328.         } else {
  329.             err('i');
  330.         }
  331.         lmode = SLIST;
  332.         return;
  333.  
  334.     case S_PAGE:
  335.         lop = NLPP;
  336.         lmode = NLIST;
  337.         return;
  338.  
  339.     default:
  340.         break;
  341.     }
  342.     if (flevel)
  343.         return;
  344.     switch (mp->m_type) {
  345.  
  346.     case S_EVEN:
  347.         outall();
  348.         dot->s_addr = (dot->s_addr + 1) & ~1;
  349.         lmode = SLIST;
  350.         break;
  351.  
  352.     case S_ODD:
  353.         outall();
  354.         dot->s_addr |= 1;
  355.         lmode = SLIST;
  356.         break;
  357.  
  358.     case S_BYTE:
  359.     case S_WORD:
  360.         do {
  361.             expr(&e1, 0);
  362.             if (mp->m_type == S_BYTE) {
  363.                 outrb(&e1, 0);
  364.             } else {
  365.                 outrw(&e1, 0);
  366.             }
  367.         } while ((c = getnb()) == ',');
  368.         unget(c);
  369.         break;
  370.  
  371.     case S_ASCII:
  372.     case S_ASCIZ:
  373.         if ((d = getnb()) == '\0')
  374.             qerr();
  375.         while ((c = getmap(d)) >= 0)
  376.             outab(c);
  377.         if (mp->m_type == S_ASCIZ)
  378.             outab(0);
  379.         break;
  380.  
  381.     case S_BLK:
  382.         expr(&e1, 0);
  383.         outall();
  384.         dot->s_addr += e1.e_addr*mp->m_valu;
  385.         break;
  386.  
  387.     case S_TITLE:
  388.         p = tb;
  389.         if (c = getnb()) {
  390.             do {
  391.                 if (p < &tb[NTITL-1])
  392.                     *p++ = c;
  393.             } while (c = get());
  394.         }
  395.         *p = 0;
  396.         unget(c);
  397.         lmode = SLIST;
  398.         break;
  399.  
  400.     case S_SBTL:
  401.         p = stb;
  402.         if (c = getnb()) {
  403.             do {
  404.                 if (p < &stb[NSBTL-1])
  405.                     *p++ = c;
  406.             } while (c = get());
  407.         }
  408.         *p = 0;
  409.         unget(c);
  410.         lmode = SLIST;
  411.         break;
  412.  
  413.     case S_MODUL:
  414.         getid(id, -1);
  415.         if (pass == 0) {
  416.             if (module[0])
  417.                 err('m');
  418.             strncpy(module, id, NCPS);
  419.         }
  420.         lmode = SLIST;
  421.         break;
  422.  
  423.     case S_GLOBL:
  424.         do {
  425.             getid(id, -1);
  426.             sp = lookup(id);
  427.             sp->s_flag |= S_GBL;
  428.         } while ((c = getnb()) == ',');
  429.         unget(c);
  430.         lmode = SLIST;
  431.         break;
  432.  
  433.     case S_DAREA:
  434.         getid(id, -1);
  435.         uaf = 0;
  436.         uf  = A_CON|A_REL;
  437.         if ((c = getnb()) == '(') {
  438.             do {
  439.                 getid(opt, -1);
  440.                 mp = mlookup(opt);
  441.                 if (mp && mp->m_type == S_ATYP) {
  442.                     ++uaf;
  443.                     uf |= mp->m_valu;
  444.                 } else {
  445.                     err('u');
  446.                 }
  447.             } while ((c = getnb()) == ',');
  448.             if (c != ')')
  449.                 qerr();
  450.         } else {
  451.             unget(c);
  452.         }
  453.         if (ap = alookup(id)) {
  454.             if (uaf && uf != ap->a_flag)
  455.                 err('m');
  456.         } else {
  457.             ap = (struct area *) new (sizeof(struct area));
  458.             ap->a_ap = areap;
  459.             strncpy(ap->a_id, id, NCPS);
  460.             ap->a_ref = areap->a_ref + 1;
  461.             ap->a_flag = uaf ? uf : (A_CON|A_REL);
  462.             areap = ap;
  463.         }
  464.         newdot(ap);
  465.         lmode = SLIST;
  466.         break;
  467.  
  468.     case S_ORG:
  469.         if (dot->s_area->a_flag & A_ABS) {
  470.             outall();
  471.             dot->s_addr = absexpr();
  472.         } else {
  473.             err('o');
  474.         }
  475.         lmode = SLIST;
  476.         break;
  477.  
  478.     case S_RADIX:
  479.         if (more()) {
  480.             switch (getnb()) {
  481.             case 'b':
  482.             case 'B':
  483.                 radix = 2;
  484.                 break;
  485.             case '@':
  486.             case 'o':
  487.             case 'O':
  488.             case 'q':
  489.             case 'Q':
  490.                 radix = 8;
  491.                 break;
  492.             case 'd':
  493.             case 'D':
  494.                 radix = 10;
  495.                 break;
  496.             case 'h':
  497.             case 'H':
  498.             case 'x':
  499.             case 'X':
  500.                 radix = 16;
  501.                 break;
  502.             default:
  503.                 qerr();
  504.                 radix = 10;
  505.                 break;
  506.             }
  507.         } else {
  508.         radix = 10;
  509.         }
  510.         lmode = SLIST;
  511.         break;
  512.  
  513.     case S_INCL:
  514.         d = getnb();
  515.         p = fn;
  516.         while ((c = get()) != d) {
  517.             if (p < &fn[FILSPC-1]) {
  518.                 *p++ = c;
  519.             } else {
  520.                 break;
  521.             }
  522.         }
  523.         *p = 0;
  524.         if (++incfil == MAXINC ||
  525.            (ifp[incfil] = fopen(fn, "r")) == NULL) {
  526.             --incfil;
  527.             err('i');
  528.             lmode = SLIST;
  529.         } else {
  530.             lop = NLPP;
  531.             lmode = NLIST;
  532.         }
  533.         break;
  534.  
  535.     default:
  536.         machine(mp);
  537.     }
  538.     goto loop;
  539. }
  540.  
  541. FILE *
  542. afile(fn, ft, wf)
  543. char *fn;
  544. char *ft;
  545. {
  546.     register char *p1, *p2, *p3;
  547.     register c;
  548.     FILE *fp;
  549.     char fb[FILSPC];
  550.  
  551.     p1 = fn;
  552.     p2 = fb;
  553.     p3 = ft;
  554.     while ((c = *p1++) && c != '.') {
  555.         if (p2 < &fb[FILSPC-4])
  556.             *p2++ = c;
  557.     }
  558.     *p2++ = '.';
  559.     if (*p3 == 0) {
  560.         if (c == '.') {
  561.             p3 = p1;
  562.         } else {
  563.             p3 = dsft;
  564.         }
  565.     }
  566.     while (c = *p3++) {
  567.         if (p2 < &fb[FILSPC-1])
  568.             *p2++ = c;
  569.     }
  570.     *p2++ = 0;
  571.     if ((fp = fopen(fb, wf?"w":"r")) == NULL) {
  572.         fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open");
  573.         exit(1);
  574.     }
  575.     return (fp);
  576. }
  577.  
  578. VOID
  579. newdot(nap)
  580. register struct area *nap;
  581. {
  582.     register struct area *oap;
  583.  
  584.     oap = dot->s_area;
  585.     oap->a_fuzz = fuzz;
  586.     oap->a_size = dot->s_addr;
  587.     fuzz = nap->a_fuzz;
  588.     dot->s_area = nap;
  589.     dot->s_addr = nap->a_size;
  590.     outall();
  591. }
  592.  
  593. VOID
  594. phase(ap, a)
  595. struct area *ap;
  596. addr_t a;
  597. {
  598.     if (ap != dot->s_area || a != dot->s_addr)
  599.         err('p');
  600. }
  601.  
  602. char *usetxt[] = {
  603.     "Usage: [-dqxgalos] file1 [file2 file3 ...]",
  604.     "  d    decimal    listing",
  605.     "  q    octal    listing",
  606.     "  x    hex    listing (default)",
  607.     "  g    undefined symbols made global",
  608.     "  a    all user symbols made global",
  609.     "  l    create list   output file1.lst",
  610.     "  o    create object output file1.rel",
  611.     "  s    create symbol output file1.sym",
  612.     "",
  613.     0
  614. };
  615.  
  616. VOID
  617. usage()
  618. {
  619.     register char    **dp;
  620.  
  621.     fprintf(stderr, "\nAssembler (%s)\n\n", cpu);
  622.     for (dp = usetxt; *dp; dp++)
  623.         fprintf(stderr, "%s\n", *dp);
  624.     exit(1);
  625. }
  626.