1*15044Smckusick /* tty_tb.c 6.2 83/09/22 */ 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 2614596Ssam #define NTBS (16) 2714596Ssam #define MALLTABCHAR (8) 2814596Ssam #define MTABCHAR (5) 2914596Ssam #define MNTABCHAR (6) 308522Sroot 3114596Ssam struct tb { 3214596Ssam short used; 3314596Ssam char cbuf[MALLTABCHAR]; 3414596Ssam struct tbpos { 3514596Ssam int xpos; 3614596Ssam int ypos; 3714596Ssam short status; 3814596Ssam short scount; 3914596Ssam } tbpos; 4014596Ssam } 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 { 5214596Ssam register struct tb *tbp; 537297Ssam 5414596Ssam if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) 5514596Ssam return (ENODEV); 5614596Ssam ttywflush(tp); 5714596Ssam for (tbp = tb; tbp < &tb[NTBS]; tbp++) 5814596Ssam if (!tbp->used) 5914596Ssam break; 6014596Ssam if (tbp >= &tb[NTBS]) 618557Sroot return (EBUSY); 6214596Ssam tbp->used++; 6314596Ssam tp->t_cp = tbp->cbuf; 647297Ssam tp->t_inbuf = 0; 6514596Ssam tbp->tbpos.xpos = tbp->tbpos.ypos = 0; 6614596Ssam tbp->tbpos.status = tbp->tbpos.scount = 0; 6714596Ssam 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 80*15044Smckusick ((struct tb *) tp->T_LINEP)->used = 0; 817297Ssam tp->t_cp = 0; 827297Ssam tp->t_inbuf = 0; 837297Ssam tp->t_rawq.c_cc = 0; /* clear queues -- paranoid */ 847297Ssam tp->t_canq.c_cc = 0; 85*15044Smckusick tp->t_line = 0; /* paranoid: avoid races */ 867297Ssam splx(s); 877297Ssam } 887297Ssam 897297Ssam /* 907297Ssam * Read from a tablet line. 917297Ssam * Characters have been buffered in a buffer and 927297Ssam * decoded. The coordinates are now sluffed back to the user. 937297Ssam */ 947732Sroot tbread(tp, uio) 957732Sroot register struct tty *tp; 967732Sroot struct uio *uio; 977297Ssam { 9814596Ssam struct tbpos *tbpos; 997297Ssam 1007297Ssam if ((tp->t_state&TS_CARR_ON)==0) 1018522Sroot return (EIO); 10214596Ssam tbpos = &(((struct tb *) (tp->T_LINEP))->tbpos); 10314596Ssam return (uiomove(tbpos, sizeof *tbpos, UIO_READ, uio)); 1047297Ssam } 1057297Ssam 1067297Ssam /* 1077297Ssam * Low level character input routine. 1087297Ssam * Stuff the character in the buffer, and decode the it 1097297Ssam * if all the chars are there. 1107297Ssam * 1117297Ssam * This routine could be expanded in-line in the receiver 1127297Ssam * interrupt routine of the dh-11 to make it run as fast as possible. 1137297Ssam */ 1148522Sroot int LASTTABC; 1158522Sroot 1167297Ssam tbinput(c, tp) 1178522Sroot register int c; 1188522Sroot register struct tty *tp; 1197297Ssam { 12014596Ssam register struct tb *tbp = (struct tb *) tp->T_LINEP; 1217297Ssam 1228522Sroot if (tp->t_line == TABLDISC) { 1238522Sroot if ((c&0200) || (tp->t_inbuf == MTABCHAR)) { 12414596Ssam tp->t_cp = tbp->cbuf; 1257297Ssam tp->t_inbuf = 0; 1267297Ssam } 1277297Ssam *tp->t_cp++ = c&0177; 1288522Sroot if (++tp->t_inbuf == MTABCHAR) 12914596Ssam tbdecode(tbp->cbuf, &tbp->tbpos); 1308522Sroot } else if (tp->t_line == NTABLDISC) { 1318522Sroot if ((c&0200) || (tp->t_inbuf == MNTABCHAR)) { 13214596Ssam tp->t_cp = tbp->cbuf; 1337297Ssam tp->t_inbuf = 0; 1347297Ssam } 1357297Ssam *tp->t_cp++ = c&0177; 1368522Sroot if (++tp->t_inbuf == MNTABCHAR) 13714596Ssam tbndecode(tbp->cbuf, &tbp->tbpos); 1387297Ssam } 1397297Ssam } 1407297Ssam 1417297Ssam /* 1427297Ssam * Decode tablet coordinates from ascii to binary. 1437297Ssam * (gtco 6 character format) 1447297Ssam */ 14514596Ssam tbndecode(cp, tbpos) 1467297Ssam register char *cp; 14714596Ssam register struct tbpos *tbpos; 1487297Ssam { 1497297Ssam 15014596Ssam tbpos->status = *cp>>2; /* this needs to be decoded */ 15114596Ssam tbpos->xpos = ((*cp++)&03)<<14; 15214596Ssam tbpos->xpos |= (*cp++)<<7; 15314596Ssam tbpos->xpos |= (*cp++); 15414596Ssam tbpos->ypos = ((*cp++)&03)<<14; 15514596Ssam tbpos->ypos |= (*cp++)<<7; 15614596Ssam tbpos->ypos |= (*cp++); 15714596Ssam tbpos->scount++; 1587297Ssam } 1597297Ssam 1607297Ssam /* 1617297Ssam * Decode tablet coordinates from ascii to binary. 1627297Ssam * (hitachi 5 character format) 1637297Ssam */ 16414596Ssam tbdecode(cp, tbpos) 1657297Ssam register char *cp; 16614596Ssam register struct tbpos *tbpos; 1677297Ssam { 1687297Ssam register int status; 1697297Ssam register char byte; 1707297Ssam 1717297Ssam byte = *cp++; 1727297Ssam status = (byte&0100) ? 0100000 : 0; 1737297Ssam byte &= ~0100; 1748522Sroot if (byte > 036) 1757297Ssam status |= 1<<((byte-040)/2); 17614596Ssam tbpos->xpos = (*cp++)<<7; 17714596Ssam tbpos->xpos |= (*cp++); 17814596Ssam if (tbpos->xpos < 256) /* tablet wraps around at 256 */ 1797297Ssam status &= 077777; /* make it out of proximity */ 18014596Ssam tbpos->ypos = (*cp++)<<7; 18114596Ssam tbpos->ypos |= (*cp++); 18214596Ssam tbpos->status = status; 18314596Ssam tbpos->scount++; 1847297Ssam } 1857297Ssam 1867297Ssam /* 1877297Ssam * This routine is called whenever a ioctl is about to be performed 1887297Ssam * and gets a chance to reject the ioctl. We reject all teletype 1897297Ssam * oriented ioctl's except those which set the discipline, and 1907297Ssam * those which get parameters (gtty and get special characters). 1917297Ssam */ 1927297Ssam /*ARGSUSED*/ 1937632Ssam tbioctl(tp, cmd, data, flag) 1947632Ssam struct tty *tp; 1957632Ssam caddr_t data; 1967297Ssam { 1977297Ssam 1987297Ssam if ((cmd>>8) != 't') 1997297Ssam return (cmd); 2007297Ssam switch (cmd) { 2017297Ssam 2027297Ssam case TIOCSETD: 2037297Ssam case TIOCGETD: 2047297Ssam case TIOCGETP: 2057297Ssam case TIOCGETC: 2067297Ssam return (cmd); 2077297Ssam } 2087297Ssam u.u_error = ENOTTY; 2097297Ssam return (0); 2107297Ssam } 2117297Ssam #endif 212