1: /*
   2:  * Copyright (c) 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)tty_tb.c	1.2 (2.11BSD GTE) 11/29/94
   7:  */
   8: 
   9: #include "tb.h"
  10: #if NTB > 0
  11: 
  12: /*
  13:  * Line discipline for RS232 tablets;
  14:  * supplies binary coordinate data.
  15:  */
  16: #include "param.h"
  17: #include "systm.h"
  18: #include "user.h"
  19: #include "tablet.h"
  20: #include "tty.h"
  21: #include "proc.h"
  22: #include "inode.h"
  23: #include "file.h"
  24: #include "buf.h"
  25: #include "uio.h"
  26: 
  27: /*
  28:  * Tablet configuration table.
  29:  */
  30: struct  tbconf {
  31:     short   tbc_recsize;    /* input record size in bytes */
  32:     short   tbc_uiosize;    /* size of data record returned user */
  33:     int tbc_sync;   /* mask for finding sync byte/bit */
  34:     int (*tbc_decode)();/* decoding routine */
  35:     char    *tbc_run;   /* enter run mode sequence */
  36:     char    *tbc_point; /* enter point mode sequence */
  37:     char    *tbc_stop;  /* stop sequence */
  38:     char    *tbc_start; /* start/restart sequence */
  39:     int tbc_flags;
  40: #define TBF_POL 0x1 /* polhemus hack */
  41: };
  42: 
  43: static  int tbdecode(), gtcodecode(), poldecode();
  44: static  int tblresdecode(), tbhresdecode();
  45: 
  46: struct  tbconf tbconf[TBTYPE] = {
  47: { 0 },
  48: { 5, sizeof (struct tbpos), 0200, tbdecode, "6", "4" },
  49: { 5, sizeof (struct tbpos), 0200, tbdecode, "\1CN", "\1RT", "\2", "\4" },
  50: { 8, sizeof (struct gtcopos), 0200, gtcodecode },
  51: {17, sizeof (struct polpos), 0200, poldecode, 0, 0, "\21", "\5\22\2\23",
  52:  TBF_POL },
  53: { 5, sizeof (struct tbpos), 0100, tblresdecode, "\1CN", "\1PT", "\2", "\4"},
  54: { 6, sizeof (struct tbpos), 0200, tbhresdecode, "\1CN", "\1PT", "\2", "\4"},
  55: };
  56: 
  57: /*
  58:  * Tablet state
  59:  */
  60: struct tb {
  61:     int tbflags;        /* mode & type bits */
  62: #define TBMAXREC    17  /* max input record size */
  63:     char    cbuf[TBMAXREC];     /* input buffer */
  64:     union {
  65:         struct  tbpos tbpos;
  66:         struct  gtcopos gtcopos;
  67:         struct  polpos polpos;
  68:     } rets;             /* processed state */
  69: #define NTBS    16
  70: } tb[NTBS];
  71: 
  72: /*
  73:  * Open as tablet discipline; called on discipline change.
  74:  */
  75: /*ARGSUSED*/
  76: tbopen(dev, tp)
  77:     dev_t dev;
  78:     register struct tty *tp;
  79: {
  80:     register struct tb *tbp;
  81: 
  82:     if (tp->t_line == TABLDISC)
  83:         return (ENODEV);
  84:     ttywflush(tp);
  85:     for (tbp = tb; tbp < &tb[NTBS]; tbp++)
  86:         if (tbp->tbflags == 0)
  87:             break;
  88:     if (tbp >= &tb[NTBS])
  89:         return (EBUSY);
  90:     tbp->tbflags = TBTIGER|TBPOINT;     /* default */
  91:     tp->t_cp = tbp->cbuf;
  92:     tp->t_inbuf = 0;
  93:     bzero((caddr_t)&tbp->rets, sizeof (tbp->rets));
  94:     tp->T_LINEP = (caddr_t)tbp;
  95:     tp->t_flags |= LITOUT;
  96:     return (0);
  97: }
  98: 
  99: /*
 100:  * Line discipline change or last device close.
 101:  */
 102: tbclose(tp, flag)
 103:     register struct tty *tp;
 104:     int flag;
 105: {
 106:     register int s;
 107:     int modebits = TBPOINT|TBSTOP;
 108: 
 109:     tbioctl(tp, (u_int)(BIOSMODE), &modebits, 0);
 110:     s = spl5();
 111:     ((struct tb *)tp->T_LINEP)->tbflags = 0;
 112:     tp->t_cp = 0;
 113:     tp->t_inbuf = 0;
 114:     tp->t_rawq.c_cc = 0;        /* clear queues -- paranoid */
 115:     tp->t_canq.c_cc = 0;
 116:     tp->t_line = 0;         /* paranoid: avoid races */
 117:     splx(s);
 118: }
 119: 
 120: /*
 121:  * Read from a tablet line.
 122:  * Characters have been buffered in a buffer and decoded.
 123:  */
 124: tbread(tp, uio, flag)
 125:     register struct tty *tp;
 126:     struct uio *uio;
 127: {
 128:     register struct tb *tbp = (struct tb *)tp->T_LINEP;
 129:     register struct tbconf *tc = &tbconf[tbp->tbflags & TBTYPE];
 130:     int ret;
 131: 
 132:     if ((tp->t_state&TS_CARR_ON) == 0)
 133:         return (EIO);
 134:     ret = uiomove(&tbp->rets, tc->tbc_uiosize, uio);
 135:     if (tc->tbc_flags&TBF_POL)
 136:         tbp->rets.polpos.p_key = ' ';
 137:     return (ret);
 138: }
 139: 
 140: /*
 141:  * Low level character input routine.
 142:  * Stuff the character in the buffer, and decode
 143:  * if all the chars are there.
 144:  *
 145:  * This routine could be expanded in-line in the receiver
 146:  * interrupt routine to make it run as fast as possible.
 147:  */
 148: tbinput(c, tp)
 149:     register int c;
 150:     register struct tty *tp;
 151: {
 152:     register struct tb *tbp = (struct tb *)tp->T_LINEP;
 153:     register struct tbconf *tc = &tbconf[tbp->tbflags & TBTYPE];
 154: 
 155:     if (tc->tbc_recsize == 0 || tc->tbc_decode == 0)    /* paranoid? */
 156:         return;
 157:     /*
 158: 	 * Locate sync bit/byte or reset input buffer.
 159: 	 */
 160:     if (c&tc->tbc_sync || tp->t_inbuf == tc->tbc_recsize) {
 161:         tp->t_cp = tbp->cbuf;
 162:         tp->t_inbuf = 0;
 163:     }
 164:     *tp->t_cp++ = c&0177;
 165:     /*
 166: 	 * Call decode routine only if a full record has been collected.
 167: 	 */
 168:     if (++tp->t_inbuf == tc->tbc_recsize)
 169:         (*tc->tbc_decode)(tbp->cbuf, &tbp->rets);
 170: }
 171: 
 172: /*
 173:  * Decode GTCO 8 byte format (high res, tilt, and pressure).
 174:  */
 175: static
 176: gtcodecode(cp, tbpos)
 177:     register char *cp;
 178:     register struct gtcopos *tbpos;
 179: {
 180: 
 181:     tbpos->pressure = *cp >> 2;
 182:     tbpos->status = (tbpos->pressure > 16) | TBINPROX; /* half way down */
 183:     tbpos->xpos = (*cp++ & 03) << 14;
 184:     tbpos->xpos |= *cp++ << 7;
 185:     tbpos->xpos |= *cp++;
 186:     tbpos->ypos = (*cp++ & 03) << 14;
 187:     tbpos->ypos |= *cp++ << 7;
 188:     tbpos->ypos |= *cp++;
 189:     tbpos->xtilt = *cp++;
 190:     tbpos->ytilt = *cp++;
 191:     tbpos->scount++;
 192: }
 193: 
 194: /*
 195:  * Decode old Hitachi 5 byte format (low res).
 196:  */
 197: static
 198: tbdecode(cp, tbpos)
 199:     register char *cp;
 200:     register struct tbpos *tbpos;
 201: {
 202:     register char byte;
 203: 
 204:     byte = *cp++;
 205:     tbpos->status = (byte&0100) ? TBINPROX : 0;
 206:     byte &= ~0100;
 207:     if (byte > 036)
 208:         tbpos->status |= 1 << ((byte-040)/2);
 209:     tbpos->xpos = *cp++ << 7;
 210:     tbpos->xpos |= *cp++;
 211:     if (tbpos->xpos < 256)          /* tablet wraps around at 256 */
 212:         tbpos->status &= ~TBINPROX; /* make it out of proximity */
 213:     tbpos->ypos = *cp++ << 7;
 214:     tbpos->ypos |= *cp++;
 215:     tbpos->scount++;
 216: }
 217: 
 218: /*
 219:  * Decode new Hitach 5-byte format (low res).
 220:  */
 221: static
 222: tblresdecode(cp, tbpos)
 223:     register char *cp;
 224:     register struct tbpos *tbpos;
 225: {
 226: 
 227:     *cp &= ~0100;       /* mask sync bit */
 228:     tbpos->status = (*cp++ >> 2) | TBINPROX;
 229:     tbpos->xpos = *cp++;
 230:     tbpos->xpos |= *cp++ << 6;
 231:     tbpos->ypos = *cp++;
 232:     tbpos->ypos |= *cp++ << 6;
 233:     tbpos->scount++;
 234: }
 235: 
 236: /*
 237:  * Decode new Hitach 6-byte format (high res).
 238:  */
 239: static
 240: tbhresdecode(cp, tbpos)
 241:     register char *cp;
 242:     register struct tbpos *tbpos;
 243: {
 244:     char byte;
 245: 
 246:     byte = *cp++;
 247:     tbpos->xpos = (byte & 03) << 14;
 248:     tbpos->xpos |= *cp++ << 7;
 249:     tbpos->xpos |= *cp++;
 250:     tbpos->ypos = *cp++ << 14;
 251:     tbpos->ypos |= *cp++ << 7;
 252:     tbpos->ypos |= *cp++;
 253:     tbpos->status = (byte >> 2) | TBINPROX;
 254:     tbpos->scount++;
 255: }
 256: 
 257: /*
 258:  * Polhemus decode.
 259:  */
 260: static
 261: poldecode(cp, polpos)
 262:     register char *cp;
 263:     register struct polpos *polpos;
 264: {
 265: 
 266:     polpos->p_x = cp[4] | cp[3]<<7 | (cp[9] & 0x03) << 14;
 267:     polpos->p_y = cp[6] | cp[5]<<7 | (cp[9] & 0x0c) << 12;
 268:     polpos->p_z = cp[8] | cp[7]<<7 | (cp[9] & 0x30) << 10;
 269:     polpos->p_azi = cp[11] | cp[10]<<7 | (cp[16] & 0x03) << 14;
 270:     polpos->p_pit = cp[13] | cp[12]<<7 | (cp[16] & 0x0c) << 12;
 271:     polpos->p_rol = cp[15] | cp[14]<<7 | (cp[16] & 0x30) << 10;
 272:     polpos->p_stat = cp[1] | cp[0]<<7;
 273:     if (cp[2] != ' ')
 274:         polpos->p_key = cp[2];
 275: }
 276: 
 277: /*ARGSUSED*/
 278: tbioctl(tp, cmd, data, flag)
 279:     struct tty *tp;
 280:     u_int cmd;
 281:     caddr_t data;
 282: {
 283:     register struct tb *tbp = (struct tb *)tp->T_LINEP;
 284: 
 285:     switch (cmd) {
 286: 
 287:     case BIOGMODE:
 288:         *(int *)data = tbp->tbflags & TBMODE;
 289:         break;
 290: 
 291:     case BIOSTYPE:
 292:         if (tbconf[*(int *)data & TBTYPE].tbc_recsize == 0 ||
 293:             tbconf[*(int *)data & TBTYPE].tbc_decode == 0)
 294:             return (EINVAL);
 295:         tbp->tbflags &= ~TBTYPE;
 296:         tbp->tbflags |= *(int *)data & TBTYPE;
 297:         /* fall thru... to set mode bits */
 298: 
 299:     case BIOSMODE: {
 300:         register struct tbconf *tc;
 301: 
 302:         tbp->tbflags &= ~TBMODE;
 303:         tbp->tbflags |= *(int *)data & TBMODE;
 304:         tc = &tbconf[tbp->tbflags & TBTYPE];
 305:         if (tbp->tbflags&TBSTOP) {
 306:             if (tc->tbc_stop)
 307:                 ttyout(tc->tbc_stop, tp);
 308:         } else if (tc->tbc_start)
 309:             ttyout(tc->tbc_start, tp);
 310:         if (tbp->tbflags&TBPOINT) {
 311:             if (tc->tbc_point)
 312:                 ttyout(tc->tbc_point, tp);
 313:         } else if (tc->tbc_run)
 314:             ttyout(tc->tbc_run, tp);
 315:         ttstart(tp);
 316:         break;
 317:     }
 318: 
 319:     case BIOGTYPE:
 320:         *(int *)data = tbp->tbflags & TBTYPE;
 321:         break;
 322: 
 323:     case TIOCSETD:
 324:     case TIOCGETD:
 325:     case TIOCGETP:
 326:     case TIOCGETC:
 327:         return (-1);        /* pass thru... */
 328: 
 329:     default:
 330:         return (ENOTTY);
 331:     }
 332:     return (0);
 333: }
 334: #endif

Defined functions

gtcodecode defined in line 175; used 2 times
poldecode defined in line 260; used 2 times
tbclose defined in line 102; used 2 times
tbdecode defined in line 197; used 3 times
tbhresdecode defined in line 239; used 2 times
tbinput defined in line 148; used 2 times
tbioctl defined in line 278; used 3 times
tblresdecode defined in line 221; used 2 times
tbopen defined in line 76; used 2 times
tbread defined in line 124; used 2 times

Defined variables

tb defined in line 70; used 3 times
tbconf defined in line 46; used 5 times

Defined struct's

tb defined in line 60; used 16 times
tbconf defined in line 30; used 8 times

Defined macros

NTBS defined in line 69; used 3 times
TBF_POL defined in line 40; used 2 times
TBMAXREC defined in line 62; used 1 times
  • in line 63
Last modified: 1994-12-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3030
Valid CSS Valid XHTML 1.0 Strict