add directory study

This commit is contained in:
gohigh
2024-02-19 00:25:23 -05:00
parent b1306b38b1
commit f3774e2f8c
4001 changed files with 2285787 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
CFLAGS = -F
ICOBJ = ic.s ic_input.s ic_output.s
ic: $(ICOBJ)
cc -T. $(ICOBJ) -o ic
chmem =5000 ic
$(ICOBJ): ic.h
clean:
@rm -f *.bak *.s ic

View File

@@ -0,0 +1,8 @@
CFLAGS = -O
ICOBJ = ic.o ic_input.o ic_output.o
ic: $(ICOBJ)
cc $(ICOBJ) -o ic
chmem =5000 ic
$(ICOBJ): ic.h

View File

@@ -0,0 +1,850 @@
/****************************************************************/
/* */
/* ic.c */
/* */
/* The main loop of the "Integer Calculator". */
/* */
/****************************************************************/
/* origination 1988-Apr-6 Terrence W. Holm */
/* added Exec_Shell() 1988-Apr-11 Terrence W. Holm */
/* added "s+" 1988-Apr-18 Terrence W. Holm */
/* added cmd line args 1988-May-13 Terrence W. Holm */
/* 'i' also does 'o' 1988-May-28 Terrence W. Holm */
/* if ~dec:unsigned *%/ 1988-Jul-10 Terrence W. Holm */
/****************************************************************/
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include "ic.h"
static char copyright[] = { "ic (c) Terrence W. Holm 1988" };
/****************************************************************/
/* */
/* main() */
/* */
/* Initialize. Enter the main processing loop. */
/* */
/****************************************************************/
main( argc, argv )
int argc;
char *argv[];
{
ic_state state; /* This state record is passed */
/* to most subroutines */
Init_State( &state );
state.scratch_pad = (FILE *) NULL; /* No 'w' command yet */
Init_Getc( argc, argv ); /* Refs to command line args */
if ( Init_Termcap() == 0 )
{
fprintf( stderr, "ic requires a termcap entry\n" );
exit( 1 );
}
Save_Term(); /* Save terminal characteristics */
if ( signal( SIGINT, SIG_IGN ) != SIG_IGN )
{
signal( SIGINT, Sigint );
signal( SIGQUIT, Sigint );
}
Set_Term(); /* Setup terminal characteristics */
Draw_Screen( &state );
while (1)
{
int rc = Process( &state, Get_Char() );
if ( rc == EOF )
break;
if ( rc == ERROR )
putchar( BELL );
}
Reset_Term(); /* Restore terminal characteristics */
exit( OK );
}
/****************************************************************/
/* */
/* Init_State() */
/* */
/* Initialize the state record. */
/* */
/****************************************************************/
Init_State( s )
ic_state *s;
{
s->stack[0] = 0;
s->stack_size = 1;
s->register_mask = 0x000;
s->last_tos = 0;
s->mode = LAST_WAS_ENTER;
s->input_base = DECIMAL;
s->output_base = DECIMAL;
}
/****************************************************************/
/* */
/* Sigint() */
/* */
/* Terminate the program on an interrupt (^C) */
/* or quit (^\) signal. */
/* */
/****************************************************************/
void Sigint(sig)
int sig;
{
Reset_Term(); /* Restore terminal characteristics */
exit( 1 );
}
/****************************************************************/
/* */
/* Process( state, input_char ) */
/* */
/* Determine the function requested by the */
/* input character. Returns OK, EOF or ERROR. */
/* */
/****************************************************************/
int Process( s, c )
ic_state *s;
int c;
{
switch ( c )
{
case '0' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9' :
return( Enter_Numeric( s, (int) c - '0' ) );
case 'a' :
case 'b' :
case 'c' :
case 'd' :
case 'e' :
case 'f' :
return( Enter_Numeric( s, (int) c - 'a' + 10 ) );
case 'h' : case '?' : /* Help */
Draw_Help_Screen();
Get_Char();
Draw_Screen( s );
return( OK );
case 'i' : /* Set i/p and o/p base */
{
int numeral;
Draw_Prompt( "Base?" );
numeral = Get_Base( Get_Char() );
Erase_Prompt();
if ( numeral == ERROR || numeral == ASCII )
return( ERROR );
s->input_base = numeral;
s->output_base = numeral;
s->mode = LAST_WAS_FUNCTION;
Draw_Screen( s );
return( OK );
}
case 'l' : case ESC_PGDN : /* Get last tos value */
if ( s->mode != LAST_WAS_ENTER )
Push( s );
s->stack[0] = s->last_tos;
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
case 'm' : /* Invoke a Minix shell */
Reset_Term();
Exec_Shell();
Set_Term();
Draw_Screen( s );
return( OK );
case 'o' : /* Set output base */
{
int numeral;
Draw_Prompt( "Base?" );
numeral = Get_Base( Get_Char() );
Erase_Prompt();
if ( numeral == ERROR )
return( ERROR );
s->output_base = numeral;
s->mode = LAST_WAS_FUNCTION;
Draw_Screen( s );
return( OK );
}
case 'p' : case ESC_DOWN : /* Pop: Roll down stack */
{
long int temp = s->stack[0];
int i;
for ( i = 0; i < s->stack_size-1; ++i )
s->stack[i] = s->stack[i+1];
s->stack[ s->stack_size-1 ] = temp;
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
}
case 'q' : case ESC_END : /* Quit */
case EOF : case CTRL_D :
return( EOF );
case 'r' : case ESC_LEFT : /* Recall from register */
{
int numeral;
Draw_Prompt( "Register?" );
numeral = Get_Char() - '0';
Erase_Prompt();
if ( numeral < 0 || numeral >= REGISTERS ||
((1 << numeral) & s->register_mask) == 0 )
return( ERROR );
if ( s->mode != LAST_WAS_ENTER )
Push( s );
s->stack[0] = s->registers[numeral];
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
}
case 's' : case ESC_RIGHT : /* Store in register, */
/* or accumulate if */
/* "s+" is typed. */
{
int c;
int numeral;
Draw_Prompt( "Register?" );
c = Get_Char();
if ( c == ESC_PLUS )
c = '+'; /* Allow keypad '+' */
if ( c == '+' )
{
Draw_Prompt( "Accumulator?" );
numeral = Get_Char() - '0';
}
else
numeral = c - '0';
Erase_Prompt();
if ( numeral < 0 || numeral >= REGISTERS )
return( ERROR );
if ( c != '+' || (s->register_mask & (1 << numeral)) == 0 )
{
s->register_mask |= 1 << numeral;
s->registers[numeral] = s->stack[0];
}
else
s->registers[numeral] += s->stack[0];
s->mode = LAST_WAS_FUNCTION;
Draw_Registers( s );
return( OK );
}
case 't' : /* Translate from ASCII */
{
long int numeral;
Draw_Prompt( "Character?" );
numeral = (long int) Getc();
Erase_Prompt();
if ( s->mode != LAST_WAS_ENTER )
Push( s );
s->stack[0] = numeral;
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
}
case 'w' : case ESC_PGUP : /* Write tos to a file */
{
if ( (int) s->scratch_pad == (int) NULL )
{
/* Try to open a scratch pad file */
strcpy( s->file_name, "./pad" );
if ( (s->scratch_pad=fopen(s->file_name,"w")) == NULL )
{
/* Unsuccessful, try in /tmp */
char *id;
strcpy( s->file_name, "/tmp/pad_" );
if ( (id=cuserid(NULL)) == NULL )
return( ERROR );
strcat( s->file_name, id );
if ( (s->scratch_pad=fopen(s->file_name,"w")) == NULL )
return( ERROR );
}
Draw_Screen( s );
}
/* We have a successfully opened file */
Print_Number( s->scratch_pad, s->stack[0], s->output_base );
putc( '\n', s->scratch_pad );
fflush( s->scratch_pad );
s->mode = LAST_WAS_FUNCTION;
return( OK );
}
case 'x' : case ESC_UP : /* Exchange top of stack */
{
long int temp = s->stack[0];
if ( s->stack_size < 2 )
return( ERROR );
s->stack[0] = s->stack[1];
s->stack[1] = temp;
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
}
case 'z' : case ESC_HOME: /* Clear all */
Init_State( s );
Draw_Screen( s );
return( OK );
case BS : case DEL : /* Clear top of stack */
s->stack[0] = 0;
s->mode = LAST_WAS_ENTER;
Draw_Top_of_Stack( s );
return( OK );
case '\n' : /* Enter */
Push( s );
s->mode = LAST_WAS_ENTER;
Draw_Stack( s );
return( OK );
case '.' : /* Change sign */
s->last_tos = s->stack[0];
s->stack[0] = - s->stack[0];
s->mode = LAST_WAS_FUNCTION;
Draw_Top_of_Stack( s );
return( OK );
case '+' : case ESC_PLUS : /* Add */
if ( s->stack_size < 2 )
return( ERROR );
s->last_tos = s->stack[0];
Pop( s );
s->stack[0] += s->last_tos;
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
case '-' : case ESC_MINUS : /* Subtract */
if ( s->stack_size < 2 )
return( ERROR );
s->last_tos = s->stack[0];
Pop( s );
s->stack[0] -= s->last_tos;
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
case '*' : /* Multiply */
if ( s->stack_size < 2 )
return( ERROR );
s->last_tos = s->stack[0];
Pop( s );
if ( s->input_base == DECIMAL )
s->stack[0] *= s->last_tos;
else
s->stack[0] = (long int)
( UNS(s->stack[0]) * UNS(s->last_tos) );
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
case '/' : /* Divide */
if ( s->stack_size < 2 || s->stack[0] == 0 )
return( ERROR );
s->last_tos = s->stack[0];
Pop( s );
if ( s->input_base == DECIMAL )
s->stack[0] /= s->last_tos;
else
s->stack[0] = (long int)
( UNS(s->stack[0]) / UNS(s->last_tos) );
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
case '%' : case ESC_5 : /* Remainder */
if ( s->stack_size < 2 || s->stack[0] == 0 )
return( ERROR );
s->last_tos = s->stack[0];
Pop( s );
if ( s->input_base == DECIMAL )
s->stack[0] %= s->last_tos;
else
s->stack[0] = (long int)
( UNS(s->stack[0]) % UNS(s->last_tos) );
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
case '~' : /* Not */
s->last_tos = s->stack[0];
s->stack[0] = ~ s->stack[0];
s->mode = LAST_WAS_FUNCTION;
Draw_Top_of_Stack( s );
return( OK );
case '&' : /* And */
if ( s->stack_size < 2 )
return( ERROR );
s->last_tos = s->stack[0];
Pop( s );
s->stack[0] &= s->last_tos;
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
case '|' : /* Or */
if ( s->stack_size < 2 )
return( ERROR );
s->last_tos = s->stack[0];
Pop( s );
s->stack[0] |= s->last_tos;
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
case '^' : /* Exclusive-or */
if ( s->stack_size < 2 )
return( ERROR );
s->last_tos = s->stack[0];
Pop( s );
s->stack[0] ^= s->last_tos;
s->mode = LAST_WAS_FUNCTION;
Draw_Stack( s );
return( OK );
default:
return( ERROR );
}
}
/****************************************************************/
/* */
/* Enter_Numeric( state, numeral ) */
/* */
/* A numeral (0 to 15) has been typed. */
/* If a number is currently being entered */
/* then shift it over and add this to the */
/* display. If the last operation was a function */
/* then push up the stack first. If the last */
/* key was "ENTER", then clear out the top of */
/* the stack and put the numeral there. */
/* */
/* Returns OK or ERROR. */
/* */
/****************************************************************/
int Enter_Numeric( s, numeral )
ic_state *s;
int numeral;
{
if ( numeral >= s->input_base )
return( ERROR );
switch ( s->mode )
{
case LAST_WAS_FUNCTION :
Push( s );
s->stack[0] = numeral;
Draw_Stack( s );
break;
case LAST_WAS_NUMERIC :
s->stack[0] = s->stack[0] * s->input_base + numeral;
Draw_Top_of_Stack( s );
break;
case LAST_WAS_ENTER :
s->stack[0] = numeral;
Draw_Top_of_Stack( s );
break;
default:
fprintf( stderr, "Internal failure (mode)\n" );
Sigint();
}
s->mode = LAST_WAS_NUMERIC;
return( OK );
}
/****************************************************************/
/* */
/* Push( state ) */
/* */
/* Push up the stack one level. */
/* */
/****************************************************************/
Push( s )
ic_state *s;
{
int i;
if ( s->stack_size == STACK_SIZE )
--s->stack_size;
for ( i = s->stack_size; i > 0; --i )
s->stack[i] = s->stack[i-1];
++s->stack_size;
}
/****************************************************************/
/* */
/* Pop( state ) */
/* */
/* Pop the stack down one level. */
/* This routine is only called with */
/* the stack size > 1. */
/* */
/****************************************************************/
Pop( s )
ic_state *s;
{
int i;
for ( i = 0; i < s->stack_size-1; ++i )
s->stack[i] = s->stack[i+1];
--s->stack_size;
}
/****************************************************************/
/* */
/* Exec_Shell() */
/* */
/* Fork off a sub-process to exec() the shell. */
/* */
/****************************************************************/
Exec_Shell()
{
int pid = fork();
if ( pid == -1 )
return;
if ( pid == 0 )
{
/* The child process */
extern char **environ;
char *shell = getenv( "SHELL" );
if ( shell == NULL )
shell = "/bin/sh";
execle( shell, shell, (char *) 0, environ );
perror( shell );
exit( 127 );
}
/* The parent process: ignore signals, wait for sub-process */
signal( SIGINT, SIG_IGN );
signal( SIGQUIT, SIG_IGN );
{
int status;
int w;
while ( (w=wait(&status)) != pid && w != -1 );
}
signal( SIGINT, Sigint );
signal( SIGQUIT, Sigint );
return;
}

