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