/*
*   Pseudoverb Functions for the TISAN Interpreter
*/

#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <dos.h>
#include <errno.h>
#include <process.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdarg.h>
#include <malloc.h>

#include "MAIN.H"

#define Pvstrnm 18

struct DEVICES HARDWARE;

short PUTADV(char *);
short GETADV(char *);
char *FNAME(short);

short Cls(void);

short PROCESS(void);
void CURSOR(short,short,short,short);
void BOX(short,short,short,short,short,short);
void SETMODE(short,short);
void BEEP(void);
void PVINIT(void);
short  PVERBCHK(char *);
short  PVERB(short);

short  Setwin(void);
short  Go(void);
short  Put(void);
short  Get(void);
short  Rename(void);
short  Delete(void);
short  Help(void);
short  Copy(void);
short  Catalog(void);
short  Run(void);
short  Dos(void);
short  Spawn(void);
short  Gethead(void);
short  Puthead(void);
short  Rem(void);
short  Wait(void);
short  Setpoint(void);

short  CALLDOS(void);
short  PUTMSG(FILE *,short);
short  PUTSTR(char *, FILE *);
void PRINTADV(char,FILE *);
short  NEWPOS(char,short *,short *,short *,short,
              short,short *,short *,short *,short *,short*);
short Inputs(char *);
void Encode(char *,...);

extern char far *SCREEN;
extern double TRANGE[2], YRANGE[2], ZRANGE[2];
extern double TMAJOR[2], YMAJOR[2], ZMAJOR[2];
extern double PARMS[10], POINT[2], ZFACTOR[2];
extern short WINDOW[4];
extern char TASKNAME[9];
extern char INNAME[_MAX_FNAME],  INCLASS[_MAX_EXT-1], INPATH[_MAX_DRIVE+_MAX_DIR-1];
extern char IN2NAME[_MAX_FNAME], IN2CLASS[_MAX_EXT-1], IN2PATH[_MAX_DRIVE+_MAX_DIR-1];
extern char IN3NAME[_MAX_FNAME], IN3CLASS[_MAX_EXT-1], IN3PATH[_MAX_DRIVE+_MAX_DIR-1];
extern char OUTNAME[_MAX_FNAME], OUTCLASS[_MAX_EXT-1], OUTPATH[_MAX_DRIVE+_MAX_DIR-1];
extern char TFORMAT[24], YFORMAT[24], ZFORMAT[24];
extern char PARITY[6], DEVICE[5];
extern char TLABEL[133], YLABEL[133], ZLABEL[133], TITLE[133];
extern double FACTOR;
extern short CODE, BAUD, STOPBITS, DATABITS, ITYPE;
extern short TMINOR, YMINOR, ZMINOR, FRAME, BORDER, QUIET, LogFlag;
extern long COLOR;

extern BOOL InterruptFlag;

extern union REGS REGISTER;
extern char ILINE[];
extern char *JPNTR, *KPNTR;
extern short MATCH;
extern short ERRTYPE, ECHO;

extern char *MSP[];

char *PVERBSTR[Pvstrnm];

/******************************************
** Arrays for the Full Path for the TISAN
** Program on startup so wew know where to
** find the INPUTS and RUN files.
*/
extern char TisanDrive[], TisanDir[];

/*
** Character strings used throughout the program
*/
extern char *NullString;
extern char *Space;
extern char *CrLf;

/*********************************************************************
*
* Initialize PSERDOVERBS
*
*/
void PVINIT()
   {
   PVERBSTR[0]  = "GO";
   PVERBSTR[1]  = "INPUTS";
   PVERBSTR[2]  = "DELETE";
   PVERBSTR[3]  = "RENAME";
   PVERBSTR[4]  = "CATALOG";
   PVERBSTR[5]  = "COPY";
   PVERBSTR[6]  = "GET";
   PVERBSTR[7]  = "PUT";
   PVERBSTR[8]  = "HELP";
   PVERBSTR[9]  = "RUN";
   PVERBSTR[10] = "DOS";
   PVERBSTR[11] = "SETWIN";
   PVERBSTR[12] = "GETHEAD";
   PVERBSTR[13] = "PUTHEAD";
   PVERBSTR[14] = "REM";
   PVERBSTR[15] = "WAIT";
   PVERBSTR[16] = "SETPOINT";
   PVERBSTR[17] = "SPAWN";
   return;
   }

/*********************************************************************
* Pseudo Verb Go
*
* Spawn a task from disk
*
*/
short Go()
   {
   char path[_MAX_PATH];
   short ERRFLAG=0;
   char TSK[9];

   if (!*JPNTR) JPNTR = TASKNAME;
   *(JPNTR+8) = (char)0;
   if (PUTADV(JPNTR)) return(1);

   _makepath(path,TisanDrive,TisanDir,JPNTR,".EXE");

   ERRFLAG = spawnlp(P_WAIT,path,path,NULL);

   if (ERRFLAG < 0)
      {
      printf(MSP[1]);
      switch (errno)
         {
         case E2BIG:
            printf(MSP[5]);
            break;
         case EINVAL:
            printf(MSP[12]);
            break;
         case ENOENT:
            printf("Task '%s' Not Found\n",JPNTR);
            break;
         case ENOEXEC:
            printf(MSP[14]);
            break;
         case ENOMEM:
            printf(MSP[10],"Task");
         }
      BEEP();
      }
   else
      {
      if (ERRFLAG)
         {
         if ((ERRFLAG == 256) || (ERRFLAG == 3))
            printf("%sTask '%s' ABORTS!\n",MSP[1],JPNTR);
         else
            {
            printf("%s'%s' Dies of Unnatural Causes\n",MSP[1],JPNTR);
            BEEP();
            }
         }
      else
         printf("%s'%s' Successfully Completes\n",MSP[1],JPNTR);
      }

   return(ERRFLAG);
   }

/*********************************************************************
* Pseudo Verb Put
*
* Put Adverbs to disk
*
*/
short Put()
   {
   if (!*JPNTR) JPNTR = TASKNAME;
   return(PUTADV(JPNTR));
   }

/*********************************************************************
* Pseudo Verb Get
*
* Get Adverbs from disk
*
*/
short Get()
   {
   char STRING[9];
   short  ERRVAL;

   strcpy(STRING,TASKNAME);
   if (!*JPNTR)
      {
      ERRVAL = GETADV(TASKNAME);
      strcpy(TASKNAME,STRING);
      }
   else
      ERRVAL = GETADV(JPNTR);
   return(ERRVAL);
   }

/*********************************************************************
* Pseudo Verb Rename
*
* Rename a disk file
*
*/
short Rename()
   {
   char *FROMFILE, *TOFILE;
   short ERRFLAG;

   FROMFILE = strtok(JPNTR," ,");
   TOFILE = strtok(NULL," ,");
   if ((!FROMFILE) || (!TOFILE))
      {
      printf(MSP[11]);
      return(1);
      }
   ERRFLAG = rename(TOFILE,FROMFILE);
   if (ERRFLAG)
      {
      printf(MSP[1]);
      switch (errno)
         {
         case EACCES:
            printf("File '%s' could not be created\n",TOFILE);
            break;
         case ENOENT:
            printf(MSP[9],FROMFILE);
            break;
         case EXDEV:
            printf("Unable to RENAME accross devices\n");
         }
      }
   return(ERRFLAG);
   }

