]>
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_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */
24 * Copyright (c) 1982, 1986, 1991, 1993
25 * The Regents of the University of California. All rights reserved.
27 * @(#)tty_tb.c 8.1 (Berkeley) 6/10/93
34 * Line discipline for RS232 tablets;
35 * supplies binary coordinate data.
37 #include <sys/param.h>
38 #include <sys/tablet.h>
41 #include <sys/proc_internal.h>
45 * Tablet configuration table.
48 short tbc_recsize
; /* input record size in bytes */
49 short tbc_uiosize
; /* size of data record returned user */
50 int tbc_sync
; /* mask for finding sync byte/bit */
51 int (*tbc_decode
)();/* decoding routine */
52 char *tbc_run
; /* enter run mode sequence */
53 char *tbc_point
; /* enter point mode sequence */
54 char *tbc_stop
; /* stop sequence */
55 char *tbc_start
; /* start/restart sequence */
57 #define TBF_POL 0x1 /* polhemus hack */
58 #define TBF_INPROX 0x2 /* tablet has proximity info */
61 static int tbdecode(), gtcodecode(), poldecode();
62 static int tblresdecode(), tbhresdecode();
64 struct tbconf tbconf
[TBTYPE
] = {
66 { 5, sizeof (struct tbpos
), 0200, tbdecode
, "6", "4" },
67 { 5, sizeof (struct tbpos
), 0200, tbdecode
, "\1CN", "\1RT", "\2", "\4" },
68 { 8, sizeof (struct gtcopos
), 0200, gtcodecode
},
69 {17, sizeof (struct polpos
), 0200, poldecode
, 0, 0, "\21", "\5\22\2\23",
71 { 5, sizeof (struct tbpos
), 0100, tblresdecode
, "\1CN", "\1PT", "\2", "\4",
73 { 6, sizeof (struct tbpos
), 0200, tbhresdecode
, "\1CN", "\1PT", "\2", "\4",
75 { 5, sizeof (struct tbpos
), 0100, tblresdecode
, "\1CL\33", "\1PT\33", 0, 0},
76 { 6, sizeof (struct tbpos
), 0200, tbhresdecode
, "\1CL\33", "\1PT\33", 0, 0},
83 int tbflags
; /* mode & type bits */
84 #define TBMAXREC 17 /* max input record size */
85 char cbuf
[TBMAXREC
]; /* input buffer */
88 struct gtcopos gtcopos
;
90 } rets
; /* processed state */
95 * Open as tablet discipline; called on discipline change.
100 register struct tty
*tp
;
102 register struct tb
*tbp
;
104 if (tp
->t_line
== TABLDISC
)
107 for (tbp
= tb
; tbp
< &tb
[NTBS
]; tbp
++)
108 if (tbp
->tbflags
== 0)
110 if (tbp
>= &tb
[NTBS
])
112 tbp
->tbflags
= TBTIGER
|TBPOINT
; /* default */
113 tp
->t_cp
= tbp
->cbuf
;
115 bzero((caddr_t
)&tbp
->rets
, sizeof (tbp
->rets
));
116 tp
->T_LINEP
= (caddr_t
)tbp
;
117 tp
->t_flags
|= LITOUT
;
122 * Line discipline change or last device close.
125 register struct tty
*tp
;
128 int modebits
= TBPOINT
|TBSTOP
;
131 tbioctl(tp
, BIOSMODE
, &modebits
, 0);
133 tbioctl(tp
, BIOSMODE
, &modebits
, 0, current_proc());
136 ((struct tb
*)tp
->T_LINEP
)->tbflags
= 0;
139 tp
->t_rawq
.c_cc
= 0; /* clear queues -- paranoid */
141 tp
->t_line
= 0; /* paranoid: avoid races */
146 * Read from a tablet line.
147 * Characters have been buffered in a buffer and decoded.
150 register struct tty
*tp
;
153 register struct tb
*tbp
= (struct tb
*)tp
->T_LINEP
;
154 register struct tbconf
*tc
= &tbconf
[tbp
->tbflags
& TBTYPE
];
157 if ((tp
->t_state
&TS_CARR_ON
) == 0)
159 ret
= uiomove(&tbp
->rets
, tc
->tbc_uiosize
, uio
);
160 if (tc
->tbc_flags
&TBF_POL
)
161 tbp
->rets
.polpos
.p_key
= ' ';
166 * Low level character input routine.
167 * Stuff the character in the buffer, and decode
168 * if all the chars are there.
170 * This routine could be expanded in-line in the receiver
171 * interrupt routine to make it run as fast as possible.
175 register struct tty
*tp
;
177 register struct tb
*tbp
= (struct tb
*)tp
->T_LINEP
;
178 register struct tbconf
*tc
= &tbconf
[tbp
->tbflags
& TBTYPE
];
180 if (tc
->tbc_recsize
== 0 || tc
->tbc_decode
== 0) /* paranoid? */
183 * Locate sync bit/byte or reset input buffer.
185 if (c
&tc
->tbc_sync
|| tp
->t_inbuf
== tc
->tbc_recsize
) {
186 tp
->t_cp
= tbp
->cbuf
;
189 *tp
->t_cp
++ = c
&0177;
191 * Call decode routine only if a full record has been collected.
193 if (++tp
->t_inbuf
== tc
->tbc_recsize
)
194 (*tc
->tbc_decode
)(tc
, tbp
->cbuf
, &tbp
->rets
);
198 * Decode GTCO 8 byte format (high res, tilt, and pressure).
201 gtcodecode(tc
, cp
, tbpos
)
204 register struct gtcopos
*tbpos
;
207 tbpos
->pressure
= *cp
>> 2;
208 tbpos
->status
= (tbpos
->pressure
> 16) | TBINPROX
; /* half way down */
209 tbpos
->xpos
= (*cp
++ & 03) << 14;
210 tbpos
->xpos
|= *cp
++ << 7;
211 tbpos
->xpos
|= *cp
++;
212 tbpos
->ypos
= (*cp
++ & 03) << 14;
213 tbpos
->ypos
|= *cp
++ << 7;
214 tbpos
->ypos
|= *cp
++;
215 tbpos
->xtilt
= *cp
++;
216 tbpos
->ytilt
= *cp
++;
221 * Decode old Hitachi 5 byte format (low res).
224 tbdecode(tc
, cp
, tbpos
)
227 register struct tbpos
*tbpos
;
232 tbpos
->status
= (byte
&0100) ? TBINPROX
: 0;
235 tbpos
->status
|= 1 << ((byte
-040)/2);
236 tbpos
->xpos
= *cp
++ << 7;
237 tbpos
->xpos
|= *cp
++;
238 if (tbpos
->xpos
< 256) /* tablet wraps around at 256 */
239 tbpos
->status
&= ~TBINPROX
; /* make it out of proximity */
240 tbpos
->ypos
= *cp
++ << 7;
241 tbpos
->ypos
|= *cp
++;
246 * Decode new Hitach 5-byte format (low res).
249 tblresdecode(tc
, cp
, tbpos
)
252 register struct tbpos
*tbpos
;
255 *cp
&= ~0100; /* mask sync bit */
256 tbpos
->status
= (*cp
++ >> 2) | TBINPROX
;
257 if (tc
->tbc_flags
&TBF_INPROX
&& tbpos
->status
&020)
258 tbpos
->status
&= ~(020|TBINPROX
);
260 tbpos
->xpos
|= *cp
++ << 6;
262 tbpos
->ypos
|= *cp
++ << 6;
267 * Decode new Hitach 6-byte format (high res).
270 tbhresdecode(tc
, cp
, tbpos
)
273 register struct tbpos
*tbpos
;
278 tbpos
->xpos
= (byte
& 03) << 14;
279 tbpos
->xpos
|= *cp
++ << 7;
280 tbpos
->xpos
|= *cp
++;
281 tbpos
->ypos
= *cp
++ << 14;
282 tbpos
->ypos
|= *cp
++ << 7;
283 tbpos
->ypos
|= *cp
++;
284 tbpos
->status
= (byte
>> 2) | TBINPROX
;
285 if (tc
->tbc_flags
&TBF_INPROX
&& tbpos
->status
&020)
286 tbpos
->status
&= ~(020|TBINPROX
);
294 poldecode(tc
, cp
, polpos
)
297 register struct polpos
*polpos
;
300 polpos
->p_x
= cp
[4] | cp
[3]<<7 | (cp
[9] & 0x03) << 14;
301 polpos
->p_y
= cp
[6] | cp
[5]<<7 | (cp
[9] & 0x0c) << 12;
302 polpos
->p_z
= cp
[8] | cp
[7]<<7 | (cp
[9] & 0x30) << 10;
303 polpos
->p_azi
= cp
[11] | cp
[10]<<7 | (cp
[16] & 0x03) << 14;
304 polpos
->p_pit
= cp
[13] | cp
[12]<<7 | (cp
[16] & 0x0c) << 12;
305 polpos
->p_rol
= cp
[15] | cp
[14]<<7 | (cp
[16] & 0x30) << 10;
306 polpos
->p_stat
= cp
[1] | cp
[0]<<7;
308 polpos
->p_key
= cp
[2];
313 tbioctl(tp
, cmd
, data
, flag
)
317 tbtioctl(tp
, cmd
, data
, flag
, p
)
325 register struct tb
*tbp
= (struct tb
*)tp
->T_LINEP
;
330 *(int *)data
= tbp
->tbflags
& TBMODE
;
334 if (tbconf
[*(int *)data
& TBTYPE
].tbc_recsize
== 0 ||
335 tbconf
[*(int *)data
& TBTYPE
].tbc_decode
== 0)
337 tbp
->tbflags
&= ~TBTYPE
;
338 tbp
->tbflags
|= *(int *)data
& TBTYPE
;
339 /* fall thru... to set mode bits */
342 register struct tbconf
*tc
;
344 tbp
->tbflags
&= ~TBMODE
;
345 tbp
->tbflags
|= *(int *)data
& TBMODE
;
346 tc
= &tbconf
[tbp
->tbflags
& TBTYPE
];
347 if (tbp
->tbflags
&TBSTOP
) {
349 ttyout(tc
->tbc_stop
, tp
);
350 } else if (tc
->tbc_start
)
351 ttyout(tc
->tbc_start
, tp
);
352 if (tbp
->tbflags
&TBPOINT
) {
354 ttyout(tc
->tbc_point
, tp
);
355 } else if (tc
->tbc_run
)
356 ttyout(tc
->tbc_run
, tp
);
362 *(int *)data
= tbp
->tbflags
& TBTYPE
;
369 return (-1); /* pass thru... */