/* asout.c */ /* * (C) Copyright 1989 * All Rights Reserved * * Alan R. Baldwin * 721 Berkeley St. * Kent, Ohio 44240 */ #include #include #include "asm.h" #define R_WORD 0 /* 16 bit */ #define R_BYTE 01 #define R_AREA 0 /* Base type */ #define R_SYM 02 #define R_NORM 0 /* PC adjust */ #define R_PCR 04 #define R_DEF 00 /* Global def. */ #define R_REF 01 /* Global ref. */ #define R_REL 00 /* Relocatable */ #define R_ABS 02 /* Absolute */ #define R_GBL 00 /* Global */ #define R_LCL 04 /* Local */ #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); if (oflag) { outchk(1, 0); *txtp++ = lobyte(b); } } ++dot->s_addr; } /* * Output absolute word. * Low then high. */ VOID outaw(w) { if (pass == 2) { out_lw(w); if (oflag) { outchk(2, 0); out_tw(w); } } dot->s_addr += 2; } /* * Output relocatable byte. */ VOID outrb(esp, pcrf) register struct expr *esp; { register n, r; if (pass == 2) { out_lb(esp->e_addr); if (oflag) { if (esp->e_flag==0 && esp->e_base.e_ap==NULL) { outchk(1, 0); *txtp++ = lobyte(esp->e_addr); } else { outchk(1, 4); *txtp++ = lobyte(esp->e_addr); r = R_BYTE; if (pcrf) r |= R_PCR; 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 - 1; out_rw(n); } } } ++dot->s_addr; } /* * Output relocatable word. * Low then high. */ VOID outrw(esp, pcrf) register struct expr *esp; { register n, r; if (pass == 2) { out_lw(esp->e_addr); if (oflag) { if (esp->e_flag==0 && esp->e_base.e_ap==NULL) { outchk(2, 0); out_tw(esp->e_addr); } else { outchk(2, 4); out_tw(esp->e_addr); r = R_WORD; if (pcrf) r |= R_PCR; 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; } /* * Clear out any bufferred text and relocation information */ VOID outall() { if (oflag && pass==2) outbuf(); } /* * Check text buffer and relocation buffer. */ VOID outchk(nt, nr) { register struct area *ap; if (txtp+nt > &txt[NTXT] || relp+nr > &rel[NREL]) { outbuf(); } if (txtp == txt) { out_tw(dot->s_addr); if (ap = dot->s_area) { *relp++ = R_WORD|R_AREA; *relp++ = 0; out_rw(ap->a_ref); } } } /* * Output any bufferred text and relocation information */ VOID outbuf() { if (txtp > &txt[2]) { fprintf(ofp, "T"); out(txt, txtp-txt); fprintf(ofp, "\n"); txtp = txt; if (relp > rel) { fprintf(ofp, "R"); out(rel, relp-rel); fprintf(ofp, "\n"); relp = rel; } } else { 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++) putc(c, ofp); } putc('\n', ofp); } /* * Global references and absolutes. */ rn = 0; for (i=0; is_area==NULL && sp->s_flag&S_GBL) { sp->s_ref = rn++; outsym(sp); } sp = sp->s_sp; } } /* * Global relocatables. */ for (i=0; ia_ref != i) ap = ap->a_ap; outarea(ap); for (j=0; js_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++) 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++) 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) register b; { if (cp < &cb[NCODE]) *cp++ = b; } /* * Output ordered word to the listing buffer. */ VOID out_lw(n) register n; { if (hilo) { out_lb(hibyte(n)); out_lb(lobyte(n)); } else { out_lb(lobyte(n)); out_lb(hibyte(n)); } } /* * 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); }