/*********************************************************************
* Pseudo Verb Delete
*
* Delete a disk file
* Always returns zero unless no argument is given
*
*/
short Delete()
   {
   if (!*JPNTR)
      {
      printf(MSP[11]);
      return(1);
      }

  if (unlink(JPNTR))
     {
     printf(MSP[1]);
     switch (errno)
        {
        case EACCES:
           printf("File '%s' is read only\n",JPNTR);
           break;
        case ENOENT:
           printf(MSP[9],JPNTR);
        }
     }
  return(0);
  }

/*********************************************************************
* Pseudo Verb Help
*
* Print some help
*
*/
short Help()
   {
   FILE *HELPSTR;
   long PL, PL2;
   unsigned short LEN;
   char C,TSK[8], FLAG=0;
   char path[_MAX_PATH];

   LEN = strlen(JPNTR);
   if (!LEN)
      {
      JPNTR = "HELP";
      LEN = 4;
      }

   _makepath(path,TisanDrive,TisanDir,"TISAN",".HLP");

   if (!(HELPSTR = fopen(path,"rb")))
      {
      printf("%s%sTISAN.HLP\n",MSP[1],MSP[7]);
      return(1);
      }

   printf(CrLf);
   do {
      fread(TSK,1,8,HELPSTR);
      fread(&PL,4,1,HELPSTR);
      if (!strncmp(JPNTR,TSK,LEN))
         {
         PL2=ftell(HELPSTR);
         FLAG = (char)1;
         fseek(HELPSTR,PL,0);
         do {
            C = fgetc(HELPSTR);
            if (C) printf("%c",C);
            }
         while ((C) && (!InterruptFlag));
         printf(CrLf);
         fseek(HELPSTR,PL2,0);
         }
      }
   while ((TSK[0]) && (!InterruptFlag));
   fclose(HELPSTR);
   if (!FLAG) printf("%sSorry, No Help Available for '%s'\n",MSP[1],JPNTR);
   return(0);
   }

void DecodeEntry(FileEntry)
struct find_t *FileEntry;
   {
   Encode("%13s  %8ld  ",FileEntry->name,FileEntry->size);
   /* Date mm/dd/yyyy */
   printf("%02d/",(((short)FileEntry->wr_date)>>5)&15);
   printf("%02d/",FileEntry->wr_date&31);
   printf("%4d  ",((((short)FileEntry->wr_date)>>9)&127)+1980);
   /* Time HH:MM:SS */
   printf("%02d:",(((short)FileEntry->wr_time)>>11)&31);
   printf("%02d:",(((short)FileEntry->wr_time)>5)&63);
   printf("%02d\n",FileEntry->wr_time&31);
   return;
   }

/*********************************************************************
* Pseudo Verb Catalog
*
* Display a disk directory
*
*/
short Catalog()
   {
   int Count=0;
   struct find_t FileEntry;
   struct diskfree_t DiskSpace;
   char cDrive;
   char DefaultDrive[_MAX_DRIVE], DefaultDir[_MAX_DIR];
   char DefaultExt[_MAX_EXT];
   char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
   char path[_MAX_PATH];

   _splitpath(INPATH,DefaultDrive,DefaultDir,fname,ext);
   strcat(DefaultDir,fname); /* if Trailing slash is missing */
   _splitpath(JPNTR,drive,dir,fname,ext);
   if (!*drive) strcpy(drive,DefaultDrive);
   if (!*dir) strcpy(dir,DefaultDir);
   if (!*fname) strcpy(fname,"*");
   if (!*ext) strcpy(ext,INCLASS);
   if (!*ext) strcpy(ext,"*");

   cDrive = *strupr(drive);
   if (cDrive) cDrive -= '@';

   _makepath(path,drive,dir,fname,ext);
   Encode("Catalog for '%s'\n",strupr(path));

   if (!_dos_findfirst(path,_A_NORMAL,&FileEntry))
      {
      Encode("    Filename       Size    Date        Time\n");
      DecodeEntry(&FileEntry);
      ++Count;
      }

   while(!_dos_findnext(&FileEntry))
      {
      DecodeEntry(&FileEntry);
      ++Count;
      }

   if (!Count)
      Encode("No Files Matching '%s'\n",path);
   else
      Encode("%d File(s) Found\n",Count);

   _dos_getdiskfree(cDrive,&DiskSpace);

   Encode("%ld Bytes Free\n",(long)DiskSpace.avail_clusters      *
                             (long)DiskSpace.sectors_per_cluster *
                             (long)DiskSpace.bytes_per_sector);

   return(0);
   }

/*********************************************************************
* Pseudo Verb Copy
*
* Copy a disk files
*
*/
short Copy()
   {
   char *FROMFILE, *TOFILE, *CPNTR, *MPNTR;
   FILE *INSTR, *OUTSTR;
   short ERRFLAG=0;
   char frompath[_MAX_PATH], fromdrive[_MAX_DRIVE], fromdir[_MAX_DIR];
   char fromfname[_MAX_FNAME], fromext[_MAX_EXT];
   char topath[_MAX_PATH], todrive[_MAX_DRIVE], todir[_MAX_DIR];
   char tofname[_MAX_FNAME], toext[_MAX_EXT];
   size_t MemorySize, N;
   char *CopyBuffer, CharBuffer;

   MemorySize = _memmax();
   CopyBuffer = malloc(MemorySize);
   if (!CopyBuffer)
      {
      CopyBuffer = &CharBuffer;
      MemorySize = 1;
      Encode("WARNING -- Memory Allocation Failure.\n");
      }
   
   FROMFILE = strtok(JPNTR," ,");
   TOFILE = strtok(NULL," ,");

   if (!FROMFILE)
      {
      Encode("Missing File Specifiers.\n");
      return(1);
      }

   _splitpath(FROMFILE,fromdrive,fromdir,fromfname,fromext);
   _splitpath(TOFILE,todrive,todir,tofname,toext);

   if (!*todrive) strcpy(todrive,fromdrive);
   if (!*todir) strcpy(todir,fromdir);
   if (!*tofname) strcpy(tofname,fromfname);
   if (!*toext) strcpy(toext,fromext);

   _makepath(frompath,fromdrive,fromdir,fromfname,fromext);
   _makepath(topath,todrive,todir,tofname,toext);

   if (!strcmp(strupr(frompath),strupr(topath)))
      {
      Encode("Cannot Copy File into Itself\n");
      return(1);
      }

   if (!(INSTR = fopen(frompath,"rb")))
      {
      perror(MSP[3]);
      return(1);
      }

   if ((OUTSTR = fopen(topath,"wb")))
      {
      Encode("Copying from '%s' to '%s'\n",frompath,topath);

      do {
         N = fread(CopyBuffer,1,MemorySize,INSTR);
         fwrite(CopyBuffer,1,N,OUTSTR);
         if (ferror(INSTR) || ferror(OUTSTR))
            {
            perror(MSP[3]);
            ERRFLAG = 1;
            break;
            }
         }
      while (N == MemorySize);
      fclose(OUTSTR);
      }
   else
      {
      perror(MSP[3]);
      ERRFLAG = 1;
      }

   if (CopyBuffer != &CharBuffer) free(CopyBuffer);

   fclose(INSTR);
   return(ERRFLAG);
   }

