Newsgroups: comp.sys.ti
Path: utzoo!utgpu!jarvis.csri.toronto.edu!csri.toronto.edu!pkern
From: pkern@csri.toronto.edu (pkern)
Subject: a vt100 emulator in Turbo C  (1 of 3)
Message-ID: <8806071608.AA12793@bloor.csri.toronto.edu>
Organization: University of Toronto, CSRI
Date:	Tue, 7 Jun 88 10:48:34 EDT


Here's something I put together to try to get some "real" use out
of the TI Professional sitting on my desk. It seems to be fairly reliable.
It only causes the Pro to hang about once out of every 15 tries. (1/2 :-)
I'm hoping that's because of the Turbo C 1.0 bugs I keep hearing about.

Duck! Here it comes.
----------------------------------------------------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	DOC
#	Makefile
#	screen.c
#	ports.c
#	keybrd.c
#	gfx.c
#	tipro.h
# This archive created: Tue Jun  7 11:19:24 1988
# By:	pkern ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(5460 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
X	Cterm  -  a vt100 emulator written in Turbo C.
X
XCterm is actually more of an XT100+ emulator since it includes some
XLanpar extensions. Cterm was written mainly because there weren't
Xany easily available, *solid* vt100 emulators for TI Professionals.
X
XCterm is currently configured for the TI Professional.
XIt should be relatively easy to port it to the IBM PC & clones.
XSuch a port would most likekly involve re-editing screen.c and keybrd.c
Xand overhauling ports.c. Also, it might be necessary to tweak term.c.
X
XFeatures:
X- eats vt100/vt52 codes and acts on most of them (see below)
X- simulates both user and remote XON/XOFF flow control
X- emulates vt100 cursor key and keypad codes and modes
X- implements most xt100+ setup options
X- implements local mode operations
X- executes commands to DOS
X- includes kermit, xmodem and raw text transfers
X- includes primitive graphics support
X- written in C
X
XNot supported:
X132 columns, printer support, reverse video, smooth scrolling,
Xdouble width & double height characters, screen saver, margin bell,
Xkeyclick, pound sign, 2-page operation, diagnostic status line,
Xbuilt-in confidence tests.
X
X
XReference material:
X
XTI Professional Computer Technical Reference Manual
X	Texas Instruments Inc.
X	(a decent machine ... so where did they go wrong?)
XZilog Z8530 SCC Product Specification
X	Zilog databook
XLanpar Limited XT-100 Plus Operating Manual
X	Lanpar Technologies Inc, 35 Riviera Dr, Markham Ont.
X	Lanpar part number B79820104
X	(they also make a pretty good vt220 clone)
XTurbo C 1.0 User's Guide and Reference Guide
X	Borland International
X	(Hmm, maybe it's time to get version 1.5)
XQkermit
X	kermit and vt100 emulation for IBM-PCs written in
X	Turbo Pascal by Victor Lee at Queen's Univ., Kingston Ont.
X	Obtained from KERMSRV@CUVMA.BITNET.
Xmsxtip.asm
X	TI Pro serial port module for MS-Kermit written by Dan Smith
X	and Joe Smith. Obtained from KERMSRV@CUVMA.BITNET.
XBYTE, March/88
X	Bresenham's line algorithm, p. 252 (see gfx.c)
X
X
XExternal source code:
Xvttest
X	vt100 validation program by Per Lindberg at Stockholm Univ.
X	(see vttest/main.c)
XC-Kermit 1.0
X	(see kermit.c)
Xxmodem 1.0
X	(see xmodem.c)
X
X
XManifest:
X
Xfile		blurb
X----		-----
XDOC		basic user information.
XREADME		you are.
Xcommon.h	definitions common to all except kermit and xmodem
Xcterm.ini	cterm startup config file
Xdefs.c		read/write setups from/to file (ie. cterm.ini)
Xesc.c		vt100(ansi) and vt52 support
Xgfx.c		simple TI graphics support (pixels, palettes and lines)
Xkermit.c	antique ckermit. chosen because it was only one file and
X		therefore easy to make all its global variables static
X		so that there wouldn't be any potential name conflicts.
Xkeybrd.c	TI Pro keyboard support.
Xmain.c		misc startup steps and some misc functions.
Xmakefile	written for Turbo's Make.
Xmisc.c		misc strings.
Xports.c		TI Pro serial port support.
Xprinter.c	phantom printer support.
Xscreen.c	TI Pro text screen support.
Xsetup.c		implements xt100-like setup screens.
X		DOS commands & file transfers take place here.
Xterm.c		main loop and local mode support.
Xtext.c		raw text transfer support.
Xtipro.h		definitions common to all TI Pro support modules.
Xtypes.h		needed to compile xmodem.c
Xxmodem.c	antique xmodem. chosen for the same reason as kermit.
X
Xvttest/*	vt100 testing. compile and run it on another system.
X
X
XNotes:
X
XWith the included makefile and source code, Turbo C 1.0 creates
Xa cterm.exe which is just under 50K. This leaves 14K breathing
Xspace before it's necessary to change memory models (probably
Xthe medium model (large code, small data)). If kermit and xmodem are
Xnot included, cterm.exe is about 30K bytes. If one protocol is used
Xexclusively it might be a good idea to drop one and hack & link in an
Xupdated version of the other in order to remain in small-model range.
X
XVttest is strictly a unix program. It's included as a testing tool.
XIf it's been ported to PCs it might make a dandy ANSI.SYS tester.
X
XKermit.c and xmodem.c are ancient self-contained UNIX programs which
Xwere re-edited to run on DOS. Any unix system should be able to compile
Xeach file as-is and then run them, without any extra work.
XThe DOS modifications involved #ifdef-swapping code in the needed areas.
XTurbo C and it's near-unix library compatibility helped a great deal.
XUnix-based kermits and xmodems with multiple modules may require a bit
Xmore re-editing before they can be "plugged in" to cterm, but it's still
Xprobably easier than trying to build in kermit and xmodem from scratch.
XThe versions included here are marginal in their ability to work with
Xtheir later generations.  They both work OK on ordinary text transfers.
XBinaries are another matter altogether. Xmodem.c will work OK with
Xitself (ie. xmodem 1.0 running on the SUN). Binaries transfers don't
Xseem to work with xmodem 3.4 on a SUN. Kermit.c seems to need 8-bit
Xprefixing added before it hack binaries.  However since binary transfers
Xare not a priority around here this doesn't cause too many problems.
XActually, forthcoming cterm versions (if there are any more) will likely
Xinclude a stripped down ckermit 4E (ie. without interactive commands).
X
X
XDOC and README were edited with vi on a SUN using cterm to connect a
XTI Pro to a DevelCon terminal switch at 9600 baud.
X
XFeedback of any kind would be most appreciated.
X
XPaul Kern		  | pkern@csri.toronto.edu
XDept of Computer Science  | ..!{cbosgd, uunet!attcan}!utgpu!utcsri!pkern
XUniversity of Toronto	  | ..!{ihnp4, utzoo, utai}!utcsri!pkern
X(416) 978-4488
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'DOC'" '(3818 characters)'
if test -f 'DOC'
then
	echo shar: will not over-write existing file "'DOC'"
else
sed 's/^X//' << \SHAR_EOF > 'DOC'
XCterm usage guide
X-----------------
X
XFunction key definitions:
X
Xvt100		TI Pro equivalent
X-----		-----------------
X(Exit program)	SHIFT-BRK (in terminal mode only)
X
XSetup		F1	or F2
XBreak		F3
XBackspace	F4
X
XDelete		Ctrl-BACKSPACE
XNo Scroll	PAUS
X
XCursor up	Up-key		or F9
X  "    down	Down-key	or F10
X  "    left     Left-key	or F11
X  "    right	Right-key	or F12
X
XPF1		Keypad =	or Alt-F1
XPF2		Keypad +	or Alt-F2
XPF3		Keypad SPAC	or Alt-F3
XPF4		Keypad TAB	or Alt-F4
X
XKeypad 0	Keypad 0	or Alt-Z	or Alt-X
XKeypad 1	Keypad 1	or Alt-A
XKeypad 2	Keypad 2	or Alt-S
XKeypad 3	Keypad 3	or Alt-D
XKeypad 4	Keypad 4	or Alt-Q
XKeypad 5	Keypad 5	or Alt-W
XKeypad 6	Keypad 6	or Alt-E
XKeypad 7	Keypad 7	or Alt-1
XKeypad 8	Keypad 8	or Alt-2
XKeypad 9	Keypad 9	or Alt-3
XKeypad .	Keypad .	or Alt-C
XKeypad -	Keypad -	or Alt-4
XKeypad '	Keypad '	or Alt-R	
XKeypad ENTER	Keypad ENTER	or Alt-F	or Alt-V
X
X
X
XCterm can be executed with or without arguments.
XWithout arguments, cterm will attempt to read "cterm.ini"
Xand then it will go immediately on-line in terminal mode.
XThe only arguments currently recognized are "-i " which
Xreplaces the default "cterm.ini" file with .
X
X
XDumb graphics:
X
XGraphics functions can be accessed via a few ANSI-like escape sequences.
XAll the sequences begin with Esc @ (^[@).  For motion sequences, upper
Xcase final characters indicate "pen up" moves and lower case means
X"draw a line."  The TI Pro graphics screen is 720 by 300 pixels.
XGraphics consists of 3 bit-planes and 3 corresponding attribute
Xlatches which allow the TI to display up to 8 colours.
XEach attribute latch is 8 bits wide (ie. a byte).
X
XThe "Interlace" option in setup B is used to control
Xwhether the graphics screen can be seen or not.
X
Xsequence	meaning		(possible range) [startup default]
X--------	-------
XEsc@Pnm		change to colour Pn (0-7) [7]
X
XEsc@Pb;Pr;PbL	set blue  attribute latch to Pb (0-255)	[170 (0xAA)]
X		 "  red       "       "   to Pr (0-255)	[204 (0xCC)]
X		 "  green     "       "   to Pg (0-255)	[240 (0xF0)]
X
XEsc@Py;PxH	goto (Px,Py) (0-719, 0-299)	[0, 0]
XEsc@Py;Pxh	draw line from current position to (Px,Py)
X
XEsc@Py;Px@	goto (Px,Py) and light the pixel (ie. boink it)
X
XEsc@PnA		go up	Pn pixels
XEsc@PnB		"  down  "   "
XEsc@PnC		"  right "   "
XEsc@PnD		"  left  "   "
X
XEsc@Pna		draw line up	Pn pixels long
XEsc@Pnb		 "    "   down  "    "     "
XEsc@Pnc		 "    "   right "    "     "
XEsc@Pnd		 "    "   left  "    "     "
X
X
X
XSetups, extensions:
X
XCterm has three setup screens. Setup A handles tabs and file transfers.
XSetup B handles most of the main terminal options. Setup C contains some
Xremaining terminal options and all the printer options. Setup key labels
Xnormally found on strip on the keyboard are now displayed on the screen.
XCterm setups work in much the same way as they do on VT100s and XT100s.
XSpace bar and TAB will move the cursor forward.
XBackspace and the Left-key will move the cursor back.
XHitting RETURN returns the cursor to the left margin.
X
XTo execute a DOS command, type '!' and then the command. Finish with
Xa RETURN. COMMAND.COM will be called to try to execute the command.
XWhen the command is done, cterm will wait for a keyhit before
Xreturning to the setup screen.  DOS can be "called" from any setup.
X
XFile transfers, however, can only be initiated while in setup A.
XTo run kermit, hit 'k' and then type in the appropriate arguments.
XTo run xmodem, hit 'x' and then type in the appropriate arguments.
XTo capture or send raw text, hit 'c' followed by the appropriate
Xarguments.  In all cases, always finish with a RETURN.  If no
Xarguments are given or if they're used incorrectly, each protocol
Xwill display the proper usage. When the transfer is done, cterm will
Xwait for a keyhit before returning to the setup screen.
X
X
XP. Kern		pkern@csri.toronto.edu, pkern@utcsri.uucp
XDCS, U of Toronto
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'Makefile'" '(305 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X#
X#
XCC=	tcc
X# CFLAGS= -Ddebug -DFINIT="cterm.ini"
XCFLAGS=	-O
XEXE=	cterm
X
XOBJ=	esc.obj keybrd.obj main.obj misc.obj ports.obj  \
X	printer.obj screen.obj term.obj  \
X	setup.obj defs.obj gfx.obj  \
X	kermit.obj xmodem.obj text.obj
X
Xterm:	$(OBJ)
X	$(CC) $(CFLAGS) -e$(EXE) *.obj
X
X.c.obj:
X	$(CC) $(CFLAGS) -c $<
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'screen.c'" '(7778 characters)'
if test -f 'screen.c'
then
	echo shar: will not over-write existing file "'screen.c'"
else
sed 's/^X//' << \SHAR_EOF > 'screen.c'
X/*
X * screen handling routines for TI Professional
X *
X *  Notes:
X *    - the attribute information for individual positions on the screen
X *	can only be accessed through AH=0x08 (as far as I can tell).
X *	This would take too long when saving the screen image so
X *	attributes are lost when switching save_scr() to restore_scr().
X *
X *    -	it seems necessary to assert the status line after each CLEANing
X *	(a minor annoyance, if we want to enforce a status line)
X *
X * copyright (c) University of Toronto, 1988.
X */
X#include 
X#include "common.h"
X#include "tipro.h"
X
X#define BLANK	0x0f
X
X#define SCRSIZE	(80*24)
X/* #define SCR_MEM (0xde000000)	/* screen location */
X#define SCR_MEM (0xde00)	/* screen location segment */
X#define L_ATTR	*((char far *)0xdf000800)	/* attribute latch */
X
X#define CRSR_BLK	0x600c	/* slow-blinking block cursor code */
X#define CRSR_UL		0x4b0b	/* fast-blinking underline cursor */
X
Xstatic union REGS r;
Xstatic struct SREGS sr;
Xstatic int xattr=0x0f;	/* attribute storage */
X
Xstatic char o_scrn[SCRSIZE];	/* screen memory storage */
Xstatic int o_xy;		/* cursor position memory */
Xstatic char far *scrn;		/* screen position memory */
X
X/* macros for frequently used code */
X#define crtint		int86(CRT_INT, &r, &r)
X#define GO_HOME		r.h.ah=2; r.x.dx=0; crtint;
X#define DO_STAT		r.h.ah=0x15; r.x.cx=24; crtint;
X#define GO_XY(a,b)	\
X	r.h.ah=2; r.h.dh=(a); r.h.dl=(b); crtint;
X#define CLEAN(n)	\
X	r.x.ax=0x0920; r.h.bl=BLANK; r.x.cx=(n); \
X	crtint; L_ATTR = xattr;
X
X/* set status region on 25th line */
Xinit_scr()
X{
X	DO_STAT
X	segread(&sr);
X}
X
X/* eliminate status region, reset attributes */
Xreset_scr()
X{
X	r.h.ah = 0x15;
X	r.x.cx = 0;
X	crtint;
X	L_ATTR = BLANK;
X}
X
Xcurs_xy(x, y)
Xuchar x, y;
X{
X	GO_XY(x-1, y-1)
X}
X
Xxypos(xp, yp)
Xuchar *xp, *yp;
X{
X	r.h.ah = 3;
X	crtint;
X	*xp = r.h.dh+1;
X	*yp = r.h.dl+1;
X}
X
X
X/* scroll up n lines between min_y and max_y */
Xscrl_up(n, min_y, max_y, x, y)
Xuchar n, min_y, max_y, x, y;
X{
X	r.h.ah = 6; r.h.al = 1;
X	r.h.dh = 0; r.h.dl = min_y-1+n;
X	r.h.bh = 0; r.h.bl = min_y-1;
X	r.h.ch = 80; r.h.cl = max_y - (min_y-1) - n;
X	crtint;
X	GO_XY(0, max_y-n)
X	CLEAN(80 * n)
X	GO_XY(x-1, y-1)
X	DO_STAT
X}
X
X/* scroll down n lines between min_y and max_y */
Xscrl_down(n, min_y, max_y, x, y)
Xuchar n, min_y, max_y, x, y;
X{
X	r.h.ah = 7; r.h.al = 1;
X	r.h.dh = 0; r.h.dl = min_y-1;
X	r.h.bh = 0; r.h.bl = min_y-1+n;
X	r.h.ch = 80; r.h.cl = max_y - (min_y-1) - n;
X	crtint;
X	GO_XY(0, min_y-1)
X	CLEAN(80 * n)
X	GO_XY(x-1, y-1)
X	DO_STAT
X}
X
X
X/* eol : erase to end of line */
Xeol_erase(x, y)  
Xuchar x, y;
X{
X	if (x > 80) return;
X	CLEAN(80-(x-1))
X	DO_STAT
X}
X
X/*
X * bol : erase from beginning of line to cursor pos.
X * ie. goto head of line, erase chars, return to original pos
X */
Xbol_erase(x, y)
Xuchar x, y;
X{
X	GO_XY(0, y-1)
X	CLEAN(x)
X	GO_XY(x-1, y-1)
X	DO_STAT
X}
X
X/* eos : erase to end of line and to end of screen */
Xeos_erase(x, y)
Xuchar x, y;
X{
X	CLEAN( (24-y) * 80 + (80-(x-1)) )
X	DO_STAT
X}
X
X/*
X * bos : erase from beginning of screen (home) to cursor pos.
X * ie. goto head of screen, erase to original pos, return to position
X */
Xbos_erase(x, y)
Xuchar x, y;
X{
X	GO_HOME
X	CLEAN(80 * (y-1) + x)
X	GO_XY(x-1, y-1)
X	DO_STAT
X}
X
X/* goto head of line, erase line, return to original pos */
Xline_erase(x, y)
Xuchar x, y;
X{
X	GO_XY(0, y-1)
X	CLEAN(80)
X	GO_XY(x-1, y-1)
X	DO_STAT
X}
X
X/* goto head of screen, erase all, return to pos */
X/* could've used AH=0x13 but it also erases the status line */
Xall_erase(x, y)
Xuchar x, y;
X{
X	GO_HOME
X	CLEAN(80*24)
X	GO_XY(x-1, y-1)
X	DO_STAT
X}
X
X
X/*
X * insert line(s) :
X * scroll down n lines, goto head of original line, erase empty space
X */
Xline_ins(n, x, y, max_y)
Xuchar n, x, y, max_y;
X{
X	if (y-1+n < max_y) {
X		r.h.ah = 6; r.h.al = 1;
X		r.h.dh = 0; r.h.dl = y-1;
X		r.h.bh = 0; r.h.bl = y-1+n;
X		r.h.ch = 80; r.h.cl = max_y-(y-1)-n;
X		crtint;
X	}
X	else
X		n = max_y - (y-1);
X	GO_XY(0, y-1)
X	CLEAN(80 * n)
X	DO_STAT
X}
X
X/*
X * delete line(s) :
X * scroll up n lines, goto new empty line, erase lines,
X * return to head of original line
X */
Xline_del(n, x, y, max_y)
Xuchar n, x, y, max_y;
X{
X	if (y-1+n < max_y) {
X		r.h.ah = 6; r.h.al = 1;
X		r.h.dh = 0; r.h.dl = y-1+n;
X		r.h.bh = 0; r.h.bl = y-1;
X		r.h.ch = 80; r.h.cl = max_y-(y-1)-n;
X		crtint;
X	}
X	else
X		n = max_y - (y-1);
X	GO_XY(0, max_y-n)
X	CLEAN(80 * n)
X	GO_XY(0, y-1)
X	DO_STAT
X}
X
X/*
X * delete char(s) :
X * ie. scroll rest of line to the left, goto line-end, erase n chars
X * and return to original cursor pos
X */
Xchar_del(n, x, y)
Xuchar n, x, y;
X{
X	if (x-1+n < 80) {
X		r.h.ah = 6; r.h.al = 1;
X		r.h.dh = x-1+n; r.h.dl = y-1;
X		r.h.bh = x-1; r.h.bl = y-1;
X		r.h.ch = 80-(x-1)-n; r.h.cl = 1;
X		crtint;
X	}
X	else
X		n = 80-(x-1);
X	GO_XY(80-n, y-1)
X	CLEAN(n)
X	GO_XY(x-1, y-1)
X	DO_STAT
X}
X
X/*
X * insert char(s) :
X * ie. scroll rest of line to right and clean out new space(s)
X */
Xchar_ins(n, x, y)
Xuchar n, x, y;
X{
X	if (x-1+n < 80) {
X		r.h.ah = 6; r.h.al = 1;
X		r.h.dh = x-1; r.h.dl = y-1;
X		r.h.bh = x-1+n; r.h.bl = y-1;
X		r.h.ch = 80-(x-1)-n; r.h.cl = 1;
X		crtint;
X	}
X	else
X		n = 80-(x-1);
X	CLEAN(n)
X	DO_STAT
X}
X
X/* set attributes
X * "bold" = 2 levels dimmer
X * reverse video also = 2 levels dimmer.
X * (so reverse and bold is 4 levels dimmer)
X */
Xattribs(attr)
Xuchar attr;
X{
X	r.h.ah = 0x16;
X	r.h.bl = 0x0f;	/* char enable, max intensity */
X	if (attr & AT_BOLD) {	r.h.bl -= 2; attr &= 0x07; }
X	if (attr & AT_REV)	r.h.bl -= 2;
X	r.h.bl |= (attr << 4);
X	L_ATTR = r.h.bl;
X	xattr = r.h.bl;
X/*	crtint;	*/
X}
X
X/*
X * screen alignment test :
X * home cursor and write a screen of E's in normal attrib mode.
X * previous attribs are not forgotten.
X */
Xe_screen()
X{
X	GO_HOME
X	r.h.ah = 0x0a;
X	r.h.al = 'E';
X	r.h.bl = 0x1d;	/* ordinary attribs */
X	r.x.cx = 80 * 24;
X	crtint;	/* screen of E's */
X	L_ATTR = xattr;
X	DO_STAT
X}
X
X/* basic single-char output */
Xburpc(c, x, y)
Xint c, x, y;
X{
X	r.h.ah = 0x0e;
X	r.h.al = c;
X	crtint;
X}
X
X/* insert mode burpc() */
X/* move line right, deposit char */
Xinsurpc(c, x, y)
Xint c, x, y;
X{
X	if (x < 80) {
X		r.h.ah = 6; r.h.al = 1;
X		r.h.bh = x; r.h.bl = y-1;
X		r.h.ch = 80-x; r.h.cl = 1;
X		r.h.dh = x-1; r.h.dl = y-1;
X		crtint;
X	}
X	r.h.ah = 0x0e;
X	r.h.al = c;
X	crtint;
X}
X
X/*  output string at x,y with attr */
Xburps(s, x, y, at)
Xchar *s;
Xuchar x, y, at;
X{
X	GO_XY(x-1, y-1)
X	r.h.ah = 0x10;
X	r.h.al = 0x0f;
X	if (at & AT_BOLD) {	r.h.al -= 2; at &= 0x07; }
X	if (at & AT_REV)	r.h.al -= 2;
X	r.h.al |= (at << 4);
X	xattr = r.h.al;
X	r.x.bx = (int)s;
X	r.x.cx = strlen(s);
X	r.x.dx = sr.ds;
X	crtint;
X}
X
X/* set cursor type */
Xcurs_type(sw)
Xuchar sw;
X{
X	r.h.ah = 1;
X	r.x.cx = (sw) ? CRSR_BLK : CRSR_UL;
X	crtint;
X}
X
X/* save screen image & cursor position */
Xsave_scr()
X{
X	register int n;
X	register char *os;
X	register char far *s;
X
X	r.h.ah = 3;
X	crtint;
X	o_xy = r.x.dx;
X	r.h.ah = 0x17;
X	crtint;
X/*	scrn = SCR_MEM | r.x.dx;	*/
X	scrn = (char far *) MK_FP(SCR_MEM, r.x.dx);
X
X	n = SCRSIZE;
X	s = scrn; os = o_scrn;
X	while (n--) *os++ = *s++;
X}
X
X/* restore screen image & cursor position */
Xrestore_scr()
X{
X	register int n;
X	register char *os;
X	register char far *s;
X
X	r.h.ah = 0x17;
X	crtint;
X/*	scrn = SCR_MEM | r.x.dx;	*/
X	scrn = (char far *) MK_FP(SCR_MEM, r.x.dx);
X
X	n = SCRSIZE;
X	s = scrn; os = o_scrn;
X	while (n--) *s++ = *os++;
X
X	r.h.ah = 2;
X	r.x.dx = o_xy;
X	crtint;
X}
X
X/* write string to status line */
Xsturp(s, x, y)
Xchar *s;
Xint x, y;
X{
X	GO_XY(0, 24)
X	r.h.ah = 0x10;
X	r.h.al = 0x1b;
X	r.x.bx = (int)s;
X	r.x.cx = strlen(s);
X	r.x.dx = sr.ds;
X	crtint;
X	GO_XY(x-1, y-1)
X	L_ATTR = xattr;
X}
X
X
X/* delay for n milliseconds */
X
Xdsleep(n)
Xunsigned int n;
X{
X	r.h.ah = 5;
X	r.x.cx = n;
X	int86(0x48, &r, &r);
X}
X
X
X/* bios -- Clear Text Screen And Home the Cursor */
X
Xclr_home()
X{
X	r.h.ah = 0x13;
X	crtint;
X}
X
X
X/* dburp -- put debug message on status line */
X
Xdburp(s)
Xchar *s;
X{
X	uchar x, y;
X
X	xypos(&x, &y);
X	sturp(s, x, y);
X}
X
X
X/* erase graphics screen */
X
Xgfx_erase()
X{
X	r.h.ah = 0x14;
X	crtint;
X}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'ports.c'" '(9944 characters)'
if test -f 'ports.c'
then
	echo shar: will not over-write existing file "'ports.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ports.c'
X/*
X * ports.c:
X *	serial port stuff for TI Professionals
X *
X * copyright (c) University of Toronto, 1988.
X */
X/*
X * layout based in part on modempro.pas from Qkermit and msxtip.asm.
X * TI Pro serial port information obtained from msxtip.asm, the
X * TI Pro Technical Manual, and the Zilog Z8530 SCC product spec.
X */
X
X#include 
X#include "common.h"
X#include "tipro.h"
X
Xextern int nbaud, n_port;
Xextern uchar flowctl, bpc, stopbits, parity, m_prty;
X
Xstatic uchar buffer[BUFMAX];
Xstatic int xout=0, xin=0, n_intr=0;
Xstatic int a_cmd=0, b_cmd=0, a_data=0, b_data=0;
Xstatic int bufovfl=BUFMAX/2,	/* flow control XOFF trigger */
X	bufmpty=BUFMAX/8;	/* flow control XON trigger */
Xstatic uchar flxoff=0;	/* flowctl XOFF-sent flag */
X
X#define BUFC(a,b)	((a bufovfl)
X			{ xmit_chr(XOFF); flxoff=1; }
X	}
X	enable();
X	outportb(IC8259r1, 0x20);	/* 8259 : End-of-interrupt */
X}
X     
X/*
X * set_prt  -  Set the baud rate, parity and stop bits for serial port.
X */
Xset_prt()
X{
X	int i;
X
X	if (!a_cmd) return(-1);
X
X	if (nbaud > EXTA)
X		nbaud = B9600;
X	
X	i = nbaud;
X		
X	/* WR13 : baud rate time const upper byte */
X	outportb(a_cmd, 13);
X	outportb(a_cmd, bdivs[i] >> 8);
X
X	/* WR12 : baud rate time const lower byte */
X	outportb(a_cmd, 12);
X	outportb(a_cmd, bdivs[i] & 0xff);
X
X	/* WR4 : x16 clock mode, 1 or 2 stopbits, parity */
X	i = 0x40;	/* x16 clock mode */
X	i |= (stopbits) ? 0x0c : 0x04;	/* stop bits  ?  2 : 1 */
X	i |= (parity << 1) | m_prty;	/* parity type & mode */
X	outportb(a_cmd, 4);
X	outportb(a_cmd, i);
X
X	bufovfl = BUFMAX/2;
X	bufmpty =  BUFMAX/8;
X
X#ifdef debug
X	regs[13] = BUFMAX; regs[14] = bufovfl; regs[15] = bufmpty;
X#endif
X
X	i = (7 + bpc) - 5;
X	/* WR5 : DTR, RTS, bpc, Tx enable */
X	outportb(a_cmd, 5);
X	outportb(a_cmd, 0x8A | bpctab[i]);
X
X	/* WR3 : bpc, Rx enable */
X	outportb(a_cmd, 3);
X	outportb(a_cmd, 0x01 | (bpctab[i]<<1));
X}
X
X/*
X * init_prt - Initialize the port and install the port ISR.
X */
Xinit_prt()
X{
X	int i, x;
X
X	if (n_port < 0 || n_port > NPORTS-1) return(-1);
X
X	n_intr = ports[n_port].vect;
X	a_cmd = ports[n_port].base + A_CMD;
X	b_cmd = ports[n_port].base + B_CMD;
X	a_data = ports[n_port].base + A_DATA;
X	b_data = ports[n_port].base + B_DATA;
X     
X 		/* clrbuf */
X	for (i=0; i<8; i++) x = inportb(a_data);
X	x = inportb(a_cmd);	/* makes it point to WR0 */
X		/* serina */
X	for (i=0; !(init_a[i] & 0x80); i+=2) {
X		outportb(a_cmd, init_a[i]);
X		outportb(a_cmd, init_a[i+1]);
X	}
X	x = inportb(b_cmd);	/* makes it point to WR0 */
X		/* serinb */
X	for (i=0; !(init_b[i] & 0x80); i+=2) {
X		outportb(b_cmd, init_b[i]);
X		outportb(b_cmd, init_b[i+1]);
X	}
X
X	xin = xout = 0;	/* initialize buffer indices */
X
X	/* save old intr vector to another spot */
X	o_portisr = getvect(n_intr);
X	/* install the new interrupt routine */
X	disable();
X	setvect(n_intr, port_isr);
X	enable();
X
X		/* enable IR0, IR1, IR2, or IR4 */
X	outportb(IC8259r2, inportb(IC8259r2) & ports[n_port].enable);
X/*	outportb(IC8259r1, ports[n_port].disable);	*/
X     
X	set_prt();
X}
X     
X/*
X *  reset_prt - restore the original interrupt, drop DTR and RTS
X */
Xreset_prt()
X{
X	if (!n_intr || !a_cmd) return(-1);
X
X	/* WR9 : disable 8530 interrupts */
X	outportb(a_cmd, 9);
X	outportb(a_cmd, 0);
X	/* WR5 : no DTR, no RTS, Tx enable, bpc */
X	outportb(a_cmd, 5);
X	outportb(a_cmd, 0x64 & bpctab[(7+bpc)-5]);
X
X	/* disable interrupts */
X	outportb(IC8259r2, inportb(IC8259r2) | ports[n_port].disable);
X	/* restore the old interrupt vector */
X	setvect(n_intr, o_portisr);
X}
X     
X/*
X *  conn_prt - checks DCD and CTS.
X * (a historical relic, no longer used)
X */
Xconn_prt()
X{
X	int i;
X
X	i = ((inportb(a_cmd) & 0x24) != 0x24);
X	return(i);
X}
X     
X/*
X * recv_chr - Receive a Character from the serial port.
X * returns:   c     - if there is a character in the buffer.
X *            -1    - if no character found.
X */
Xrecv_chr()
X{
X	uchar c;
X
X	if (flxoff && BUFC(xin,xout) < bufmpty)
X		{ xmit_chr(XON); flxoff=0; }
X
X	if (BUFC(xin,xout) > 0) { /* get char from buffer */
X		c = buffer[xout++] & 0x7f;
X		xout %= BUFMAX;
X		return(c);
X	}
X	return(-1);
X}
X     
Xrecv_byt()
X{
X	uchar c;
X
X	if (BUFC(xin,xout) > 0) {
X		c = buffer[xout++];
X		xout %= BUFMAX;
X		return(c);
X	}
X	return(-1);
X}
X     
X/*
X * xmit_chr - Send a character thru the serial port.
X *           It waits for the previous character to be sent before
X *           sending the current character.
X */
Xxmit_chr(c)
Xint c;
X{
X	while (!(inportb(a_cmd) & 0x04)) ;
X	outportb(a_data, c & 0xff);
X}
X
X/*
X * xmit_str - Same as xmit_chr() except a string is sent instead.
X */
Xxmit_str(p)
Xchar *p;
X{
X	int c;
X
X	while (c = *p++) {
X		while (!(inportb(a_cmd) & 0x04)) ;
X		outportb(a_data, c & 0xff);
X	}
X}
X     
X/*
X * send_brk- Send a long break via the comm port.
X */
Xsend_brk(sw)
Xint sw;
X{
X
X	if (sw) return;		/* ie. in local mode */
X	if (!a_cmd) return(-1);
X
X	/* WR5 : no DTR, no RTS, send break, Tx enable, bpc */
X	outportb(a_cmd, 0x05);
X	outportb(a_cmd, 0x18 | bpctab[(7+bpc)-5]);
X
X	dsleep(250);	/* 1/4 sec. delay */
X
X	/* WR5 : DTR, RTS, Tx enable, bpc */
X	outportb(a_cmd, 0x05);
X	outportb(a_cmd, 0x8A | bpctab[(7+bpc)-5]);
X
X}
X
X/* put char into incoming data buffer (ie. simulate echo) */
Xloop_chr(c)
Xint c;
X{
X	disable();
X	buffer[xin++] = c;
X	xin %= BUFMAX;
X	enable();
X}
X
X/*
X * trns_chr: same as recv_chr but translate control chars
X */
Xtrns_chr()
X{
X	uchar c;
X
X	if (flxoff && BUFC(xin,xout) < bufmpty)
X		{ xmit_chr(XON); flxoff=0; }
X
X	if (BUFC(xin,xout) > 0) { /* get char from buffer */
X		c = buffer[xout] & 0x7F;
X		if (c & 0x60) {
X			xout = (++xout) % BUFMAX;
X			return(c);
X		}
X		else {
X			buffer[xout] = c | '@';
X			return('^');
X		}
X	}
X	return(-1);
X}
X
X/* return vt100 speed number */
Xvtspeed(x)
Xint x;
X{
X/*
X	switch (x) {
X	case B0: case B50: x=0; break;
X	case B75: x=8; break;		case B110: x=16; break;
X	case B134: x=24; break;		case B150: x=32; break;
X	case B200: x=40; break;		case B300: x=48; break;
X	case B600: x=56; break;		case B1200: x=64; break;
X	case B1800: x=72; break;	case B2000: x=80; break;
X	case B2400: x=88; break;	case B3600: x=96; break;
X	case B4800: x=104; break;	case EXTA: x=120; break;
X	case B9600:
X	default: x=112; break;
X	}
X */
X	if (x < B75)
X		return(0);
X	else if (x > B4800)
X		return(112);	/* default 9600 */
X	return((x-1)*8);
X}
X
X/* return bdivs index for speed n */
Xprtspd(n)
Xunsigned int n;
X{
X	int i;
X
X	for (i=0; spdtab[i]; i+=2)
X		if (spdtab[i] == n)
X			return(spdtab[i+1]);
X	return(nbaud);
X}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'keybrd.c'" '(5744 characters)'
if test -f 'keybrd.c'
then
	echo shar: will not over-write existing file "'keybrd.c'"