View File

@@ -0,0 +1,177 @@
/****************************************************************/
/* */
/* ic.h */
/* */
/* Definitions for the "Integer Calculator". */
/* */
/****************************************************************/
/* origination 1988-Apr-6 Terrence W. Holm */
/****************************************************************/
/****************************************************************/
/* */
/* ic(1) */
/* */
/* This is a simple RPN calculator, used for small calculations */
/* and base conversions. All calculations are done using 32 bit */
/* integers. */
/* */
/* Commands are available for stack operations, saving results, */
/* arithmetic and logical operations, and escaping to the Minix */
/* shell. */
/* */
/* The program requires termcap(3), but otherwise should run */
/* under all Unix (tm) variants. */
/* */
/* See the ic(1) man page. */
/* */
/****************************************************************/
/****************************************************************/
/* */
/* ic Copyright Terrence W. Holm 1988 */
/* */
/* This program was written for users of the Minix operating */
/* system, and in the spirit of other public domain software */
/* written for said system, this source code is made available */
/* at no cost to everyone. */
/* */
/* This program (one .h, three .c and a "man" page) may be */
/* copied and/or modified subject to (1) no charge must be */
/* made for distribution, other than for the medium, (2) all */
/* modified sources must be clearly marked as such, (3) all */
/* sources must carry this copyright. */
/* */
/****************************************************************/
/****************************************************************/
/* */
/* files */
/* */
/* ic.h Definitions */
/* ic.c The main loop */
/* ic_input.c Character input routines */
/* ic_output.c Output routines */
/* */
/* ic.1 "Man" page */
/* Makefile For "make" */
/* */
/****************************************************************/
#define UNS(x) ((unsigned long)(x))
#define STACK_SIZE 6 /* Max # of levels */
#define REGISTERS 10 /* Registers 0 to 9 */
#define LAST_WAS_ENTER 1 /* Numeric input modes */
#define LAST_WAS_NUMERIC 2
#define LAST_WAS_FUNCTION 3
#define ASCII -1 /* Input and output */
#define BINARY 2 /* modes */
#define OCTAL 8
#define DECIMAL 10
#define HEXADECIMAL 16
#define OK 0 /* Return codes */
#define ERROR 1
#define CTRL_D '\004' /* ASCII ^D */
#define BELL '\007' /* ASCII bell code */
#define BS '\010' /* ASCII back space */
#define ESCAPE '\033' /* ASCII escape code */
#define DEL '\177' /* ASCII delete code */
/* Input escape codes generated by the Minix console. */
/* Format: ESC [ X. Shows character equivalent for ic. */
#define ESC_HOME 'H' + 0x80 /* z */
#define ESC_UP 'A' + 0x80 /* x */
#define ESC_PGUP 'V' + 0x80 /* w */
#define ESC_LEFT 'D' + 0x80 /* r */
#define ESC_5 'G' + 0x80 /* % */
#define ESC_RIGHT 'C' + 0x80 /* s */
#define ESC_END 'Y' + 0x80 /* q */
#define ESC_DOWN 'B' + 0x80 /* p */
#define ESC_PGDN 'U' + 0x80 /* l */
#define ESC_PLUS 'T' + 0x80 /* + */
#define ESC_MINUS 'S' + 0x80 /* - */
/* Move positions for the output display. */
#define STACK_COLUMN 4
#define STACK_LINE 7
#define REG_COLUMN STACK_COLUMN+36
#define REG_LINE 3
#define STATUS_COLUMN 6
#define STATUS_LINE 0
#define WAIT_COLUMN 0
#define WAIT_LINE 14
typedef struct ic_state /* State of int. calc. */
{
long int stack[ STACK_SIZE ]; /* The stack */
long int registers[ REGISTERS ]; /* The registers */
int stack_size; /* Current size (>= 1) */
int register_mask; /* In use bit mask */
long int last_tos; /* For 'L' command */
int mode; /* Last key type. See */
/* LAST_WAS_ENTER, etc */
int input_base; /* Current i/o base, */
int output_base; /* ASCII, BINARY, etc */
FILE *scratch_pad; /* For 'w' command */
char file_name[20]; /* "pad" or "/tmp/pad" */
} ic_state;
void Sigint();
int Process();
int Enter_Numeric();
int Get_Char();
int Get_Base();
char *getenv();
char *tgetstr();
char *tgoto();
char *cuserid();
FILE *fopen();

