[net.emacs] Gosling emacs hp [presumably 264x/262x] driver wanted

chris@umcp-cs.UUCP (Chris Torek) (09/06/85)

You will have to convert this back to a "pure 264" driver; it uses
my own display code.  But it does work reasonably well.  Beware,
some HPs require immense amounts of padding; this driver provides
only that which works on the ones we have around here.

Anyone who wants to get confused about HP26xx internals should read
through the code here.  They must be strange inside!

: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
all=FALSE
if [ x$1 = x-a ]; then
	all=TRUE
fi
/bin/echo 'Extracting TrmHP.c'
sed 's/^X//' <<'//go.sysin dd *' >TrmHP.c
X/* Terminal control module for HP26xx */

#include <stdio.h>
#include "Trm.h"
#include "cm.h"

#define ILpad	2000L		/* 2ms */
#define DLpad	2000L		/* 2ms */
#define ICpad	3000L		/* 3ms */
#define DCpad	4000L		/* 4ms */

static int DesHL, HLflags[24], DesIns, CurIns, Text[24], MayBeJunkBelow;

static INSmode (new) {
	DesIns = new;
}

static HLmode (new) {
	DesHL = new;
}

X/* The HP terminal has a number of oddities: highlight is weird; it runs
   less than 9600 baud when overwriting text; and (sigh) the cursor wraps.
   These macros are mostly to get around these limitations. */

X/* Must do all highlighting at column 0. */
#define SetHL()		if (DesHL != HLflags[curY]) {			\
				printf (DesHL ? "\033&dB" : "\033&d@");	\
				HLflags[curY] = DesHL;			\
			} else

X/* Distressingly normal! */
#define SetIns()	if (DesIns != CurIns) { 			\
				putchar (033); 				\
				putchar (DesIns ? 'Q' : 'R');		\
				CurIns = DesIns;			\
			} else

X/* When overwriting text, must pad */
#define	MIN(a,b) ((a)<(b)?(a):(b))
#define	PadText(n)	if (!DesIns && curX <= Text[curY]) {		\
				register zz = Text[curY] - curX;	\
				pad (MIN (zz, n), 1000L);		\
			} else

#define	SetText()	if (curX > Text[curY])				\
				Text[curY] = curX;			\
			else

X/* Cursor wrap from last line?  Must un-scroll */
#define	FixCurs()	if (curY >= 24) {				\
				printf ("\033H");			\
				curY = 0;				\
			} else

static inslines (n) register n; {
	register i;
	for (i = 24 - n; --i >= curY; )
		HLflags[i + n] = HLflags[i], Text[i + n] = Text[i];
	for (i = curY + n; --i >= curY; ) {
		HLflags[i] = 0, Text[i] = 0;
		putchar (033), putchar ('L');
		pad (24 - curY, ILpad);
	}
	MayBeJunkBelow++;
}

static dellines (n) register n; {
	register i;
	for (i = curY + n; i < 24; i++)
		HLflags[i - n] = HLflags[i], Text[i - n] = Text[i];
	for (i = 24 - n; i < 24; i++) {
		HLflags[i] = 0, Text[i] = 0;
		putchar (033), putchar ('M');
		pad (24 - curY, DLpad);
	}
	/* Clear new lines (delete line brings up stuff that was held below) */
	if (MayBeJunkBelow) {
		MayBeJunkBelow = 0;
		cmgoto (24 - n, 0);
		putchar (033), putchar ('J');
		pad (49 - n, 1000L);
	}
}

static writechars (start, end) register char *start, *end; {
	int n = end-start+1;

	PadText (n);
	SetIns ();
	while (start <= end)
		putchar (*start++);
	cmplus (n);
	if (CurIns) {
		Text[curY] += n;
		pad (n, ICpad);
	}
	else
		SetText ();
	FixCurs ();
}

static blanks (n) {
	register k = n;

	PadText (k);
	SetIns ();
	while (--k >= 0)
		putchar (' ');
	cmplus (n);
	if (CurIns) {
		Text[curY] += n;
		pad (n, ICpad);
	}
	else
		SetText ();
	FixCurs ();
}

static topos (row, col) {
	cmgoto (row-1, col-1);
	pad (1, 1000L);
}

static init (BaudRate, tabok) {
	double BaudFactor = BaudRate / 10000.;

	tt.t_ILnpf = BaudFactor * (ILpad/1000.);
	tt.t_DLnpf = BaudFactor * (DLpad/1000.);
	tt.t_ICmf = BaudFactor * (ICpad/1000.);
	tt.t_DCmf = 2.0 + BaudFactor * (DCpad/1000.);
	UseTabs = tabok;
	cmcostinit ();
}

static reset () {
	printf ("\033R");
	CurIns = 0;
	wipescreen ();
}

static cleanup () {
	printf ("\033&d@\033R\033J");
	MayBeJunkBelow = 0;
}

static wipeline (h) {
	putchar (033);
	putchar ('K');
	if (curX == 0)
		HLflags[curY] = 0;
	if (h || curX == 0)
		SetHL ();
	Text[curY] = curX;
	pad (1, 2000L);
}

static wipescreen () {
	register i;

	for (i = 0; i < 24; i++)
		HLflags[i] = 0, Text[i] = 0;
	printf ("\033H\033J");
	cmat (0, 0);
	MayBeJunkBelow = 0;
	pad (1, 20000L);
}

static delchars (n) {
	register k = n;
	while (--k >= 0)
		putchar (033), putchar ('P');
	Text[curY] -= n;
	pad (n, DCpad);
}

TrmHP () {
	tt.t_INSmode = INSmode;
	tt.t_HLmode = HLmode;
	tt.t_inslines = inslines;
	tt.t_dellines = dellines;
	tt.t_blanks = blanks;
	tt.t_init = init;
	tt.t_cleanup = cleanup;
	tt.t_wipeline = wipeline;
	tt.t_wipescreen = wipescreen;
	tt.t_topos = topos;
	tt.t_reset = reset;
	tt.t_delchars = delchars;
	tt.t_writechars = writechars;
	tt.t_length = 24;
	tt.t_width = 80;
	tt.t_ILov = 2;
	tt.t_DLov = 2;
	tt.t_ICov = 2;
	Up = "\033A";
	Down = "\n";
	Left = "\b";
	Right = "\033C";
	Home = "\033H";		/* wonder if all HPs have these? */
	CR = "\r";
	Tab = "\t";
	TabWidth = 8;
	AbsPosition = "\033&a%dr%dC";
	ColPosition = "\033&a%dC";
	RowPosition = "\033&a%dR";
	ScreenRows = tt.t_length;
	ScreenCols = tt.t_width;
	AutoWrap = 1;
	Wcm_init ();
}
//go.sysin dd *
if [ `wc -c < TrmHP.c` != 4301 ]; then
	made=FALSE
	/bin/echo 'error transmitting "TrmHP.c" --'
	/bin/echo 'length should be 4301, not' `wc -c < TrmHP.c`
else
	made=TRUE
fi
if [ $made = TRUE ]; then
	/bin/chmod 644 TrmHP.c
	/bin/echo -n '	'; /bin/ls -ld TrmHP.c
fi
exit 0
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland