Files
2024-02-19 00:25:23 -05:00

473 lines
8.9 KiB
C

/****************************************************************/
/* */
/* ic_output.c */
/* */
/* Output routines for the "Integer Calculator". */
/* */
/****************************************************************/
/* origination 1988-Apr-6 Terrence W. Holm */
/****************************************************************/
#include <stdio.h>
#include "ic.h"
/****************************************************************/
/* Code for handling termcap */
/****************************************************************/
#define TC_BUFFER 1024 /* Size of termcap(3) buffer */
#define TC_STRINGS 200 /* Enough room for cm,cl,so,se */
static char *Tmove; /* (cm) - Format for tgoto */
static char *Tclr_all; /* (cl) - String to clear screen */
static char *Treverse; /* (so) - String to reverse mode */
static char *Tnormal; /* (se) - String to undo reverse */
/****************************************************************/
/* */
/* Init_Termcap() */
/* */
/* Initializes the external variables for the */
/* current terminal. */
/* */
/* NULL is returned on error conditions. */
/* */
/****************************************************************/
Init_Termcap()
{
char *term;
char buffer[ TC_BUFFER ];
static char strings[ TC_STRINGS ];
char *s = &strings[0];
term = getenv( "TERM" );
if ( term == NULL )
return( 0 );
if ( tgetent( buffer, term ) != 1 )
return( 0 );
if ( (Tmove=tgetstr( "cm", &s )) == NULL )
return( 0 );
if ( (Tclr_all=tgetstr( "cl", &s )) == NULL )
return( 0 );
if ( (Treverse=tgetstr( "so", &s )) == NULL )
{
Treverse = s;
*s = '\0';
++s;
}
if ( (Tnormal=tgetstr( "se", &s )) == NULL )
{
Tnormal = s;
*s = '\0';
++s;
}
return( EOF );
}
/****************************************************************/
/* */
/* Move( column, line ) */
/* */
/* Use the termcap string to move the cursor. */
/* */
/****************************************************************/
Move( column, line )
int column;
int line;
{
Puts( tgoto( Tmove, column, line ) );
}
/****************************************************************/
/* */
/* Puts( string ) */
/* */
/* Write the given termcap string to the standard */
/* output device. */
/* */
/****************************************************************/
Puts( string )
char *string;
{
int Putchar();
tputs( string, 1, Putchar );
}
Putchar( c )
char c;
{
putchar( c );
}
/****************************************************************/
/* Output routines */
/****************************************************************/
/****************************************************************/
/* */
/* Draw_Help_Screen() */
/* */
/****************************************************************/
Draw_Help_Screen()
{
Puts( Tclr_all ); /* Clear the screen */
printf( "\n\n " );
Puts( Treverse );
printf( "IC COMMANDS" );
Puts( Tnormal );
printf( "\n\n\n" );
printf(" h Help ENTER Push stack\n");
printf(" i Input base (h d o b) DEL Clear entry\n" );
printf(" PGDN l Last top of stack\n" );
printf(" m Minix shell . Change sign\n" );
printf(" o Output base (h d o b a) + Add\n" );
printf(" DOWN p Pop stack - Subtract\n" );
printf(" END q Quit * Multiply\n" );
printf(" LEFT r Recall (0-9) / Divide\n" );
printf(" RIGHT s Store [+] (0-9) %% Remainder\n");
printf(" t Translate (char) ~ Not\n" );
printf(" PGUP w Write top to scratch pad & And\n" );
printf(" UP x Exchange top of stack | Or\n" );
printf(" HOME z Zero all state ^ Exclusive-or\n\n\n" );
printf( "\n\nPress a key to continue..." );
}
/****************************************************************/
/* */
/* Draw_Prompt( string ) */
/* */
/* Write a message in the "wait" area. */
/* */
/****************************************************************/
Draw_Prompt( string )
char *string;
{
Move( WAIT_COLUMN, WAIT_LINE );
Puts( Treverse );
printf( string );
Puts( Tnormal );
}
/****************************************************************/
/* */
/* Erase_Prompt() */
/* */
/* Erase the message in the "wait" area. */
/* */
/****************************************************************/
Erase_Prompt()
{
Move( WAIT_COLUMN, WAIT_LINE );
printf(" " );
Move( WAIT_COLUMN, WAIT_LINE );
}
/****************************************************************/
/* */
/* Draw_Screen( state ) */
/* */
/* Redraw everything. */
/* */
/****************************************************************/
Draw_Screen( s )
ic_state *s;
{
Puts( Tclr_all ); /* Clear the screen */
Draw_Stack( s );
Draw_Registers( s );
Move( STATUS_COLUMN, STATUS_LINE );
printf( "Input base = %2d ", s->input_base );
if ( s->output_base == ASCII )
printf( "Output is ASCII " );
else
printf( "Output base = %2d ", s->output_base );
if ( (int) s->scratch_pad != 0 )
printf( "Scratch file = %s", s->file_name );
Move( WAIT_COLUMN, WAIT_LINE );
}
/****************************************************************/
/* */
/* Draw_Stack( state ) */
/* */
/* Redraw the stack. */
/* */
/****************************************************************/
Draw_Stack( s )
ic_state *s;
{
int i;
for ( i = STACK_SIZE-1; i >= 0; --i )
{
Move( STACK_COLUMN, STACK_LINE + STACK_SIZE - 1 - i );
if ( i >= s->stack_size )
printf( "%*c", s->output_base == BINARY ? 32 : 17, ' ' );
else
Print_Number( stdout, s->stack[i], s->output_base );
}
Move( WAIT_COLUMN, WAIT_LINE );
}
/****************************************************************/
/* */
/* Draw_Registers( state ) */
/* */
/* Redraw the registers. Note that only registers */
/* in use are displayed. A register only drops */
/* out of use after a 'z' command, which will */
/* explicitly clear the display, thus we never */
/* have to "wipe off" a value, as the */
/* Draw_Stack() routine must. */
/* */
/****************************************************************/
Draw_Registers( s )
ic_state *s;
{
int i;
for ( i = 0; i < REGISTERS; ++i )
{
if ( (1 << i) & s->register_mask )
{
Move( REG_COLUMN, REG_LINE + i );
Print_Number( stdout, s->registers[i], s->output_base );
printf( " (r%1d)", i );
}
}
Move( WAIT_COLUMN, WAIT_LINE );
}
/****************************************************************/
/* */
/* Draw_Top_of_Stack( state ) */
/* */
/* Redraw only the entry on the top of the stack. */
/* */
/****************************************************************/
Draw_Top_of_Stack( s )
ic_state *s;
{
Move( STACK_COLUMN, STACK_LINE + STACK_SIZE - 1 );
Print_Number( stdout, s->stack[0], s->output_base );
Move( WAIT_COLUMN, WAIT_LINE );
}
/****************************************************************/
/* */
/* Print_Number( stream, number, output_base ) */
/* */
/* Output the "number" to "stream" in the */
/* specified "output_base". */
/* */
/****************************************************************/
Print_Number( stream, number, output_base )
FILE *stream;
long int number;
int output_base;
{
switch ( output_base )
{
case HEXADECIMAL : fprintf( stream, "%12lx", number );
break;
case DECIMAL : fprintf( stream, "%12ld", number );
break;
case OCTAL : fprintf( stream, "%12lo", number );
break;
case BINARY : {
unsigned long int mask;
char pad = ' ';
for ( mask = 0x80000000; mask > 1; mask >>= 1 )
putc( ( mask & number ) ? (pad = '0', '1') : pad, stream );
putc( ( 0x01 & number ) ? '1' : '0', stream );
break;
}
case ASCII : {
char c = number & 0x7f;
if ( (number & ~ 0x7fL) == 0 )
fprintf( stream, "%15c", ' ' );
else
fprintf( stream, "%12lx + ", number & ~ 0x7fL );
if ( c < ' ' )
fprintf( stream, "^%c", c + '@' );
else if ( c == ' ' )
fprintf( stream, "sp" );
else if ( c < 0x7f )
fprintf( stream, " %c", c );
else
fprintf( stream, "^?" );
break;
}
default : fprintf( stderr, "Internal failure (output base)\n" );
Sigint();
}
}