home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progasm / asca11.arj / ASOUT.C < prev    next >
C/C++ Source or Header  |  1990-11-23  |  8KB  |  460 lines

  1. /* asout.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989,1990
  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 <string.h>
  15. #include <alloc.h>
  16. #include "asm.h"
  17.  
  18.  
  19. #define     NTXT    16
  20. #define     NREL    16
  21.  
  22. char     txt[NTXT];
  23. char     rel[NREL];
  24.  
  25. char    *txtp = { &txt[0] };
  26. char    *relp = { &rel[0] };
  27.  
  28. /*
  29.  * Output absolute byte.
  30.  */
  31. VOID
  32. outab(b)
  33. {
  34.     if (pass == 2) {
  35.         out_lb(b,0);
  36.         if (oflag) {
  37.             outchk(1, 0);
  38.             *txtp++ = lobyte(b);
  39.         }
  40.     }
  41.     ++dot.s_addr;
  42. }
  43.  
  44. /*
  45.  * Output absolute word.
  46.  */
  47. VOID
  48. outaw(w)
  49. {
  50.     if (pass == 2) {
  51.         out_lw(w,0);
  52.         if (oflag) {
  53.             outchk(2, 0);
  54.             out_tw(w);
  55.         }
  56.     }
  57.     dot.s_addr += 2;
  58. }
  59.  
  60. /*
  61.  * Output relocatable byte.
  62.  */
  63. VOID
  64. outrb(esp, r)
  65. register struct expr *esp;
  66. int r;
  67. {
  68.     register n;
  69.  
  70.     if (pass == 2) {
  71.         if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
  72.             out_lb(esp->e_addr,0);
  73.             if (oflag) {
  74.                 outchk(1, 0);
  75.                 *txtp++ = lobyte(esp->e_addr);
  76.             }
  77.         } else {
  78.             r |= R_BYTE|R_BYT2;
  79.             out_lb(esp->e_addr,r|R_RELOC);
  80.             if (oflag) {
  81.                 outchk(2, 4);
  82.                 out_tw(esp->e_addr);
  83.                 if (esp->e_flag) {
  84.                     n = esp->e_base.e_sp->s_ref;
  85.                     r |= R_SYM;
  86.                 } else {
  87.                     n = esp->e_base.e_ap->a_ref;
  88.                 }
  89.                 *relp++ = r;
  90.                 *relp++ = txtp - txt - 2;
  91.                 out_rw(n);
  92.             }
  93.         }
  94.     }
  95.     ++dot.s_addr;
  96. }
  97.  
  98. /*
  99.  * Output relocatable word.
  100.  */
  101. VOID
  102. outrw(esp, r)
  103. register struct expr *esp;
  104. int r;
  105. {
  106.     register n;
  107.  
  108.     if (pass == 2) {
  109.         if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
  110.             out_lw(esp->e_addr,0);
  111.             if (oflag) {
  112.                 outchk(2, 0);
  113.                 out_tw(esp->e_addr);
  114.             }
  115.         } else {
  116.             r |= R_WORD;
  117.             out_lw(esp->e_addr,r|R_RELOC);
  118.             if (oflag) {
  119.                 outchk(2, 4);
  120.                 out_tw(esp->e_addr);
  121.                 if (esp->e_flag) {
  122.                     n = esp->e_base.e_sp->s_ref;
  123.                     r |= R_SYM;
  124.                 } else {
  125.                     n = esp->e_base.e_ap->a_ref;
  126.                 }
  127.                 *relp++ = r;
  128.                 *relp++ = txtp - txt - 2;
  129.                 out_rw(n);
  130.             }
  131.         }
  132.     }
  133.     dot.s_addr += 2;
  134. }
  135.  
  136. /*
  137.  * Output Page Information
  138.  */
  139. VOID
  140. outdp(carea, esp)
  141. register struct area *carea;
  142. register struct expr *esp;
  143. {
  144.     register n, r;
  145.  
  146.     if (pass == 2 && oflag != 0) {
  147.         outchk(16,16);
  148.         out_tw(carea->a_ref);
  149.         out_tw(esp->e_addr);
  150.         if (esp->e_flag || esp->e_base.e_ap!=NULL) {
  151.             r = R_WORD;
  152.             if (esp->e_flag) {
  153.                 n = esp->e_base.e_sp->s_ref;
  154.                 r |= R_SYM;
  155.             } else {
  156.                 n = esp->e_base.e_ap->a_ref;
  157.             }
  158.             *relp++ = r;
  159.             *relp++ = txtp - txt - 2;
  160.             out_rw(n);
  161.         }
  162.         outbuf("P");
  163.     }
  164. }
  165.  
  166. /*
  167.  * Clear out any bufferred text and relocation information
  168.  */
  169. VOID
  170. outall()
  171. {
  172.     if (oflag && pass==2)
  173.         outbuf("R");
  174. }
  175.  
  176. /*
  177.  * Check text buffer and relocation buffer.
  178.  */
  179. VOID
  180. outchk(nt, nr)
  181. {
  182.     register struct area *ap;
  183.  
  184.     if (txtp+nt > &txt[NTXT] || relp+nr > &rel[NREL]) {
  185.         outbuf("R");
  186.     }
  187.     if (txtp == txt) {
  188.         out_tw(dot.s_addr);
  189.         if ((ap = dot.s_area) != NULL) {
  190.             *relp++ = R_WORD|R_AREA;
  191.             *relp++ = 0;
  192.             out_rw(ap->a_ref);
  193.         }
  194.     }
  195. }
  196.  
  197. /*
  198.  * Output any bufferred text and relocation information
  199.  */
  200. VOID
  201. outbuf(s)
  202. char *s;
  203. {
  204.     if (txtp > &txt[2]) {
  205.         fprintf(ofp, "T");
  206.         out(txt,(int) (txtp-txt));
  207.         fprintf(ofp, "\n");
  208.         fprintf(ofp, s);
  209.         out(rel,(int) (relp-rel));
  210.         fprintf(ofp, "\n");
  211.     }
  212.     txtp = txt;
  213.     relp = rel;
  214. }
  215.  
  216. /*
  217.  * Walk through the symbol table and the
  218.  * area list and put out the global
  219.  * symbol information at the front of the
  220.  * relocatable file. This routine is also
  221.  * responsible for setting up the reference
  222.  * numbers in the symbol tabel.
  223.  */
  224. VOID
  225. outgsd()
  226. {
  227.     register struct area *ap;
  228.     register struct sym  *sp;
  229.     register i, j;
  230.     char *ptr;
  231.     int c, narea, nglob, rn;
  232.  
  233.     narea = areap->a_ref + 1;
  234.     nglob = 0;
  235.     for (i = 0; i < NHASH; ++i) {
  236.         sp = symhash[i];
  237.         while (sp) {
  238.             if (sp->s_flag&S_GBL)
  239.                 ++nglob;
  240.             sp = sp->s_sp;
  241.         }
  242.     }
  243.     if (xflag == 0) {
  244.         fprintf(ofp, "X%c\n", hilo ? 'H' : 'L');
  245.         fprintf(ofp, "H %X areas %X global symbols\n", narea, nglob);
  246.     } else
  247.     if (xflag == 1) {
  248.         fprintf(ofp, "Q%c\n", hilo ? 'H' : 'L');
  249.         fprintf(ofp, "H %o areas %o global symbols\n", narea, nglob);
  250.     } else
  251.     if (xflag == 2) {
  252.         fprintf(ofp, "D%c\n", hilo ? 'H' : 'L');
  253.         fprintf(ofp, "H %u areas %u global symbols\n", narea, nglob);
  254.     }        
  255.  
  256.     /*
  257.      * Module name
  258.      */
  259.     if (module[0]) {
  260.         fprintf(ofp, "M ");
  261.         ptr = &module[0];
  262.         while (ptr < &module[NCPS]) {
  263.             if ((c = *ptr++) != 0)
  264.                 putc(c, ofp);
  265.         }
  266.         putc('\n', ofp);
  267.     }
  268.  
  269.     /*
  270.      * Global references and absolutes.
  271.      */
  272.     rn = 0;
  273.     for (i=0; i<NHASH; ++i) {
  274.         sp = symhash[i];
  275.         while (sp) {
  276.             if (sp->s_area==NULL && sp->s_flag&S_GBL) {
  277.                 sp->s_ref = rn++;
  278.                 outsym(sp);
  279.             }
  280.             sp = sp->s_sp;
  281.         }
  282.     }
  283.  
  284.     /*
  285.      * Global relocatables.
  286.      */
  287.     for (i=0; i<narea; ++i) {
  288.         ap = areap;
  289.         while (ap->a_ref != i)
  290.             ap = ap->a_ap;
  291.         outarea(ap);
  292.         for (j=0; j<NHASH; ++j) {
  293.             sp = symhash[j];
  294.             while (sp) {
  295.                 if (sp->s_area==ap && sp->s_flag&S_GBL) {
  296.                     sp->s_ref = rn++;
  297.                     outsym(sp);
  298.                 }
  299.                 sp = sp->s_sp;
  300.             }
  301.         }
  302.     }
  303. }
  304.  
  305. /*
  306.  * Output the relocatable item defining
  307.  * an area.
  308.  */
  309. VOID
  310. outarea(ap)
  311. register struct area *ap;
  312. {
  313.     register char *ptr;
  314.     register c;
  315.  
  316.     fprintf(ofp, "A ");
  317.     ptr = &ap->a_id[0];
  318.     while (ptr < &ap->a_id[NCPS]) {
  319.         if ((c = *ptr++) != 0)
  320.             putc(c, ofp);
  321.     }
  322.     if (xflag == 0) {
  323.         fprintf(ofp, " size %X flags %X\n", ap->a_size, ap->a_flag);
  324.     } else
  325.     if (xflag == 1) {
  326.         fprintf(ofp, " size %o flags %o\n", ap->a_size, ap->a_flag);
  327.     } else
  328.     if (xflag == 2) {
  329.         fprintf(ofp, " size %u flags %u\n", ap->a_size, ap->a_flag);
  330.     }
  331. }
  332.  
  333. /*
  334.  * Output the relocatable item describing a
  335.  * global symbol.
  336.  */
  337. VOID
  338. outsym(sp)
  339. register struct sym *sp;
  340. {
  341.     register char *ptr;
  342.     register c;
  343.  
  344.     fprintf(ofp, "S ");
  345.     ptr = &sp->s_id[0];
  346.     while (ptr < &sp->s_id[NCPS]) {
  347.         if ((c = *ptr++) != 0)
  348.             putc(c, ofp);
  349.     }
  350.     fprintf(ofp, " %s", sp->s_type==S_NEW ? "Ref" : "Def");
  351.     if (xflag == 0) {
  352.         fprintf(ofp, "%04X\n", sp->s_addr);
  353.     } else
  354.     if (xflag == 1) {
  355.         fprintf(ofp, "%06o\n", sp->s_addr);
  356.     } else
  357.     if (xflag == 2) {
  358.         fprintf(ofp, "%05u\n", sp->s_addr);
  359.     }
  360. }
  361.  
  362. VOID
  363. out(p, n)
  364. register char *p;
  365. register n;
  366. {
  367.     while (n--) {
  368.         if (xflag == 0) {
  369.             fprintf(ofp, " %02X", (*p++)&0377);
  370.         } else
  371.         if (xflag == 1) {
  372.             fprintf(ofp, " %03o", (*p++)&0377);
  373.         } else
  374.         if (xflag == 2) {
  375.             fprintf(ofp, " %03u", (*p++)&0377);
  376.         }
  377.     }
  378. }
  379.  
  380. /*
  381.  * Output a byte to the listing buffer.
  382.  */
  383. VOID
  384. out_lb(b,t)
  385. register b,t;
  386. {
  387.     if (cp < &cb[NCODE])
  388.         *cp++ = b;
  389.         *cpt++ = t;
  390. }
  391.  
  392. /*
  393.  * Output ordered word to the listing buffer.
  394.  */
  395. VOID
  396. out_lw(n,t)
  397. register n,t;
  398. {
  399.     if (hilo) {
  400.         out_lb(hibyte(n),t ? t|R_HIGH : 0);
  401.         out_lb(lobyte(n),t);
  402.     } else {
  403.         out_lb(lobyte(n),t);
  404.         out_lb(hibyte(n),t ? t|R_HIGH : 0);
  405.     }
  406. }
  407.  
  408. /*
  409.  * Output ordered 'Relocation' word.
  410.  */
  411. VOID
  412. out_rw(n)
  413. register n;
  414. {
  415.     if (hilo) {
  416.         *relp++ = hibyte(n);
  417.         *relp++ = lobyte(n);
  418.     } else {
  419.         *relp++ = lobyte(n);
  420.         *relp++ = hibyte(n);
  421.     }
  422. }
  423.  
  424. /*
  425.  * Output ordered 'Text' word.
  426.  */
  427. VOID
  428. out_tw(n)
  429. register n;
  430. {
  431.     if (hilo) {
  432.         *txtp++ = hibyte(n);
  433.         *txtp++ = lobyte(n);
  434.     } else {
  435.         *txtp++ = lobyte(n);
  436.         *txtp++ = hibyte(n);
  437.     }
  438. }
  439.  
  440. /*
  441.  * Extract low half of a word.
  442.  */
  443. int
  444. lobyte(n)
  445. {
  446.     return (n&0377);
  447. }
  448.  
  449. /*
  450.  * Extract high half of a word.
  451.  */
  452. int
  453. hibyte(n)
  454. {
  455.     return ((n>>8)&0377);
  456. }
  457.                mov     r,m
  458.                 mov     m,r
  459.         
  460.