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