else
sed 's/^X//' << \SHAR_EOF > 'keybrd.c'
X/*
X * keybrd.c:
X *	functions, maps and interrupt routines for TI Pro keyboards
X *	(see TI Technical Manual for nitty gritty details)
X *
X * copyright (c) University of Toronto, 1988.
X */
X#include 
X#include "common.h"
X#include "tipro.h"
X
Xuchar keyhit=0, keyboom=0;
X
Xstatic union REGS r;
Xstatic uchar f_map=0, f_vec=0;
X
Xextern int zip();
Xextern uchar flowctl, local, xoff;
X
X/* bios check for queued keys */
Xkbdhit()
X{
X	r.h.ah = 1;
X	int86(KBD_INT, &r, &r);
X	return (!(r.x.flags & Zflag));	/* ie. ! Z-flag */
X}
X
X/* flush keyboard type-ahead queue */
Xkbflush()
X{
X	r.h.ah = 3;
X	int86(KBD_INT, &r, &r);
X	keyhit = 0;
X}
X
X/* toggle keyboard autorepeat */
Xkbautorep(sw)
Xint sw;	/* switch : 1 = on, 0 = off */
X{
X	r.h.ah = 4;
X	r.h.al = (sw) ? 1 : 2;
X	int86(KBD_INT, &r, &r);
X}
X
X/* get keyboard word */
Xunsigned int
Xkbdget()
X{
X	r.h.ah = 0;
X	int86(KBD_INT, &r, &r);
X	keyhit--;
X	return((unsigned int) r.x.ax);
X}
X
X/* return a keypadv[] offset */
Xkbdfn(kn)
Xunsigned int kn;
X{
X	extern keymap[];
X
X	return(keymap[kn>>8]);
X}
X
X/*
X *  keypad map (aN == alt N)
X * +-----+-----+-----+-----+
X * | PF1 | PF2 | PF3 | PF4 |		cursor code offsets:
X * | aF1 | aF2 | aF3 | aF4 |			UP - 0
X * +-----+-----+-----+-----+		      DOWN - 1
X * |  7  |  8  |  9  |  -  |		     RIGHT - 2
X * | a1  | a2  | a3  | a4  |		      LEFT - 3
X * +-----+-----+-----+-----+
X * |  4  |  5  |  6  |  ,  |	keypad code string offsets:
X * | aQ  | aW  | aE  | aR  |	8 - "0"	 10 - "8"	18 - "F3"
X * +-----+-----+-----+-----+	9 - "1"  11 - "9"	19 - "F4"
X * |  1  |  2  |  3  |     |	A - "2"  12 - "-"	1A - "\200"
X * | aA  | aS  | aD  |Enter|	B - "3"  13 - ","	1B - "\b"
X * +-----+-----+-----+     |	C - "4"  14 - "."	1C - "\003"
X * |     0     |  .  | aF  |	D - "5"  15 - "ENTER"	1D - "\r\n"
X * | aZ    aX  | aC  | aV  |	E - "6"  16 - "F1"	1E --> ansback
X * +-----------+-----+-----+	F - "7"  17 - "F2"	1F - ""	 (empty)
X */
X
X
X/*
X * keymap:
X *	keypadv[] offsets for all possible
X *	(ie. 90H) extended function-key codes
X */
Xint keymap[0x90] = {
X/* 0x0_ */	0x1f, 0x1f, 0x1f, 0x1a, 0x1f, 0x1f, 0x1f, 0x1f,
X		0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x1f, 0x1f,
X/* 0x1_ */	0x0c, 0x0d, 0x0e, 0x13, 0x1f, 0x1f, 0x1f, 0x1f,
X		0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x09, 0x0a,
X/* 0x2_ */	0x0b, 0x15, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
X		0x1f, 0x1f, 0x1f, 0x1f, 0x08, 0x08, 0x14, 0x15,
X/* 0x3_ */	0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
X		0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1b, 0x1f,
X/* 0x4_ */	0x1f, 0x1f, 0x1f, 0x00, 0x01, 0x03, 0x02, 0x1f,
X		0x00, 0x00, 0x1f, 0x03, 0x03, 0x02, 0x02, 0x1f,
X/* 0x5_ */	0x01, 0x01, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
X		0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x01, 0x1f, 0x1f,
X/* 0x6_ */	0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x01,
X		0x16, 0x17, 0x18, 0x19, 0x1f, 0x1f, 0x1f, 0x1f,
X/* 0x7_ */	0x00, 0x01, 0x1f, 0x03, 0x02, 0x1f, 0x01, 0x1f,
X		0x0f, 0x10, 0x11, 0x12, 0x1f, 0x1f, 0x1f, 0x1f,
X/* 0x8_ */	0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x1f, 0x1f, 0x1f,
X		0x00, 0x01, 0x02, 0x03, 0x16, 0x17, 0x18, 0x19
X};
X
X/* k_brk -- intercept SHIFT BRK/PAUS interrupt */
Xvoid interrupt
Xk_brk(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags)
Xunsigned int bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags;
X{
X	send_brk();
X	flags |= Cflag;		/* ie. don't queue it */
X	keyboom++;
X}	
X
X/* k_paus -- intercept PAUS key interrupt */
Xvoid interrupt
Xk_paus(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags)
Xunsigned int bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags;
X{
X	if (flowctl && !local)
X		if (xoff)
X			{ xmit(XON); recv = o_recv; xoff = 0; }
X		else
X			{ xmit(XOFF); recv = zip; xoff++; }
X	flags |= Cflag;		/* don't queue it */
X}
X
X/* k_que -- take note of new keystroke in buffer */
Xvoid interrupt
Xk_que()
X{
X	keyhit++;
X/*	outport(0,7);	/* simple but pathetic-sounding keyclick */
X}
X
X/*
X * remap: table of scan codes for remapping TI Pro keypad
X *	- new scan values for scan codes 23 -> 44
X * 0 = scan code unused (ie. it should never occur)
X */
Xstatic uchar remap[22] = {
X	 23,  24,  25,  26,
X	 66,   0,  82,  69,
X	 50,  51,  11,  12,
X	 67,   0,   0,   0,
X	  9,  10,  52,  53,
X	 68,  84
X};
X
X/* k_map -- remap keypad scan codes */
Xvoid interrupt
Xk_map(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags)
Xunsigned int bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags;
X{
X	uchar al, ah;
X
X	al = ax & 0xff;	ah = (ax >> 8) | 0x02;
X	if (al < 45 && al > 22)
X		/* force ALT-key bit & remap key code */
X		ax = (ah << 8) + remap[al-23];
X}
X
X/*
X * o_brk, o_paus, o_que, o_map:
X *	temp storage for old interrupt vectors
X */
Xvoid interrupt (*o_brk)();
Xvoid interrupt (*o_paus)();
Xvoid interrupt (*o_que)();
Xvoid interrupt (*o_map)();
X
Xinit_kbd()
X{
X	if (f_vec) return(0);
X
X	kbflush();
X
X	/* remember old intr vectors */
X	o_brk = getvect(KEYBRK);
X	o_paus = getvect(KEYPAUS);
X	o_que = getvect(KBDQUE);
X	o_map = getvect(KBDMAP);
X	/* install new ones */
X	disable();
X	setvect(KEYBRK, k_brk);
X	setvect(KEYPAUS, k_paus);
X	setvect(KBDQUE, k_que);
X	setvect(KBDMAP, k_map);
X	enable();
X
X	f_vec = 1;	/* vectors installed */
X
X	/* some important key mappings */
X	keymap[K_SETUP >> 8] = 0x80;	/* flag the SETUP key */
X	keymap[(K_SETUP >> 8)+1] = 0x80;	/* ditto on F2 */
X	keymap[K_shBRK >> 8] = 0x40;	/* shiftBrk - send BRK */
X	keymap[K_NUL >> 8] = 0x41;	/* ctrl-2@  - send NUL */
X	keymap[K_BKSP >> 8] = 0x1b;	/* backsp keypadv[] position */
X	keymap[K_BREAK >> 8] = 0x1c;	/* break keypadv[] position */
X	keymap[K_cBRK >> 8] = 0x1e;	/* ctrlBrk keypadv[] position */
X	keyboom = 0;
X}
X
Xreset_kbd()
X{
X	if (!f_vec) return;	/* no vectors to reset, yet */
X
X	kbflush();
X
X	/* restore old intr vectors */
X	disable();
X	setvect(KEYBRK, o_brk);
X	setvect(KEYPAUS, o_paus);
X	setvect(KBDQUE, o_que);
X	setvect(KBDMAP, o_map);
X	enable();
X
X	f_vec = 0;	/* vectors reset */
X}
X
Xnlmod(sw)	/* switch newline mode */
Xuchar sw;
X{
X	/* shift ENTER offset, if needed */
X	keymap[0x21] = keymap[0x2f] = ((sw) ? 0x1d : 0x15);
X}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'gfx.c'" '(5928 characters)'
if test -f 'gfx.c'
then
	echo shar: will not over-write existing file "'gfx.c'"
