📄 tek.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)tek.c 1.1 92/07/30 Copyr 1985 Sun Micro";#endif#endif/* * Copyright (c) 1985 by Sun Microsystems, Inc. *//* * tek makes the Sun into a Tektronix 4014 * * Author: Steve Kleiman */#include <sys/types.h>#include <stdio.h>#include "tek.h"#undef DEBUGextern char *calloc();extern void cfree();/* * constants */#define ADDRBITS 037 /* mask for address bits in a char */#define EXTRABITS 003 /* mask for extra address bits in a char */#define LO 2 /* position of low order bits in pos reg */#define HI 7 /* position of hi order bits in pos reg */#define XEXTRA 0 /* position of x extra bits in char */#define YEXTRA 2 /* position of Y extra bit in char */#define CNTRL 00 /* control characters */#define HIYX 040 /* hi order x or y addr */#define LOX 0100 /* low order x addr */#define LOYE 0140 /* low order y addr or extension bits */#define SADDR 040 /* high order bits for sending address */#define STATUS 0241 /* dummy status byte-see 4014 man. pg.3-30 */#define SGRAPH 010 /* graph mode bit in status byte */#define SMARGIN2 002 /* margin 2 bit in status byte */#define NONCHR 0377 /* dummy noncharacter */#define METACHR 0200 /* lowest meta character *//* * macros *//* * update an address from a char */#define CHARTOADDR(r, c, s) ((r & ~(ADDRBITS<<s)) | ((c & ADDRBITS)<<s))#define EXTRATOADDR(r, c, s) ((r & (~EXTRABITS)) | ((c >> s) & EXTRABITS))/* * make a char from an address */#define ADDRTOCHAR(r, s) ((r>>s) & ADDRBITS)/* * get upper control bit from character */#define CTYPE(c) ((c & ~ADDRBITS) & 0x7F)/* * types and structures */enum tmode { /* term modes */ ALPHA, GRAPH, GIN, INCPLOT, PTPLOT, SPPTPLOT};typedef char bool;#define TRUE 1#define FALSE 0struct Point { int x; int y;};struct tek { int straps; /* tek4014 straps see tek.h */ struct Point tekgfxpos; /* last tek4014 graphics position */ struct Point tekpos; /* current tek4014 position */ u_char extra; /* last extra byte sent */ int font; /* current character font */ enum tmode mode; /* tek4014 terminal mode */ enum vtype vtype; /* vector type */ enum vstyle vstyle; /* vector style */ int margin; /* alpha margin x location */ int intensity; /* pt plot intensity */ bool full; /* page full */ bool lce; /* current lce state */ bool bypass; /* bypass state see tek4014 manual */ bool darkvec; /* dark vector indicator */ bool got_loy; /* low y address has been sent */ caddr_t tdata; /* token to give to output routines */}; /* * global data */static struct Point tekfontsize[4] = { {TEKFONT0X, TEKFONT0Y}, {TEKFONT1X, TEKFONT1Y}, {TEKFONT2X, TEKFONT2Y}, {TEKFONT3X, TEKFONT3Y},};/* * internal routines */static void tek_reset(); /* reset terminal */static void tek_page(); /* clear page */static void tek_putchar(); /* place alpha character */static void tek_gfxdecode(); /* decode graphics address chars */static void tek_spptdecode(); /* special point plot decode */static void tek_incdecode(); /* inc plot decode */static void tek_newmode(); /* goto new terminal mode */static void tek_sendstatus(); /* send terminal status to tty */static void tek_sendpos(); /* send position to tty */#ifdef DEBUGFILE *debug;#endifcaddr_ttek_create(tdata, straps) caddr_t tdata; int straps;{ register struct tek *tp;#ifdef DEBUG debug = fopen("debug", "w+"); /* setbuf(debug, NULL); */#endif if ((tp = (struct tek *) calloc(1, sizeof (struct tek))) == NULL) return (NULL); tp->tdata = tdata; tp->straps = straps; tek_reset(tp); return ((caddr_t) tp);}voidtek_destroy(dp){ register struct tek *tp; tp = (struct tek *) dp; cfree(tp);}voidtek_set_straps(dp, straps) caddr_t dp; int straps;{ register struct tek *tp; tp = (struct tek *) dp; tp->straps = straps; if (tp->straps & LOCAL) tp->bypass = FALSE;}voidtek_ttyinput(dp, c) caddr_t dp; register u_char c;{ register struct tek *tp; bool arm; /* indicator for next lce (ESC) state */ tp = (struct tek *) dp; c &= 0x7f; arm = FALSE; /* default: reset lce */ if (CTYPE(c) == CNTRL) { switch (c) { case NUL: if (tp->lce) arm = TRUE; break; case ENQ: if (tp->lce) { tp->bypass = TRUE; if (tp->mode == GIN) { tek_sendpos(tp); } else { tek_sendstatus(tp); tek_sendpos(tp); } tek_newmode(tp, ALPHA); } break; case BEL: tp->bypass = FALSE; tek_putchar(tp, c); break; case BS: case TAB: case VT: if ((tp->mode == ALPHA) || tp->lce) tek_putchar(tp, c); break; case LF: tp->bypass = FALSE; if (tp->lce) { arm = TRUE; } else { if (tp->mode == GRAPH) { tp->tekgfxpos.y -= 4; if (tp->tekgfxpos.y < 0) tp->tekgfxpos.y = 0; } else { tek_putchar(tp, c); } if (tp->straps & LFCR) { tp->tekgfxpos.x &= ~EXTRABITS; tp->tekgfxpos.y &= ~EXTRABITS; tp->vtype = VT_NORMAL; tp->vstyle = VS_NORMAL; tek_displaymode(tp->tdata, tp->vstyle, tp->vtype); tek_newmode(tp, ALPHA); tek_putchar(tp, CR); } } break; case CR: tp->bypass = FALSE; if (tp->lce) { arm = TRUE; } else { tp->tekgfxpos.x &= ~EXTRABITS; tp->tekgfxpos.y &= ~EXTRABITS; tp->vtype = VT_NORMAL; tp->vstyle = VS_NORMAL; tek_displaymode(tp->tdata, tp->vstyle, tp->vtype); tek_newmode(tp, ALPHA); tek_putchar(tp, c); if (tp->straps & CRLF) tek_putchar(tp, LF); } break; case SO: /* alt character set */ break; case SI: tp->bypass = FALSE; /* normal character set */ break; case FF: if (tp->lce) { tp->tekgfxpos.x &= ~EXTRABITS; tp->tekgfxpos.y &= ~EXTRABITS; tp->bypass = FALSE; tek_newmode(tp, ALPHA); tek_putchar(tp, c); } break; case ETB: if (tp->lce) { tek_makecopy(tp->tdata); /* make hard copy */ tp->bypass = FALSE; } break; case CAN: if (tp->lce) tp->bypass = TRUE; break; case SUB: if (tp->lce) { tp->bypass = TRUE; tek_newmode(tp, GIN); } break; case ESC: arm = TRUE; break; case FS: if (tp->lce) tek_newmode(tp, SPPTPLOT); else tek_newmode(tp, PTPLOT); break; case GS: tp->bypass = FALSE; tek_newmode(tp, GRAPH); break; case RS: tek_newmode(tp, INCPLOT); break; case US: tp->bypass = FALSE; tek_newmode(tp, ALPHA); break; default: break; } } else if (tp->lce) { if (c >= '8' && c <= ';') { tp->font = c - '8'; tek_chfont(tp->tdata, c - '8'); } else if (c == '?') { c = 0x7f; if (tp->mode != ALPHA) goto InterpretAddr; } else if (c >= '`' && c <= 'w') { switch ((c - '`') >> 3) { case 0: tp->vtype = VT_NORMAL; break; case 1: tp->vtype = VT_DEFOCUSED; break; case 2: tp->vtype = VT_WRITETHRU; break; } switch ((c - '`') & 0x07) { case 0: case 5: case 6: case 7: tp->vstyle = VS_NORMAL; break; case 1: tp->vstyle = VS_DOTTED; break; case 2: tp->vstyle = VS_DOTDASH; break; case 3: tp->vstyle = VS_SHORTDASH; break; case 4: tp->vstyle = VS_LONGDASH; break; } tek_displaymode(tp->tdata, tp->vstyle, tp->vtype); } else if (c == 0x7f) { arm = TRUE; } } else if (!tp->bypass) {InterpretAddr: switch (tp->mode) { case ALPHA: tek_putchar(tp, c); break; case PTPLOT: case GRAPH: tek_gfxdecode(tp, c); break; case SPPTPLOT: tek_spptdecode(tp, c); break; case INCPLOT: tek_incdecode(tp, c); break; default: break; } } tp->lce = arm;}#ifndef DISPLAY_ONLYvoidtek_kbdinput(dp, c) caddr_t dp; register u_char c;{ register struct tek *tp; tp = (struct tek *) dp; c &= 0xff; if (tp->full && c != COPY) { tek_pagefull_off(tp->tdata); tp->full = 0; } if (c >= METACHR) { switch (c) { case RESET: tek_reset(tp); break; case PAGE: tek_page(tp); break; case COPY: tek_makecopy(tp->tdata); tp->bypass = FALSE; case RELEASE: default: break; } } else { if (!(tp->straps & LOCAL)) { tek_ttyoutput(tp->tdata, c); } if (tp->mode == GIN) { tp->bypass = FALSE; tek_sendpos(tp); tek_newmode(tp, ALPHA); } else if ((tp->straps & LOCAL) || (tp->straps & AECHO)) { tek_ttyinput((caddr_t) tp, c); } }}voidtek_posinput(dp, x, y) caddr_t dp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -