/************************************************************************* Copyright (c) 1984 by Nick de Smith This software is supplied for interest and non-profit making purposes only. Under no circumstance shall it be lent, copied or otherwise used for profit. All rights regarding the use and ownership of this software shall at all times remain with the author, who does not guarantee the accuracy or reliabilty of this software and who will not accept any liability for its use. This software may not be copied or distributed without the inclusion of the above copyright notice. January 31st 1984 *************************************************************************/ /************************************************************************* Program : CAM Module : OP.C Author : Nick de Smith November/December 1982 Description : Output utilities for the object module dis- assembler. *************************************************************************/ #define MODULE #include #include "cam.h" /************************************************************************* * * * l i n e _ n e w * --------------- * * Initialise the line pointers for a scan. * *************************************************************************/ global line_new() { t_label = t_inst = t_args = t_comments = NULL; IR->d_flags = D1->d_flags = D2->d_flags = NULL; IR->d_value = D1->d_value = D2->d_value = NULL; } /************************************************************************* * * * s e t _ p t r * ------------- * * Set an output buffer pointer. * *************************************************************************/ global set_ptr(flags, t_ptr) register int flags; register char *t_ptr; { if (flags & F_LABEL) t_label = t_ptr; if (flags & F_INST) t_inst = t_ptr; if (flags & F_ARGS) t_args = t_ptr; if (flags & F_COM) t_comments = t_ptr; } /************************************************************************* * * * l i n e _ o u t * --------------- * * Output a line to wherever. * *************************************************************************/ global line_out(flags) register int flags; { if (flags & F_PBL) putb(); ++lnum; blank_line = FALSE; if (!lines) flags &= ~F_LNUM; if (!octal) flags &= ~F_CODE; /* if (!code) flags &= ~F_TEXT; if (!ascii) flags &= ~F_COM; */ if (flags & F_LNUM) printf("%6d", lnum); if (lines) putchar('\t'); if (octal) code_out(flags); /* if (code) */ text_out(flags); putchar('\n'); if (flags & F_TBL) putb(); } /************************************************************************* * * * c o d e _ o u t * --------------- * * Output the current code / data bytes * *************************************************************************/ local code_out(flags) register int flags; { if (flags & F_PC) oct_out(&dot); putchar('\t'); if (ascii) { set_ptr(F_COM, asc_buf); asc_ptr = &asc_buf[0]; *asc_ptr = NULL; } if (flags & F_IR) asc_out(IR); putchar('\t'); if (flags & F_D1) asc_out(D1); putchar('\t'); if (flags & F_D2) asc_out(D2); putchar('\t'); } /************************************************************************* * * * a s c _ o u t * ------------- * * Maybe output the ascii of a data item. * *************************************************************************/ local asc_out(d_ptr) register DATA_PTR d_ptr; { register int flags, value; if (ascii && (flags = d_ptr->d_flags) & A_VALID) { chr_out(value = d_ptr->d_value); if (!(flags & A_B)) chr_out(swabi(value)); } oct_out(d_ptr); } /************************************************************************* * * * c h r _ o u t * ------------- * * Output the ascii of the passed data item. If a byte is non- * printing then output a dot. * *************************************************************************/ local chr_out(value) register int value; { if ((value &= 255) >= 32 && value < 127) *asc_ptr++ = value; else *asc_ptr++ = '.'; *asc_ptr = NULL; } /************************************************************************* * * * o c t _ o u t * ------------- * * Output a code/data byte with possible attributes. * *************************************************************************/ local oct_out(d_ptr) register DATA_PTR d_ptr; { if (!(d_ptr->d_flags & A_VALID)) return; if (d_ptr->d_flags & A_B) printf(" %03o", d_ptr->d_value & 0377); else printf("%06o", d_ptr->d_value); if (d_ptr->d_flags & A_R) putchar('\''); else if (d_ptr->d_flags & A_G) putchar('G'); else if (d_ptr->d_flags & A_C) putchar('C'); } /************************************************************************* * * * t e x t _ o u t * --------------- * * Output a controlled and formatted line of text to the output * file. Try to avoid using printf. * *************************************************************************/ local text_out(flags) register int flags; { register int temp; if (flags & F_LABEL && t_label) { fputs(t_label, stdout); if (strlen(t_label) < 8) putchar('\t'); } else putchar('\t'); if (flags & F_INST && t_inst) fputs(t_inst, stdout); putchar('\t'); temp = 4; if (flags & F_ARGS && t_args) { fputs(t_args, stdout); temp = 4 - (strlen(t_args) / 8); if (temp <= 0) temp = 1; } if (flags & F_COM) { while (temp--) putchar('\t'); putchar(';'); if (ascii && t_comments) { putchar('\040'); fputs(t_comments, stdout); } } } /************************************************************************* * * * p u t l * ------- * * Output a single element line in a controlled fashion. * *************************************************************************/ global putl(flags, t_ptr) register int flags; char *t_ptr; { line_new(); set_ptr(flags, t_ptr); line_out(flags); } /************************************************************************* * * * p u t b * ------- * * Output a blank line. Note that we only output a blank line if the * previous line was non-blank. Line_out() resets the flag. * *************************************************************************/ global putb() { if (blank_line) return; ++lnum; blank_line = TRUE; putchar('\n'); } /************************************************************************* * * * r a d n a m * ----------- * * Convert two radix 50 integers into ascii text. return a pointer * to the buffer that was used. * *************************************************************************/ global char * radnam(i_ptr) register int *i_ptr; { r50toa(buff, i_ptr, 2); buff[6] = NULL; return (&buff[0]); } /************************************************************************* * * * r a d m i n * ----------- * * Convert two radix 50 integers into ascii text. Trailing spaces * are removed. Return a pointer to the buffer that was used. * *************************************************************************/ global char * radmin(i_ptr) register int *i_ptr; { register char *t_ptr; r50toa(buff, i_ptr, 2); t_ptr = &buff[6]; while (t_ptr != &buff[0] && *--t_ptr == '\040') ; if (*t_ptr != '\040') t_ptr++; *t_ptr = '\0'; return(&buff[0]); } /************************************************************************* * * * a r g _ i * --------- * * Initialise the argument working buffer. * *************************************************************************/ global arg_i() { w_ptr = wbuf; *w_ptr = '\0'; } /************************************************************************* * * * a r g _ n * --------- * * Return the number of characters in the argument buffer. * *************************************************************************/ global arg_n() { return(w_ptr - wbuf); } /************************************************************************* * * * a r g _ c * --------- * * Put a character into the argument working buffer. * *************************************************************************/ global arg_c(c) char c; { *w_ptr++ = c; *w_ptr = '\0'; } /************************************************************************* * * * a r g _ s * --------- * * Put a string into the argument working buffer. * *************************************************************************/ global arg_s(t_ptr) register char *t_ptr; { while (*t_ptr) *w_ptr++ = *t_ptr++; *w_ptr = '\0'; } /************************************************************************* * * * a r g _ o * --------- * * Put a minimal octal string into the argument buffer. * *************************************************************************/ global char * arg_o(n) int n; { sprintf(w_ptr, "%o", n); while (*w_ptr) w_ptr++; return(w_ptr); } /************************************************************************* * * * a r g _ 3 o * ----------- * * Put a three character octal string into the argument buffer. * *************************************************************************/ global char * arg_3o(n) int n; { sprintf(w_ptr, "%03o", n); while (*w_ptr) w_ptr++; return(w_ptr); } /************************************************************************* * * * a r g _ 6 o * ----------- * * Put a six character octal string into the argument buffer. * *************************************************************************/ global char * arg_6o(n) int n; { sprintf(w_ptr, "%06o", n); while (*w_ptr) w_ptr++; return(w_ptr); }