View File

@@ -0,0 +1,277 @@
/****************************************************************/
/* */
/* ic_input.c */
/* */
/* Character input routines for the */
/* "Integer Calculator". */
/* */
/****************************************************************/
/* origination 1988-Apr-7 Terrence W. Holm */
/* added cmd line args 1988-May-13 Terrence W. Holm */
/****************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <sgtty.h>
#include "ic.h"
static struct sgttyb saved_mode;
static struct tchars saved_chars;
/****************************************************************/
/* */
/* Save_Term() */
/* */
/* Save the current terminal characteristics. */
/* */
/****************************************************************/
Save_Term()
{
ioctl( 0, TIOCGETP, &saved_mode );
ioctl( 0, TIOCGETC, (struct sgttyb *) &saved_chars );
}
/****************************************************************/
/* */
/* Set_Term() */
/* */
/* Set up the terminal characteristics for ic. */
/* */
/****************************************************************/
Set_Term()
{
struct sgttyb ic_mode;
struct tchars ic_chars;
ic_mode = saved_mode;
ic_chars = saved_chars;
/* No tab expansion, no echo, cbreak mode */
ic_mode.sg_flags = ic_mode.sg_flags & ~XTABS & ~ECHO | CBREAK;
/* Change the interrupt character to ^C, ignore ^S & ^Q */
ic_chars.t_intrc = '\003';
ic_chars.t_startc = '\377';
ic_chars.t_stopc = '\377';
ioctl( 0, TIOCSETP, &ic_mode );
ioctl( 0, TIOCSETC, (struct sgttyb *) &ic_chars );
}
/****************************************************************/
/* */
/* Reset_Term() */
/* */
/* Restore the terminal characteristics. */
/* */
/****************************************************************/
Reset_Term()
{
ioctl( 0, TIOCSETP, &saved_mode );
ioctl( 0, TIOCSETC, (struct sgttyb *) &saved_chars );
}
/****************************************************************/
/* */
/* Get_Char() */
/* */
/* Return the next input character. Upper case */
/* is mapped to lower case. Escape sequences */
/* are mapped to special codes (msb set). */
/* */
/****************************************************************/
int Get_Char()
{
int c;
/* fflush() used because Minix does not automatically */
/* flush the output. */
fflush( stdout );
if ( (c = Getc()) == EOF )
return( EOF );
c &= 0x7f;
if ( isupper(c) )
return( tolower(c) );
if ( c == ESCAPE )
if ( (c=Getc()) != '[' )
{
ungetc( c, stdin );
return( ESCAPE );
}
else
{
c = Getc() | 0x80;
if ( c == ESC_HOME || c == ESC_UP || c == ESC_PGUP ||
c == ESC_LEFT || c == ESC_5 || c == ESC_RIGHT ||
c == ESC_END || c == ESC_DOWN || c == ESC_PGDN ||
c == ESC_PLUS || c == ESC_MINUS )
return( c );
else
return( ESCAPE );
}
return( c );
}
/****************************************************************/
/* */
/* Init_Getc( argc, argv ) */
/* */
/* Give Getc() references to the command line */
/* arguments. */
/* */
/****************************************************************/
static int args_remaining;
static char **args_pointer;
static int args_index;
Init_Getc( argc, argv )
int argc;
char *argv[];
{
args_remaining = argc - 1;
args_pointer = &argv[1];
args_index = 0;
}
/****************************************************************/
/* */
/* Getc() */
/* */
/* Get the next input character from the command */
/* line if there is some more, else from stdin. */
/* */
/****************************************************************/
int Getc()
{
int c;
if ( args_remaining > 0 )
if ( (c = args_pointer[ 0 ][ args_index++ ]) == '\0' )
{
--args_remaining;
++args_pointer;
args_index = 0;
if ( args_remaining > 0 )
return( '\n' );
}
else
return( c );
return( getchar() );
}
/****************************************************************/
/* */
/* Get_Base( character ) */
/* */
/* Return an appropriate base number for the */
/* given character code. Used by 'i' and 'o'. */
/* */
/****************************************************************/
int Get_Base( code )
char code;
{
switch ( code )
{
case 'h' : return( HEXADECIMAL );
case 'd' : return( DECIMAL );
case 'o' : return( OCTAL );
case 'b' : return( BINARY );
case 'a' : return( ASCII );
default : return( ERROR );
}
}

View File

@@ -0,0 +1,472 @@
/****************************************************************/
/* */
/* 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();
}
}