/* aslist.c */ /* * (C) Copyright 1989-1995 * All Rights Reserved * * Alan R. Baldwin * 721 Berkeley St. * Kent, Ohio 44240 * * 28-Oct-97 JLH: * - lstsym: show s_id as string rather than array [NCPS] */ #include #include #include #include #include "asm.h" /*)Module aslist.c * * The module aslist.c contains all the functions used * to generate the assembler list and symbol output files. * * aslist.c contains the following functions: * VOID list() * VOID list1() * VOID list2() * VOID slew() * VOID lstsym() * * The module aslist.c contains no local/static variables */ /*)Function VOID list() * * The function list() generates the listing output * which includes the input source, line numbers, * and generated code. Numerical output may be selected * as hexadecimal, decimal, or octal. * * local variables: * int * wp pointer to the assembled data bytes * int * wpt pointer to the data byte mode * int nb computed number of assembled bytes * * global variables: * int cb[] array of assembler output values * int cbt[] array of assembler relocation types * describing the data in cb[] * int * cp pointer to assembler output array cb[] * int * cpt pointer to assembler relocation type * output array cbt[] * char eb[] array of generated error codes * char * ep pointer into error list * array eb[] * char ib[] assembler-source text line * FILE * lfp list output file handle * int line current assembler source line number * int lmode listing mode * int xflag -x, listing radix flag * * functions called: * int fprintf() c_library * VOID list1() aslist.c * int putc() c_library * VOID slew() asslist.c * * side effects: * Listing or symbol output updated. */ VOID list() { register char *wp; register int *wpt; register int nb; if (lfp == NULL || lmode == NLIST) return; /* * Get Correct Line Number */ if (incfil >= 0) { line = incline[incfil]; if (line == 0) { if (incfil > 0) { line = incline[incfil-1]; } else { line = srcline[cfile]; } } } else { line = srcline[cfile]; } /* * Move to next line. */ slew(lfp, pflag); /* * Output a maximum of NERR error codes with listing. */ while (ep < &eb[NERR]) *ep++ = ' '; fprintf(lfp, "%.2s", eb); /* * Source listing only option. */ if (lmode == SLIST) { fprintf(lfp, "%24s%5u %s\n", "", line, ib); return; } if (lmode == ALIST) { outchk(HUGE,HUGE); } /* * HEX output Option. */ if (xflag == 0) { /* HEX */ /* * Equate only */ if (lmode == ELIST) { fprintf(lfp, "%18s%04X", "", laddr); fprintf(lfp, " %5u %s\n", line, ib); return; } /* * Address (with allocation) */ fprintf(lfp, " %04X", laddr); if (lmode == ALIST || lmode == BLIST) { fprintf(lfp, "%19s%5u %s\n", "", line, ib); outdot(); return; } wp = cb; wpt = cbt; nb = (int) (cp - cb); /* * First line of output for this source line with data. */ list1(wp, wpt, nb, 1); fprintf(lfp, " %5u %s\n", line, ib); /* * Subsequent lines of output if more data. */ while ((nb -= 6) > 0) { wp += 6; wpt += 6; slew(lfp, 0); fprintf(lfp, "%7s", ""); list1(wp, wpt, nb, 0); putc('\n', lfp); } } else /* * OCTAL output Option. */ if (xflag == 1) { /* OCTAL */ /* * Equate only */ if (lmode == ELIST) { fprintf(lfp, "%16s%06o", "", laddr); fprintf(lfp, " %5u %s\n", line, ib); return; } /* * Address (with allocation) */ fprintf(lfp, " %06o", laddr); if (lmode == ALIST || lmode == BLIST) { fprintf(lfp, "%17s%5u %s\n", "", line, ib); outdot(); return; } wp = cb; wpt = cbt; nb = (int) (cp - cb); /* * First line of output for this source line with data. */ list1(wp, wpt, nb, 1); fprintf(lfp, " %5u %s\n", line, ib); /* * Subsequent lines of output if more data. */ while ((nb -= 4) > 0) { wp += 4; wpt += 4; slew(lfp, 0); fprintf(lfp, "%9s", ""); list1(wp, wpt, nb, 0); putc('\n', lfp); } } else /* * DECIMAL output Option. */ if (xflag == 2) { /* DECIMAL */ /* * Equate only */ if (lmode == ELIST) { fprintf(lfp, "%16s%05u", "", laddr); fprintf(lfp, " %5u %s\n", line, ib); return; } /* * Address (with allocation) */ fprintf(lfp, " %05u", laddr); if (lmode == ALIST || lmode == BLIST) { fprintf(lfp, "%17s%5u %s\n", "", line, ib); outdot(); return; } wp = cb; wpt = cbt; nb = (int) (cp - cb); /* * First line of output for this source line with data. */ list1(wp, wpt, nb, 1); fprintf(lfp, " %5u %s\n", line, ib); /* * Subsequent lines of output if more data. */ while ((nb -= 4) > 0) { wp += 4; wpt += 4; slew(lfp, 0); fprintf(lfp, "%9s", ""); list1(wp, wpt, nb, 0); putc('\n', lfp); } } } /*)Function VOID list1(wp, wpt, nw, f) * * int f fill blank fields (1) * int nb number of data bytes * int * wp pointer to data bytes * int * wpt pointer to data byte mode * * local variables: * int i loop counter * * global variables: * int xflag -x, listing radix flag * * functions called: * VOID list2() asslist.c * int fprintf() c_library * * side effects: * Data formatted and output to listing. */ VOID list1(wp, wpt, nb, f) register char *wp; register int *wpt, nb, f; { register int i; /* * HEX output Option. */ if (xflag == 0) { /* HEX */ /* * Bound number of words to HEX maximum per line. */ if (nb > 6) nb = 6; /* * Output bytes. */ for (i=0; i 4) nb = 4; /* * Output bytes. */ for (i=0; i 4) nb = 4; /* * Output bytes. */ for (i=0; i= 2) { if (t & R_RELOC) { if (t & (R_PAG0|R_PAG)) { c = '*'; } else if (t & R_USGN) { c = 'u'; } else if (t & R_PCR) { c = 'p'; } else { c = 'r'; } if (t & R_HIGH) c += 1; } } /* * Output the selected mode. */ putc(c, lfp); } /*)Function VOID slew(fp, flag) * * FILE * fp file handle for listing * int flag enable pagination * * The function slew() increments the page line count. * If the page overflows and pagination is enabled: * 1) put out a page skip, * 2) a title, * 3) a subtitle, * 4) and reset the line count. * * local variables: * none * * global variables: * char cpu[] cpu type string * int lop current line number on page * int page current page number * char stb[] Subtitle string buffer * char tb[] Title string buffer * * functions called: * int fprintf() c_library * * side effects: * Increments page line counter, on overflow * a new page header is output to the listing file. */ VOID slew(fp,flag) FILE *fp; int flag; { if ((lop++ >= NLPP) && flag) { fprintf(fp, "\fASxxxx Assembler %s (%s), page %u.\n", VERSION, cpu, ++page); fprintf(fp, "%s\n", tb); fprintf(fp, "%s\n\n", stb); lop = 5; } } /* Used for qsort call in lstsym */ static int _cmpSym(const void *p1, const void *p2) { struct sym **s1 = (struct sym **)(p1); struct sym **s2 = (struct sym **)(p2); return strcmp((*s1)->s_id,(*s2)->s_id); } /*)Function VOID lstsym(fp) * * FILE * fp file handle for output * * The function lstsym() outputs alphabetically * sorted symbol and area tables. * * local variables: * int c temporary * int i loop counter * int j temporary * int k temporary * char * ptr pointer to an id string * int nmsym number of symbols * int narea number of areas * sym * sp pointer to symbol structure * sym ** p pointer to an array of * pointers to symbol structures * area * ap pointer to an area structure * * global variables: * area * areap pointer to an area structure * char aretbl[] string "Area Table" * sym dot defined as sym[0] * char stb[] Subtitle string buffer * sym * symhash[] array of pointers to NHASH * linked symbol lists * char symtbl[] string "Symbol Table" * FILE * tfp symbol table output file handle * int xflag -x, listing radix flag * * functions called: * int fprintf() c_library * int putc() c_library * VOID slew() aslist.c * int strcmp() c_library * char * strcpy() c_library * * side effects: * Symbol and area tables output. */ VOID lstsym(fp) FILE *fp; { register int c, i, j, k; register char *ptr; int nmsym, narea; struct sym *sp; struct sym **p; struct area *ap; /* * Symbol Table Header */ strcpy(stb, &symtbl[0]); lop = NLPP; if (fp == tfp) page = 0; slew(fp, 1); /* * Find number of symbols */ nmsym = 0; for (i=0; is_sp; } } if (nmsym == 0) goto atable; /* * Allocate space for an array of pointers to symbols * and load array. */ if ((p = (struct sym **) malloc(sizeof((struct sym *) sp)*nmsym)) == NULL) { fprintf(fp, "Insufficient space to build Symbol Table.\n"); return; } nmsym = 0; for (i=0; is_sp; } } #if 0 /* BUBBLE SORT?? WTF??? */ /* * Bubble Sort on Symbol Table Array */ j = 1; c = nmsym - 1; while (j) { j = 0; for (i=0; is_id[0],&p[i+1]->s_id[0]) > 0) { j = 1; sp = p[i+1]; p[i+1] = p[i]; p[i] = sp; } } } #else qsort(p, nmsym, sizeof(struct sym *), _cmpSym); #endif /* * Symbol Table Output */ for (i=0; is_area) { j = sp->s_area->a_ref; if (xflag == 0) { fprintf(fp, " %2X ", j); } else if (xflag == 1) { fprintf(fp, "%3o ", j); } else if (xflag == 2) { fprintf(fp, "%3u ", j); } } else { fprintf(fp, " "); } ptr = &sp->s_id[0]; fprintf(fp, "%-60s", ptr ); /* JLH */ if (sp->s_flag & S_ASG) { putc('=', fp); } else { putc(' ', fp); } if (sp->s_type == S_NEW) { if (xflag == 0) { fprintf(fp, " **** "); } else if (xflag == 1) { fprintf(fp, "****** "); } else if (xflag == 2) { fprintf(fp, " ***** "); } } else { j = sp->s_addr; if (xflag == 0) { fprintf(fp, " %04X ", j); } else if (xflag == 1) { fprintf(fp, "%06o ", j); } else if (xflag == 2) { fprintf(fp, " %05u ", j); } } j = 0; if (sp->s_flag & S_GBL) { putc('G', fp); ++j; } if (sp->s_area != NULL) { putc('R', fp); ++j; } if (sp->s_type == S_NEW) { putc('X', fp); ++j; } #if NCPS-8 putc('\n', fp); slew(fp, 0); ++i; #else if (++i % 3 == 0) { putc('\n', fp); slew(fp, pflag); } else if (i < nmsym) { while (j++ < 4) putc(' ', fp); fprintf(fp, "| "); } #endif } putc('\n', fp); /* * Area Table Header */ atable: strcpy(stb, &aretbl[0]); lop = NLPP; slew(fp, 1); /* * Area Table Output */ narea = 0; ap = areap; while (ap) { ++narea; ap = ap->a_ap; } for (i=0; ia_ap; j = ap->a_ref; if (xflag == 0) { fprintf(fp, " %2X ", j); } else if (xflag == 1) { fprintf(fp, " %3o ", j); } else if (xflag == 2) { fprintf(fp, " %3u ", j); } ptr = &ap->a_id[0]; while (ptr < &ap->a_id[NCPS]) { if ((c = *ptr++) != 0) { putc(c, fp); } else { putc(' ', fp); } } j = ap->a_size; k = ap->a_flag; if (xflag==0) { fprintf(fp, " size %4X flags %X\n", j, k); } else if (xflag==1) { fprintf(fp, " size %6o flags %o\n", j, k); } else if (xflag==2) { fprintf(fp, " size %5u flags %u\n", j, k); } } }