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