xref: /csrg-svn/sys/kern/tty_tb.c (revision 8522)
1 /*	tty_tb.c	4.5	82/10/13	*/
2 
3 #include "tb.h"
4 #if NTB > 0
5 
6 #include "../h/param.h"
7 #include "../h/systm.h"
8 #include "../h/dir.h"
9 #include "../h/user.h"
10 #include "../h/tty.h"
11 #include "../h/proc.h"
12 #include "../h/inode.h"
13 #include "../h/file.h"
14 #include "../h/conf.h"
15 #include "../h/buf.h"
16 #include "../h/uio.h"
17 
18 /*
19  * Line discipline for RS232 tablets.
20  * Supplies binary coordinate data.
21  *
22  * FIX WAY IN WHICH OVERLAYING IS DONE
23  * MAKE TABLET TYPE AN ioctl TO AVOID HAVING ONE DISCIPLINE PER TABLET TYPE.
24  */
25 
26 #define MTABCHAR 5
27 #define MNTABCHAR 6
28 
29 struct tbposition {
30 	int	xpos;
31 	int	ypos;
32 	short	status;
33 	short	scount;
34 };
35 
36 /*
37  * Open as tablet discipline.  Called when discipline changed
38  * with ioctl, and changes the interpretation of the information
39  * in the tty structure.
40  */
41 /*ARGSUSED*/
42 tbopen(dev, tp)
43 	dev_t dev;
44 	register struct tty *tp;
45 {
46 	register struct tbposition *tbp;
47 
48 	if (u.u_error)
49 		return;		/* paranoia */
50 	if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) {
51 		u.u_error = EBUSY;
52 		return;
53 	}
54 	wflushtty(tp);
55 	tp->t_cp = (char *) &tp->t_un.T_CTLQ;	/* overlay control queue */
56 	tp->t_inbuf = 0;
57 	tbp = (struct tbposition *) &tp->t_rocount;
58 	tbp->xpos = tbp->ypos = tbp->status = tbp->scount = 0;
59 }
60 
61 /*
62  * Break down... called when discipline changed or from device
63  * close routine.
64  */
65 tbclose(tp)
66 register struct tty *tp;
67 {
68 	register s;
69 
70 	s = spl5();
71 	tp->t_cp = 0;
72 	tp->t_inbuf = 0;
73 	tp->t_rawq.c_cc = 0;		/* clear queues -- paranoid */
74 	tp->t_canq.c_cc = 0;
75 	tp->t_un.T_CTLQ.c_cc = 0;	/* clear overlaid queue status */
76 	tp->t_un.T_CTLQ.c_cf = tp->t_un.T_CTLQ.c_cl = NULL;
77 	tp->t_line = 0;		/* paranoid: avoid races */
78 	splx(s);
79 }
80 
81 /*
82  * Read from a tablet line.
83  * Characters have been buffered in a buffer and
84  * decoded. The coordinates are now sluffed back to the user.
85  */
86 tbread(tp, uio)
87 	register struct tty *tp;
88 	struct uio *uio;
89 {
90 	register int i;
91 	register s;
92 	struct tbposition tbposition;
93 
94 	if ((tp->t_state&TS_CARR_ON)==0)
95 		return (EIO);
96 	return (iomove(&tp->t_rocount, sizeof tbposition, UIO_READ, uio));
97 }
98 
99 /*
100  * Low level character input routine.
101  * Stuff the character in the buffer, and decode the it
102  * if all the chars are there.
103  *
104  * This routine could be expanded in-line in the receiver
105  * interrupt routine of the dh-11 to make it run as fast as possible.
106  */
107 int	LASTTABC;
108 
109 tbinput(c, tp)
110 	register int c;
111 	register struct tty *tp;
112 {
113 
114 	if (tp->t_line == TABLDISC) {
115 		if ((c&0200) || (tp->t_inbuf == MTABCHAR)) {
116 			tp->t_cp = (char *) &tp->t_un.T_CTLQ;
117 			tp->t_inbuf = 0;
118 		}
119 		*tp->t_cp++ = c&0177;
120 		if (++tp->t_inbuf == MTABCHAR)
121 			tbdecode((char *) &tp->t_un.T_CTLQ,
122 				(struct tbposition *) &tp->t_rocount);
123 	} else if (tp->t_line == NTABLDISC) {
124 		if ((c&0200) || (tp->t_inbuf == MNTABCHAR)) {
125 			tp->t_cp = (char *) &tp->t_un.T_CTLQ;
126 			tp->t_inbuf = 0;
127 		}
128 		*tp->t_cp++ = c&0177;
129 		if (++tp->t_inbuf == MNTABCHAR)
130 			tbndecode((char *) &tp->t_un.T_CTLQ,
131 					(struct tbposition *) &tp->t_rocount);
132 	}
133 }
134 
135 /*
136  * Decode tablet coordinates from ascii to binary.
137  *	(gtco 6 character format)
138  */
139 tbndecode(cp, tbposition)
140 	register char *cp;
141 	register struct tbposition *tbposition;
142 {
143 
144 	tbposition->status = *cp>>2;	/* this needs to be decoded */
145 	tbposition->xpos = ((*cp++)&03)<<14;
146 	tbposition->xpos |= (*cp++)<<7;
147 	tbposition->xpos |= (*cp++);
148 	tbposition->ypos = ((*cp++)&03)<<14;
149 	tbposition->ypos |= (*cp++)<<7;
150 	tbposition->ypos |= (*cp++);
151 	tbposition->scount++;
152 }
153 
154 /*
155  * Decode tablet coordinates from ascii to binary.
156  *	(hitachi 5 character format)
157  */
158 tbdecode(cp, tbposition)
159 	register char *cp;
160 	register struct tbposition *tbposition;
161 {
162 	register int status;
163 	register char byte;
164 
165 	byte = *cp++;
166 	status = (byte&0100) ? 0100000 : 0;
167 	byte &= ~0100;
168 	if (byte > 036)
169 		status |= 1<<((byte-040)/2);
170 	tbposition->xpos = (*cp++)<<7;
171 	tbposition->xpos |= (*cp++);
172 	if (tbposition->xpos < 256)	/* tablet wraps around at 256 */
173 		status &= 077777;	/* make it out of proximity */
174 	tbposition->ypos = (*cp++)<<7;
175 	tbposition->ypos |= (*cp++);
176 	tbposition->status  = status;
177 	tbposition->scount++;
178 }
179 
180 /*
181  * This routine is called whenever a ioctl is about to be performed
182  * and gets a chance to reject the ioctl.  We reject all teletype
183  * oriented ioctl's except those which set the discipline, and
184  * those which get parameters (gtty and get special characters).
185  */
186 /*ARGSUSED*/
187 tbioctl(tp, cmd, data, flag)
188 	struct tty *tp;
189 	caddr_t data;
190 {
191 
192 	if ((cmd>>8) != 't')
193 		return (cmd);
194 	switch (cmd) {
195 
196 	case TIOCSETD:
197 	case TIOCGETD:
198 	case TIOCGETP:
199 	case TIOCGETC:
200 		return (cmd);
201 	}
202 	u.u_error = ENOTTY;
203 	return (0);
204 }
205 #endif
206