]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/tty_tb.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 /* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */
30 * Copyright (c) 1982, 1986, 1991, 1993
31 * The Regents of the University of California. All rights reserved.
33 * @(#)tty_tb.c 8.1 (Berkeley) 6/10/93
40 * Line discipline for RS232 tablets;
41 * supplies binary coordinate data.
43 #include <sys/param.h>
44 #include <sys/tablet.h>
47 #include <sys/proc_internal.h>
51 * Tablet configuration table.
54 short tbc_recsize
; /* input record size in bytes */
55 short tbc_uiosize
; /* size of data record returned user */
56 int tbc_sync
; /* mask for finding sync byte/bit */
57 int (*tbc_decode
)();/* decoding routine */
58 char *tbc_run
; /* enter run mode sequence */
59 char *tbc_point
; /* enter point mode sequence */
60 char *tbc_stop
; /* stop sequence */
61 char *tbc_start
; /* start/restart sequence */
63 #define TBF_POL 0x1 /* polhemus hack */
64 #define TBF_INPROX 0x2 /* tablet has proximity info */
67 static int tbdecode(), gtcodecode(), poldecode();
68 static int tblresdecode(), tbhresdecode();
70 struct tbconf tbconf
[TBTYPE
] = {
72 { 5, sizeof (struct tbpos
), 0200, tbdecode
, "6", "4" },
73 { 5, sizeof (struct tbpos
), 0200, tbdecode
, "\1CN", "\1RT", "\2", "\4" },
74 { 8, sizeof (struct gtcopos
), 0200, gtcodecode
},
75 {17, sizeof (struct polpos
), 0200, poldecode
, 0, 0, "\21", "\5\22\2\23",
77 { 5, sizeof (struct tbpos
), 0100, tblresdecode
, "\1CN", "\1PT", "\2", "\4",
79 { 6, sizeof (struct tbpos
), 0200, tbhresdecode
, "\1CN", "\1PT", "\2", "\4",
81 { 5, sizeof (struct tbpos
), 0100, tblresdecode
, "\1CL\33", "\1PT\33", 0, 0},
82 { 6, sizeof (struct tbpos
), 0200, tbhresdecode
, "\1CL\33", "\1PT\33", 0, 0},
89 int tbflags
; /* mode & type bits */
90 #define TBMAXREC 17 /* max input record size */
91 char cbuf
[TBMAXREC
]; /* input buffer */
94 struct gtcopos gtcopos
;
96 } rets
; /* processed state */
101 * Open as tablet discipline; called on discipline change.
106 register struct tty
*tp
;
108 register struct tb
*tbp
;
110 if (tp
->t_line
== TABLDISC
)
113 for (tbp
= tb
; tbp
< &tb
[NTBS
]; tbp
++)
114 if (tbp
->tbflags
== 0)
116 if (tbp
>= &tb
[NTBS
])
118 tbp
->tbflags
= TBTIGER
|TBPOINT
; /* default */
119 tp
->t_cp
= tbp
->cbuf
;
121 bzero((caddr_t
)&tbp
->rets
, sizeof (tbp
->rets
));
122 tp
->T_LINEP
= (caddr_t
)tbp
;
123 tp
->t_flags
|= LITOUT
;
128 * Line discipline change or last device close.
131 register struct tty
*tp
;
134 int modebits
= TBPOINT
|TBSTOP
;
137 tbioctl(tp
, BIOSMODE
, &modebits
, 0);
139 tbioctl(tp
, BIOSMODE
, &modebits
, 0, current_proc());
142 ((struct tb
*)tp
->T_LINEP
)->tbflags
= 0;
145 tp
->t_rawq
.c_cc
= 0; /* clear queues -- paranoid */
147 tp
->t_line
= 0; /* paranoid: avoid races */
152 * Read from a tablet line.
153 * Characters have been buffered in a buffer and decoded.
156 register struct tty
*tp
;
159 register struct tb
*tbp
= (struct tb
*)tp
->T_LINEP
;
160 register struct tbconf
*tc
= &tbconf
[tbp
->tbflags
& TBTYPE
];
163 if ((tp
->t_state
&TS_CARR_ON
) == 0)
165 ret
= uiomove(&tbp
->rets
, tc
->tbc_uiosize
, uio
);
166 if (tc
->tbc_flags
&TBF_POL
)
167 tbp
->rets
.polpos
.p_key
= ' ';
172 * Low level character input routine.
173 * Stuff the character in the buffer, and decode
174 * if all the chars are there.
176 * This routine could be expanded in-line in the receiver
177 * interrupt routine to make it run as fast as possible.
181 register struct tty
*tp
;
183 register struct tb
*tbp
= (struct tb
*)tp
->T_LINEP
;
184 register struct tbconf
*tc
= &tbconf
[tbp
->tbflags
& TBTYPE
];
186 if (tc
->tbc_recsize
== 0 || tc
->tbc_decode
== 0) /* paranoid? */
189 * Locate sync bit/byte or reset input buffer.
191 if (c
&tc
->tbc_sync
|| tp
->t_inbuf
== tc
->tbc_recsize
) {
192 tp
->t_cp
= tbp
->cbuf
;
195 *tp
->t_cp
++ = c
&0177;
197 * Call decode routine only if a full record has been collected.
199 if (++tp
->t_inbuf
== tc
->tbc_recsize
)
200 (*tc
->tbc_decode
)(tc
, tbp
->cbuf
, &tbp
->rets
);
204 * Decode GTCO 8 byte format (high res, tilt, and pressure).
207 gtcodecode(tc
, cp
, tbpos
)
210 register struct gtcopos
*tbpos
;
213 tbpos
->pressure
= *cp
>> 2;
214 tbpos
->status
= (tbpos
->pressure
> 16) | TBINPROX
; /* half way down */
215 tbpos
->xpos
= (*cp
++ & 03) << 14;
216 tbpos
->xpos
|= *cp
++ << 7;
217 tbpos
->xpos
|= *cp
++;
218 tbpos
->ypos
= (*cp
++ & 03) << 14;
219 tbpos
->ypos
|= *cp
++ << 7;
220 tbpos
->ypos
|= *cp
++;
221 tbpos
->xtilt
= *cp
++;
222 tbpos
->ytilt
= *cp
++;
227 * Decode old Hitachi 5 byte format (low res).
230 tbdecode(tc
, cp
, tbpos
)
233 register struct tbpos
*tbpos
;
238 tbpos
->status
= (byte
&0100) ? TBINPROX
: 0;
241 tbpos
->status
|= 1 << ((byte
-040)/2);
242 tbpos
->xpos
= *cp
++ << 7;
243 tbpos
->xpos
|= *cp
++;
244 if (tbpos
->xpos
< 256) /* tablet wraps around at 256 */
245 tbpos
->status
&= ~TBINPROX
; /* make it out of proximity */
246 tbpos
->ypos
= *cp
++ << 7;
247 tbpos
->ypos
|= *cp
++;
252 * Decode new Hitach 5-byte format (low res).
255 tblresdecode(tc
, cp
, tbpos
)
258 register struct tbpos
*tbpos
;
261 *cp
&= ~0100; /* mask sync bit */
262 tbpos
->status
= (*cp
++ >> 2) | TBINPROX
;
263 if (tc
->tbc_flags
&TBF_INPROX
&& tbpos
->status
&020)
264 tbpos
->status
&= ~(020|TBINPROX
);
266 tbpos
->xpos
|= *cp
++ << 6;
268 tbpos
->ypos
|= *cp
++ << 6;
273 * Decode new Hitach 6-byte format (high res).
276 tbhresdecode(tc
, cp
, tbpos
)
279 register struct tbpos
*tbpos
;
284 tbpos
->xpos
= (byte
& 03) << 14;
285 tbpos
->xpos
|= *cp
++ << 7;
286 tbpos
->xpos
|= *cp
++;
287 tbpos
->ypos
= *cp
++ << 14;
288 tbpos
->ypos
|= *cp
++ << 7;
289 tbpos
->ypos
|= *cp
++;
290 tbpos
->status
= (byte
>> 2) | TBINPROX
;
291 if (tc
->tbc_flags
&TBF_INPROX
&& tbpos
->status
&020)
292 tbpos
->status
&= ~(020|TBINPROX
);
300 poldecode(tc
, cp
, polpos
)
303 register struct polpos
*polpos
;
306 polpos
->p_x
= cp
[4] | cp
[3]<<7 | (cp
[9] & 0x03) << 14;
307 polpos
->p_y
= cp
[6] | cp
[5]<<7 | (cp
[9] & 0x0c) << 12;
308 polpos
->p_z
= cp
[8] | cp
[7]<<7 | (cp
[9] & 0x30) << 10;
309 polpos
->p_azi
= cp
[11] | cp
[10]<<7 | (cp
[16] & 0x03) << 14;
310 polpos
->p_pit
= cp
[13] | cp
[12]<<7 | (cp
[16] & 0x0c) << 12;
311 polpos
->p_rol
= cp
[15] | cp
[14]<<7 | (cp
[16] & 0x30) << 10;
312 polpos
->p_stat
= cp
[1] | cp
[0]<<7;
314 polpos
->p_key
= cp
[2];
319 tbioctl(tp
, cmd
, data
, flag
)
323 tbtioctl(tp
, cmd
, data
, flag
, p
)
331 register struct tb
*tbp
= (struct tb
*)tp
->T_LINEP
;
336 *(int *)data
= tbp
->tbflags
& TBMODE
;
340 if (tbconf
[*(int *)data
& TBTYPE
].tbc_recsize
== 0 ||
341 tbconf
[*(int *)data
& TBTYPE
].tbc_decode
== 0)
343 tbp
->tbflags
&= ~TBTYPE
;
344 tbp
->tbflags
|= *(int *)data
& TBTYPE
;
345 /* fall thru... to set mode bits */
348 register struct tbconf
*tc
;
350 tbp
->tbflags
&= ~TBMODE
;
351 tbp
->tbflags
|= *(int *)data
& TBMODE
;
352 tc
= &tbconf
[tbp
->tbflags
& TBTYPE
];
353 if (tbp
->tbflags
&TBSTOP
) {
355 ttyout(tc
->tbc_stop
, tp
);
356 } else if (tc
->tbc_start
)
357 ttyout(tc
->tbc_start
, tp
);
358 if (tbp
->tbflags
&TBPOINT
) {
360 ttyout(tc
->tbc_point
, tp
);
361 } else if (tc
->tbc_run
)
362 ttyout(tc
->tbc_run
, tp
);
368 *(int *)data
= tbp
->tbflags
& TBTYPE
;
375 return (-1); /* pass thru... */