pccons.c revision 1.25 1 1.25 scw /* $NetBSD: pccons.c,v 1.25 2001/05/02 10:32:21 scw Exp $ */
2 1.14 soda /* $OpenBSD: pccons.c,v 1.22 1999/01/30 22:39:37 imp Exp $ */
3 1.13 soda /* NetBSD: pccons.c,v 1.89 1995/05/04 19:35:20 cgd Exp */
4 1.13 soda /* NetBSD: pms.c,v 1.21 1995/04/18 02:25:18 mycroft Exp */
5 1.1 jonathan
6 1.1 jonathan /*-
7 1.11 mycroft * Copyright (c) 1993, 1994, 1995 Charles M. Hannum. All rights reserved.
8 1.1 jonathan * Copyright (c) 1990 The Regents of the University of California.
9 1.1 jonathan * All rights reserved.
10 1.1 jonathan *
11 1.1 jonathan * This code is derived from software contributed to Berkeley by
12 1.1 jonathan * William Jolitz and Don Ahn.
13 1.1 jonathan *
14 1.11 mycroft * Copyright (c) 1994 Charles M. Hannum.
15 1.1 jonathan * Copyright (c) 1992, 1993 Erik Forsberg.
16 1.1 jonathan *
17 1.1 jonathan * Redistribution and use in source and binary forms, with or without
18 1.1 jonathan * modification, are permitted provided that the following conditions
19 1.1 jonathan * are met:
20 1.1 jonathan * 1. Redistributions of source code must retain the above copyright
21 1.1 jonathan * notice, this list of conditions and the following disclaimer.
22 1.1 jonathan * 2. Redistributions in binary form must reproduce the above copyright
23 1.1 jonathan * notice, this list of conditions and the following disclaimer in the
24 1.1 jonathan * documentation and/or other materials provided with the distribution.
25 1.1 jonathan * 3. All advertising materials mentioning features or use of this software
26 1.1 jonathan * must display the following acknowledgement:
27 1.1 jonathan * This product includes software developed by the University of
28 1.1 jonathan * California, Berkeley and its contributors.
29 1.1 jonathan * 4. Neither the name of the University nor the names of its contributors
30 1.1 jonathan * may be used to endorse or promote products derived from this software
31 1.1 jonathan * without specific prior written permission.
32 1.1 jonathan *
33 1.1 jonathan * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34 1.1 jonathan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 1.1 jonathan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 1.1 jonathan * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37 1.1 jonathan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 1.1 jonathan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 1.1 jonathan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 1.1 jonathan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 1.1 jonathan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 1.1 jonathan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 1.1 jonathan * SUCH DAMAGE.
44 1.1 jonathan *
45 1.1 jonathan * @(#)pccons.c 5.11 (Berkeley) 5/21/91
46 1.1 jonathan */
47 1.1 jonathan
48 1.1 jonathan /*
49 1.1 jonathan * code to work keyboard & display for PC-style console
50 1.1 jonathan */
51 1.1 jonathan
52 1.14 soda #include "opt_ddb.h"
53 1.14 soda
54 1.1 jonathan #include <sys/param.h>
55 1.1 jonathan #include <sys/systm.h>
56 1.1 jonathan #include <sys/ioctl.h>
57 1.1 jonathan #include <sys/proc.h>
58 1.1 jonathan #include <sys/user.h>
59 1.1 jonathan #include <sys/select.h>
60 1.1 jonathan #include <sys/tty.h>
61 1.1 jonathan #include <sys/uio.h>
62 1.1 jonathan #include <sys/callout.h>
63 1.1 jonathan #include <sys/syslog.h>
64 1.1 jonathan #include <sys/device.h>
65 1.8 jonathan #include <sys/poll.h>
66 1.13 soda #include <sys/conf.h>
67 1.13 soda #include <sys/vnode.h>
68 1.13 soda #include <sys/fcntl.h>
69 1.13 soda #include <sys/kernel.h>
70 1.13 soda #include <sys/kcore.h>
71 1.1 jonathan
72 1.1 jonathan #include <dev/cons.h>
73 1.1 jonathan
74 1.1 jonathan #include <machine/cpu.h>
75 1.1 jonathan #include <machine/pio.h>
76 1.1 jonathan #include <machine/autoconf.h>
77 1.7 jonathan #include <machine/bus.h>
78 1.1 jonathan #include <machine/display.h>
79 1.1 jonathan #include <machine/pccons.h>
80 1.13 soda #include <arc/arc/arctype.h>
81 1.13 soda #include <arc/arc/arcbios.h>
82 1.23 ur #include <arc/jazz/pica.h>
83 1.13 soda #include <arc/dti/desktech.h>
84 1.23 ur #include <arc/jazz/jazziovar.h>
85 1.1 jonathan
86 1.1 jonathan #include <dev/isa/isavar.h>
87 1.13 soda #include <machine/isa_machdep.h>
88 1.1 jonathan #include <machine/kbdreg.h>
89 1.1 jonathan
90 1.13 soda #include <dev/cons.h>
91 1.13 soda
92 1.20 soda #include "pc.h"
93 1.20 soda
94 1.1 jonathan #define XFREE86_BUG_COMPAT
95 1.1 jonathan
96 1.1 jonathan #ifndef BEEP_FREQ
97 1.1 jonathan #define BEEP_FREQ 1600
98 1.1 jonathan #endif
99 1.1 jonathan #ifndef BEEP_TIME
100 1.1 jonathan #define BEEP_TIME (hz/5)
101 1.1 jonathan #endif
102 1.1 jonathan
103 1.1 jonathan #define PCBURST 128
104 1.1 jonathan
105 1.1 jonathan static u_short *Crtat; /* pointer to backing store */
106 1.1 jonathan static u_short *crtat; /* pointer to current char */
107 1.1 jonathan static u_char async, kernel, polling; /* Really, you don't want to know. */
108 1.1 jonathan static u_char lock_state = 0x00, /* all off */
109 1.1 jonathan old_lock_state = 0xff,
110 1.1 jonathan typematic_rate = 0xff, /* don't update until set by user */
111 1.1 jonathan old_typematic_rate = 0xff;
112 1.1 jonathan static u_short cursor_shape = 0xffff, /* don't update until set by user */
113 1.1 jonathan old_cursor_shape = 0xffff;
114 1.13 soda static pccons_keymap_t scan_codes[KB_NUM_KEYS];/* keyboard translation table */
115 1.1 jonathan int pc_xmode = 0;
116 1.1 jonathan
117 1.13 soda cdev_decl(pc);
118 1.13 soda
119 1.1 jonathan /*
120 1.1 jonathan * Keyboard output queue.
121 1.1 jonathan */
122 1.1 jonathan int kb_oq_put = 0;
123 1.1 jonathan int kb_oq_get = 0;
124 1.1 jonathan u_char kb_oq[8];
125 1.1 jonathan
126 1.1 jonathan #define PCUNIT(x) (minor(x))
127 1.1 jonathan
128 1.1 jonathan static struct video_state {
129 1.1 jonathan int cx, cy; /* escape parameters */
130 1.1 jonathan int row, col; /* current cursor position */
131 1.1 jonathan int nrow, ncol, nchr; /* current screen geometry */
132 1.13 soda int offset; /* Saved cursor pos */
133 1.1 jonathan u_char state; /* parser state */
134 1.1 jonathan #define VSS_ESCAPE 1
135 1.1 jonathan #define VSS_EBRACE 2
136 1.1 jonathan #define VSS_EPARAM 3
137 1.1 jonathan char so; /* in standout mode? */
138 1.1 jonathan char color; /* color or mono display */
139 1.1 jonathan char at; /* normal attributes */
140 1.1 jonathan char so_at; /* standout attributes */
141 1.1 jonathan } vs;
142 1.1 jonathan
143 1.1 jonathan struct pc_softc {
144 1.1 jonathan struct device sc_dev;
145 1.1 jonathan struct tty *sc_tty;
146 1.1 jonathan };
147 1.1 jonathan
148 1.13 soda struct opms_softc { /* driver status information */
149 1.1 jonathan struct device sc_dev;
150 1.1 jonathan
151 1.1 jonathan struct clist sc_q;
152 1.1 jonathan struct selinfo sc_rsel;
153 1.1 jonathan u_char sc_state; /* mouse driver state */
154 1.1 jonathan #define PMS_OPEN 0x01 /* device is open */
155 1.1 jonathan #define PMS_ASLP 0x02 /* waiting for mouse data */
156 1.1 jonathan u_char sc_status; /* mouse button status */
157 1.1 jonathan int sc_x, sc_y; /* accumulated motion in the X,Y axis */
158 1.1 jonathan };
159 1.1 jonathan
160 1.17 thorpej static struct callout async_update_ch = CALLOUT_INITIALIZER;
161 1.17 thorpej
162 1.13 soda int pcprobe __P((struct device *, struct cfdata *, void *));
163 1.1 jonathan void pcattach __P((struct device *, struct device *, void *));
164 1.1 jonathan int pcintr __P((void *));
165 1.13 soda void pc_xmode_on __P((void));
166 1.13 soda void pc_xmode_off __P((void));
167 1.13 soda static u_char kbc_get8042cmd __P((void));
168 1.13 soda static int kbc_put8042cmd __P((u_char));
169 1.13 soda int kbc_8042sysreset __P((void));
170 1.13 soda int kbd_cmd __P((u_char, u_char));
171 1.13 soda static __inline int kbd_wait_output __P((void));
172 1.13 soda static __inline int kbd_wait_input __P((void));
173 1.13 soda static __inline void kbd_flush_input __P((void));
174 1.13 soda void set_cursor_shape __P((void));
175 1.13 soda void get_cursor_shape __P((void));
176 1.13 soda void async_update __P((void));
177 1.13 soda void do_async_update __P((u_char));;
178 1.13 soda
179 1.13 soda void pccnattach __P((void));
180 1.13 soda void pccnputc __P((dev_t, int c));
181 1.13 soda int pccngetc __P((dev_t));
182 1.13 soda void pccnpollc __P((dev_t, int));
183 1.1 jonathan
184 1.13 soda extern struct cfdriver pc_cd;
185 1.13 soda
186 1.23 ur struct cfattach pc_jazzio_ca = {
187 1.13 soda sizeof(struct pc_softc), pcprobe, pcattach
188 1.2 thorpej };
189 1.2 thorpej
190 1.13 soda struct cfattach pc_isa_ca = {
191 1.13 soda sizeof(struct pc_softc), pcprobe, pcattach
192 1.13 soda };
193 1.20 soda
194 1.13 soda int opmsprobe __P((struct device *, struct cfdata *, void *));
195 1.13 soda void opmsattach __P((struct device *, struct device *, void *));
196 1.13 soda int opmsintr __P((void *));
197 1.1 jonathan
198 1.20 soda #if NOPMS > 0
199 1.13 soda struct cfattach opms_ca = {
200 1.13 soda sizeof(struct opms_softc), opmsprobe, opmsattach
201 1.13 soda };
202 1.20 soda #endif
203 1.1 jonathan
204 1.13 soda extern struct cfdriver opms_cd;
205 1.2 thorpej
206 1.1 jonathan #define PMSUNIT(dev) (minor(dev))
207 1.1 jonathan
208 1.1 jonathan #define CHR 2
209 1.1 jonathan
210 1.13 soda static unsigned int addr_6845;
211 1.13 soda static unsigned int mono_base = 0x3b4;
212 1.13 soda static unsigned int mono_buf = 0xb0000;
213 1.13 soda static unsigned int cga_base = 0x3d4;
214 1.13 soda static unsigned int cga_buf = 0xb8000;
215 1.13 soda static unsigned int kbd_cmdp = 0x64;
216 1.13 soda static unsigned int kbd_datap = 0x60;
217 1.1 jonathan
218 1.1 jonathan char *sget __P((void));
219 1.1 jonathan void sput __P((u_char *, int));
220 1.1 jonathan
221 1.13 soda void pcstart __P((struct tty *));
222 1.13 soda int pcparam __P((struct tty *, struct termios *));
223 1.13 soda static __inline void wcopy __P((void *, void *, u_int));
224 1.20 soda void pcinithandle __P((void));
225 1.13 soda
226 1.13 soda extern void fillw __P((int, u_int16_t *, int));
227 1.1 jonathan
228 1.1 jonathan #define KBD_DELAY \
229 1.1 jonathan DELAY(10);
230 1.1 jonathan
231 1.20 soda void
232 1.20 soda pcinithandle()
233 1.20 soda {
234 1.20 soda static int initialized = 0;
235 1.20 soda
236 1.20 soda if (initialized)
237 1.20 soda return;
238 1.20 soda initialized = 1;
239 1.20 soda
240 1.20 soda switch (cputype) {
241 1.20 soda
242 1.20 soda case ACER_PICA_61:
243 1.20 soda case NEC_R96: /* XXX - not really confirmed */
244 1.20 soda mono_base += PICA_V_LOCAL_VIDEO_CTRL;
245 1.20 soda mono_buf += PICA_V_LOCAL_VIDEO;
246 1.20 soda cga_base += PICA_V_LOCAL_VIDEO_CTRL;
247 1.20 soda cga_buf += PICA_V_LOCAL_VIDEO;
248 1.20 soda case MAGNUM:
249 1.20 soda case NEC_R94:
250 1.20 soda case NEC_RAx94:
251 1.20 soda case NEC_RD94:
252 1.24 tsutsui case NEC_JC94:
253 1.20 soda kbd_cmdp = PICA_SYS_KBD + 0x61;
254 1.20 soda kbd_datap = PICA_SYS_KBD + 0x60;
255 1.20 soda break;
256 1.20 soda
257 1.20 soda case DESKSTATION_TYNE:
258 1.20 soda bus_space_map(&arc_bus_io, mono_base, 2, 0, &mono_base);
259 1.20 soda bus_space_map(&arc_bus_mem, mono_buf, 0x20000, 0, &mono_buf);
260 1.20 soda bus_space_map(&arc_bus_io, cga_base, 2, 0, &cga_base);
261 1.20 soda bus_space_map(&arc_bus_mem, cga_buf, 0x20000, 0, &cga_buf);
262 1.20 soda bus_space_map(&arc_bus_io, 0x64, 1, 0, &kbd_cmdp);
263 1.20 soda bus_space_map(&arc_bus_io, 0x60, 1, 0, &kbd_datap);
264 1.20 soda break;
265 1.20 soda
266 1.20 soda case DESKSTATION_RPC44:
267 1.20 soda bus_space_map(&arc_bus_io, mono_base, 2, 0, &mono_base);
268 1.20 soda bus_space_map(&arc_bus_mem, mono_buf, 0x20000, 0, &mono_buf);
269 1.20 soda bus_space_map(&arc_bus_io, cga_base, 2, 0, &cga_base);
270 1.20 soda bus_space_map(&arc_bus_mem, 0xa0000, 0x20000, 0, &cga_buf);
271 1.20 soda bus_space_map(&arc_bus_io, 0x64, 1, 0, &kbd_cmdp);
272 1.20 soda bus_space_map(&arc_bus_io, 0x60, 1, 0, &kbd_datap);
273 1.20 soda break;
274 1.20 soda
275 1.20 soda case SNI_RM200:
276 1.20 soda bus_space_map(&arc_bus_io, mono_base, 2, 0, &mono_base);
277 1.20 soda bus_space_map(&arc_bus_mem, mono_buf, 0x20000, 0, &mono_buf);
278 1.20 soda bus_space_map(&arc_bus_io, cga_base, 2, 0, &cga_base);
279 1.20 soda bus_space_map(&arc_bus_mem, cga_buf, 0x20000, 0, &cga_buf);
280 1.20 soda bus_space_map(&arc_bus_io, 0x64, 1, 0, &kbd_cmdp);
281 1.20 soda bus_space_map(&arc_bus_io, 0x60, 1, 0, &kbd_datap);
282 1.20 soda break;
283 1.20 soda }
284 1.20 soda }
285 1.20 soda
286 1.13 soda /*
287 1.13 soda * bcopy variant that only moves word-aligned 16-bit entities,
288 1.13 soda * for stupid VGA cards. cnt is required to be an even vale.
289 1.13 soda */
290 1.13 soda static __inline void
291 1.13 soda wcopy(src, tgt, cnt)
292 1.13 soda void *src, *tgt;
293 1.13 soda u_int cnt;
294 1.13 soda {
295 1.13 soda u_int16_t *from = src;
296 1.13 soda u_int16_t *to = tgt;
297 1.13 soda
298 1.13 soda cnt >>= 1;
299 1.13 soda if (to < from || to >= from + cnt)
300 1.13 soda while(cnt--)
301 1.13 soda *to++ = *from++;
302 1.13 soda else {
303 1.13 soda to += cnt;
304 1.13 soda from += cnt;
305 1.13 soda while(cnt--)
306 1.13 soda *--to = *--from;
307 1.13 soda }
308 1.13 soda }
309 1.13 soda
310 1.13 soda static __inline int
311 1.1 jonathan kbd_wait_output()
312 1.1 jonathan {
313 1.1 jonathan u_int i;
314 1.1 jonathan
315 1.1 jonathan for (i = 100000; i; i--)
316 1.13 soda if ((inb(kbd_cmdp) & KBS_IBF) == 0) {
317 1.1 jonathan KBD_DELAY;
318 1.1 jonathan return 1;
319 1.1 jonathan }
320 1.1 jonathan return 0;
321 1.1 jonathan }
322 1.1 jonathan
323 1.13 soda static __inline int
324 1.1 jonathan kbd_wait_input()
325 1.1 jonathan {
326 1.1 jonathan u_int i;
327 1.1 jonathan
328 1.1 jonathan for (i = 100000; i; i--)
329 1.13 soda if ((inb(kbd_cmdp) & KBS_DIB) != 0) {
330 1.1 jonathan KBD_DELAY;
331 1.1 jonathan return 1;
332 1.1 jonathan }
333 1.1 jonathan return 0;
334 1.1 jonathan }
335 1.1 jonathan
336 1.13 soda static __inline void
337 1.1 jonathan kbd_flush_input()
338 1.1 jonathan {
339 1.1 jonathan u_char c;
340 1.1 jonathan
341 1.13 soda while ((c = inb(kbd_cmdp)) & 0x03)
342 1.1 jonathan if ((c & KBS_DIB) == KBS_DIB) {
343 1.1 jonathan /* XXX - delay is needed to prevent some keyboards from
344 1.1 jonathan wedging when the system boots */
345 1.1 jonathan delay(6);
346 1.13 soda (void) inb(kbd_datap);
347 1.1 jonathan }
348 1.1 jonathan }
349 1.1 jonathan
350 1.1 jonathan
351 1.13 soda
352 1.13 soda /*
353 1.13 soda * Pass system reset command to keyboard controller (8042).
354 1.13 soda */
355 1.13 soda int
356 1.13 soda kbc_8042sysreset()
357 1.13 soda {
358 1.13 soda
359 1.20 soda pcinithandle();
360 1.20 soda
361 1.13 soda if (!kbd_wait_output())
362 1.13 soda return 0;
363 1.13 soda outb(kbd_cmdp, 0xd1);
364 1.13 soda if (!kbd_wait_output())
365 1.13 soda return 0;
366 1.13 soda outb(kbd_datap, 0); /* ZAP */
367 1.13 soda return 1;
368 1.13 soda }
369 1.13 soda
370 1.1 jonathan #if 1
371 1.1 jonathan /*
372 1.1 jonathan * Get the current command byte.
373 1.1 jonathan */
374 1.1 jonathan static u_char
375 1.1 jonathan kbc_get8042cmd()
376 1.1 jonathan {
377 1.1 jonathan
378 1.1 jonathan if (!kbd_wait_output())
379 1.1 jonathan return -1;
380 1.13 soda outb(kbd_cmdp, K_RDCMDBYTE);
381 1.1 jonathan if (!kbd_wait_input())
382 1.1 jonathan return -1;
383 1.13 soda return inb(kbd_datap);
384 1.1 jonathan }
385 1.1 jonathan #endif
386 1.1 jonathan
387 1.1 jonathan /*
388 1.1 jonathan * Pass command byte to keyboard controller (8042).
389 1.1 jonathan */
390 1.1 jonathan static int
391 1.1 jonathan kbc_put8042cmd(val)
392 1.1 jonathan u_char val;
393 1.1 jonathan {
394 1.1 jonathan
395 1.1 jonathan if (!kbd_wait_output())
396 1.1 jonathan return 0;
397 1.13 soda outb(kbd_cmdp, K_LDCMDBYTE);
398 1.1 jonathan if (!kbd_wait_output())
399 1.1 jonathan return 0;
400 1.13 soda outb(kbd_datap, val);
401 1.1 jonathan return 1;
402 1.1 jonathan }
403 1.1 jonathan
404 1.1 jonathan /*
405 1.1 jonathan * Pass command to keyboard itself
406 1.1 jonathan */
407 1.1 jonathan int
408 1.1 jonathan kbd_cmd(val, polling)
409 1.1 jonathan u_char val;
410 1.1 jonathan u_char polling;
411 1.1 jonathan {
412 1.1 jonathan u_int retries = 3;
413 1.1 jonathan register u_int i;
414 1.1 jonathan
415 1.1 jonathan if(!polling) {
416 1.1 jonathan i = spltty();
417 1.1 jonathan if(kb_oq_get == kb_oq_put) {
418 1.13 soda outb(kbd_datap, val);
419 1.1 jonathan }
420 1.1 jonathan kb_oq[kb_oq_put] = val;
421 1.1 jonathan kb_oq_put = (kb_oq_put + 1) & 7;
422 1.1 jonathan splx(i);
423 1.1 jonathan return(1);
424 1.1 jonathan }
425 1.1 jonathan else do {
426 1.1 jonathan if (!kbd_wait_output())
427 1.1 jonathan return 0;
428 1.13 soda outb(kbd_datap, val);
429 1.1 jonathan for (i = 100000; i; i--) {
430 1.13 soda if (inb(kbd_cmdp) & KBS_DIB) {
431 1.1 jonathan register u_char c;
432 1.1 jonathan
433 1.1 jonathan KBD_DELAY;
434 1.13 soda c = inb(kbd_datap);
435 1.1 jonathan if (c == KBR_ACK || c == KBR_ECHO) {
436 1.1 jonathan return 1;
437 1.1 jonathan }
438 1.1 jonathan if (c == KBR_RESEND) {
439 1.1 jonathan break;
440 1.1 jonathan }
441 1.1 jonathan #ifdef DIAGNOSTIC
442 1.6 christos printf("kbd_cmd: input char %x lost\n", c);
443 1.1 jonathan #endif
444 1.1 jonathan }
445 1.1 jonathan }
446 1.1 jonathan } while (--retries);
447 1.1 jonathan return 0;
448 1.1 jonathan }
449 1.1 jonathan
450 1.1 jonathan void
451 1.1 jonathan set_cursor_shape()
452 1.1 jonathan {
453 1.1 jonathan register int iobase = addr_6845;
454 1.1 jonathan
455 1.1 jonathan outb(iobase, 10);
456 1.1 jonathan outb(iobase+1, cursor_shape >> 8);
457 1.1 jonathan outb(iobase, 11);
458 1.1 jonathan outb(iobase+1, cursor_shape);
459 1.1 jonathan old_cursor_shape = cursor_shape;
460 1.1 jonathan }
461 1.1 jonathan
462 1.1 jonathan void
463 1.1 jonathan get_cursor_shape()
464 1.1 jonathan {
465 1.1 jonathan register int iobase = addr_6845;
466 1.1 jonathan
467 1.1 jonathan outb(iobase, 10);
468 1.1 jonathan cursor_shape = inb(iobase+1) << 8;
469 1.1 jonathan outb(iobase, 11);
470 1.1 jonathan cursor_shape |= inb(iobase+1);
471 1.1 jonathan
472 1.1 jonathan /*
473 1.1 jonathan * real 6845's, as found on, MDA, Hercules or CGA cards, do
474 1.1 jonathan * not support reading the cursor shape registers. the 6845
475 1.1 jonathan * tri-states it's data bus. This is _normally_ read by the
476 1.1 jonathan * cpu as either 0x00 or 0xff.. in which case we just use
477 1.1 jonathan * a line cursor.
478 1.1 jonathan */
479 1.1 jonathan if (cursor_shape == 0x0000 || cursor_shape == 0xffff)
480 1.1 jonathan cursor_shape = 0x0b10;
481 1.1 jonathan else
482 1.1 jonathan cursor_shape &= 0x1f1f;
483 1.1 jonathan }
484 1.1 jonathan
485 1.1 jonathan void
486 1.1 jonathan do_async_update(poll)
487 1.1 jonathan u_char poll;
488 1.1 jonathan {
489 1.1 jonathan int pos;
490 1.1 jonathan static int old_pos = -1;
491 1.1 jonathan
492 1.1 jonathan async = 0;
493 1.1 jonathan
494 1.1 jonathan if (lock_state != old_lock_state) {
495 1.1 jonathan old_lock_state = lock_state;
496 1.1 jonathan if (!kbd_cmd(KBC_MODEIND, poll) ||
497 1.1 jonathan !kbd_cmd(lock_state, poll)) {
498 1.6 christos printf("pc: timeout updating leds\n");
499 1.1 jonathan (void) kbd_cmd(KBC_ENABLE, poll);
500 1.1 jonathan }
501 1.1 jonathan }
502 1.1 jonathan if (typematic_rate != old_typematic_rate) {
503 1.1 jonathan old_typematic_rate = typematic_rate;
504 1.1 jonathan if (!kbd_cmd(KBC_TYPEMATIC, poll) ||
505 1.1 jonathan !kbd_cmd(typematic_rate, poll)) {
506 1.6 christos printf("pc: timeout updating typematic rate\n");
507 1.1 jonathan (void) kbd_cmd(KBC_ENABLE, poll);
508 1.1 jonathan }
509 1.1 jonathan }
510 1.1 jonathan
511 1.1 jonathan if (pc_xmode > 0)
512 1.1 jonathan return;
513 1.1 jonathan
514 1.1 jonathan pos = crtat - Crtat;
515 1.1 jonathan if (pos != old_pos) {
516 1.1 jonathan register int iobase = addr_6845;
517 1.1 jonathan outb(iobase, 14);
518 1.1 jonathan outb(iobase+1, pos >> 8);
519 1.1 jonathan outb(iobase, 15);
520 1.1 jonathan outb(iobase+1, pos);
521 1.1 jonathan old_pos = pos;
522 1.1 jonathan }
523 1.1 jonathan if (cursor_shape != old_cursor_shape)
524 1.1 jonathan set_cursor_shape();
525 1.1 jonathan }
526 1.1 jonathan
527 1.1 jonathan void
528 1.1 jonathan async_update()
529 1.1 jonathan {
530 1.1 jonathan
531 1.1 jonathan if (kernel || polling) {
532 1.1 jonathan if (async)
533 1.17 thorpej callout_stop(&async_update_ch);
534 1.1 jonathan do_async_update(1);
535 1.1 jonathan } else {
536 1.1 jonathan if (async)
537 1.1 jonathan return;
538 1.1 jonathan async = 1;
539 1.17 thorpej callout_reset(&async_update_ch, 1,
540 1.17 thorpej (void(*)(void *))do_async_update, NULL);
541 1.1 jonathan }
542 1.1 jonathan }
543 1.1 jonathan
544 1.1 jonathan /*
545 1.1 jonathan * these are both bad jokes
546 1.1 jonathan */
547 1.1 jonathan int
548 1.13 soda pcprobe(parent, match, aux)
549 1.1 jonathan struct device *parent;
550 1.13 soda struct cfdata *match;
551 1.13 soda void *aux;
552 1.1 jonathan {
553 1.23 ur struct jazzio_attach_args *ja = aux;
554 1.1 jonathan u_int i;
555 1.1 jonathan
556 1.1 jonathan /* Make shure we're looking for this type of device */
557 1.13 soda if(!strcmp((parent)->dv_cfdata->cf_driver->cd_name, "pica")) {
558 1.23 ur if (strcmp(ja->ja_name, "pckbd") != 0)
559 1.13 soda return(0);
560 1.20 soda
561 1.20 soda switch (cputype) { /* XXX ick */
562 1.20 soda case ACER_PICA_61:
563 1.20 soda case NEC_R96: /* XXX - not really confirmed */
564 1.20 soda break;
565 1.20 soda default:
566 1.20 soda return (0);
567 1.20 soda }
568 1.20 soda } else { /* ISA */
569 1.20 soda switch (cputype) { /* XXX ick */
570 1.20 soda case DESKSTATION_RPC44:
571 1.20 soda case DESKSTATION_TYNE:
572 1.20 soda break;
573 1.20 soda default:
574 1.20 soda return (0);
575 1.20 soda }
576 1.13 soda }
577 1.1 jonathan
578 1.20 soda pcinithandle();
579 1.20 soda
580 1.1 jonathan /* Enable interrupts and keyboard, etc. */
581 1.1 jonathan if (!kbc_put8042cmd(CMDBYTE)) {
582 1.13 soda printf("pcprobe: command error\n");
583 1.1 jonathan return 0;
584 1.1 jonathan }
585 1.1 jonathan
586 1.1 jonathan #if 1
587 1.1 jonathan /* Flush any garbage. */
588 1.1 jonathan kbd_flush_input();
589 1.1 jonathan /* Reset the keyboard. */
590 1.1 jonathan if (!kbd_cmd(KBC_RESET, 1)) {
591 1.13 soda printf("pcprobe: reset error %d\n", 1);
592 1.1 jonathan goto lose;
593 1.1 jonathan }
594 1.1 jonathan for (i = 600000; i; i--)
595 1.13 soda if ((inb(kbd_cmdp) & KBS_DIB) != 0) {
596 1.1 jonathan KBD_DELAY;
597 1.1 jonathan break;
598 1.1 jonathan }
599 1.13 soda if (i == 0 || inb(kbd_datap) != KBR_RSTDONE) {
600 1.13 soda printf("pcprobe: reset error %d\n", 2);
601 1.1 jonathan goto lose;
602 1.1 jonathan }
603 1.1 jonathan /*
604 1.1 jonathan * Some keyboards seem to leave a second ack byte after the reset.
605 1.1 jonathan * This is kind of stupid, but we account for them anyway by just
606 1.1 jonathan * flushing the buffer.
607 1.1 jonathan */
608 1.1 jonathan kbd_flush_input();
609 1.1 jonathan /* Just to be sure. */
610 1.1 jonathan if (!kbd_cmd(KBC_ENABLE, 1)) {
611 1.13 soda printf("pcprobe: reset error %d\n", 3);
612 1.1 jonathan goto lose;
613 1.1 jonathan }
614 1.1 jonathan
615 1.1 jonathan /*
616 1.1 jonathan * Some keyboard/8042 combinations do not seem to work if the keyboard
617 1.1 jonathan * is set to table 1; in fact, it would appear that some keyboards just
618 1.1 jonathan * ignore the command altogether. So by default, we use the AT scan
619 1.1 jonathan * codes and have the 8042 translate them. Unfortunately, this is
620 1.1 jonathan * known to not work on some PS/2 machines. We try desparately to deal
621 1.1 jonathan * with this by checking the (lack of a) translate bit in the 8042 and
622 1.1 jonathan * attempting to set the keyboard to XT mode. If this all fails, well,
623 1.1 jonathan * tough luck.
624 1.1 jonathan *
625 1.1 jonathan * XXX It would perhaps be a better choice to just use AT scan codes
626 1.1 jonathan * and not bother with this.
627 1.1 jonathan */
628 1.1 jonathan if (kbc_get8042cmd() & KC8_TRANS) {
629 1.1 jonathan /* The 8042 is translating for us; use AT codes. */
630 1.1 jonathan if (!kbd_cmd(KBC_SETTABLE, 1) || !kbd_cmd(2, 1)) {
631 1.13 soda printf("pcprobe: reset error %d\n", 4);
632 1.1 jonathan goto lose;
633 1.1 jonathan }
634 1.1 jonathan } else {
635 1.1 jonathan /* Stupid 8042; set keyboard to XT codes. */
636 1.1 jonathan if (!kbd_cmd(KBC_SETTABLE, 1) || !kbd_cmd(1, 1)) {
637 1.13 soda printf("pcprobe: reset error %d\n", 5);
638 1.1 jonathan goto lose;
639 1.1 jonathan }
640 1.1 jonathan }
641 1.1 jonathan
642 1.1 jonathan lose:
643 1.1 jonathan /*
644 1.13 soda * Technically, we should probably fail the probe. But we'll be nice
645 1.1 jonathan * and allow keyboard-less machines to boot with the console.
646 1.1 jonathan */
647 1.1 jonathan #endif
648 1.1 jonathan
649 1.1 jonathan return 1;
650 1.1 jonathan }
651 1.1 jonathan
652 1.1 jonathan void
653 1.1 jonathan pcattach(parent, self, aux)
654 1.1 jonathan struct device *parent, *self;
655 1.1 jonathan void *aux;
656 1.1 jonathan {
657 1.23 ur struct jazzio_attach_args *ja = aux;
658 1.13 soda struct isa_attach_args *ia = aux;
659 1.1 jonathan struct pc_softc *sc = (void *)self;
660 1.1 jonathan
661 1.6 christos printf(": %s\n", vs.color ? "color" : "mono");
662 1.1 jonathan do_async_update(1);
663 1.1 jonathan
664 1.20 soda switch (cputype) {
665 1.13 soda case ACER_PICA_61:
666 1.18 soda case NEC_R96:
667 1.23 ur jazzio_intr_establish(ja->ja_intr, pcintr, (void *)(long)sc);
668 1.13 soda break;
669 1.13 soda case DESKSTATION_RPC44: /* XXX ick */
670 1.13 soda case DESKSTATION_TYNE:
671 1.13 soda isa_intr_establish(ia->ia_ic, ia->ia_irq, 1,
672 1.13 soda 2, pcintr, sc); /*XXX ick */
673 1.13 soda break;
674 1.13 soda }
675 1.1 jonathan }
676 1.1 jonathan
677 1.1 jonathan int
678 1.1 jonathan pcopen(dev, flag, mode, p)
679 1.1 jonathan dev_t dev;
680 1.1 jonathan int flag, mode;
681 1.1 jonathan struct proc *p;
682 1.1 jonathan {
683 1.1 jonathan struct pc_softc *sc;
684 1.1 jonathan int unit = PCUNIT(dev);
685 1.1 jonathan struct tty *tp;
686 1.1 jonathan
687 1.2 thorpej if (unit >= pc_cd.cd_ndevs)
688 1.1 jonathan return ENXIO;
689 1.2 thorpej sc = pc_cd.cd_devs[unit];
690 1.1 jonathan if (sc == 0)
691 1.1 jonathan return ENXIO;
692 1.1 jonathan
693 1.1 jonathan if (!sc->sc_tty) {
694 1.1 jonathan tp = sc->sc_tty = ttymalloc();
695 1.1 jonathan }
696 1.1 jonathan else {
697 1.1 jonathan tp = sc->sc_tty;
698 1.1 jonathan }
699 1.1 jonathan
700 1.1 jonathan tp->t_oproc = pcstart;
701 1.1 jonathan tp->t_param = pcparam;
702 1.1 jonathan tp->t_dev = dev;
703 1.1 jonathan if ((tp->t_state & TS_ISOPEN) == 0) {
704 1.1 jonathan ttychars(tp);
705 1.1 jonathan tp->t_iflag = TTYDEF_IFLAG;
706 1.1 jonathan tp->t_oflag = TTYDEF_OFLAG;
707 1.1 jonathan tp->t_cflag = TTYDEF_CFLAG;
708 1.1 jonathan tp->t_lflag = TTYDEF_LFLAG;
709 1.1 jonathan tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
710 1.1 jonathan pcparam(tp, &tp->t_termios);
711 1.1 jonathan ttsetwater(tp);
712 1.1 jonathan } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
713 1.1 jonathan return EBUSY;
714 1.1 jonathan tp->t_state |= TS_CARR_ON;
715 1.1 jonathan
716 1.22 eeh return ((*tp->t_linesw->l_open)(dev, tp));
717 1.1 jonathan }
718 1.1 jonathan
719 1.1 jonathan int
720 1.1 jonathan pcclose(dev, flag, mode, p)
721 1.1 jonathan dev_t dev;
722 1.1 jonathan int flag, mode;
723 1.1 jonathan struct proc *p;
724 1.1 jonathan {
725 1.2 thorpej struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
726 1.1 jonathan struct tty *tp = sc->sc_tty;
727 1.1 jonathan
728 1.22 eeh (*tp->t_linesw->l_close)(tp, flag);
729 1.1 jonathan ttyclose(tp);
730 1.1 jonathan #ifdef notyet /* XXX */
731 1.1 jonathan ttyfree(tp);
732 1.1 jonathan #endif
733 1.1 jonathan return(0);
734 1.1 jonathan }
735 1.1 jonathan
736 1.1 jonathan int
737 1.1 jonathan pcread(dev, uio, flag)
738 1.1 jonathan dev_t dev;
739 1.1 jonathan struct uio *uio;
740 1.1 jonathan int flag;
741 1.1 jonathan {
742 1.2 thorpej struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
743 1.1 jonathan struct tty *tp = sc->sc_tty;
744 1.1 jonathan
745 1.22 eeh return ((*tp->t_linesw->l_read)(tp, uio, flag));
746 1.1 jonathan }
747 1.1 jonathan
748 1.1 jonathan int
749 1.1 jonathan pcwrite(dev, uio, flag)
750 1.1 jonathan dev_t dev;
751 1.1 jonathan struct uio *uio;
752 1.1 jonathan int flag;
753 1.1 jonathan {
754 1.2 thorpej struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
755 1.1 jonathan struct tty *tp = sc->sc_tty;
756 1.1 jonathan
757 1.22 eeh return ((*tp->t_linesw->l_write)(tp, uio, flag));
758 1.25 scw }
759 1.25 scw
760 1.25 scw int
761 1.25 scw pcpoll(dev, events, p)
762 1.25 scw dev_t dev;
763 1.25 scw int events;
764 1.25 scw struct proc *p;
765 1.25 scw {
766 1.25 scw struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
767 1.25 scw struct tty *tp = sc->sc_tty;
768 1.25 scw
769 1.25 scw return ((*tp->t_linesw->l_poll)(tp, events, p));
770 1.1 jonathan }
771 1.1 jonathan
772 1.1 jonathan struct tty *
773 1.1 jonathan pctty(dev)
774 1.1 jonathan dev_t dev;
775 1.1 jonathan {
776 1.2 thorpej struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
777 1.1 jonathan struct tty *tp = sc->sc_tty;
778 1.1 jonathan
779 1.1 jonathan return (tp);
780 1.1 jonathan }
781 1.1 jonathan
782 1.1 jonathan /*
783 1.1 jonathan * Got a console receive interrupt -
784 1.1 jonathan * the console processor wants to give us a character.
785 1.1 jonathan * Catch the character, and see who it goes to.
786 1.1 jonathan */
787 1.1 jonathan int
788 1.1 jonathan pcintr(arg)
789 1.1 jonathan void *arg;
790 1.1 jonathan {
791 1.1 jonathan struct pc_softc *sc = arg;
792 1.1 jonathan register struct tty *tp = sc->sc_tty;
793 1.1 jonathan u_char *cp;
794 1.1 jonathan
795 1.13 soda if ((inb(kbd_cmdp) & KBS_DIB) == 0)
796 1.1 jonathan return 0;
797 1.1 jonathan if (polling)
798 1.1 jonathan return 1;
799 1.1 jonathan do {
800 1.1 jonathan cp = sget();
801 1.1 jonathan if (!tp || (tp->t_state & TS_ISOPEN) == 0)
802 1.1 jonathan return 1;
803 1.1 jonathan if (cp)
804 1.1 jonathan do
805 1.22 eeh (*tp->t_linesw->l_rint)(*cp++, tp);
806 1.1 jonathan while (*cp);
807 1.13 soda } while (inb(kbd_cmdp) & KBS_DIB);
808 1.1 jonathan return 1;
809 1.1 jonathan }
810 1.1 jonathan
811 1.1 jonathan int
812 1.1 jonathan pcioctl(dev, cmd, data, flag, p)
813 1.1 jonathan dev_t dev;
814 1.1 jonathan u_long cmd;
815 1.1 jonathan caddr_t data;
816 1.1 jonathan int flag;
817 1.1 jonathan struct proc *p;
818 1.1 jonathan {
819 1.2 thorpej struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
820 1.1 jonathan struct tty *tp = sc->sc_tty;
821 1.1 jonathan int error;
822 1.1 jonathan
823 1.22 eeh error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p);
824 1.1 jonathan if (error >= 0)
825 1.1 jonathan return error;
826 1.1 jonathan error = ttioctl(tp, cmd, data, flag, p);
827 1.1 jonathan if (error >= 0)
828 1.1 jonathan return error;
829 1.1 jonathan
830 1.1 jonathan switch (cmd) {
831 1.1 jonathan case CONSOLE_X_MODE_ON:
832 1.1 jonathan pc_xmode_on();
833 1.1 jonathan return 0;
834 1.1 jonathan case CONSOLE_X_MODE_OFF:
835 1.1 jonathan pc_xmode_off();
836 1.1 jonathan return 0;
837 1.1 jonathan case CONSOLE_X_BELL:
838 1.1 jonathan /*
839 1.1 jonathan * If set, data is a pointer to a length 2 array of
840 1.1 jonathan * integers. data[0] is the pitch in Hz and data[1]
841 1.1 jonathan * is the duration in msec.
842 1.1 jonathan */
843 1.1 jonathan if (data)
844 1.1 jonathan sysbeep(((int*)data)[0],
845 1.1 jonathan (((int*)data)[1] * hz) / 1000);
846 1.1 jonathan else
847 1.1 jonathan sysbeep(BEEP_FREQ, BEEP_TIME);
848 1.1 jonathan return 0;
849 1.1 jonathan case CONSOLE_SET_TYPEMATIC_RATE: {
850 1.1 jonathan u_char rate;
851 1.1 jonathan
852 1.1 jonathan if (!data)
853 1.1 jonathan return EINVAL;
854 1.1 jonathan rate = *((u_char *)data);
855 1.1 jonathan /*
856 1.1 jonathan * Check that it isn't too big (which would cause it to be
857 1.1 jonathan * confused with a command).
858 1.1 jonathan */
859 1.1 jonathan if (rate & 0x80)
860 1.1 jonathan return EINVAL;
861 1.1 jonathan typematic_rate = rate;
862 1.1 jonathan async_update();
863 1.1 jonathan return 0;
864 1.1 jonathan }
865 1.13 soda case CONSOLE_SET_KEYMAP: {
866 1.13 soda pccons_keymap_t *map = (pccons_keymap_t *) data;
867 1.13 soda int i;
868 1.13 soda
869 1.13 soda if (!data)
870 1.13 soda return EINVAL;
871 1.13 soda for (i = 0; i < KB_NUM_KEYS; i++)
872 1.13 soda if (map[i].unshift[KB_CODE_SIZE-1] ||
873 1.13 soda map[i].shift[KB_CODE_SIZE-1] ||
874 1.13 soda map[i].ctl[KB_CODE_SIZE-1] ||
875 1.13 soda map[i].altgr[KB_CODE_SIZE-1] ||
876 1.13 soda map[i].shift_altgr[KB_CODE_SIZE-1])
877 1.13 soda return EINVAL;
878 1.13 soda
879 1.13 soda bcopy(data, scan_codes, sizeof(pccons_keymap_t[KB_NUM_KEYS]));
880 1.13 soda return 0;
881 1.13 soda }
882 1.13 soda case CONSOLE_GET_KEYMAP:
883 1.13 soda if (!data)
884 1.13 soda return EINVAL;
885 1.13 soda bcopy(scan_codes, data, sizeof(pccons_keymap_t[KB_NUM_KEYS]));
886 1.13 soda return 0;
887 1.13 soda
888 1.1 jonathan default:
889 1.1 jonathan return ENOTTY;
890 1.1 jonathan }
891 1.1 jonathan
892 1.1 jonathan #ifdef DIAGNOSTIC
893 1.1 jonathan panic("pcioctl: impossible");
894 1.1 jonathan #endif
895 1.1 jonathan }
896 1.1 jonathan
897 1.1 jonathan void
898 1.1 jonathan pcstart(tp)
899 1.1 jonathan struct tty *tp;
900 1.1 jonathan {
901 1.1 jonathan struct clist *cl;
902 1.13 soda int s, len;
903 1.1 jonathan u_char buf[PCBURST];
904 1.1 jonathan
905 1.1 jonathan s = spltty();
906 1.1 jonathan if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
907 1.1 jonathan goto out;
908 1.1 jonathan tp->t_state |= TS_BUSY;
909 1.1 jonathan splx(s);
910 1.1 jonathan /*
911 1.1 jonathan * We need to do this outside spl since it could be fairly
912 1.1 jonathan * expensive and we don't want our serial ports to overflow.
913 1.1 jonathan */
914 1.1 jonathan cl = &tp->t_outq;
915 1.1 jonathan len = q_to_b(cl, buf, PCBURST);
916 1.1 jonathan sput(buf, len);
917 1.1 jonathan s = spltty();
918 1.1 jonathan tp->t_state &= ~TS_BUSY;
919 1.1 jonathan if (cl->c_cc) {
920 1.1 jonathan tp->t_state |= TS_TIMEOUT;
921 1.17 thorpej callout_reset(&tp->t_rstrt_ch, 1, ttrstrt, tp);
922 1.1 jonathan }
923 1.1 jonathan if (cl->c_cc <= tp->t_lowat) {
924 1.1 jonathan if (tp->t_state & TS_ASLEEP) {
925 1.1 jonathan tp->t_state &= ~TS_ASLEEP;
926 1.1 jonathan wakeup(cl);
927 1.1 jonathan }
928 1.1 jonathan selwakeup(&tp->t_wsel);
929 1.1 jonathan }
930 1.1 jonathan out:
931 1.1 jonathan splx(s);
932 1.1 jonathan }
933 1.1 jonathan
934 1.1 jonathan void
935 1.1 jonathan pcstop(tp, flag)
936 1.1 jonathan struct tty *tp;
937 1.1 jonathan int flag;
938 1.1 jonathan {
939 1.1 jonathan }
940 1.1 jonathan
941 1.13 soda /* ARGSUSED */
942 1.1 jonathan void
943 1.13 soda pccnattach()
944 1.1 jonathan {
945 1.1 jonathan int maj;
946 1.13 soda static struct consdev pccons = {
947 1.16 thorpej NULL, NULL, pccngetc, pccnputc, pccnpollc, NULL,
948 1.16 thorpej NODEV, CN_NORMAL
949 1.13 soda };
950 1.13 soda
951 1.13 soda /*
952 1.13 soda * For now, don't screw with it.
953 1.13 soda */
954 1.13 soda /* crtat = 0; */
955 1.20 soda pcinithandle();
956 1.20 soda
957 1.20 soda switch (cputype) {
958 1.13 soda
959 1.13 soda case ACER_PICA_61:
960 1.18 soda case NEC_R96: /* XXX - not really confirmed */
961 1.13 soda break;
962 1.13 soda
963 1.13 soda case DESKSTATION_TYNE:
964 1.18 soda outb(arc_bus_io.bs_vbase + 0x3ce, 6); /* Correct video mode */
965 1.18 soda outb(arc_bus_io.bs_vbase + 0x3cf,
966 1.18 soda inb(arc_bus_io.bs_vbase + 0x3cf) | 0xc);
967 1.13 soda kbc_put8042cmd(CMDBYTE); /* Want XT codes.. */
968 1.13 soda break;
969 1.13 soda
970 1.13 soda case DESKSTATION_RPC44:
971 1.13 soda kbc_put8042cmd(CMDBYTE); /* Want XT codes.. */
972 1.13 soda break;
973 1.14 soda
974 1.14 soda case SNI_RM200:
975 1.14 soda break;
976 1.13 soda }
977 1.1 jonathan
978 1.1 jonathan /* locate the major number */
979 1.1 jonathan for (maj = 0; maj < nchrdev; maj++)
980 1.1 jonathan if (cdevsw[maj].d_open == pcopen)
981 1.1 jonathan break;
982 1.13 soda pccons.cn_dev = makedev(maj, 0);
983 1.1 jonathan
984 1.13 soda cn_tab = &pccons;
985 1.1 jonathan }
986 1.1 jonathan
987 1.1 jonathan /* ARGSUSED */
988 1.1 jonathan void
989 1.1 jonathan pccnputc(dev, c)
990 1.1 jonathan dev_t dev;
991 1.13 soda int c;
992 1.1 jonathan {
993 1.15 soda u_char cc, oldkernel = kernel;
994 1.1 jonathan
995 1.1 jonathan kernel = 1;
996 1.15 soda if (c == '\n') {
997 1.1 jonathan sput("\r\n", 2);
998 1.15 soda } else {
999 1.15 soda cc = c;
1000 1.15 soda sput(&cc, 1);
1001 1.15 soda }
1002 1.1 jonathan kernel = oldkernel;
1003 1.1 jonathan }
1004 1.1 jonathan
1005 1.1 jonathan /* ARGSUSED */
1006 1.13 soda int
1007 1.1 jonathan pccngetc(dev)
1008 1.1 jonathan dev_t dev;
1009 1.1 jonathan {
1010 1.1 jonathan register char *cp;
1011 1.1 jonathan
1012 1.1 jonathan if (pc_xmode > 0)
1013 1.1 jonathan return 0;
1014 1.1 jonathan
1015 1.1 jonathan do {
1016 1.1 jonathan /* wait for byte */
1017 1.13 soda while ((inb(kbd_cmdp) & KBS_DIB) == 0);
1018 1.1 jonathan /* see if it's worthwhile */
1019 1.1 jonathan cp = sget();
1020 1.1 jonathan } while (!cp);
1021 1.1 jonathan if (*cp == '\r')
1022 1.1 jonathan return '\n';
1023 1.1 jonathan return *cp;
1024 1.1 jonathan }
1025 1.1 jonathan
1026 1.1 jonathan void
1027 1.1 jonathan pccnpollc(dev, on)
1028 1.1 jonathan dev_t dev;
1029 1.1 jonathan int on;
1030 1.1 jonathan {
1031 1.1 jonathan
1032 1.1 jonathan polling = on;
1033 1.1 jonathan if (!on) {
1034 1.1 jonathan int unit;
1035 1.1 jonathan struct pc_softc *sc;
1036 1.1 jonathan int s;
1037 1.1 jonathan
1038 1.1 jonathan /*
1039 1.1 jonathan * If disabling polling on a device that's been configured,
1040 1.1 jonathan * make sure there are no bytes left in the FIFO, holding up
1041 1.1 jonathan * the interrupt line. Otherwise we won't get any further
1042 1.1 jonathan * interrupts.
1043 1.1 jonathan */
1044 1.1 jonathan unit = PCUNIT(dev);
1045 1.2 thorpej if (pc_cd.cd_ndevs > unit) {
1046 1.2 thorpej sc = pc_cd.cd_devs[unit];
1047 1.1 jonathan if (sc != 0) {
1048 1.1 jonathan s = spltty();
1049 1.1 jonathan pcintr(sc);
1050 1.1 jonathan splx(s);
1051 1.1 jonathan }
1052 1.1 jonathan }
1053 1.1 jonathan }
1054 1.1 jonathan }
1055 1.1 jonathan
1056 1.1 jonathan /*
1057 1.1 jonathan * Set line parameters.
1058 1.1 jonathan */
1059 1.1 jonathan int
1060 1.1 jonathan pcparam(tp, t)
1061 1.1 jonathan struct tty *tp;
1062 1.1 jonathan struct termios *t;
1063 1.1 jonathan {
1064 1.1 jonathan
1065 1.1 jonathan tp->t_ispeed = t->c_ispeed;
1066 1.1 jonathan tp->t_ospeed = t->c_ospeed;
1067 1.1 jonathan tp->t_cflag = t->c_cflag;
1068 1.1 jonathan return 0;
1069 1.1 jonathan }
1070 1.1 jonathan
1071 1.1 jonathan #define wrtchar(c, at) do {\
1072 1.1 jonathan char *cp = (char *)crtat; *cp++ = (c); *cp = (at); crtat++; vs.col++; \
1073 1.1 jonathan } while (0)
1074 1.1 jonathan
1075 1.1 jonathan /* translate ANSI color codes to standard pc ones */
1076 1.1 jonathan static char fgansitopc[] = {
1077 1.1 jonathan FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
1078 1.1 jonathan FG_MAGENTA, FG_CYAN, FG_LIGHTGREY
1079 1.1 jonathan };
1080 1.1 jonathan
1081 1.1 jonathan static char bgansitopc[] = {
1082 1.1 jonathan BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
1083 1.1 jonathan BG_MAGENTA, BG_CYAN, BG_LIGHTGREY
1084 1.1 jonathan };
1085 1.1 jonathan
1086 1.1 jonathan static u_char iso2ibm437[] =
1087 1.1 jonathan {
1088 1.1 jonathan 0, 0, 0, 0, 0, 0, 0, 0,
1089 1.1 jonathan 0, 0, 0, 0, 0, 0, 0, 0,
1090 1.1 jonathan 0, 0, 0, 0, 0, 0, 0, 0,
1091 1.1 jonathan 0, 0, 0, 0, 0, 0, 0, 0,
1092 1.1 jonathan 0xff, 0xad, 0x9b, 0x9c, 0, 0x9d, 0, 0x40,
1093 1.1 jonathan 0x6f, 0x63, 0x61, 0xae, 0, 0, 0, 0,
1094 1.1 jonathan 0xf8, 0xf1, 0xfd, 0x33, 0, 0xe6, 0, 0xfa,
1095 1.1 jonathan 0, 0x31, 0x6f, 0xaf, 0xac, 0xab, 0, 0xa8,
1096 1.1 jonathan 0x41, 0x41, 0x41, 0x41, 0x8e, 0x8f, 0x92, 0x80,
1097 1.1 jonathan 0x45, 0x90, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49,
1098 1.1 jonathan 0x81, 0xa5, 0x4f, 0x4f, 0x4f, 0x4f, 0x99, 0x4f,
1099 1.1 jonathan 0x4f, 0x55, 0x55, 0x55, 0x9a, 0x59, 0, 0xe1,
1100 1.1 jonathan 0x85, 0xa0, 0x83, 0x61, 0x84, 0x86, 0x91, 0x87,
1101 1.1 jonathan 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b,
1102 1.1 jonathan 0, 0xa4, 0x95, 0xa2, 0x93, 0x6f, 0x94, 0x6f,
1103 1.1 jonathan 0x6f, 0x97, 0xa3, 0x96, 0x81, 0x98, 0, 0
1104 1.1 jonathan };
1105 1.1 jonathan
1106 1.1 jonathan /*
1107 1.1 jonathan * `pc3' termcap emulation.
1108 1.1 jonathan */
1109 1.1 jonathan void
1110 1.1 jonathan sput(cp, n)
1111 1.1 jonathan u_char *cp;
1112 1.1 jonathan int n;
1113 1.1 jonathan {
1114 1.1 jonathan u_char c, scroll = 0;
1115 1.1 jonathan
1116 1.1 jonathan if (pc_xmode > 0)
1117 1.1 jonathan return;
1118 1.1 jonathan
1119 1.1 jonathan if (crtat == 0) {
1120 1.13 soda volatile u_short *cp;
1121 1.1 jonathan u_short was;
1122 1.1 jonathan unsigned cursorat;
1123 1.1 jonathan
1124 1.13 soda cp = (volatile u_short *)cga_buf;
1125 1.1 jonathan was = *cp;
1126 1.13 soda *cp = (volatile u_short) 0xA55A;
1127 1.1 jonathan if (*cp != 0xA55A) {
1128 1.13 soda cp = (volatile u_short *)mono_buf;
1129 1.13 soda addr_6845 = mono_base;
1130 1.1 jonathan vs.color = 0;
1131 1.1 jonathan } else {
1132 1.1 jonathan *cp = was;
1133 1.13 soda addr_6845 = cga_base;
1134 1.1 jonathan vs.color = 1;
1135 1.1 jonathan }
1136 1.1 jonathan
1137 1.1 jonathan #ifdef FAT_CURSOR
1138 1.1 jonathan cursor_shape = 0x0012;
1139 1.1 jonathan #else
1140 1.1 jonathan get_cursor_shape();
1141 1.1 jonathan #endif
1142 1.1 jonathan
1143 1.13 soda bios_display_info(&vs.col, &vs.row, &vs.ncol, &vs.nrow);
1144 1.13 soda vs.nchr = vs.ncol * vs.nrow;
1145 1.13 soda vs.col--;
1146 1.13 soda vs.row--;
1147 1.13 soda cursorat = vs.ncol * vs.row + vs.col;
1148 1.13 soda vs.at = FG_LIGHTGREY | BG_BLACK;
1149 1.13 soda
1150 1.1 jonathan Crtat = (u_short *)cp;
1151 1.13 soda crtat = Crtat + cursorat;
1152 1.1 jonathan
1153 1.1 jonathan if (vs.color == 0)
1154 1.1 jonathan vs.so_at = FG_BLACK | BG_LIGHTGREY;
1155 1.1 jonathan else
1156 1.1 jonathan vs.so_at = FG_YELLOW | BG_BLACK;
1157 1.1 jonathan
1158 1.1 jonathan fillw((vs.at << 8) | ' ', crtat, vs.nchr - cursorat);
1159 1.1 jonathan }
1160 1.1 jonathan
1161 1.1 jonathan while (n--) {
1162 1.1 jonathan if (!(c = *cp++))
1163 1.1 jonathan continue;
1164 1.1 jonathan
1165 1.1 jonathan switch (c) {
1166 1.1 jonathan case 0x1B:
1167 1.1 jonathan if (vs.state >= VSS_ESCAPE) {
1168 1.1 jonathan wrtchar(c, vs.so_at);
1169 1.1 jonathan vs.state = 0;
1170 1.1 jonathan goto maybe_scroll;
1171 1.1 jonathan } else
1172 1.1 jonathan vs.state = VSS_ESCAPE;
1173 1.1 jonathan break;
1174 1.1 jonathan
1175 1.13 soda case 0x9B: /* CSI */
1176 1.13 soda vs.cx = vs.cy = 0;
1177 1.13 soda vs.state = VSS_EBRACE;
1178 1.13 soda break;
1179 1.13 soda
1180 1.1 jonathan case '\t': {
1181 1.1 jonathan int inccol = 8 - (vs.col & 7);
1182 1.1 jonathan crtat += inccol;
1183 1.1 jonathan vs.col += inccol;
1184 1.1 jonathan }
1185 1.1 jonathan maybe_scroll:
1186 1.13 soda if (vs.col >= vs.ncol) {
1187 1.13 soda vs.col -= vs.ncol;
1188 1.1 jonathan scroll = 1;
1189 1.1 jonathan }
1190 1.1 jonathan break;
1191 1.1 jonathan
1192 1.13 soda case '\b':
1193 1.1 jonathan if (crtat <= Crtat)
1194 1.1 jonathan break;
1195 1.1 jonathan --crtat;
1196 1.1 jonathan if (--vs.col < 0)
1197 1.13 soda vs.col += vs.ncol; /* non-destructive backspace */
1198 1.1 jonathan break;
1199 1.1 jonathan
1200 1.1 jonathan case '\r':
1201 1.1 jonathan crtat -= vs.col;
1202 1.1 jonathan vs.col = 0;
1203 1.1 jonathan break;
1204 1.1 jonathan
1205 1.1 jonathan case '\n':
1206 1.1 jonathan crtat += vs.ncol;
1207 1.1 jonathan scroll = 1;
1208 1.1 jonathan break;
1209 1.1 jonathan
1210 1.1 jonathan default:
1211 1.1 jonathan switch (vs.state) {
1212 1.1 jonathan case 0:
1213 1.1 jonathan if (c == '\a')
1214 1.1 jonathan sysbeep(BEEP_FREQ, BEEP_TIME);
1215 1.1 jonathan else {
1216 1.1 jonathan /*
1217 1.1 jonathan * If we're outputting multiple printed
1218 1.1 jonathan * characters, just blast them to the
1219 1.1 jonathan * screen until we reach the end of the
1220 1.1 jonathan * buffer or a control character. This
1221 1.1 jonathan * saves time by short-circuiting the
1222 1.1 jonathan * switch.
1223 1.1 jonathan * If we reach the end of the line, we
1224 1.1 jonathan * break to do a scroll check.
1225 1.1 jonathan */
1226 1.1 jonathan for (;;) {
1227 1.1 jonathan if (c & 0x80)
1228 1.1 jonathan c = iso2ibm437[c&0x7f];
1229 1.1 jonathan
1230 1.1 jonathan if (vs.so)
1231 1.1 jonathan wrtchar(c, vs.so_at);
1232 1.1 jonathan else
1233 1.1 jonathan wrtchar(c, vs.at);
1234 1.1 jonathan if (vs.col >= vs.ncol) {
1235 1.1 jonathan vs.col = 0;
1236 1.1 jonathan scroll = 1;
1237 1.1 jonathan break;
1238 1.1 jonathan }
1239 1.1 jonathan if (!n || (c = *cp) < ' ')
1240 1.1 jonathan break;
1241 1.1 jonathan n--, cp++;
1242 1.1 jonathan }
1243 1.1 jonathan }
1244 1.1 jonathan break;
1245 1.1 jonathan case VSS_ESCAPE:
1246 1.13 soda switch (c) {
1247 1.13 soda case '[': /* Start ESC [ sequence */
1248 1.13 soda vs.cx = vs.cy = 0;
1249 1.13 soda vs.state = VSS_EBRACE;
1250 1.13 soda break;
1251 1.13 soda case 'c': /* Create screen & home */
1252 1.13 soda fillw((vs.at << 8) | ' ',
1253 1.13 soda Crtat, vs.nchr);
1254 1.13 soda crtat = Crtat;
1255 1.13 soda vs.col = 0;
1256 1.13 soda vs.state = 0;
1257 1.13 soda break;
1258 1.13 soda case '7': /* save cursor pos */
1259 1.13 soda vs.offset = crtat - Crtat;
1260 1.13 soda vs.state = 0;
1261 1.13 soda break;
1262 1.13 soda case '8': /* restore cursor pos */
1263 1.13 soda crtat = Crtat + vs.offset;
1264 1.13 soda vs.row = vs.offset / vs.ncol;
1265 1.13 soda vs.col = vs.offset % vs.ncol;
1266 1.13 soda vs.state = 0;
1267 1.13 soda break;
1268 1.13 soda default: /* Invalid, clear state */
1269 1.13 soda wrtchar(c, vs.so_at);
1270 1.13 soda vs.state = 0;
1271 1.13 soda goto maybe_scroll;
1272 1.1 jonathan }
1273 1.1 jonathan break;
1274 1.13 soda
1275 1.1 jonathan default: /* VSS_EBRACE or VSS_EPARAM */
1276 1.1 jonathan switch (c) {
1277 1.1 jonathan int pos;
1278 1.1 jonathan case 'm':
1279 1.1 jonathan if (!vs.cx)
1280 1.1 jonathan vs.so = 0;
1281 1.1 jonathan else
1282 1.1 jonathan vs.so = 1;
1283 1.1 jonathan vs.state = 0;
1284 1.1 jonathan break;
1285 1.1 jonathan case 'A': { /* back cx rows */
1286 1.1 jonathan int cx = vs.cx;
1287 1.1 jonathan if (cx <= 0)
1288 1.1 jonathan cx = 1;
1289 1.1 jonathan else
1290 1.1 jonathan cx %= vs.nrow;
1291 1.1 jonathan pos = crtat - Crtat;
1292 1.1 jonathan pos -= vs.ncol * cx;
1293 1.1 jonathan if (pos < 0)
1294 1.1 jonathan pos += vs.nchr;
1295 1.1 jonathan crtat = Crtat + pos;
1296 1.1 jonathan vs.state = 0;
1297 1.1 jonathan break;
1298 1.1 jonathan }
1299 1.1 jonathan case 'B': { /* down cx rows */
1300 1.1 jonathan int cx = vs.cx;
1301 1.1 jonathan if (cx <= 0)
1302 1.1 jonathan cx = 1;
1303 1.1 jonathan else
1304 1.1 jonathan cx %= vs.nrow;
1305 1.1 jonathan pos = crtat - Crtat;
1306 1.1 jonathan pos += vs.ncol * cx;
1307 1.1 jonathan if (pos >= vs.nchr)
1308 1.1 jonathan pos -= vs.nchr;
1309 1.1 jonathan crtat = Crtat + pos;
1310 1.1 jonathan vs.state = 0;
1311 1.1 jonathan break;
1312 1.1 jonathan }
1313 1.1 jonathan case 'C': { /* right cursor */
1314 1.1 jonathan int cx = vs.cx,
1315 1.1 jonathan col = vs.col;
1316 1.1 jonathan if (cx <= 0)
1317 1.1 jonathan cx = 1;
1318 1.1 jonathan else
1319 1.1 jonathan cx %= vs.ncol;
1320 1.1 jonathan pos = crtat - Crtat;
1321 1.1 jonathan pos += cx;
1322 1.1 jonathan col += cx;
1323 1.1 jonathan if (col >= vs.ncol) {
1324 1.1 jonathan pos -= vs.ncol;
1325 1.1 jonathan col -= vs.ncol;
1326 1.1 jonathan }
1327 1.1 jonathan vs.col = col;
1328 1.1 jonathan crtat = Crtat + pos;
1329 1.1 jonathan vs.state = 0;
1330 1.1 jonathan break;
1331 1.1 jonathan }
1332 1.1 jonathan case 'D': { /* left cursor */
1333 1.1 jonathan int cx = vs.cx,
1334 1.1 jonathan col = vs.col;
1335 1.1 jonathan if (cx <= 0)
1336 1.1 jonathan cx = 1;
1337 1.1 jonathan else
1338 1.1 jonathan cx %= vs.ncol;
1339 1.1 jonathan pos = crtat - Crtat;
1340 1.1 jonathan pos -= cx;
1341 1.1 jonathan col -= cx;
1342 1.1 jonathan if (col < 0) {
1343 1.1 jonathan pos += vs.ncol;
1344 1.1 jonathan col += vs.ncol;
1345 1.1 jonathan }
1346 1.1 jonathan vs.col = col;
1347 1.1 jonathan crtat = Crtat + pos;
1348 1.1 jonathan vs.state = 0;
1349 1.1 jonathan break;
1350 1.1 jonathan }
1351 1.1 jonathan case 'J': /* Clear ... */
1352 1.1 jonathan switch (vs.cx) {
1353 1.1 jonathan case 0:
1354 1.1 jonathan /* ... to end of display */
1355 1.13 soda fillw((vs.at << 8) | ' ',
1356 1.13 soda crtat,
1357 1.1 jonathan Crtat + vs.nchr - crtat);
1358 1.1 jonathan break;
1359 1.1 jonathan case 1:
1360 1.1 jonathan /* ... to next location */
1361 1.13 soda fillw((vs.at << 8) | ' ',
1362 1.13 soda Crtat,
1363 1.1 jonathan crtat - Crtat + 1);
1364 1.1 jonathan break;
1365 1.1 jonathan case 2:
1366 1.1 jonathan /* ... whole display */
1367 1.13 soda fillw((vs.at << 8) | ' ',
1368 1.13 soda Crtat,
1369 1.1 jonathan vs.nchr);
1370 1.1 jonathan break;
1371 1.1 jonathan }
1372 1.1 jonathan vs.state = 0;
1373 1.1 jonathan break;
1374 1.1 jonathan case 'K': /* Clear line ... */
1375 1.1 jonathan switch (vs.cx) {
1376 1.1 jonathan case 0:
1377 1.1 jonathan /* ... current to EOL */
1378 1.13 soda fillw((vs.at << 8) | ' ',
1379 1.13 soda crtat,
1380 1.1 jonathan vs.ncol - vs.col);
1381 1.1 jonathan break;
1382 1.1 jonathan case 1:
1383 1.1 jonathan /* ... beginning to next */
1384 1.1 jonathan fillw((vs.at << 8) | ' ',
1385 1.1 jonathan crtat - vs.col,
1386 1.1 jonathan vs.col + 1);
1387 1.1 jonathan break;
1388 1.1 jonathan case 2:
1389 1.1 jonathan /* ... entire line */
1390 1.1 jonathan fillw((vs.at << 8) | ' ',
1391 1.1 jonathan crtat - vs.col, vs.ncol);
1392 1.1 jonathan break;
1393 1.1 jonathan }
1394 1.1 jonathan vs.state = 0;
1395 1.1 jonathan break;
1396 1.1 jonathan case 'f': /* in system V consoles */
1397 1.1 jonathan case 'H': { /* Cursor move */
1398 1.1 jonathan int cx = vs.cx,
1399 1.1 jonathan cy = vs.cy;
1400 1.1 jonathan if (!cx || !cy) {
1401 1.1 jonathan crtat = Crtat;
1402 1.1 jonathan vs.col = 0;
1403 1.1 jonathan } else {
1404 1.1 jonathan if (cx > vs.nrow)
1405 1.1 jonathan cx = vs.nrow;
1406 1.1 jonathan if (cy > vs.ncol)
1407 1.1 jonathan cy = vs.ncol;
1408 1.1 jonathan crtat = Crtat +
1409 1.1 jonathan (cx - 1) * vs.ncol + cy - 1;
1410 1.1 jonathan vs.col = cy - 1;
1411 1.1 jonathan }
1412 1.1 jonathan vs.state = 0;
1413 1.1 jonathan break;
1414 1.1 jonathan }
1415 1.1 jonathan case 'M': { /* delete cx rows */
1416 1.1 jonathan u_short *crtAt = crtat - vs.col;
1417 1.1 jonathan int cx = vs.cx,
1418 1.1 jonathan row = (crtAt - Crtat) / vs.ncol,
1419 1.1 jonathan nrow = vs.nrow - row;
1420 1.1 jonathan if (cx <= 0)
1421 1.1 jonathan cx = 1;
1422 1.1 jonathan else if (cx > nrow)
1423 1.1 jonathan cx = nrow;
1424 1.1 jonathan if (cx < nrow)
1425 1.13 soda #ifdef PCCONS_FORCE_WORD
1426 1.13 soda wcopy(crtAt + vs.ncol * cx,
1427 1.13 soda crtAt, vs.ncol * (nrow -
1428 1.13 soda cx) * CHR);
1429 1.13 soda #else
1430 1.1 jonathan bcopy(crtAt + vs.ncol * cx,
1431 1.1 jonathan crtAt, vs.ncol * (nrow -
1432 1.1 jonathan cx) * CHR);
1433 1.13 soda #endif
1434 1.1 jonathan fillw((vs.at << 8) | ' ',
1435 1.1 jonathan crtAt + vs.ncol * (nrow - cx),
1436 1.1 jonathan vs.ncol * cx);
1437 1.1 jonathan vs.state = 0;
1438 1.1 jonathan break;
1439 1.1 jonathan }
1440 1.1 jonathan case 'S': { /* scroll up cx lines */
1441 1.1 jonathan int cx = vs.cx;
1442 1.1 jonathan if (cx <= 0)
1443 1.1 jonathan cx = 1;
1444 1.1 jonathan else if (cx > vs.nrow)
1445 1.1 jonathan cx = vs.nrow;
1446 1.1 jonathan if (cx < vs.nrow)
1447 1.13 soda #ifdef PCCONS_FORCE_WORD
1448 1.13 soda wcopy(Crtat + vs.ncol * cx,
1449 1.13 soda Crtat, vs.ncol * (vs.nrow -
1450 1.13 soda cx) * CHR);
1451 1.13 soda #else
1452 1.1 jonathan bcopy(Crtat + vs.ncol * cx,
1453 1.1 jonathan Crtat, vs.ncol * (vs.nrow -
1454 1.1 jonathan cx) * CHR);
1455 1.13 soda #endif
1456 1.1 jonathan fillw((vs.at << 8) | ' ',
1457 1.1 jonathan Crtat + vs.ncol * (vs.nrow - cx),
1458 1.1 jonathan vs.ncol * cx);
1459 1.13 soda /* crtat -= vs.ncol * cx; XXX */
1460 1.1 jonathan vs.state = 0;
1461 1.1 jonathan break;
1462 1.1 jonathan }
1463 1.1 jonathan case 'L': { /* insert cx rows */
1464 1.1 jonathan u_short *crtAt = crtat - vs.col;
1465 1.1 jonathan int cx = vs.cx,
1466 1.1 jonathan row = (crtAt - Crtat) / vs.ncol,
1467 1.1 jonathan nrow = vs.nrow - row;
1468 1.1 jonathan if (cx <= 0)
1469 1.1 jonathan cx = 1;
1470 1.1 jonathan else if (cx > nrow)
1471 1.1 jonathan cx = nrow;
1472 1.1 jonathan if (cx < nrow)
1473 1.13 soda #ifdef PCCONS_FORCE_WORD
1474 1.13 soda wcopy(crtAt,
1475 1.13 soda crtAt + vs.ncol * cx,
1476 1.13 soda vs.ncol * (nrow - cx) *
1477 1.13 soda CHR);
1478 1.13 soda #else
1479 1.1 jonathan bcopy(crtAt,
1480 1.1 jonathan crtAt + vs.ncol * cx,
1481 1.1 jonathan vs.ncol * (nrow - cx) *
1482 1.1 jonathan CHR);
1483 1.13 soda #endif
1484 1.1 jonathan fillw((vs.at << 8) | ' ', crtAt,
1485 1.1 jonathan vs.ncol * cx);
1486 1.1 jonathan vs.state = 0;
1487 1.1 jonathan break;
1488 1.1 jonathan }
1489 1.1 jonathan case 'T': { /* scroll down cx lines */
1490 1.1 jonathan int cx = vs.cx;
1491 1.1 jonathan if (cx <= 0)
1492 1.1 jonathan cx = 1;
1493 1.1 jonathan else if (cx > vs.nrow)
1494 1.1 jonathan cx = vs.nrow;
1495 1.1 jonathan if (cx < vs.nrow)
1496 1.13 soda #ifdef PCCONS_FORCE_WORD
1497 1.13 soda wcopy(Crtat,
1498 1.13 soda Crtat + vs.ncol * cx,
1499 1.13 soda vs.ncol * (vs.nrow - cx) *
1500 1.13 soda CHR);
1501 1.13 soda #else
1502 1.1 jonathan bcopy(Crtat,
1503 1.1 jonathan Crtat + vs.ncol * cx,
1504 1.1 jonathan vs.ncol * (vs.nrow - cx) *
1505 1.1 jonathan CHR);
1506 1.13 soda #endif
1507 1.1 jonathan fillw((vs.at << 8) | ' ', Crtat,
1508 1.1 jonathan vs.ncol * cx);
1509 1.13 soda /* crtat += vs.ncol * cx; XXX */
1510 1.1 jonathan vs.state = 0;
1511 1.1 jonathan break;
1512 1.1 jonathan }
1513 1.1 jonathan case ';': /* Switch params in cursor def */
1514 1.1 jonathan vs.state = VSS_EPARAM;
1515 1.1 jonathan break;
1516 1.1 jonathan case 'r':
1517 1.1 jonathan vs.so_at = (vs.cx & FG_MASK) |
1518 1.1 jonathan ((vs.cy << 4) & BG_MASK);
1519 1.1 jonathan vs.state = 0;
1520 1.1 jonathan break;
1521 1.13 soda case 's': /* save cursor pos */
1522 1.13 soda vs.offset = crtat - Crtat;
1523 1.13 soda vs.state = 0;
1524 1.13 soda break;
1525 1.13 soda case 'u': /* restore cursor pos */
1526 1.13 soda crtat = Crtat + vs.offset;
1527 1.13 soda vs.row = vs.offset / vs.ncol;
1528 1.13 soda vs.col = vs.offset % vs.ncol;
1529 1.13 soda vs.state = 0;
1530 1.13 soda break;
1531 1.1 jonathan case 'x': /* set attributes */
1532 1.1 jonathan switch (vs.cx) {
1533 1.1 jonathan case 0:
1534 1.1 jonathan vs.at = FG_LIGHTGREY | BG_BLACK;
1535 1.1 jonathan break;
1536 1.1 jonathan case 1:
1537 1.1 jonathan /* ansi background */
1538 1.1 jonathan if (!vs.color)
1539 1.1 jonathan break;
1540 1.1 jonathan vs.at &= FG_MASK;
1541 1.1 jonathan vs.at |= bgansitopc[vs.cy & 7];
1542 1.1 jonathan break;
1543 1.1 jonathan case 2:
1544 1.1 jonathan /* ansi foreground */
1545 1.1 jonathan if (!vs.color)
1546 1.1 jonathan break;
1547 1.1 jonathan vs.at &= BG_MASK;
1548 1.1 jonathan vs.at |= fgansitopc[vs.cy & 7];
1549 1.1 jonathan break;
1550 1.1 jonathan case 3:
1551 1.1 jonathan /* pc text attribute */
1552 1.1 jonathan if (vs.state >= VSS_EPARAM)
1553 1.1 jonathan vs.at = vs.cy;
1554 1.1 jonathan break;
1555 1.1 jonathan }
1556 1.1 jonathan vs.state = 0;
1557 1.1 jonathan break;
1558 1.1 jonathan
1559 1.1 jonathan default: /* Only numbers valid here */
1560 1.1 jonathan if ((c >= '0') && (c <= '9')) {
1561 1.1 jonathan if (vs.state >= VSS_EPARAM) {
1562 1.1 jonathan vs.cy *= 10;
1563 1.1 jonathan vs.cy += c - '0';
1564 1.1 jonathan } else {
1565 1.1 jonathan vs.cx *= 10;
1566 1.1 jonathan vs.cx += c - '0';
1567 1.1 jonathan }
1568 1.1 jonathan } else
1569 1.1 jonathan vs.state = 0;
1570 1.1 jonathan break;
1571 1.1 jonathan }
1572 1.1 jonathan break;
1573 1.1 jonathan }
1574 1.1 jonathan }
1575 1.1 jonathan if (scroll) {
1576 1.1 jonathan scroll = 0;
1577 1.1 jonathan /* scroll check */
1578 1.1 jonathan if (crtat >= Crtat + vs.nchr) {
1579 1.1 jonathan if (!kernel) {
1580 1.1 jonathan int s = spltty();
1581 1.13 soda if (lock_state & KB_SCROLL)
1582 1.13 soda tsleep(&lock_state,
1583 1.1 jonathan PUSER, "pcputc", 0);
1584 1.1 jonathan splx(s);
1585 1.1 jonathan }
1586 1.13 soda #if PCCONS_FORCE_WORD
1587 1.13 soda wcopy(Crtat + vs.ncol, Crtat,
1588 1.13 soda (vs.nchr - vs.ncol) * CHR);
1589 1.13 soda #else
1590 1.1 jonathan bcopy(Crtat + vs.ncol, Crtat,
1591 1.1 jonathan (vs.nchr - vs.ncol) * CHR);
1592 1.13 soda #endif
1593 1.1 jonathan fillw((vs.at << 8) | ' ',
1594 1.13 soda Crtat + vs.nchr - vs.ncol,
1595 1.13 soda vs.ncol);
1596 1.1 jonathan crtat -= vs.ncol;
1597 1.1 jonathan }
1598 1.1 jonathan }
1599 1.1 jonathan }
1600 1.1 jonathan async_update();
1601 1.1 jonathan }
1602 1.1 jonathan
1603 1.13 soda /* the unshifted code for KB_SHIFT keys is used by X to distinguish between
1604 1.13 soda left and right shift when reading the keyboard map */
1605 1.13 soda static pccons_keymap_t scan_codes[KB_NUM_KEYS] = {
1606 1.13 soda /* type unshift shift control altgr shift_altgr scancode */
1607 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 0 unused */
1608 1.13 soda { KB_ASCII, "\033", "\033", "\033", "", ""}, /* 1 ESCape */
1609 1.13 soda { KB_ASCII, "1", "!", "!", "", ""}, /* 2 1 */
1610 1.13 soda { KB_ASCII, "2", "@", "\000", "", ""}, /* 3 2 */
1611 1.13 soda { KB_ASCII, "3", "#", "#", "", ""}, /* 4 3 */
1612 1.13 soda { KB_ASCII, "4", "$", "$", "", ""}, /* 5 4 */
1613 1.13 soda { KB_ASCII, "5", "%", "%", "", ""}, /* 6 5 */
1614 1.13 soda { KB_ASCII, "6", "^", "\036", "", ""}, /* 7 6 */
1615 1.13 soda { KB_ASCII, "7", "&", "&", "", ""}, /* 8 7 */
1616 1.13 soda { KB_ASCII, "8", "*", "\010", "", ""}, /* 9 8 */
1617 1.13 soda { KB_ASCII, "9", "(", "(", "", ""}, /* 10 9 */
1618 1.13 soda { KB_ASCII, "0", ")", ")", "", ""}, /* 11 0 */
1619 1.13 soda { KB_ASCII, "-", "_", "\037", "", ""}, /* 12 - */
1620 1.13 soda { KB_ASCII, "=", "+", "+", "", ""}, /* 13 = */
1621 1.13 soda { KB_ASCII, "\177", "\177", "\010", "", ""}, /* 14 backspace */
1622 1.13 soda { KB_ASCII, "\t", "\t", "\t", "", ""}, /* 15 tab */
1623 1.13 soda { KB_ASCII, "q", "Q", "\021", "", ""}, /* 16 q */
1624 1.13 soda { KB_ASCII, "w", "W", "\027", "", ""}, /* 17 w */
1625 1.13 soda { KB_ASCII, "e", "E", "\005", "", ""}, /* 18 e */
1626 1.13 soda { KB_ASCII, "r", "R", "\022", "", ""}, /* 19 r */
1627 1.13 soda { KB_ASCII, "t", "T", "\024", "", ""}, /* 20 t */
1628 1.13 soda { KB_ASCII, "y", "Y", "\031", "", ""}, /* 21 y */
1629 1.13 soda { KB_ASCII, "u", "U", "\025", "", ""}, /* 22 u */
1630 1.13 soda { KB_ASCII, "i", "I", "\011", "", ""}, /* 23 i */
1631 1.13 soda { KB_ASCII, "o", "O", "\017", "", ""}, /* 24 o */
1632 1.13 soda { KB_ASCII, "p", "P", "\020", "", ""}, /* 25 p */
1633 1.13 soda { KB_ASCII, "[", "{", "\033", "", ""}, /* 26 [ */
1634 1.13 soda { KB_ASCII, "]", "}", "\035", "", ""}, /* 27 ] */
1635 1.13 soda { KB_ASCII, "\r", "\r", "\n", "", ""}, /* 28 return */
1636 1.13 soda { KB_CTL, "", "", "", "", ""}, /* 29 control */
1637 1.13 soda { KB_ASCII, "a", "A", "\001", "", ""}, /* 30 a */
1638 1.13 soda { KB_ASCII, "s", "S", "\023", "", ""}, /* 31 s */
1639 1.13 soda { KB_ASCII, "d", "D", "\004", "", ""}, /* 32 d */
1640 1.13 soda { KB_ASCII, "f", "F", "\006", "", ""}, /* 33 f */
1641 1.13 soda { KB_ASCII, "g", "G", "\007", "", ""}, /* 34 g */
1642 1.13 soda { KB_ASCII, "h", "H", "\010", "", ""}, /* 35 h */
1643 1.13 soda { KB_ASCII, "j", "J", "\n", "", ""}, /* 36 j */
1644 1.13 soda { KB_ASCII, "k", "K", "\013", "", ""}, /* 37 k */
1645 1.13 soda { KB_ASCII, "l", "L", "\014", "", ""}, /* 38 l */
1646 1.13 soda { KB_ASCII, ";", ":", ";", "", ""}, /* 39 ; */
1647 1.13 soda { KB_ASCII, "'", "\"", "'", "", ""}, /* 40 ' */
1648 1.13 soda { KB_ASCII, "`", "~", "`", "", ""}, /* 41 ` */
1649 1.13 soda { KB_SHIFT, "\001", "", "", "", ""}, /* 42 shift */
1650 1.13 soda { KB_ASCII, "\\", "|", "\034", "", ""}, /* 43 \ */
1651 1.13 soda { KB_ASCII, "z", "Z", "\032", "", ""}, /* 44 z */
1652 1.13 soda { KB_ASCII, "x", "X", "\030", "", ""}, /* 45 x */
1653 1.13 soda { KB_ASCII, "c", "C", "\003", "", ""}, /* 46 c */
1654 1.13 soda { KB_ASCII, "v", "V", "\026", "", ""}, /* 47 v */
1655 1.13 soda { KB_ASCII, "b", "B", "\002", "", ""}, /* 48 b */
1656 1.13 soda { KB_ASCII, "n", "N", "\016", "", ""}, /* 49 n */
1657 1.13 soda { KB_ASCII, "m", "M", "\r", "", ""}, /* 50 m */
1658 1.13 soda { KB_ASCII, ",", "<", "<", "", ""}, /* 51 , */
1659 1.13 soda { KB_ASCII, ".", ">", ">", "", ""}, /* 52 . */
1660 1.13 soda { KB_ASCII, "/", "?", "\037", "", ""}, /* 53 / */
1661 1.13 soda { KB_SHIFT, "\002", "", "", "", ""}, /* 54 shift */
1662 1.13 soda { KB_KP, "*", "*", "*", "", ""}, /* 55 kp * */
1663 1.13 soda { KB_ALT, "", "", "", "", ""}, /* 56 alt */
1664 1.13 soda { KB_ASCII, " ", " ", "\000", "", ""}, /* 57 space */
1665 1.13 soda { KB_CAPS, "", "", "", "", ""}, /* 58 caps */
1666 1.13 soda { KB_FUNC, "\033[M", "\033[Y", "\033[k", "", ""}, /* 59 f1 */
1667 1.13 soda { KB_FUNC, "\033[N", "\033[Z", "\033[l", "", ""}, /* 60 f2 */
1668 1.13 soda { KB_FUNC, "\033[O", "\033[a", "\033[m", "", ""}, /* 61 f3 */
1669 1.13 soda { KB_FUNC, "\033[P", "\033[b", "\033[n", "", ""}, /* 62 f4 */
1670 1.13 soda { KB_FUNC, "\033[Q", "\033[c", "\033[o", "", ""}, /* 63 f5 */
1671 1.13 soda { KB_FUNC, "\033[R", "\033[d", "\033[p", "", ""}, /* 64 f6 */
1672 1.13 soda { KB_FUNC, "\033[S", "\033[e", "\033[q", "", ""}, /* 65 f7 */
1673 1.13 soda { KB_FUNC, "\033[T", "\033[f", "\033[r", "", ""}, /* 66 f8 */
1674 1.13 soda { KB_FUNC, "\033[U", "\033[g", "\033[s", "", ""}, /* 67 f9 */
1675 1.13 soda { KB_FUNC, "\033[V", "\033[h", "\033[t", "", ""}, /* 68 f10 */
1676 1.13 soda { KB_NUM, "", "", "", "", ""}, /* 69 num lock */
1677 1.13 soda { KB_SCROLL, "", "", "", "", ""}, /* 70 scroll lock */
1678 1.13 soda { KB_KP, "7", "\033[H", "7", "", ""}, /* 71 kp 7 */
1679 1.13 soda { KB_KP, "8", "\033[A", "8", "", ""}, /* 72 kp 8 */
1680 1.13 soda { KB_KP, "9", "\033[I", "9", "", ""}, /* 73 kp 9 */
1681 1.13 soda { KB_KP, "-", "-", "-", "", ""}, /* 74 kp - */
1682 1.13 soda { KB_KP, "4", "\033[D", "4", "", ""}, /* 75 kp 4 */
1683 1.13 soda { KB_KP, "5", "\033[E", "5", "", ""}, /* 76 kp 5 */
1684 1.13 soda { KB_KP, "6", "\033[C", "6", "", ""}, /* 77 kp 6 */
1685 1.13 soda { KB_KP, "+", "+", "+", "", ""}, /* 78 kp + */
1686 1.13 soda { KB_KP, "1", "\033[F", "1", "", ""}, /* 79 kp 1 */
1687 1.13 soda { KB_KP, "2", "\033[B", "2", "", ""}, /* 80 kp 2 */
1688 1.13 soda { KB_KP, "3", "\033[G", "3", "", ""}, /* 81 kp 3 */
1689 1.13 soda { KB_KP, "0", "\033[L", "0", "", ""}, /* 82 kp 0 */
1690 1.13 soda { KB_KP, ",", "\177", ",", "", ""}, /* 83 kp , */
1691 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 84 0 */
1692 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 85 0 */
1693 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 86 0 */
1694 1.13 soda { KB_FUNC, "\033[W", "\033[i", "\033[u", "", ""}, /* 87 f11 */
1695 1.13 soda { KB_FUNC, "\033[X", "\033[j", "\033[v", "", ""}, /* 88 f12 */
1696 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 89 0 */
1697 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 90 0 */
1698 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 91 0 */
1699 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 92 0 */
1700 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 93 0 */
1701 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 94 0 */
1702 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 95 0 */
1703 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 96 0 */
1704 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 97 0 */
1705 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 98 0 */
1706 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 99 0 */
1707 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 100 */
1708 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 101 */
1709 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 102 */
1710 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 103 */
1711 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 104 */
1712 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 105 */
1713 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 106 */
1714 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 107 */
1715 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 108 */
1716 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 109 */
1717 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 110 */
1718 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 111 */
1719 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 112 */
1720 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 113 */
1721 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 114 */
1722 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 115 */
1723 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 116 */
1724 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 117 */
1725 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 118 */
1726 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 119 */
1727 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 120 */
1728 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 121 */
1729 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 122 */
1730 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 123 */
1731 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 124 */
1732 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 125 */
1733 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 126 */
1734 1.13 soda { KB_NONE, "", "", "", "", ""} /* 127 */
1735 1.1 jonathan };
1736 1.1 jonathan
1737 1.1 jonathan /*
1738 1.1 jonathan * Get characters from the keyboard. If none are present, return NULL.
1739 1.1 jonathan */
1740 1.1 jonathan char *
1741 1.1 jonathan sget()
1742 1.1 jonathan {
1743 1.1 jonathan u_char dt;
1744 1.1 jonathan static u_char extended = 0, shift_state = 0;
1745 1.1 jonathan static u_char capchar[2];
1746 1.1 jonathan
1747 1.1 jonathan top:
1748 1.1 jonathan KBD_DELAY;
1749 1.13 soda dt = inb(kbd_datap);
1750 1.1 jonathan
1751 1.1 jonathan switch (dt) {
1752 1.1 jonathan case KBR_ACK: case KBR_ECHO:
1753 1.1 jonathan kb_oq_get = (kb_oq_get + 1) & 7;
1754 1.1 jonathan if(kb_oq_get != kb_oq_put) {
1755 1.13 soda outb(kbd_datap, kb_oq[kb_oq_get]);
1756 1.1 jonathan }
1757 1.1 jonathan goto loop;
1758 1.1 jonathan case KBR_RESEND:
1759 1.13 soda outb(kbd_datap, kb_oq[kb_oq_get]);
1760 1.1 jonathan goto loop;
1761 1.1 jonathan }
1762 1.1 jonathan
1763 1.1 jonathan if (pc_xmode > 0) {
1764 1.1 jonathan #if defined(DDB) && defined(XSERVER_DDB)
1765 1.1 jonathan /* F12 enters the debugger while in X mode */
1766 1.1 jonathan if (dt == 88)
1767 1.1 jonathan Debugger();
1768 1.1 jonathan #endif
1769 1.1 jonathan capchar[0] = dt;
1770 1.1 jonathan capchar[1] = 0;
1771 1.1 jonathan /*
1772 1.1 jonathan * Check for locking keys.
1773 1.1 jonathan *
1774 1.1 jonathan * XXX Setting the LEDs this way is a bit bogus. What if the
1775 1.1 jonathan * keyboard has been remapped in X?
1776 1.1 jonathan */
1777 1.13 soda switch (scan_codes[dt & 0x7f].type) {
1778 1.13 soda case KB_NUM:
1779 1.1 jonathan if (dt & 0x80) {
1780 1.13 soda shift_state &= ~KB_NUM;
1781 1.1 jonathan break;
1782 1.1 jonathan }
1783 1.13 soda if (shift_state & KB_NUM)
1784 1.1 jonathan break;
1785 1.13 soda shift_state |= KB_NUM;
1786 1.13 soda lock_state ^= KB_NUM;
1787 1.1 jonathan async_update();
1788 1.1 jonathan break;
1789 1.13 soda case KB_CAPS:
1790 1.1 jonathan if (dt & 0x80) {
1791 1.13 soda shift_state &= ~KB_CAPS;
1792 1.1 jonathan break;
1793 1.1 jonathan }
1794 1.13 soda if (shift_state & KB_CAPS)
1795 1.1 jonathan break;
1796 1.13 soda shift_state |= KB_CAPS;
1797 1.13 soda lock_state ^= KB_CAPS;
1798 1.1 jonathan async_update();
1799 1.1 jonathan break;
1800 1.13 soda case KB_SCROLL:
1801 1.1 jonathan if (dt & 0x80) {
1802 1.13 soda shift_state &= ~KB_SCROLL;
1803 1.1 jonathan break;
1804 1.1 jonathan }
1805 1.13 soda if (shift_state & KB_SCROLL)
1806 1.1 jonathan break;
1807 1.13 soda shift_state |= KB_SCROLL;
1808 1.13 soda lock_state ^= KB_SCROLL;
1809 1.13 soda if ((lock_state & KB_SCROLL) == 0)
1810 1.1 jonathan wakeup((caddr_t)&lock_state);
1811 1.1 jonathan async_update();
1812 1.1 jonathan break;
1813 1.1 jonathan }
1814 1.1 jonathan return capchar;
1815 1.1 jonathan }
1816 1.1 jonathan
1817 1.1 jonathan switch (dt) {
1818 1.1 jonathan case KBR_EXTENDED:
1819 1.1 jonathan extended = 1;
1820 1.1 jonathan goto loop;
1821 1.1 jonathan }
1822 1.1 jonathan
1823 1.13 soda #ifdef DDB
1824 1.1 jonathan /*
1825 1.1 jonathan * Check for cntl-alt-esc.
1826 1.1 jonathan */
1827 1.13 soda if ((dt == 1) && (shift_state & (KB_CTL | KB_ALT)) == (KB_CTL | KB_ALT)) {
1828 1.13 soda /* XXX - check pccons_is_console */
1829 1.13 soda Debugger();
1830 1.1 jonathan dt |= 0x80; /* discard esc (ddb discarded ctl-alt) */
1831 1.1 jonathan }
1832 1.1 jonathan #endif
1833 1.1 jonathan
1834 1.1 jonathan /*
1835 1.1 jonathan * Check for make/break.
1836 1.1 jonathan */
1837 1.1 jonathan if (dt & 0x80) {
1838 1.1 jonathan /*
1839 1.1 jonathan * break
1840 1.1 jonathan */
1841 1.1 jonathan dt &= 0x7f;
1842 1.13 soda switch (scan_codes[dt].type) {
1843 1.13 soda case KB_NUM:
1844 1.13 soda shift_state &= ~KB_NUM;
1845 1.1 jonathan break;
1846 1.13 soda case KB_CAPS:
1847 1.13 soda shift_state &= ~KB_CAPS;
1848 1.1 jonathan break;
1849 1.13 soda case KB_SCROLL:
1850 1.13 soda shift_state &= ~KB_SCROLL;
1851 1.1 jonathan break;
1852 1.13 soda case KB_SHIFT:
1853 1.13 soda shift_state &= ~KB_SHIFT;
1854 1.1 jonathan break;
1855 1.13 soda case KB_ALT:
1856 1.1 jonathan if (extended)
1857 1.13 soda shift_state &= ~KB_ALTGR;
1858 1.1 jonathan else
1859 1.13 soda shift_state &= ~KB_ALT;
1860 1.1 jonathan break;
1861 1.13 soda case KB_CTL:
1862 1.13 soda shift_state &= ~KB_CTL;
1863 1.1 jonathan break;
1864 1.1 jonathan }
1865 1.1 jonathan } else {
1866 1.1 jonathan /*
1867 1.1 jonathan * make
1868 1.1 jonathan */
1869 1.13 soda switch (scan_codes[dt].type) {
1870 1.1 jonathan /*
1871 1.1 jonathan * locking keys
1872 1.1 jonathan */
1873 1.13 soda case KB_NUM:
1874 1.13 soda if (shift_state & KB_NUM)
1875 1.1 jonathan break;
1876 1.13 soda shift_state |= KB_NUM;
1877 1.13 soda lock_state ^= KB_NUM;
1878 1.1 jonathan async_update();
1879 1.1 jonathan break;
1880 1.13 soda case KB_CAPS:
1881 1.13 soda if (shift_state & KB_CAPS)
1882 1.1 jonathan break;
1883 1.13 soda shift_state |= KB_CAPS;
1884 1.13 soda lock_state ^= KB_CAPS;
1885 1.1 jonathan async_update();
1886 1.1 jonathan break;
1887 1.13 soda case KB_SCROLL:
1888 1.13 soda if (shift_state & KB_SCROLL)
1889 1.1 jonathan break;
1890 1.13 soda shift_state |= KB_SCROLL;
1891 1.13 soda lock_state ^= KB_SCROLL;
1892 1.13 soda if ((lock_state & KB_SCROLL) == 0)
1893 1.1 jonathan wakeup((caddr_t)&lock_state);
1894 1.1 jonathan async_update();
1895 1.1 jonathan break;
1896 1.1 jonathan /*
1897 1.1 jonathan * non-locking keys
1898 1.1 jonathan */
1899 1.13 soda case KB_SHIFT:
1900 1.13 soda shift_state |= KB_SHIFT;
1901 1.1 jonathan break;
1902 1.13 soda case KB_ALT:
1903 1.1 jonathan if (extended)
1904 1.13 soda shift_state |= KB_ALTGR;
1905 1.1 jonathan else
1906 1.13 soda shift_state |= KB_ALT;
1907 1.1 jonathan break;
1908 1.13 soda case KB_CTL:
1909 1.13 soda shift_state |= KB_CTL;
1910 1.1 jonathan break;
1911 1.13 soda case KB_ASCII:
1912 1.13 soda /* control has highest priority */
1913 1.13 soda if (shift_state & KB_CTL)
1914 1.13 soda capchar[0] = scan_codes[dt].ctl[0];
1915 1.13 soda else if (shift_state & KB_ALTGR) {
1916 1.13 soda if (shift_state & KB_SHIFT)
1917 1.13 soda capchar[0] = scan_codes[dt].shift_altgr[0];
1918 1.13 soda else
1919 1.13 soda capchar[0] = scan_codes[dt].altgr[0];
1920 1.1 jonathan }
1921 1.13 soda else {
1922 1.13 soda if (shift_state & KB_SHIFT)
1923 1.13 soda capchar[0] = scan_codes[dt].shift[0];
1924 1.13 soda else
1925 1.13 soda capchar[0] = scan_codes[dt].unshift[0];
1926 1.13 soda }
1927 1.13 soda if ((lock_state & KB_CAPS) && capchar[0] >= 'a' &&
1928 1.1 jonathan capchar[0] <= 'z') {
1929 1.1 jonathan capchar[0] -= ('a' - 'A');
1930 1.1 jonathan }
1931 1.13 soda capchar[0] |= (shift_state & KB_ALT);
1932 1.1 jonathan extended = 0;
1933 1.1 jonathan return capchar;
1934 1.13 soda case KB_NONE:
1935 1.6 christos printf("keycode %d\n",dt);
1936 1.1 jonathan break;
1937 1.13 soda case KB_FUNC: {
1938 1.1 jonathan char *more_chars;
1939 1.13 soda if (shift_state & KB_SHIFT)
1940 1.13 soda more_chars = scan_codes[dt].shift;
1941 1.13 soda else if (shift_state & KB_CTL)
1942 1.13 soda more_chars = scan_codes[dt].ctl;
1943 1.1 jonathan else
1944 1.13 soda more_chars = scan_codes[dt].unshift;
1945 1.1 jonathan extended = 0;
1946 1.1 jonathan return more_chars;
1947 1.1 jonathan }
1948 1.13 soda case KB_KP: {
1949 1.1 jonathan char *more_chars;
1950 1.13 soda if (shift_state & (KB_SHIFT | KB_CTL) ||
1951 1.13 soda (lock_state & KB_NUM) == 0 || extended)
1952 1.13 soda more_chars = scan_codes[dt].shift;
1953 1.1 jonathan else
1954 1.13 soda more_chars = scan_codes[dt].unshift;
1955 1.1 jonathan extended = 0;
1956 1.1 jonathan return more_chars;
1957 1.1 jonathan }
1958 1.1 jonathan }
1959 1.1 jonathan }
1960 1.1 jonathan
1961 1.1 jonathan extended = 0;
1962 1.1 jonathan loop:
1963 1.13 soda if ((inb(kbd_cmdp) & KBS_DIB) == 0)
1964 1.1 jonathan return 0;
1965 1.1 jonathan goto top;
1966 1.1 jonathan }
1967 1.1 jonathan
1968 1.21 simonb paddr_t
1969 1.1 jonathan pcmmap(dev, offset, nprot)
1970 1.1 jonathan dev_t dev;
1971 1.21 simonb off_t offset;
1972 1.1 jonathan int nprot;
1973 1.1 jonathan {
1974 1.1 jonathan
1975 1.13 soda switch(cputype) {
1976 1.13 soda
1977 1.13 soda case ACER_PICA_61:
1978 1.18 soda case NEC_R96:
1979 1.13 soda if (offset >= 0xa0000 && offset < 0xc0000)
1980 1.13 soda return mips_btop(PICA_P_LOCAL_VIDEO + offset);
1981 1.13 soda if (offset >= 0x0000 && offset < 0x10000)
1982 1.13 soda return mips_btop(PICA_P_LOCAL_VIDEO_CTRL + offset);
1983 1.13 soda if (offset >= 0x40000000 && offset < 0x40800000)
1984 1.13 soda return mips_btop(PICA_P_LOCAL_VIDEO + offset - 0x40000000);
1985 1.14 soda return -1;
1986 1.14 soda
1987 1.14 soda case DESKSTATION_RPC44:
1988 1.14 soda if (offset >= 0xa0000 && offset < 0xc0000)
1989 1.14 soda return mips_btop(RPC44_P_ISA_MEM + offset);
1990 1.14 soda if (offset >= 0x0000 && offset < 0x10000)
1991 1.14 soda return mips_btop(RPC44_P_ISA_IO + offset);
1992 1.14 soda if (offset >= 0x40000000 && offset < 0x40800000)
1993 1.14 soda return mips_btop(RPC44_P_ISA_MEM + offset - 0x40000000);
1994 1.13 soda return -1;
1995 1.13 soda
1996 1.13 soda case DESKSTATION_TYNE:
1997 1.13 soda if (offset >= 0xa0000 && offset < 0xc0000)
1998 1.18 soda return mips_btop(TYNE_P_ISA_MEM + offset);
1999 1.13 soda if (offset >= 0x0000 && offset < 0x10000)
2000 1.18 soda return mips_btop(TYNE_P_ISA_IO + offset);
2001 1.13 soda if (offset >= 0x40000000 && offset < 0x40800000)
2002 1.18 soda return mips_btop(TYNE_P_ISA_MEM + offset - 0x40000000);
2003 1.13 soda return -1;
2004 1.13 soda }
2005 1.1 jonathan return -1;
2006 1.1 jonathan }
2007 1.1 jonathan
2008 1.13 soda void
2009 1.1 jonathan pc_xmode_on()
2010 1.1 jonathan {
2011 1.1 jonathan if (pc_xmode)
2012 1.1 jonathan return;
2013 1.1 jonathan pc_xmode = 1;
2014 1.1 jonathan
2015 1.1 jonathan #ifdef XFREE86_BUG_COMPAT
2016 1.1 jonathan /* If still unchanged, get current shape. */
2017 1.1 jonathan if (cursor_shape == 0xffff)
2018 1.1 jonathan get_cursor_shape();
2019 1.1 jonathan #endif
2020 1.1 jonathan }
2021 1.1 jonathan
2022 1.13 soda void
2023 1.1 jonathan pc_xmode_off()
2024 1.1 jonathan {
2025 1.1 jonathan if (pc_xmode == 0)
2026 1.1 jonathan return;
2027 1.1 jonathan pc_xmode = 0;
2028 1.1 jonathan
2029 1.1 jonathan #ifdef XFREE86_BUG_COMPAT
2030 1.1 jonathan /* XXX It would be hard to justify why the X server doesn't do this. */
2031 1.1 jonathan set_cursor_shape();
2032 1.1 jonathan #endif
2033 1.1 jonathan async_update();
2034 1.1 jonathan }
2035 1.1 jonathan
2036 1.1 jonathan #include <machine/mouse.h>
2037 1.1 jonathan
2038 1.1 jonathan /* status bits */
2039 1.1 jonathan #define PMS_OBUF_FULL 0x01
2040 1.1 jonathan #define PMS_IBUF_FULL 0x02
2041 1.1 jonathan
2042 1.1 jonathan /* controller commands */
2043 1.1 jonathan #define PMS_INT_ENABLE 0x47 /* enable controller interrupts */
2044 1.1 jonathan #define PMS_INT_DISABLE 0x65 /* disable controller interrupts */
2045 1.1 jonathan #define PMS_AUX_ENABLE 0xa7 /* enable auxiliary port */
2046 1.1 jonathan #define PMS_AUX_DISABLE 0xa8 /* disable auxiliary port */
2047 1.1 jonathan #define PMS_MAGIC_1 0xa9 /* XXX */
2048 1.1 jonathan
2049 1.1 jonathan #define PMS_8042_CMD 0x65
2050 1.1 jonathan
2051 1.1 jonathan /* mouse commands */
2052 1.1 jonathan #define PMS_SET_SCALE11 0xe6 /* set scaling 1:1 */
2053 1.1 jonathan #define PMS_SET_SCALE21 0xe7 /* set scaling 2:1 */
2054 1.1 jonathan #define PMS_SET_RES 0xe8 /* set resolution */
2055 1.1 jonathan #define PMS_GET_SCALE 0xe9 /* get scaling factor */
2056 1.1 jonathan #define PMS_SET_STREAM 0xea /* set streaming mode */
2057 1.1 jonathan #define PMS_SET_SAMPLE 0xf3 /* set sampling rate */
2058 1.1 jonathan #define PMS_DEV_ENABLE 0xf4 /* mouse on */
2059 1.1 jonathan #define PMS_DEV_DISABLE 0xf5 /* mouse off */
2060 1.1 jonathan #define PMS_RESET 0xff /* reset */
2061 1.1 jonathan
2062 1.1 jonathan #define PMS_CHUNK 128 /* chunk size for read */
2063 1.1 jonathan #define PMS_BSIZE 1020 /* buffer size */
2064 1.1 jonathan
2065 1.13 soda #define FLUSHQ(q) { if((q)->c_cc) ndflush(q, (q)->c_cc); }
2066 1.13 soda
2067 1.20 soda #if NOPMS > 0
2068 1.20 soda
2069 1.13 soda int opmsopen __P((dev_t, int));
2070 1.13 soda int opmsclose __P((dev_t, int));
2071 1.13 soda int opmsread __P((dev_t, struct uio *, int));
2072 1.13 soda int opmsioctl __P((dev_t, u_long, caddr_t, int));
2073 1.13 soda int opmsselect __P((dev_t, int, struct proc *));
2074 1.15 soda int opmspoll __P((dev_t, int, struct proc *));
2075 1.13 soda static __inline void pms_dev_cmd __P((u_char));
2076 1.13 soda static __inline void pms_aux_cmd __P((u_char));
2077 1.13 soda static __inline void pms_pit_cmd __P((u_char));
2078 1.1 jonathan
2079 1.13 soda static __inline void
2080 1.1 jonathan pms_dev_cmd(value)
2081 1.1 jonathan u_char value;
2082 1.1 jonathan {
2083 1.1 jonathan kbd_flush_input();
2084 1.13 soda outb(kbd_cmdp, 0xd4);
2085 1.1 jonathan kbd_flush_input();
2086 1.13 soda outb(kbd_datap, value);
2087 1.1 jonathan }
2088 1.1 jonathan
2089 1.13 soda static __inline void
2090 1.1 jonathan pms_aux_cmd(value)
2091 1.1 jonathan u_char value;
2092 1.1 jonathan {
2093 1.1 jonathan kbd_flush_input();
2094 1.13 soda outb(kbd_cmdp, value);
2095 1.1 jonathan }
2096 1.1 jonathan
2097 1.13 soda static __inline void
2098 1.1 jonathan pms_pit_cmd(value)
2099 1.1 jonathan u_char value;
2100 1.1 jonathan {
2101 1.1 jonathan kbd_flush_input();
2102 1.13 soda outb(kbd_cmdp, 0x60);
2103 1.1 jonathan kbd_flush_input();
2104 1.13 soda outb(kbd_datap, value);
2105 1.1 jonathan }
2106 1.1 jonathan
2107 1.1 jonathan int
2108 1.13 soda opmsprobe(parent, match, aux)
2109 1.1 jonathan struct device *parent;
2110 1.13 soda struct cfdata *match;
2111 1.13 soda void *aux;
2112 1.1 jonathan {
2113 1.1 jonathan struct confargs *ca = aux;
2114 1.1 jonathan u_char x;
2115 1.1 jonathan
2116 1.1 jonathan /* Make shure we're looking for this type of device */
2117 1.1 jonathan if(!BUS_MATCHNAME(ca, "pms"))
2118 1.1 jonathan return(0);
2119 1.1 jonathan
2120 1.20 soda pcinithandle();
2121 1.1 jonathan pms_dev_cmd(KBC_RESET);
2122 1.1 jonathan pms_aux_cmd(PMS_MAGIC_1);
2123 1.1 jonathan delay(10000);
2124 1.13 soda x = inb(kbd_datap);
2125 1.1 jonathan pms_pit_cmd(PMS_INT_DISABLE);
2126 1.1 jonathan if (x & 0x04)
2127 1.1 jonathan return 0;
2128 1.1 jonathan
2129 1.1 jonathan return 1;
2130 1.1 jonathan }
2131 1.1 jonathan
2132 1.1 jonathan void
2133 1.13 soda opmsattach(parent, self, aux)
2134 1.1 jonathan struct device *parent, *self;
2135 1.1 jonathan void *aux;
2136 1.1 jonathan {
2137 1.13 soda struct opms_softc *sc = (void *)self;
2138 1.1 jonathan struct confargs *ca = aux;
2139 1.1 jonathan
2140 1.6 christos printf("\n");
2141 1.1 jonathan
2142 1.13 soda /* Other initialization was done by opmsprobe. */
2143 1.1 jonathan sc->sc_state = 0;
2144 1.1 jonathan
2145 1.13 soda BUS_INTR_ESTABLISH(ca, opmsintr, (void *)(long)sc);
2146 1.1 jonathan }
2147 1.1 jonathan
2148 1.1 jonathan int
2149 1.13 soda opmsopen(dev, flag)
2150 1.1 jonathan dev_t dev;
2151 1.1 jonathan int flag;
2152 1.1 jonathan {
2153 1.1 jonathan int unit = PMSUNIT(dev);
2154 1.13 soda struct opms_softc *sc;
2155 1.1 jonathan
2156 1.13 soda if (unit >= opms_cd.cd_ndevs)
2157 1.1 jonathan return ENXIO;
2158 1.13 soda sc = opms_cd.cd_devs[unit];
2159 1.1 jonathan if (!sc)
2160 1.1 jonathan return ENXIO;
2161 1.1 jonathan
2162 1.1 jonathan if (sc->sc_state & PMS_OPEN)
2163 1.1 jonathan return EBUSY;
2164 1.1 jonathan
2165 1.1 jonathan if (clalloc(&sc->sc_q, PMS_BSIZE, 0) == -1)
2166 1.1 jonathan return ENOMEM;
2167 1.1 jonathan
2168 1.1 jonathan sc->sc_state |= PMS_OPEN;
2169 1.1 jonathan sc->sc_status = 0;
2170 1.1 jonathan sc->sc_x = sc->sc_y = 0;
2171 1.1 jonathan
2172 1.1 jonathan /* Enable interrupts. */
2173 1.1 jonathan pms_dev_cmd(PMS_DEV_ENABLE);
2174 1.1 jonathan pms_aux_cmd(PMS_AUX_ENABLE);
2175 1.1 jonathan pms_dev_cmd(PMS_SET_RES);
2176 1.1 jonathan pms_dev_cmd(3); /* 8 counts/mm */
2177 1.1 jonathan pms_dev_cmd(PMS_SET_SCALE21);
2178 1.1 jonathan #if 0
2179 1.1 jonathan pms_dev_cmd(PMS_SET_SAMPLE);
2180 1.1 jonathan pms_dev_cmd(100); /* 100 samples/sec */
2181 1.1 jonathan pms_dev_cmd(PMS_SET_STREAM);
2182 1.1 jonathan #endif
2183 1.1 jonathan pms_pit_cmd(PMS_INT_ENABLE);
2184 1.1 jonathan
2185 1.1 jonathan return 0;
2186 1.1 jonathan }
2187 1.1 jonathan
2188 1.1 jonathan int
2189 1.13 soda opmsclose(dev, flag)
2190 1.1 jonathan dev_t dev;
2191 1.1 jonathan int flag;
2192 1.1 jonathan {
2193 1.13 soda struct opms_softc *sc = opms_cd.cd_devs[PMSUNIT(dev)];
2194 1.1 jonathan
2195 1.1 jonathan /* Disable interrupts. */
2196 1.1 jonathan pms_dev_cmd(PMS_DEV_DISABLE);
2197 1.1 jonathan pms_pit_cmd(PMS_INT_DISABLE);
2198 1.1 jonathan pms_aux_cmd(PMS_AUX_DISABLE);
2199 1.1 jonathan
2200 1.1 jonathan sc->sc_state &= ~PMS_OPEN;
2201 1.1 jonathan
2202 1.1 jonathan clfree(&sc->sc_q);
2203 1.1 jonathan
2204 1.1 jonathan return 0;
2205 1.1 jonathan }
2206 1.1 jonathan
2207 1.1 jonathan int
2208 1.13 soda opmsread(dev, uio, flag)
2209 1.1 jonathan dev_t dev;
2210 1.1 jonathan struct uio *uio;
2211 1.1 jonathan int flag;
2212 1.1 jonathan {
2213 1.13 soda struct opms_softc *sc = opms_cd.cd_devs[PMSUNIT(dev)];
2214 1.1 jonathan int s;
2215 1.13 soda int error = 0;
2216 1.1 jonathan size_t length;
2217 1.1 jonathan u_char buffer[PMS_CHUNK];
2218 1.1 jonathan
2219 1.1 jonathan /* Block until mouse activity occured. */
2220 1.1 jonathan
2221 1.1 jonathan s = spltty();
2222 1.1 jonathan while (sc->sc_q.c_cc == 0) {
2223 1.1 jonathan if (flag & IO_NDELAY) {
2224 1.1 jonathan splx(s);
2225 1.1 jonathan return EWOULDBLOCK;
2226 1.1 jonathan }
2227 1.1 jonathan sc->sc_state |= PMS_ASLP;
2228 1.13 soda error = tsleep((caddr_t)sc, PZERO | PCATCH, "pmsrea", 0);
2229 1.13 soda if (error) {
2230 1.1 jonathan sc->sc_state &= ~PMS_ASLP;
2231 1.1 jonathan splx(s);
2232 1.1 jonathan return error;
2233 1.1 jonathan }
2234 1.1 jonathan }
2235 1.1 jonathan splx(s);
2236 1.1 jonathan
2237 1.1 jonathan /* Transfer as many chunks as possible. */
2238 1.1 jonathan
2239 1.1 jonathan while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0) {
2240 1.1 jonathan length = min(sc->sc_q.c_cc, uio->uio_resid);
2241 1.1 jonathan if (length > sizeof(buffer))
2242 1.1 jonathan length = sizeof(buffer);
2243 1.1 jonathan
2244 1.1 jonathan /* Remove a small chunk from the input queue. */
2245 1.1 jonathan (void) q_to_b(&sc->sc_q, buffer, length);
2246 1.1 jonathan
2247 1.1 jonathan /* Copy the data to the user process. */
2248 1.13 soda error = uiomove(buffer, length, uio);
2249 1.13 soda if (error)
2250 1.1 jonathan break;
2251 1.1 jonathan }
2252 1.1 jonathan
2253 1.1 jonathan return error;
2254 1.1 jonathan }
2255 1.1 jonathan
2256 1.1 jonathan int
2257 1.13 soda opmsioctl(dev, cmd, addr, flag)
2258 1.1 jonathan dev_t dev;
2259 1.1 jonathan u_long cmd;
2260 1.1 jonathan caddr_t addr;
2261 1.1 jonathan int flag;
2262 1.1 jonathan {
2263 1.13 soda struct opms_softc *sc = opms_cd.cd_devs[PMSUNIT(dev)];
2264 1.1 jonathan struct mouseinfo info;
2265 1.1 jonathan int s;
2266 1.1 jonathan int error;
2267 1.1 jonathan
2268 1.1 jonathan switch (cmd) {
2269 1.1 jonathan case MOUSEIOCREAD:
2270 1.1 jonathan s = spltty();
2271 1.1 jonathan
2272 1.1 jonathan info.status = sc->sc_status;
2273 1.1 jonathan if (sc->sc_x || sc->sc_y)
2274 1.1 jonathan info.status |= MOVEMENT;
2275 1.1 jonathan
2276 1.1 jonathan if (sc->sc_x > 127)
2277 1.1 jonathan info.xmotion = 127;
2278 1.1 jonathan else if (sc->sc_x < -127)
2279 1.1 jonathan /* Bounding at -127 avoids a bug in XFree86. */
2280 1.1 jonathan info.xmotion = -127;
2281 1.1 jonathan else
2282 1.1 jonathan info.xmotion = sc->sc_x;
2283 1.1 jonathan
2284 1.1 jonathan if (sc->sc_y > 127)
2285 1.1 jonathan info.ymotion = 127;
2286 1.1 jonathan else if (sc->sc_y < -127)
2287 1.1 jonathan info.ymotion = -127;
2288 1.1 jonathan else
2289 1.1 jonathan info.ymotion = sc->sc_y;
2290 1.1 jonathan
2291 1.1 jonathan /* Reset historical information. */
2292 1.1 jonathan sc->sc_x = sc->sc_y = 0;
2293 1.1 jonathan sc->sc_status &= ~BUTCHNGMASK;
2294 1.1 jonathan ndflush(&sc->sc_q, sc->sc_q.c_cc);
2295 1.1 jonathan
2296 1.1 jonathan splx(s);
2297 1.1 jonathan error = copyout(&info, addr, sizeof(struct mouseinfo));
2298 1.1 jonathan break;
2299 1.1 jonathan default:
2300 1.1 jonathan error = EINVAL;
2301 1.1 jonathan break;
2302 1.1 jonathan }
2303 1.1 jonathan
2304 1.1 jonathan return error;
2305 1.1 jonathan }
2306 1.1 jonathan
2307 1.1 jonathan /* Masks for the first byte of a packet */
2308 1.1 jonathan #define PS2LBUTMASK 0x01
2309 1.1 jonathan #define PS2RBUTMASK 0x02
2310 1.1 jonathan #define PS2MBUTMASK 0x04
2311 1.1 jonathan
2312 1.1 jonathan int
2313 1.13 soda opmsintr(arg)
2314 1.1 jonathan void *arg;
2315 1.1 jonathan {
2316 1.13 soda struct opms_softc *sc = arg;
2317 1.1 jonathan static int state = 0;
2318 1.1 jonathan static u_char buttons;
2319 1.1 jonathan u_char changed;
2320 1.1 jonathan static char dx, dy;
2321 1.1 jonathan u_char buffer[5];
2322 1.1 jonathan
2323 1.1 jonathan if ((sc->sc_state & PMS_OPEN) == 0) {
2324 1.1 jonathan /* Interrupts are not expected. Discard the byte. */
2325 1.1 jonathan kbd_flush_input();
2326 1.1 jonathan return 0;
2327 1.1 jonathan }
2328 1.1 jonathan
2329 1.1 jonathan switch (state) {
2330 1.1 jonathan
2331 1.1 jonathan case 0:
2332 1.13 soda buttons = inb(kbd_datap);
2333 1.1 jonathan if ((buttons & 0xc0) == 0)
2334 1.1 jonathan ++state;
2335 1.1 jonathan break;
2336 1.1 jonathan
2337 1.1 jonathan case 1:
2338 1.13 soda dx = inb(kbd_datap);
2339 1.1 jonathan /* Bounding at -127 avoids a bug in XFree86. */
2340 1.1 jonathan dx = (dx == -128) ? -127 : dx;
2341 1.1 jonathan ++state;
2342 1.1 jonathan break;
2343 1.1 jonathan
2344 1.1 jonathan case 2:
2345 1.13 soda dy = inb(kbd_datap);
2346 1.1 jonathan dy = (dy == -128) ? -127 : dy;
2347 1.1 jonathan state = 0;
2348 1.1 jonathan
2349 1.1 jonathan buttons = ((buttons & PS2LBUTMASK) << 2) |
2350 1.1 jonathan ((buttons & (PS2RBUTMASK | PS2MBUTMASK)) >> 1);
2351 1.1 jonathan changed = ((buttons ^ sc->sc_status) & BUTSTATMASK) << 3;
2352 1.1 jonathan sc->sc_status = buttons | (sc->sc_status & ~BUTSTATMASK) | changed;
2353 1.1 jonathan
2354 1.1 jonathan if (dx || dy || changed) {
2355 1.1 jonathan /* Update accumulated movements. */
2356 1.1 jonathan sc->sc_x += dx;
2357 1.1 jonathan sc->sc_y += dy;
2358 1.1 jonathan
2359 1.1 jonathan /* Add this event to the queue. */
2360 1.13 soda buffer[0] = 0x80 | (buttons & BUTSTATMASK);
2361 1.1 jonathan if(dx < 0)
2362 1.1 jonathan buffer[0] |= 0x10;
2363 1.1 jonathan buffer[1] = dx & 0x7f;
2364 1.1 jonathan if(dy < 0)
2365 1.1 jonathan buffer[0] |= 0x20;
2366 1.1 jonathan buffer[2] = dy & 0x7f;
2367 1.1 jonathan buffer[3] = buffer[4] = 0;
2368 1.1 jonathan (void) b_to_q(buffer, sizeof buffer, &sc->sc_q);
2369 1.1 jonathan
2370 1.1 jonathan if (sc->sc_state & PMS_ASLP) {
2371 1.1 jonathan sc->sc_state &= ~PMS_ASLP;
2372 1.1 jonathan wakeup((caddr_t)sc);
2373 1.1 jonathan }
2374 1.1 jonathan selwakeup(&sc->sc_rsel);
2375 1.1 jonathan }
2376 1.1 jonathan
2377 1.1 jonathan break;
2378 1.1 jonathan }
2379 1.1 jonathan return -1;
2380 1.1 jonathan }
2381 1.1 jonathan
2382 1.1 jonathan int
2383 1.13 soda opmspoll(dev, events, p)
2384 1.1 jonathan dev_t dev;
2385 1.8 jonathan int events;
2386 1.1 jonathan struct proc *p;
2387 1.1 jonathan {
2388 1.13 soda struct opms_softc *sc = opms_cd.cd_devs[PMSUNIT(dev)];
2389 1.8 jonathan int revents = 0;
2390 1.8 jonathan int s = spltty();
2391 1.1 jonathan
2392 1.19 soda if (events & (POLLIN | POLLRDNORM)) {
2393 1.8 jonathan if (sc->sc_q.c_cc > 0)
2394 1.8 jonathan revents |= events & (POLLIN | POLLRDNORM);
2395 1.8 jonathan else
2396 1.8 jonathan selrecord(p, &sc->sc_rsel);
2397 1.19 soda }
2398 1.1 jonathan
2399 1.1 jonathan splx(s);
2400 1.8 jonathan return (revents);
2401 1.1 jonathan }
2402 1.20 soda
2403 1.20 soda #endif /* NOPMS > 0 */
2404