home *** CD-ROM | disk | FTP | other *** search
- /* asout.c */
-
- /*
- * (C) Copyright 1989,1990
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio 44240
- */
-
- #include <stdio.h>
- #include <setjmp.h>
- #include <string.h>
- #include <alloc.h>
- #include "asm.h"
-
-
- #define NTXT 16
- #define NREL 16
-
- char txt[NTXT];
- char rel[NREL];
-
- char *txtp = { &txt[0] };
- char *relp = { &rel[0] };
-
- /*
- * Output absolute byte.
- */
- VOID
- outab(b)
- {
- if (pass == 2) {
- out_lb(b,0);
- if (oflag) {
- outchk(1, 0);
- *txtp++ = lobyte(b);
- }
- }
- ++dot.s_addr;
- }
-
- /*
- * Output absolute word.
- */
- VOID
- outaw(w)
- {
- if (pass == 2) {
- out_lw(w,0);
- if (oflag) {
- outchk(2, 0);
- out_tw(w);
- }
- }
- dot.s_addr += 2;
- }
-
- /*
- * Output relocatable byte.
- */
- VOID
- outrb(esp, r)
- register struct expr *esp;
- int r;
- {
- register n;
-
- if (pass == 2) {
- if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
- out_lb(esp->e_addr,0);
- if (oflag) {
- outchk(1, 0);
- *txtp++ = lobyte(esp->e_addr);
- }
- } else {
- r |= R_BYTE|R_BYT2;
- out_lb(esp->e_addr,r|R_RELOC);
- if (oflag) {
- outchk(2, 4);
- out_tw(esp->e_addr);
- if (esp->e_flag) {
- n = esp->e_base.e_sp->s_ref;
- r |= R_SYM;
- } else {
- n = esp->e_base.e_ap->a_ref;
- }
- *relp++ = r;
- *relp++ = txtp - txt - 2;
- out_rw(n);
- }
- }
- }
- ++dot.s_addr;
- }
-
- /*
- * Output relocatable word.
- */
- VOID
- outrw(esp, r)
- register struct expr *esp;
- int r;
- {
- register n;
-
- if (pass == 2) {
- if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
- out_lw(esp->e_addr,0);
- if (oflag) {
- outchk(2, 0);
- out_tw(esp->e_addr);
- }
- } else {
- r |= R_WORD;
- out_lw(esp->e_addr,r|R_RELOC);
- if (oflag) {
- outchk(2, 4);
- out_tw(esp->e_addr);
- if (esp->e_flag) {
- n = esp->e_base.e_sp->s_ref;
- r |= R_SYM;
- } else {
- n = esp->e_base.e_ap->a_ref;
- }
- *relp++ = r;
- *relp++ = txtp - txt - 2;
- out_rw(n);
- }
- }
- }
- dot.s_addr += 2;
- }
-
- /*
- * Output Page Information
- */
- VOID
- outdp(carea, esp)
- register struct area *carea;
- register struct expr *esp;
- {
- register n, r;
-
- if (pass == 2 && oflag != 0) {
- outchk(16,16);
- out_tw(carea->a_ref);
- out_tw(esp->e_addr);
- if (esp->e_flag || esp->e_base.e_ap!=NULL) {
- r = R_WORD;
- if (esp->e_flag) {
- n = esp->e_base.e_sp->s_ref;
- r |= R_SYM;
- } else {
- n = esp->e_base.e_ap->a_ref;
- }
- *relp++ = r;
- *relp++ = txtp - txt - 2;
- out_rw(n);
- }
- outbuf("P");
- }
- }
-
- /*
- * Clear out any bufferred text and relocation information
- */
- VOID
- outall()
- {
- if (oflag && pass==2)
- outbuf("R");
- }
-
- /*
- * Check text buffer and relocation buffer.
- */
- VOID
- outchk(nt, nr)
- {
- register struct area *ap;
-
- if (txtp+nt > &txt[NTXT] || relp+nr > &rel[NREL]) {
- outbuf("R");
- }
- if (txtp == txt) {
- out_tw(dot.s_addr);
- if ((ap = dot.s_area) != NULL) {
- *relp++ = R_WORD|R_AREA;
- *relp++ = 0;
- out_rw(ap->a_ref);
- }
- }
- }
-
- /*
- * Output any bufferred text and relocation information
- */
- VOID
- outbuf(s)
- char *s;
- {
- if (txtp > &txt[2]) {
- fprintf(ofp, "T");
- out(txt,(int) (txtp-txt));
- fprintf(ofp, "\n");
- fprintf(ofp, s);
- out(rel,(int) (relp-rel));
- fprintf(ofp, "\n");
- }
- txtp = txt;
- relp = rel;
- }
-
- /*
- * Walk through the symbol table and the
- * area list and put out the global
- * symbol information at the front of the
- * relocatable file. This routine is also
- * responsible for setting up the reference
- * numbers in the symbol tabel.
- */
- VOID
- outgsd()
- {
- register struct area *ap;
- register struct sym *sp;
- register i, j;
- char *ptr;
- int c, narea, nglob, rn;
-
- narea = areap->a_ref + 1;
- nglob = 0;
- for (i = 0; i < NHASH; ++i) {
- sp = symhash[i];
- while (sp) {
- if (sp->s_flag&S_GBL)
- ++nglob;
- sp = sp->s_sp;
- }
- }
- if (xflag == 0) {
- fprintf(ofp, "X%c\n", hilo ? 'H' : 'L');
- fprintf(ofp, "H %X areas %X global symbols\n", narea, nglob);
- } else
- if (xflag == 1) {
- fprintf(ofp, "Q%c\n", hilo ? 'H' : 'L');
- fprintf(ofp, "H %o areas %o global symbols\n", narea, nglob);
- } else
- if (xflag == 2) {
- fprintf(ofp, "D%c\n", hilo ? 'H' : 'L');
- fprintf(ofp, "H %u areas %u global symbols\n", narea, nglob);
- }
-
- /*
- * Module name
- */
- if (module[0]) {
- fprintf(ofp, "M ");
- ptr = &module[0];
- while (ptr < &module[NCPS]) {
- if ((c = *ptr++) != 0)
- putc(c, ofp);
- }
- putc('\n', ofp);
- }
-
- /*
- * Global references and absolutes.
- */
- rn = 0;
- for (i=0; i<NHASH; ++i) {
- sp = symhash[i];
- while (sp) {
- if (sp->s_area==NULL && sp->s_flag&S_GBL) {
- sp->s_ref = rn++;
- outsym(sp);
- }
- sp = sp->s_sp;
- }
- }
-
- /*
- * Global relocatables.
- */
- for (i=0; i<narea; ++i) {
- ap = areap;
- while (ap->a_ref != i)
- ap = ap->a_ap;
- outarea(ap);
- for (j=0; j<NHASH; ++j) {
- sp = symhash[j];
- while (sp) {
- if (sp->s_area==ap && sp->s_flag&S_GBL) {
- sp->s_ref = rn++;
- outsym(sp);
- }
- sp = sp->s_sp;
- }
- }
- }
- }
-
- /*
- * Output the relocatable item defining
- * an area.
- */
- VOID
- outarea(ap)
- register struct area *ap;
- {
- register char *ptr;
- register c;
-
- fprintf(ofp, "A ");
- ptr = &ap->a_id[0];
- while (ptr < &ap->a_id[NCPS]) {
- if ((c = *ptr++) != 0)
- putc(c, ofp);
- }
- if (xflag == 0) {
- fprintf(ofp, " size %X flags %X\n", ap->a_size, ap->a_flag);
- } else
- if (xflag == 1) {
- fprintf(ofp, " size %o flags %o\n", ap->a_size, ap->a_flag);
- } else
- if (xflag == 2) {
- fprintf(ofp, " size %u flags %u\n", ap->a_size, ap->a_flag);
- }
- }
-
- /*
- * Output the relocatable item describing a
- * global symbol.
- */
- VOID
- outsym(sp)
- register struct sym *sp;
- {
- register char *ptr;
- register c;
-
- fprintf(ofp, "S ");
- ptr = &sp->s_id[0];
- while (ptr < &sp->s_id[NCPS]) {
- if ((c = *ptr++) != 0)
- putc(c, ofp);
- }
- fprintf(ofp, " %s", sp->s_type==S_NEW ? "Ref" : "Def");
- if (xflag == 0) {
- fprintf(ofp, "%04X\n", sp->s_addr);
- } else
- if (xflag == 1) {
- fprintf(ofp, "%06o\n", sp->s_addr);
- } else
- if (xflag == 2) {
- fprintf(ofp, "%05u\n", sp->s_addr);
- }
- }
-
- VOID
- out(p, n)
- register char *p;
- register n;
- {
- while (n--) {
- if (xflag == 0) {
- fprintf(ofp, " %02X", (*p++)&0377);
- } else
- if (xflag == 1) {
- fprintf(ofp, " %03o", (*p++)&0377);
- } else
- if (xflag == 2) {
- fprintf(ofp, " %03u", (*p++)&0377);
- }
- }
- }
-
- /*
- * Output a byte to the listing buffer.
- */
- VOID
- out_lb(b,t)
- register b,t;
- {
- if (cp < &cb[NCODE])
- *cp++ = b;
- *cpt++ = t;
- }
-
- /*
- * Output ordered word to the listing buffer.
- */
- VOID
- out_lw(n,t)
- register n,t;
- {
- if (hilo) {
- out_lb(hibyte(n),t ? t|R_HIGH : 0);
- out_lb(lobyte(n),t);
- } else {
- out_lb(lobyte(n),t);
- out_lb(hibyte(n),t ? t|R_HIGH : 0);
- }
- }
-
- /*
- * Output ordered 'Relocation' word.
- */
- VOID
- out_rw(n)
- register n;
- {
- if (hilo) {
- *relp++ = hibyte(n);
- *relp++ = lobyte(n);
- } else {
- *relp++ = lobyte(n);
- *relp++ = hibyte(n);
- }
- }
-
- /*
- * Output ordered 'Text' word.
- */
- VOID
- out_tw(n)
- register n;
- {
- if (hilo) {
- *txtp++ = hibyte(n);
- *txtp++ = lobyte(n);
- } else {
- *txtp++ = lobyte(n);
- *txtp++ = hibyte(n);
- }
- }
-
- /*
- * Extract low half of a word.
- */
- int
- lobyte(n)
- {
- return (n&0377);
- }
-
- /*
- * Extract high half of a word.
- */
- int
- hibyte(n)
- {
- return ((n>>8)&0377);
- }
- mov r,m
- mov m,r
-
-