date and time created 82/06/26 16:09:08 by sam
[unix-history] / usr / src / sys / kern / tty_tb.c
CommitLineData
4f9a21f0
SL
1/* tty_tb.c 4.1 82/06/26 */
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
17/*
18 * Line discipline for RS232 tablets.
19 *
20 * This supplies binary coordinate data to a user level program
21 * with a minimum of fuss.
22 *
23 * This discipline requires that tty device drivers call
24 * the line specific l_ioctl routine from their ioctl routines,
25 * assigning the result to cmd so that we can refuse most tty specific
26 * ioctls which are unsafe because we have ambushed the
27 * teletype input queues and other data, overlaying them with
28 * the following information: the tty queue header, t_un.T_CTLQ,
29 * is overlaid with a MTABCHAR character buffer -- the raw input
30 * chars. The local characters (t_rocount on) are overlaid with
31 * the current coordinate position.
32 */
33
34#define MTABCHAR 5
35#define MNTABCHAR 6
36struct tbposition {
37 int xpos;
38 int ypos;
39 short int status;
40 short int scount;
41};
42
43/*
44 * Open as tablet discipline. Called when discipline changed
45 * with ioctl, and changes the interpretation of the information
46 * in the tty structure.
47 */
48/*ARGSUSED*/
49tbopen(dev, tp)
50dev_t dev;
51register struct tty *tp;
52{
53 register struct tbposition *tbp;
54
55 if (u.u_error)
56 return; /* paranoia */
57 if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) {
58 u.u_error = EBUSY;
59 return;
60 }
61 wflushtty(tp);
62 tp->t_cp = (char *) &tp->t_un.T_CTLQ; /* overlay control queue */
63 tp->t_inbuf = 0;
64 tbp = (struct tbposition *) &tp->t_rocount;
65 tbp->xpos = tbp->ypos = tbp->status = tbp->scount = 0;
66}
67
68/*
69 * Break down... called when discipline changed or from device
70 * close routine.
71 */
72tbclose(tp)
73register struct tty *tp;
74{
75 register s;
76
77 s = spl5();
78 tp->t_cp = 0;
79 tp->t_inbuf = 0;
80 tp->t_rawq.c_cc = 0; /* clear queues -- paranoid */
81 tp->t_canq.c_cc = 0;
82 tp->t_un.T_CTLQ.c_cc = 0; /* clear overlaid queue status */
83 tp->t_un.T_CTLQ.c_cf = tp->t_un.T_CTLQ.c_cl = NULL;
84 tp->t_line = 0; /* paranoid: avoid races */
85 splx(s);
86}
87
88/*
89 * Read from a tablet line.
90 * Characters have been buffered in a buffer and
91 * decoded. The coordinates are now sluffed back to the user.
92 */
93tbread(tp)
94register struct tty *tp;
95{
96 register int i;
97 register s;
98 struct tbposition tbposition;
99
100 if ((tp->t_state&TS_CARR_ON)==0)
101 return (-1);
102 if (copyout(&tp->t_rocount, u.u_base, (unsigned)(sizeof tbposition))) {
103 u.u_error = EFAULT;
104 return (-1);
105 }
106 u.u_count -= sizeof tbposition;
107 u.u_base += sizeof tbposition;
108 u.u_offset += sizeof tbposition;
109 return (0);
110}
111
112/*
113 * Low level character input routine.
114 * Stuff the character in the buffer, and decode the it
115 * if all the chars are there.
116 *
117 * This routine could be expanded in-line in the receiver
118 * interrupt routine of the dh-11 to make it run as fast as possible.
119 */
120int LASTTABC;
121tbinput(c, tp)
122register c;
123register struct tty *tp;
124{
125
126 if(tp->t_line == TABLDISC) {
127 if((c&0200) || (tp->t_inbuf == MTABCHAR)) {
128 tp->t_cp = (char *) &tp->t_un.T_CTLQ;
129 tp->t_inbuf = 0;
130 }
131 *tp->t_cp++ = c&0177;
132 if(++tp->t_inbuf == MTABCHAR)
133 tbdecode((char *) &tp->t_un.T_CTLQ,
134 (struct tbposition *) &tp->t_rocount);
135 } else if(tp->t_line == NTABLDISC) {
136 if((c&0200) || (tp->t_inbuf == MNTABCHAR)) {
137 tp->t_cp = (char *) &tp->t_un.T_CTLQ;
138 tp->t_inbuf = 0;
139 }
140 *tp->t_cp++ = c&0177;
141 if(++tp->t_inbuf == MNTABCHAR)
142 tbndecode((char *) &tp->t_un.T_CTLQ,
143 (struct tbposition *) &tp->t_rocount);
144 }
145}
146
147/*
148 * Decode tablet coordinates from ascii to binary.
149 * (gtco 6 character format)
150 */
151tbndecode(cp, tbposition)
152 register char *cp;
153 register struct tbposition *tbposition;
154{
155
156 tbposition->status = *cp>>2; /* this needs to be decoded */
157 tbposition->xpos = ((*cp++)&03)<<14;
158 tbposition->xpos |= (*cp++)<<7;
159 tbposition->xpos |= (*cp++);
160 tbposition->ypos = ((*cp++)&03)<<14;
161 tbposition->ypos |= (*cp++)<<7;
162 tbposition->ypos |= (*cp++);
163 tbposition->scount++;
164}
165
166/*
167 * Decode tablet coordinates from ascii to binary.
168 * (hitachi 5 character format)
169 */
170tbdecode(cp, tbposition)
171 register char *cp;
172 register struct tbposition *tbposition;
173{
174 register int status;
175 register char byte;
176
177 byte = *cp++;
178 status = (byte&0100) ? 0100000 : 0;
179 byte &= ~0100;
180 if(byte > 036)
181 status |= 1<<((byte-040)/2);
182 tbposition->xpos = (*cp++)<<7;
183 tbposition->xpos |= (*cp++);
184 if(tbposition->xpos < 256) /* tablet wraps around at 256 */
185 status &= 077777; /* make it out of proximity */
186 tbposition->ypos = (*cp++)<<7;
187 tbposition->ypos |= (*cp++);
188 tbposition->status = status;
189 tbposition->scount++;
190}
191
192/*
193 * This routine is called whenever a ioctl is about to be performed
194 * and gets a chance to reject the ioctl. We reject all teletype
195 * oriented ioctl's except those which set the discipline, and
196 * those which get parameters (gtty and get special characters).
197 */
198/*ARGSUSED*/
199tbioctl(tp, cmd, addr)
200struct tty *tp;
201caddr_t addr;
202{
203
204 if ((cmd>>8) != 't')
205 return (cmd);
206 switch (cmd) {
207
208 case TIOCSETD:
209 case TIOCGETD:
210 case TIOCGETP:
211 case TIOCGETC:
212 return (cmd);
213 }
214 u.u_error = ENOTTY;
215 return (0);
216}
217#endif