/*********************************************************************
* Pseudo Verb Run
*
* Execute a RUN file
*
*/
short Run()
   {
   FILE *FPNTR;
   long CURPOS;
   short I;
   char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
   char path[_MAX_PATH];

   _splitpath(JPNTR,drive,dir,fname,ext);

   if (!*dir && !*drive)
      {
      strcpy(dir,TisanDir);
      strcat(dir,"RUN\\");
      strcpy(drive,TisanDrive);
      }

   _makepath(path,drive,dir,fname,".RUN");

   if ((FPNTR = fopen(path,"rb")) == NULL)
      {
      printf(MSP[6],MSP[1],path);
      return(1);
      }

   while (!feof(FPNTR) && !InterruptFlag)
      {
      if (kbhit() && (getch() == (char)26))
         {
         CURPOS = ftell(FPNTR);
         CALLDOS();
         fseek(FPNTR,CURPOS,0);
         }
      memset(ILINE,0,256);
      I = 0;
      do ILINE[0] = fgetc(FPNTR);
      while ((!feof(FPNTR)) && (ILINE[0]<33));
      if (feof(FPNTR)) break;
      while ((!feof(FPNTR)) && (ILINE[I] > (char)31))
         ILINE[++I] = fgetc(FPNTR);
      ILINE[I] = 0;
      if (ECHO) printf("%s>%s\n",MSP[0],ILINE);
      if (ferror(FPNTR))
         {
         printf("%s%sFile '%s'\n",MSP[1],MSP[8],path);
         perror(MSP[3]);
         fclose(FPNTR);
         BEEP();
         return(1);
         }
      CURPOS = ftell(FPNTR);
      I = PROCESS();
      fseek(FPNTR,CURPOS,0);
      if (I<0) break; /* End Command */
      else if (I>0)
         {
         fclose(FPNTR);
         return(1);
         }
      }
   fclose(FPNTR);
   memset(ILINE,(char)0,256);
   return(0);
   }

/*********************************************************************
* Pseudo Verb Dos
*
* Execute a DOS command
*
*/
short Dos()
   {
   short ERRFLAG=0;

   errno=0;

   if (!*JPNTR)
      ERRFLAG = CALLDOS();
   else
      ERRFLAG = system(JPNTR);

   if (ERRFLAG)
      {
      switch (errno)
         {
         case E2BIG:
            printf("%sArgument List too Long\n",MSP[1]);
            break;
         case ENOENT:
            printf("%sFile COMMAND.COM not Found\n",MSP[1]);
            break;
         case ENOEXEC:
            printf("%sInvalid COMMAND.COM File\n",MSP[1]);
            break;
         case ENOMEM:
            printf("%sNot Enough Memory to Execute Command\n",MSP[1]);
            break;
         default:
            ERRFLAG=0;
         }
      }

   return(ERRFLAG);
   }

/*********************************************************************
* Pseudo Verb Spawn
*
* Spawn a Child Process
*
*/
short Spawn()
   {
   short ERRFLAG=0;
   ERRFLAG = spawnlp(P_WAIT,JPNTR,JPNTR,NULL);

   if (ERRFLAG < 0)
      {
      printf(MSP[1]);
      switch (errno)
         {
         case E2BIG:
            printf(MSP[5]);
            break;
         case EINVAL:
            printf(MSP[12]);
            break;
         case ENOENT:
            printf(MSP[9],JPNTR);
            break;
         case ENOEXEC:
            printf(MSP[14]);
            break;
         case ENOMEM:
            printf(MSP[10],"File");
         }
      }
   return(ERRFLAG);
   }

/*********************************************************************
*
* Pseudo Verb SETWIN to set the plotting window
*
*/
short Setwin()
   {
   char C;
   short XLOC, YLOC, SXMAX, SYMAX;
   short XP1, YP1, XP2, YP2, X, Y, BFLAG=0;
   unsigned short I;
   short W0, W1, W2, W3, LOOPFLG, WHATSIDE=1;
   FILE *STREAM;
   struct FILEHDR FileHeader;

   if (HARDWARE.scrn == HERC_scrn)
      SYMAX = 347;
   else
      {
      if ((HARDWARE.scrn == CGA_scrn) || (HARDWARE.scrn == DUAL_scrn))
         SYMAX = 199;
      else
         {
         printf(MSP[13]);
         return(1);
         }
      }

   WINDOW[1] = SYMAX - WINDOW[1];
   WINDOW[3] = SYMAX - WINDOW[3];
   W0 = Min(WINDOW[0],WINDOW[2]);
   W1 = Max(WINDOW[1],WINDOW[3]);
   W2 = Max(WINDOW[0],WINDOW[2]);
   W3 = Min(WINDOW[1],WINDOW[3]);
   STREAM = fopen(JPNTR,"rb");
   if (STREAM)
      {
      fread(&FileHeader,sizeof(struct FILEHDR),1,STREAM);
      switch (FileHeader.type)
         {
         case CGA_HiResImage:
            if ((HARDWARE.scrn != CGA_scrn) && 
                (HARDWARE.scrn != DUAL_scrn))
               {
               STREAM = 0;
               break;
               }
            SETMODE(6,0);
            SXMAX = 639;
            for (I=0;I<0x4000;++I,++SCREEN) *SCREEN = fgetc(STREAM);
            break;
         case CGA_LoResImage:
            if ((HARDWARE.scrn != CGA_scrn) && 
                (HARDWARE.scrn != DUAL_scrn))
               {
               STREAM = 0;
               break;
               }
            I = Min(156,(int)COLOR);
            I = Max(1,I);
            SETMODE(4,I);
            SXMAX = 319;
            for (I=0;I<0x4000;++I,++SCREEN) *SCREEN = fgetc(STREAM);
            break;
         case HERC_MonoImage:
            if (HARDWARE.scrn != HERC_scrn)
               {
               STREAM = 0;
               break;
               }
            SETMODE(7,0);
            SXMAX = 719;
            for (I=0;I<0x8000;++I,++SCREEN) *SCREEN = fgetc(STREAM);
            break;
         default:
            fclose(STREAM);
            STREAM = 0;
         }
      }

   if (!STREAM)
      {
      if (HARDWARE.scrn == HERC_scrn)
         {
         SETMODE(7,0);
         SXMAX = 719;
         }
      else if (COLOR)
         {
         I = Min(156,(int)COLOR);
         SETMODE(4,I);
         SXMAX = 319;
         }
      else
         {
         SXMAX = 639;
         SETMODE(6,0);
         }
      }
   XLOC = W0;
   YLOC = W1;
   CURSOR(XLOC,YLOC,SXMAX,SYMAX);

   do {
      LOOPFLG = 1;
      C = getch();
      if (!C) C = getch();
      CURSOR(XLOC,YLOC,SXMAX,SYMAX);
      if (BFLAG==1)
         BOX(W0,W1,XLOC,YLOC,SXMAX,SYMAX);
      else if (BFLAG==2)
         BOX(XLOC,YLOC,W2,W3,SXMAX,SYMAX);

      LOOPFLG = 
            NEWPOS(C,&XLOC,&YLOC,&WHATSIDE,SXMAX,SYMAX,&W0,&W1,&W2,&W3,&BFLAG);
      if (YLOC < 0) YLOC = SYMAX + YLOC + 1;
      if (XLOC < 0) XLOC = SXMAX + XLOC + 1;
      if (XLOC > SXMAX) XLOC = (XLOC-SXMAX) - 1;
      if (YLOC > SYMAX) YLOC = (YLOC-SYMAX) - 1;
      CURSOR(XLOC,YLOC,SXMAX,SYMAX);
      if (BFLAG==1)
         BOX(W0,W1,XLOC,YLOC,SXMAX,SYMAX);
      else if (BFLAG==2)
         BOX(XLOC,YLOC,W2,W3,SXMAX,SYMAX);
      }
   while (LOOPFLG > 0);

   CURSOR(XLOC,YLOC,SXMAX,SYMAX);
   if (BFLAG==1)
      BOX(W0,W1,XLOC,YLOC,SXMAX,SYMAX);
   else if (BFLAG==2)
      BOX(XLOC,YLOC,W2,W3,SXMAX,SYMAX);
   if (!LOOPFLG)
      {
      WINDOW[0] = Min(W0,W2);
      WINDOW[1] = Max(W1,W3);
      WINDOW[2] = Max(W0,W2);
      WINDOW[3] = Min(W1,W3);
      }
   WINDOW[1] = SYMAX - WINDOW[1];
   WINDOW[3] = SYMAX - WINDOW[3];
   Cls();
   if (!LOOPFLG)
      {
      printf("%sWindow Set to ",MSP[1]);
      printf("%d, %d, %d, %d\n",WINDOW[0],WINDOW[1],WINDOW[2],WINDOW[3]);
      }
   return(0);
   }

