1*14596Ssam /* tty_tb.c 4.9 83/08/13 */ 27297Ssam 37297Ssam #include "tb.h" 47297Ssam #if NTB > 0 57297Ssam 67297Ssam #include "../h/param.h" 77297Ssam #include "../h/systm.h" 87297Ssam #include "../h/dir.h" 97297Ssam #include "../h/user.h" 109562Ssam #include "../h/ioctl.h" 117297Ssam #include "../h/tty.h" 127297Ssam #include "../h/proc.h" 137297Ssam #include "../h/inode.h" 147297Ssam #include "../h/file.h" 157297Ssam #include "../h/conf.h" 167297Ssam #include "../h/buf.h" 177732Sroot #include "../h/uio.h" 187297Ssam 197297Ssam /* 207297Ssam * Line discipline for RS232 tablets. 218522Sroot * Supplies binary coordinate data. 227297Ssam * 238522Sroot * MAKE TABLET TYPE AN ioctl TO AVOID HAVING ONE DISCIPLINE PER TABLET TYPE. 247297Ssam */ 257297Ssam 26*14596Ssam #define NTBS (16) 27*14596Ssam #define MALLTABCHAR (8) 28*14596Ssam #define MTABCHAR (5) 29*14596Ssam #define MNTABCHAR (6) 308522Sroot 31*14596Ssam struct tb { 32*14596Ssam short used; 33*14596Ssam char cbuf[MALLTABCHAR]; 34*14596Ssam struct tbpos { 35*14596Ssam int xpos; 36*14596Ssam int ypos; 37*14596Ssam short status; 38*14596Ssam short scount; 39*14596Ssam } tbpos; 40*14596Ssam } tb[NTBS]; 417297Ssam 427297Ssam /* 437297Ssam * Open as tablet discipline. Called when discipline changed 447297Ssam * with ioctl, and changes the interpretation of the information 457297Ssam * in the tty structure. 467297Ssam */ 477297Ssam /*ARGSUSED*/ 487297Ssam tbopen(dev, tp) 497632Ssam dev_t dev; 507632Ssam register struct tty *tp; 517297Ssam { 52*14596Ssam register struct tb *tbp; 537297Ssam 54*14596Ssam if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) 55*14596Ssam return (ENODEV); 56*14596Ssam ttywflush(tp); 57*14596Ssam for (tbp = tb; tbp < &tb[NTBS]; tbp++) 58*14596Ssam if (!tbp->used) 59*14596Ssam break; 60*14596Ssam if (tbp >= &tb[NTBS]) 618557Sroot return (EBUSY); 62*14596Ssam tbp->used++; 63*14596Ssam tp->t_cp = tbp->cbuf; 647297Ssam tp->t_inbuf = 0; 65*14596Ssam tbp->tbpos.xpos = tbp->tbpos.ypos = 0; 66*14596Ssam tbp->tbpos.status = tbp->tbpos.scount = 0; 67*14596Ssam tp->T_LINEP = (caddr_t) tbp; 688557Sroot return (0); 697297Ssam } 707297Ssam 717297Ssam /* 727297Ssam * Break down... called when discipline changed or from device 737297Ssam * close routine. 747297Ssam */ 757297Ssam tbclose(tp) 768557Sroot register struct tty *tp; 777297Ssam { 788557Sroot register int s = spl5(); 797297Ssam 807297Ssam tp->t_cp = 0; 817297Ssam tp->t_inbuf = 0; 827297Ssam tp->t_rawq.c_cc = 0; /* clear queues -- paranoid */ 837297Ssam tp->t_canq.c_cc = 0; 847297Ssam tp->t_line = 0; /* paranoid: avoid races */ 857297Ssam splx(s); 867297Ssam } 877297Ssam 887297Ssam /* 897297Ssam * Read from a tablet line. 907297Ssam * Characters have been buffered in a buffer and 917297Ssam * decoded. The coordinates are now sluffed back to the user. 927297Ssam */ 937732Sroot tbread(tp, uio) 947732Sroot register struct tty *tp; 957732Sroot struct uio *uio; 967297Ssam { 977297Ssam register int i; 987297Ssam register s; 99*14596Ssam struct tbpos *tbpos; 1007297Ssam 1017297Ssam if ((tp->t_state&TS_CARR_ON)==0) 1028522Sroot return (EIO); 103*14596Ssam tbpos = &(((struct tb *) (tp->T_LINEP))->tbpos); 104*14596Ssam return (uiomove(tbpos, sizeof *tbpos, UIO_READ, uio)); 1057297Ssam } 1067297Ssam 1077297Ssam /* 1087297Ssam * Low level character input routine. 1097297Ssam * Stuff the character in the buffer, and decode the it 1107297Ssam * if all the chars are there. 1117297Ssam * 1127297Ssam * This routine could be expanded in-line in the receiver 1137297Ssam * interrupt routine of the dh-11 to make it run as fast as possible. 1147297Ssam */ 1158522Sroot int LASTTABC; 1168522Sroot 1177297Ssam tbinput(c, tp) 1188522Sroot register int c; 1198522Sroot register struct tty *tp; 1207297Ssam { 121*14596Ssam register struct tb *tbp = (struct tb *) tp->T_LINEP; 1227297Ssam 1238522Sroot if (tp->t_line == TABLDISC) { 1248522Sroot if ((c&0200) || (tp->t_inbuf == MTABCHAR)) { 125*14596Ssam tp->t_cp = tbp->cbuf; 1267297Ssam tp->t_inbuf = 0; 1277297Ssam } 1287297Ssam *tp->t_cp++ = c&0177; 1298522Sroot if (++tp->t_inbuf == MTABCHAR) 130*14596Ssam tbdecode(tbp->cbuf, &tbp->tbpos); 1318522Sroot } else if (tp->t_line == NTABLDISC) { 1328522Sroot if ((c&0200) || (tp->t_inbuf == MNTABCHAR)) { 133*14596Ssam tp->t_cp = tbp->cbuf; 1347297Ssam tp->t_inbuf = 0; 1357297Ssam } 1367297Ssam *tp->t_cp++ = c&0177; 1378522Sroot if (++tp->t_inbuf == MNTABCHAR) 138*14596Ssam tbndecode(tbp->cbuf, &tbp->tbpos); 1397297Ssam } 1407297Ssam } 1417297Ssam 1427297Ssam /* 1437297Ssam * Decode tablet coordinates from ascii to binary. 1447297Ssam * (gtco 6 character format) 1457297Ssam */ 146*14596Ssam tbndecode(cp, tbpos) 1477297Ssam register char *cp; 148*14596Ssam register struct tbpos *tbpos; 1497297Ssam { 1507297Ssam 151*14596Ssam tbpos->status = *cp>>2; /* this needs to be decoded */ 152*14596Ssam tbpos->xpos = ((*cp++)&03)<<14; 153*14596Ssam tbpos->xpos |= (*cp++)<<7; 154*14596Ssam tbpos->xpos |= (*cp++); 155*14596Ssam tbpos->ypos = ((*cp++)&03)<<14; 156*14596Ssam tbpos->ypos |= (*cp++)<<7; 157*14596Ssam tbpos->ypos |= (*cp++); 158*14596Ssam tbpos->scount++; 1597297Ssam } 1607297Ssam 1617297Ssam /* 1627297Ssam * Decode tablet coordinates from ascii to binary. 1637297Ssam * (hitachi 5 character format) 1647297Ssam */ 165*14596Ssam tbdecode(cp, tbpos) 1667297Ssam register char *cp; 167*14596Ssam register struct tbpos *tbpos; 1687297Ssam { 1697297Ssam register int status; 1707297Ssam register char byte; 1717297Ssam 1727297Ssam byte = *cp++; 1737297Ssam status = (byte&0100) ? 0100000 : 0; 1747297Ssam byte &= ~0100; 1758522Sroot if (byte > 036) 1767297Ssam status |= 1<<((byte-040)/2); 177*14596Ssam tbpos->xpos = (*cp++)<<7; 178*14596Ssam tbpos->xpos |= (*cp++); 179*14596Ssam if (tbpos->xpos < 256) /* tablet wraps around at 256 */ 1807297Ssam status &= 077777; /* make it out of proximity */ 181*14596Ssam tbpos->ypos = (*cp++)<<7; 182*14596Ssam tbpos->ypos |= (*cp++); 183*14596Ssam tbpos->status = status; 184*14596Ssam tbpos->scount++; 1857297Ssam } 1867297Ssam 1877297Ssam /* 1887297Ssam * This routine is called whenever a ioctl is about to be performed 1897297Ssam * and gets a chance to reject the ioctl. We reject all teletype 1907297Ssam * oriented ioctl's except those which set the discipline, and 1917297Ssam * those which get parameters (gtty and get special characters). 1927297Ssam */ 1937297Ssam /*ARGSUSED*/ 1947632Ssam tbioctl(tp, cmd, data, flag) 1957632Ssam struct tty *tp; 1967632Ssam caddr_t data; 1977297Ssam { 1987297Ssam 1997297Ssam if ((cmd>>8) != 't') 2007297Ssam return (cmd); 2017297Ssam switch (cmd) { 2027297Ssam 2037297Ssam case TIOCSETD: 2047297Ssam case TIOCGETD: 2057297Ssam case TIOCGETP: 2067297Ssam case TIOCGETC: 2077297Ssam return (cmd); 2087297Ssam } 2097297Ssam u.u_error = ENOTTY; 2107297Ssam return (0); 2117297Ssam } 2127297Ssam #endif 213