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 (2 of 3)
Message-ID: <8806071609.AA12844@bloor.csri.toronto.edu>
Organization: University of Toronto, CSRI
Date: Tue, 7 Jun 88 10:49:58 EDT
#! /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:
# common.h
# cterm.ini
# defs.c
# esc.c
# main.c
# misc.c
# printer.c
# setup.c
# term.c
# text.c
# This archive created: Tue Jun 7 11:27:25 1988
# By: pkern ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'common.h'" '(1599 characters)'
if test -f 'common.h'
then
echo shar: will not over-write existing file "'common.h'"
else
sed 's/^X//' << \SHAR_EOF > 'common.h'
X/*
X * common.h: main common definitions
X *
X * copyright (c) University of Toronto, 1988.
X */
X /* ascii control char names */
X#define NUL 000 /* ^@ */
X#define SOH 001 /* ^A */
X#define STX 002 /* ^B */
X#define ETX 003 /* ^C */
X#define EOT 004 /* ^D */
X#define ENQ 005 /* ^E */
X#define ACK 006 /* ^F */
X#define BEL 007 /* ^G */
X#define BS 010 /* ^H */
X#define HT 011 /* ^I */
X#define LF 012 /* ^J */
X#define VT 013 /* ^K */
X#define FF 014 /* ^L */
X#define CR 015 /* ^M */
X#define SO 016 /* ^N */
X#define SI 017 /* ^O */
X#define DLE 020 /* ^P */
X#define DC1 021 /* ^Q */
X#define DC2 022 /* ^R */
X#define DC3 023 /* ^S */
X#define DC4 024 /* ^T */
X#define NAK 025 /* ^U */
X#define SYN 026 /* ^V */
X#define ETB 027 /* ^W */
X#define CAN 030 /* ^X */
X#define EM 031 /* ^Y */
X#define SUB 032 /* ^Z */
X#define ESC 033 /* ^[ */
X#define FS 034 /* ^\ */
X#define GS 035 /* ^] */
X#define RS 036 /* ^^ */
X#define US 037 /* ^_ */
X#define SP 040 /* ' ' */
X#define DEL 0177 /* ^? */
X
X#define XON DC1 /* ^Q */
X#define XOFF DC3 /* ^S */
X
X#ifndef FINIT
X#define FINIT "cterm.ini" /* setups init file */
X#endif
X
X#ifndef NARGS
X#define NARGS 32 /* max args allowed */
X#endif
X
X /* attribute bits */
X#define AT_MASK 0x0f
X#define AT_REV 0x01
X#define AT_UL 0x02
X#define AT_BLINK 0x04
X#define AT_BOLD 0x08
X
X#define UP 0
X#define DOWN 1
X#define RIGHT 2
X#define LEFT 3
X
X#define VT52 0
X#define ANSI 1
X#define OFS52 0
X#define ANSOFS 0x40
X#define KEYNORM 0
X#define KEYAPPL 0x20
X
X#define BUFMAX 512
X
X
Xtypedef unsigned char uchar;
X
Xextern int (*xmit)(), (*recv)();
Xextern int (*o_xmit)(), (*o_recv)();
Xextern int (*burp)(), (*esc)();
X
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'cterm.ini'" '(265 characters)'
if test -f 'cterm.ini'
then
echo shar: will not over-write existing file "'cterm.ini'"
else
sed 's/^X//' << \SHAR_EOF > 'cterm.ini'
X# -- cterm.ini setups --
X# setup A: tabs
XA: 1 9 17 25 33 41 49 57 65 73 89 97 105 113 121 129
X#
X# setup B: main terminal options
XB: 0 1 0 0 0 0 1 1 0 1 0 1 0 0 1 0 2 9600 9600
X#
X# setup C: printer & misc. options
XC: 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 4 1200
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'defs.c'" '(3313 characters)'
if test -f 'defs.c'
then
echo shar: will not over-write existing file "'defs.c'"
else
sed 's/^X//' << \SHAR_EOF > 'defs.c'
X/*
X * defs.c: init file(s) read or write handling.
X *
X * copyright (c) University of Toronto, 1988.
X */
X#include
X#include
X#include
X#include "common.h"
X
Xextern char tabs[];
X
Xextern uchar *sB[16], *sC[16];
Xextern int *sBi[3], *sCi[2];
X
Xextern int nbaud, pbaud, t_spd, pr_spd;
X
Xstatic char *svfl = FINIT; /* saved setups filename */
Xstatic char fnbuf[80];
X
X/*
X * getdef -- retrieve setup configuration from a file.
X * - reads from fnam instead of FINIT, if fnam not null.
X */
Xgetdefs(fnam)
Xchar *fnam;
X{
X FILE *fp;
X char *p, *bp, buf[128];
X int n=0, na=0, nb=0, nc=0, nt=0;
X
X
X nbaud = prtspd(t_spd);
X pbaud = prtspd(pr_spd);
X
X if (fnam && *fnam) /* ... then use another setups file */
X { strcpy(fnbuf, fnam); svfl = fnbuf; }
X if ((fp = fopen(svfl, "r")) == NULL)
X return(-1);
X
X /* read the saved setups and initialize */
X while(bp = fgets(buf, 127, fp)) {
X p = bp; bp += strlen(bp);
X switch(buf[0]) {
X case 'A': /* set some tabs */
X nb = nc = 0;
X do {
X while (p 15)
X *(sBi[nb-16]) = atoi(p);
X else
X *(sB[nb]) = atoi(p) % 2;
X nb++;
X while (p < bp && isdigit(*p)) p++;
X }
X break;
X case 'C': /* setup C */
X na = nb = 0;
X /*
X * get the 4 block of 4 1/0 flags and
X * the printer port number and speed
X */
X while (p < bp && nc < 18) {
X if (!isdigit(*p)) {
X if (*p == '#') break;
X p++; continue;
X }
X if (nc > 15)
X *(sCi[nc-16]) = atoi(p);
X else
X *(sC[nc]) = atoi(p) % 2;
X nc++;
X while (p < bp && isdigit(*p)) p++;
X }
X break;
X default: /* notes, junk, ... etc. */
X break;
X }
X }
X
X fclose(fp);
X
X /* set new tabs */
X if (nt) for(na=0; na<132; na++)
X tabs[na] = (tabs[na] == 't') ? 'T' : SP;
X
X /* adjustments */
X *(sBi[0]) -= 1; *(sCi[0]) -= 1; /* n_port--; p_port--; */
X
X#ifdef debug
Xcputs("B: ");
Xfor(n=0; n<16; n++)
X cprintf(" %d%s", *sB[n], ((n+1)%4)?"":" ");
Xcprintf(" %d %d %d\r\n", *sBi[0], *sBi[1], *sBi[2]);
Xcputs("C: ");
Xfor(n=0; n<16; n++)
X cprintf(" %d%s", *sC[n], ((n+1)%4)?"":" ");
Xcprintf(" %d %d\r\n", *sCi[0], *sCi[1]);
X
Xn = getch();
X#endif
X}
X
X/*
X * putdefs -- write current setup configuration to file svfl
X */
Xputdefs()
X{
X FILE *fp;
X int i, n;
X
X if ((fp = fopen(svfl, "a")) == NULL)
X return(-1);
X
X /* save tabs */
X fprintf(fp, "# -- terminal setups --\n# setup A: tabs\nA:");
X for (i=n=0; i<132; i++) {
X if (tabs[i] == 'T') {
X fprintf(fp, " %d", i+1);
X n += 2 + (i > 8) + (i > 98);
X }
X if (n > 72)
X fprintf(fp, "\nA:");
X }
X
X fprintf(fp, "\n#\n# setup B: main terminal options\nB:");
X for (i=0; i<16; i++)
X fprintf(fp, " %d%s", *sB[i], ((i+1)%4)?"":" ");
X /* n_port, t_spd, r_spd */
X fprintf(fp, " %d %d %d\n", *sBi[0]+1, *sBi[1], *sBi[2]);
X
X fprintf(fp, "#\n# setup C: printer & misc. options\nC:");
X for (i=0; i<16; i++)
X fprintf(fp, " %d%s", *sC[i], ((i+1)%4)?"":" ");
X /* p_port, pr_spd */
X fprintf(fp, " %d %d\n", *sCi[0]+1, *sCi[1]);
X fclose(fp);
X}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'esc.c'" '(11542 characters)'
if test -f 'esc.c'
then
echo shar: will not over-write existing file "'esc.c'"
else
sed 's/^X//' << \SHAR_EOF > 'esc.c'
X/*
X * esc.c:
X * Escape sequence handling routines. The "guts" of vt100-ness.
X *
X * copyright (c) University of Toronto, 1988.
X */
X/*
X * layout based in part on connect.inc from Qkermit.
X */
X#include "common.h"
X
X /* some xt100 modes (and their default) */
Xuchar m_ansi = ANSI; /* ANSI/VT52 mode (ANSI) */
Xuchar m_newline = 0; /* linefeed/newline (linefeed) */
Xuchar m_repeat = 1; /* auto repeat (on) */
Xuchar m_wrap = 1; /* wraparound (on) */
Xuchar m_smooth = 0; /* scrolling mode (jump) */
Xuchar m_print = 0; /* printer controller mode (exit) */
Xuchar m_autopr = 0; /* auto print mode (exit) */
Xuchar m_prxtent = 1; /* print extent (full page) */
Xuchar m_prterm = 0; /* print termintation (none) */
Xuchar m_origin = 0; /* origin mode (absolute) */
Xuchar m_reverse = 0; /* screen mode (normal) */
Xuchar m_insert = 0; /* insertion/replacement (replacement) */
Xuchar m_columns = 80; /* column mode (80 cols) */
Xuchar m_crskey = KEYNORM; /* cursor key mode (cursor) */
Xuchar m_keypad = KEYNORM; /* keypad mode (numeric) */
X
Xuchar srgn_top=1, srgn_bot=24; /* scroll region markers */
X
Xstatic int attrb, o_attr, o_x, o_y=0; /* storage */
Xstatic char *o_cset; /* more storage */
X
Xextern uchar cx, cy;
Xextern char tabs[], led[];
Xextern char *cset, *g0, *g1;
Xextern char *ukascii, *usascii;
Xextern int nbaud;
Xextern uchar parity, bpc, m_prty;
Xextern int avofs;
Xextern char *vt100ids[];
Xextern uchar vtidnum;
X
X#define EBMAX 256
Xchar ebuf[EBMAX]; /* escape sequence buffer: place to collect */
X /* chars for potential future post-mortems */
X
X/*
X * EGETC():
X * - get next byte from input buffer.
X * - return(0) if it's CAN or return(1) if it's ESC.
X * - execute if it's a control char.
X */
X#define EGETC(a) \
X while((a=recv()) 1)
X curs_xy(cx, --cy);
X break;
X case '7': /* save cursor & attributes */
X o_x = cx, o_y = cy, o_attr = attrb; o_cset = cset;
X break;
X case '8': /* restore cursor & attributes */
X if (!o_y) break; /* nothing saved yet */
X curs_xy(cx=o_x, cy=o_y);
X attribs(o_attr);
X cset = o_cset;
X break;
X case 'H': /* set tab stop */
X tabs[cx-1] = 'T';
X break;
X case '=': m_keypad = KEYAPPL; break;
X case '>': m_keypad = KEYNORM; break;
X case '@': /* NB: this ain't ANSI ! */
X /* an extension to access graphics screens for */
X /* those too lazy to emulate Tektronix (ie. me) */
X do {
X EGETC(c)
X ebuf[ebi++] = c;
X } while ((c >= '0' && c <= '9') || c == ';');
X ebuf[ebi] = NUL;
X gfx(ebuf, ebi);
X break;
X case '[': /* CSI (command sequence introducer) */
X qmark = 0;
X EGETC(c)
X if (c == '?') {
X qmark = 1;
X EGETC(c)
X }
X while ((c >= '0' && c <= '9') || c == ';') {
X ebuf[ebi++] = c;
X EGETC(c)
X }
X ebuf[ebi++] = c;
X /* get parameter numbers */
X pn[0] = pn[1] = pn[2] = pn[3] = pn[4] = 0;
X pn[5] = pn[6] = pn[7] = pn[8] = pn[9] = pn[10] = 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 switch (c) {
X case 'A': /* cursor up */
X if (!pn[0]) pn[0] = 1;
X while (cy>1 && pn[0]-- && cy != srgn_top) cy--;
X curs_xy(cx, cy);
X break;
X case 'B': /* cursor down */
X if (!pn[0]) pn[0] = 1;
X while (cy<24 && pn[0]-- && cy != srgn_bot) cy++;
X curs_xy(cx, cy);
X break;
X case 'C': /* cursor right */
X if (!pn[0]) pn[0] = 1;
X if ((cx += pn[0]) > m_columns) cx = m_columns;
X curs_xy(cx, cy);
X break;
X case 'D': /* cursor left */
X if (!pn[0]) pn[0] = 1;
X cx = (cx > pn[0]) ? (cx - pn[0]) : 1;
X curs_xy(cx, cy);
X break;
X case 'H': case 'f': /* direct cursor address */
X if (!(cx = pn[1])) cx = 1;
X if (!(cy = pn[0])) cy = 1;
X if (m_origin) {
X cy += (srgn_top-1);
X if (cy > srgn_bot) cy = srgn_bot;
X }
X if (cx > m_columns) cx = m_columns;
X if (cy > 24) cy = 24;
X curs_xy(cx, cy);
X break;
X case 'K': /* line erase */
X switch (pn[0]) {
X case 0: eol_erase(cx, cy); break;
X case 1: bol_erase(cx, cy); break;
X case 2: line_erase(cx, cy); break;
X }
X break;
X case 'J': /* screen erase */
X switch (pn[0]) {
X case 0: eos_erase(cx, cy); break;
X case 1: bos_erase(cx, cy); break;
X case 2: all_erase(cx, cy); break;
X }
X break;
X case 'L': /* insert line */
X if (cy < srgn_top || cy > srgn_bot) break;
X if (!pn[0]) pn[0] = 1;
X cx = 1;
X line_ins(pn[0], cx, cy, srgn_bot);
X break;
X case 'M': /* delete line */
X if (cy < srgn_top || cy > srgn_bot) break;
X if (!pn[0]) pn[0] = 1;
X cx = 1;
X line_del(pn[0], cx, cy, srgn_bot);
X break;
X case '@': /* insert char */
X if (!pn[0]) pn[0] = 1;
X char_ins(pn[0], cx, cy); break;
X case 'P': /* delete char */
X if (!pn[0]) pn[0] = 1;
X char_del(pn[0], cx, cy); break;
X case 'm': /* attributes */
X for (i=0; i1 && cy != srgn_top) curs_xy(cx, --cy); break;
X case 'B': if (cy<24 && cy != srgn_bot) curs_xy(cx, ++cy); break;
X case 'C': if (cx < 80) curs_xy(++cx, cy); break;
X case 'D': if (cx > 1) curs_xy(--cx, cy); break;
X case 'F': /* UK ASCII */
X cset = ukascii;
X break;
X case 'G': /* US ASCII */
X cset = usascii;
X break;
X case 'H': curs_xy(cx=1, cy=1); break;
X case 'I': /* reverse line feed */
X if (cy == srgn_top)
X scrl_down(1, srgn_top, srgn_bot, cx, cy);
X else if (cy > 1)
X curs_xy(cx, --cy);
X break;
X case 'J': eos_erase(cx, cy); break;
X case 'K': eol_erase(cx, cy); break;
X case 'Y': /* cursor addressing */
X EGETC(c)
X ebuf[ebi++] = c;
X EGETC(c)
X ebuf[ebi++] = c;
X /* ignore address if it's out of bounds */
X if (ebuf[2] > '7' || ebuf[3] > 'o') break;
X cy = ebuf[2] - SP;
X cx = ebuf[3] - SP;
X curs_xy(++cx, ++cy);
X break;
X case 'Z': /* vt52 identify */
X p = "\033/Z";
X while (*p) xmit(*p++);
X break;
X case '=': m_keypad = KEYAPPL; break;
X case '>': m_keypad = KEYNORM; break;
X case '<':
X m_ansi = ANSI; avofs = ANSOFS;
X cset = usascii; esc = ansi;
X break;
X /* printer commands */
X case 'W': /* enter printer mode */
X case 'X': /* exit printer mode */
X case '^': /* auto print mode on */
X case '_': /* auto print mode off */
X case 'V': /* print line */
X case ']': /* print page */
X break;
X }
X ebuf[ebi] = '\0';
X return(0);
X}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'main.c'" '(2812 characters)'
if test -f 'main.c'
then
echo shar: will not over-write existing file "'main.c'"
else
sed 's/^X//' << \SHAR_EOF > 'main.c'
X/*
X * main.c:
X * main() and some misc. routines
X *
X * copyright (c) University of Toronto, 1988.
X */
X#include
X#include
X#include
X#include
X#include
X
X#include "common.h"
X#include "tipro.h"
X
Xstatic uchar iflag=0;
X
X/*
X * initialize the world and run the terminal ...
X * ... then reset the world and exit.
X */
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X char *s;
X int n, boom();
X
X while (--argc) {
X argv++;
X if (argv[0][0] == '-')
X switch (argv[0][1]) {
X case 'i':
X if (getdefs(argv[1]) < 0) {
X perror(argv[1]);
X exit(1);
X }
X argv++;
X iflag++;
X break;
X default:
X break;
X }
X }
X
X if (!iflag)
X getdefs(FINIT);
X ctrlbrk(boom); /* for safety sake */
X init_kbd();
X init_scr();
X curs_xy(1, 1); eos_erase(1, 1);
X init_prt();
X term();
X boom(1);
X}
X
Xboom(sw)
Xint sw;
X{
X reset_prt();
X reset_kbd();
X reset_scr();
X if (sw) cputs("**ZAP**");
X return(0);
X}
X
X
X/*
X * some misc. routines
X */
X
X
X/*
X * counter(), cntdn, timer_int():
X * attempt to simulate time-outs (eg. signals on UNIX)
X */
Xunsigned int cntdn=0;
X
Xvoid interrupt (*o_timer)();
X
Xvoid interrupt
Xtimer_int()
X{
X if (cntdn) cntdn--;
X}
X
X/*
X * install or reset timer_int ISR
X * allows cntdn to be used as a count-down clock.
X * (see tipro.h for difference between TIMER and TICKER)
X * (see kermit.c or xmodem.c for counter/cntdn usage examples)
X */
Xcounter(sw)
Xint sw;
X{
X if (sw) { /* install timer_int ISR */
X o_timer = getvect(TIMER);
X disable();
X setvect(TIMER, timer_int);
X enable();
X }
X else { /* restore old ISR */
X disable();
X setvect(TIMER, o_timer);
X enable();
X }
X}
X
X
X/* run cmd in dos */
X/*
X * please excuse the tortured code but both system() and
X * spawnl() refused to exit properly (version 1.0 Turbo C)
X */
Xdocmd(cmd)
Xchar *cmd;
X{
X int i;
X union REGS r;
X char *av[] = { "", "", (char *)0 };
X char buf[128], cpath[128];
X
X strcpy(cpath, getenv("COMSPEC"));
X for(i=strlen(cpath)-1; i>0; i--)
X if (cpath[i]=='\\' || cpath[i]=='/' || cpath[i]==':')
X { i++; break; }
X strcpy(buf, &cpath[i]);
X av[0] = buf; av[1] = buf + strlen(buf);
X r.x.ax = 0x3700; intdos(&r, &r); /* get switchar */
X sprintf(av[1], "%cC %s", r.h.dl, cmd);
X
X /* phew! ok, now do it */
X if (spawnv(P_WAIT, cpath, av) < 0)
X perror(cmd);
X}
X
X/* doxpnd: expand name if it contains glob chars */
X/* (lazy version ... uses Turbo C's findfirst/findnext routines) */
Xstatic char *ap, abuf[NARGS*16];
X
Xdoxpnd(ac, av)
Xint ac;
Xchar *av[];
X{
X struct ffblk ff;
X
X if (ac < 2) ap = abuf;
X#ifdef debug
Xcprintf("%d: %s\r\n", ac, av[ac]);
X#endif
X if (findfirst(av[ac], &ff, ~FA_LABEL) < 0) return(ac);
X do {
X strcpy(ap, ff.ff_name);
X av[ac] = ap;
X ap += strlen(ap); *ap++ = NUL;
X#ifdef debug
Xcprintf("%d: %s\r\n", ac, av[ac]);
X#endif
X } while (!findnext(&ff) && ac++ < NARGS);
X return(ac); /* return new arg count */
X}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'misc.c'" '(4202 characters)'
if test -f 'misc.c'
then
echo shar: will not over-write existing file "'misc.c'"
else
sed 's/^X//' << \SHAR_EOF > 'misc.c'
X/*
X * misc.c:
X * misc. strings including keypadv[] and vt100ids[]
X *
X * copyright (c) University of Toronto, 1988.
X */
X#include "common.h"
X
Xchar ansback[33]; /* answerback message */
X
Xchar *keypadv[0x80] = { /* cursor key & keypad strings */
X/* vt52 */
X /* normal mode */
X /* cursor keys */
X "\033A", "\033B", "\033C", "\033D", "", "", "", "",
X /* keypad */
X "0", "1", "2", "3", "4", "5", "6", "7",
X "8", "9", "-", ",", ".", "\r", "\033P", "\033Q",
X "\033R", "\033S", "\200", "\b", "\003", "\r\n", ansback, "",
X
X /* application mode */
X /* cursor keys */
X "\033A", "\033B", "\033C", "\033D", "", "", "", "",
X /* keypad */
X "\033?p", "\033?q", "\033?r", "\033?s",
X "\033?t", "\033?u", "\033?v", "\033?w",
X "\033?x", "\033?y", "\033?m", "\033?l",
X "\033?n", "\033?M", "\033P", "\033Q",
X "\033R", "\033S", "\200", "\b",
X "\003", "\033?M", ansback, "",
X
X/* ansi */
X /* normal mode */
X /* cursor keys */
X "\033[A", "\033[B", "\033[C", "\033[D", "", "", "", "",
X /* keypad */
X "0", "1", "2", "3", "4", "5", "6", "7",
X "8", "9", "-", ",", ".", "\r", "\033OP", "\033OQ",
X "\033OR", "\033OS", "\200", "\b", "\003", "\r\n", ansback, "",
X
X /* application mode */
X /* cursor keys */
X "\033OA", "\033OB", "\033OC", "\033OD", "", "", "", "",
X /* keypad */
X "\033Op", "\033Oq", "\033Or", "\033Os",
X "\033Ot", "\033Ou", "\033Ov", "\033Ow",
X "\033Ox", "\033Oy", "\033Om", "\033Ol",
X "\033On", "\033OM", "\033OP", "\033OQ",
X "\033OR", "\033OS", "\200", "\b",
X "\003", "\033OM", ansback, ""
X};
X
X
Xuchar vtidnum = 9; /* vt100ids index (see below) */
X
Xchar *vt100ids[] = { /* device report terminal ID strings */
X /*
X * strings lifted from vttest's main.c
X * STP = processor option
X * PP = printer port
X * AVO = advanced video option
X * GPO = graphics processor option
X */
X "\033[?1;0c", /* No options (vanilla VT100) */
X/* "\033[?1;1c", /* VT100 with STP */
X "\033[?1;2c", /* VT100 with AVO (could be a VT102) */
X/* "\033[?1;3c", /* VT100 with STP and AVO */
X/* "\033[?1;4c", /* VT100 with GPO */
X/* "\033[?1;5c", /* VT100 with STP and GPO */
X/* "\033[?1;6c", /* VT100 with AVO and GPO */
X/* "\033[?1;7c", /* VT100 with STP, AVO and GPO */
X "\033[?1;11c", /* VT100 with PP and AVO */
X "\033[?1;15c", /* VT100 with PP, GPO and AVO */
X/* "\033[?4;2c", /* VT132 with AVO */
X/* "\033[?4;3c", /* VT132 with AVO and STP */
X/* "\033[?4;6c", /* VT132 with GPO and AVO */
X/* "\033[?4;7c", /* VT132 with GPO, AVO, and STP */
X/* "\033[?4;11c", /* VT132 with PP and AVO */
X/* "\033[?4;15c", /* VT132 with PP, GPO and AVO */
X/* "\033[?7c", /* VT131 */
X/* "\033[?12;5c", /* VT125 */
X/* "\033[?12;7c", /* VT125 with AVO */
X/* "\033[?5;0c", /* VK100 (GIGI) */
X/* "\033[?5c", /* VK100 (GIGI) */
X ""
X};
X
Xchar led[4] = { SP, SP, SP, SP}; /* simulated LEDs */
X
Xchar *cset, *g0, *g1; /* character set pointers */
X /* simulated US ASCII char set */
Xchar *usascii = "\
X\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\
X\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\
X !\"#$%&'()*+,-./0123456789:;<=>\
X?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^\
X_`abcdefghijklmnopqrstuvwxyz{|}~\177";
X
X /* simulated UK ASCII set */
Xchar *ukascii = "\
X\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\
X\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\
X !\"#$%&'()*+,-./0123456789:;<=>\
X?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^\
X\040\004\261....\370\361..\331\277\332\300\305\304\
X\304\304\304_\303\264\301\302\263\363\362\343\330\234\371\177";
X
X/* tab string */
Xchar tabs[133] = {
X 'T',SP,SP,SP,SP,SP,SP,SP,'T',SP,SP,SP,SP,SP,SP,SP,
X 'T',SP,SP,SP,SP,SP,SP,SP,'T',SP,SP,SP,SP,SP,SP,SP,
X 'T',SP,SP,SP,SP,SP,SP,SP,'T',SP,SP,SP,SP,SP,SP,SP,
X 'T',SP,SP,SP,SP,SP,SP,SP,'T',SP,SP,SP,SP,SP,SP,SP,
X 'T',SP,SP,SP,SP,SP,SP,SP,'T',SP,SP,SP,SP,SP,SP,SP,
X 'T',SP,SP,SP,SP,SP,SP,SP,'T',SP,SP,SP,SP,SP,SP,SP,
X 'T',SP,SP,SP,SP,SP,SP,SP,'T',SP,SP,SP,SP,SP,SP,SP,
X 'T',SP,SP,SP,SP,SP,SP,SP,'T',SP,SP,SP,SP,SP,SP,SP,
X 'T',SP,SP,SP,NUL};
X
Xextern uchar m_columns;
X
X/*
X * tab -- return next tab-stop column position (x == current column).
X */
Xtab(x)
Xint x;
X{
X register int i;
X
X i = x-1;
X if (tabs[i] != SP) i++;
X while (i+1 < m_columns && tabs[i] == SP) ++i;
X return(i+1);
X}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'printer.c'" '(414 characters)'
if test -f 'printer.c'
then
echo shar: will not over-write existing file "'printer.c'"
else
sed 's/^X//' << \SHAR_EOF > 'printer.c'
X/*
X * printer.c:
X * printer related (dummy) functions.
X *
X * copyright (c) University of Toronto, 1988.
X */
X#include "common.h"
X
X/* send current page to printer */
Xpr_page() { }
X
X/* send curent line to printer */
Xpr_line() { }
X
X/*
X * send printer status to host
X * possible responses:
X * 1 = printer ready
X * 0 = printer not ready
X * -1 = no printer
X */
Xpr_stat() { return(-1); }
X
Xpr_init() { }
X
Xpr_reset() { }
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'setup.c'" '(14100 characters)'
if test -f 'setup.c'
then
echo shar: will not over-write existing file "'setup.c'"
else
sed 's/^X//' << \SHAR_EOF > 'setup.c'
X/*
X * setup.c:
X * setups(): simulate XT100+ setup screens.
X * (beware! code in setups() is not pretty)
X * genstat(): put general status bar on line 25.
X *
X * copyright (c) University of Toronto, 1988.
X */
X#include "common.h"
X#include "tipro.h"
X
X#define TOGGLE(a) a=((a)+1)%2 /* toggle between 0 and 1 */
X#define SWAP(a,b,x) x=a;a=b;b=x;
X
Xextern int keyhit;
Xextern char tabs[], ansback[];
Xextern uchar m_ansi, m_wrap, m_newline;
Xextern uchar m_smooth, m_repeat, m_reverse;
X
Xextern char *bauds[];
X
X/* main port parameters */
Xint n_port=1, nbaud=B9600, t_spd=9600, r_spd=9600;
Xuchar bpc=1, parity=0, stopbits=0, m_prty=0;
X
X/* printer port parameters */
Xint p_port=3, pbaud=B1200, pr_spd=1200;
Xuchar p_bpc=1, p_prty=0, p_sbits=0, pm_pty=0;
X
Xuchar cursor=1; /* block or underline cursor (block) */
Xuchar echo=0; /* local echo (none) */
Xuchar transparent=0; /* control chars (interpret) */
Xuchar local=0; /* connect (on line) */
Xuchar flowctl=1, xoff=0; /* auto xon/xoff, ready to receive */
Xuchar interlace=0; /* graphics display */
Xuchar ignrflow=0; /* don't ignore remote xon/xoff */
Xuchar rxoff=0; /* no remote XOFF yet */
Xuchar devrep=1; /* device report */
X
Xextern char *ukascii;
Xuchar pt, zilch=0;
X
Xuchar *sB[16] = { /* setup B related variables */
X &m_smooth, /* scroll mode */
X &m_repeat, /* autorepeat */
X &m_reverse, /* screen mode */
X &cursor, /* cursor type */
X &zilch, /* margin bell (NA) (off) */
X &zilch, /* keyclick (NA) (off) */
X &m_ansi, /* ansi/vt52 */
X &flowctl, /* auto xon/xoff */
X &zilch, /* #/pound sign (NA) (#) */
X &m_wrap, /* wraparound */
X &m_newline, /* newline */
X &interlace, /* interlace */
X &parity, /* parity sense */
X &m_prty, /* parity */
X &bpc, /* bits per char */
X/* &zilch; /* power (NA) (60 Hz) */
X &stopbits /* stop bits */
X};
X
Xuchar *sC[16] = {
X &zilch, /* printer => host */
X &zilch, /* printer test */
X &zilch, /* print termination */
X &zilch, /* print extent */
X &p_prty, /* printer parity sense */
X &pm_pty, /* printer parity */
X &p_bpc, /* printer bits per char */
X &echo, /* local echo */
X &zilch, /* screen saver */
X &zilch, /* diagnostic mode */
X &zilch, /* two page operation */
X &zilch, /* smooth scroll speed */
X &transparent, /* transparency mode */
X &ignrflow, /* discard xon/xoff from host */
X &zilch, /* character rate to host */
X &devrep /* identification */
X};
X
Xint *sBi[3] = {
X &n_port, /* comm port number */
X &t_spd, /* Tx speed */
X &r_spd /* Rx speed */
X};
X
Xint *sCi[2] = {
X &p_port, /* printer port */
X &pr_spd /* printer speed */
X};
X
Xstatic char *sBs[48] = { /* setup B label strings */
X "SCROLL: ", "jump", "smooth",
X "AUTOREPEAT: ", "off", "on",
X "SCREEN BACKGROUND: ", "dark", "light",
X "CURSOR: ", "underline", "block",
X "MARGIN BELL: ", "off", "on",
X "KEYCLICK: ", "off", "on",
X "ANSI/VT52: ", "vt52", "ansi",
X "AUTO XON XOFF: ", "off", "on",
X "SHIFTED \"3\": ", "#", "\234",
X "WRAP AROUND: ", "off", "on",
X "NEW LINE: ", "off", "on",
X "INTERLACE: ", "off", "on",
X "PARITY SENSE: ", "odd", "even",
X "PARITY: ", "disabled", "enabled",
X "BITS PER CHAR: ", "7", "8",
X/* "POWER (HZ): ", "60", "50", */
X "STOPBITS: ", "1", "2",
X};
X
Xstatic char *sCs[48] = { /* setup C label strings */
X "PRINTER => HOST: ", "disabled", "enabled",
X "PRINTER TEST: ", "disabled", "enabled",
X "PRINT TERMINATION: ", "none", "form feed",
X "PRINT EXTENT: ", "scroll window", "all",
X "PARITY SENSE: ", "odd", "even",
X "PARITY: ", "disabled", "enabled",
X "BITS PER CHAR: ", "7", "8",
X "LOCAL ECHO: ", "disabled", "enabled",
X "SCREEN SAVER: ", "disabled", "enabled",
X "DIAGNOSTIC MODE: ", "disabled", "enabled",
X "TWO PAGE OPERATION (80 COL): ", "disabled", "enabled",
X "SMOOTH SCROLL SPEED: ", "slow", "fast",
X "TRANSPARENCY MODE: ", "disabled", "enabled",
X "DO NOT PROCESS \"XOFF/XON\": ", "disabled", "enabled",
X "CHARACTER RATE TO HOST: ", "unlimited", "limited to 60 cps",
X "DEVICE REPORT: ", "Esc[?1;11c", "Esc[?1;2c",
X};
X
X/* display setup screens, set modes/parameters */
Xsetups()
X{
X int ac;
X char *av[NARGS];
X int (*proto)(), kermit(), xmodem(), text();
X
X char b, pb, nbuf[256], *p, *s;
X int c, i, n, n0, x, ox, togl, pnum, ppn;
X
X /* restore kb interrupts */
X reset_kbd();
X /* save screen image */
X save_scr();
X
X pt = *(ukascii+'l');
X pnum = n_port; ppn = p_port;
X b = nbaud; pb = pbaud;
X togl = 0;
X av[0] = (char *)0;
X
Xset_up: /* re-entry ... refreshes info screen */
X curs_xy(1, 1);
X eos_erase(1, 1);
X genstat(1, 1);
X burps("SET-UP", 2, 2, AT_BLINK);
X burps("TO EXIT PRESS \"SETUP\"", 2, 4, AT_UL);
X burps("\
X F1 F2 F3 F4 \
X F9 F10 F11 F12 \
X SETUP (SETUP) Break Backspace\
X Up Down Left Right ", 1, 8, 0);
X burps("\
X clear/ clear line/ setups\
X toggle transmit receive 80/132 reset \
Xset tabs all tabs local a/b/c\
X 1/0 speed speed (port) \
X 2@ 3# 4$ 5% \
X 6^ 7& 8* 9( 0) ", 1, 14, 0);
X
Xset_a:
X burps("A", 9, 2, AT_BLINK);
X for (i=0; i<80; i+=20) {
X burps("1234567890", i+1, 24, 0);
X burps("1234567890", i+11, 24, AT_REV);
X }
X tabs[80] = NUL;
X burps(tabs, 1, 23, 0);
X for(x=1;;) switch(c=kbdget()) {
X case K_SETUP:
X case K_F2: goto done;
X
X case '0':
Xfresh: /* reset terminal configuration */
X getdefs("");
X devset();
X pnum = n_port; ppn = p_port;
X b = nbaud; pb = pbaud;
X goto set_up; break;
X
X case SP:
X case K_F12:
X case K_RIGHT: x=(x<80)?x+1:80; curs_xy(x, 23); break;
X
X case BS:
X case K_F11:
X case K_LEFT: x=(x>1)?x-1:1; curs_xy(x, 23); break;
X
X case CR: curs_xy(x=1, 23); break;
X
X case HT: curs_xy(x=tab(x), 23); break;
X
X case '5':
X case K_DOWN: goto set_b; break;
X
X case K_UP: goto set_c; break;
X
X case '4': /* toggle connect mode */
X TOGGLE(local);
X genstat(x, 23);
X break;
X
X case '2': /* toggle tab */
X if (tabs[x-1] == 'T')
X tabs[x-1] = SP;
X else
X tabs[x-1] = 'T';
X burpc(tabs[x-1]); burpc(BS);
X break;
X
X case K_INS: /* set tab */
X tabs[x-1] = 'T';
X burpc(tabs[x-1]); burpc(BS);
X break;
X
X case K_DEL: /* erase tab */
X tabs[x-1] = SP;
X burpc(tabs[x-1]); burpc(BS);
X break;
X
X case 'T': /* set default tabs */
X curs_xy(1, 23);
X for(i=0; i<80; i++) {
X tabs[i] = SP;
X if (i && !(i%8)) tabs[i] = 'T';
X burpc(tabs[i]);
X }
X curs_xy(x, 23);
X break;
X
X case '3': /* clear all tabs */
X for(i=0; i<80; i++) tabs[i] = SP;
X burps(tabs, x=1, 23, 0);
X break;
X
X case 'S': /* save setup */
Xdumpit:
X all_erase();
X burps(" PLEASE WAIT ", 31, 6, AT_REV | AT_BLINK);
X curs_xy(48,6);
X t_spd = r_spd = atoi(bauds[b]);
X pr_spd = atoi(bauds[pb]);
X sBi[0] = &pnum; sCi[0] = &ppn;
X
X sleep(3); /* pretend churning :-) */
X putdefs();
X
X sBi[0] = &n_port; sCi[0] = &p_port;
X goto set_up;
X break;
X
X case '!': /* execute a command in dos */
Xcmd:
X burps("! ", 1, 21, 0); curs_xy(3,21);
X nbuf[0] = 80; s = cgets(nbuf);
X if (nbuf[1]) {
X reset_scr();
X clr_home();
X docmd(s);
X kbflush();
X burps(s, 1, 25, AT_REV);
X curs_xy(nbuf[1]+1, 25);
X c = kbdget();
X init_scr();
X goto set_up;
X }
X curs_xy(1, 21); eol_erase(1, 21);
X curs_xy(x, 23);
X break;
X
X /*
X * file transfer:
X * k - kermit
X * x - xmodem
X * c - text ("cat")
X */
X case 'k':
X av[0] = "kermit";
X proto = kermit;
X case 'c':
X if (!av[0]) {
X av[0] = "cat";
X proto = text;
X }
X case 'x':
X if (!av[0]) {
X av[0] = "xmodem";
X proto = xmodem;
X }
X burps("$ ", 1, 21, 0);
X burps(av[0], 3, 21, 0);
X curs_xy(4+strlen(av[0]),21);
X nbuf[0] = 80; s = cgets(nbuf);
X reset_scr();
X clr_home();
X for(ac=1, n=*s; *s && n && ac1)?x-1:1; break;
X
X case K_UP: goto set_a; break;
X
X case '4': /* toggle connect mode */
X TOGGLE(local);
X genstat(x, 23);
X break;
X
X case '5':
X case K_DOWN: goto set_c; break;
X
X case CR: x = 1; break;
X
X case HT: x = tab(x); break;
X
X case '6': togl++; break;
X
X case 'A': /* answer back message */
X burps("A = ", 1, 21, 0); curs_xy(5, 21);
X i = 0;
X c = (n0 = kbdget()) & 0xff;
X if (c 27 || i & 4) continue;
X i = (i & 3) | ((i & 24) >> 1);
X n = i * 3;
X if (togl) switch (i) {
X /* block 1 */
X case 1:
X TOGGLE(m_repeat);
X kbautorep(m_repeat);
X break;
X case 3:
X TOGGLE(cursor);
X curs_type(cursor);
X break;
X
X/*
X * case 6: case 7: case 9: case 10:
X * case 12: case 13: case 14: case 15:
X * TOGGLE(*sB[i]); break;
X */
X /* block 2 */
X case 6: TOGGLE(m_ansi); break;
X case 7: TOGGLE(flowctl); break;
X
X /* block 3 */
X case 9: TOGGLE(m_wrap); break;
X case 10: TOGGLE(m_newline); break;
X case 11:
X TOGGLE(interlace);
X init_gfx();
X break;
X
X /* block 4 */
X case 12: TOGGLE(parity); break;
X case 13: TOGGLE(m_prty); break;
X case 14: TOGGLE(bpc); break;
X case 15: TOGGLE(stopbits); break;
X
X default:
X break;
X }
X sdisp(x, *sB[i], sBs[n], sBs[n+1], sBs[n+2]);
X }
X goto done;
X
Xset_c: /* mostly printer-related */
X curs_xy(1, 23); eos_erase(1, 23);
X burps("C", 9, 2, AT_BLINK);
X for (i=0; i<16; i++)
X nbuf[i] = (*sC[i]) + '0';
X
X burps("1 .... 2 .... 3 .... 4 ....", 1, 24, 0);
X for(i=16, n=27; i; i-=4, n-=8) {
X nbuf[i] = NUL;
X burps(nbuf+i-4, n, 24, AT_REV);
X }
X
X burps("PRINTER PORT .", 49, 24, 0);
X s = "0"; *s = '1'+ppn; burps(s, 63, 24, 0);
X burps("SPEED ..... ", 66, 24, 0);
X burps(bauds[pb], 72, 24, 0);
X curs_xy(1, 23);
X
X for(ox=x=1, togl=0;; togl=0) {
X switch(c=kbdget()) {
X case K_SETUP:
X case K_F2: goto done;
X
X case '0': goto fresh; break;
X
X case SP:
X case K_F12:
X case K_LEFT: x=(x>1)?x-1:1; break;
X
X case BS:
X case K_F11:
X case K_RIGHT: x=(x<80)?x+1:80; break;
X
X case K_UP: goto set_b; break;
X
X case '4': /* toggle connect mode */
X TOGGLE(local);
X genstat(x, 23);
X break;
X
X case '5':
X case K_DOWN: goto set_a; break;
X
X case CR: x = 1; break;
X
X case HT: x = tab(x); break;
X
X case '6': togl++; break;
X
X case '7': case '8': /* printer speed */
X pb = (pb+1) % (EXTB+1);
X burps(bauds[pb], 72, 24, 0);
X curs_xy(x, 23);
X break;
X
X case '9': /* was 80/132 toggle */
X case 'p': case 'P': /* printer port */
X ppn = (ppn+1) % NPORTS;
X s = "0"; *s = '1'+ppn; burps(s, 63, 24, 0);
X curs_xy(x, 23);
X break;
X
X case 'S': /* save setups */
X goto dumpit;
X break;
X
X case '!': /* dos command */
X goto cmd;
X break;
X
X default:
X break;
X }
X
X if (x != ox)
X { eol_erase(ox, 23); curs_xy(x, 23); }
X
X
X ox = x;
X i = x-3;
X if (i > 27 || i & 4) continue;
X i = (i & 3) | ((i & 24) >> 1);
X n = i * 3;
X if (togl) switch (i) {
X/*
X * case 4: case 5: case 6: case 7: case 12:
X * TOGGLE(*sC[i]); break;
X */
X case 4: TOGGLE(p_prty); break;
X case 5: TOGGLE(pm_pty); break;
X case 6: TOGGLE(p_bpc); break;
X case 7: TOGGLE(echo); break;
X
X /* block 4 */
X case 12: TOGGLE(transparent); break;
X case 13: TOGGLE(ignrflow); break;
X case 15: TOGGLE(devrep); break;
X
X default:
X break;
X }
X sdisp(x, *sC[i], sCs[n], sCs[n+1], sCs[n+2]);
X }
Xdone:
X pbaud = pb;
X pr_reset();
X p_port = ppn;
X pr_init();
X
X nbaud = b;
X if (pnum != n_port) {
X reset_prt();
X n_port = pnum;
X init_prt();
X }
X restore_scr();
X init_kbd();
X set_prt();
X devset();
X}
X
X/* display a setup option, underline current selection */
X
Xsdisp(x, sw, label, off, on)
Xint x, sw;
Xchar *label, *off, *on;
X{
X char *p;
X int l, n, f;
X
X l = strlen(label); n = strlen(on);
X f = x+2+l+n; n = x+1+l;
X p = "0"; *p = '0' + (sw>0);
X burps(p, x, 24, AT_REV);
X burps(label, x+1, 23, 0);
X burps(on, n, 23, (sw)? AT_UL : 0);
X *p = '/'; burps(p, f-1, 23, 0);
X burps(off, f, 23, (sw)? 0 : AT_UL);
X *p = pt; burps(p, x, 23, 0);
X}
X
Xchar stbuf[81]; /* status line buffer */
Xextern char led[];
X
X/* general status line */
Xgenstat(x, y)
Xuchar x, y;
X{
X /* comm information */
X sprintf(stbuf, "port:%d data:%d%c%d speed:%5s ",
X n_port+1, bpc+7,
X ((m_prty) ? ((parity) ? 'E' : 'O') : 'N'),
X stopbits+1, bauds[nbaud]);
X /* connect mode "leds" */
X sprintf(&stbuf+35, "on line %c local %c ",
X (local) ? SP : '*', (local) ? '*' : SP);
X /* programmable "leds" */
X sprintf(&stbuf+60, "1 %c 2 %c 3 %c 4 %c ",
X led[0], led[1], led[2], led[3]);
X sturp(stbuf, x, y);
X}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'term.c'" '(7801 characters)'
if test -f 'term.c'
then
echo shar: will not over-write existing file "'term.c'"
else
sed 's/^X//' << \SHAR_EOF > 'term.c'
X/*
X * term.c:
X * term(): the terminal.
X * rloop(), xloop(): local mode recv & xmit routines
X * devset(): assigns xmit & recv and
X * handles other setings and "devices."
X * note: some code gets repeated here and there.
X * this may not be pretty but it keeps the
X * main loops from getting bogged down.
X *
X * copyright (c) University of Toronto, 1988.
X */
X#include "common.h"
X
Xuchar cx=1, cy=1; /* current cursor position */
Xuchar tx=0, ty=0; /* cursor "memory" (for wrap, scroll, etc.) */
X
Xextern char ansback[];
Xextern char *cset, *g0, *g1;
Xextern char *usascii, *ukascii;
Xextern char *keypadv[];
X
Xextern uchar keyboom, keyhit;
Xextern uchar m_insert, m_repeat;
Xextern uchar m_ansi, m_crskey, m_keypad;
Xextern uchar m_columns, m_wrap, m_newline;
Xextern uchar srgn_bot, srgn_top;
Xextern uchar local, transparent, echo, xoff, cursor;
Xextern uchar ignrflow, rxoff, devrep, vtidnum, txtxfr;
X
Xextern int xmit_chr(), recv_chr(), trns_chr();
Xextern int burpc(), insurpc(), ansi(), vt52();
Xextern int kbdget();
X
Xint avofs = ANSOFS; /* ansi/vt52 keypadv "offset" bits */
Xint (*xmit)(), (*recv)(); /* xmit = output to "comm port" */
Xint (*o_xmit)(), (*o_recv)(); /* recv = input from "comm port" */
Xint (*burp)(); /* output to "screen" */
Xint (*keyg)(), (*o_keyg)(); /* input from "keyboard" */
X
X/*
X * term -- the main loop, the guts, "where the action is"
X * "key" input has priority. Only after the "key type-ahead"
X * buffer is emptied does it check the input buffer.
X * (except when rxoff is high (ie. a remote XOFF request))
X */
Xterm()
X{
X char *p;
X int zip();
X register int c;
X
X cset = g0 = g1 = usascii;
X
X devset();
X
X while (!keyboom) {
X while (keyhit) { /* drain key buffer(s) */
X if ((c = keyg()) & 0xff) { /* ascii keys */
X xmit(c);
X if (c < SP) switch (c) {
X case CR:
X if (m_newline) xmit(LF);
X break;
X case XOFF:
X xoff++; recv=zip;
X break;
X case XON:
X xoff=0; recv=o_recv;
X break;
X default:
X break;
X }
X }
X else if ((c = kbdfn(c)) & 0x80) /* setup keys */
X setups();
X else if (c & 0x40) { /* send BREAK or NUL */
X if (c & 1) xmit(NUL);
X else send_brk(local);
X }
X else { /* function "keys" */
X c |= (c & 0x18) ? m_keypad : m_crskey;
X p = keypadv[c | avofs];
X while (*p) xmit(*p++ & 0x7f);
X if (rxoff) break;
X }
X }
X
X /* check incoming buffer(s) */
X if ((c = recv()) < 0) continue;
X
X if (c & 0x60) { /* visible ascii */
Xsplat:
X /*
X * wraparound handling: tx indicates a visible
X * char was last placed in the final column.
X * if our line position (cy) hasn't changed
X * and if m_wrap then if we're at the end of a
X * scroll region, scroll else move down 1 line.
X */
X if (tx && ty == cy && m_wrap) {
X tx = ty = 0;
X curs_xy(cx=1, cy); /* CR */
X if (cy == srgn_bot) /* scroll it */
X /* scrl_up(1, srgn_top, srgn_bot, cx, cy); */
X /*
X * seems TI bios scrolls faster
X * when burping LF than with
X * scrl_up(1,1,24), so let's try
X * to take advantage of that.
X */
X if (srgn_top-1 || cy < 24)
X scrl_up(1, srgn_top, srgn_bot, cx, cy);
X else
X burpc(LF, cx, cy);
X else if (cy < 24)
X curs_xy(cx, ++cy);
X }
X
X burp(*(cset+c), cx++, cy); /* screen it */
X
X if (cx > m_columns) { /* at last column? */
X /* next char might wraparound */
X ty = cy;
X curs_xy(cx=tx=m_columns, cy);
X }
X continue;
X }
X
X switch (c) { /* control chars */
X case CR: tx = 0; curs_xy(cx=1, cy); break;
X case LF: case VT: case FF:
X tx = 0;
X if (cy == srgn_bot) /* scroll it */
X if (cy < 24 || srgn_top-1)
X scrl_up(1, srgn_top, srgn_bot, cx, cy);
X else
X burpc(LF, cx, cy);
X else if (cy < 24)
X curs_xy(cx, ++cy);
X break;
X case ESC:
X while (esc()) ;
X if (tx && !(ty == cy && tx == cx)) tx = 0;
X break;
X case HT: tx = 0; curs_xy(cx=tab(cx), cy); break;
X case BS:
X tx = 0;
X if (cx > 1) curs_xy(--cx, cy);
X break;
X case SO: cset = g1; break;
X case SI: cset = g0; break;
X/* case DC1: kbunlck(); break; /* XON */
X/* case DC3: kblock(); break; /* XOFF */
X case DC1: rxoff = 0; break;
X case DC3: if (!ignrflow) rxoff++; break;
X case BEL:
X /* might want to have another BEL.
X * in the meantime let bios handle it */
X burpc(c, cx, cy); break;
X case ENQ: p = ansback; while (*p) xmit(*p++); break;
X case NUL: break;
X default: /* not a special ctrl char? */
X /* ok burp it, lessee what happens */
X goto splat;
X break; /* not reached */
X }
X }
X}
X
X/* handle ctrl chars (from EGETC in esc.c) */
Xdoctrl(c)
Xregister int c;
X{
X char *p;
X
X switch (c) {
X case CR: tx = 0; curs_xy(cx=1, cy); break;
X case LF: case VT: case FF:
X tx = 0;
X if (cy == srgn_bot)
X if (cy < 24 || srgn_top-1)
X scrl_up(1, srgn_top, srgn_bot, cx, cy);
X else
X burpc(LF, cx, cy);
X else if (cy < 24)
X curs_xy(cx, ++cy);
X break;
X/* NB: case ESC: ... not handled here. */
X case ENQ: p = ansback; while (*p) xmit(*p++); break;
X case BS:
X tx = 0;
X if (cx > 1) curs_xy(--cx, cy);
X break;
X case HT: tx = 0; curs_xy(cx=tab(cx), cy); break;
X case SO: cset = g1; break;
X case SI: cset = g0; break;
X/* case DC1: kbunlck(); break; /* XON */
X/* case DC3: kblock(); break; /* XOFF */
X case DC1: rxoff = 0; break;
X case DC3: if (!ignrflow) rxoff++; break;
X case BEL: /* see BEL comment in term() */
X burpc(c, cx, cy); break;
X default:
X break;
X }
X}
X
X/*
X * local mode:
X * "key" output is placed into local input buffer
X * where it's received and read as "comm" input.
X * (see devset() for xmit/recv assignments)
X */
X
X/* get more chars into lbuf buffer (called from rloop()) */
Xxtract()
X{
X int c;
X char *p;
X
X while (keyhit) {
X if ((c = keyg()) & 0xff) { /* ascii keys */
X xmit(c);
X if (m_newline && c == CR) xmit(LF);
X }
X else if ((c = kbdfn(c)) & 0x80) { /* setup key */
X setups();
X if (!local) return(-2);
X }
X else if (c & 0x40) { /* send BREAK or NUL */
X if (c & 1) xmit(NUL);
X else send_brk(local);
X }
X else { /* "function" keys */
X c |= (c & 0x18) ? m_keypad : m_crskey;
X p = keypadv[c | avofs];
X while (*p) xmit(*p++);
X if (rxoff) break;
X }
X }
X return(-1);
X}
X
X/* local mode buffer + buffer indices */
Xint lin, lout;
Xchar lbuf[BUFMAX];
X#define BUFC(a,b) ((a BUFMAX-8) { /* buffer almost full */
X rxoff++; /* probably due to stxt() */
X lbuf[lin++] = DC1;
X lin %= BUFMAX;
X }
X
X if (transparent && c < SP) {
X lbuf[lin++] = '^';
X lin %= BUFMAX;
X c |= '@';
X }
X lbuf[lin++] = c & 0x7f;
X lin %= BUFMAX;
X}
X
X/* local mode "recv" -- get chars from local input buffer */
Xrloop()
X{
X int c;
X
X if (BUFC(lin,lout) > 0) {
X c = lbuf[lout++];
X lout %= BUFMAX;
X return(c);
X }
X /* buffer empty so check for more key input */
X return(xtract());
X}
X
X/* echo mode "xmit" (not used when "local") */
Xxsplit(c)
X{
X loop_chr(c); /* insert char into incoming data buffer */
X xmit_chr(c); /* send char to host */
X}
X
X
X/*
X * choose devices(ie. procedures) according to current options.
X */
Xdevset()
X{
X xypos(&cx, &cy);
X curs_type(cursor);
X kbautorep(m_repeat);
X nlmod(m_newline);
X genstat(cx, cy);
X init_gfx();
X if (ignrflow) rxoff = 0;
X vtidnum = (devrep) ? 1 : 2; /* see misc.c */
X
X xmit = (echo) ? xsplit : xmit_chr;
X recv = (transparent) ? trns_chr : recv_chr;
X
X if (local) {
X recv = rloop;
X xmit = xloop;
X }
X
X burp = (m_insert) ? insurpc : burpc;
X esc = (m_ansi) ? ansi : vt52;
X keyg = kbdget;
X
X avofs = (m_ansi) ? ANSOFS : OFS52;
X
X o_xmit = xmit;
X o_recv = recv;
X o_keyg = keyg;
X
X if (txtxfr) /* ... then reassign keyg() */
X txtset();
X}
X
X/*
X * zip -- dummy comm port input function
X * used when XOFF hit (or PAUS (see keybrd.c)) to "freeze" the screen.
X * (depends on flow control to take care of incoming comm data)
X */
Xzip()
X{
X return(-1);
X}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'text.c'" '(3105 characters)'
if test -f 'text.c'
then
echo shar: will not over-write existing file "'text.c'"
else
sed 's/^X//' << \SHAR_EOF > 'text.c'
X/*
X * text.c:
X * raw ascii text transfer functions
X *
X * copyright (c) University of Toronto, 1988.
X */
X#include
X
Xstatic int xfd=0;
X
Xunsigned char txtxfr=0;
X
X#define LSZ 255
X
X#ifdef debug
Xstatic int dfd;
Xstatic char *dp, dbuf[LSZ];
X#endif
X
Xstatic int ln = 0;
Xstatic char *lp, lbuf[LSZ];
Xstatic char prog[16], *opt, fnam[16];
Xstatic int oparms;
Xstatic int sflag, rflag, fdone, bflag, tflag, errflg;
X
X/*
X * text -- text transfer "interface" called from setups()
X * sets local flags needed by txtset().
X * checks argument options and the filename.
X */
Xtext(ac, av)
Xint ac;
Xchar *av[];
X{
X char *p;
X
X strcpy(prog, av[0]);
X sflag = rflag = fdone = bflag = tflag = errflg = 0;
X
X if (ac < 2 || ac > 3)
X goto usage;
X
X opt = av[1];
X
X for (p = opt; *p; p++)
X switch (*p) {
X case '$': fdone++; break;
X case 's': sflag++; break;
X case 'r': rflag++; break;
X case 't': tflag++; break;
X case 'b': bflag++; break;
X default: errflg++; break;
X }
X
X if (errflg || (sflag+rflag) != 1 || (bflag+tflag+fdone) != 1) {
Xusage:
X cprintf("\
XUsage: %s {st|sb|s$|rt|rb|r$} filename\r\n", prog);
X cputs("\
X\tst - send text\r\n\
X\tsb - send binary\r\n\
X\ts$ - terminate send (close file)\r\n\
X\trt - receive text\r\n\
X\trb - receive binary\r\n\
X\tr$ - terminate receive\r\n");
X return(-1);
X }
X
X if (fdone) { /* shutdown rtxt() or stxt() */
X if (xfd > 0) {
X if (rflag && ln > 0)
X write(xfd, lbuf, ln);
X close(xfd);
X }
X txtxfr = xfd = 0;
X return(0);
X }
X
X if (sflag)
X oparms = O_RDONLY | ((bflag) ? O_BINARY : 0);
X else
X oparms = O_WRONLY|O_BINARY|O_CREAT;
X
X strcpy(fnam, av[2]);
X if (xfd > 0) close(xfd);
X if ((xfd = open(fnam, oparms, 0664)) < 0) {
X perror(fnam);
X txtxfr = xfd = 0;
X return(-1);
X }
X close(xfd); /* only wanted to test fnam */
X cprintf("\r\n%s transfer of %s will begin on exit from setups.\r\n",
X (tflag) ? "Ascii text" : "Raw data", fnam);
X txtxfr++;
X return(0);
X}
X
Xextern unsigned char keyhit, rxoff;
Xextern int (*recv)(), (*o_recv)();
Xextern int (*keyg)(), (*xmit)();
X
X/* prepare files and routines for text transfer */
Xtxtset()
X{
X int stxt();
X int rtxt();
X extern int recv_byt();
X extern unsigned char local, transparent;
X
X lp = lbuf; ln = 0;
X
X if (sflag) {
X xfd = open(fnam, oparms);
X ln = read(xfd, lp, LSZ);
X if (ln < 1 || keyhit) {
X txtxfr = 0;
X return;
X }
X keyg = stxt;
X keyhit = ln;
X }
X else if (rflag) {
X recv = rtxt;
X xfd = open(fnam, oparms, 0664);
X if (bflag && !(local || transparent))
X o_recv = recv_byt; /* was recv_chr */
X }
X
X txtxfr = 0;
X}
X
X/* send text */
Xstxt()
X{
X int n;
X
X if (rxoff) /* remote XOFF? ok, take a break */
X return(0);
X
X n = *lp++;
X if (n == '\n' && tflag) n = '\r';
X
X if (keyhit != ln) { /* user hit a key? */
X close(xfd);
X xfd = keyhit = 0;
X devset();
X return(n);
X }
X
X ln--;
X if (keyhit) keyhit--;
X
X if (ln < 1) {
X lp = lbuf;
X keyhit = ln = read(xfd, lp, LSZ);
X if (ln < 1) {
X close(xfd);
X xfd = keyhit = 0;
X devset();
X }
X }
X return(n);
X}
X
X/* receive text */
Xrtxt()
X{
X int n;
X char c;
X
X if ((n = o_recv()) < 0)
X return(n);
X lbuf[ln] = n; ln++;
X if (ln >= LSZ) {
X write(xfd, lbuf, ln);
X ln = 0;
X }
X return(n);
X}
SHAR_EOF
fi # end of overwriting check
# End of shell archive
exit 0