/*********************************************************************
*
* Update Cursor position
*
*/
short NEWPOS(C,XLOC,YLOC,WHATSIDE,SXMAX,SYMAX,W0,W1,W2,W3,BFLAG)
char C;
short *XLOC, *YLOC, *WHATSIDE, SXMAX, SYMAX, *W0, *W1, *W2, *W3, *BFLAG;
   {
   short LOOPFLG;
   switch ((unsigned char)C)
      {
      case 71:
         --*XLOC;
         --*YLOC;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 72:
         --*YLOC;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 73:
         ++*XLOC;
         --*YLOC;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 75:
         --*XLOC;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 77:
         ++*XLOC;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 79:
         --*XLOC;
         ++*YLOC;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 80:
         ++*YLOC;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 81:
         ++*YLOC;
         ++*XLOC;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 55:
         *XLOC -= 10;
         *YLOC -= 9;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 56:
         *YLOC -= 9;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 57:
         *YLOC -= 9;
         *XLOC += 10;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 52:
         *XLOC -= 10;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 54:
         *XLOC += 10;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 49:
         *YLOC += 9;
         *XLOC -= 10;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 50:
         *YLOC += 9;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 51:
         *YLOC += 9;
         *XLOC += 10;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 119:
         *YLOC = 0;
         *XLOC = 0;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 132:
         *YLOC = 0;
         *XLOC = SXMAX;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 117:
         *YLOC = SYMAX;
         *XLOC = 0;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 118:
         *YLOC = SYMAX;
         *XLOC = SXMAX;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 115:
      case 116:
         *YLOC = SYMAX/2;
         *XLOC = SXMAX/2;
         *WHATSIDE = abs(*WHATSIDE);
         break;
      case 27:
         LOOPFLG = -1;
         break;
      case 13:
         BEEP();
         if (*WHATSIDE == 1)
            {
            *W0 = *XLOC;
            *W1 = *YLOC;
            *XLOC = *W2;
            *YLOC = *W3;
            *WHATSIDE = 2;
            *BFLAG = 1;
            }
         else if (*WHATSIDE == 2)
            {
            *W2 = *XLOC;
            *W3 = *YLOC;
            *XLOC = *W0;
            *YLOC = *W1;
            *WHATSIDE = -1;
            *BFLAG = 2;
            }
         else LOOPFLG = 0;
      }
   return(LOOPFLG);
   }

/*********************************************************************
* Pseudoverb Gethead
*
* Get header and put into TITLE and TRANGE
*
*/
short Gethead()
   {
   FILE *INSTR;
   short ERRFLAG = 0;
   struct FILEHDR FileHeader;

   if (!*JPNTR) JPNTR = FNAME(0);
   if ((INSTR = fopen(JPNTR,"rb")) == NULL)
      {
      printf(MSP[6],MSP[1],JPNTR);
      return(1);
      }

   fread(&FileHeader,sizeof(struct FILEHDR),1,INSTR);
   switch (FileHeader.type)
      {
      case R_Data:
        printf("%sREAL Time Series File\n",MSP[1]);
        break;
      case TR_Data:
        printf("%sREAL Time Stamped Data File\n",MSP[1]);
        break;
      case X_Data:
        printf("%sCOMPLEX Time Series File\n",MSP[1]);
        break;
      case TX_Data:
        printf("%sCOMPLEX Time Stamped Data File\n",MSP[1]);
        break;
      case CGA_HiResImage:
        printf("%sCGA High Resolution Image\n",MSP[1]);
        break;
      case CGA_LoResImage:
        printf("%sCGA Low Resolution Image\n",MSP[1]);
        break;
      case HERC_MonoImage:
        printf("%sHercules Image\n",MSP[1]);
        break;
      case EGA_Image:
        printf("%sEGA Image\n",MSP[1]);
        break;
      case PGA_Image:
        printf("%sPGA Image\n",MSP[1]);
        break;
      case EPSN_Image:
        printf("%sEPSON Printer Image\n",MSP[1]);
        break;
      case HPLJ_Image:
        printf("%sLaser Jet Printer Image\n",MSP[1]);
        break;
      default:
        printf("%sUnknown File Type\n",MSP[1]);
        ERRFLAG=1;
      }

   if (ferror(INSTR))
      {
      perror(MSP[3]);
      ERRFLAG=1;
      }
   if (!ERRFLAG)
      {
      TRANGE[0] = FileHeader.m;
      TRANGE[1] = FileHeader.b;
      }
   fclose(INSTR);
   return(ERRFLAG);
   }

/*********************************************************************
* Pseudoverb Puthead
*
* Put header from TITLE and TRANGE
*
*/
short Puthead()
   {
   FILE *OUTSTR;
   short ERRFLAG = 0;
   char DATTYP;
   struct FILEHDR FileHeader;

   if (!*JPNTR) JPNTR = FNAME(1);
   if ((OUTSTR = fopen(JPNTR,"r+b")) == NULL)
      {
      printf(MSP[6],MSP[1],JPNTR);
      return(1);
      }

   fread(&FileHeader,sizeof(struct FILEHDR),1,OUTSTR); /* Read in data type */
   rewind(OUTSTR);
   FileHeader.m = TRANGE[0];
   FileHeader.b = TRANGE[1];
   fwrite(&FileHeader,sizeof(struct FILEHDR),1,OUTSTR);

   if (ferror(OUTSTR))
      {
      perror(MSP[3]);
      ERRFLAG=1;
      }

   fclose(OUTSTR);
   return(ERRFLAG);
   }

/*********************************************************************
* Pseudo Verb Rem
*
* Remark statment to ignore everyting else on the line
*
*/
short Rem()
   {
   memset(ILINE,(char)0,256);
   return(0);
   }

/*********************************************************************
* Pseudo Verb Wait
*
* Print JLINE and wait for a key press
*
*/
short Wait()
   {
   BEEP();
   while (kbhit()) getch();       /* Clear Buffer of Pending Keys */
   printf("%s%s\n",MSP[1],JPNTR);
   printf("%sPress Any Key to Continue...\n",MSP[1]);
   getch();
   return(0);
   }

