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