*BSD News Article 9914


Return to BSD News archive

Received: by minnie.vk1xwt.ampr.org with NNTP
	id AA6797 ; Fri, 15 Jan 93 10:35:13 EST
Xref: sserve comp.unix.bsd:9971 alt.sources:4992
Path: sserve!manuel.anu.edu.au!munnari.oz.au!sgiblab!darwin.sura.net!paladin.american.edu!news.univie.ac.at!hp4at!mcsun!Germany.EU.net!hcshh!hm
From: hm@hcshh.hcs.de (Hellmuth Michaelis)
Newsgroups: comp.unix.bsd,alt.sources
Subject: [386BSD] pcvt 2.00 - VT220 console driver (part 10/11)
Summary: 386BSD 0.1 VT220 console device driver source code
Keywords: 386BSD console driver VT220
Message-ID: <1626@hcshh.hcs.de>
Date: 15 Jan 93 13:03:16 GMT
Followup-To: comp.unix.bsd
Organization: HCS GmbH, Hamburg, Europe
Lines: 3625

Submitted-by: hm@hcshh.hcs.de (Hellmuth Michaelis)
Archive-name: pcvt-2.00/part10

---- Cut Here and unpack ----
#!/bin/sh
# This is part 10 of pcvt-2.00
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= pcvt_out.c ==============
if test X"$1" != X"-c" -a -f 'pcvt_out.c'; then
	echo "File already exists: skipping 'pcvt_out.c'"
