1*9562Ssam /* tty_tb.c 4.7 82/12/05 */ 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" 10*9562Ssam #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 * FIX WAY IN WHICH OVERLAYING IS DONE 248522Sroot * MAKE TABLET TYPE AN ioctl TO AVOID HAVING ONE DISCIPLINE PER TABLET TYPE. 257297Ssam */ 267297Ssam 277297Ssam #define MTABCHAR 5 287297Ssam #define MNTABCHAR 6 298522Sroot 307297Ssam struct tbposition { 318522Sroot int xpos; 328522Sroot int ypos; 338522Sroot short status; 348522Sroot short scount; 357297Ssam }; 367297Ssam 377297Ssam /* 387297Ssam * Open as tablet discipline. Called when discipline changed 397297Ssam * with ioctl, and changes the interpretation of the information 407297Ssam * in the tty structure. 417297Ssam */ 427297Ssam /*ARGSUSED*/ 437297Ssam tbopen(dev, tp) 447632Ssam dev_t dev; 457632Ssam register struct tty *tp; 467297Ssam { 477297Ssam register struct tbposition *tbp; 487297Ssam 497297Ssam if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) { 508557Sroot return (EBUSY); 517297Ssam wflushtty(tp); 527297Ssam tp->t_cp = (char *) &tp->t_un.T_CTLQ; /* overlay control queue */ 537297Ssam tp->t_inbuf = 0; 547297Ssam tbp = (struct tbposition *) &tp->t_rocount; 557297Ssam tbp->xpos = tbp->ypos = tbp->status = tbp->scount = 0; 568557Sroot return (0); 577297Ssam } 587297Ssam 597297Ssam /* 607297Ssam * Break down... called when discipline changed or from device 617297Ssam * close routine. 627297Ssam */ 637297Ssam tbclose(tp) 648557Sroot register struct tty *tp; 657297Ssam { 668557Sroot register int s = spl5(); 677297Ssam 687297Ssam tp->t_cp = 0; 697297Ssam tp->t_inbuf = 0; 707297Ssam tp->t_rawq.c_cc = 0; /* clear queues -- paranoid */ 717297Ssam tp->t_canq.c_cc = 0; 727297Ssam tp->t_un.T_CTLQ.c_cc = 0; /* clear overlaid queue status */ 737297Ssam tp->t_un.T_CTLQ.c_cf = tp->t_un.T_CTLQ.c_cl = NULL; 747297Ssam tp->t_line = 0; /* paranoid: avoid races */ 757297Ssam splx(s); 767297Ssam } 777297Ssam 787297Ssam /* 797297Ssam * Read from a tablet line. 807297Ssam * Characters have been buffered in a buffer and 817297Ssam * decoded. The coordinates are now sluffed back to the user. 827297Ssam */ 837732Sroot tbread(tp, uio) 847732Sroot register struct tty *tp; 857732Sroot struct uio *uio; 867297Ssam { 877297Ssam register int i; 887297Ssam register s; 897297Ssam struct tbposition tbposition; 907297Ssam 917297Ssam if ((tp->t_state&TS_CARR_ON)==0) 928522Sroot return (EIO); 938522Sroot return (iomove(&tp->t_rocount, sizeof tbposition, UIO_READ, uio)); 947297Ssam } 957297Ssam 967297Ssam /* 977297Ssam * Low level character input routine. 987297Ssam * Stuff the character in the buffer, and decode the it 997297Ssam * if all the chars are there. 1007297Ssam * 1017297Ssam * This routine could be expanded in-line in the receiver 1027297Ssam * interrupt routine of the dh-11 to make it run as fast as possible. 1037297Ssam */ 1048522Sroot int LASTTABC; 1058522Sroot 1067297Ssam tbinput(c, tp) 1078522Sroot register int c; 1088522Sroot register struct tty *tp; 1097297Ssam { 1107297Ssam 1118522Sroot if (tp->t_line == TABLDISC) { 1128522Sroot if ((c&0200) || (tp->t_inbuf == MTABCHAR)) { 1137297Ssam tp->t_cp = (char *) &tp->t_un.T_CTLQ; 1147297Ssam tp->t_inbuf = 0; 1157297Ssam } 1167297Ssam *tp->t_cp++ = c&0177; 1178522Sroot if (++tp->t_inbuf == MTABCHAR) 1187297Ssam tbdecode((char *) &tp->t_un.T_CTLQ, 1198522Sroot (struct tbposition *) &tp->t_rocount); 1208522Sroot } else if (tp->t_line == NTABLDISC) { 1218522Sroot if ((c&0200) || (tp->t_inbuf == MNTABCHAR)) { 1227297Ssam tp->t_cp = (char *) &tp->t_un.T_CTLQ; 1237297Ssam tp->t_inbuf = 0; 1247297Ssam } 1257297Ssam *tp->t_cp++ = c&0177; 1268522Sroot if (++tp->t_inbuf == MNTABCHAR) 1277297Ssam tbndecode((char *) &tp->t_un.T_CTLQ, 1287297Ssam (struct tbposition *) &tp->t_rocount); 1297297Ssam } 1307297Ssam } 1317297Ssam 1327297Ssam /* 1337297Ssam * Decode tablet coordinates from ascii to binary. 1347297Ssam * (gtco 6 character format) 1357297Ssam */ 1367297Ssam tbndecode(cp, tbposition) 1377297Ssam register char *cp; 1387297Ssam register struct tbposition *tbposition; 1397297Ssam { 1407297Ssam 1417297Ssam tbposition->status = *cp>>2; /* this needs to be decoded */ 1427297Ssam tbposition->xpos = ((*cp++)&03)<<14; 1437297Ssam tbposition->xpos |= (*cp++)<<7; 1447297Ssam tbposition->xpos |= (*cp++); 1457297Ssam tbposition->ypos = ((*cp++)&03)<<14; 1467297Ssam tbposition->ypos |= (*cp++)<<7; 1477297Ssam tbposition->ypos |= (*cp++); 1487297Ssam tbposition->scount++; 1497297Ssam } 1507297Ssam 1517297Ssam /* 1527297Ssam * Decode tablet coordinates from ascii to binary. 1537297Ssam * (hitachi 5 character format) 1547297Ssam */ 1557297Ssam tbdecode(cp, tbposition) 1567297Ssam register char *cp; 1577297Ssam register struct tbposition *tbposition; 1587297Ssam { 1597297Ssam register int status; 1607297Ssam register char byte; 1617297Ssam 1627297Ssam byte = *cp++; 1637297Ssam status = (byte&0100) ? 0100000 : 0; 1647297Ssam byte &= ~0100; 1658522Sroot if (byte > 036) 1667297Ssam status |= 1<<((byte-040)/2); 1677297Ssam tbposition->xpos = (*cp++)<<7; 1687297Ssam tbposition->xpos |= (*cp++); 1698522Sroot if (tbposition->xpos < 256) /* tablet wraps around at 256 */ 1707297Ssam status &= 077777; /* make it out of proximity */ 1717297Ssam tbposition->ypos = (*cp++)<<7; 1727297Ssam tbposition->ypos |= (*cp++); 1737297Ssam tbposition->status = status; 1747297Ssam tbposition->scount++; 1757297Ssam } 1767297Ssam 1777297Ssam /* 1787297Ssam * This routine is called whenever a ioctl is about to be performed 1797297Ssam * and gets a chance to reject the ioctl. We reject all teletype 1807297Ssam * oriented ioctl's except those which set the discipline, and 1817297Ssam * those which get parameters (gtty and get special characters). 1827297Ssam */ 1837297Ssam /*ARGSUSED*/ 1847632Ssam tbioctl(tp, cmd, data, flag) 1857632Ssam struct tty *tp; 1867632Ssam caddr_t data; 1877297Ssam { 1887297Ssam 1897297Ssam if ((cmd>>8) != 't') 1907297Ssam return (cmd); 1917297Ssam switch (cmd) { 1927297Ssam 1937297Ssam case TIOCSETD: 1947297Ssam case TIOCGETD: 1957297Ssam case TIOCGETP: 1967297Ssam case TIOCGETC: 1977297Ssam return (cmd); 1987297Ssam } 1997297Ssam u.u_error = ENOTTY; 2007297Ssam return (0); 2017297Ssam } 2027297Ssam #endif 203