TVX: PD Editor (3 of 7)

wampler at unmvax.UUCP wampler at unmvax.UUCP
Tue Jan 14 07:40:26 AEST 1986


#--------CUT---------CUT---------CUT---------CUT--------#
#########################################################
#                                                       #
# This is a shell archive file.  To extract files:      #
#                                                       #
#    1)	Make a directory (like tvx) for the files.      #
#    2) Write a file, such as "filen.shar", containing  #
#       this archive file into the directory.           #
#    3) Type "sh file.shar".  Do not use csh.           #
#                                                       #
#########################################################
#
#
echo Extracting tvx_io.c:
sed 's/^X//' >tvx_io.c <<\SHAR_EOF
X/* ---------------------------- tvx_io.c ------------------------------- */
X#include "tvx_defs.ic"
X#include "tvx_glbl.ic"
X
X#define SWITCH '-'
X#define FILESEP '.'
X
X#ifdef MSDOS
X#define TEMPEXT ".$$1"		/* name of temporary file */
X#define BACKEXT ".BAK"		/* name of backup file */
X#endif
X
X#ifdef OSCPM
X#define TEMPEXT ".$$1"		/* name of temporary file */
X#define BACKEXT ".BAK"		/* name of backup file */
X#endif
X
X#ifdef GEMDOS
X#define TEMPEXT ".Z1X"		/* name of temporary file */
X#define BACKEXT ".BAK"		/* name of backup file */
X#endif
X
X#ifdef UNIX
X#define BACKEXT ".B"		/* name of backup file */
X#endif
X
X    FILE *fopen();
X
X/* local globals (used by tv terminal driver section) */
X
X    static int linptr; /* common "linot" */
X    static char linout[242];
X
X    static char stemp[FNAMESIZE+1];
X
X/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
X
X	FILE IO section
X
X   File handling algorithm:
X
X	The original name specified on command line is called orig_file.
X	It will remain untouched throughout the editing session.  At the
X	very end (normal exit), it will be renamed to the ".BAK" name.
X
X	source_file is the current name of the file with source.  It will
X	orignally be the same as orig_file, but may change to a generated
X	scratch name depending on the operating system.  source_file is
X	always the lastest fully written version of the file (like after
X	file beginning, for example). 
X
X	work_file is the output file.  On normal exit, this is the
X	file renamed to dest_file.  On buffer beginning, it will be
X	moved to source_file, possibly after renameing.
X	
X	dest_file is the ultimate destination file.  This name is not
X	actually used until the final rename on normal exit.  It is
X	checked to be sure it is a valid name to be opened, however.
X
X   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
X
X/* =============================>>> ABORT <<<============================= */
X  abort()
X  {    /* abort - close files, abort operation */
X
X    char rply[4];
X
X    tvclr();
X    ask("Abort, are you sure? ",rply,1);
X    if (clower(rply[0]) != 'y')
X      {
X	verify(1);
X	return;
X      }
X    abort2();
X  }
X
X/* =============================>>> ABORT2 <<<============================= */
X  abort2()
X  {
X    clobak();
X    tvclr();
X
X    if (!newfil)
X	fclose(infile);
X    if (!rdonly)
X	fclose(outfile);
X
X    if (strcmp(orig_file,source_file) != 0)
X      {
X	prompt("File begin used, intermediate edits in: ");
X	remark(source_file);
X      }
X    unlink(work_file);		/* delete the work file */
X
X    reset();
X    quit();
X  }
X
X/* =============================>>> FBEG   <<<============================= */
X  int fbeg()
X  { /* fbeg - go back to file top */
X 
X    SLOW int fbegv;
X 
X    if (rdonly)
X      {
X	tverrb("Can't: R/O");	/* can't do this for read only access */
X	return (FALSE);
X      }
X
X    for (wtpage(1) ; rdpage() ; wtpage(1) )	/* write out rest */
X	;
X
X    if ((! newfil))
X      {
X	fclose(infile);			/* close source_file */
X      }
X    if (usecz)
X	fputc(ENDFILE,outfile);
X
X    fclose(outfile);			/* close work_file */
X
X/* files closed now, re-open */ 
X 
X    newfil = FALSE;		/* not a new file any more */
X
X    strcpy(source_file,work_file);	/* new source file */
X    temp_name(work_file,FALSE);		/* make a new temporary name */
X
X    if (!(infile = fopen(source_file,FILEREAD)))
X	goto l900;
X    else
X	ineof = FALSE;
X
X    unlink(work_file);			/* get rid of previous copies */
X    if (!(outfile = fopen(work_file,FILEWRITE)))
X      {
X	goto l900;
X      }
X 
X    fbegv=rdpage();		/* read in new buffer */
X    newscr();
X    return (fbegv);
X
Xl900: tverrb("Error re-opening");
X    return (FALSE);
X  }
X 
X/* =============================>>> FILE_EXIT <<<============================= */
X  file_exit()
X  { /* close the input and output files, rename */
X 
X    SLOW int i;
X
X    if (!newfil)		/* don't close input if new file */
X      {
X	fclose(infile);
X      }
X
X    while (!rdonly && !*dest_file)
X      {
X	remark("No name for output file has been specified.");
X        prompt("Enter new name for output file: ");
X	reply(dest_file,FNAMESIZE);
X      }
X
X    if (!rdonly)	/* don't close output if read only access */
X      {
X	if (usecz)
X	    fputc(ENDFILE,outfile);
X	set_mode(outfile);		/* set output mode if can */
X	fclose(outfile);
X
X    /*	orig_file has the name to be renamed to .bak
X	work_file has the file name we want to be dest_name
X    */
X	if (strcmp(orig_file,dest_file) == 0)	/* make backup version */
X	  {
X	    strcpy(stemp,orig_file);
X#ifndef COMMA_BAK
X	    if ((i = rindex(stemp,FILESEP)) > 0)	/* see if extenstion */
X		scopy(BACKEXT,0,stemp,i);		/* make .bak */
X	    else
X	      {
X		scopy(BACKEXT,0,stemp,strlen(stemp));	/* just add on */
X	      }
X#else
X	    i = rindex(orig_file,'/')+1;
X	    scopy(".,",0,stemp,i);
X	    scopy(orig_file,i,stemp,strlen(stemp));
X#endif
X
X	    unlink(stemp);			/* delete previous generation */
X	    ren_file(orig_file,stemp);		/* rename the file */
X	    if (!makebackup)			/* don't want to keep old one */
X		unlink(stemp);	/* delete it if don't want backup file */
X	  }
X
X	if (strcmp(orig_file,source_file) != 0)	/* delete intermediate file */
X	    unlink(source_file);
X
X
X	while (infile = fopen(dest_file,FILEREAD))	/* output exists? */
X	  {
X	    fclose(infile);
X	    prompt("Output file "); prompt(dest_file);
X	    prompt(" already exists.  Overwrite it? (y/n) ");
X	    ureply(stemp,1);
X	    if (*stemp == 'Y')
X	      {
X		unlink(dest_file);
X		break;
X	      }
X	    prompt("Enter new name for output file: ");
X	    reply(dest_file,FNAMESIZE);
X	  }
X
X	ren_file(work_file,dest_file);		/* finally, rename last file */
X      }
X
X  }
X
X/* =============================>>> FOPENX  <<<============================= */
X  fopenx(argc,argv)
X  int argc;
X  char *argv[];
X  {  /* open the input file
X	This routine picks up file name from the user, creates a backup
X	version in some appropriate manner, and opens the file for input
X	and output. */
X 
X    SLOW int iswval, iswbeg, argnum, set_ttymode;
X    SLOW char ch;
X    char rply[4];
X 
X    usebak = logdef;		/* if useing backup log file */
X
X    ttymode = FALSE;		/* not in tty mode, so io ok */
X    ttynext = 1000;		/* force read */
X
X    if (argc <= 1)
X      {
X	remark("Usage: tvx filename [-b -i -l -o=f -r -s -t -w -# {-z -c=f}]");
X#ifdef FULLHELP
X	remark("");
X	prompt(" Options: "); remark(VERSION);
X	remark("  -[no]b : backup file   -[no]i : autoindent");
X	remark("  -[no]l : make command log file");
X	remark("  -o=outputfile          -r : read only");
X	remark("  -s : big save buff     -[no]w : word processing mode");
X	remark("  -t : tty edit mode     -# : set virtual window lines to #");
X#ifdef MSDOS
X        remark("  -[no]z : use control-z for end of file");
X#endif
X#ifdef CONFIGFILE
X#ifdef MSDOS
X        remark("  -c=configfile        -c : use /bin/config.tvx");
X#endif
X#ifdef GEMDOS
X        remark("  -c=configfile        -c : use /bin/config.tvx");
X#endif
X#ifdef OSCPM
X        remark("  -c=configfile        -c : use A:config.tvx");
X#endif
X#endif
X#ifdef UNIX
X	remark("  {options not available for unix}");
X#endif
X#endif
X	remark("");
X	reset();
X	quit();
X      }
X
X    newfil=				/* assume opening an old file */
X    rdonly = FALSE;			/* assume not read only */
X    makebackup = MAKE_BACKUP;		/* default value for make a backup */
X    blimit = BUFFLIMIT;
X 
X    for (argnum = 1 ; argnum < argc ; ++argnum)
X      {
X	strcpy(stemp,argv[argnum]);	/* pick up the file name or switch */
XREDO:
X	if (stemp[0] == SWITCH)		/* switch in form "/R filename" only */
X	  {
X	    iswbeg=1;		/* start at 1 */
X	    iswval = TRUE;
X	    if (clower(stemp[1]) == 'n' && clower(stemp[2]) == 'o')
X	      {
X		iswval = FALSE ; iswbeg = 3 ;
X	      }
X
X	    ch = clower(stemp[iswbeg]);		/* get the char */
X	    if (ch == 'r')		/* read only access */
X		rdonly=iswval;
X	    else if (ch == 'i')		/* auto indent */
X		autoin = iswval;
X	    else if (ch == 'w')		/* word processing mode */
X	      {
X		if (iswval)
X		    wraplm = 70;
X		else
X		    wraplm = 0;
X	      }
X	    else if (ch == 'l')
X		usebak=iswval;
X	    else if (ch == 'b')
X		makebackup = iswval;	/* make a backup file */
X	    else if (ch == 'z')
X		usecz = iswval;
X	    else if (ch == 'o' && (stemp[iswbeg+1] == '=' ||
X	      stemp[iswbeg+1] == ':'))	/* specifying output */
X	      {
X		if (!iswval)		/* wrong order! */
X		  {
X		    remark("Bad -O= switch");
X		    quit();
X		  }
X		scopy(stemp,iswbeg+2,dest_file,0);  /* remember name */
X	      }
X#ifdef CONFIGFILE
X	    else if (stemp[iswbeg] == 'c' && stemp[iswbeg+1] == 0) /* default cfg */
X	      {
X		strcpy(stemp,cfgname);
X	  	goto REDO;
X	      }
X	    else if (stemp[iswbeg] == 'c' && (stemp[iswbeg+1] == '=' ||
X	      stemp[iswbeg+1] == ':'))	/* specifying config */
X	      {
X		expand_name(&stemp[iswbeg+2]);
X		if ((bkuin = fopen(&stemp[iswbeg+2],FILEREAD))==0)
X		  {
X		    remark("Can't open configuration file.");
X		    continue;
X		  }
X		rdcfg(lexsym,LEXVALUES+1);
X		rdcfg(synofr,20);
X		rdcfg(synoto,20);
X		rdcfg(funchar,50);
X		rdcfg(funcmd,50);
X		rdcfg(&funkey,1);
X		rdcfg(&autoin,1);
X		rdcfg(&ddline,1);
X		rdcfg(&dscrl,1);
X		rdcfg(&dxcase,1);
X		rdcfg(&wraplm,1);
X		rdcfg(&use_wild,1);
X		rdcfg(&usebak,1);
X		logdef = usebak;
X#ifdef MSDOS
X		rdcfg(&usecz,1);
X#endif
X#ifdef GEMDOS
X		rdcfg(&usecz,1);
X#endif
X		fclose(bkuin);
X	      }
X#endif
X	    else if (ch == 's')	/* big save buffer */
X	      {
X		if (!iswval)
X		    blimit=BUFFLIMIT;
X		else
X		    blimit=BUFFLIMIT*3;
X	      }
X#ifndef VTERM
X	    else if (ch == 't')	/* tty mode */
X		set_ttymode = iswval;	/* make a backup file */
X#endif
X	    else if (ch >= '0' && ch <= '9')	/* making a virtual window */
X	      {
X		tvlins = atoi(&stemp[iswbeg]);	/* get virtual screen size */
X		if (tvlins < 3 || tvlins > tvhardlines)	/* invalid window */
X		  {
X		    remark("Invalid window size");
X		    tvlins = tvhardlines;
X		  }
X		else
X		  {
X		    ddline = (tvlins / 2) + 1;	/* fix home line */
X		    setdscrl();
X		  }
X	      }
X	    else				/* illegal switch */
X	      {
X		prompt("Unknown switch -"); ttwt(ch);
X		prompt(": Ignore and continue? (y/n) ");
X		ureply(rply,1);
X		if (*rply != 'Y')
X		  {
X		    reset();  quit();
X		  }
X	      }
X	  }
X	else			/* must have a file name */
X	  {
X	    strcpy(orig_file,stemp);
X	  }
X      }		/* end for */
X 
X/*	now open file properly - make copies to all 4 names */
X
XGETNAME:
X	while (!*orig_file)
X	  {
X	    ask("Edit file? ",orig_file,FNAMESIZE);
X	  }
X
X	expand_name(orig_file);		/* expand on unix */
X
X	if (!(infile = fopen(orig_file,FILEREAD)))	/* can open? */
X	  {
X	    prompt("Create file "); prompt(orig_file);
X	    prompt("? (y/n) ");
X	    ureply(rply,1);
X	    if (*rply != 'Y')
X	      {
X		*orig_file = 0; goto GETNAME;
X	      }
X	    if (*dest_file)
X	        remark("New file, -o= switch ignored");
X	    *dest_file = 0;
X	    newfil = TRUE;		/* a new file */
X	    rdonly = FALSE;
X	  }
X
X/* orig_file now has the name of the source file, and it might be open */
X
X	ineof = FALSE;
X	strcpy(source_file,orig_file);	/* copy to other names */
X	strcpy(work_file,orig_file);
X	if (!*dest_file)		/* no -o specified */
X	    strcpy(dest_file,orig_file);
X
X
X	if (!newfil)			/* not new file */
X	  {
X	    fclose(infile);		/* close orig file */
X	    if (!(infile = fopen(source_file,FILEREAD)))	/* re-open */
X	      {
X		remark("Internal editor error, aborting");
X		exit(100);
X	      }
X	    get_mode(infile);		/* get mode of original file */
X	  }
X	else
X	  {
X	    *orig_file = *source_file = 0; 
X	  }
X
X/* now see if we can make an output file */
X	
X	if (!rdonly)
X	  {
X	    temp_name(work_file,TRUE);	/* make into a temporary name 1st time*/
X	    unlink(work_file);		/* get rid if already there */
X
X	    if (!(outfile = fopen(work_file,FILEWRITE)))
X	      {
X		prompt("Unable to create output work file: ");
X		remark(work_file);
X		if (!newfil)
X		  {
X	            prompt("Continue in read only mode? (y/n) ");
X		    ureply(rply,1);
X		    if (*rply != 'Y')
X		      {
X			fclose(infile);
X			reset();
X			exit(100);		/* abnormal exit */
X		      }
X		  }
X	        *dest_file = *work_file = 0;
X		rdonly = TRUE;
X	      }
X	  }
X	else
X	  {
X	    *dest_file = *work_file = 0;
X	  }
X
X    ttymode = force_tty ? TRUE : set_ttymode;	/* now safe to set ttymode */
X  }
X
X/* =============================>>> setdscrl <<<============================= */
X  setdscrl()
X  {	/* compute a new value for dscrl */
X
X    if (dscrl == 0)
X	return;			/* if already 0, don't change */
X    dscrl = tvlins / 3;
X    if ((ddline + dscrl) >= tvlins)	/* looks ugly if hits last line */
X	dscrl--;
X    if (dscrl < 0)		/* don't allow this */
X	dscrl = 0;
X  }
X
X#ifdef CONFIGFILE
X/* =============================>>> RDCFG <<<============================= */
X  rdcfg(toset,cnt)
X  char *toset;
X  int cnt;
X    {	/* read cnt vals from bkuin */
X
X    FAST int i,val;
X
X    for (i = 0 ; i < cnt ; ++i)
X      {
X	if ((val = fgetc(bkuin)) == EOF)
X	 {
X	    remark("Invalid configuration file, aborting");
X	    fclose(bkuin);
X	    quit();
X	 }
X	*toset++ = val;	/* replace with new commands */
X      }
X  }
X#endif
X
X/* =============================>>> ADDFIL <<<============================= */
X  int addfil(rw)
X  int rw;
X  {  /* addfil - add contents of external file to save buffer
X	positive means read into buffer, negative means write save buffer */
X
X    SLOW int chr;
X    SLOW int limit;
X
X    SLOW BUFFINDEX fromch;
X    SLOW int i;
X    SLOW FILE *outf;
X
X    if (rw >= 0)	/* read a file */
X      {
X	if (!gbgcol(nxtchr))	/* gc first */
X	  {
X	    newscr();
X	    tverrb("No save room");
X	    return (FALSE);
X	  }
X
X        tvclr();
X#ifdef LASL
X	ask("Read external filename: ",stemp,FNAMESIZE);
X#else
X	ask("Yank filename: ",stemp,FNAMESIZE);
X#endif
X
X	expand_name(stemp);			/* expand on some systems */
X
X	if (!(bkuin = fopen(stemp,FILEREAD)) || !*stemp)
X	  {
X	    newscr();
X#ifdef LASL
X	    tverrb(" Unable to open external file ");
X#else
X	    tverrb(" Unable to open yank file ");
X#endif
X	    return (FALSE);
X	 }
X
X	savlin=0 ; savlen=0 ; nxtsav =mxbuff ;	/* clear out save buffer */
X
X	limit = max(nxtchr,mxbuff/2)-ALMOSTOUT;
X	do
X	  {
X	    if ((chr = getchr(bkuin)) < 0)
X	      {
X		newscr();
X		fclose(bkuin);
X		return (TRUE);
X	      }
X	    if (chr == NEWLINE)
X	      {
X#ifdef FILELF
X	        getchr(bkuin);
X#endif
X		chr=ENDLINE;
X		++savlin;
X	      }
X	    *(buff+nxtsav--) = chr;
X	    if (nxtsav <= limit)
X	      {
X		newscr();
X		tverrb("File only partly read");
X		break;
X	      }
X	  }
X	while (1);
X	fclose(bkuin);
X	return (TRUE);
X      }
X
X    /* --------------- to here, then writing from save buffer --------------*/
X
X
X    if (nxtsav==mxbuff)		/* nothing to save */
X      {
X 	tverrb("Save buffer empty!");
X	return (TRUE);
X      }
X
X    tvclr();
X    ask("Write to external filename: ",stemp,FNAMESIZE);
X
X    expand_name(stemp);			/* expand on some systems */
X
X    if (!(outf = fopen(stemp,FILEWRITE)) || !*stemp)
X      {
X	newscr();
X	tverrb(" Unable to open external file ");
X	return (FALSE);
X      }
X
X    
X/*   # move down line to make space for new */
X    fromch = mxbuff;		/* where taking saved stuff from */
X    for (i = 0 ; i < savlin ; ++i)
X      {
X        for ( ; ; )		/* scan save buffer */
X	  {
X	     if ((chr = *(buff+fromch--)) == ENDLINE)
X	      {
X		fputc(NEWLINE,outf);
X#ifdef FILELF
X		fputc(LF,outf);
X#endif
X		break;
X	      }
X	    else
X		fputc(chr,outf);
X	  }
X      }
X
X    if (usecz)
X	fputc(ENDFILE,outf);
X    fclose(outf);
X    newscr();
X    return (TRUE);
X
X  }
X
X/*=============================>>> SCOPY  <<<================================*/
X  scopy(old,oldbeg,new,newbeg)
X  char old[], new[];
X  int oldbeg,newbeg;
X  {
X    while (old[oldbeg])
X	new[newbeg++]=old[oldbeg++];
X    new[newbeg] = 0;
X  }
X
X/* **************************************************************************
X
X	Following code is for non-unix systems
X
X **************************************************************************** */
X#ifndef UNIX
X/* =============================>>> get_mode <<<============================= */
X  get_mode(f)
X  FILE *f;
X  {		/* gets access mode of open file f */
X  }
X
X/* =============================>>> set_mode <<<============================= */
X  set_mode(f)
X  FILE *f;
X  {		/* sets access mode of open file f */
X  }
X
X/* ==========================>>> expand_name <<<============================ */
X  expand_name(n)
X  char *n;
X  {		/* expands unix file names */
X  }
X
X/* =============================>>> ren_file <<<=========================== */
X  ren_file(old,new)
X  char *old, *new;
X  {
X#ifndef GEMDOS
X    if (rename(old,new) != 0)
X      {
X	prompt(old) ; prompt(" not renamed to "); remark(new);
X      }
X#endif
X#ifdef GEMDOS
X    gemdos(0x56,0,old,new);	/* can't find C version */
X#endif
X  }
X
X/* =============================>>> temp_name <<<=========================== */
X  temp_name(n,first)
X  char *n;
X  int first;
X  {
X	/* generates a temporary name from n.  Depending on value of
X	   first, it will either add a 1 or 2 to name */
X
X    SLOW int i;
X
X    if (first)
X      {
X	if ((i = rindex(n,FILESEP)) > 0)	/* see if extenstion */
X	    scopy(TEMPEXT,0,n,i);		/* make .bak */
X	else
X	  {
X	    scopy(TEMPEXT,0,n,strlen(n));	/* just add on */
X	  }
X      }
X    else
X      {
X	i = strlen(n);
X	if (n[i-1] == '1')
X	    n[i-1] = '2';
X	else
X	    n[i-1] = '1';
X      }
X  }
X
X#endif
X
X/* **************************************************************************
X
X	This section is for the version supporting command logfile
X	backup.  The code necessary for this version is included here,
X	and may be compiled by defining VB to be a blank.
X
X **************************************************************************** */
X 
X/* =============================>>> OPNBAK <<<============================= */
X  opnbak()
X  { 
X	/* opnbak - open the backup log file
X	   if VB defined as ' ', then backup version created */
X 
X#ifdef VB
X 
X    if (! usebak)
X      {
X	bakflg = FALSE;
X	return;
X      }
X
X    bkuout = fopen(BACKUPNAME,FILEWRITE);
X    bakpos = 1;
X#endif
X 
X  }
X 
X/* =============================>>> PUTBAK <<<============================= */
X  putbak(chr)
X  char chr;
X  { /* putbak - put a character into the backup file */
X 
X#ifdef VB
X    static char copy;
X
X    if (! usebak)
X	return;
X    copy=chr;
X    if (copy < 32 || copy == '@' || copy==delkey)
X      {
X	fputc('@',bkuout);
X	bakcrlf();
X	if (copy < 32)
X	    copy += '@';
X	else if (copy==delkey)
X	    copy = '?'; 	/* let @? be rubout */
X      }
X    fputc(copy,bkuout);
X    bakcrlf();
X#endif
X  }
X 
X#ifdef VB
X/* =============================>>> BAKCRLF <<<============================= */
X  bakcrlf()
X  {    /* conditionally put a cr/lf to backup file */
X
X    if (++bakpos > 63)
X      {
X	fputc(NEWLINE,bkuout);
X#ifdef FILELF
X	fputc(LF,bkuout);
X#endif
X	bakpos = 1;
X      }
X  }
X#endif
X
X/* =============================>>> CLOBAK <<<============================= */
X  clobak()
X  {
X
X#ifdef VB
X    if (! usebak)
X	return;
X    fputc(NEWLINE,bkuout);
X#ifdef FILELF
X    fputc(LF,bkuout);
X#endif
X    if (usecz)
X	fputc(ENDFILE,bkuout);
X
X    fclose(bkuout);
X#endif
X  }
X 
X/* =============================>>> GETBAK <<<============================= */
X  getbak(chr)
X  char *chr;
X  {  /* get one char from back up file if there */
X
X#ifdef VB
X    SLOW int ich;
X
Xl10:
X    if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE)
X      {
Xl15:	fclose(bkuin);
X	*chr=0;			/* harmless character */
X	bakflg=FALSE;
X	newscr();
X	return;
X      }
X    if (ich == NEWLINE)
X	goto l10;
X#ifdef FILELF
X    if (ich == LF)
X	goto l10;
X#endif
X    *chr=ich;
X    if (ich=='@')
X      {
Xl20:    if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE)
X	  {
X	    goto l15;
X	  }
X	if (ich == NEWLINE)
X	    goto l20;
X#ifdef FILELF
X	if (ich == LF)
X	    goto l20;
X#endif
X	*chr=ich;
X	if (ich == '?')
X	    *chr=delkey;
X	else if (*chr != '@')
X	    *chr= ich - '@';
X      }
X#endif
X  }
X 
X/* =============================>>> OPNATF <<<============================= */
X  opnatf()
X  { /* open an indirect command file */
X 
X#ifdef VB
X
X 
X    tvclr();
X 
X    ask("Name of command file: ",stemp,FNAMESIZE);
X		/* read in the file name from the terminal */
X
X    expand_name(stemp);
X
X    if (!*stemp)
X	return;
X
X    if (!(bkuin = fopen(stemp,FILEREAD)))
X      {
X	newscr();
X	tverrb("Bad @ name");
X	return;
X      }
X    bakflg=TRUE;
X    newscr();
X#endif
X  }
X
X/* **************************************************************************
X
X	This section contains code to write and read buffers of data
X
X **************************************************************************** */
X
X/* =============================>>> RDPAGE <<<============================= */
X  int rdpage()
X  { /* rdpage - read in file up to buffer limit
X       only place text read from edited file */
X 
X    SLOW int chr;
X    SLOW int l,newlns;
X 
X    if (newfil)		/* can't read in when a new file */
X      {
X	return (FALSE);
X      }
X    if (nxtlin > mxline || nxtchr > mxbuff-130)	/* error check */
X      {
X	tverrb("Lines filled ");
X	return (FALSE);
X      }
X 
X    newlns=0;			/* begin at the beginning */
X    while (mxline-nxtlin > LINELIMIT  && nxtsav-nxtchr > blimit && !ineof)
X      { 			/* read in while have room */
X	chr = fgetc(infile);
X	if (chr == EOF)
X	  {
X	    ineof = TRUE;
X	    break;
X	  }
X	if (chr == ENDFILE && usecz)
X	  {
X	    ineof = TRUE;
X	    break;
X	  }
X#ifdef FILELF
X	if (chr == LF)
X	    continue;
X#endif
X	*(buff+nxtchr) = BEGLINE;
X	*(lines+nxtlin) = nxtchr++;
X	++newlns ;
X	    
X	while (chr != NEWLINE)		/* store a line */
X	  {
X	    *(buff+nxtchr++) = chr;
X	    chr = fgetc(infile);
X	    if (chr == EOF)
X	      {
X		ineof = TRUE;
X		break;
X	      }
X	    if (chr == ENDFILE && usecz)
X	      {
X		ineof = TRUE;
X		break;
X	      }
X	  }
X	*(buff+nxtchr++)=ENDLINE;
X	++nxtlin;
X      }
X
Xl900:
X    if (nxtlin > 1)		/* we really read something */
X      {
X	curlin=1;		/* point to top of char */
X	curchr = *(lines+1)+1;	/* point to first character */
X      }
X    return (newlns > 0) ;
X  }
X
X/* =============================>>> WTPAGE <<<============================= */
X  wtpage(whow)
X  int whow;
X  { /* wtpage - write out contents of text buffer, and clear line list */
X 
X    FAST int i;
X    FAST char *chrp;
X    SLOW char *lim;
X    SLOW int wlimit;
X 
X    if (whow < 0)		/* allow writing partial buffer */
X	wlimit = curlin - 1;
X    else
X	wlimit = nxtlin -1;
X
X    if (nxtlin <= 1 || rdonly)
X      {
X	tverr("Empty buffer");
X	goto zapb;
X      }
X
X    if (whow < 0)
X	tverr("Writing partial buffer");
X    else
X	tverr("Writing buffer");
X 
X    tvhdln();
X 
X    for (i = 1 ; i <= wlimit ; ++i)
X      {
X	chrp = buff + (*(lines+i)+1);	/* ptr to first char of line */
X	while (*chrp != ENDLINE)
X	  {
X	    fputc(*chrp++, outfile);
X	  }
X	fputc(NEWLINE,outfile);
X#ifdef FILELF
X	fputc(LF,outfile);
X#endif
X      }
X
Xzapb:
X
X    if (whow < 0)
X      {
X	killin(-(curlin-1));	/* kill to top of buffer */
X	if (!gbgcol(nxtchr))	/* gc first */
X	  {
X	    newscr();
X	    tverrb("Warning: no extra room created");
X	    return (FALSE);
X	  }
X	return (TRUE);
X      }
X    else
X      {
X	lim = buff + nxtsav;
X	for (chrp=buff ; chrp < lim ; *chrp++ = GARBAGE)
X	    ;
X	tvdlin =			/* start on first line again */
X	nxtlin =			/* reset to initial state */
X	nxtchr = 1;
X	curchr =
X	curlin=0;
X	return (TRUE);
X      }
X  }
X
X/* **************************************************************************
X
X    This section contains misc. stuff likely to be operating system dependent
X
X **************************************************************************** */
X
X/* ===========================>>> OPSYSTEM <<<============================== */
X  opsystem()
X  {
X#ifdef MSDOS			/* !!! cii-86 dependent */
X
X    char rp[80];
X
XMS_AGAIN:
X    tvclr();
X    ask("DOS command (any key to resume edit when done): ",rp,79);
X    remark("");
X    if (system(rp) != 0)
X      {
X    	tvxy(1,1);
X	ask("Sorry, but couldn't find COMMAND.COM.",rp,1);
X      }
X    else
X      {
X	tvxy(1,1);
X	ask("",rp,1);
X	if (*rp == '!')
X	   goto MS_AGAIN;
X      }
X    verify(1);
X#endif
X#ifdef UNIX
X    unix_sys();
X#endif
X#ifdef GEMDOS
X    return;
X#endif
X  }
X
X#ifndef UNIX
X/* ===========================>>> TTINIT <<<============================== */
X  ttinit()
X  { /*  this routine could be used to set up keyboard input, perhaps
X	turning on non-echoed input */
X    return;
X  }
X
X/* ===========================>>> TTCLOS <<<============================== */
X  ttclos()
X  {  /* this routine could undo anything ttinit() did */
X    return;
X  }
X#endif
X
X#ifndef VTERM
X/* ===========================>>> TTRD <<<============================== */
X  ttrd()
X  { /* this routine is called to read one unechoed char from the keyboard */
X
X  static int tc, i;
X  static char chr;
X
XRDTOP:
X    if (ttymode)
X	tc = rdtty();		/* get a char from the tty */
X    else
X      {
X
X#ifdef CPM
X    while (!(tc = bdos(6,-1)))		/* cp/m implementation */
X	;
X#endif
X#ifdef MSDOS
X    tc = bdos(7,-1);		/* ms-dos implementation  (!!! cii-86) */
X#endif
X#ifdef GEMDOS
X    tc = gemdos(7);		/* GEMDOS application */
X#endif
X#ifdef UNIX
X    tc = ttrd_unix();
X#endif
X       }
X
X    chr = tc & 0377;
X
X    if (chr == funkey)			/* function key */
X      {
X	if (ttymode)
X	  {
X	    tc = rdtty();		/* get a char from the tty */
X	  }
X	else
X	  {
X#ifdef CPM
X	while (!(tc = bdos(6,-1)))		/* cp/m implementation */
X	    ;
X#endif
X#ifdef MSDOS
X	tc = bdos(7,-1);		/* ms-dos implementation */
X#endif
X#ifdef GEMDOS
X    tc = gemdos(7);		/* GEMDOS application */
X#endif
X#ifdef UNIX
X	tc = ttrd_unix();
X#endif
X	  }
X	chr = tc & 0377;
X	for (i = 0 ; i < 50 && funchar[i] ; ++i)
X	  {
X	    if (chr == funchar[i])
X	      {
X		tc = funcmd[i] & 0377;
X		return (tc);
X	      }
X	  }
X	goto RDTOP;			/* ignore invalid function keys */
X      }
X    tc = chr & 0377;
X    return (tc);
X
X  }
X#endif
X
X#ifndef UNIX
X/* ===========================>>> TTWT <<<============================== */
X  ttwt(chr)
X  char chr;
X  { /*  this routine is called to write one char to the keyboard
X	It also interprets print direction */
X
X    if (ttymode)
X	return;
X    dispch(chr);	/* cp/m, ms-dos version */
X    if (useprint)
X	printc(chr);
X  }
X#endif
X
X#ifdef MSDOS
X/* ===========================>>> GETCHR <<<============================== */
X  getchr(filnum)
X  FILE *filnum;
X  {  /* get a character from filnum */
X
X#define EOFBYTE 26
X
X    FAST int ichr;
X
X    if (((ichr = fgetc(filnum)) == EOFBYTE))
X      {
X	if (usecz)
X	    return (EOF);
X      }
X
X    return (ichr);
X  }
X#endif
X
X#ifdef GEMDOS
X/* ===========================>>> GETCHR <<<============================== */
X  getchr(filnum)
X  FILE *filnum;
X  {  /* get a character from filnum */
X
X#define EOFBYTE 26
X
X    FAST int ichr;
X
X    if (((ichr = fgetc(filnum)) == EOFBYTE))
X      {
X	if (usecz)
X	    return (EOF);
X      }
X
X    return (ichr);
X  }
X#endif
X
X/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
X
X    TVX TERMINAL DRIVER  for various terminals
X
X   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
X 
X
X/* =============================>>> TRMINI <<<============================= */
X  trmini()
X  {  /* initialize term if necessary */
X
X    sendcs(cinit);
X    tvclr();
X  }
X
X/* =============================>>> reset <<<============================= */
X  reset()
X  {
X    sendcs(cendit);
X    ttclos();
X  }
X
X/* =============================>>> ttyverify <<<============================= */
X  ttyverify(knt)
X  int knt;
X  {
X    SLOW BUFFINDEX oldline, oldchr, limit;		/* current position */
X
X    oldline = curlin; oldchr = curchr;	/* remember where we were */
X
X    ttymode = FALSE;			/* enable output stuff */
X
X    if (knt < 0)			/* type some above */
X      {
X	curchr = 0;
X	curlin = curlin + knt ;		/* back n lines */
X	if (curlin < 1)
X	   curlin = 1;
X	while (curlin < oldline)	/* write out the lines */
X	    ttyline(curlin++);	/* write line, no cursor */
X      }
X    else
X      {
X	ttyline(curlin);		/* type current line */
X	curchr = 0;			/* this turns off cursor */
X	limit = oldline + knt - 1;
X	if (limit >= nxtlin)
X		limit = nxtlin - 1;
X	while (++curlin <= limit)
X	    ttyline(curlin);
X      }
X    curchr = oldchr;
X    curlin = oldline;
X    ttymode = TRUE;
X  }
X
X/* =============================>>> ttyline <<<============================= */
X  ttyline(linenr,cursor)
X  BUFFINDEX linenr;
X  {
X    SLOW BUFFINDEX chrc;
X    SLOW int outlen;
X    
X    chrc = *(lines+linenr)+1;	/* point to first character in line */
X    outlen = 0;			/* nothing out yet */
X    for ( ; ; )
X      {
X	if (chrc == curchr)	/* at cursor */
X	  {
X	    outlen += 2;
X	    if (outlen > 78)	/* line wrap */
X	      {
X		remark("");
X		ttwt('_');
X		outlen = 3;
X	      }
X	    ttwt('/'); ttwt('\\');
X	  }
X    	if (*(buff+chrc) == ENDLINE)	/* done */
X	    break;
X	outlen += ttywtch(*(buff+chrc));	/* watch for line wrap */
X	if (outlen > 78)
X	  {
X	    remark("");
X	    ttwt('_');
X	    outlen = 1;
X	  }
X	++chrc;			/* next character */
X      }
X    remark("");
X  }
X  
X/* =============================>>> ttywtch <<<============================= */
X  ttywtch(chr)
X  char chr;
X  {
X    if (chr >= ' ')		/* regular character */
X      {
X        ttwt(chr);
X	return 1;
X      }
X    else			/* control character */
X      {
X	ttwt('^');
X	ttwt(chr+'@');
X	return 2;
X      }
X  }
X  
X/* =============================>>> rdtty <<<============================= */
X  rdtty(knt)
X  int knt;
X  {		/* fake rdtt for ttymode - only called when in ttymode */
X
X#define RDBUFFSIZE 81
X    static char rdtbuf[RDBUFFSIZE];
X
XRDTOP:
X    ttymode = FALSE;			/* take out of ttymode for echo */
X    if (ttynext >= RDBUFFSIZE)		/* need to read a line */
X      {
X	if (ins_mode)			/* different prompts for modes */
X	    prompt("+");
X	else
X	    prompt("tvx>");
X	reply(rdtbuf,80);		/* read a line */
X	ttynext = 0;			/* reset pointer */
X      }
X    ttymode = TRUE;			/* no echo again */
X    if (rdtbuf[ttynext] == 0)		/* end of buffer */
X      {
X	ttynext = 1000;
X	if (ins_mode)
X	    return (CR);		/* return a carriage return for ins */
X	else
X	    goto RDTOP;			/* read another line */
X      }
X    else
X      {
X	return (rdtbuf[ttynext++]);	/* return character */
X      }
X  }
X
X/* =============================>>> TVPLIN <<<============================= */
X  tvplin(chrptr)
X  BUFFINDEX chrptr;
X  { /* tvplin - put line beginning at chrptr
X		will only type what will fit on screen (using xout) */
X 
X    SLOW char tmp;
X    SLOW int linlen, origx;
X    SLOW BUFFINDEX i;
X 
X#ifdef ULBD
X    SLOW int ul, bd, useul, usebd;
X
X    ul = bd = useul = usebd = FALSE;
X#endif
X
X    last_col_out = linptr = 0;
X    origx = xoutcm;			/* save x so can get true linelen */
X    for (i=chrptr; *(buff+i)!=ENDLINE && xoutcm <= 240; ++i)
X      {
X#ifdef NO_EXTEND_CHAR
X	if ((*(buff+i) < ' ' || (*(buff+i) & 0x80) ) && (*(buff+i) >= 0))
X		/* control character? */
X#else
X	if (*(buff+i)<' ' && *(buff+i) >= 0)	/* control character? */
X#endif
X	  {
X	    if (*(buff+i) == TAB)
X	      {
X		if (tabspc > 0)
X		  {
X		    do 
X		      {
X			linout[linptr++] = ' ';	/* replace with blanks */
X			++xoutcm;
X		      }
X		    while ( ((xoutcm-1) % tabspc) != 0);
X		  }
X		else
X		  {
X		    linout[linptr++] = '^';
X		    linout[linptr++] = 'I';
X		    xoutcm += 2;
X		  }
X		continue;
X	      }
X	    else		/*  other control character */
X	      {
X		linout[linptr++] = (*(buff+i) & 0x80) ? '~' : '^';
X		++xoutcm;
X		if (xoutcm==tvcols && *(buff+i) != ENDLINE)
X		    continue;
X
X/*  #$$$	ascii machines!!!! */
X		tmp = *(buff+i);
X		if ((tmp &= 0x7f) < ' ')	/* ok to mix extended, ctrl */
X		    tmp += '@';
X		linout[linptr++]=tmp;
X
X#ifdef ULBD
X		if ( *(buff+i)==TOGUNDERLINE && cundlb[0] != 0)
X		  {
X		    if (ul)
X		      {
X			strcopy(cundle,0,linout,&linptr);
X			ul = FALSE;
X		      }
X		    else
X		      {
X			strcopy(cundlb,0,linout,&linptr);
X			useul = TRUE;
X			ul = TRUE;
X		      }
X		  }
X		if (*(buff+i) == TOGBOLD && cboldb[0] != 0)
X		  {
X		    if (bd)
X		      {
X			strcopy(cbolde,0,linout,&linptr);
X			bd = FALSE;
X		      }
X		    else
X		      {
X			strcopy(cboldb,0,linout,&linptr);
X			usebd = TRUE;
X			bd = TRUE;
X		      }
X		  }
X#endif		  
X	      }
X	  } /*# end if control character */
X	else 
X	  {
X	    linout[linptr++] = *(buff+i);
X	  }
X	++xoutcm;
X      }
X
X    if (*(buff+chrptr-1)==BEGLINE)		/* write whole line */
X      {
X	last_col_out = linlen = min(tvcols,linptr-leftmg+1);
X	if (linlen > 0)
X	  {
X	    tvlout(&linout[leftmg-1],linlen);
X	  }
X      }
X    else
X      {
X	linlen = min(tvcols-origx+1,linptr);
X	last_col_out = linlen + origx - 1;
X	if (linlen > 0)
X	    tvlout(linout,linlen);
X      }
X#ifdef ULBD
X    if (useul)
X	sendcs(cundle);
X    if (usebd)
X	sendcs(cbolde);
X#endif
X	
X  }
X 
X/* =============================>>> TVLOUT <<<============================= */
X  tvlout(chrbuf,lenbuf)
X  char chrbuf[];
X  int lenbuf;
X  {  /* tvlout - intercepts tvcout calls to use line I/O */
X 
X    if (!(echof && !bakflg))
X	return;
X    ttwtln(chrbuf,lenbuf);	/* write out whole line */
X  }
X 
X/* =============================>>> TVTYPE <<<============================= */
X  tvtype(ibeg,icnt)
X  int ibeg,icnt;
X  { /* tytype - type icnt lines starting at lines[ibeg]
X		no cr/lf on the last line */
X 
X    FAST int i,lim;
X    SLOW BUFFINDEX start;
X 
X    if (!echof)
X	return;
X    xoutcm=tvx;
X    lim = ibeg+icnt-1;
X
X    for (i = ibeg ; i<=lim && i<nxtlin ; ++i)
X      {
X	start = (*(lines+i))+1;
X	tvplin(start);	/* type out a line */
X	xoutcm=1;
X	if (celin[0] && last_col_out < tvcols)
X	    tvelin();	/* erase rest of line */
X	if ( i != lim )
X	  {
X	    tvcout(CR);
X#ifdef USELF
X	    tvcout(LF);
X#endif
X	  }
X      }
X  }
X
X/* =============================>>> SCRPRINT <<<============================= */
X  scrprint()
X  {	/* print screen on printer */
X
X#ifndef UNIX
X 
X   SLOW beg, cnt;
X
X    tvclr();		/* clear screen first */
X    finddl(&beg, &cnt);
X    useprint = TRUE;	/* enable printing */
X    tvtype(beg,cnt);	/* and display/print */
X    printc(CR);		/* force closing cr/lf */
X#ifdef USELF
X    printc(LF);
X#endif
X    useprint = FALSE;
X#endif
X    verify(1);		/* reset screen */
X  }
X 
X/* =============================>>> VERIFY <<<============================= */
X  verify(knt)
X  int knt;
X  { /* verify - rewrite the screen or type current line with cursor */
X
X    SLOW int xf;
X 
X    if (ttymode)
X	ttyverify(knt);
X    else
X      {
X	newscr();
X	xf = findx();
X	tvxy(xf,tvy);	/* reset cursor to current position */
X      }
X  }
X
X/* =============================>>> CSRCMD <<<============================= */
X  csrcmd()
X  {
X    ins_mode = FALSE;		/* let world know in command mode */
X    sendcs(ccsrcm);
X  }
X
X/* =============================>>> CSRINS <<<============================= */
X  csrins()
X  {
X    SLOW int oldx,oldy,oldxot;
X
X    ins_mode = TRUE;		/* in insert mode */
X    sendcs(ccsrin);
X
X    if (tvdlin != tvhardlines)
X      {
X    	oldx = tvx; oldy = tvy; oldxot = xoutcm;
X	tvmsg("### Insert Mode ###",FALSE);
X	tvxy(oldx,oldy);
X	xoutcm = oldxot;
X      }
X  }
X  
X/* **************************************************************************
X
X   tv screen primitives follow
X
X*************************************************************************** */
X 
X/* =============================>>> TVBOTB <<<============================= */
X  tvbotb(n)
X  int n;
X  {  /* tvbotb - make n blank lines at the bottom of the screen */
X 
X    FAST int i,j;
X 
X/*  All versions  control sequences */
X 
X    if (n >= tvlins)
X      {
X	tvclr();
X      }
X    else 
X      {
X	tvxy(1,tvhardlines);	/* go to real last line */
X	for (i = 1 ; i <= n ; ++i)	/* and write n blank lines */
X	    sendcs(cbotb);
X	j=tvlins-n+1;	/* home to virtual last line */
X	tvxy(1,j);	/* position at first new blank line */
X      }
X  }
X 
X/* =============================>>> TVCLR  <<<============================= */
X  tvclr()
X  {  /* tvclr - clear the entire screen and home */
X 
X    tvxy(1,1);
X    tvescr();
X  }
X 
X/* =============================>>> TVCOUT <<<============================= */
X  tvcout(chr)
X  char chr;
X  {  /* tvcout - send one character to the terminal */
X 
X    if (echof && !bakflg)
X	ttwt(chr);
X  }
X 
X/* =============================>>> TVELIN <<<============================= */
X  tvelin()
X  {  /* tvelin - erase the rest of the current line */
X 
X    sendcs(celin);
X  }
X 
X/* =============================>>> TVESCR <<<============================= */
X  tvescr()
X  {  /* tvescr - erase from current cursor position to end of screen */
X 
X    SLOW int oldx,oldy;
X    FAST int i;
X
X    if (cescr[0])
X	sendcs(cescr);
X    else
X      {
X	oldx = tvx ; oldy = tvy ;
X	tvelin();
X	for (i = oldy+1 ; i <= tvhardlines ; ++i)
X	  {
X	    tvxy(1,i);
X	    tvelin();
X	  }
X	tvxy(oldx,oldy);
X      }
X  }
X 
X/* =============================>>> TVINSL <<<============================= */
X  tvinsl()
X  {  /* tvinsl - insert line, handle virtual screen size */
X 
X    SLOW int oldx,oldy;
X    FAST int i;
X
X    oldx = tvx ; oldy = tvy ;
X    sendcs(ciline);
X    if (tvlins != tvhardlines)
X      {
X	tvxy(1,tvlins+1);	/* kill scrolled down line */
X	tvelin();
X	tvxy(oldx,oldy);
X      }
X  }
X 
X/* =============================>>> TVTOPB <<<============================= */
X  tvtopb(n)
X  int n;
X  {  /* tvtopb - create n blank lines at the top of the screen */
X 
X    FAST int i;
X
X    if (! ctopb[0])
X	return;
X    tvxy(1,1);		/* home first */
X    if ( n >= tvlins)
X	tvescr();	/* simply erase the screen */
X    else
X      {
X	for (i = 1 ; i <= n ; ++i)
X	    sendcs(ctopb);
X	if (tvlins != tvhardlines)
X          {
X	    tvxy(1,tvlins+1);	/* kill scrolled down line */
X	    tvelin();
X	    tvxy(1,1);
X	  }
X      }
X  }
X 
X/* =============================>>> TVXY   <<<============================= */
X  tvxy(ix,iy)
X  int ix,iy;
X  {  /* tvxy - position cursor at position x,y 
X		x=0 is left most column
X		y=0 is top most line	*/
X 
X#ifdef TERMCAP			/* TERMCAP different */
X
X    tvx=ix;
X    tvy=iy;
X    tcapxy(ix,iy);		/* call termcap version of xy */
X
X#else				/* generic version of tvxy */
X
X    SLOW int x,y, coord1, coord2;
X    FAST int i;
X    SLOW char chrrep[4];
X 
X    x = min(ix+addx,tvcols+addx);	/* column is addx */
X    y = iy+addy;			/* same for row */
X    tvx = ix;
X    tvy = iy;
X
X    sendcs(cxybeg);		/* opening control sequence */
X    if (cxy1st == 'l')
X      {
X	coord1 = y ; coord2 = x;
X      }
X    else
X      {
X	coord1 = x ; coord2 = y;
X      }
X
X    if (cxychr)
X      {
X	itoa(coord1,chrrep);
X	sendcs(chrrep);
X      }
X    else
X	tvcout(coord1);
X
X    sendcs(cxymid);		/* middle control sequence */
X
X    if (cxychr)
X      {
X	itoa(coord2,chrrep);
X	sendcs(chrrep);
X      }
X    else
X	tvcout(coord2);
X
X    sendcs(cxyend);		/* send terminating sequence */
X
X#endif				/* end of gerneric version */
X  }
X
X/* =============================>>> SENDCS <<<============================= */
X  sendcs(cs)
X  char cs[];
X  {	/* send a control sequencs to terminal */
X
X    FAST int i;
X
X#ifndef UNIX
X
X    for (i = 0 ; cs[i] ; ++i)
X	tvcout(cs[i]);
X#else				/* unix version */
X
X#ifdef TERMCAP			/* termcap uses special output */
X    tcapcs(cs);			/* send control string to termcap */
X#else
X    i = strlen(cs);
X    tvlout(cs,i);
X#endif				/* terminal specific unix version */
X
X#endif				/* end of unix version */
X  
X  }
X
X/* =============================>>> GKBD   <<<============================= */
X  gkbd(chr)
X  char *chr;
X  {  /* gkbd - get one character from the keyboard */
X 
X#ifdef VB
X    if (!bakflg)
X      {
X#endif
X	do 
X	  {
X	    *chr = ttrd();	/* read only if non-backup version */
X	  }
X	while (*chr == 0);	/* ignore EOS character */
X#ifdef VB
X      }
X    else
X	getbak(chr);
X    putbak(*chr);	/* save to backup file */
X#endif
X  }
X
X#ifndef UNIX
X/* =============================>>> TTWTLN <<<============================= */
X  ttwtln(chrbuf,len)
X  char chrbuf[];
X  int len;
X  {  /*  write one line to terminal, generic version, unix uses its own */
X 
X    FAST int i;
X
X    for (i = 0 ; i < len ; i++)
X	ttwt(chrbuf[i]);
X  } 
X#endif
X
X#ifdef CPM
X/* ===========================>>> DISPCH <<<============================== */
X  dispch(chr)
X  char chr;
X  {
X
X	bdos(2,chr);	/* cp/m, ms-dos version */
X  }
X#endif
X#ifdef MSDOS
X#ifndef IBMPC
X/* ===========================>>> DISPCH <<<============================== */
X  dispch(chr)
X  char chr;
X  {
X
X	bdos(2,chr);	/* cp/m, ms-dos version */
X  }
X#endif
X/* =============================>>> USER_1 <<<============================= */
X  user_1(knt)
X  int knt;
X  {
X    knt = 0;
X    return (TRUE);
X  }
X
X/* =============================>>> USER_2 <<<============================= */
X  user_2(knt)
X  int knt;
X  {
X    knt = 0;
X    return (TRUE);
X  }
X#endif
X
X#ifdef GEMDOS
X/* ===========================>>> DISPCH <<<============================== */
X  dispch(chr)
X  char chr;
X  {
X
X	gemdos(2,chr);	/* cp/m, ms-dos version */
X  }
X
X/* =============================>>> USER_1 <<<============================= */
X  user_1(knt)
X  int knt;
X  {
X    knt = 0;
X    return (TRUE);
X  }
X
X/* =============================>>> USER_2 <<<============================= */
X  user_2(knt)
X  int knt;
X  {
X    knt = 0;
X    return (TRUE);
X  }
X#endif
X/* ---------------------------- tvx_io.c ------------------------------- */
SHAR_EOF
echo Extracting tvx_unix.c:
sed 's/^X//' >tvx_unix.c <<\SHAR_EOF
X/* -------------------------- tvx_unix.c ------------------------------ */
X#include "tvx_defs.ic"
X#include "tvx_glbl.ic"
X
X#define TEMPEXT ".$$1"		/* temporary file */
X#define BACKEXT ".B"		/* backup file */
X#define SWITCH '-'
X#define FILESEP '.'
X
X/* define USETMP if you want intermediate workfiles built on
X   /tmp.  Otherwise, they will be built on the same directory as
X   the original file.  This latter method is often a bit faster,
X   especially when exiting if /tmp is on a different volume than
X   the destination file (which makes mv COPY the file rather than
X   just renameing. */
X
X/* #define USETMP */			/* define if create temp files on /tmp */
X
X#include <ctype.h>
X#include <sys/ioctl.h>
X#include <sys/types.h>
X
X
X/* --------------  terminal I/O stuff --------------- */
X
Xstatic struct sgttyb sgb;
Xstatic struct tchars tch;
Xstatic struct ltchars ltc;
X
X#define Ioctl ioctl
X#define Read read
X#define Write write
X
X/* ------------- file mode stuff ---------------------- */
X#include <sys/stat.h>
X  static struct stat info;		/* structure to get info */
X
X/* ------------- misc stuff ---------------------- */
X
X  extern int errno;
X  extern char **environ;
X
X
X#ifdef TERMCAP			/* routines needed for termcap */
X/* ------------- termcap stuff ---------------------- */
X  char PC;
X  char *BC;
X  char *UP;
X  char TERM[40];
X  short ospeed;
X
X  static char Tcm[80];		/* special entry for cm */
X  static char empty[2];
X  static char Tbc[20];
X  static char Tup[20];
X
X  static int	Tco,			/* number of columns per line */
X		Tli;			/* number of lines */
X
X  static char tcbuff[1024];		/* buffer to hold termcap entry */
X 
X
X/* ==========================>>> gettermcap  <<<========================= */
X  gettermcap()
X  {
X    char *tp;
X    char *getenv();
X    char entry[80];		/* scratch buffer for entry */
X
X    empty[0] = 0;
X
X    ospeed = sgb.sg_ospeed;	/* get the speed */
X
X    if ((tp = getenv("TERM")) == NULL)
X      {
X	goto FORCETTY;
X      }
X    strcpy(TERM,tp);		/* copy to our TERM */
X
X    if (tgetent(tcbuff,TERM) < 1)
X      {
X	goto FORCETTY;
X      }
X
X/*	read required termcap entries, save in appropriate TVX arrays */
X
X    if (!gettcap("cm",Tcm))
X      {
X	goto FORCETTY;
X      }
X
X    if (!gettcap("ce",entry))
X      {
X	goto FORCETTY;
X      }
X    if (!capcpy(celin,entry,7))	/* copy entry to end of line */
X      {
X	goto FORCETTY;
X      }
X    
X    gettcap("cd",entry);		/* clear to end of display */
X    capcpy(cescr,entry,7);
X
X    gettcap("al",entry);		/* insert a line (add line) */
X    capcpy(ciline,entry,7);
X
X    gettcap("dl",entry);	/* delete a line */
X    capcpy(ckline,entry,7);
X
X    if (!gettcap("sr",entry))	/* reverse scroll */
X      {
X	strcpy(ctopb,ciline);	/* add line works the same */
X      }
X    else
X	capcpy(ctopb,entry,7);
X
X    gettcap("ve",entry);		/* stand cursor changer end */
X    capcpy(ccsrcm,entry,7);
X    gettcap("vs",entry);		/* stand cursor changer begin */
X    capcpy(ccsrin,entry,7);
X
X    gettcap("se",entry);		/* stand out end */
X    capcpy(cbolde,entry,7);
X
X    gettcap("so",entry);		/* begin standout */
X    capcpy(cboldb,entry,7);
X
X    cerred[0] = 7;				/* bell for sure */
X    gettcap("vb",entry);		/* visual bell? */
X    if (*entry)
X	capcpy(cerred,entry,7);
X
X    if (!capcpy(&cversn[1],TERM,10))		/* copy name to version */
X	strcpy(cversn,"TERMCAP");
X
X    if ((Tco = tgetnum("co")) < 0)	/* # of cols */
X	Tco = 79;		/* assume 80 x 24 */
X    if ((Tli = tgetnum("li")) < 0)	/* # of lines */
X	Tli = 24;		/* assume 80 x 24 */
X
X    tvhardlines = tvlins = Tli;	/* number of lines */
X    tvcols = Tco - 1; /* set col val (-1 avoids all the line wrap crap )*/
X    if (tvhardlines != 24 || tvhardlines != 25)	/* strange terminal */
X      {
X	ddline = (tvlins / 2) + 1;
X	setdscrl();		/* calculate scroll */
X      }
X
X    gettcap("bc",entry);		/* get backspace character */
X    if (!*entry)
X      {
X	Tbc[0] = 8; Tbc[1] = 0;
X      }
X    else
X	capcpy(Tbc,entry,19);
X    BC = Tbc;
X    gettcap("up",entry);		/* get backspace character */
X    if (!*entry)
X      {
X	Tup[0] = 0;
X      }
X    else
X	capcpy(Tup,entry,19);
X    UP = Tup;
X    gettcap("pc",entry);		/* get the pad character */
X    PC = *entry;
X
X    gettcap("is",entry);		/* initialization string */
X    tcapcs(entry);			/* send the intialization string */
X
X    gettcap("ti",entry);		/* cm initialization string */
X    tcapcs(entry);			/* send the intialization string */
X
X    return;
X
XFORCETTY:
X   force_tty = TRUE;
X   remark("Unable to set up for video terminal, tty mode assumed.");
X   strcpy(cversn,"tty");
X  }
X
X/* =============================>>> capcpy  <<<============================= */
X  capcpy(to,from,len)
X  char *to, *from;
X  int len;
X  {		/* copy a capability, checking length */
X    if (strlen(from) > len)
X      {
X	*to = 0;
X	return (FALSE);
X      }
X    else
X	strcpy(to,from);
X    return (TRUE);
X  }
X
X/* =============================>>> gettcap  <<<============================= */
X  gettcap(cap,area)
X  char *cap, *area;
X  {
X    char **cpp, *cp;
X
X    cpp = &cp;		/* I think */
X    cp = area;
X    *area = 0;		/* assume null entry */
X
X    tgetstr(cap,cpp);	/* get the capability */
X    return (*area);		/* return 1st char */
X	
X  }
X
X/* =============================>>> tcapcs  <<<============================= */
X  tcapcs(str)
X  char *str;
X  {
X 	/* send a termcap generated control string to terminal */
X
X    register char *cp;
X    int ttwt();
X
X    if (!(echof && !bakflg && !ttymode))
X	return;
X    if (!*str)		/* don't send null strings */
X	return;
X    cp = str;
X    tputs(cp,1,ttwt);
X
X  }
X
X/* =============================>>> tcapxy  <<<============================= */
X  tcapxy(x,y)
X  int x,y;
X  {
X	/* move cursor to x,y */
X
X   char *tgoto();
X
X   tcapcs(tgoto(Tcm,x-1,y-1));	/* send the string, adjusting x,y */
X
X  }
X#endif   /* termcap */
X
X
X/* =============================>>> ttinit  <<<============================= */
X  ttinit()
X  {
X    struct sgttyb nsgb;
X    struct tchars ntch;
X    struct ltchars nltc;
X
X    (void) Ioctl(0, TIOCGETP, &sgb);
X    (void) Ioctl(0, TIOCGETP, &nsgb);
X    (void) Ioctl(0, TIOCGETC, &tch);
X    (void) Ioctl(0, TIOCGETC, &ntch);
X    (void) Ioctl(0, TIOCGLTC, &ltc);
X
X    nsgb.sg_flags |= CBREAK;
X    nsgb.sg_flags &= ~(CRMOD|ECHO|LCASE|TANDEM);
X
X    ntch.t_intrc = -1;  /* interrupt */
X    ntch.t_quitc = -1;  /* quit */
X
X/* the following two lines control flow control */
X
X#ifndef FLOWCONTROL
X    ntch.t_startc = -1; /* start output */
X    ntch.t_stopc = -1;  /* stop output */
X#endif
X
X    ntch.t_eofc = -1;   /* end-of-file */
X    ntch.t_brkc = -1;   /* input delimiter (like nl) */
X
X    nltc.t_suspc = -1;  /* stop process signal */
X    nltc.t_dsuspc = -1; /* delayed stop process signal */
X    nltc.t_rprntc = -1; /* reprint line */
X    nltc.t_flushc = -1; /* flush output (toggles) */
X    nltc.t_werasc = -1; /* word erase */
X    nltc.t_lnextc = -1; /* literal next character */
X
X    (void) Ioctl(0, TIOCSETP, &nsgb);
X    (void) Ioctl(0, TIOCSETC, &ntch);
X    (void) Ioctl(0, TIOCSLTC, &nltc);
X
X#ifdef TERMCAP
X    gettermcap();			/* set up terminal characteristics */
X#endif
X
X    info.st_mode = -1;			/* no mode stuff yet */
X }
X
X
X/* =============================>>> ttrd_unix  <<<============================= */
X  ttrd_unix()
X  {
X           char c;
X
X    Read(0, &c, 1);
X    return(c);
X  }
X
X/* =============================>>> ttwtln  <<<============================= */
X  ttwtln(cbuf,cnt)
X  char *cbuf;
X  int cnt;
X  {
X    if (echof && !bakflg && !ttymode)
X	Write(1, cbuf, cnt);
X  }
X
X/* =============================>>> ttwt  <<<============================= */
X  ttwt(c)
X  char c;
X  {
X    if (ttymode)
X	return;
X    Write(1, &c, 1);
X  }
X
X/* =============================>>> ttclos  <<<============================= */
X  ttclos()
X  {
X
X#ifdef TERMCAP
X    char entry[80];
X
X    gettcap("te",entry);		/* cm end up string */
X    tcapcs(entry);			/* send it */
X
X#endif
X    (void) Ioctl(0, TIOCSETP, &sgb);
X    (void) Ioctl(0, TIOCSETC, &tch);
X    (void) Ioctl(0, TIOCSLTC, &ltc);
X  }
X
X/* =============================>>> ttosinit  <<<============================= */
X  ttosinit()
X  {			/* need a special version for not doing termcap */
X    struct sgttyb nsgb;
X    struct tchars ntch;
X    struct ltchars nltc;
X    char entry[80];		/* scratch buffer for entry */
X
X    (void) Ioctl(0, TIOCGETP, &sgb);
X    (void) Ioctl(0, TIOCGETP, &nsgb);
X    (void) Ioctl(0, TIOCGETC, &tch);
X    (void) Ioctl(0, TIOCGETC, &ntch);
X    (void) Ioctl(0, TIOCGLTC, &ltc);
X
X    nsgb.sg_flags |= CBREAK;
X    nsgb.sg_flags &= ~(CRMOD|ECHO|LCASE|TANDEM);
X
X    ntch.t_intrc = -1;  /* interrupt */
X    ntch.t_quitc = -1;  /* quit */
X
X/* the following two lines control flow control */
X
X#ifndef FLOWCONTROL
X    ntch.t_startc = -1; /* start output */
X    ntch.t_stopc = -1;  /* stop output */
X#endif
X
X    ntch.t_eofc = -1;   /* end-of-file */
X    ntch.t_brkc = -1;   /* input delimiter (like nl) */
X
X    nltc.t_suspc = -1;  /* stop process signal */
X    nltc.t_dsuspc = -1; /* delayed stop process signal */
X    nltc.t_rprntc = -1; /* reprint line */
X    nltc.t_flushc = -1; /* flush output (toggles) */
X    nltc.t_werasc = -1; /* word erase */
X    nltc.t_lnextc = -1; /* literal next character */
X
X    (void) Ioctl(0, TIOCSETP, &nsgb);
X    (void) Ioctl(0, TIOCSETC, &ntch);
X    (void) Ioctl(0, TIOCSLTC, &nltc);
X
X#ifdef TERMCAP
X    gettcap("is",entry);		/* initialization string */
X    tcapcs(entry);			/* send the intialization string */
X
X    gettcap("ti",entry);		/* cm initialization string */
X    tcapcs(entry);			/* send the intialization string */
X#endif
X }
X
X/* ==========================>>> unix_sys  <<<============================= */
X  unix_sys()
X  {
X    char rp[150];
X    int oldtty;
X
X    tvclr();			/* clear the screen */
X    oldtty = ttymode; ttymode = FALSE;
XDO_UNIX:
X    remark("Unix command interface"); remark("");
X    remark("Enter Unix command line: ");
X    reply(rp,149);
X    reset();		/* reset terminal to unix mode */
X
X    system(rp);
X
X    ttosinit();		/* reset terinal to our mode */
X
X    remark("");
X    remark("");
X
X    prompt("Any key to continue with edit (! for another Unix command): ");
X    reply(rp,1);
X
X    trmini();		/* this has to be here or screen is cleared! */
X    if (*rp == '!')
X	goto DO_UNIX;
X
X    ttymode = oldtty;
X    verify(1);
X  }
X
X/* =============================>>> get_mode <<<============================= */
X  get_mode(f)
X  FILE *f;
X  {		/* gets access mode of open file f */
X
X    char rp[10];
X
X    info.st_mode = -1;	/* assume no mode */
X
X    if (newfil)
X	return;
X    if (fstat(fileno(f),&info) != 0)
X      {
X	info.st_mode = -1;	/* assume no mode */
X	return;
X      }
X    info.st_mode &= 07777;	/* zap extraneous stuff*/
X    if (((info.st_mode & 0222) == 0) && !rdonly)  /* no write permission */
X      {
X	prompt("No write permission for file, edit R/O? (y/n) ");
X	ureply(rp,1);
X	if (*rp == 'Y')
X	    rdonly = TRUE;
X	else
X	  {
X	    reset();
X	    exit(999);
X	  }
X      }
X  }
X
X/* =============================>>> set_mode <<<============================= */
X  set_mode(f)
X  FILE *f;
X  {		/* sets access mode of open file f */
X    if (newfil || info.st_mode == -1)
X	return;
X    if (fchmod(fileno(f),info.st_mode) != 0)
X	tverrb("Unable to set file mode, umask will be used.");
X  }
X
X/* ==========================>>> expand_name <<<============================ */
X  expand_name(n)
X  char *n;
X  {		/* expands unix file names */
X    char tmp[FNAMESIZE+1];
X
X    if ((*n == '~') && (n[1] == '/'))
X      {
X	strcpy(tmp,getenv("HOME"));
X	scopy(n,1,tmp,strlen(tmp));
X	strcpy(n,tmp);
X      }
X  }
X
X/* =============================>>> ren_file <<<=========================== */
X  ren_file(old,new)
X  char *old, *new;
X  {
X    int pid;
X    static char *mvarg[4];
X    static int status;
X
X    if (rename(old,new) != 0)
X      {
X	mvarg[0] = "/bin/mv";
X	mvarg[1] = old;
X	mvarg[2] = new;
X	mvarg[3]=0;
X	pid=fork();
X	if (pid == 0)
X	  {
X	    execve("/bin/mv",mvarg,environ);
X            tverrb("Error trying to start mv utility");
X	    _exit(999);
X	  }
X	wait(&status);
X	if (status > 255)		/* error return */
X	  {
X	    prompt(old) ; prompt(" not renamed to "); remark(new);
X	    prompt("Edited file found as: "); remark(old);
X	  }
X      }
X  }
X
X/* =============================>>> temp_name <<<=========================== */
X  temp_name(n,first)
X  char *n;
X  int first;
X  {
X	/* generates a temporary name from n.  Depending on value of
X	   first, it will either add a 1 or 2 to name */
X    SLOW int i;
X
X#ifdef USETMP
X    SLOW char pidno[20];
X    long pidint;
X
X    if (first)			/* create full temp name */
X      {
X	*n = 0;
X	pidint=getpid();
X	itoa(pidint,pidno);
X	strcpy(n,"/tmp/tvx1");
X	scopy(pidno,0,n,9);
X      }
X    else			/* alternate between 1 and 2 */
X      {
X	if (n[8] == '1')
X	    n[8] = '2';
X	else
X	    n[8] = '1';
X      }
X#else
X    if (first)
X      {
X	if ((i = rindex(n,FILESEP)) > 0)	/* see if extenstion */
X	    scopy(TEMPEXT,0,n,i);		/* make .bak */
X	else
X	  {
X	    scopy(TEMPEXT,0,n,strlen(n));	/* just add on */
X	  }
X      }
X    else
X      {
X	i = strlen(n);
X	if (n[i-1] == '1')
X	    n[i-1] = '2';
X	else
X	    n[i-1] = '1';
X      }
X#endif
X  }
X
X#ifndef SUN
X/* =============================>>> USER_1 <<<============================= */
X  user_1(knt)
X  int knt;
X  {
X    knt = 0;
X    return (TRUE);
X  }
X
X#else
X/* =============================>>> USER_1 <<<============================= */
X  user_1(knt)
X  int knt;
X  {
X	/* for suns, re-initialize window */
X#ifdef TERMCAP
X    gettermcap();		/* set up terminal characteristics */
X    tvidefs();		/* and reset defs */
X#endif
X    verify(1);
X    return (TRUE);
X  }
X#endif
X
X/* =============================>>> USER_2 <<<============================= */
X  user_2(knt)
X  int knt;
X  {
X    knt = 0;
X    return (TRUE);
X  }
X/* -------------------------- tvx_unix.c ------------------------------ */
SHAR_EOF
echo Extracting tvx_ibm.c:
sed 's/^X//' >tvx_ibm.c <<\SHAR_EOF
X/* ------------------------------- tvx_ibm.c ------------------------ */
X#define FALSE 0
X#define TRUE 1
X/*	Interface to IBM ROM BIOS INT10 screen control.  Following
X	control codes are defined:
X
X	^@,0	^A,1	^B,2	^C,3
X	other, erslin, erseos, inslin
X	^D,4	^E,5	^F,6	^G,7
X	undlon, undloff, dellin, bell
X	^H,8	^I,9	^J,10	^K,11
X	backsp,	tab, linefeed, boldon
X	^L,12	^M,13	^N,14	^O,15
X	boldoff, enter, reversoff, blinkoff
X	^P,16	^Q,17	^R,18	^S,19, ^T,20
X	reverson, blinkon, setxy, cursor1, initcursor
X */
X#define m_normal 07	/* white on black */
X#define m_underline 01	/* normal, underlined */
X#define m_reverse 0x70
X#define m_dim 0xF7	/* dim display */
X#define m_bright 0x08	/* bright display */
X#define m_blink	0x80	/* blink for errors */
X#define m_noblink 0x7F
X
X
X/* ============================ dispch ============================== */
X  dispch(chin)
X  int chin;
X  {
X
X    static int ch;
X    struct regval
X      {
X	unsigned int ax;
X	unsigned int bx;
X	unsigned int cx;
X	unsigned int dx;
X	unsigned int si;
X	unsigned int di;
X	unsigned int ds;
X	unsigned int es;
X      };
X    struct regval rin, rout;
X
X	/* data structures for screen control */
X    static int ich;
X    static int maxcol = 79;		/*  max col, counting from 0 */
X    static int savechar;
X    static int initflg = FALSE;
X    static int curpage = 0;		/* current display page (internal) */
X    static int curmode = 7;		/* white on black */
X    static int curcol;			/* col and row, preserve this order */
X    static int currow;			/* so can load in one instruction */
X    static int curstate = 0;		/* 0: accepting chars
X					   1: waiting for row
X					   2: waiting for col */
X    static int rowpend = 0;		/* to save pending row */
X    static int initcursor;		/* initial cursor */
X    static int altcursor;
X    static int color;		/* mono or color */
X
X    ch = chin & 0xff;
X
X    if (!initflg)
X      {
X	rin.ax = 0x0F00;		/* ah is 15, get video state */
X	sysint(0x10, &rin, &rout);	/* int 10h */
X	maxcol = ((rout.ax >> 8) & 0xff) - 1;	/* make relative value (0-79) */
X  	curpage = (rout.bx >> 8) & 0xff;	/* the active page */
X	rin.ax = 0x0300;		/* read cursor position */
X	sysint(0x10, &rin, &rout);	/* int 10h */
X	curcol = rout.dx & 0xff;	/* low order is col */
X	currow = (rout.dx >> 8) & 0xff;
X	sysint(0x11,&rin,&rout);	/* get system configuration */
X	color = (rout.ax & 0x30) != 0x30;
X	if (!color)
X	  {
X	    initcursor = 0x0c0d;	/* 12, 13 - avoids PC ROM bug! */
X	    altcursor = 0x060d;		/* 6,13 for insert */
X	  }
X	else
X	  {
X	    initcursor = 0x0607;	/* current cursor mode, color */
X	    altcursor = 0x0307;		/* half block */
X	  }
X	initflg = TRUE;
X      }
X
X
X    if (curstate != 0)		/* waiting for row or col? */
X      {
X	if (curstate == 1)
X	  {
X		/* in state 1, so this is row */
X	    rowpend = ch;		/* save pending row */
X	    curstate = 2;		/* now in wait state */
X	    return;
X	  }
X	else		/* waiting for column */
X	  {
X	    ich = ch - ' ';	/* convert to absolute */
X	    if (ich > maxcol)
X		ich = maxcol;
X	    curcol = ich;	/* remember column */
X	    rowpend -= ' ';	/* convert row */
X	    if (rowpend > 24)
X		rowpend = 24;
X	    currow = rowpend;
X	    rin.dx = (currow << 8) | curcol;
X	    rin.bx = curpage << 8;
X	    rin.ax = 0x200;	/* 2 => set cursor */
X	    sysint(0x10, &rin, &rout);	/* int 10h */
X	    curstate = 0;
X	    return;
X	  }
X      }
X    else
X      {
X	if (ch >= ' ')
X	    goto SHOWCHAR;	/* slight optimization */
X
X	switch (ch)
X	  {
X	    case 1:		/* erase from cursor to end of line */
Xerslin:
X		rin.cx = rin.dx = currow << 8;		/* set row */
X		rin.cx |= curcol;		/* set col */
X		rin.dx |= maxcol;		/* blank to max col */
X		rin.ax = 0x600;	      /* scroll active page up, blank section */
X		rin.bx = curmode << 8;
X		sysint(0x10, &rin, &rout);	/* int 10h */
X		return;
X
X	    case 2:		/* erase from cursor to end of screen */
X		/* first, earase current row */
X		rin.cx = rin.dx = currow << 8;		/* set row */
X		rin.cx |= curcol;		/* set col */
X		rin.dx |= maxcol;		/* blank to max col */
X		rin.ax = 0x600;	      /* scroll active page up, blank section */
X		rin.bx = curmode << 8;
X		sysint(0x10, &rin, &rout);	/* int 10h */
X		if (currow >= 24)	/* on bottom row now? */
X		    return;
X		rin.cx = (currow + 1) << 8; 	/* next row, col 0 */
X		rin.dx = 0x1800 | maxcol;
X		rin.ax = 0x0600;		/* 6: scroll 0: blank */
X		sysint(0x10, &rin, &rout);	/* int 10h */
X		return;
X
X	    case 3:		/* insert a blank line at cursor */
X		if (currow < 24)
X		  {
X		    rin.cx = (currow << 8);
X		    rin.dx = 0x1800 | maxcol;	/* define window to scroll */
X		    rin.bx = curmode << 8;
X		    rin.ax = 0x0701;		/* one line, scroll down */
X		    sysint(0x10, &rin, &rout);	/* int 10h */
X		  }
X		curcol = 0;		/* home to line beginning */
X		rin.dx = currow << 8;	/* dh = currow, dl = 0 */
X		rin.bx = curpage << 8;
X		rin.ax = 0x0200;	/* reset cursor position */
X		sysint(0x10, &rin, &rout);	/* int 10h */
X		if (currow >= 24)	/* special case */
X		    goto erslin;
X		return;
X
X	    case 4:		/* underline on */
X		curmode = (curmode & 0x88) | m_underline;
X		return;
X
X	    case 5:		/* underline off */
X		curmode = (curmode & 0x88) | m_normal;
X		return;
X
X	    case 6:			/*  kill line cursor is on */
X		rin.cx = currow << 8;	/* define window to scroll */
X		rin.dx = 0x1800 | maxcol;
X		rin.ax = 0x0601;		/* one line (al), scroll up (6) */
X		rin.bx = curmode << 8;
X		sysint(0x10, &rin, &rout);	/* int 10h */
X		curcol = 0 ;		/* home to line beginning */
X		rin.dx = currow << 8;
X		rin.bx = curpage << 8;
X		rin.ax = 0x0200;
X		sysint(0x10, &rin, &rout);	/* int 10h */
X		return;
X
X	    case 7:		/* bell */
X		bdos(2,ch);
X		return;
X
X	    case 8:		/* backspace */
X		if (curcol <= 0)
X		    return;
X		--curcol;
X		rin.bx = curpage << 8;
X		rin.dx = (currow << 8) | curcol;
X		rin.ax = 0x0200;	/* set cursor pos */
X		sysint(0x10, &rin, &rout);	/* int 10h */
X		return;
X
X	    case 9:		/* tab */
X		ch = ' ';
X		goto SHOWCHAR;
X
X	    case 10:		/* line feed, scroll if bottom */
X		if (currow < 24)
X		  {
X		    rin.dx = (++currow << 8) | curcol;
X		    rin.bx = curpage << 8;
X		    rin.ax = 0x0200;		/* set cursor */
X		    sysint(0x10, &rin, &rout);	/* int 10h */
X		  }
X		else
X		  {
X			/* need to scroll up */
X		    rin.ax = 0x0601;	/* scroll up (6) 1 line (1) */
X		    rin.cx = 0;		/* upper right */
X		    rin.dx = 0x1800 | maxcol;
X		    rin.bx = curmode << 8;
X		    sysint(0x10, &rin, &rout);	/* int 10h */
X		  }
X		return;
X
X	    case 11:		/* bold on */
X		curmode |= m_bright;
X		return;
X
X	    case 12:		/* bold off */
X		curmode &= m_dim;
X		return;
X
X	    case 13:		/* CR, include erase end of line */
X		if (curcol >= maxcol)
X		    goto NOBLANK;
X		rin.cx = rin.dx = currow << 8;		/* set row */
X		rin.cx |= curcol;		/* set col */
X		rin.dx |= maxcol;		/* blank to max col */
X		rin.ax = 0x0600;	/* scroll up, blank section */
X		rin.bx = curmode << 8;
X		sysint(0x10, &rin, &rout);	/* int 10h */
XNOBLANK:
X		curcol = 0;
X	        rin.dx = (currow << 8);
X		rin.bx = curpage << 8;
X		rin.ax = 0x0200;
X		sysint(0x10, &rin, &rout);	/* int 10h */
X		return;
X
X	    case 14:		/* reverse off */
X		curmode = (curmode & 0x88) | m_normal ;
X		return;
X
X	    case 15:		/* blink off */
X		curmode &= m_noblink;
X		return;
X
X	    case 16:		/* reverse on */
X		curmode = (curmode & 0x88) | m_reverse;
X		return;
X
X	    case 17:		/* blink on */
X		curmode |= m_blink;
X		return;
X
X	    case 18:		/* set xy */
X		curstate = 1;
X		return;
X
X	    case 19:			/* change cursor */
X		rin.ax = 0x0100;	/* set cursor type */
X		rin.cx = altcursor;	/* half block */
X		sysint(0x10, &rin, &rout);
X		return;
X
X	    case 20:			/* change cursor */
X		rin.ax = 0x0100;	/* set cursor type */
X		rin.cx = initcursor;	/* original */
X		sysint(0x10, &rin, &rout);
X		return;
X
X
X	    default:		/* show char */
XSHOWCHAR:
X		if (curcol > maxcol)	/* update column */
X		    return;
X		rin.ax = 0x0900 | ch;		/* display char */
X		rin.bx = (curpage << 8) | curmode;
X		rin.cx = 1;
X		sysint(0x10, &rin, &rout);	/* int 10h */
X		++curcol;
X		rin.dx = (currow << 8) | curcol;
X		rin.ax = 0x0200;
X		sysint(0x10, &rin, &rout);	/* int 10h */
X		return;
X	  }	/* end of switch */
X      }		/* end of else */
X  }
X/* ------------------------------- tvx_ibm.c ------------------------ */
SHAR_EOF
echo ALL DONE!
exit 0



More information about the Comp.sources.unix mailing list