else
sed 's/^X//' << \SHAR_EOF > 'gfx.c'
X/*
X * gfx.c: simple access for TI Pro graphics
X *
X * copyright (c) University of Toronto, 1988.
X */
X
X#ifdef dbgfx
X#include 
Xstatic int fd=0;
Xstatic char buf[256];
X#endif
X
Xtypedef unsigned char uchar;
X
X#define GMAX_X	720
X#define GMAX_Y	300
X
Xstatic int gx=0, gy=0;
Xstatic uchar gcolour=7;
X
X/* graphics palette attribute latches */
X#define L_BLU	*((char far *)0xdf000010)
X#define L_GRN	*((char far *)0xdf000020)
X#define L_RED	*((char far *)0xdf000030)
X
Xstatic uchar l_blu=0xAA, l_red=0xCC, l_grn=0xF0;
X
X#define L_SYNC	L_BLU=l_blu; L_RED=l_red; L_GRN=l_grn;
X
Xextern uchar interlace;
X
X/*
X * gfx -- simple (dumb?) graphics access
X * expects "^[@"
X *	upper case cmd	-> do move "with pen up"
X *	lower case cmd	-> draw line to new position
X */
Xgfx(s, slen)
Xchar *s;
Xint slen;
X{
X	char *p, c;
X	int i, n, pnc, pn[8];
X
X	/* get parameter numbers */
X	pn[0] = pn[1] = pn[2] = pn[3] = 0;
X	pn[4] = pn[5] = pn[6] = pn[7] = 0;
X	for (i=2, pnc=0; i=0 && n<=9)
X			pn[pnc] = pn[pnc] * 10 + n;
X		else	/* it's ';' or it's the final char */
X			pn[++pnc] = 0;
X	}
X	c = s[i-1];
X#ifdef dbgfx
Xif (fd) write(fd, "@", 1);
Xfor (n=0; n GMAX_X) pn[1] = GMAX_X;
X		if (pn[0] > GMAX_Y) pn[0] = GMAX_Y;
X		if (c & 040) bline(gx, gy, pn[1], pn[0], gcolour);
X		gx = pn[1]; gy = pn[0];
X		if (c == '@') boink(gx, gy, gcolour);
X		break;
X	case 'A': case 'a':	/* "cursor" up */
X		if (!pn[0]) pn[0] = 1;
X		if ((pn[0] = (gy - pn[0])) < 0) pn[0] = 0;
X		if (c & 040) vline(gx, pn[0], gy-pn[0]+1, gcolour);
X		gy = pn[0];
X		break;
X	case 'B': case 'b':	/* down */
X		if (!pn[0]) pn[0] = 1;
X		if ((pn[0] = (gy + pn[0])) > GMAX_Y) pn[0] = GMAX_Y;
X		if (c & 040) vline(gx, gy, pn[0]-gy+1, gcolour);
X		gy = pn[0];
X		break;
X	case 'C': case 'c':	/* right */
X		if (!pn[0]) pn[0] = 1;
X		if ((pn[0] = (gx + pn[0])) > GMAX_X) pn[0] = GMAX_X;
X		if (c & 040) hline(gx, gy, pn[0]-gx+1, gcolour);
X		gx = pn[0];
X		break;
X	case 'D': case 'd':	/* left */
X		if (!pn[0]) pn[0] = 1;
X		if ((pn[0] = (gx - pn[0])) < 0) pn[0] = 0;
X		if (c & 040) hline(pn[0], gy, gx-pn[0]+1, gcolour);
X		gx = pn[0];
X		break;
X	case 'L': case 'l':	/* access palette latches */
X		if (c & 040) {	/* relative palette changes */
X			l_blu += pn[0];	l_red += pn[1];	l_grn += pn[2];
X			l_blu %= 0xFF;	l_red %= 0xFF;	l_grn %= 0xFF;
X		}
X		else {		/* absolute palette changes */
X			l_blu = pn[0] % 0xFF;
X			l_red = pn[1] % 0xFF;
X			l_grn = pn[2] % 0xFF;
X		}
X		L_SYNC
X		break;
X	case 'J':	/* erase */
X		gfx_erase();
X		break;
X	case 'm':	/* change current colour */
X		gcolour = pn[pnc-1] % 8;
X		break;
X	default:
X		break;
X	}
X}
X
X#define GBa(i)	*((int far *)0xc0000000+i)
X#define GBb(i)	*((int far *)0xc8000000+i)
X#define GBc(i)	*((int far *)0xd0000000+i)
X
X#define GBOFS(a,b)	(((b)*46)+((a)/16))
X#define GMASK(a)	(0x8000 >> ((a)%16))
X
Xinit_gfx()
X{
X#ifdef dbgfx
Xif (fd > 0) close(fd);
Xfd = open("gfx.log", O_WRONLY|O_CREAT|O_APPEND, 0664);
Xif (fd < 0) fd = 0;
X#endif
X	L_BLU = L_RED = L_GRN = 0;
X
X	if (interlace) {
X		gcolour = 7;
X		L_SYNC
X	}
X}
X
Xstatic unsigned int ofs, msk;
X#define BOINK(o,m,n)	\
X	GBa(o) = ((n & 1) ? (GBa(o) | m) : (GBb(o) & ~m)); \
X	GBb(o) = ((n & 4) ? (GBb(o) | m) : (GBb(o) & ~m)); \
X	GBc(o) = ((n & 2) ? (GBc(o) | m) : (GBb(o) & ~m));
X
Xstatic
Xboink(x,y,c)
Xint x, y;
Xuchar c;
X{
X	msk = GMASK(x);
X	ofs = GBOFS(x,y);
X	BOINK(ofs, msk, c)
X}
X
X/*
X * draw line from (x0,y0) to (x1,y1) with colour clr.
X *	using Bresenham's Line Algorithm (BYTE, Mar/88, p.252)
X */
Xstatic
Xbline(x0,y0,x1,y1,clr)
Xint x0,y0,x1,y1;
Xuchar clr;
X{
X	int	x, y,		/* current x,y coords */
X		d, i,		/* decision variable / utility */
X		a, b,		/* line displacements in x, y */
X		dx_d, dy_d,	/* diagonal x/y steps for next point */
X		dx_nd, dy_nd,	/* nondiag. x/y steps for next point */
X		d_inc, nd_inc;	/* "d" inc for diag/nondiag steps */
X
X	x = x0; y = y0;		/* start point */
X
X	a = x1 - x0;	dx_d = 1;
X	b = y1 - y0;	dy_d = 1;
X
X	/* if vert or horiz lines, use custom routines instead */
X	if (b == 0) { hline(x, y, a, clr);	return; }
X	if (a == 0) { vline(x, y, b, clr);	return; }
X
X	if (a < 0) { a = -a; dx_d = -1; }
X	if (b < 0) { b = -b; dy_d = -1; }
X
X		/* identify end-point octant */
X	if (a < b) {
X		i = a; a = b; b = i;	/* swap a and b */
X		dx_nd = 0;	/* larger y-diff means x won't change */
X		dy_nd = dy_d;	/* on nondiag steps, but y will */
X	}
X	else {
X		dx_nd = dx_d;	/* x changes every step; y changes */
X		dy_nd = 0;	/* only on the diag steps */
X	}
X
X	d = b + b - a;
X	nd_inc = b + b;
X	d_inc = b + b - a - a;
X
X	for (i=0; i <= a; i++) {	/* draw a+1 points */
X	/*	boink(x,y,clr);		*/
X		msk = GMASK(x);
X		ofs = GBOFS(x,y);
X		BOINK(ofs, msk, clr)
X
X		/* if midpoint is above the line ... */
X		if (d < 0)	/* then step nondiagonally */
X			{ x += dx_nd;	y += dy_nd;	d += nd_inc; }
X		else		/* else step diagonally */
X			{ x += dx_d;	y += dy_d;	d += d_inc; }
X	}
X}
X
X/*
X * hline -- only does horizontal lines (union regulations :-)
X *	use solid(ie. multi bit) masks and increment the offset
X */
Xstatic
Xhline(x,y,n,c)
Xint x,y,n;
Xuchar c;
X{
X	if (n < 0) {
X		n = -n; x -= n;
X		if (x < 0)
X			{ n += x; x = 0; }
X	}
X	msk = 0xffff >> (x%16);	/* make mask go to end of 16bit word */
X	for(ofs=GBOFS(x,y); ofs < GBOFS(x+n, y); ofs++) {
X		BOINK(ofs, msk, c)
X		msk = 0xffff;	/* ie. solid while between end-points */
X	}
X	msk &= ~(0xffff >> ((x+n)%16));	/* remainder word mask */
X	BOINK(ofs, msk, c)
X}
X
X/*
X * vline -- vertical lines only
X *	get bit mask once then move it up or down
X *	by changing only the offset +/- 46.
X */
Xstatic
Xvline(x,y,n,c)
Xint x,y,n;
Xuchar c;
X{
X	if (n < 0) {
X		n = -n; y -= n;
X		if (y < 0)
X			{ n += y; y = 0; }
X	}
X	msk = GMASK(x);
X	ofs = GBOFS(x,y);
X	for (; n; n--, ofs+=46) {
X		BOINK(ofs, msk, c)
X	}
X}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'tipro.h'" '(1788 characters)'
if test -f 'tipro.h'
then
	echo shar: will not over-write existing file "'tipro.h'"