/*********************************************************************
*
* Pseudo Verb SETPOINT to set POINT[]
*
*/
short Setpoint()
   {
   char C;
   short XLOC, YLOC, SXMAX, SYMAX;
   short XP1, YP1, XP2, YP2, X, Y;
   unsigned short I;
   short W0, W1, LOOPFLG;
   FILE *STREAM;
   struct FILEHDR FileHeader;

   if (HARDWARE.scrn == HERC_scrn)
      SYMAX = 347;
   else
      {
      if ((HARDWARE.scrn == CGA_scrn) || (HARDWARE.scrn == DUAL_scrn))
         SYMAX = 199;
      else
         {
         printf(MSP[13]);
         return(1);
         }
      }

   POINT[1] = SYMAX - POINT[1];
   W0 = POINT[0];
   W1 = POINT[1];
   STREAM = fopen(JPNTR,"rb");
   if (STREAM)
      {
      fread(&FileHeader,sizeof(struct FILEHDR),1,STREAM);
      switch (FileHeader.type)
         {
         case CGA_HiResImage:
            if ((HARDWARE.scrn != CGA_scrn) && 
                (HARDWARE.scrn != DUAL_scrn))
               {
               STREAM = 0;
               break;
               }
            SETMODE(6,0);
            SXMAX = 639;
            for (I=0;I<0x4000;++I,++SCREEN) *SCREEN = fgetc(STREAM);
            break;
         case CGA_LoResImage:
            if ((HARDWARE.scrn != CGA_scrn) && 
                (HARDWARE.scrn != DUAL_scrn))
               {
               STREAM = 0;
               break;
               }
            I = Min(156,(int)COLOR);
            I = Max(1,I);
            SETMODE(4,I);
            SXMAX = 319;
            for (I=0;I<0x4000;++I,++SCREEN) *SCREEN = fgetc(STREAM);
            break;
         case HERC_MonoImage:
            if (HARDWARE.scrn != HERC_scrn)
               {
               STREAM = 0;
               break;
               }
            SETMODE(7,0);
            SXMAX = 719;
            for (I=0;I<0x8000;++I,++SCREEN) *SCREEN = fgetc(STREAM);
            break;
         default:
            fclose(STREAM);
            STREAM = 0;
         }
      }
   if (!STREAM)
      {
      if (HARDWARE.scrn == HERC_scrn)
         {
         SETMODE(7,0);
         SXMAX = 719;
         }
      else if (COLOR)
         {
         I = Min(156,(int)COLOR);
         SETMODE(4,I);
         SXMAX = 319;
         }
      else
         {
         SXMAX = 639;
         SETMODE(6,0);
         }
      }
   XLOC = W0;
   YLOC = W1;
   CURSOR(XLOC,YLOC,SXMAX,SYMAX);
   do {
      LOOPFLG = 1;
      C = getch();
      if (!C) C = getch();
      CURSOR(XLOC,YLOC,SXMAX,SYMAX);
      switch ((unsigned char)C)
         {
         case 71:
            --XLOC;
            --YLOC;
            break;
         case 72:
            --YLOC;
            break;
         case 73:
            ++XLOC;
            --YLOC;
            break;
         case 75:
            --XLOC;
            break;
         case 77:
            ++XLOC;
            break;
         case 79:
            --XLOC;
            ++YLOC;
            break;
         case 80:
            ++YLOC;
            break;
         case 81:
            ++YLOC;
            ++XLOC;
            break;
         case 55:
            XLOC -= 10;
            YLOC -= 9;
            break;
         case 56:
            YLOC -= 9;
            break;
         case 57:
            YLOC -= 9;
            XLOC += 10;
            break;
         case 52:
            XLOC -= 10;
            break;
         case 54:
            XLOC += 10;
            break;
         case 49:
            YLOC += 9;
            XLOC -= 10;
            break;
         case 50:
            YLOC += 9;
            break;
         case 51:
            YLOC += 9;
            XLOC += 10;
            break;
         case 119:
            YLOC = 0;
            XLOC = 0;
            break;
         case 132:
            YLOC = 0;
            XLOC = SXMAX;
            break;
         case 117:
            YLOC = SYMAX;
            XLOC = 0;
            break;
         case 118:
            YLOC = SYMAX;
            XLOC = SXMAX;
            break;
         case 115:
         case 116:
            YLOC = SYMAX/2;
            XLOC = SXMAX/2;
            break;
         case 27:
            LOOPFLG = -1;
            break;
         case 13:
            BEEP();
            W0 = XLOC;
            W1 = YLOC;
            LOOPFLG=0;
            break;
         }
      if (XLOC < 0) XLOC = SXMAX + XLOC + 1;
      if (YLOC < 0) YLOC = SYMAX + YLOC + 1;
      if (XLOC > SXMAX) XLOC = (XLOC-SXMAX) - 1;
      if (YLOC > SYMAX) YLOC = (YLOC-SYMAX) - 1;
      CURSOR(XLOC,YLOC,SXMAX,SYMAX);
      }
   while (LOOPFLG > 0);

   CURSOR(XLOC,YLOC,SXMAX,SYMAX);
   if (!LOOPFLG)
      {
      POINT[0] = W0;
      POINT[1] = W1;
      }
   POINT[1] = SYMAX - POINT[1];
   Cls();
   if (!LOOPFLG)
      {
      printf("%sPOINT Set to ",MSP[1]);
      printf("%G, %G\n",POINT[0],POINT[1]);
      }
   return(0);
   }

/*********************************************************************
*
* Search for a PSEUDOVERB
*
*/
short PVERBCHK(PNTR)
char *PNTR;
   {
   unsigned short I, LEN;
   short PVRB=0;

   if ((LEN = strlen(strupr(PNTR))) == 0) return(0);

   if (MATCH < 0)
      {
      for (I=0;I<Pvstrnm;++I)
         {
         if (!strncmp(PVERBSTR[I],PNTR,LEN))
            printf("%sCould be %-.8s\n",MSP[1],PVERBSTR[I]);
         }
      return(0);
      }

   for (I=0;I<Pvstrnm;++I)
      {
      if (!strncmp(PVERBSTR[I],PNTR,LEN))
         {
         PVRB = I+1;
         ++MATCH;
         if (LEN == strlen(PVERBSTR[I])) /* Exact Match */
            {
            MATCH = 1;
            break;
            }
         }
      }

   return(PVRB);
   }

/*********************************************************************
*
* Process a PSEUDOVERB , JPNTR has the argument
*
*/
short PVERB(N)
short N;
   {
   unsigned short LEN, I, J;
   short RVAL=0, F1, F2=0;

   LEN = strlen(JPNTR); /* Find Number of Arguments 0,1,>1 */
   for (I=0;I<LEN;++I)
      if (isspace(*(JPNTR + I)) || (*(JPNTR+I) == ',')) {F1 = I; break;}
   while(isspace(*(JPNTR + I))) ++I;
   for (J=I;J<LEN;++J)
      if (isspace(*(JPNTR + J)) || (*(JPNTR+J) == ',')) {++F2; break;}
   while(isspace(*(JPNTR + J))) ++J;

   strupr(JPNTR);
   if ((N != 4) && (N != 6) && (N != 11) && (N != 15) && (N != 16))
      {
      if (F2)
         {
         printf("%sToo many arguments for PSEUDOVERB\n",MSP[1]);
         return(1);
         }
      }

   switch (N)
      {
      case 1:
         RVAL = Go();
         break;
      case 2:
         RVAL = Inputs(JPNTR);
         break;
      case 3:
         RVAL = Delete();
         break;
      case 4:
         RVAL = Rename();
         break;
      case 5:
         RVAL = Catalog();
         break;
      case 6:
         RVAL = Copy();
         break;
      case 7:
         RVAL = Get();
         break;
      case 8:
         RVAL = Put();
         break;
      case 9:
         RVAL = Help();
         break;
      case 10:
         RVAL = Run();
         break;
      case 11:
         RVAL = Dos();
         break;
      case 12:
         RVAL = Setwin();
         break;
      case 13:
         RVAL = Gethead();
         break;
      case 14:
         RVAL = Puthead();
         break;
      case 15:
         RVAL = Rem();
         break;
      case 16:
         RVAL = Wait();
         break;
      case 17:
         RVAL = Setpoint();
         break;
      case 18:
         RVAL = Spawn();
         break;
      }
   return(RVAL);
   }

