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