1: /*
   2:  * Copyright (c) 1982, 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	7.1 (Berkeley) 6/5/86
   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 "dir.h"
  19: #include "user.h"
  20: #include "tablet.h"
  21: #include "tty.h"
  22: #include "proc.h"
  23: #include "inode.h"
  24: #include "file.h"
  25: #include "buf.h"
  26: #include "uio.h"
  27: 
  28: /*
  29:  * Tablet configuration table.
  30:  */
  31: struct  tbconf {
  32:     short   tbc_recsize;    /* input record size in bytes */
  33:     short   tbc_uiosize;    /* size of data record returned user */
  34:     int tbc_sync;   /* mask for finding sync byte/bit */
  35:     int (*tbc_decode)();/* decoding routine */
  36:     char    *tbc_run;   /* enter run mode sequence */
  37:     char    *tbc_point; /* enter point mode sequence */
  38:     char    *tbc_stop;  /* stop sequence */
  39:     char    *tbc_start; /* start/restart sequence */
  40:     int tbc_flags;
  41: #define TBF_POL 0x1 /* polhemus hack */
  42: };
  43: 
  44: static  int tbdecode(), gtcodecode(), poldecode();
  45: static  int tblresdecode(), tbhresdecode();
  46: 
  47: struct  tbconf tbconf[TBTYPE] = {
  48: { 0 },
  49: { 5, sizeof (struct tbpos), 0200, tbdecode, "6", "4" },
  50: { 5, sizeof (struct tbpos), 0200, tbdecode, "\1CN", "\1RT", "\2", "\4" },
  51: { 8, sizeof (struct gtcopos), 0200, gtcodecode },
  52: {17, sizeof (struct polpos), 0200, poldecode, 0, 0, "\21", "\5\22\2\23",
  53:  TBF_POL },
  54: { 5, sizeof (struct tbpos), 0100, tblresdecode, "\1CN", "\1PT", "\2", "\4"},
  55: { 6, sizeof (struct tbpos), 0200, tbhresdecode, "\1CN", "\1PT", "\2", "\4"},
  56: };
  57: 
  58: /*
  59:  * Tablet state
  60:  */
  61: struct tb {
  62:     int tbflags;        /* mode & type bits */
  63: #define TBMAXREC    17  /* max input record size */
  64:     char    cbuf[TBMAXREC];     /* input buffer */
  65:     union {
  66:         struct  tbpos tbpos;
  67:         struct  gtcopos gtcopos;
  68:         struct  polpos polpos;
  69:     } rets;             /* processed state */
  70: #define NTBS    16
  71: } tb[NTBS];
  72: 
  73: /*
  74:  * Open as tablet discipline; called on discipline change.
  75:  */
  76: /*ARGSUSED*/
  77: tbopen(dev, tp)
  78:     dev_t dev;
  79:     register struct tty *tp;
  80: {
  81:     register struct tb *tbp;
  82: 
  83:     if (tp->t_line == TABLDISC)
  84:         return (ENODEV);
  85:     ttywflush(tp);
  86:     for (tbp = tb; tbp < &tb[NTBS]; tbp++)
  87:         if (tbp->tbflags == 0)
  88:             break;
  89:     if (tbp >= &tb[NTBS])
  90:         return (EBUSY);
  91:     tbp->tbflags = TBTIGER|TBPOINT;     /* default */
  92:     tp->t_cp = tbp->cbuf;
  93:     tp->t_inbuf = 0;
  94:     bzero((caddr_t)&tbp->rets, sizeof (tbp->rets));
  95:     tp->T_LINEP = (caddr_t)tbp;
  96:     tp->t_flags |= LITOUT;
  97:     return (0);
  98: }
  99: 
 100: /*
 101:  * Line discipline change or last device close.
 102:  */
 103: tbclose(tp)
 104:     register struct tty *tp;
 105: {
 106:     register int s;
 107:     int modebits = TBPOINT|TBSTOP;
 108: 
 109:     tbioctl(tp, 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)
 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_READ, 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:     caddr_t data;
 281: {
 282:     register struct tb *tbp = (struct tb *)tp->T_LINEP;
 283: 
 284:     switch (cmd) {
 285: 
 286:     case BIOGMODE:
 287:         *(int *)data = tbp->tbflags & TBMODE;
 288:         break;
 289: 
 290:     case BIOSTYPE:
 291:         if (tbconf[*(int *)data & TBTYPE].tbc_recsize == 0 ||
 292:             tbconf[*(int *)data & TBTYPE].tbc_decode == 0)
 293:             return (EINVAL);
 294:         tbp->tbflags &= ~TBTYPE;
 295:         tbp->tbflags |= *(int *)data & TBTYPE;
 296:         /* fall thru... to set mode bits */
 297: 
 298:     case BIOSMODE: {
 299:         register struct tbconf *tc;
 300: 
 301:         tbp->tbflags &= ~TBMODE;
 302:         tbp->tbflags |= *(int *)data & TBMODE;
 303:         tc = &tbconf[tbp->tbflags & TBTYPE];
 304:         if (tbp->tbflags&TBSTOP) {
 305:             if (tc->tbc_stop)
 306:                 ttyout(tc->tbc_stop, tp);
 307:         } else if (tc->tbc_start)
 308:             ttyout(tc->tbc_start, tp);
 309:         if (tbp->tbflags&TBPOINT) {
 310:             if (tc->tbc_point)
 311:                 ttyout(tc->tbc_point, tp);
 312:         } else if (tc->tbc_run)
 313:             ttyout(tc->tbc_run, tp);
 314:         ttstart(tp);
 315:         break;
 316:     }
 317: 
 318:     case BIOGTYPE:
 319:         *(int *)data = tbp->tbflags & TBTYPE;
 320:         break;
 321: 
 322:     case TIOCSETD:
 323:     case TIOCGETD:
 324:     case TIOCGETP:
 325:     case TIOCGETC:
 326:         return (-1);        /* pass thru... */
 327: 
 328:     default:
 329:         return (ENOTTY);
 330:     }
 331:     return (0);
 332: }
 333: #endif

Defined functions

gtcodecode defined in line 175; used 2 times
poldecode defined in line 260; used 2 times
tbclose defined in line 103; 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 77; used 2 times
tbread defined in line 124; used 2 times

Defined variables

tb defined in line 71; used 3 times
tbconf defined in line 47; used 5 times

Defined struct's

tb defined in line 61; used 16 times
tbconf defined in line 31; used 8 times

Defined macros

NTBS defined in line 70; used 3 times
TBF_POL defined in line 41; used 2 times
TBMAXREC defined in line 63; used 1 times
  • in line 64
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1009
Valid CSS Valid XHTML 1.0 Strict