/*********************************************************************
*
* Put Adverbs to file
*
*/
short PUTADV(NAMEPNTR)
char *NAMEPNTR;
   {
   FILE *PNTR;
   short ERRFLAG=0, Trash;
   char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
   char path[_MAX_PATH];

   _splitpath(NAMEPNTR,drive,dir,fname,ext);

   if (!*dir && !*drive)
      {
      strcpy(dir,TisanDir);
      strcat(dir,"INPUTS\\");
      strcpy(drive,TisanDrive);
      }

   _makepath(path,drive,dir,fname,".INP");

   PNTR = fopen(path,"wb");
   if (PNTR)
      {
/* Double Precision Arrays */
      fwrite(TRANGE,sizeof(double),2,PNTR);
      fwrite(YRANGE,sizeof(double),2,PNTR);
      fwrite(ZRANGE,sizeof(double),2,PNTR);
      fwrite(TMAJOR,sizeof(double),2,PNTR);
      fwrite(YMAJOR,sizeof(double),2,PNTR);
      fwrite(ZMAJOR,sizeof(double),2,PNTR);
      fwrite(PARMS,sizeof(double),10,PNTR);
      fwrite(POINT,sizeof(double),2,PNTR);
      fwrite(ZFACTOR,sizeof(double),2,PNTR);
/* Short Arrays */
      fwrite(WINDOW,sizeof(short),4,PNTR);
/* Character Arrays */
          fwrite(TASKNAME, sizeof(TASKNAME),1,PNTR);
          fwrite(INNAME  , sizeof(INNAME  ),1,PNTR);
          fwrite(INCLASS , sizeof(INCLASS ),1,PNTR);
          fwrite(INPATH  , sizeof(INPATH  ),1,PNTR);
          fwrite(IN2NAME , sizeof(IN2NAME ),1,PNTR);
          fwrite(IN2CLASS, sizeof(IN2CLASS),1,PNTR);
          fwrite(IN2PATH , sizeof(IN2PATH ),1,PNTR);
          fwrite(IN3NAME , sizeof(IN3NAME ),1,PNTR);
          fwrite(IN3CLASS, sizeof(IN3CLASS),1,PNTR);
          fwrite(IN3PATH , sizeof(IN3PATH ),1,PNTR);
          fwrite(OUTNAME , sizeof(OUTNAME ),1,PNTR);
          fwrite(OUTCLASS, sizeof(OUTCLASS),1,PNTR);
          fwrite(OUTPATH , sizeof(OUTPATH ),1,PNTR);
          fwrite(TFORMAT , sizeof(TFORMAT ),1,PNTR);
          fwrite(YFORMAT , sizeof(YFORMAT ),1,PNTR);
          fwrite(ZFORMAT , sizeof(ZFORMAT ),1,PNTR);
          fwrite(PARITY  , sizeof(PARITY  ),1,PNTR);
          fwrite(DEVICE  , sizeof(DEVICE  ),1,PNTR);
          fwrite(TLABEL  , sizeof(TLABEL  ),1,PNTR);
          fwrite(YLABEL  , sizeof(YLABEL  ),1,PNTR);
          fwrite(ZLABEL  , sizeof(ZLABEL  ),1,PNTR);
          fwrite(TITLE   , sizeof(TITLE   ),1,PNTR);
/* Double Precision Variables */
      fwrite(&FACTOR,sizeof(double),1,PNTR);
/* Short Variables */
      fwrite(&CODE,sizeof(short),1,PNTR);
      fwrite(&ITYPE,sizeof(short),1,PNTR);
      fwrite(&BAUD,sizeof(short),1,PNTR);
      fwrite(&STOPBITS,sizeof(short),1,PNTR);
      fwrite(&DATABITS,sizeof(short),1,PNTR);
      fwrite(&TMINOR,sizeof(short),1,PNTR);
      fwrite(&YMINOR,sizeof(short),1,PNTR);
      fwrite(&ZMINOR,sizeof(short),1,PNTR);
      fwrite(&FRAME,sizeof(short),1,PNTR);
      fwrite(&BORDER,sizeof(short),1,PNTR);
      fwrite(&COLOR,sizeof(long),1,PNTR);
      fwrite(&QUIET,sizeof(short),1,PNTR);
      fwrite(&HARDWARE,sizeof(struct DEVICES),1,PNTR);
      fwrite(&LogFlag,sizeof(short),1,PNTR);
      if (ferror(PNTR))
         {
         printf("%sError Writing Inputs File '%s'\n",MSP[1],path);
         ERRFLAG=1;
         }
      fclose(PNTR);
      }
   else
      {
      ERRFLAG=1;
      printf("%s%sInputs File '%s'\n",MSP[1],MSP[7],path);
      }
   return(ERRFLAG);
   }

/*********************************************************************
*
* Get Adverbs from file
*
*/
short GETADV(NAMEPNTR)
char *NAMEPNTR;
   {
   FILE *PNTR;
   short ERRFLAG=0, Trash;
   static char IFLAG;
   struct DEVICES Hware;
   char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
   char path[_MAX_PATH];

   _splitpath(NAMEPNTR,drive,dir,fname,ext);

   if (!*dir && !*drive)
      {
      strcpy(dir,TisanDir);
      strcat(dir,"INPUTS\\");
      strcpy(drive,TisanDrive);
      }

   _makepath(path,drive,dir,fname,".INP");

   PNTR = fopen(path,"rb");
   if (PNTR)
      {
/* Double Precision Arrays */
      fread(TRANGE,sizeof(double),2,PNTR);
      fread(YRANGE,sizeof(double),2,PNTR);
      fread(ZRANGE,sizeof(double),2,PNTR);
      fread(TMAJOR,sizeof(double),2,PNTR);
      fread(YMAJOR,sizeof(double),2,PNTR);
      fread(ZMAJOR,sizeof(double),2,PNTR);
      fread(PARMS,sizeof(double),10,PNTR);
      fread(POINT,sizeof(double),2,PNTR);
      fread(ZFACTOR,sizeof(double),2,PNTR);
/* Short Arrays */
      fread(WINDOW,sizeof(short),4,PNTR);
/* Character Arrays */
          fread(TASKNAME, sizeof(TASKNAME),1,PNTR);
          fread(INNAME  , sizeof(INNAME  ),1,PNTR);
          fread(INCLASS , sizeof(INCLASS ),1,PNTR);
          fread(INPATH  , sizeof(INPATH  ),1,PNTR);
          fread(IN2NAME , sizeof(IN2NAME ),1,PNTR);
          fread(IN2CLASS, sizeof(IN2CLASS),1,PNTR);
          fread(IN2PATH , sizeof(IN2PATH ),1,PNTR);
          fread(IN3NAME , sizeof(IN3NAME ),1,PNTR);
          fread(IN3CLASS, sizeof(IN3CLASS),1,PNTR);
          fread(IN3PATH , sizeof(IN3PATH ),1,PNTR);
          fread(OUTNAME , sizeof(OUTNAME ),1,PNTR);
          fread(OUTCLASS, sizeof(OUTCLASS),1,PNTR);
          fread(OUTPATH , sizeof(OUTPATH ),1,PNTR);
          fread(TFORMAT , sizeof(TFORMAT ),1,PNTR);
          fread(YFORMAT , sizeof(YFORMAT ),1,PNTR);
          fread(ZFORMAT , sizeof(ZFORMAT ),1,PNTR);
          fread(PARITY  , sizeof(PARITY  ),1,PNTR);
          fread(DEVICE  , sizeof(DEVICE  ),1,PNTR);
          fread(TLABEL  , sizeof(TLABEL  ),1,PNTR);
          fread(YLABEL  , sizeof(YLABEL  ),1,PNTR);
          fread(ZLABEL  , sizeof(ZLABEL  ),1,PNTR);
          fread(TITLE   , sizeof(TITLE   ),1,PNTR);
/* Double Precision Variables */
      fread(&FACTOR,sizeof(double),1,PNTR);
/* Short Variables */
      fread(&CODE,sizeof(short),1,PNTR);
      fread(&ITYPE,sizeof(short),1,PNTR);
      fread(&BAUD,sizeof(short),1,PNTR);
      fread(&STOPBITS,sizeof(short),1,PNTR);
      fread(&DATABITS,sizeof(short),1,PNTR);
      fread(&TMINOR,sizeof(short),1,PNTR);
      fread(&YMINOR,sizeof(short),1,PNTR);
      fread(&ZMINOR,sizeof(short),1,PNTR);
      fread(&FRAME,sizeof(short),1,PNTR);
      fread(&BORDER,sizeof(short),1,PNTR);
      fread(&COLOR,sizeof(long),1,PNTR);
      fread(&QUIET,sizeof(short),1,PNTR);
      fread(&Hware,sizeof(struct DEVICES),1,PNTR);
      fread(&Trash,sizeof(short),1,PNTR);
      if (!IFLAG)
         {
         HARDWARE = Hware;
         IFLAG=1;
         }
      if (ferror(PNTR))
         {
         printf("%s%sInputs File '%s'\n",MSP[1],MSP[8],path);
         ERRFLAG=1;
         }
      fclose(PNTR);
      }
   else
      {
      ERRFLAG=1;
      printf(MSP[15],path);
      }
   return(ERRFLAG);
   }

