1*8557Sroot /* tty_tb.c 4.6 82/10/17 */ 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" 107297Ssam #include "../h/tty.h" 117297Ssam #include "../h/proc.h" 127297Ssam #include "../h/inode.h" 137297Ssam #include "../h/file.h" 147297Ssam #include "../h/conf.h" 157297Ssam #include "../h/buf.h" 167732Sroot #include "../h/uio.h" 177297Ssam 187297Ssam /* 197297Ssam * Line discipline for RS232 tablets. 208522Sroot * Supplies binary coordinate data. 217297Ssam * 228522Sroot * FIX WAY IN WHICH OVERLAYING IS DONE 238522Sroot * MAKE TABLET TYPE AN ioctl TO AVOID HAVING ONE DISCIPLINE PER TABLET TYPE. 247297Ssam */ 257297Ssam 267297Ssam #define MTABCHAR 5 277297Ssam #define MNTABCHAR 6 288522Sroot 297297Ssam struct tbposition { 308522Sroot int xpos; 318522Sroot int ypos; 328522Sroot short status; 338522Sroot short scount; 347297Ssam }; 357297Ssam 367297Ssam /* 377297Ssam * Open as tablet discipline. Called when discipline changed 387297Ssam * with ioctl, and changes the interpretation of the information 397297Ssam * in the tty structure. 407297Ssam */ 417297Ssam /*ARGSUSED*/ 427297Ssam tbopen(dev, tp) 437632Ssam dev_t dev; 447632Ssam register struct tty *tp; 457297Ssam { 467297Ssam register struct tbposition *tbp; 477297Ssam 487297Ssam if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) { 49*8557Sroot return (EBUSY); 507297Ssam wflushtty(tp); 517297Ssam tp->t_cp = (char *) &tp->t_un.T_CTLQ; /* overlay control queue */ 527297Ssam tp->t_inbuf = 0; 537297Ssam tbp = (struct tbposition *) &tp->t_rocount; 547297Ssam tbp->xpos = tbp->ypos = tbp->status = tbp->scount = 0; 55*8557Sroot return (0); 567297Ssam } 577297Ssam 587297Ssam /* 597297Ssam * Break down... called when discipline changed or from device 607297Ssam * close routine. 617297Ssam */ 627297Ssam tbclose(tp) 63*8557Sroot register struct tty *tp; 647297Ssam { 65*8557Sroot register int s = spl5(); 667297Ssam 677297Ssam tp->t_cp = 0; 687297Ssam tp->t_inbuf = 0; 697297Ssam tp->t_rawq.c_cc = 0; /* clear queues -- paranoid */ 707297Ssam tp->t_canq.c_cc = 0; 717297Ssam tp->t_un.T_CTLQ.c_cc = 0; /* clear overlaid queue status */ 727297Ssam tp->t_un.T_CTLQ.c_cf = tp->t_un.T_CTLQ.c_cl = NULL; 737297Ssam tp->t_line = 0; /* paranoid: avoid races */ 747297Ssam splx(s); 757297Ssam } 767297Ssam 777297Ssam /* 787297Ssam * Read from a tablet line. 797297Ssam * Characters have been buffered in a buffer and 807297Ssam * decoded. The coordinates are now sluffed back to the user. 817297Ssam */ 827732Sroot tbread(tp, uio) 837732Sroot register struct tty *tp; 847732Sroot struct uio *uio; 857297Ssam { 867297Ssam register int i; 877297Ssam register s; 887297Ssam struct tbposition tbposition; 897297Ssam 907297Ssam if ((tp->t_state&TS_CARR_ON)==0) 918522Sroot return (EIO); 928522Sroot return (iomove(&tp->t_rocount, sizeof tbposition, UIO_READ, uio)); 937297Ssam } 947297Ssam 957297Ssam /* 967297Ssam * Low level character input routine. 977297Ssam * Stuff the character in the buffer, and decode the it 987297Ssam * if all the chars are there. 997297Ssam * 1007297Ssam * This routine could be expanded in-line in the receiver 1017297Ssam * interrupt routine of the dh-11 to make it run as fast as possible. 1027297Ssam */ 1038522Sroot int LASTTABC; 1048522Sroot 1057297Ssam tbinput(c, tp) 1068522Sroot register int c; 1078522Sroot register struct tty *tp; 1087297Ssam { 1097297Ssam 1108522Sroot if (tp->t_line == TABLDISC) { 1118522Sroot if ((c&0200) || (tp->t_inbuf == MTABCHAR)) { 1127297Ssam tp->t_cp = (char *) &tp->t_un.T_CTLQ; 1137297Ssam tp->t_inbuf = 0; 1147297Ssam } 1157297Ssam *tp->t_cp++ = c&0177; 1168522Sroot if (++tp->t_inbuf == MTABCHAR) 1177297Ssam tbdecode((char *) &tp->t_un.T_CTLQ, 1188522Sroot (struct tbposition *) &tp->t_rocount); 1198522Sroot } else if (tp->t_line == NTABLDISC) { 1208522Sroot if ((c&0200) || (tp->t_inbuf == MNTABCHAR)) { 1217297Ssam tp->t_cp = (char *) &tp->t_un.T_CTLQ; 1227297Ssam tp->t_inbuf = 0; 1237297Ssam } 1247297Ssam *tp->t_cp++ = c&0177; 1258522Sroot if (++tp->t_inbuf == MNTABCHAR) 1267297Ssam tbndecode((char *) &tp->t_un.T_CTLQ, 1277297Ssam (struct tbposition *) &tp->t_rocount); 1287297Ssam } 1297297Ssam } 1307297Ssam 1317297Ssam /* 1327297Ssam * Decode tablet coordinates from ascii to binary. 1337297Ssam * (gtco 6 character format) 1347297Ssam */ 1357297Ssam tbndecode(cp, tbposition) 1367297Ssam register char *cp; 1377297Ssam register struct tbposition *tbposition; 1387297Ssam { 1397297Ssam 1407297Ssam tbposition->status = *cp>>2; /* this needs to be decoded */ 1417297Ssam tbposition->xpos = ((*cp++)&03)<<14; 1427297Ssam tbposition->xpos |= (*cp++)<<7; 1437297Ssam tbposition->xpos |= (*cp++); 1447297Ssam tbposition->ypos = ((*cp++)&03)<<14; 1457297Ssam tbposition->ypos |= (*cp++)<<7; 1467297Ssam tbposition->ypos |= (*cp++); 1477297Ssam tbposition->scount++; 1487297Ssam } 1497297Ssam 1507297Ssam /* 1517297Ssam * Decode tablet coordinates from ascii to binary. 1527297Ssam * (hitachi 5 character format) 1537297Ssam */ 1547297Ssam tbdecode(cp, tbposition) 1557297Ssam register char *cp; 1567297Ssam register struct tbposition *tbposition; 1577297Ssam { 1587297Ssam register int status; 1597297Ssam register char byte; 1607297Ssam 1617297Ssam byte = *cp++; 1627297Ssam status = (byte&0100) ? 0100000 : 0; 1637297Ssam byte &= ~0100; 1648522Sroot if (byte > 036) 1657297Ssam status |= 1<<((byte-040)/2); 1667297Ssam tbposition->xpos = (*cp++)<<7; 1677297Ssam tbposition->xpos |= (*cp++); 1688522Sroot if (tbposition->xpos < 256) /* tablet wraps around at 256 */ 1697297Ssam status &= 077777; /* make it out of proximity */ 1707297Ssam tbposition->ypos = (*cp++)<<7; 1717297Ssam tbposition->ypos |= (*cp++); 1727297Ssam tbposition->status = status; 1737297Ssam tbposition->scount++; 1747297Ssam } 1757297Ssam 1767297Ssam /* 1777297Ssam * This routine is called whenever a ioctl is about to be performed 1787297Ssam * and gets a chance to reject the ioctl. We reject all teletype 1797297Ssam * oriented ioctl's except those which set the discipline, and 1807297Ssam * those which get parameters (gtty and get special characters). 1817297Ssam */ 1827297Ssam /*ARGSUSED*/ 1837632Ssam tbioctl(tp, cmd, data, flag) 1847632Ssam struct tty *tp; 1857632Ssam caddr_t data; 1867297Ssam { 1877297Ssam 1887297Ssam if ((cmd>>8) != 't') 1897297Ssam return (cmd); 1907297Ssam switch (cmd) { 1917297Ssam 1927297Ssam case TIOCSETD: 1937297Ssam case TIOCGETD: 1947297Ssam case TIOCGETP: 1957297Ssam case TIOCGETC: 1967297Ssam return (cmd); 1977297Ssam } 1987297Ssam u.u_error = ENOTTY; 1997297Ssam return (0); 2007297Ssam } 2017297Ssam #endif 202