else
echo "x - extracting pcvt_out.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > pcvt_out.c &&
X/*
X * Copyright (c) 1992, 1993 Hellmuth Michaelis and Brian Dunford-Shore.
X *
X * All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * William Jolitz and Don Ahn.
X *
X * This driver is contributed to the 386BSD operating system.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X *    must display the following acknowledgement:
X *	This product includes software contributed to 386BSD and developed
X *      by Hellmuth Michaelis and Brian Dunford-Shore.
X * 4. Neither the name of the developers nor the names "386BSD" and "pcvt"
X *    may be used to endorse or promote products derived from this software
X *    without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
X * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
X/*
X *	@(#)pcvt_out.c		2.00		   (contributed to 386BSD)
X *				Last Edit-Date: [Tue Jan 12 13:56:36 1993]
X */
X
X/*---------------------------------------------------------------------------*
X *
X *	pcvt_out.c	VT220 Terminal Emulator for Video Displays
X *	----------------------------------------------------------
X *
X *	written by Hellmuth Michaelis, hm@hcshh.hcs.de          and
X *		   Brian H. Dunford-Shore, brian@morpheus.wustl.edu
X *
X *	-hm	released alpha version 1.0 to alt.sources
X *	-hm	last char on line debugging
X *	-hm	fixed bug in erase in display and erase in line
X *	-hm	downloadable character sets from brian dunford-shore
X *	-hm	revised function key labels & status line policy
X *	-hm	adapter detection from brian dunford-shore
X *	-hm	intro of vt_pure_mode
X *	-hm	cursorshape ioctl changed
X *	-hm	screeninfo ioctl
X *	-hm	vt220 character sets and escape sequences
X *	-hm	keypad application/numeric
X *	-hm	cursor key mode
X *	-hm	character set conversion tables
X *	-hm	color cleanup ...
X *	-hm	ansi function prototypes
X *	-hm	independent conversion tables for ega/vga and mda/hcg/cga
X *	-hm	integrating brian's dowloadable charset functionality
X *	-hm	integrating brian's user defined keys and fiddlin' pcvt_kbd.c
X *	-hm	cleanup, polish & housekeeping ....
X *	-hm	masking minor driver number
X *	-hm	display functions cleanup
X *	-hm	new select graphic rendition scheme
X *	-hm	removing bug in vt_aln()
X *	-hm	lovely timebomb fix in respond() from scotty
X *
X *---------------------------------------------------------------------------*/
X
X#include "pcvt_hdr.h"		/* global include */
X#include "pcvt_tbl.h"		/* character set conversion tables */
X
Xstatic void write_char ( struct video_state *svsp, u_char kernel, u_char ch );
Xstatic void vt_coldinit ( void );
Xstatic void check_scroll ( struct video_state *svsp );
Xstatic void vt_str ( struct video_state *svsp );
Xstatic void writefkl ( int num, unsigned char *string, struct video_state *svsp );
Xstatic void swritefkl ( int num, unsigned char *string, struct video_state *svsp );
Xstatic void wrfkl ( int num, unsigned char *string, struct video_state *svsp );
Xstatic void vt_stbm ( struct video_state *svsp );
Xstatic void vt_sgr ( struct video_state *svsp );
Xstatic void vt_cuu ( struct video_state *svsp );
Xstatic void vt_cud ( struct video_state *svsp );
Xstatic void vt_cuf ( struct video_state *svsp );
Xstatic void vt_cub ( struct video_state *svsp );
Xstatic void vt_clreos ( struct video_state *svsp );
Xstatic void vt_clreol ( struct video_state *svsp );
Xstatic void vt_curadr ( struct video_state *svsp );
Xstatic void vt_ris ( struct video_state *svsp );
Xstatic void vt_ri ( struct video_state *svsp );
Xstatic void vt_ind ( struct video_state *svsp );
Xstatic void vt_nel ( struct video_state *svsp );
Xstatic void roll_up ( struct video_state *svsp );
Xstatic void roll_down ( struct video_state *svsp );
Xstatic void vt_set_dec_priv_qm ( struct video_state *svsp );
Xstatic void vt_reset_dec_priv_qm ( struct video_state *svsp );
Xstatic void vt_set_ansi ( struct video_state *svsp );
Xstatic void vt_reset_ansi ( struct video_state *svsp );
Xstatic void vt_clrtab ( struct video_state *svsp );
Xstatic void vt_sc ( struct video_state *svsp );
Xstatic void vt_rc ( struct video_state *svsp );
Xstatic void vt_designate ( struct video_state *svsp);
Xstatic void swcsp(struct video_state *svsp, u_short *ctp);
Xstatic void vt_da ( struct video_state *svsp );
Xstatic void vt_aln ( struct video_state *svsp );
Xstatic void vt_reqtparm ( struct video_state *svsp );
Xstatic void vt_tst ( struct video_state *svsp );
Xstatic void vt_dsr ( struct video_state *svsp );
Xstatic void vt_il ( struct video_state *svsp );
Xstatic void vt_ic ( struct video_state *svsp );
Xstatic void vt_dl ( struct video_state *svsp );
Xstatic void vt_dch ( struct video_state *svsp );
Xstatic void vt_su ( struct video_state *svsp );
Xstatic void vt_sd ( struct video_state *svsp );
Xstatic void vt_ech ( struct video_state *svsp );
Xstatic void vt_mc ( struct video_state *svsp );
Xstatic void vt_udk ( struct video_state *svsp );
Xstatic void init_udk ( struct video_state *svsp );
Xstatic void vt_dld ( struct video_state *svsp );
Xstatic void clear_dld ( struct video_state *svsp );
Xstatic void init_dld ( struct video_state *svsp );
Xstatic void vt_sca ( struct video_state *svsp );
Xstatic void init_sel ( struct video_state *svsp );
Xstatic void selective_attribute ( struct video_state *svsp );
Xstatic void selective_erase ( struct video_state *svsp, u_short *pcrtat, int length );
Xstatic void vt_sel ( struct video_state *svsp );
Xstatic void vt_sed ( struct video_state *svsp );
Xstatic void hp_entry ( u_char ch, struct video_state *svsp );
Xstatic void dcs_entry ( u_char ch, struct video_state *svsp );
Xstatic void clear_udk ( struct video_state *svsp );
X
X/*---------------------------------------------------------------------------*
X *	emulator main entry
X *---------------------------------------------------------------------------*/
Xvoid sput(u_char ch, u_char attrib, int page)
X{
X	register struct video_state *svsp;
X	
X	page &= MINORMASK;
X	
X	svsp = &vs[page];
X
X	if(do_initialization)
X		vt_coldinit();
X
X	if(svsp->sevenbit)
X		ch &= 0x7f;
X
X#ifdef PCVT_SCREENSAVER
X	if(svsp == vsp)
X		/* on current page */
X		pcvt_scrnsv_reset();
X#endif
X
X	if((ch <= 0x1f) && (svsp->transparent == 0))
X	{
X	
X/* always process control-chars in the range 0x00..0x1f !!! */
X
X		if(svsp->dis_fnc)
X		{
X			if(svsp->lastchar && svsp->m_awm && (svsp->lastrow == svsp->row))
X			{
X				svsp->crtat++;
X				svsp->col = 0;
X				svsp->lastchar = 0;
X				check_scroll(svsp);
X			}
X
X			if(svsp->irm)
X				ovbcopy(svsp->crtat, svsp->crtat + 1, (MAXCOL - svsp->col) * CHR);
X					
X			write_char(svsp, attrib, ch);
X
X			selective_attribute(svsp);
X
X			if(svsp->col >= MAXCOL && ch != 0x0a && ch != 0x0b && ch != 0x0c)
X			{
X				svsp->lastchar = 1;
X				svsp->lastrow = svsp->row;
X			}
X			else if(ch == 0x0a || ch == 0x0b || ch == 0x0c)
X			{
X				svsp->crtat -= svsp->col;
X				svsp->crtat += COL;
X				svsp->col = 0;
X				svsp->lastchar = 0;
X			}
X			else
X			{
X				svsp->crtat++;
X				svsp->col++;
X				svsp->lastchar = 0;
X			}
X		}			
X		else
X		{
X			switch(ch)	
X			{
X				case 0x00:	/* NUL */
X				case 0x01:	/* SOH */
X				case 0x02:	/* STX */
X				case 0x03:	/* ETX */
X				case 0x04:	/* EOT */
X				case 0x05:	/* ENQ */
X				case 0x06:	/* ACK */
X					break;
X					
X				case 0x07:	/* BEL */
X					if(svsp->bell_on)
X						sysbeep(0x31b, hz/4);
X					break;
X					
X				case 0x08:	/* BS */
X					if(svsp->col > 0)
X					{
X						svsp->crtat--;
X						svsp->col--;
X					}
X					break;
X					
X				case 0x09:	/* TAB */
X					while(svsp->col < MAXCOL)
X					{
X						svsp->crtat++;
X						if(svsp->tab_stops[++svsp->col])
X							break;
X					}
X					break;
X					
X				case 0x0a:	/* LF */
X				case 0x0b:	/* VT */
X				case 0x0c:	/* FF */
X					if(svsp->lnm)
X					{
X						svsp->crtat -= svsp->col;
X						svsp->crtat += COL;
X						svsp->col = 0;
X					}
X					else
X					{
X						svsp->crtat += COL;
X					}
X					break;
X					
X				case 0x0d:	/* CR */
X					svsp->crtat -= svsp->col;
X					svsp->col = 0;
X					break;
X					
X				case 0x0e:	/* SO */
X					svsp->GL = svsp->G1;
X					break;
X					
X				case 0x0f:	/* SI */
X					svsp->GL = svsp->G0;
X					break;
X	
X				case 0x10:	/* DLE */
X				case 0x11:	/* DC1/XON */
X				case 0x12:	/* DC2 */
X				case 0x13:	/* DC3/XOFF */
X				case 0x14:	/* DC4 */
X				case 0x15:	/* NAK */
X				case 0x16:	/* SYN */
X				case 0x17:	/* ETB */		
X					break;
X					
X				case 0x18:	/* CAN */
X					svsp->state = STATE_INIT;
X					clr_parms(svsp);
X					break;
X					
X				case 0x19:	/* EM */
X					break;
X					
X				case 0x1a:	/* SUB */
X					svsp->state = STATE_INIT;
X					clr_parms(svsp);
X					break;
X					
X				case 0x1b:	/* ESC */
X					svsp->state = STATE_ESC;
X					clr_parms(svsp);
X					break;
X					
X				case 0x1c:	/* FS */
X				case 0x1d:	/* GS */
X				case 0x1e:	/* RS */
X				case 0x1f:	/* US */
X				break;
X			}
X		}
X	}
X	else
X	{
X		
X	/* char range 0x20...0xff processing depends on current state */	
X		
X		switch(svsp->state)
X		{
X			case STATE_INIT:
X				if(svsp->lastchar && svsp->m_awm && (svsp->lastrow == svsp->row))
X				{
X					svsp->crtat++;
X					svsp->col = 0;
X					svsp->lastchar = 0;
X					check_scroll(svsp);
X				}
X
X				if(svsp->irm)
X					ovbcopy(svsp->crtat, svsp->crtat + 1, (MAXCOL - svsp->col) * CHR);
X					
X				write_char(svsp, attrib, ch);
X
X				selective_attribute(svsp);
X
X				if(svsp->col >= MAXCOL)
X				{
X					svsp->lastchar = 1;
X					svsp->lastrow = svsp->row;
X				}
X				else
X				{
X					svsp->lastchar = 0;
X					svsp->crtat++;
X					svsp->col++;
X				}
X				break;
X
X			case STATE_ESC:
X				switch(ch)
X				{
X	
X					case '#':	/* ESC # family */
X						svsp->state = STATE_HASH;
X						break;
X	
X					case '&':	/* ESC & family (HP) */
X						if(svsp->vt_pure_mode == M_HPVT)
X						{
X							svsp->state = STATE_AMPSND;
X							svsp->hp_state = SHP_INIT;
X						}
X						else
X							svsp->state = STATE_INIT;
X						break;
X	
X					case '(':	/* ESC ( family */
X						svsp->state = STATE_BROPN;
X						break;
X	
X					case ')':	/* ESC ) family */
X						svsp->state = STATE_BRCLO;
X						break;
X	
X					case '*':	/* ESC * family */
X						svsp->state = STATE_STAR;
X						break;
X	
X					case '+':	/* ESC + family */
X						svsp->state = STATE_PLUS;
X						break;
X	
X					case '-':	/* ESC - family */
X						svsp->state = STATE_MINUS;
X						break;
X	
X					case '.':	/* ESC . family */
X						svsp->state = STATE_DOT;
X						break;
X	
X					case '/':	/* ESC / family */
X						svsp->state = STATE_SLASH;
X						break;
X	
X					case '7':	/* SAVE CURSOR */
X						vt_sc(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case '8':	/* RESTORE CURSOR */
X						vt_rc(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case '=':	/* keypad application mode */
X						vt_keyappl(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case '>':	/* keypad numeric mode */
X						vt_keynum(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'D':	/* INDEX */
X						vt_ind(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'E':	/* NEXT LINE */
X						vt_nel(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'H':	/* set TAB at current col */
X						svsp->tab_stops[svsp->col] = 1;
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'M':	/* REVERSE INDEX */
X						vt_ri(svsp);
X						svsp->state = STATE_INIT;
X						break;
X 	
X					case 'N':	/* SINGLE SHIFT G2 */
X						svsp->ss2 = 1;
X						svsp->state = STATE_INIT;
X						break;
X 	
X					case 'O':	/* SINGLE SHIFT G3 */
X						svsp->ss3 = 1;
X						svsp->state = STATE_INIT;
X						break;
X
X					case 'P':	/* DCS detected */
X						svsp->dcs_state = DCS_INIT;
X						svsp->state = STATE_DCS;
X						break;
X
X					case 'Z':	/* What are you = ESC [ c */
X						vt_da(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case '[':	/* CSI detected */
X						clr_parms(svsp);
X						svsp->state = STATE_CSI;
X						break;
X	
X					case '\\':	/* String Terminator */
X						svsp->state = STATE_INIT;
X						break;
X 	
X					case 'c':	/* hard reset */
X						vt_ris(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'n':	/* Lock Shift G2 -> GL */
X						svsp->GL = svsp->G2;
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'o':	/* Lock Shift G3 -> GL */
X						svsp->GL = svsp->G3;
X						svsp->state = STATE_INIT;
X						break;
X	
X					case '}':	/* Lock Shift G2 -> GR */
X						svsp->GR = svsp->G2;
X						svsp->state = STATE_INIT;
X						break;
X	
X					case '|':	/* Lock Shift G3 -> GR */
X						svsp->GR = svsp->G3;
X						svsp->state = STATE_INIT;
X						break;
X	
X					case '~':	/* Lock Shift G1 -> GR */
X						svsp->GR = svsp->G1;
X						svsp->state = STATE_INIT;
X						break;
X	
X					default:
X						svsp->state = STATE_INIT;
X						break;
X				}
X				break;
X	
X			case STATE_HASH:
X				switch(ch)
X				{
X					case '3':	/* double height top half */
X					case '4':	/* double height bottom half */
X					case '5':	/* single width single height */
X					case '6':	/* double width single height */
X						svsp->state = STATE_INIT;
X						break;
X						
X					case '8':	/* fill sceen with 'E's */
X						vt_aln(svsp);
X						svsp->state = STATE_INIT;
X						break;
X						
X					default:	/* anything else */
X						svsp->state = STATE_INIT;
X						break;
X				}
X				break;
X				
X			case STATE_BROPN:	/* designate G0 */
X			case STATE_BRCLO:	/* designate G1 */
X			case STATE_STAR:	/* designate G2 */
X			case STATE_PLUS:	/* designate G3 */
X			case STATE_MINUS:	/* designate G1 (96) */
X			case STATE_DOT:		/* designate G2 (96) */
X			case STATE_SLASH:	/* designate G3 (96) */
X				svsp->which[svsp->whichi++] = ch;
X				if(ch >= 0x20 && ch <= 0x2f && svsp->whichi <= 2)
X					break;
X				else if(ch >=0x30 && ch <= 0x7e)
X				{
X					svsp->which[svsp->whichi] = '\0';
X					vt_designate(svsp);
X				}
X				svsp->whichi = 0;
X				svsp->state = STATE_INIT;
X				break;
X
X			case STATE_CSIQM:	/* DEC private modes */
X				switch(ch)
X				{
X					case '0':
X					case '1':
X					case '2':
X					case '3':
X					case '4':
X					case '5':
X					case '6':
X					case '7':
X					case '8':
X					case '9':	/* parameters */
X						svsp->parms[svsp->parmi] *= 10;
X						svsp->parms[svsp->parmi] += (ch -'0');
X						break;
X	
X					case ';':	/* next parameter */
X						svsp->parmi = 
X						 (svsp->parmi+1 < MAXPARMS) ?
X						 svsp->parmi+1 : svsp->parmi;
X						break;
X	
X					case 'h':	/* set mode */
X						vt_set_dec_priv_qm(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'l':	/* reset mode */
X						vt_reset_dec_priv_qm(svsp);
X						svsp->state = STATE_INIT;
X						break;
X
X					case 'n':	/* Reports */
X						vt_dsr(svsp);
X						svsp->state = STATE_INIT;
X						break;
X
X					case 'K':	/* selective erase in line */
X						vt_sel(svsp);
X						svsp->state = STATE_INIT;
X						break;
X
X					case 'J':	/* selective erase in display */
X						vt_sed(svsp);
X						svsp->state = STATE_INIT;
X						break;
X
X					default:
X						svsp->state = STATE_INIT;
X						break;
X
X				}
X				break;
X				
X			case STATE_CSI:
X				switch(ch)
X				{
X					case '0':
X					case '1':
X					case '2':
X					case '3':
X					case '4':
X					case '5':
X					case '6':
X					case '7':
X					case '8':
X					case '9':	/* parameters */
X						svsp->parms[svsp->parmi] *= 10;
X						svsp->parms[svsp->parmi] += (ch -'0');
X						break;
X	
X					case ';':	/* next parameter */
X						svsp->parmi = 
X						 (svsp->parmi+1 < MAXPARMS) ?
X						 svsp->parmi+1 : svsp->parmi;
X						break;
X	
X					case '?':	/* ESC [ ? family */
X						svsp->state = STATE_CSIQM;
X						break;
X						
X					case '@':	/* insert char */
X						vt_ic(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case '"':	/* select char attribute */
X						svsp->state = STATE_SCA;
X						break;
X	
X					case '!':	/* soft terminal reset */
X						svsp->state = STATE_STR;
X						break;
X	
X					case 'A':	/* cursor up */
X						vt_cuu(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'B':	/* cursor down */
X						vt_cud(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'C':	/* cursor forward */
X						vt_cuf(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'D':	/* cursor backward */
X						vt_cub(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'H':	/* direct cursor addressing */
X						vt_curadr(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'J':	/* erase screen */
X						vt_clreos(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'K':	/* erase line */
X						vt_clreol(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'L':	/* insert line */
X						vt_il(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'M':	/* delete line */
X						vt_dl(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'P':	/* delete character */
X						vt_dch(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'S':	/* scroll up */
X						vt_su(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'T':	/* scroll down */
X						vt_sd(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'X':	/* erase character */
X						vt_ech(svsp);
X						svsp->state = STATE_INIT;
X						break;
X
X					case 'c':	/* device attributes */
X						vt_da(svsp); 
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'f':	/* direct cursor addressing */
X						vt_curadr(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'g':	/* clear tabs */
X						vt_clrtab(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'h':	/* set mode(s) */
X						vt_set_ansi(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'i':	/* media copy */
X						vt_mc(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'l':	/* reset mode(s) */
X						vt_reset_ansi(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'm':	/* select graphic rendition */
X						vt_sgr(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'n':	/* reports */
X						vt_dsr(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'r':	/* set scrolling region */
X						vt_stbm(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'x':	/* request/report parameters */
X						vt_reqtparm(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					case 'y':	/* invoke seftest(s) */
X						vt_tst(svsp);
X						svsp->state = STATE_INIT;
X						break;
X	
X					default:
X						svsp->state = STATE_INIT;
X						break;
X				}
X				break;
X
X			case STATE_AMPSND:
X				hp_entry(ch,svsp);
X				break;
X
X			case STATE_DCS:
X				dcs_entry(ch,svsp);
X				break;
X
X			case STATE_SCA:
X				switch(ch)
X				{
X					case 'q':
X						vt_sca(svsp);
X						svsp->state = STATE_INIT;
X						break;
X						
X					default:
X						svsp->state = STATE_INIT;
X						break;
X				}
X				break;
X
X			case STATE_STR:
X				switch(ch)
X				{
X					case 'p':	/* soft terminal reset */
X						vt_str(svsp);
X						svsp->state = STATE_INIT;
X						break;
X
X					default:
X						svsp->state = STATE_INIT;
X						break;
X				}
X				break;
X
X			default:		/* failsafe */
X				svsp->state = STATE_INIT;
X				break;
X
X		}
X	}
X
X	check_scroll(svsp);				/* check scroll up */
X
X	svsp->row = ((svsp->crtat - svsp->Crtat)/COL);	/* current row update */
X
X	if((svsp->vt_pure_mode == M_HPVT) && svsp->labels_on)	/* update row / col ? */
X	{
X		/* display row */
X	
X		*((svsp->Crtat+(svsp->screen_rows*COL))+LABEL_ROWH) =
X		 (user_attr | (((svsp->row+1)/10) + '0'));
X		*((svsp->Crtat+(svsp->screen_rows*COL))+LABEL_ROWL) =
X		 (user_attr | (((svsp->row+1)%10) + '0'));
X
X		/* display column */
X	
X		*((svsp->Crtat+(svsp->screen_rows*COL))+LABEL_COLH) =
X		 (user_attr | (((svsp->col+1)/10) + '0'));
X		*((svsp->Crtat+(svsp->screen_rows*COL))+LABEL_COLL) =
X		 (user_attr | (((svsp->col+1)%10) + '0'));
X	}
X	
X	if(svsp == vsp)		/* on active page ? */
X	{
X		/* update cursor position */
X		
X	 	outb(addr_6845, M6845_CURSORH);	/* select high register */
X		outb(addr_6845+1, (svsp->crtat - Crtat) >> 8);
X		outb(addr_6845, M6845_CURSORL);	/* select low register */
X		outb(addr_6845+1, (svsp->crtat - Crtat));
X	}
X
X	/* take care of last character on line behaviour */
X	
X	if(svsp->lastchar && (svsp->col < MAXCOL))
X		svsp->lastchar = 0;
X}
X
X/*---------------------------------------------------------------------------*
X *	do character set transformation and write to display memory
X *---------------------------------------------------------------------------*/
Xstatic void write_char(struct video_state *svsp, u_char kernel, u_char ch)
X{
X	register u_short result;
X	register u_short *gsave;
X	
X	if(kernel)
X		result = kern_attr;
X	else
X		result = svsp->c_attr;
X
X	if(svsp->ss2)				/* single shift G2 -> GL ? */
X	{
X		gsave = svsp->GL;		/* save GL */
X		svsp->GL = svsp->G2;		/* G2 -> GL */
X	}
X	else if(svsp->ss3)			/* single shift G3 -> GL ? */	
X	{
X		gsave = svsp->GL;		/* save GL */
X		svsp->GL = svsp->G3;		/* G3 -> GL */
X	}
X	
X	if(ch >= 0xA0)				/* use GR if ch >= 0xA0 */
X		result |= svsp->GR[ch-0xA0];
X
X	else if(ch >= 0x80)			/* display controls C1 */
X	{
X		if(vgacs[svsp->vga_charset].secondloaded)
X		{
X			result |= ((ch-0x60) | CSH);
X		}
X		else	/* use normal ibm charset for control display */
X		{
X			result |= ch;
X		}
X	}
X
X	else if (ch >= 0x20)			/* use GL if ch >= 0x20 */
X		result |= svsp->GL[ch-0x20];
X
X	else					/* display controls C0 */
X	{
X		if(vgacs[svsp->vga_charset].secondloaded)
X		{
X			result |= (ch | CSH);
X		}
X		else	/* use normal ibm charset for control display */
X		{
X			result |= ch;
X		}
X	}
X	
X	*svsp->crtat = result;			/* write char to screen */
X
X	if(svsp->ss2)				/* was single shift G2->GL ? */
X	{
X		svsp->GL = gsave;		/* restore GL */
X		svsp->ss2 = 0;			/* reset flag */
X	}
X	else if(svsp->ss3)			/* was single shift G3->GL ? */	
X	{
X		svsp->GL = gsave;		/* restore GL */
X		svsp->ss3 = 0;			/* reset flag */
X	}
X	
X}
X
X/*---------------------------------------------------------------------------*
X *	this is the absolute cold initialization of the emulator
X *---------------------------------------------------------------------------*/
Xstatic void vt_coldinit()
X{
X	u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was;
X	int nscr, charset;
X
X	do_initialization = 0;
X	
X	was = *cp;
X	*cp = (u_short) 0xA55A;
X	if (*cp != 0xA55A)
X	{
X		addr_6845 = MONO_BASE;
X		color = 0;
X	}
X	else
X	{
X		*cp = was;
X		addr_6845 = CGA_BASE;
X		Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
X		color = 1;
X	}
X
X	if(egavga_test())
X	{
X		if (vga_test())
X		{
X			adaptor_type = VGA_ADAPTOR;
X			totalfonts = 8;
X		}
X		else
X		{
X			adaptor_type = EGA_ADAPTOR;
X			totalfonts = 4;
X		}
X		totalscreens = NSCREENS;
X
X		set_2ndcharset(); /* decouple vga charsets and intensity */
X	}
X	else
X	{
X		if(color)
X		{
X			adaptor_type = CGA_ADAPTOR;
X			totalscreens = (NSCREENS > 4) ? 4 : NSCREENS;
X			totalfonts = 0;
X		}
X		else	/* Need to Distinguish Hercules */
X		{
X			adaptor_type = MDA_ADAPTOR;
X			totalscreens = 1;
X			totalfonts = 0;			
X		}
X	}
X
X#ifdef FORCE_EGA
X	force_ega();
X#endif /* FORCE_EGA */
X
X	/* establish default colors */
X	
X	if(color)
X	{
X		kern_attr = (COLOR_KERNEL_FG | COLOR_KERNEL_BG) << 8;
X		user_attr = sgr_tab_color[0] << 8;
X	}
X	else
X	{
X		kern_attr = (MONO_KERNEL_FG | MONO_KERNEL_BG) << 8;
X		user_attr = sgr_tab_mono[0] << 8;
X	}
X
X	for(nscr = 0; nscr < NSCREENS; nscr++)
X	{
X		if(adaptor_type == CGA_ADAPTOR)		/* For CGA */
X		{
X			vs[nscr].Crtat = Crtat + nscr * 0x800;
X		}
X		else					/* For EGA/VGA */
X		{
X			vs[nscr].Crtat = Crtat + nscr * SCR_MAXROW * COL;
X		}
X		vs[nscr].crtat = vs[nscr].Crtat;	/* virtual screen begin */
X		vs[nscr].c_attr = user_attr;		/* non-kernel attributes */
X		vs[nscr].bell_on = 1;			/* enable bell */
X		vs[nscr].sevenbit = 0;			/* set to 8-bit path */
X		vs[nscr].dis_fnc = 0;			/* disable display functions */
X		vs[nscr].transparent = 0;		/* disable internal tranparency */
X		vs[nscr].scr_beg = vs[nscr].Crtat;	/* scrolling region begin addr */
X		vs[nscr].row_beg = 0;			/* scrolling region begin row */
X		vs[nscr].lastchar = 0;			/* VTxxx behaviour of last char on line */
X		vs[nscr].report_chars = NULL;		/* VTxxx reports init */
X		vs[nscr].report_count = 0;		/* VTxxx reports init */
X		vs[nscr].state = STATE_INIT;		/* main state machine init */
X		vs[nscr].m_awm = 1;			/* enable auto wrap mode */
X		vs[nscr].m_om = 0;			/* origin mode = absolute */
X		vs[nscr].sc_flag = 0;			/* init saved cursor flag */
X		vs[nscr].which_fkl = SYS_FKL;		/* display system fkey-labels */
X		vs[nscr].labels_on = 1;			/* if in HP-mode, display fkey-labels */
X		vs[nscr].attribute = 0;			/* HP mode init */
X		vs[nscr].key = 0;			/* HP mode init */
X		vs[nscr].l_len = 0;			/* HP mode init */
X		vs[nscr].s_len = 0;			/* HP mode init */
X		vs[nscr].m_len = 0;			/* HP mode init */
X		vs[nscr].i = 0;				/* HP mode init */
X		vs[nscr].vt_pure_mode = M_PUREVT;	/* initial mode = pure VT220 */
X		vs[nscr].vga_charset = CH_SET0;		/* use bios default charset */
X		vs[nscr].screen_rows = 25;		/* default 25 rows on screen */
X		vs[nscr].screen_rowsize = 25;		/* default 25 rows on screen */		
X		vs[nscr].maxrow=vs[nscr].screen_rows-1;	/* scrolling region end */
X		vs[nscr].cursor_start = 0;		/* cursor upper scanline */
X		vs[nscr].cursor_end = 15;		/* cursor lower scanline */
X		vs[nscr].num = 1;			/* keypad numeric */
X		vs[nscr].ckm = 1;			/* normal cursor key mode */
X		vs[nscr].irm = 0;			/* replace mode */
X		vs[nscr].lnm = 0;			/* CR only */
X		vs[nscr].selchar = 0;	   		/* selective attribute off */
X		vs[nscr].G0 = csd_ascii;		/* G0 = ascii	*/
X		vs[nscr].G1 = csd_ascii;		/* G1 = ascii	*/
X		vs[nscr].G2 = csd_supplemental;		/* G2 = supplemental */
X		vs[nscr].G3 = csd_supplemental;		/* G3 = supplemental */
X		vs[nscr].GL = vs[nscr].G0;		/* GL = G0 */
X		vs[nscr].GR = vs[nscr].G2;		/* GR = G2 */
X		vs[nscr].whichi = 0;			/* char set designate init */
X		vs[nscr].which[0] = '\0';		/* char set designate init */
X		vs[nscr].hp_state = SHP_INIT;		/* init HP mode state machine */
X		vs[nscr].dcs_state = DCS_INIT;		/* init DCS mode state machine */
X		vs[nscr].ss2 = 0;			/* init single shift 2 */
X		vs[nscr].ss3 = 0;			/* init single shift 3 */
X
X		clear_udk(&(vs[nscr]));			/* clear vt220 udk's */
X
X		vt_str(&vs[nscr]);			/* init emulator */
X
X		fillw(user_attr | ' ', vs[nscr].crtat, COL*SCR_MAXROW);
X	}
X
X 	for(charset = 0;charset < NVGAFONTS;charset++)
X	{
X		vgacs[charset].loaded = 0;		/* not populated yet */
X		vgacs[charset].secondloaded = 0;	/* not populated yet */
X		switch(adaptor_type)
X		{
X			case VGA_ADAPTOR:
X				vgacs[charset].scr_scanlines = 0x8F; /* 0x8F for 25 lines */
X				vgacs[charset].char_scanlines = 0x4F; /* 0x4F for 25 lines */
X				break;
X
X			case EGA_ADAPTOR:
X				vgacs[charset].scr_scanlines = 0x5D; /* 0x5D for 25 lines */
X				vgacs[charset].char_scanlines = 0x4D; /* 0x4D for 25 lines */
X				break;
X
X			case CGA_ADAPTOR:
X			case MDA_ADAPTOR:
X			case HGC_ADAPTOR:
X			default:
X				/* These shouldn't be used for CGA/MDA/HERC */
X				vgacs[charset].scr_scanlines = 0;
X				vgacs[charset].char_scanlines = 0;
X				break;
X		}
X		vgacs[charset].screen_size = SIZ_25x80;	 /* set screen size   */
X 	}
X
X 	vgacs[0].loaded = 1; /* The BIOS loaded this at boot */
X
X	/* set cursor for first screen */
X	
X	outb(addr_6845,M6845_CURSTART);	/* cursor start reg */
X	outb(addr_6845+1,vs[0].cursor_start);	
X	outb(addr_6845,M6845_CUREND);	/* cursor end reg */
X	outb(addr_6845+1,vs[0].cursor_end);
X
X	update_led();			/* update led's */
X}
X
X/*---------------------------------------------------------------------------*
X *	check if we must scroll up screen
X *---------------------------------------------------------------------------*/
Xstatic void check_scroll(svsp)
Xstruct video_state *svsp;
X{
X	if(svsp->crtat >= (svsp->scr_beg + (COL*(svsp->maxrow+1))))
X	{
X		if(svsp->openf)
X		{
X			do
X				sgetc(1);
X			while(kbd_scroll);
X		}
X		bcopyb( svsp->scr_beg + COL, svsp->scr_beg, COL * svsp->maxrow * CHR );
X		fillw(user_attr | ' ', svsp->scr_beg + (COL*svsp->maxrow), COL);
X		svsp->crtat -= COL;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	write to one user function key label
X *---------------------------------------------------------------------------*/
Xstatic void writefkl(num,string,svsp)
Xint num;			/* 0...7 */
Xunsigned char *string;		/* max 16 char string */
Xstruct video_state *svsp;
X{
X	if((num < 0) || (num > 7))	/* range ok ? */
X		return;
X		
X	strncpy(svsp->ufkl[num], string, 16);	/* save string in static array */
X
X	if(svsp->which_fkl == USR_FKL)
X		wrfkl(num,string,svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	write to one system function key label
X *---------------------------------------------------------------------------*/
Xstatic void swritefkl(num,string,svsp)
Xint num;			/* 0...7 */
Xunsigned char *string;		/* max 16 char string */
Xstruct video_state *svsp;
X{
X	if((num < 0) || (num > 7))	/* range ok ? */
X		return;
X		
X	strncpy(svsp->sfkl[num], string, 16);	/* save string in static array */
X
X	if(svsp->which_fkl == SYS_FKL)
X		wrfkl(num,string,svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	write function key label onto screen
X *---------------------------------------------------------------------------*/
Xstatic void wrfkl(num,string,svsp)
Xint num;
Xunsigned char *string;
Xstruct video_state *svsp;
X{
X	register u_short *p;
X	register u_short *p1;	
X	register int cnt = 0;
X		
X	if(!svsp->labels_on || (svsp->vt_pure_mode == M_PUREVT))
X		return;
X		
X	p = (svsp->Crtat+(svsp->screen_rows*COL));	/* screen_rows+1 line */
X
X	if(num < 4)	/* labels 1 .. 4 */
X		p += (num * LABEL_LEN);
X	else		/* labels 5 .. 8 */
X		p += ((num * LABEL_LEN) + LABEL_MID + 1);
X
X	p1 = p+COL;	/* second label line */
X	
X	while((*string != '\0') && (cnt < 8))
X	{
X		*p = ((0x70 << 8) + (*string & 0xff));
X		p++;
X		string++;
X		cnt++;
X	}
X	while(cnt < 8)
X	{
X		*p = ((0x70 << 8) + ' ');
X		p++;
X		cnt++;
X	}
X
X	while((*string != '\0') && (cnt < 16))
X	{
X		*p1 = ((0x70 << 8) + (*string & 0xff));
X		p1++;
X		string++;
X		cnt++;
X	}
X	while(cnt < 16)
X	{
X		*p1 = ((0x70 << 8) + ' ');
X		p1++;
X		cnt++;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	remove (blank) function key labels, row/col and status line
X *---------------------------------------------------------------------------*/
Xvoid fkl_off(svsp)
Xstruct video_state *svsp;
X{
X	register u_short *p;
X	register int num;
X		
X	svsp->labels_on = 0;
X
X	p = (svsp->Crtat+(svsp->screen_rows*COL));
X
X	for(num = 0; num < (3*COL); num++)
X		*p++ = ' ';
X}
X
X/*---------------------------------------------------------------------------*
X *	(re-) display function key labels, row/col and status line
X *---------------------------------------------------------------------------*/
Xvoid fkl_on(svsp)
Xstruct video_state *svsp;
X{
X	svsp->labels_on = 1;
X
X	if(svsp->which_fkl == SYS_FKL)
X		sw_sfkl(svsp);
X	else if(svsp->which_fkl == USR_FKL)
X		sw_ufkl(svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	set emulation mode, switch between pure VTxxx mode and HP/VTxxx mode
X *---------------------------------------------------------------------------*/
Xvoid set_emulation_mode(svsp, mode)
Xstruct video_state *svsp;
Xint mode;
X{
X	if(svsp->vt_pure_mode == mode)
X		return;
X	
X	fillw(user_attr | ' ', svsp->Crtat, COL * SCR_MAXROW);
X
X	clr_parms(svsp);			/* escape parameter init */
X	svsp->state = STATE_INIT;		/* initial state */
X
X	svsp->col = 0;				/* init row */
X	svsp->row = 0;				/* init col */
X	svsp->crtat = svsp->Crtat;		/* cursor address init */
X	svsp->scr_beg = svsp->Crtat;		/* start of scrolling region */
X	svsp->row_beg = 0;			/* start of scrolling region */
X	svsp->sc_flag = 0;			/* invalidate saved cursor position */
X	svsp->transparent = 0;			/* disable control code processing */
X
X	if(mode == M_HPVT)	/* vt-pure -> hp/vt-mode */
X	{
X		svsp->vt_pure_mode = M_HPVT;
X		svsp->screen_rows = svsp->screen_rowsize - 3;
X		svsp->maxrow = svsp->screen_rows - 1;
X
X		if(svsp->labels_on)
X		{
X			if(svsp->which_fkl == SYS_FKL)
X				sw_sfkl(svsp);
X			else if(svsp->which_fkl == USR_FKL)
X				sw_ufkl(svsp);
X		}
X	}
X	else if(mode == M_PUREVT)	/* hp/vt-mode -> vt-pure */
X	{
X		svsp->vt_pure_mode = M_PUREVT;
X		svsp->screen_rows = svsp->screen_rowsize;
X		svsp->maxrow = svsp->screen_rows - 1;
X	}		
X
X	if(svsp == vsp)	/* update cursor position if on current screen */
X	{
X	 	outb(addr_6845, M6845_CURSORH);	/* select high register */
X		outb(addr_6845+1, (svsp->crtat - Crtat) >> 8);
X		outb(addr_6845, M6845_CURSORL);	/* select low register */
X		outb(addr_6845+1, (svsp->crtat - Crtat));
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	initialize user function key labels
X *---------------------------------------------------------------------------*/
Xinit_ufkl(svsp)
Xstruct video_state *svsp;
X{
X	writefkl(0,(u_char *)"   f1",svsp);	/* init fkey labels */
X	writefkl(1,(u_char *)"   f2",svsp);
X	writefkl(2,(u_char *)"   f3",svsp);
X	writefkl(3,(u_char *)"   f4",svsp);
X	writefkl(4,(u_char *)"   f5",svsp);
X	writefkl(5,(u_char *)"   f6",svsp);
X	writefkl(6,(u_char *)"   f7",svsp);
X	writefkl(7,(u_char *)"   f8",svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	initialize system user function key labels
X *---------------------------------------------------------------------------*/
Xinit_sfkl(svsp)
Xstruct video_state *svsp;
X{
X			    /* 1234567812345678 */
X	swritefkl(0,(u_char *)" ",svsp);
X	swritefkl(1,(u_char *)" ",svsp);
X	swritefkl(2,(u_char *)" ",svsp);
X	swritefkl(3,(u_char *)" ",svsp);
X	swritefkl(4,(u_char *)"  BELL     ON  *",svsp);
X	swritefkl(5,(u_char *)"  USE    8 BITS*",svsp);
X	swritefkl(6,(u_char *)"DISPLAY FUNCTNS ",svsp);
X	swritefkl(7,(u_char *)"  AUTO    WRAP *",svsp);
X			    /* 1234567812345678 */	
X}
X 
X/*---------------------------------------------------------------------------*
X *	switch display to user function key labels
X *---------------------------------------------------------------------------*/
Xvoid sw_ufkl(svsp)
Xstruct video_state *svsp;
X{
X	int i;
X	svsp->which_fkl = USR_FKL;
X	for(i = 0; i < 8; i++)
X		wrfkl(i,svsp->ufkl[i],svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	switch display to system function key labels
X *---------------------------------------------------------------------------*/
Xvoid sw_sfkl(svsp)
Xstruct video_state *svsp;
X{
X	int i;
X	svsp->which_fkl = SYS_FKL;
X	for(i = 0; i < 8; i++)
X		wrfkl(i,svsp->sfkl[i],svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	toggle display functions
X *---------------------------------------------------------------------------*/
Xvoid toggl_dspf(svsp)
Xstruct video_state *svsp;
X{
X	if(svsp->which_fkl == SYS_FKL)
X	{
X		if(svsp->dis_fnc)
X		{
X			svsp->dis_fnc = 0;
X			swritefkl(6,(u_char *)"DISPLAY FUNCTNS ",svsp);
X		}
X		else
X		{
X			svsp->dis_fnc = 1;
X			swritefkl(6,(u_char *)"DISPLAY FUNCTNS*",svsp);
X		}
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	auto wrap on/off
X *---------------------------------------------------------------------------*/
Xvoid toggl_awm(svsp)
Xstruct video_state *svsp;
X{
X	if(svsp->which_fkl == SYS_FKL)
X	{
X		if(svsp->m_awm)
X		{
X			svsp->m_awm = 0;
X			swritefkl(7,(u_char *)"  AUTO    WRAP  ",svsp);
X		}
X		else
X		{
X			svsp->m_awm = 1;
X			swritefkl(7,(u_char *)"  AUTO    WRAP *",svsp);
X		}
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	bell on/off
X *---------------------------------------------------------------------------*/
Xvoid toggl_bell(svsp)
Xstruct video_state *svsp;
X{
X	if(svsp->which_fkl == SYS_FKL)
X	{
X		if(svsp->bell_on)
X		{
X			svsp->bell_on = 0;
X			swritefkl(4,(u_char *)"  BELL     OFF *",svsp);
X		}
X		else
X		{
X			svsp->bell_on = 1;
X			swritefkl(4,(u_char *)"  BELL     ON  *",svsp);
X		}
X	}
X}
X/*---------------------------------------------------------------------------*
X *	7/8 bit usage
X *---------------------------------------------------------------------------*/
Xvoid toggl_sevenbit(svsp)
Xstruct video_state *svsp;
X{
X	if(svsp->which_fkl == SYS_FKL)
X	{
X		if(svsp->sevenbit)
X		{
X			svsp->sevenbit = 0;
X			swritefkl(5,(u_char *)"  USE    8 BITS*",svsp);
X		}
X		else
X		{
X			svsp->sevenbit = 1;
X			swritefkl(5,(u_char *)"  USE    7 BITS*",svsp);
X		}
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	initialize ansi escape sequence parameter buffers
X *---------------------------------------------------------------------------*/
Xvoid clr_parms(svsp)
Xstruct video_state *svsp;
X{
X	register int i;
X	for(i=0; i < MAXPARMS; i++)
X		svsp->parms[i] = 0;
X	svsp->parmi = 0;
X}
X
X/*---------------------------------------------------------------------------*
X *	DECSTBM - set top and bottom margins
X *---------------------------------------------------------------------------*/
Xstatic void vt_stbm(svsp)
Xstruct video_state *svsp;
X{
X	/* both 0 => scrolling region = entire screen */
X	
X	if((svsp->parms[0] == 0) && (svsp->parms[1] == 0))
X	{
X		svsp->scr_beg = svsp->Crtat;
X		svsp->row_beg = 0;
X		svsp->crtat = svsp->Crtat;
X		svsp->maxrow = svsp->screen_rows-1;
X		svsp->col = 0;
X		return;
X	}
X
X	if(svsp->parms[1] <= svsp->parms[0])
X		return;
X
X	/* range parm 1 */
X	
X	if(svsp->parms[0] < 1)
X		svsp->parms[0] = 1;
X	else if(svsp->parms[0] > svsp->screen_rows-1)
X		svsp->parms[0] = svsp->screen_rows-1;
X
X	/* range parm 2 */
X		
X	if(svsp->parms[1] < 2)
X		svsp->parms[1] = 2;
X	else if(svsp->parms[1] > svsp->screen_rows)
X		svsp->parms[1] = svsp->screen_rows;
X
X	svsp->scr_beg = svsp->Crtat + ((svsp->parms[0]-1) * COL);	/* first line */
X	svsp->row_beg = svsp->parms[0]-1;			/* begin of scrolling region */
X	svsp->maxrow = svsp->parms[1] - svsp->parms[0];		/* no of lines */
X	if(svsp->m_om)
X		svsp->crtat = svsp->scr_beg;		/* cursor to first pos */
X	else
X		svsp->crtat = svsp->Crtat;			/* cursor to first pos */
X	svsp->col = 0;
X}
X
X/*---------------------------------------------------------------------------*
X *	SGR - set graphic rendition
X *---------------------------------------------------------------------------*/
Xstatic void vt_sgr(svsp)
Xstruct video_state *svsp;
X{
X	register int i = 0;
X	u_short setcolor = 0;
X	char colortouched = 0;
X	
X	do
X	{
X		switch(svsp->parms[i++])
X		{
X			case 0:		/* reset to normal attributes */
X				svsp->vtsgr = VT_NORMAL;
X				break;
X
X			case 1:		/* bold */
X				svsp->vtsgr |= VT_BOLD;
X				break;
X				
X			case 4:		/* underline */
X				svsp->vtsgr |= VT_UNDER;
X				break;
X				
X			case 5:		/* blinking */
X				svsp->vtsgr |= VT_BLINK;
X				break;
X				
X			case 7:		/* reverse */
X				svsp->vtsgr |= VT_INVERSE;
X				break;
X
X			case 22:	/* not bold */
X				svsp->vtsgr &= ~VT_BOLD;
X				break;
X				
X			case 24:	/* not underlined */
X				svsp->vtsgr &= ~VT_UNDER;
X				break;
X				
X			case 25:	/* not blinking */
X				svsp->vtsgr &= ~VT_BLINK;
X				break;
X				
X			case 27:	/* not reverse */
X				svsp->vtsgr &= ~VT_INVERSE;
X				break;
X			
X			case 30:	/* foreground colors */
X			case 31:
X			case 32:
X			case 33:
X			case 34:
X			case 35:
X			case 36:
X			case 37:
X				if(color)
X				{
X				 colortouched = 1;
X				 setcolor |= ((fgansitopc[(svsp->parms[i-1]-30) & 7]) << 8);
X				}
X				break;
X				
X			case 40:	/* background colors */
X			case 41:
X			case 42:
X			case 43:
X			case 44:
X			case 45:
X			case 46:
X			case 47:
X				if(color)
X				{
X				 colortouched = 1;
X				 setcolor |= ((bgansitopc[(svsp->parms[i-1]-40) & 7]) << 8);
X				}
X				break;
X		}
X	}
X	while(i <= svsp->parmi);
X	if(color)
X	{
X		if(colortouched)
X			svsp->c_attr = setcolor;
X		else
X			svsp->c_attr = ((sgr_tab_color[svsp->vtsgr]) << 8);
X	}
X	else
X		svsp->c_attr = ((sgr_tab_mono[svsp->vtsgr]) << 8);	
X}
X
X/*---------------------------------------------------------------------------*
X *	CUU - cursor up
X *---------------------------------------------------------------------------*/
Xstatic void vt_cuu(svsp)
Xstruct video_state *svsp;
X{
X	register int p = svsp->parms[0];
X
X	if(svsp->row <= svsp->row_beg)	/* cursor above scrolling region  ? */
X		return;
X		
X	if(p <= 0)		/* parameter min */
X		p = 1;
X		
X	if(p >= (svsp->row - svsp->row_beg))	/* parameter max */
X		p = svsp->row - svsp->row_beg;
X
X	svsp->crtat -= (COL * p);
X}
X
X/*---------------------------------------------------------------------------*
X *	CUD - cursor down
X *---------------------------------------------------------------------------*/
Xstatic void vt_cud(svsp)
Xstruct video_state *svsp;
X{
X	register int p = svsp->parms[0];
X	
X	if(svsp->row >= (svsp->row_beg + svsp->maxrow))	/* already at end of screen */
X		return;
X		
X	if(p <= 0)			/* parameter min */
X		p = 1;
X
X	if(p >= (svsp->row_beg+svsp->maxrow-svsp->row))	/* parameter max */
X		p = svsp->row_beg+svsp->maxrow-svsp->row;
X
X	svsp->crtat += (COL * p);
X}
X
X/*---------------------------------------------------------------------------*
X *	CUF - cursor forward
X *---------------------------------------------------------------------------*/
Xstatic void vt_cuf(svsp)
Xstruct video_state *svsp;
X{
X	register int p = svsp->parms[0];	
X
X	if(svsp->col == MAXCOL)		/* already at right margin */
X		return;
X	if(p <= 0)			/* parameter min = 1 */
X		p = 1;
X	else if(p > MAXCOL)		/* parameter max = 79 */
X		p = MAXCOL;
X	if((svsp->col + p) > MAXCOL)		/* not more than right margin */
X		p = MAXCOL - svsp->col;
X	svsp->crtat += p;
X	svsp->col += p;
X}
X
X/*---------------------------------------------------------------------------*
X *	CUB - cursor backward
X *---------------------------------------------------------------------------*/
Xstatic void vt_cub(svsp)
Xstruct video_state *svsp;
X{
X	register int p = svsp->parms[0];	
X
X	if(svsp->col == 0)			/* already at left margin ? */
X		return;
X	if(p <= 0)			/* parameter min = 1 */
X		p = 1;
X	else if(p > MAXCOL)		/* parameter max = 79 */
X		p = MAXCOL;
X	if((svsp->col - p) <= 0)		/* not more than left margin */
X		p = svsp->col;
X	svsp->crtat -= p;
X	svsp->col -= p;
X}
X
X/*---------------------------------------------------------------------------*
X *	ED - erase in display
X *---------------------------------------------------------------------------*/
Xstatic void vt_clreos(svsp)
Xstruct video_state *svsp;
X{
X	switch(svsp->parms[0])
X	{
X		case 0:
X			fillw(user_attr | ' ', svsp->crtat,
X				 svsp->Crtat + (COL * svsp->screen_rows) - svsp->crtat);
X			break;
X		case 1:
X			fillw(user_attr | ' ', svsp->Crtat, svsp->crtat - svsp->Crtat + 1 );
X			break;
X		case 2:				
X			fillw(user_attr | ' ', svsp->Crtat, COL * svsp->screen_rows);
X			break;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	EL - erase in line
X *---------------------------------------------------------------------------*/
Xstatic void vt_clreol(svsp)
Xstruct video_state *svsp;
X{
X	switch(svsp->parms[0])
X	{
X		case 0:
X			fillw(user_attr | ' ', svsp->crtat, COL-svsp->col);
X			break;
X		case 1:
X			fillw(user_attr | ' ', svsp->crtat-svsp->col, svsp->col + 1);
X			break;
X		case 2:
X			fillw(user_attr | ' ', svsp->crtat-svsp->col, COL);
X			break;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	CUP - cursor position / HVP - horizontal & vertical position
X *---------------------------------------------------------------------------*/
Xstatic void vt_curadr(svsp)
Xstruct video_state *svsp;
X{
X	if(svsp->m_om)	/* relative to scrolling region */
X	{
X		if((svsp->parms[0] == 0) && (svsp->parms[1] == 0)) 
X		{
X			svsp->crtat = svsp->scr_beg;
X			svsp->col = 0;
X			return;
X		}
X		
X		if(svsp->parms[0] <= 0)
X			svsp->parms[0] = 1;
X		else if(svsp->parms[0] > (svsp->maxrow+1))
X			svsp->parms[0] = svsp->maxrow + 1;
X	
X		if(svsp->parms[1] <= 0 )
X			svsp->parms[1] = 1;
X		if(svsp->parms[1] > COL)
X			svsp->parms[1] = COL;
X	
X		svsp->crtat = svsp->scr_beg + ( ((svsp->parms[0]-1)*COL) + (svsp->parms[1]-1) );
X		svsp->col = svsp->parms[1]-1;
X	}
X	else	/* relative to screen start */
X	{
X		if((svsp->parms[0] == 0) && (svsp->parms[1] == 0)) 
X		{
X			svsp->crtat = svsp->Crtat;
X			svsp->col = 0;
X			return;
X		}
X		
X		if(svsp->parms[0] <= 0)
X			svsp->parms[0] = 1;
X		else if(svsp->parms[0] > svsp->screen_rows)
X			svsp->parms[0] = svsp->screen_rows;
X	
X		if(svsp->parms[1] <= 0 )
X			svsp->parms[1] = 1;
X		if(svsp->parms[1] > COL)			/* col */
X			svsp->parms[1] = COL;
X	
X		svsp->crtat = svsp->Crtat + ( ((svsp->parms[0]-1)*COL) + (svsp->parms[1]-1) );
X		svsp->col = svsp->parms[1]-1;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	RIS - reset to initial state (hard emulator runtime reset)
X *---------------------------------------------------------------------------*/
Xstatic void vt_ris(struct video_state *svsp)
X{
X	fillw(user_attr | ' ', svsp->Crtat, COL * svsp->screen_rows);
X	svsp->crtat = svsp->Crtat;	/* cursor upper left corner */
X	svsp->col = 0;
X	svsp->row = 0;	
X	svsp->lnm = 0;			/* CR only */
X	clear_dld(svsp);		/* clear download charset */
X	clear_udk(svsp);		/* clear user defined keys */
X	svsp->selchar = 0;		/* selective attribute off */
X
X	vt_str(svsp);			/* and soft terminal reset */
X}
X
X/*---------------------------------------------------------------------------*
X *	DECSTR - soft terminal reset (SOFT emulator runtime reset)
X *---------------------------------------------------------------------------*/
Xstatic void vt_str(struct video_state *svsp)
X{
X	int i;
X	
X	clr_parms(svsp);			/* escape parameter init */
X	svsp->state = STATE_INIT;		/* initial state */
X
X	init_ufkl(svsp);			/* init user fkey labels */
X	init_sfkl(svsp);			/* init system fkey labels */  
X
X	svsp->sc_flag = 0;			/* save cursor position */
X	svsp->transparent = 0;			/* enable control code processing */
X
X	for(i = 0; i < MAXTAB; i++)		/* setup tabstops */
X	{
X		if(!(i % 8))
X			svsp->tab_stops[i] = 1;
X		else
X			svsp->tab_stops[i] = 0;
X	}
X
X	svsp->irm = 0;				/* replace mode */
X	svsp->m_om = 0;				/* origin mode */
X	svsp->m_awm = 1;			/* auto wrap mode */
X	svsp->num = 1;				/* keyboard numeric mode */
X	svsp->ckm = 1;				/* cursor key mode = "normal" ... */
X	svsp->scr_beg = svsp->Crtat;		/* start of scrolling region */
X	svsp->row_beg = 0;			/* start of scrolling region */
X	svsp->maxrow = svsp->screen_rows-1;	/* no. of lines in scrolling region */
X
X	if(adaptor_type == EGA_ADAPTOR || adaptor_type == VGA_ADAPTOR)
X	{
X		svsp->G0 = cse_ascii;		/* G0 = ascii	*/
X		svsp->G1 = cse_ascii;		/* G1 = ascii	*/
X		svsp->G2 = cse_supplemental;	/* G2 = supplemental */
X		svsp->G3 = cse_supplemental;	/* G3 = supplemental */
X		svsp->GL = svsp->G0;		/* GL = G0 */
X		svsp->GR = svsp->G2;		/* GR = G2 */
X	}
X	else
X	{
X		svsp->G0 = csd_ascii;		/* G0 = ascii	*/
X		svsp->G1 = csd_ascii;		/* G1 = ascii	*/
X		svsp->G2 = csd_supplemental;	/* G2 = supplemental */
X		svsp->G3 = csd_supplemental;	/* G3 = supplemental */
X		svsp->GL = svsp->G0;		/* GL = G0 */
X		svsp->GR = svsp->G2;		/* GR = G2 */
X	}
X
X	svsp->vtsgr = VT_NORMAL;		/* no attributes */
X	svsp->c_attr = user_attr;		/* reset sgr to normal */
X
X	svsp->selchar = 0;			/* selective attribute off */
X	init_sel(svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	RI - reverse index, move cursor up
X *---------------------------------------------------------------------------*/
Xstatic void vt_ri(svsp)
Xstruct video_state *svsp;
X{
X	if(svsp->crtat >= (svsp->scr_beg+COL))
X		svsp->crtat -= COL;
X	else
X		roll_down(svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	IND - index, move cursor down
X *---------------------------------------------------------------------------*/
Xstatic void vt_ind(svsp)
Xstruct video_state *svsp;
X{
X	if(svsp->crtat <= (svsp->scr_beg + (svsp->maxrow * COL) ))
X		svsp->crtat += COL;
X	else
X		roll_up(svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	NEL - next line, first pos of next line
X *---------------------------------------------------------------------------*/
Xstatic void vt_nel(svsp)
Xstruct video_state *svsp;
X{					
X	if(svsp->crtat <= (svsp->scr_beg + (svsp->maxrow * COL) ))
X	{
X		svsp->crtat += (COL-svsp->col);
X		svsp->col = 0;
X	}
X	else
X	{
X		roll_up(svsp);
X		svsp->crtat -= svsp->col;
X		svsp->col = 0;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	scroll screen one line up
X *---------------------------------------------------------------------------*/
Xstatic void roll_up(svsp)
Xstruct video_state *svsp;
X{
X	if(svsp->openf)
X	{
X		do
X			sgetc(1);
X		while(kbd_scroll);
X	}
X	bcopyb( svsp->scr_beg + COL, svsp->scr_beg, COL * svsp->maxrow * CHR );
X	fillw(user_attr | ' ', svsp->scr_beg + (COL*svsp->maxrow), COL);
X}
X
X/*---------------------------------------------------------------------------*
X *	scroll screen one line down
X *---------------------------------------------------------------------------*/
Xstatic void roll_down(svsp)
Xstruct video_state *svsp;
X{
X	if(svsp->openf)
X	{
X		do
X			sgetc(1);
X		while(kbd_scroll);
X	}
X	ovbcopy( svsp->scr_beg, svsp->scr_beg + COL, COL * svsp->maxrow * CHR );
X	fillw(user_attr | ' ', svsp->scr_beg , COL);
X}
X
X/*---------------------------------------------------------------------------*
X *	set dec private modes, esc [ ? x
X *---------------------------------------------------------------------------*/
Xstatic void vt_set_dec_priv_qm(svsp)
Xstruct video_state *svsp;
X{
X	switch(svsp->parms[0])
X	{
X		case 0:		/* error, ignored */
X		case 1:		/* CKM - cursor key mode */
X			svsp->ckm = 1;
X			break;
X
X		case 2:		/* ANM - ansi/vt52 mode */
X		case 3:		/* COLM - column mode */
X		case 4:		/* SCLM - scrolling mode */
X		case 5:		/* SCNM - screen mode */
X			break;
X			
X		case 6:		/* OM - origin mode */
X			svsp->m_om = 1;
X			break;
X
X		case 7:		/* AWM - auto wrap mode */
X			svsp->m_awm = 1;
X			swritefkl(7,(u_char *)"  AUTO    WRAP *",svsp);
X			break;
X
X		case 8:		/* ARM - auto repeat mode */
X		case 9:		/* INLM - interlace mode */
X		case 10:	/* EDM - edit mode */
X		case 11:	/* LTM - line transmit mode */
X		case 12:	/* */
X		case 13:	/* SCFDM - space compression / field delimiting */
X		case 14:	/* TEM - transmit execution mode */
X		case 15:	/* */
X		case 16:	/* EKEM - edit key execution mode */
X			break;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	reset dec private modes, esc [ ? x
X *---------------------------------------------------------------------------*/
Xstatic void vt_reset_dec_priv_qm(svsp)
Xstruct video_state *svsp;
X{
X	switch(svsp->parms[0])
X	{
X		case 0:		/* error, ignored */
X		case 1:		/* CKM - cursor key mode */
X			svsp->ckm = 0;
X			break;
X
X		case 2:		/* ANM - ansi/vt52 mode */
X		case 3:		/* COLM - column mode */
X		case 4:		/* SCLM - scrolling mode */
X		case 5:		/* SCNM - screen mode */
X			break;
X			
X		case 6:		/* OM - origin mode */
X			svsp->m_om = 0;
X			break;
X
X		case 7:		/* AWM - auto wrap mode */
X			svsp->m_awm = 0;
X			swritefkl(7,(u_char *)"  AUTO    WRAP  ",svsp);
X			break;
X
X		case 8:		/* ARM - auto repeat mode */
X		case 9:		/* INLM - interlace mode */
X		case 10:	/* EDM - edit mode */
X		case 11:	/* LTM - line transmit mode */
X		case 12:	/* */
X		case 13:	/* SCFDM - space compression / field delimiting */
X		case 14:	/* TEM - transmit execution mode */
X		case 15:	/* */
X		case 16:	/* EKEM - edit key execution mode */
X			break;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	set ansi modes, esc [ x
X *---------------------------------------------------------------------------*/
Xstatic void vt_set_ansi(svsp)
Xstruct video_state *svsp;
X{
X	switch(svsp->parms[0])
X	{
X		case 0:		/* error, ignored */
X		case 1:		/* GATM - guarded area transfer mode */
X		case 2:		/* KAM - keyboard action mode */
X		case 3:		/* CRM - Control Representation mode */
X			break;
X			
X		case 4:		/* IRM - insert replacement mode */
X			svsp->irm = 1; /* Insert mode */
X			break;
X
X		case 5:		/* SRTM - status report transfer mode */
X		case 6:		/* ERM - erasue mode */
X		case 7:		/* VEM - vertical editing mode */
X		case 10:	/* HEM - horizontal editing mode */
X		case 11:	/* PUM - position unit mode */
X		case 12:	/* SRM - send-receive mode */
X		case 13:	/* FEAM - format effector action mode */
X		case 14:	/* FETM - format effector transfer mode */
X		case 15:	/* MATM - multiple area transfer mode */
X		case 16:	/* TTM - transfer termination */
X		case 17:	/* SATM - selected area transfer mode */
X		case 18:	/* TSM - tabulation stop mode */
X		case 19:	/* EBM - editing boundary mode */
X			break;
X			
X		case 20:	/* LNM - line feed / newline mode */
X			svsp->lnm = 1;
X			break;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	reset ansi modes, esc [ x
X *---------------------------------------------------------------------------*/
Xstatic void vt_reset_ansi(svsp)
Xstruct video_state *svsp;
X{
X	switch(svsp->parms[0])
X	{
X		case 0:		/* error, ignored */
X		case 1:		/* GATM - guarded area transfer mode */
X		case 2:		/* KAM - keyboard action mode */
X		case 3:		/* CRM - Control Representation mode */
X			break;
X			
X		case 4:		/* IRM - insert replacement mode */
X			svsp->irm = 0;  /* Replace mode */
X			break;
X			
X		case 5:		/* SRTM - status report transfer mode */
X		case 6:		/* ERM - erasue mode */
X		case 7:		/* VEM - vertical editing mode */
X		case 10:	/* HEM - horizontal editing mode */
X		case 11:	/* PUM - position unit mode */
X		case 12:	/* SRM - send-receive mode */
X		case 13:	/* FEAM - format effector action mode */
X		case 14:	/* FETM - format effector transfer mode */
X		case 15:	/* MATM - multiple area transfer mode */
X		case 16:	/* TTM - transfer termination */
X		case 17:	/* SATM - selected area transfer mode */
X		case 18:	/* TSM - tabulation stop mode */
X		case 19:	/* EBM - editing boundary mode */
X			break;
X			
X		case 20:	/* LNM - line feed / newline mode */
X			svsp->lnm = 0;
X			break;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	clear tab stop(s)
X *---------------------------------------------------------------------------*/
Xstatic void vt_clrtab(svsp)
Xstruct video_state *svsp;
X{
X	int i;
X
X	if(svsp->parms[0] == 0)
X		svsp->tab_stops[svsp->col] = 0;
X	else if(svsp->parms[0] == 3)
X	{
X		for(i=0; i<MAXTAB; i++)
X			svsp->tab_stops[i] = 0;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	DECSC - save cursor & attributes
X *---------------------------------------------------------------------------*/
Xstatic void vt_sc(svsp)
Xstruct video_state *svsp;
X{
X	svsp->sc_flag = 1;
X	svsp->sc_row = svsp->row;
X	svsp->sc_col = svsp->col;
X	svsp->sc_crtat = svsp->crtat;
X	svsp->sc_attr = svsp->c_attr;
X	svsp->sc_awm = svsp->m_awm;
X	svsp->sc_om = svsp->m_om;
X	svsp->sc_G0 = svsp->G0;
X	svsp->sc_G1 = svsp->G1;
X	svsp->sc_G2 = svsp->G2;	
X	svsp->sc_G3 = svsp->G3;
X	svsp->sc_GL = svsp->GL;
X	svsp->sc_GR = svsp->GR;		
X	svsp->sc_sel = svsp->selchar;
X	svsp->sc_vtsgr = svsp->vtsgr;
X}
X
X/*---------------------------------------------------------------------------*
X *	DECRC - restore cursor & attributes
X *---------------------------------------------------------------------------*/
Xstatic void vt_rc(svsp)
Xstruct video_state *svsp;
X{
X	if(svsp->sc_flag == 1)
X	{
X		svsp->sc_flag = 0;
X		svsp->row = svsp->sc_row;
X		svsp->col = svsp->sc_col;
X		svsp->crtat = svsp->sc_crtat;
X		svsp->c_attr = svsp->sc_attr;
X		svsp->m_awm = svsp->sc_awm;
X		svsp->m_om = svsp->sc_om;
X		svsp->G0 = svsp->sc_G0;
X		svsp->G1 = svsp->sc_G1;
X		svsp->G2 = svsp->sc_G2;
X		svsp->G3 = svsp->sc_G3;
X		svsp->GL = svsp->sc_GL;
X		svsp->GR = svsp->sc_GR;
X		svsp->selchar = svsp->sc_sel;
X		svsp->vtsgr = svsp->sc_vtsgr;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	designate a character set as G0, G1, G2 or G3 for 94/96 char sets
X *---------------------------------------------------------------------------*/
Xstatic void vt_designate(struct video_state *svsp)
X{
X	u_short *ctp = NULL;
X	u_char ch;
X	
X	if(svsp->whichi == 1)
X		ch = svsp->which[0];
X	else
X	{
X		int i;
X
X		if(svsp->dld_id[0] == '\0')
X			return;
X			
X		if(!(((adaptor_type == EGA_ADAPTOR) || (adaptor_type == VGA_ADAPTOR)) &&
X			(vgacs[svsp->vga_charset].secondloaded)))
X			return;
X
X		for(i = (svsp->whichi)-1; i >= 0; i--)
X		{
X			 if(svsp->which[i] != svsp->dld_id[i])
X				return;
X		}
X#ifdef HAVECSE_DOWNLOADABLE
X		ctp = cse_downloadable;
X		swcsp(svsp, ctp);
X#endif		
X		return;
X	}
X	
X	if(((adaptor_type == EGA_ADAPTOR) || (adaptor_type == VGA_ADAPTOR)) &&
X	   (vgacs[svsp->vga_charset].secondloaded))
X	{
X		if((ch == svsp->dld_id[0]) && (svsp->dld_id[1] == '\0'))
X		{
X#ifdef HAVECSE_DOWNLOADABLE
X			ctp = cse_downloadable;
X			swcsp(svsp, ctp);
X#endif			
X			return;
X		}
X			
X		switch(ch)
X		{
X			case 'A': /* British or ISO-Latin-1 */
X				switch(svsp->state)
X				{
X					case STATE_BROPN:	/* designate G0 */
X					case STATE_BRCLO:	/* designate G1 */
X					case STATE_STAR:	/* designate G2 */
X					case STATE_PLUS:	/* designate G3 */
X#ifdef HAVECSE_BRITISH
X						ctp = cse_british;
X#endif
X						break;
X	
X					case STATE_MINUS:	/* designate G1 (96) */
X					case STATE_DOT:		/* designate G2 (96) */
X					case STATE_SLASH:	/* designate G3 (96) */
X#ifdef HAVECSE_ISOLATIN
X						ctp = cse_isolatin;
X#endif
X						break;
X				}
X				break;
X				
X			case 'B': /* USASCII */
X#ifdef HAVECSE_ASCII
X				ctp = cse_ascii;
X#endif			
X				break;
X
X			case 'C': /* Finnish */
X			case '5': /* Finnish */
X#ifdef HAVECSE_FINNISH
X				ctp = cse_finnish;
X#endif
X				break;
X
X			case 'E': /* Norwegian/Danish */
X			case '6': /* Norwegian/Danish */
X#ifdef HAVECSE_NORWEGIANDANISH
X				ctp = cse_norwegiandanish;
X#endif
X				break;
X
X			case 'H': /* Swedish */
X			case '7': /* Swedish */
X#ifdef HAVECSE_SWEDISH
X				ctp = cse_swedish;
X#endif			
X				break;
X	
X			case 'K': /* German */
X#ifdef HAVECSE_GERMAN
X				ctp = cse_german;
X#endif			
X				break;
X				
X			case 'Q': /* French Canadien */
X#ifdef HAVECSE_FRENCHCANADA
X				ctp = cse_frenchcanada;
X#endif			
X				break;
X
X			case 'R': /* French */
X#ifdef HAVECSE_FRENCH
X				ctp = cse_french;
X#endif			
X				break;
X
X			case 'Y': /* Italian */
X#ifdef HAVECSE_ITALIAN
X				ctp = cse_italian;
X#endif			
X				break;
X
X			case 'Z': /* Spanish */
X#ifdef HAVECSE_SPANISH
X				ctp = cse_spanish;
X#endif			
X				break;
X				
X			case '0': /* special graphics */
X#ifdef HAVECSE_SPECIAL
X				ctp = cse_special;
X#endif			
X				break;
X
X			case '1': /* alternate ROM */
X#ifdef HAVECSE_ALTERNATEROM1
X				ctp = cse_alternaterom1;
X#endif			
X				break;
X
X			case '2': /* alt ROM, spec graphics */
X#ifdef HAVECSE_ALTERNATEROM2
X				ctp = cse_alternaterom2;
X#endif			
X				break;
X
X			case '3': /* HP Roman 8, upper 128 chars*/
X#ifdef HAVECSE_ROMAN8
X				ctp = cse_roman8;
X#endif			
X				break;
X
X			case '4': /* Dutch */
X#ifdef HAVECSE_DUTCH
X				ctp = cse_dutch;
X#endif			
X				break;
X
X			case '<': /* DEC Supplemental */
X#ifdef HAVECSE_SUPPLEMENTAL
X				ctp = cse_supplemental;
X#endif			
X				break;
X
X			case '=': /* Swiss */
X#ifdef HAVECSE_SWISS
X				ctp = cse_swiss;
X#endif			
X				break;
X
X			case '>': /* DEC Technical */
X#ifdef HAVECSE_TECHNICAL
X				ctp = cse_technical;
X#endif			
X				break;
X	
X			default:
X				break;
X		}
X	}
X	else
X	{
X		switch(ch)
X		{
X			case 'A': /* British or ISO-Latin-1 */
X				switch(svsp->state)
X				{
X					case STATE_BROPN:	/* designate G0 */
X					case STATE_BRCLO:	/* designate G1 */
X					case STATE_STAR:	/* designate G2 */
X					case STATE_PLUS:	/* designate G3 */
X#ifdef HAVECSD_BRITISH
X						ctp = csd_british;
X#endif
X						break;
X	
X					case STATE_MINUS:	/* designate G1 (96) */
X					case STATE_DOT:		/* designate G2 (96) */
X					case STATE_SLASH:	/* designate G3 (96) */
X#ifdef HAVECSD_ISOLATIN
X						ctp = csd_isolatin;
X#endif
X						break;
X				}
X				break;
X				
X			case 'B': /* USASCII */
X#ifdef HAVECSD_ASCII
X				ctp = csd_ascii;
X#endif			
X				break;
X
X			case 'C': /* Finnish */
X			case '5': /* Finnish */
X#ifdef HAVECSD_FINNISH
X				ctp = csd_finnish;
X#endif
X				break;
X
X			case 'E': /* Norwegian/Danish */
X			case '6': /* Norwegian/Danish */
X#ifdef HAVECSD_NORWEGIANDANISH
X				ctp = csd_norwegiandanish;
X#endif
X				break;
X
X			case 'H': /* Swedish */
X			case '7': /* Swedish */
X#ifdef HAVECSD_SWEDISH
X				ctp = csd_swedish;
X#endif			
X				break;
X	
X			case 'K': /* German */
X#ifdef HAVECSD_GERMAN
X				ctp = csd_german;
X#endif			
X				break;
X				
X			case 'Q': /* French Canadien */
X#ifdef HAVECSD_FRENCHCANADA
X				ctp = csd_frenchcanada;
X#endif			
X				break;
X
X			case 'R': /* French */
X#ifdef HAVECSD_FRENCH
X				ctp = csd_french;
X#endif			
X				break;
X
X			case 'Y': /* Italian */
X#ifdef HAVECSD_ITALIAN
X				ctp = csd_italian;
X#endif			
X				break;
X
X			case 'Z': /* Spanish */
X#ifdef HAVECSD_SPANISH
X				ctp = csd_spanish;
X#endif			
X				break;
X				
X			case '0': /* special graphics */
X#ifdef HAVECSD_SPECIAL
X				ctp = csd_special;
X#endif			
X				break;
X
X			case '1': /* alternate ROM */
X#ifdef HAVECSD_ALTERNATEROM1
X				ctp = csd_alternaterom1;
X#endif			
X				break;
X
X			case '2': /* alt ROM, spec graphics */
X#ifdef HAVECSD_ALTERNATEROM2
X				ctp = csd_alternaterom2;
X#endif			
X				break;
X
X			case '3': /* HP Roman 8, upper 128 chars*/
X#ifdef HAVECSD_ROMAN8
X				ctp = csd_roman8;
X#endif			
X				break;
X
X			case '4': /* Dutch */
X#ifdef HAVECSD_DUTCH
X				ctp = csd_dutch;
X#endif			
X				break;
X
X			case '<': /* DEC Supplemental */
X#ifdef HAVECSD_SUPPLEMENTAL
X				ctp = csd_supplemental;
X#endif			
X				break;
X
X			case '=': /* Swiss */
X#ifdef HAVECSD_SWISS
X				ctp = csd_swiss;
X#endif			
X				break;
X
X			case '>': /* DEC Technical */
X#ifdef HAVECSD_TECHNICAL
X				ctp = csd_technical;
X#endif			
X				break;
X	
X			default:
X				break;
X		}
X	}
X	swcsp(svsp, ctp);
X}
X		
X/*---------------------------------------------------------------------------*
X *	switch charset pointers
X *---------------------------------------------------------------------------*/
Xstatic void swcsp(struct video_state *svsp, u_short *ctp)
X{
X	if(ctp == NULL)
X		return;
X		
X	switch(svsp->state)
X	{
X		case STATE_BROPN:	/* designate G0 */
X			svsp->G0 = ctp;
X			break;
X
X		case STATE_BRCLO:	/* designate G1 */
X		case STATE_MINUS:	/* designate G1 (96) */
X			svsp->G1 = ctp;
X			break;
X
X		case STATE_STAR:	/* designate G2 */
X		case STATE_DOT:		/* designate G2 (96) */
X			svsp->G2 = ctp;
X			break;
X
X		case STATE_PLUS:	/* designate G3 */
X		case STATE_SLASH:	/* designate G3 (96) */
X			svsp->G3 = ctp;
X			break;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	process terminal responses
X *---------------------------------------------------------------------------*/
Xrespond(svsp)
Xstruct video_state *svsp;
X{
X        if(!(svsp->openf))              /* are we opened ? */
X                return;
X
X        while (*svsp->report_chars && svsp->report_count > 0)
X        {
X		(*linesw[svsp->vs_tty->t_line].l_rint)
X			(*svsp->report_chars++ & 0xff, svsp->vs_tty);
X		svsp->report_count--;
X        }
X}
X
X/*---------------------------------------------------------------------------*
X *	device attributes
X *---------------------------------------------------------------------------*/
Xstatic void vt_da(svsp)
Xstruct video_state *svsp;
X{
X	static u_char *response = (u_char *)DA_VT220;
X	
X	svsp->report_chars = response;
X	svsp->report_count = 18;
X	respond(svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	screen alignment display
X *---------------------------------------------------------------------------*/
Xstatic void vt_aln(svsp)
Xstruct video_state *svsp;
X{
X	register int i;
X
X	svsp->crtat = svsp->Crtat;
X	svsp->col = 0;
X
X	for(i=0; i < (svsp->screen_rows*COL); i++)
X	{
X		*svsp->crtat = user_attr | 'E';
X		selective_attribute(svsp);
X		svsp->crtat++;
X		svsp->col++;
X	}
X
X	svsp->crtat = svsp->Crtat;	/* reset everything ! */
X	svsp->col = 0;
X	svsp->row = 0;	
X}
X
X/*---------------------------------------------------------------------------*
X *	request terminal parameters
X *---------------------------------------------------------------------------*/
Xstatic void vt_reqtparm(svsp)
Xstruct video_state *svsp;
X{
X	static u_char *answr = (u_char *)"\033[3;1;1;120;120;1;0x";
X
X	svsp->report_chars = answr;
X	svsp->report_count = 20;
X	respond(svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	invoke selftest
X *---------------------------------------------------------------------------*/
Xstatic void vt_tst(svsp)
Xstruct video_state *svsp;
X{
X	clear_dld(svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	device status reports
X *---------------------------------------------------------------------------*/
Xstatic void vt_dsr(svsp)
Xstruct video_state *svsp;
X{
X	static u_char *answr = (u_char *)"\033[0n";
X	static u_char *panswr = (u_char *)"\033[?13n"; /* Printer Unattached */
X	static u_char *udkanswr = (u_char *)"\033[?21n"; /* UDK Locked */
X	static u_char *langanswr = (u_char *)"\033[?27;1n"; /* North American*/
X	static u_char buffer[16];
X	int i = 0;
X	
X	switch(svsp->parms[0])
X	{
X		case 5:		/* return status */
X			svsp->report_chars = answr;
X			svsp->report_count = 4;
X			respond(svsp);
X			break;
X
X		case 6:		/* return cursor position */
X			buffer[i++] = 0x1b;
X			buffer[i++] = '[';
X			if((svsp->row+1) > 10)
X				buffer[i++] = ((svsp->row+1) / 10) + '0';
X			buffer[i++] = ((svsp->row+1) % 10) + '0';
X			buffer[i++] = ';';	
X			if((svsp->col+1) > 10)
X				buffer[i++] = ((svsp->col+1) / 10) + '0';
X			buffer[i++] = ((svsp->col+1) % 10) + '0';
X			buffer[i++] = 'R';
X			buffer[i++] = '\0';
X		
X			svsp->report_chars = buffer;
X			svsp->report_count = i;
X			respond(svsp);
X			break;
X
X		case 15:	/* return printer status */
X			svsp->report_chars = panswr;
X			svsp->report_count = 6;
X			respond(svsp);
X			break;
X
X		case 25:	/* return udk status */
X			svsp->report_chars = udkanswr;
X			svsp->report_count = 6;
X			respond(svsp);
X			break;
X
X		case 26:	/* return language status */
X			svsp->report_chars = langanswr;
X			svsp->report_count = 8;
X			respond(svsp);
X			break;
X
X		default:	/* nothing else valid */
X			break;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	IL - insert line 
X *---------------------------------------------------------------------------*/
Xstatic void vt_il(svsp)
Xstruct video_state *svsp;
X{
X	register int p = svsp->parms[0];
X	
X	if((svsp->row >= svsp->row_beg) && (svsp->row <= svsp->row_beg + svsp->maxrow))
X	{
X		if(p <= 0)
X			p = 1;
X		else if(p > svsp->row_beg + svsp->maxrow - svsp->row)
X			p = svsp->row_beg + svsp->maxrow - svsp->row;
X
X		svsp->crtat -= svsp->col;
X		svsp->col = 0;
X		while(p--)
X		{
X			ovbcopy(svsp->crtat, svsp->crtat + COL, COL * (svsp->row_beg + svsp->maxrow - svsp->row) * CHR );
X			fillw(user_attr | ' ', svsp->crtat, COL);
X		}
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	ICH - insert character
X *---------------------------------------------------------------------------*/
Xstatic void vt_ic(svsp)
Xstruct video_state *svsp;
X{
X	register int p = svsp->parms[0];
X
X	if(p <= 0)
X		p = 1;
X	else if(p > COL-svsp->col)
X		p = COL-svsp->col;
X	
X	while(p--)
X	{
X		ovbcopy(svsp->crtat, svsp->crtat + 1,(MAXCOL-svsp->col) * CHR);
X		*svsp->crtat = user_attr | ' ';
X		selective_attribute(svsp);
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	DL - delete line
X *---------------------------------------------------------------------------*/
Xstatic void vt_dl(svsp)
Xstruct video_state *svsp;
X{
X	register int p = svsp->parms[0];
X	
X	if((svsp->row >= svsp->row_beg) && (svsp->row <= svsp->row_beg + svsp->maxrow))
X	{
X		if(p <= 0)
X			p = 1;
X		else if(p > svsp->row_beg + svsp->maxrow - svsp->row)
X			p = svsp->row_beg + svsp->maxrow - svsp->row;
X
X		svsp->crtat -= svsp->col;
X		svsp->col = 0;
X		while(p--)
X		{
X			bcopyb( svsp->crtat + COL , svsp->crtat, COL * (svsp->row_beg + svsp->maxrow - svsp->row) * CHR );
X			fillw(user_attr | ' ', svsp->scr_beg + (COL * svsp->maxrow), COL);
X		}
X	}		
X}
X
X/*---------------------------------------------------------------------------*
X *	DCH - delete character
X *---------------------------------------------------------------------------*/
Xstatic void vt_dch(svsp)
Xstruct video_state *svsp;
X{
X	register int p = svsp->parms[0];
X
X	if(p <= 0)
X		p = 1;
X	else if(p > COL-svsp->col)
X		p = COL-svsp->col;
X	
X	while(p--)
X	{
X		bcopyb(svsp->crtat+1 , svsp->crtat,(MAXCOL - svsp->col)* CHR );
X		*(svsp->crtat+MAXCOL-svsp->col) = user_attr | ' ';
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	scroll up
X *---------------------------------------------------------------------------*/
Xstatic void vt_su(svsp)
Xstruct video_state *svsp;
X{
X	register int p = svsp->parms[0];
X	
X	if(p <= 0)
X		p = 1;
X	else if(p > svsp->screen_rows-1)
X		p = svsp->screen_rows-1;
X	
X	while(p--)
X		roll_up(svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	scroll down
X *---------------------------------------------------------------------------*/
Xstatic void vt_sd(svsp)
Xstruct video_state *svsp;
X{
X	register int p = svsp->parms[0];
X	
X	if(p <= 0)
X		p = 1;
X	else if(p > svsp->screen_rows-1)
X		p = svsp->screen_rows-1;
X	
X	while(p--)
X		roll_down(svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	ECH - erase character
X *---------------------------------------------------------------------------*/
Xstatic void vt_ech(svsp)
Xstruct video_state *svsp;
X{
X	register int p = svsp->parms[0];
X
X	if(p <= 0)
X		p = 1;
X	else if(p > COL-svsp->col)
X		p = COL-svsp->col;
X	
X	fillw(user_attr | ' ', svsp->crtat, p);
X}
X
X/*---------------------------------------------------------------------------*
X *	media copy	(NO PRINTER AVAILABLE IN KERNEL ...)
X *---------------------------------------------------------------------------*/
Xstatic void vt_mc(svsp)
Xstruct video_state *svsp;
X{
X}
X
X/*---------------------------------------------------------------------------*
X *	Device Control String State Machine Entry for:
X *
X *	DECUDK - user-defined keys	and
X *	DECDLD - downloadable charset
X *
X *---------------------------------------------------------------------------*/
Xstatic void dcs_entry(u_char ch, struct video_state *svsp)
X{
X	switch(svsp->dcs_state)
X	{
X		case DCS_INIT:
X			switch(ch)
X			{
X				case '0':
X				case '1':
X				case '2':
X				case '3':
X				case '4':
X				case '5':
X				case '6':
X				case '7':
X				case '8':
X				case '9':	/* parameters */
X					svsp->parms[svsp->parmi] *= 10;
X					svsp->parms[svsp->parmi] += (ch -'0');
X					break;
X	
X				case ';':	/* next parameter */
X					svsp->parmi = 
X						(svsp->parmi+1 < MAXPARMS) ?
X						svsp->parmi+1 : svsp->parmi;
X					break;
X
X				case '|':	/* DECUDK */
X					svsp->transparent = 1;
X					init_udk(svsp);
X					svsp->dcs_state = DCS_AND_UDK;
X					break;
X
X				case '{':	/* DECDLD */
X					svsp->transparent = 1;
X					init_dld(svsp);
X					svsp->dcs_state = DCS_DLD_DSCS;
X					break;
X
X				default:	 /* failsafe */
X					svsp->transparent = 0;
X					svsp->state = STATE_INIT;
X					svsp->dcs_state = DCS_INIT;
X					break;
X			}
X			break;
X
X		case DCS_AND_UDK:	 /* DCS ... | */
X			switch(ch)
X			{
X				case '0':
X				case '1':
X				case '2':
X				case '3':
X				case '4':
X				case '5':
X				case '6':
X				case '7':
X				case '8':
X				case '9':	/* fkey number */
X					svsp->udk_fnckey *= 10;
X					svsp->udk_fnckey += (ch -'0');
X					break;
X
X				case '/':	/* Key */
X					svsp->dcs_state = DCS_UDK_DEF;
X					break;
X
X				case 0x1b:	 /* ESC */
X					svsp->dcs_state = DCS_UDK_ESC;
X					break;
X	
X				default:
X					svsp->transparent = 0;
X					svsp->state = STATE_INIT;
X					svsp->dcs_state = DCS_INIT;
X					break;
X			}
X			break;
X
X		case DCS_UDK_DEF:	 /* DCS ... | fnckey / */
X			switch(ch)
X			{
X				case '0':
X				case '1':
X				case '2':
X				case '3':
X				case '4':
X				case '5':
X				case '6':
X				case '7':
X				case '8':
X				case '9':
X					if(svsp->udk_deflow)	/* low nibble */
X					{
X						svsp->udk_def[svsp->udk_defi] |= (ch -'0');
X						svsp->udk_deflow = 0;
X						svsp->udk_defi = (svsp->udk_defi+1 >= MAXUDKDEF) ?
X						svsp->udk_defi : svsp->udk_defi+1;
X					}
X					else			/* high nibble */
X					{
X						svsp->udk_def[svsp->udk_defi] = ((ch -'0') << 4);
X						svsp->udk_deflow = 1;
X					}
X					break;
X
X				case 'a':
X				case 'b':
X				case 'c':
X				case 'd':
X				case 'e':
X				case 'f':
X					if(svsp->udk_deflow) 	/* low nibble */
X					{
X						svsp->udk_def[svsp->udk_defi] |= (ch - 'a' + 10);
X						svsp->udk_deflow = 0;
X						svsp->udk_defi = (svsp->udk_defi+1 >= MAXUDKDEF) ?
X						svsp->udk_defi : svsp->udk_defi+1;
X					}
X					else			/* high nibble */
X					{
X						svsp->udk_def[svsp->udk_defi] = ((ch - 'a' + 10) << 4);
X						svsp->udk_deflow = 1;
X					}
X					break;
X
X
X
X				case 'A':
X				case 'B':
X				case 'C':
X				case 'D':
X				case 'E':
X				case 'F':
X					if(svsp->udk_deflow) 	/* low nibble */
X					{
X						svsp->udk_def[svsp->udk_defi] |= (ch - 'A' + 10);
X						svsp->udk_deflow = 0;
X						svsp->udk_defi = (svsp->udk_defi+1 >= MAXUDKDEF) ?
X						svsp->udk_defi : svsp->udk_defi+1;
X					}
X					else			/* high nibble */
X					{
X						svsp->udk_def[svsp->udk_defi] = ((ch - 'A' + 10) << 4);
X						svsp->udk_deflow = 1;
X					}
X					break;
X
X				case ';':	/* next function key */
X					vt_udk(svsp);
X					svsp->dcs_state = DCS_AND_UDK;
X					break;
X
X				case 0x1b:	 /* ESC */
X					svsp->dcs_state = DCS_UDK_ESC;
X					break;
X	
X				default:
X					svsp->transparent = 0;
X					svsp->state = STATE_INIT;
X					svsp->dcs_state = DCS_INIT;
X					break;
X			}
X			break;
X		
X		case DCS_UDK_ESC:	 /* DCS ... | fkey/def ... ESC */
X			switch(ch)
X			{
X				case '\\':	/* ST */
X					vt_udk(svsp);
X					svsp->transparent = 0;
X					svsp->state = STATE_INIT;
X					svsp->dcs_state = DCS_INIT;
X					break;
X
X				default:
X					svsp->transparent = 0;
X					svsp->state = STATE_INIT;
X					svsp->dcs_state = DCS_INIT;
X					break;
X			}
X			break;
X							
X
X		case DCS_DLD_DSCS:	 /* got DCS ... { */
X			if(ch >= ' ' && ch <= '/')	/* intermediates ... */
X			{
X				svsp->dld_dscs[svsp->dld_dscsi] = ch;
X				svsp->dld_id[svsp->dld_dscsi] = ch;		
X				if(svsp->dld_dscsi >= DSCS_LENGTH)
X				{
X					svsp->transparent = 0;
X					svsp->state = STATE_INIT;
X					svsp->dcs_state = DCS_INIT;
X					svsp->dld_id[0] = '\0';
X				}
X				else
X				{
X					svsp->dld_dscsi++;
X				}
X			}
X			else if(ch >= '0' && ch <= '~')	/* final .... */
X			{
X				svsp->dld_dscs[svsp->dld_dscsi] = ch;
X				svsp->dld_id[svsp->dld_dscsi++] = ch;
X				svsp->dld_id[svsp->dld_dscsi] = '\0';
X				svsp->dcs_state = DCS_DLD_DEF;
X			}
X			else
X			{
X				svsp->transparent = 0;
X				svsp->state = STATE_INIT;
X				svsp->dcs_state = DCS_INIT;
X				svsp->dld_id[0] = '\0';
X			}
X			break;
X
X		case DCS_DLD_DEF:	 /* DCS ... { dscs */
X			switch(ch)
X			{
X				case 0x1b:	 /* ESC */
X					svsp->dcs_state = DCS_DLD_ESC;
X					break;
X	
X				case '/':	 /* sixel upper / lower divider */
X					svsp->dld_sixel_lower = 1;
X					break;
X	
X				case ';':	 /* character divider */
X					vt_dld(svsp);
X					svsp->parms[1]++;	/* next char */
X					break;
X	
X 				default:
X					if (svsp->dld_sixel_lower)
X					{
X						if(ch >= '?' && ch <= '~')
X							svsp->sixel.lower[svsp->dld_sixelli] = ch - '?';
X						svsp->dld_sixelli =
X						 (svsp->dld_sixelli+1 < MAXSIXEL) ?
X						 svsp->dld_sixelli+1 : svsp->dld_sixelli;
X					}
X					else
X					{
X						if(ch >= '?' && ch <= '~')
X							svsp->sixel.upper[svsp->dld_sixelui] = ch - '?';
X						svsp->dld_sixelui =
X						 (svsp->dld_sixelui+1 < MAXSIXEL) ?
X						 svsp->dld_sixelui+1 : svsp->dld_sixelui;
X					}
X					break;
X			}
X			break;
X
X		case DCS_DLD_ESC:	 /* DCS ... { dscs ... / ... ESC */
X			switch(ch)
X			{
X				case '\\':	/* String Terminator ST */
X					vt_dld(svsp);
X					svsp->transparent = 0;
X					svsp->state = STATE_INIT;
X					svsp->dcs_state = DCS_INIT;
X					break;
X
X 				default:
X					svsp->transparent = 0;
X					svsp->state = STATE_INIT;
X					svsp->dcs_state = DCS_INIT;
X					svsp->dld_id[0] = '\0';
X					break;
X			}
X			break;
X
X		default:
X			svsp->transparent = 0;
X			svsp->state = STATE_INIT;
X			svsp->dcs_state = DCS_INIT;
X			break;
X	}
X}
X
X
X/*---------------------------------------------------------------------------*
X *	User Defineable Keys
X *---------------------------------------------------------------------------*/
Xstatic void vt_udk(svsp)
Xstruct video_state *svsp;
X{
X	int key, start, max, i;
X	int usedff = 0;
X	
X	if(svsp->parms[0] != 1)		/* clear all ? */
X	{
X		clear_udk(svsp);
X		svsp->parms[0] = 1;
X	}
X
X	if(svsp->udk_fnckey < 17 || svsp->udk_fnckey > 34)
X	{
X		init_udk(svsp);
X		return;
X	}
X
X	key = svsp->udk_fnckey - 17;	/* index into table */
X	
X	if(svsp->ukt.length[key] == 0)			/* never used ? */
X	{
X		if(svsp->udkff < MAXUDKDEF-2)		/* space available ? */
X		{
X			start = svsp->udkff;		/* next sequential */
X			max = MAXUDKDEF - svsp->udkff;	/* space available */
X			svsp->ukt.first[key] = start;	/* start entry */
X			usedff = 1;			/* flag to update later */
X		}
X		else					/* no space */
X		{
X			init_udk(svsp);
X			return;
X		}
X	}
X	else						/* in use, redefine */
X	{
X		start = svsp->ukt.first[key];		/* start entry */
X		max = svsp->ukt.length[key];		/* space available */
X	}
X
X	if(max < 2)				/* hmmm .. */
X	{
X		init_udk(svsp);
X		return;
X	}
X
X	max--;		/* adjust for tailing '\0' */
X	
X	for(i = 0; i < max && i < svsp->udk_defi; i++)
X		svsp->udkbuf[start++] = svsp->udk_def[i];
X
X	svsp->udkbuf[start] = '\0';	/* make it a string, see pcvt_kbd.c */
X	svsp->ukt.length[key] = i+1;	/* count for tailing '\0' */
X	if(usedff)
X		svsp->udkff += (i+2);	/* new start location */
X	
X	init_udk(svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	clear all User Defineable Keys
X *---------------------------------------------------------------------------*/
Xstatic void clear_udk(svsp)
Xstruct video_state *svsp;
X{
X	register int i;
X
X	for(i = 0; i < MAXUDKEYS; i++)
X	{
X		svsp->ukt.first[i] = 0;
X		svsp->ukt.length[i] = 0;
X	}
X	svsp->udkff = 0;
X}
X
X/*---------------------------------------------------------------------------*
X *	Initialization for User Defineable Keys
X *---------------------------------------------------------------------------*/
Xstatic void init_udk(svsp)
Xstruct video_state *svsp;
X{
X	svsp->udk_defi = 0;
X	svsp->udk_deflow = 0;
X	svsp->udk_fnckey = 0;
X}
X
X/*---------------------------------------------------------------------------*
X *	Down line LoaDable Fonts
X *---------------------------------------------------------------------------*/
Xstatic void vt_dld(svsp)
Xstruct video_state *svsp;
X{
X	unsigned char vgacharset;
X	unsigned char vgachar[16];
X	unsigned char vgacharb[16];
X
X	if(vgacs[svsp->vga_charset].secondloaded)
X		vgacharset = vgacs[svsp->vga_charset].secondloaded;
X	else
X		return;
X
X	svsp->parms[1] = (svsp->parms[1] < 1) ? 1 : 
X		((svsp->parms[1] > 0x7E) ? 0x7E : svsp->parms[1]);
X
X	if(svsp->parms[2] != 1)   /* Erase all characters ? */
X	{
X		clear_dld(svsp);
X		svsp->parms[2] = 1;   /* Only erase all characters once per sequence */
X	}
X
X	sixel_vga(&(svsp->sixel),vgachar);
X
X	switch(vgacs[vgacharset].char_scanlines & 0x0F)
X	{
X		case 7:
X			vga10_vga8(vgachar,vgacharb);
X			break;
X
X		case 9:
X		default:
X			vga10_vga10(vgachar,vgacharb);
X			break;
X
X		case 13:
X			vga10_vga14(vgachar,vgacharb);
X			break;
X
X		case 15:
X			vga10_vga16(vgachar,vgacharb);
X			break;
X	}
X
X	loadchar(vgacharset, svsp->parms[1] + 0xA0, 16, vgacharb);
X
X	init_dld(svsp);
X}
X
X/*---------------------------------------------------------------------------*
X *	Clear loaded downloadable (DLD) character set
X *---------------------------------------------------------------------------*/
Xstatic void clear_dld(struct video_state *svsp)
X{
X	register int i;
X	unsigned char vgacharset;
X	unsigned char vgachar[16];
X
X	if(vgacs[svsp->vga_charset].secondloaded)
X		vgacharset = vgacs[svsp->vga_charset].secondloaded;
X	else
X		return;
X	
X	for(i=0;i < 16;i++)  /* A zeroed character, vt220 has inverted '?' */
X		vgachar[i] = 0x00;
X
X	for(i=1;i <= 94;i++) /* Load (erase) all characters */
X		loadchar(vgacharset, i + 0xA0, 16, vgachar);
X}
X
X/*---------------------------------------------------------------------------*
X *	Initialization for Down line LoaDable Fonts
X *---------------------------------------------------------------------------*/
Xstatic void init_dld(svsp)
Xstruct video_state *svsp;
X{
X	register int i;
X
X	svsp->dld_dscsi = 0;
X	svsp->dld_sixel_lower = 0;
X	svsp->dld_sixelli = 0;
X	svsp->dld_sixelui = 0;
X
X	for(i = 0;i < MAXSIXEL;i++)
X		svsp->sixel.lower[i] = svsp->sixel.upper[i] = 0;
X}
X
X/*---------------------------------------------------------------------------*
X *	select character attributes
X *---------------------------------------------------------------------------*/
Xstatic void vt_sca(svsp)
Xstruct video_state *svsp;
X{
X	switch(svsp->parms[0])
X	{
X		case 1:
X			svsp->selchar = 1;
X			break;
X		case 0:
X		case 2:
X		default:
X			svsp->selchar = 0;
X			break;
X	}
X}
X
X#define INT_BITS	(sizeof(unsigned int) * 8)
X#define INT_INDEX(n)	((n) / INT_BITS)
X#define BIT_INDEX(n)	((n) % INT_BITS)
X
X/*---------------------------------------------------------------------------*
X *	initalize selective attribute bit array
X *---------------------------------------------------------------------------*/
Xstatic void init_sel(svsp)
Xstruct video_state *svsp;
X{
X	register int i;
X	
X	for(i = 0;i < MAXDECSCA;i++)
X		svsp->decsca[i] = 0;
X}
X
X
X/*---------------------------------------------------------------------------*
X *	set selective attribute if appropriate
X *---------------------------------------------------------------------------*/
Xstatic void selective_attribute(svsp)
Xstruct video_state *svsp;
X{
X	int i;
X
X	i = svsp->crtat - svsp->Crtat;
X
X	if(svsp->selchar)
X		svsp->decsca[INT_INDEX(i)] |=  (1 << BIT_INDEX(i));
X	else
X		svsp->decsca[INT_INDEX(i)] &= ~(1 << BIT_INDEX(i));
X}
X
X/*---------------------------------------------------------------------------*
X *	selective erase a region
X *---------------------------------------------------------------------------*/
Xstatic void
Xselective_erase(struct video_state *svsp, u_short *pcrtat, int length)
X{
X	register int i, j;
X	
X	for(j = pcrtat - svsp->Crtat, i = 0;i < length;i++,pcrtat++)
X	{
X		if(!(svsp->decsca[INT_INDEX(j+i)] & (1 << BIT_INDEX(j+i))))
X		{
X			*pcrtat &= 0xFF00; /* Keep the video character attributes */
X			*pcrtat += ' ';	   /* Erase the character */
X		}
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	DECSEL - selective erase in line
X *---------------------------------------------------------------------------*/
Xstatic void vt_sel(svsp)
Xstruct video_state *svsp;
X{
X	switch(svsp->parms[0])
X	{
X		case 0:
X			selective_erase(svsp, svsp->crtat, COL-svsp->col);
X			break;
X
X		case 1:
X			selective_erase(svsp, svsp->crtat-svsp->col, svsp->col + 1);
X			break;
X
X		case 2:
X			selective_erase(svsp, svsp->crtat-svsp->col, COL);
X			break;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *	DECSED - selective erase in display
X *---------------------------------------------------------------------------*/
Xstatic void vt_sed(svsp)
Xstruct video_state *svsp;
X{
X	switch(svsp->parms[0])
X	{
X		case 0:
X			selective_erase(svsp, svsp->crtat, svsp->Crtat + (COL * svsp->screen_rows) - svsp->crtat);
X			break;
X
X		case 1:
X			selective_erase(svsp, svsp->Crtat, svsp->crtat - svsp->Crtat + 1 );
X			break;
X
X		case 2:				
X			selective_erase(svsp, svsp->Crtat, COL * svsp->screen_rows);
X			break;
X	}
X}
X
X/*---------------------------------------------------------------------------*
X *
X *	partial HP 2392 ANSI mode Emulator
X *	==================================
X *
X *	this part tooks over the emulation of some escape sequences
X *	needed to handle the function key labels
X *
X *	They are modeled after the corresponding escape sequences
X *	introduced with the HP2392 terminals from Hewlett-Packard.
X *
X *	see:
X *	"HP2392A, Display Terminal Reference Manual",
X *	HP Manual Part Number 02390-90001
X *	and:
X *	Reference Manual Supplement
X *	"2392A Display Terminal Option 049, ANSI Operation"
X *	HP Manual Part Number 02390-90023EN
X *
X *---------------------------------------------------------------------------*/
X
Xstatic void hp_entry(u_char ch, struct video_state *svsp)
X{
X	switch(svsp->hp_state)
X	{
X		case SHP_INIT:
X			switch(ch)
X			{
X				case 'f':
X					svsp->hp_state = SHP_AND_F;
X					svsp->attribute = 0;
X					svsp->key = 0;
X					svsp->l_len = 0;
X					svsp->s_len = 0;
X					svsp->i = 0;
X					break;
X
X				case 'j':
X					svsp->m_len = 0;
X					svsp->hp_state = SHP_AND_J;
X					break;
X
X				default:
X					svsp->hp_state = SHP_INIT;
X					svsp->state = STATE_INIT;
X					break;
X			}
X			break;
X	
X		case SHP_AND_F:
X			if((ch >= '0') && (ch <= '2'))
X			{
X				svsp->attribute = ch;
X				svsp->hp_state = SHP_AND_Fa;
X			}
X			else
X			{
X				svsp->hp_state = SHP_INIT;
X				svsp->state = STATE_INIT;
X			}
X			break;
X
X		case SHP_AND_Fa:
X			if(ch == 'a')
X			{
X				svsp->hp_state = SHP_AND_Fak;
X			}
X			else
X			{
X				svsp->hp_state = SHP_INIT;
X				svsp->state = STATE_INIT;
X			}
X			break;
X
X		case SHP_AND_Fak:
X			if((ch >= '1') && (ch <= '8'))
X			{
X				svsp->key = ch;
X				svsp->hp_state = SHP_AND_Fak1;
X			}
X			else
X			{
X				svsp->hp_state = SHP_INIT;
X				svsp->state = STATE_INIT;
X			}
X			break;
X
X		case SHP_AND_Fak1:			
X			if(ch == 'k')
X				svsp->hp_state = SHP_AND_Fakd;
X			else
X			{
X				svsp->hp_state = SHP_INIT;
X				svsp->state = STATE_INIT;
X			}
X			break;
X			
X		case SHP_AND_Fakd:
X			if(svsp->l_len > 16)
X			{
X				svsp->hp_state = SHP_INIT;
X				svsp->state = STATE_INIT;
X			}
X			else if(ch >= '0' && ch <= '9')
X			{
X				svsp->l_len *= 10;
X				svsp->l_len += (ch -'0');
X			}
X			else if(ch == 'd')
X				svsp->hp_state = SHP_AND_FakdL;
X			else
X			{
X				svsp->hp_state = SHP_INIT;
X				svsp->state = STATE_INIT;
X			}
X			break;
X
X		case SHP_AND_FakdL:
X			if(svsp->s_len > 80)
X			{
X				svsp->hp_state = SHP_INIT;
X				svsp->state = STATE_INIT;
X			}
X			else if(ch >= '0' && ch <= '9')
X			{
X				svsp->s_len *= 10;
X				svsp->s_len += (ch -'0');
X			}
X			else if(ch == 'L')
X			{
X				svsp->hp_state = SHP_AND_FakdLl;
X				svsp->transparent = 1;
X			}
X			else
X			{
X				svsp->hp_state = SHP_INIT;
X				svsp->state = STATE_INIT;
X			}
X			break;
X
X		case SHP_AND_FakdLl:
X			svsp->l_buf[svsp->i] = ch;
X			if(svsp->i >= svsp->l_len-1)
X			{
X				svsp->hp_state = SHP_AND_FakdLls;
X				svsp->i = 0;
X			}
X			else
X				svsp->i++;
X			break;
X			
X		case SHP_AND_FakdLls:
X			svsp->s_buf[svsp->i] = ch;
X			if(svsp->i >= svsp->s_len-1)
X			{
X				svsp->state = STATE_INIT;
X				svsp->hp_state = SHP_INIT;
X				svsp->transparent = 0;
X				svsp->i = 0;
X				svsp->l_buf[svsp->l_len] = '\0';
X				svsp->s_buf[svsp->s_len] = '\0';
X				writefkl((svsp->key - '0' -1), svsp->l_buf, svsp);
X			}
X			else
X				svsp->i++;
X			break;
X
X		case SHP_AND_J:
X			switch(ch)
X			{
X				case '@':	/* enable user keys, remove */
X						/* all labels & status from */
X						/* screen 		    */
X					svsp->hp_state = SHP_INIT;
X					svsp->state = STATE_INIT;
X					fkl_off(svsp);
X					break;
X
X				case 'A':	/* enable & display "modes" */
X					svsp->hp_state = SHP_INIT;
X					svsp->state = STATE_INIT;
X					fkl_on(svsp);
X					sw_sfkl(svsp);
X					break;
X
X				case 'B':	/* enable & display "user"  */
X					svsp->hp_state = SHP_INIT;
X					svsp->state = STATE_INIT;
X					fkl_on(svsp);
X					sw_ufkl(svsp);
X					break;
X
X				case 'C':	/* remove (clear) status line*/
X						/* and restore current labels*/
X					svsp->hp_state = SHP_INIT;
X					svsp->state = STATE_INIT;
X					fkl_on(svsp);
X					break;
X
X				case 'R':	/* enable usr/menu keys */
X						/* and fkey label modes */
X					svsp->hp_state = SHP_INIT;
X					svsp->state = STATE_INIT;
X					break;
X
X				case 'S':	/* disable usr/menu keys */
X						/* and fkey label modes */
X					svsp->hp_state = SHP_INIT;
X					svsp->state = STATE_INIT;
X					break;
X
X				case '0':
X				case '1':
X				case '2':
X				case '3':
X				case '4':
X				case '5':
X				case '6':
X				case '7':
X				case '8':
X				case '9':	/* parameters for esc & j xx L mm */
X					svsp->m_len *= 10;
X					svsp->m_len += (ch -'0');
X					break;
X	
X				case 'L':
X					svsp->hp_state = SHP_AND_JL;
X					svsp->i = 0;
X					svsp->transparent = 1;
X					break;
X
X				default:
X					svsp->hp_state = SHP_INIT;
X					svsp->state = STATE_INIT;
X					break;
X
X			}
X			break;
X
X
X		case SHP_AND_JL:
X			svsp->m_buf[svsp->i] = ch;
X			if(svsp->i >= svsp->m_len-1)
X			{
X				svsp->state = STATE_INIT;
X				svsp->hp_state = SHP_INIT;
X				svsp->transparent = 0;
X				svsp->i = 0;
X				svsp->m_buf[svsp->m_len] = '\0';
X/* display status line */
X/* needs to be implemented */
X/* see 2392 man, 3-14 */
X			
X			}
X			else
X				svsp->i++;
X			break;
X
X		default:
X			svsp->hp_state = SHP_INIT;
X			svsp->state = STATE_INIT;
X			svsp->transparent = 0;
X			break;
X	}
X}
X
X/* ------------------------- E O F ------------------------------------------*/
SHAR_EOF
$TOUCH -am 0114130693 pcvt_out.c &&
chmod 0660 pcvt_out.c ||
echo "restore of pcvt_out.c failed"
set `wc -c pcvt_out.c`;Wc_c=$1
if test "$Wc_c" != "88687"; then
	echo original size 88687, current size $Wc_c
fi
fi
echo "End of part 10, continue with part 11"
exit 0
-- 
hellmuth michaelis    HCS Hanseatischer Computerservice GmbH   hamburg, europe
hm@hcshh.hcs.de              tel: +49/40/55903-170         fax: +49/40/5591486