Commit | Line | Data |
---|---|---|
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 | |
36 | struct 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*/ | |
49 | tbopen(dev, tp) | |
50 | dev_t dev; | |
51 | register 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 | */ | |
72 | tbclose(tp) | |
73 | register 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 | */ | |
93 | tbread(tp) | |
94 | register 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 | */ | |
120 | int LASTTABC; | |
121 | tbinput(c, tp) | |
122 | register c; | |
123 | register 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 | */ | |
151 | tbndecode(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 | */ | |
170 | tbdecode(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*/ | |
199 | tbioctl(tp, cmd, addr) | |
200 | struct tty *tp; | |
201 | caddr_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 |