else
sed 's/^X//' << \SHAR_EOF > 'tipro.h'
X/*
X * tipro.h: TI Pro-specific definitions
X *
X * copyright (c) University of Toronto, 1988.
X */
X#define CRT_INT	0x49	/* crt dsr interface */
X#define KBD_INT	0x4a	/* keyboard interface */
X
X#define TICKER	0x58	/* system timing, 25 ms. */
X#define TIMER	0x5a	/* system timing, 100 ms. */
X#define KBDMAP	0x5b	/* kbd mapping vector */
X#define KEYPAUS	0x5c	/* kbd program pause key vector */
X#define KEYBRK	0x5d	/* kbd program break key vector */
X#define KEYPRNT	0x5e	/* kbd print screen vector */
X#define KBDQUE	0x5f	/* kbd queueing vector */
X
X#define Zflag	0x40
X#define Cflag	0x01
X
X#define NOPARITY	0
X#define O_PARITY	1
X#define E_PARITY	3
X
X
X	/* function key codes */
X#define K_UP	0x4800
X#define K_DOWN	0x5000
X#define K_RIGHT	0x4d00
X#define K_LEFT	0x4b00
X
X#define K_INS	0x5200
X#define K_DEL	0x5300
X#define K_sDEL	0x3800	/* shift DELETE */
X#define K_HOME	0x4700
X
X#define K_F1	0x3b00
X#define K_F2	0x3c00
X#define K_F3	0x3d00
X#define K_F4	0x3e00
X
X#define K_F5	0x3f00
X#define K_F6	0x4000
X#define K_F7	0x4100
X#define K_F8	0x4200
X
X#define K_F9	0x4300
X#define K_F10	0x4400
X#define K_F11	0x4500
X#define K_F12	0x4600
X
X#define K_sF3	0x5600
X#define K_cF3	0x6000
X
X#define K_NUL	0x0300	/* Fnul, ctrl-2@ */
X
X#define K_SETUP	K_F1	/* and K_F2, when not in setup mode */
X#define K_BREAK	K_F3
X#define K_BKSP	K_F4
X
X#define K_shBRK	K_sF3
X#define K_cBRK	K_cF3
X
X
X#define NPORTS	4
X
X/* speeds (see  on a unix system) */
X/* (corresponds to table position in ports.c) */
X#define B0	0
X#define B50	1
X#define B75	2
X#define B110	3
X#define B134	4
X#define B150	5
X#define B200	6
X#define B300	7
X#define B600	8
X#define B1200	9
X#define B1800	10
X#define B2000	11
X#define B2400	12
X#define B3600	13
X#define B4800	14
X#define B7200	15
X#define B9600	16
X#define EXTA	17	/* 19200 */
X#define EXTB	18	/* 38400 (unsupported) */
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0