/*********************************************************************
*
*  Make a file name and return a pointer
*
*/
char *FNAME(TYPE)
short TYPE;
   {
   static char path[_MAX_PATH];
   char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];

   switch (TYPE)
      {
      case 0:        /* Create an INfile name */
         _splitpath(INPATH,drive,dir,fname,ext);
         strcat(dir,fname);
         _makepath(path,drive,dir,INNAME,INCLASS);
         break;
      case 1:        /* Create an OUTfile name */
         if (*OUTPATH)
            strcpy(path,OUTPATH);
         else
            strcpy(path,INPATH);

         _splitpath(INPATH,drive,dir,fname,ext);
         strcat(dir,fname);

         if (*OUTNAME)
            strcpy(fname,OUTNAME);
         else
            strcpy(fname,INNAME);

         if (*OUTCLASS)
            strcpy(ext,OUTCLASS);
         else
            strcpy(ext,INCLASS);

         _makepath(path,drive,dir,fname,ext);
         
         break;
      }
   return(strupr(path));
   }

void Encode(cFormatPntr,...)
char *cFormatPntr;
   {
   va_list arg_ptr;

   va_start(arg_ptr,cFormatPntr);

   printf("TISAN   : ");
   vprintf(cFormatPntr,arg_ptr);

   va_end(arg_ptr);
   return;
   }


/*********************************************************************
*
* Get a Message From the File TISAN.IDX and Print it 
* from cloumn 44 to 80 by however-many lines
*
*/
short DisplayText(IndexTableStream)
FILE *IndexTableStream;
   {
   long PL;
   short I;
   short P;
   char C;

   if (!IndexTableStream)
      {
      printf("\nTISAN   : ");
      return(0);
      }

   I=0;
   while (I<36)
      {
      C = fgetc(IndexTableStream);
      if (!C || (C == '\n')) break;
      printf("%c",C);
      ++I;
      } /* End While */
   if (I < 36) printf(CrLf);
   return(C);
   }

/*********************************************************************
*
* Write a string to columns 22 to 41 and the message line after it
*
*/
short WriteString(StringPointer,IndexTableStream)
char *StringPointer;
FILE *IndexTableStream;
  {
  short M,N,I;
  BOOL PassFlag=FALSE;
  char C=1;

  do {
     if (!PassFlag)
        {
        N = printf("%.19s",StringPointer);
        PassFlag = TRUE;
        M = N + 1;
        }
     else
        {
        M = N = printf("%.20s",StringPointer);
        }

     if (M < 20)
        {
        ++M;
        PassFlag = -1;
        printf("'");
        }

     for (I=M;I<21;++I) printf(Space);
     if (C)
        C = (char)DisplayText(IndexTableStream);
     else
        DisplayText(NULL);
     if ((M == 20) && (PassFlag > 0))
        {
        StringPointer += N;
        printf("%13s",Space);
        }
     }
  while ((M == 20) && (PassFlag > 0));
  if (C) printf("%34s",Space);
  return(C);
  }

