xref: /csrg-svn/sys/kern/tty_tb.c (revision 14596)
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