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