/*********************************************************************
*
* Print an adverb and its value
*/
void DisplayInputs(InputsAdverbToken,IndexTableStream)
unsigned char InputsAdverbToken;
FILE *IndexTableStream;
  {
  short I;
  char C=1, BUFFER[80];

  switch (InputsAdverbToken)
     {
     case 1:
        sprintf(BUFFER,"INNAME   ... '%s'",INNAME);
        Encode("%-34s",BUFFER);
        break;
     case 2:
        sprintf(BUFFER,"INCLASS  ... '%s'",INCLASS);
        Encode("%-34s",BUFFER);
        break;
     case 3:
        Encode("INPATH   ... '");
        C = WriteString(INPATH,IndexTableStream);
        break;
     case 4:
        sprintf(BUFFER,"IN2NAME  ... '%s'",IN2NAME);
        Encode("%-34s",BUFFER);
        break;
     case 5:
        sprintf(BUFFER,"IN2CLASS ... '%s'",IN2CLASS);
        Encode("%-34s",BUFFER);
        break;
     case 6:
        Encode("IN2PATH  ... '");
        C = WriteString(IN2PATH,IndexTableStream);
        break;
     case 7:
        sprintf(BUFFER,"IN3NAME  ... '%s'",IN3NAME);
        Encode("%-34s",BUFFER);
        break;
     case 8:
        sprintf(BUFFER,"IN3CLASS ... '%s'",IN3CLASS);
        Encode("%-34s",BUFFER);
        break;
     case 9:
        Encode("IN3PATH  ... '");
        C = WriteString(IN3PATH,IndexTableStream);
        break;
     case 10:
        sprintf(BUFFER,"OUTNAME  ... '%s'",OUTNAME);
        Encode("%-34s",BUFFER);
        break;
     case 11:
        sprintf(BUFFER,"OUTCLASS ... '%s'",OUTCLASS);
        Encode("%-34s",BUFFER);
        break;
     case 12:
        Encode("OUTPATH  ... '");
        C = WriteString(OUTPATH,IndexTableStream);
        break;
     case 13:
        sprintf(BUFFER,"CODE     ... %d",CODE);
        Encode("%-34s",BUFFER);
        break;
     case 14:
        sprintf(BUFFER,"ITYPE    ...   ",ITYPE);
        Encode("%-34s",BUFFER);
        break;
     case 15:
        sprintf(BUFFER,"FACTOR   ... %G",FACTOR);
        Encode("%-34s",BUFFER);
        break;
     case 16:
        sprintf(BUFFER,"TRANGE   ... %G, %G",TRANGE[0],TRANGE[1]);
        Encode("%-34s",BUFFER);
        break;
     case 17:
        sprintf(BUFFER,"YRANGE   ... %G, %G",YRANGE[0],YRANGE[1]);
        Encode("%-34s",BUFFER);
        break;
     case 18:
        sprintf(BUFFER,"ZRANGE   ...       ",ZRANGE[0],ZRANGE[1]);
        Encode("%-34s",BUFFER);
        break;
     case 19:
        sprintf(BUFFER,"WINDOW   ... %d, %d,",WINDOW[0],WINDOW[1]);
        Encode("%-34s",BUFFER);
        C = DisplayText(IndexTableStream);
        sprintf(BUFFER,"             %d, %d",WINDOW[2],WINDOW[3]);
        Encode("%-34s",BUFFER);
        if (C) C = DisplayText(IndexTableStream); else printf(CrLf);
        break;
     case 20:
        sprintf(BUFFER,"TFORMAT  ... '%s'",TFORMAT);
        Encode("%-34s",BUFFER);
        break;
     case 21:
        sprintf(BUFFER,"YFORMAT  ... '%s'",YFORMAT);
        Encode("%-34s",BUFFER);
        break;
     case 22:
        sprintf(BUFFER,"ZFORMAT  ... ",ZFORMAT);
        Encode("%-34s",BUFFER);
        break;
     case 23:
        sprintf(BUFFER,"DEVICE   ... '%s'",DEVICE);
        Encode("%-34s",BUFFER);
        break;
     case 24:
        sprintf(BUFFER,"BAUD     ... %d",BAUD);
        Encode("%-34s",BUFFER);
        break;
     case 25:
        sprintf(BUFFER,"STOPBITS ... %d",STOPBITS);
        Encode("%-34s",BUFFER);
        break;
     case 26:
        sprintf(BUFFER,"DATABITS ... %d",DATABITS);
        Encode("%-34s",BUFFER);
        break;
     case 27:
        sprintf(BUFFER,"PARITY   ... '%s'",PARITY);
        Encode("%-34s",BUFFER);
        break;
     case 28:
        sprintf(BUFFER,"FRAME    ... %d",FRAME);
        Encode("%-34s",BUFFER);
        break;
     case 29:
        sprintf(BUFFER,"BORDER   ... %d",BORDER);
        Encode("%-34s",BUFFER);
        break;
     case 30:
        sprintf(BUFFER,"COLOR    ... %ld",COLOR);
        Encode("%-34s",BUFFER);
        break;
     case 31:
        sprintf(BUFFER,"TMINOR   ... %d",TMINOR);
        Encode("%-34s",BUFFER);
        break;
     case 32:
        sprintf(BUFFER,"YMINOR   ... %d",YMINOR);
        Encode("%-34s",BUFFER);
        break;
     case 33:
        sprintf(BUFFER,"ZMINOR   ... ",ZMINOR);
        Encode("%-34s",BUFFER);
        break;
     case 34:
        sprintf(BUFFER,"TMAJOR   ... %G, %G",TMAJOR[0],TMAJOR[1]);
        Encode("%-34s",BUFFER);
        break;
     case 35:
        sprintf(BUFFER,"YMAJOR   ... %G, %G",YMAJOR[0],YMAJOR[1]);
        Encode("%-34s",BUFFER);
        break;
     case 36:
        sprintf(BUFFER,"ZMAJOR   ... ",ZMAJOR[0],ZMAJOR[1]);
        Encode("%-34s",BUFFER);
        break;
     case 37:
        Encode("TLABEL   ... '");
        C = WriteString(TLABEL,IndexTableStream);
        break;
     case 38:
        Encode("YLABEL   ... '");
        C = WriteString(YLABEL,IndexTableStream);
        break;
     case 39:
        Encode("ZLABEL   ... '");
        C = WriteString(ZLABEL,IndexTableStream);
        break;
     case 40:
        Encode("TITLE    ... '");
        C = WriteString(TITLE,IndexTableStream);
        break;
     case 41:
        sprintf(BUFFER,"PARMS    ... %G, %G,",PARMS[0],PARMS[1]);
        Encode("%-34s",BUFFER);
        C = DisplayText(IndexTableStream);
        sprintf(BUFFER,"             %G, %G,",PARMS[2],PARMS[3]);
        Encode("%-34s",BUFFER);
        if (C) C = DisplayText(IndexTableStream); else printf(CrLf);
        sprintf(BUFFER,"             %G, %G,",PARMS[4],PARMS[5]);
        Encode("%-34s",BUFFER);
        if (C) C = DisplayText(IndexTableStream); else printf(CrLf);
        sprintf(BUFFER,"             %G, %G,",PARMS[6],PARMS[7]);
        Encode("%-34s",BUFFER);
        if (C) C = DisplayText(IndexTableStream); else printf(CrLf);
        sprintf(BUFFER,"             %G, %G",PARMS[8],PARMS[9]);
        Encode("%-34s",BUFFER);
        if (C) C = DisplayText(IndexTableStream); else printf(CrLf);
        break;
     case 42:
        sprintf(BUFFER,"QUIET    ... %d",QUIET);
        Encode("%-34s",BUFFER);
        break;
     case 43:
        sprintf(BUFFER,"POINT    ... %G, %G",POINT[0],POINT[1]);
        Encode("%-34s",BUFFER);
        break;
     case 44:
        sprintf(BUFFER,"ZFACTOR  ... %G, %G",ZFACTOR[0],ZFACTOR[1]);
        Encode("%-34s",BUFFER);
        break;
     }

  while (C)
     {
     if (C = DisplayText(IndexTableStream)) Encode("%34s",Space);
     }

  return;
  }

/*********************************************************************
* Pseudo Verb Inputs
*
* Display Adverbs on Screen for a Given TASKNAME
*
* Format for TISAN.IDX is
* TASKNAME1234TASKNAME1234....NULL0000TextTtextTtextTtext<NULL>
*
*/
short Inputs(cPointer)
char *cPointer;
   {
   short I;
   short J;
   char C;
   FILE *IndexTableStream;
   BOOL NoMatch;
   long longP;
   unsigned char InputsAdverbToken;
   char path[_MAX_PATH], fname[_MAX_FNAME];

   if (!*strupr(cPointer)) cPointer = TASKNAME;
   if (!*cPointer)
      {
      Encode("TASKNAME is Currently Undefined.\n");
      return(FALSE);
      }

   _makepath(path,TisanDrive,TisanDir,"TISAN",".IDX");
   IndexTableStream = fopen(path,"rb");
   if (!IndexTableStream)
      {
      Encode("Error Opening Index File for Read.\n");
      return(FALSE);
      }
/*
** Locate the Current Task in the index file
**
*/
   do {
      fread(fname,1,8,IndexTableStream);
      fread(&longP,sizeof(long),1,IndexTableStream);
      fname[8] = '\0';  /* Make sure the Null is there */
      if (ferror(IndexTableStream))
         {
         Encode("Error Reading TISAN.IDX\n");
         fcloseall();
         return(FALSE);
         }
      if (!longP)
         {
         Encode("Task %s Not Found in TISAN.IDX\n",cPointer);
         fcloseall();
         return(FALSE);
         }
      NoMatch = strcmp(fname,cPointer);  /* No match ?*/
      }
   while (NoMatch);

   fseek(IndexTableStream,longP,SEEK_SET);
     
   Encode(CrLf);
   Encode("%s - ",cPointer);
   do {
      if (C = fgetc(IndexTableStream))
         printf("%c",C);
      else
         printf(CrLf);
      }
   while (C);

   Encode("---------------------------------------\
------------------------------\n");
   do {
      if (!(InputsAdverbToken = fgetc(IndexTableStream))) break;
      DisplayInputs(InputsAdverbToken,IndexTableStream);
      }
   while (!InterruptFlag);
   Encode(CrLf);
   fclose(IndexTableStream);
   return(TRUE);
   }