1 /* $NetBSD: pccons.c,v 1.56 2008/09/13 17:13:57 tsutsui Exp $ */
2 /* $OpenBSD: pccons.c,v 1.22 1999/01/30 22:39:37 imp Exp $ */
3 /* NetBSD: pccons.c,v 1.89 1995/05/04 19:35:20 cgd Exp */
6 * Copyright (c) 1990 The Regents of the University of California.
9 * This code is derived from software contributed to Berkeley by
10 * William Jolitz and Don Ahn.
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * @(#)pccons.c 5.11 (Berkeley) 5/21/91
39 * Copyright (c) 1993, 1994, 1995 Charles M. Hannum. All rights reserved.
41 * This code is derived from software contributed to Berkeley by
42 * William Jolitz and Don Ahn.
44 * Copyright (c) 1994 Charles M. Hannum.
45 * Copyright (c) 1992, 1993 Erik Forsberg.
47 * Redistribution and use in source and binary forms, with or without
48 * modification, are permitted provided that the following conditions
50 * 1. Redistributions of source code must retain the above copyright
51 * notice, this list of conditions and the following disclaimer.
52 * 2. Redistributions in binary form must reproduce the above copyright
53 * notice, this list of conditions and the following disclaimer in the
54 * documentation and/or other materials provided with the distribution.
55 * 3. All advertising materials mentioning features or use of this software
56 * must display the following acknowledgement:
57 * This product includes software developed by the University of
58 * California, Berkeley and its contributors.
59 * 4. Neither the name of the University nor the names of its contributors
60 * may be used to endorse or promote products derived from this software
61 * without specific prior written permission.
63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
75 * @(#)pccons.c 5.11 (Berkeley) 5/21/91
79 * code to work keyboard & display for PC-style console
82 #include <sys/cdefs.h>
83 __KERNEL_RCSID(0, "$NetBSD: pccons.c,v 1.56 2008/09/13 17:13:57 tsutsui Exp $");
87 #include <sys/param.h>
88 #include <sys/systm.h>
90 #include <sys/callout.h>
93 #include <sys/vnode.h>
94 #include <sys/kernel.h>
95 #include <sys/kcore.h>
96 #include <sys/device.h>
98 #include <sys/kauth.h>
100 #include <machine/bus.h>
102 #include <dev/ic/pcdisplay.h>
103 #include <machine/pccons.h>
104 #include <machine/kbdreg.h>
106 #include <dev/cons.h>
107 #include <dev/isa/isavar.h>
109 #include <arc/arc/arcbios.h>
110 #include <arc/dev/pcconsvar.h>
114 #define XFREE86_BUG_COMPAT
117 #define BEEP_FREQ 1600
120 #define BEEP_TIME (hz/5)
125 static u_short
*Crtat
; /* pointer to backing store */
126 static u_short
*crtat
; /* pointer to current char */
127 static u_char async
, kernel
, polling
; /* Really, you don't want to know. */
128 static u_char lock_state
= 0x00, /* all off */
129 old_lock_state
= 0xff,
130 typematic_rate
= 0xff, /* don't update until set by user */
131 old_typematic_rate
= 0xff;
132 static u_short cursor_shape
= 0xffff, /* don't update until set by user */
133 old_cursor_shape
= 0xffff;
134 static pccons_keymap_t scan_codes
[KB_NUM_KEYS
];/* keyboard translation table */
138 * Keyboard output queue.
144 #define PCUNIT(x) (minor(x))
146 static struct video_state
{
147 int cx
, cy
; /* escape parameters */
148 int row
, col
; /* current cursor position */
149 int nrow
, ncol
, nchr
; /* current screen geometry */
150 int offset
; /* Saved cursor pos */
151 u_char state
; /* parser state */
155 char so
; /* in standout mode? */
156 char color
; /* color or mono display */
157 char at
; /* normal attributes */
158 char so_at
; /* standout attributes */
161 static callout_t async_update_ch
;
163 void pc_xmode_on(void);
164 void pc_xmode_off(void);
165 static u_char
kbc_get8042cmd(void);
166 int kbd_cmd(u_char
, u_char
);
167 static inline int kbd_wait_output(void);
168 static inline int kbd_wait_input(void);
169 void kbd_flush_input(void);
170 void set_cursor_shape(void);
171 void get_cursor_shape(void);
172 void async_update(void);
173 void do_async_update(u_char
);
175 void pccnputc(dev_t
, int c
);
177 void pccnpollc(dev_t
, int);
179 dev_type_open(pcopen
);
180 dev_type_close(pcclose
);
181 dev_type_read(pcread
);
182 dev_type_write(pcwrite
);
183 dev_type_ioctl(pcioctl
);
185 dev_type_poll(pcpoll
);
186 dev_type_mmap(pcmmap
);
188 const struct cdevsw pc_cdevsw
= {
189 pcopen
, pcclose
, pcread
, pcwrite
, pcioctl
,
190 nostop
, pctty
, pcpoll
, pcmmap
, ttykqfilter
, D_TTY
196 void sput(const u_char
*, int);
198 void pcstart(struct tty
*);
199 int pcparam(struct tty
*, struct termios
*);
200 static inline void wcopy(void *, void *, u_int
);
201 void pc_context_init(bus_space_tag_t
, bus_space_tag_t
, bus_space_tag_t
,
202 struct pccons_config
*);
204 extern void fillw(int, uint16_t *, int);
209 #define crtc_read_1(reg) \
210 bus_space_read_1(pccons_console_context.pc_crt_iot, \
211 pccons_console_context.pc_6845_ioh, reg)
212 #define crtc_write_1(reg, data) \
213 bus_space_write_1(pccons_console_context.pc_crt_iot, \
214 pccons_console_context.pc_6845_ioh, reg, data)
216 struct pccons_context pccons_console_context
;
219 kbd_context_init(bus_space_tag_t kbd_iot
, struct pccons_config
*config
)
221 struct pccons_kbd_context
*pkc
= &pccons_console_context
.pc_pkc
;
223 if (pkc
->pkc_initialized
)
225 pkc
->pkc_initialized
= 1;
227 pkc
->pkc_iot
= kbd_iot
;
229 bus_space_map(kbd_iot
, config
->pc_kbd_cmdp
, 1, 0,
231 bus_space_map(kbd_iot
, config
->pc_kbd_datap
, 1, 0,
236 pc_context_init(bus_space_tag_t crt_iot
, bus_space_tag_t crt_memt
,
237 bus_space_tag_t kbd_iot
, struct pccons_config
*config
)
239 struct pccons_context
*pc
= &pccons_console_context
;
241 if (pc
->pc_initialized
)
243 pc
->pc_initialized
= 1;
245 kbd_context_init(kbd_iot
, config
);
247 pc
->pc_crt_iot
= crt_iot
;
248 pc
->pc_crt_memt
= crt_memt
;
250 bus_space_map(crt_iot
, config
->pc_mono_iobase
, 2, 0,
252 bus_space_map(crt_memt
, config
->pc_mono_memaddr
, 0x20000, 0,
254 bus_space_map(crt_iot
, config
->pc_cga_iobase
, 2, 0,
256 bus_space_map(crt_memt
, config
->pc_cga_memaddr
, 0x20000, 0,
260 * pc->pc_6845_ioh and pc->pc_crt_memh will be initialized later,
261 * when `Crtat' is initialized.
264 pc
->pc_config
= config
;
266 (*config
->pc_init
)();
270 * bcopy variant that only moves word-aligned 16-bit entities,
271 * for stupid VGA cards. cnt is required to be an even value.
274 wcopy(void *src
, void *tgt
, u_int cnt
)
276 uint16_t *from
= src
;
280 if (to
< from
|| to
>= from
+ cnt
)
292 kbd_wait_output(void)
296 for (i
= 100000; i
; i
--)
297 if ((kbd_cmd_read_1() & KBS_IBF
) == 0) {
309 for (i
= 100000; i
; i
--)
310 if ((kbd_cmd_read_1() & KBS_DIB
) != 0) {
318 kbd_flush_input(void)
322 while ((c
= kbd_cmd_read_1()) & 0x03)
323 if ((c
& KBS_DIB
) == KBS_DIB
) {
324 /* XXX - delay is needed to prevent some keyboards from
325 wedging when the system boots */
327 (void)kbd_data_read_1();
333 * Get the current command byte.
339 if (!kbd_wait_output())
341 kbd_cmd_write_1(K_RDCMDBYTE
);
342 if (!kbd_wait_input())
344 return kbd_data_read_1();
349 * Pass command byte to keyboard controller (8042).
352 kbc_put8042cmd(uint8_t val
)
355 if (!kbd_wait_output())
357 kbd_cmd_write_1(K_LDCMDBYTE
);
358 if (!kbd_wait_output())
360 kbd_data_write_1(val
);
365 * Pass command to keyboard itself
368 kbd_cmd(uint8_t val
, uint8_t polled
)
375 if (kb_oq_get
== kb_oq_put
) {
376 kbd_data_write_1(val
);
378 kb_oq
[kb_oq_put
] = val
;
379 kb_oq_put
= (kb_oq_put
+ 1) & 7;
385 if (!kbd_wait_output())
387 kbd_data_write_1(val
);
388 for (i
= 100000; i
; i
--) {
389 if (kbd_cmd_read_1() & KBS_DIB
) {
393 c
= kbd_data_read_1();
394 if (c
== KBR_ACK
|| c
== KBR_ECHO
) {
397 if (c
== KBR_RESEND
) {
401 printf("kbd_cmd: input char %x lost\n", c
);
410 set_cursor_shape(void)
414 crtc_write_1(1, cursor_shape
>> 8);
416 crtc_write_1(1, cursor_shape
);
417 old_cursor_shape
= cursor_shape
;
421 get_cursor_shape(void)
425 cursor_shape
= crtc_read_1(1) << 8;
427 cursor_shape
|= crtc_read_1(1);
430 * real 6845's, as found on, MDA, Hercules or CGA cards, do
431 * not support reading the cursor shape registers. the 6845
432 * tri-states it's data bus. This is _normally_ read by the
433 * CPU as either 0x00 or 0xff.. in which case we just use
436 if (cursor_shape
== 0x0000 || cursor_shape
== 0xffff)
437 cursor_shape
= 0x0b10;
439 cursor_shape
&= 0x1f1f;
443 do_async_update(uint8_t poll
)
446 static int old_pos
= -1;
450 if (lock_state
!= old_lock_state
) {
451 old_lock_state
= lock_state
;
452 if (!kbd_cmd(KBC_MODEIND
, poll
) ||
453 !kbd_cmd(lock_state
, poll
)) {
454 printf("pc: timeout updating leds\n");
455 (void) kbd_cmd(KBC_ENABLE
, poll
);
458 if (typematic_rate
!= old_typematic_rate
) {
459 old_typematic_rate
= typematic_rate
;
460 if (!kbd_cmd(KBC_TYPEMATIC
, poll
) ||
461 !kbd_cmd(typematic_rate
, poll
)) {
462 printf("pc: timeout updating typematic rate\n");
463 (void) kbd_cmd(KBC_ENABLE
, poll
);
471 if (pos
!= old_pos
) {
473 crtc_write_1(1, pos
>> 8);
475 crtc_write_1(1, pos
);
478 if (cursor_shape
!= old_cursor_shape
)
486 if (kernel
|| polling
) {
488 callout_stop(&async_update_ch
);
494 callout_reset(&async_update_ch
, 1,
495 (void(*)(void *))do_async_update
, NULL
);
500 * these are both bad jokes
503 pccons_common_match(bus_space_tag_t crt_iot
, bus_space_tag_t crt_memt
,
504 bus_space_tag_t kbd_iot
, struct pccons_config
*config
)
508 pc_context_init(crt_iot
, crt_memt
, kbd_iot
, config
);
510 /* Enable interrupts and keyboard, etc. */
511 if (!kbc_put8042cmd(CMDBYTE
)) {
512 printf("pcprobe: command error\n");
517 /* Flush any garbage. */
519 /* Reset the keyboard. */
520 if (!kbd_cmd(KBC_RESET
, 1)) {
521 printf("pcprobe: reset error %d\n", 1);
524 for (i
= 600000; i
; i
--)
525 if ((kbd_cmd_read_1() & KBS_DIB
) != 0) {
529 if (i
== 0 || kbd_data_read_1() != KBR_RSTDONE
) {
530 printf("pcprobe: reset error %d\n", 2);
534 * Some keyboards seem to leave a second ack byte after the reset.
535 * This is kind of stupid, but we account for them anyway by just
536 * flushing the buffer.
539 /* Just to be sure. */
540 if (!kbd_cmd(KBC_ENABLE
, 1)) {
541 printf("pcprobe: reset error %d\n", 3);
546 * Some keyboard/8042 combinations do not seem to work if the keyboard
547 * is set to table 1; in fact, it would appear that some keyboards just
548 * ignore the command altogether. So by default, we use the AT scan
549 * codes and have the 8042 translate them. Unfortunately, this is
550 * known to not work on some PS/2 machines. We try desparately to deal
551 * with this by checking the (lack of a) translate bit in the 8042 and
552 * attempting to set the keyboard to XT mode. If this all fails, well,
555 * XXX It would perhaps be a better choice to just use AT scan codes
556 * and not bother with this.
558 if (kbc_get8042cmd() & KC8_TRANS
) {
559 /* The 8042 is translating for us; use AT codes. */
560 if (!kbd_cmd(KBC_SETTABLE
, 1) || !kbd_cmd(2, 1)) {
561 printf("pcprobe: reset error %d\n", 4);
565 /* Stupid 8042; set keyboard to XT codes. */
566 if (!kbd_cmd(KBC_SETTABLE
, 1) || !kbd_cmd(1, 1)) {
567 printf("pcprobe: reset error %d\n", 5);
574 * Technically, we should probably fail the probe. But we'll be nice
575 * and allow keyboard-less machines to boot with the console.
582 void pccons_common_attach(struct pc_softc
*sc
, bus_space_tag_t crt_iot
,
583 bus_space_tag_t crt_memt
, bus_space_tag_t kbd_iot
,
584 struct pccons_config
*config
)
587 printf(": %s\n", vs
.color
? "color" : "mono");
588 callout_init(&async_update_ch
, 0);
593 pcopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
598 sc
= device_lookup_private(&pc_cd
, PCUNIT(dev
));
603 tp
= sc
->sc_tty
= ttymalloc();
609 tp
->t_oproc
= pcstart
;
610 tp
->t_param
= pcparam
;
613 if (kauth_authorize_device_tty(l
->l_cred
, KAUTH_DEVICE_TTY_OPEN
, tp
))
616 if ((tp
->t_state
& TS_ISOPEN
) == 0) {
618 tp
->t_iflag
= TTYDEF_IFLAG
;
619 tp
->t_oflag
= TTYDEF_OFLAG
;
620 tp
->t_cflag
= TTYDEF_CFLAG
;
621 tp
->t_lflag
= TTYDEF_LFLAG
;
622 tp
->t_ispeed
= tp
->t_ospeed
= TTYDEF_SPEED
;
623 pcparam(tp
, &tp
->t_termios
);
627 tp
->t_state
|= TS_CARR_ON
;
629 return (*tp
->t_linesw
->l_open
)(dev
, tp
);
633 pcclose(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
635 struct pc_softc
*sc
= device_lookup_private(&pc_cd
, PCUNIT(dev
));
636 struct tty
*tp
= sc
->sc_tty
;
638 (*tp
->t_linesw
->l_close
)(tp
, flag
);
640 #ifdef notyet /* XXX */
647 pcread(dev_t dev
, struct uio
*uio
, int flag
)
649 struct pc_softc
*sc
= device_lookup_private(&pc_cd
, PCUNIT(dev
));
650 struct tty
*tp
= sc
->sc_tty
;
652 return (*tp
->t_linesw
->l_read
)(tp
, uio
, flag
);
656 pcwrite(dev_t dev
, struct uio
*uio
, int flag
)
658 struct pc_softc
*sc
= device_lookup_private(&pc_cd
, PCUNIT(dev
));
659 struct tty
*tp
= sc
->sc_tty
;
661 return (*tp
->t_linesw
->l_write
)(tp
, uio
, flag
);
665 pcpoll(dev_t dev
, int events
, struct lwp
*l
)
667 struct pc_softc
*sc
= device_lookup_private(&pc_cd
, PCUNIT(dev
));
668 struct tty
*tp
= sc
->sc_tty
;
670 return (*tp
->t_linesw
->l_poll
)(tp
, events
, l
);
676 struct pc_softc
*sc
= device_lookup_private(&pc_cd
, PCUNIT(dev
));
677 struct tty
*tp
= sc
->sc_tty
;
683 * Got a console receive interrupt -
684 * the console processor wants to give us a character.
685 * Catch the character, and see who it goes to.
690 struct pc_softc
*sc
= arg
;
691 struct tty
*tp
= sc
->sc_tty
;
694 if ((kbd_cmd_read_1() & KBS_DIB
) == 0)
700 if (!tp
|| (tp
->t_state
& TS_ISOPEN
) == 0)
704 (*tp
->t_linesw
->l_rint
)(*cp
++, tp
);
706 } while (kbd_cmd_read_1() & KBS_DIB
);
711 pcioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
713 struct pc_softc
*sc
= device_lookup_private(&pc_cd
, PCUNIT(dev
));
714 struct tty
*tp
= sc
->sc_tty
;
717 error
= (*tp
->t_linesw
->l_ioctl
)(tp
, cmd
, data
, flag
, l
);
718 if (error
!= EPASSTHROUGH
)
720 error
= ttioctl(tp
, cmd
, data
, flag
, l
);
721 if (error
!= EPASSTHROUGH
)
725 case CONSOLE_X_MODE_ON
:
728 case CONSOLE_X_MODE_OFF
:
733 * If set, data is a pointer to a length 2 array of
734 * integers. data[0] is the pitch in Hz and data[1]
735 * is the duration in msec.
738 sysbeep(((int*)data
)[0],
739 (((int*)data
)[1] * hz
) / 1000);
741 sysbeep(BEEP_FREQ
, BEEP_TIME
);
743 case CONSOLE_SET_TYPEMATIC_RATE
: {
748 rate
= *((u_char
*)data
);
750 * Check that it isn't too big (which would cause it to be
751 * confused with a command).
755 typematic_rate
= rate
;
759 case CONSOLE_SET_KEYMAP
: {
760 pccons_keymap_t
*map
= (pccons_keymap_t
*) data
;
765 for (i
= 0; i
< KB_NUM_KEYS
; i
++)
766 if (map
[i
].unshift
[KB_CODE_SIZE
-1] ||
767 map
[i
].shift
[KB_CODE_SIZE
-1] ||
768 map
[i
].ctl
[KB_CODE_SIZE
-1] ||
769 map
[i
].altgr
[KB_CODE_SIZE
-1] ||
770 map
[i
].shift_altgr
[KB_CODE_SIZE
-1])
773 memcpy(scan_codes
, data
, sizeof(pccons_keymap_t
[KB_NUM_KEYS
]));
776 case CONSOLE_GET_KEYMAP
:
779 memcpy(scan_codes
, data
, sizeof(pccons_keymap_t
[KB_NUM_KEYS
]));
787 panic("pcioctl: impossible");
792 pcstart(struct tty
*tp
)
799 if (tp
->t_state
& (TS_TIMEOUT
| TS_BUSY
| TS_TTSTOP
))
801 tp
->t_state
|= TS_BUSY
;
804 * We need to do this outside spl since it could be fairly
805 * expensive and we don't want our serial ports to overflow.
808 len
= q_to_b(cl
, buf
, PCBURST
);
811 tp
->t_state
&= ~TS_BUSY
;
813 tp
->t_state
|= TS_TIMEOUT
;
814 callout_schedule(&tp
->t_rstrt_ch
, 1);
821 void pccons_common_cnattach(bus_space_tag_t crt_iot
, bus_space_tag_t crt_memt
,
822 bus_space_tag_t kbd_iot
, struct pccons_config
*config
)
825 static struct consdev pccons
= {
826 NULL
, NULL
, pccngetc
, pccnputc
, pccnpollc
, NULL
, NULL
,
827 NULL
, NODEV
, CN_NORMAL
831 * For now, don't screw with it.
835 pc_context_init(crt_iot
, crt_memt
, kbd_iot
, config
);
837 /* locate the major number */
838 maj
= cdevsw_lookup_major(&pc_cdevsw
);
839 pccons
.cn_dev
= makedev(maj
, 0);
846 pccnputc(dev_t dev
, int c
)
848 u_char cc
, oldkernel
= kernel
;
871 while ((kbd_cmd_read_1() & KBS_DIB
) == 0);
872 /* see if it's worthwhile */
881 pccnpollc(dev_t dev
, int on
)
891 * If disabling polling on a device that's been configured,
892 * make sure there are no bytes left in the FIFO, holding up
893 * the interrupt line. Otherwise we won't get any further
897 if (pc_cd
.cd_ndevs
> unit
) {
898 sc
= device_lookup_private(&pc_cd
, unit
);
909 * Set line parameters.
912 pcparam(struct tty
*tp
, struct termios
*t
)
915 tp
->t_ispeed
= t
->c_ispeed
;
916 tp
->t_ospeed
= t
->c_ospeed
;
917 tp
->t_cflag
= t
->c_cflag
;
921 #define wrtchar(c, at) do {\
922 char *cp0 = (char *)crtat; *cp0++ = (c); *cp0 = (at); crtat++; vs.col++; \
925 /* translate ANSI color codes to standard pc ones */
926 static char fgansitopc
[] = {
927 FG_BLACK
, FG_RED
, FG_GREEN
, FG_BROWN
, FG_BLUE
,
928 FG_MAGENTA
, FG_CYAN
, FG_LIGHTGREY
931 static char bgansitopc
[] = {
932 BG_BLACK
, BG_RED
, BG_GREEN
, BG_BROWN
, BG_BLUE
,
933 BG_MAGENTA
, BG_CYAN
, BG_LIGHTGREY
936 static u_char iso2ibm437
[] =
938 0, 0, 0, 0, 0, 0, 0, 0,
939 0, 0, 0, 0, 0, 0, 0, 0,
940 0, 0, 0, 0, 0, 0, 0, 0,
941 0, 0, 0, 0, 0, 0, 0, 0,
942 0xff, 0xad, 0x9b, 0x9c, 0, 0x9d, 0, 0x40,
943 0x6f, 0x63, 0x61, 0xae, 0, 0, 0, 0,
944 0xf8, 0xf1, 0xfd, 0x33, 0, 0xe6, 0, 0xfa,
945 0, 0x31, 0x6f, 0xaf, 0xac, 0xab, 0, 0xa8,
946 0x41, 0x41, 0x41, 0x41, 0x8e, 0x8f, 0x92, 0x80,
947 0x45, 0x90, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49,
948 0x81, 0xa5, 0x4f, 0x4f, 0x4f, 0x4f, 0x99, 0x4f,
949 0x4f, 0x55, 0x55, 0x55, 0x9a, 0x59, 0, 0xe1,
950 0x85, 0xa0, 0x83, 0x61, 0x84, 0x86, 0x91, 0x87,
951 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b,
952 0, 0xa4, 0x95, 0xa2, 0x93, 0x6f, 0x94, 0x6f,
953 0x6f, 0x97, 0xa3, 0x96, 0x81, 0x98, 0, 0
957 * `pc3' termcap emulation.
960 sput(const u_char
*cp
, int n
)
962 struct pccons_context
*pc
= &pccons_console_context
;
963 u_char c
, scroll
= 0;
969 volatile u_short
*dp
;
973 dp
= bus_space_vaddr(pc
->pc_crt_memt
, pc
->pc_cga_memh
);
977 dp
= bus_space_vaddr(pc
->pc_crt_memt
,
979 pc
->pc_6845_ioh
= pc
->pc_mono_ioh
;
980 pc
->pc_crt_memh
= pc
->pc_mono_memh
;
984 pc
->pc_6845_ioh
= pc
->pc_cga_ioh
;
985 pc
->pc_crt_memh
= pc
->pc_cga_memh
;
990 cursor_shape
= 0x0012;
995 bios_display_info(&vs
.col
, &vs
.row
, &vs
.ncol
, &vs
.nrow
);
996 vs
.nchr
= vs
.ncol
* vs
.nrow
;
999 cursorat
= vs
.ncol
* vs
.row
+ vs
.col
;
1000 vs
.at
= FG_LIGHTGREY
| BG_BLACK
;
1002 Crtat
= (u_short
*)__UNVOLATILE(dp
);
1003 crtat
= Crtat
+ cursorat
;
1006 vs
.so_at
= FG_BLACK
| BG_LIGHTGREY
;
1008 vs
.so_at
= FG_YELLOW
| BG_BLACK
;
1010 fillw((vs
.at
<< 8) | ' ', crtat
, vs
.nchr
- cursorat
);
1019 if (vs
.state
>= VSS_ESCAPE
) {
1020 wrtchar(c
, vs
.so_at
);
1024 vs
.state
= VSS_ESCAPE
;
1027 case 0x9B: /* CSI */
1029 vs
.state
= VSS_EBRACE
;
1033 int inccol
= 8 - (vs
.col
& 7);
1038 if (vs
.col
>= vs
.ncol
) {
1049 vs
.col
+= vs
.ncol
; /* non-destructive backspace */
1066 sysbeep(BEEP_FREQ
, BEEP_TIME
);
1069 * If we're outputting multiple printed
1070 * characters, just blast them to the
1071 * screen until we reach the end of the
1072 * buffer or a control character. This
1073 * saves time by short-circuiting the
1075 * If we reach the end of the line, we
1076 * break to do a scroll check.
1080 c
= iso2ibm437
[c
&0x7f];
1083 wrtchar(c
, vs
.so_at
);
1086 if (vs
.col
>= vs
.ncol
) {
1091 if (!n
|| (c
= *cp
) < ' ')
1099 case '[': /* Start ESC [ sequence */
1101 vs
.state
= VSS_EBRACE
;
1103 case 'c': /* Create screen & home */
1104 fillw((vs
.at
<< 8) | ' ',
1110 case '7': /* save cursor pos */
1111 vs
.offset
= crtat
- Crtat
;
1114 case '8': /* restore cursor pos */
1115 crtat
= Crtat
+ vs
.offset
;
1116 vs
.row
= vs
.offset
/ vs
.ncol
;
1117 vs
.col
= vs
.offset
% vs
.ncol
;
1120 default: /* Invalid, clear state */
1121 wrtchar(c
, vs
.so_at
);
1127 default: /* VSS_EBRACE or VSS_EPARAM */
1137 case 'A': { /* back cx rows */
1143 pos
= crtat
- Crtat
;
1144 pos
-= vs
.ncol
* cx
;
1147 crtat
= Crtat
+ pos
;
1151 case 'B': { /* down cx rows */
1157 pos
= crtat
- Crtat
;
1158 pos
+= vs
.ncol
* cx
;
1161 crtat
= Crtat
+ pos
;
1165 case 'C': { /* right cursor */
1172 pos
= crtat
- Crtat
;
1175 if (col
>= vs
.ncol
) {
1180 crtat
= Crtat
+ pos
;
1184 case 'D': { /* left cursor */
1191 pos
= crtat
- Crtat
;
1199 crtat
= Crtat
+ pos
;
1203 case 'J': /* Clear ... */
1206 /* ... to end of display */
1207 fillw((vs
.at
<< 8) | ' ',
1209 Crtat
+ vs
.nchr
- crtat
);
1212 /* ... to next location */
1213 fillw((vs
.at
<< 8) | ' ',
1218 /* ... whole display */
1219 fillw((vs
.at
<< 8) | ' ',
1226 case 'K': /* Clear line ... */
1229 /* ... current to EOL */
1230 fillw((vs
.at
<< 8) | ' ',
1235 /* ... beginning to next */
1236 fillw((vs
.at
<< 8) | ' ',
1241 /* ... entire line */
1242 fillw((vs
.at
<< 8) | ' ',
1243 crtat
- vs
.col
, vs
.ncol
);
1248 case 'f': /* in system V consoles */
1249 case 'H': { /* Cursor move */
1261 (cx
- 1) * vs
.ncol
+ cy
- 1;
1267 case 'M': { /* delete cx rows */
1268 u_short
*crtAt
= crtat
- vs
.col
;
1270 row
= (crtAt
- Crtat
) / vs
.ncol
,
1271 nrow
= vs
.nrow
- row
;
1277 #ifdef PCCONS_FORCE_WORD
1278 wcopy(crtAt
+ vs
.ncol
* cx
,
1279 crtAt
, vs
.ncol
* (nrow
-
1283 crtAt
+ vs
.ncol
* cx
,
1284 vs
.ncol
* (nrow
- cx
) *
1287 fillw((vs
.at
<< 8) | ' ',
1288 crtAt
+ vs
.ncol
* (nrow
- cx
),
1293 case 'S': { /* scroll up cx lines */
1297 else if (cx
> vs
.nrow
)
1300 #ifdef PCCONS_FORCE_WORD
1301 wcopy(Crtat
+ vs
.ncol
* cx
,
1302 Crtat
, vs
.ncol
* (vs
.nrow
-
1306 Crtat
+ vs
.ncol
* cx
,
1307 vs
.ncol
* (vs
.nrow
- cx
) *
1310 fillw((vs
.at
<< 8) | ' ',
1311 Crtat
+ vs
.ncol
* (vs
.nrow
- cx
),
1313 /* crtat -= vs.ncol * cx; XXX */
1317 case 'L': { /* insert cx rows */
1318 u_short
*crtAt
= crtat
- vs
.col
;
1320 row
= (crtAt
- Crtat
) / vs
.ncol
,
1321 nrow
= vs
.nrow
- row
;
1327 #ifdef PCCONS_FORCE_WORD
1329 crtAt
+ vs
.ncol
* cx
,
1330 vs
.ncol
* (nrow
- cx
) *
1333 memmove(crtAt
+ vs
.ncol
* cx
,
1335 vs
.ncol
* (nrow
- cx
) *
1338 fillw((vs
.at
<< 8) | ' ', crtAt
,
1343 case 'T': { /* scroll down cx lines */
1347 else if (cx
> vs
.nrow
)
1350 #ifdef PCCONS_FORCE_WORD
1352 Crtat
+ vs
.ncol
* cx
,
1353 vs
.ncol
* (vs
.nrow
- cx
) *
1356 memmove(Crtat
+ vs
.ncol
* cx
,
1358 vs
.ncol
* (vs
.nrow
- cx
) *
1361 fillw((vs
.at
<< 8) | ' ', Crtat
,
1363 /* crtat += vs.ncol * cx; XXX */
1367 case ';': /* Switch params in cursor def */
1368 vs
.state
= VSS_EPARAM
;
1371 vs
.so_at
= (vs
.cx
& FG_MASK
) |
1372 ((vs
.cy
<< 4) & BG_MASK
);
1375 case 's': /* save cursor pos */
1376 vs
.offset
= crtat
- Crtat
;
1379 case 'u': /* restore cursor pos */
1380 crtat
= Crtat
+ vs
.offset
;
1381 vs
.row
= vs
.offset
/ vs
.ncol
;
1382 vs
.col
= vs
.offset
% vs
.ncol
;
1385 case 'x': /* set attributes */
1388 vs
.at
= FG_LIGHTGREY
| BG_BLACK
;
1391 /* ansi background */
1395 vs
.at
|= bgansitopc
[vs
.cy
& 7];
1398 /* ansi foreground */
1402 vs
.at
|= fgansitopc
[vs
.cy
& 7];
1405 /* pc text attribute */
1406 if (vs
.state
>= VSS_EPARAM
)
1413 default: /* Only numbers valid here */
1414 if ((c
>= '0') && (c
<= '9')) {
1415 if (vs
.state
>= VSS_EPARAM
) {
1432 if (crtat
>= Crtat
+ vs
.nchr
) {
1435 if (lock_state
& KB_SCROLL
)
1437 PUSER
, "pcputc", 0);
1440 #if PCCONS_FORCE_WORD
1441 wcopy(Crtat
+ vs
.ncol
, Crtat
,
1442 (vs
.nchr
- vs
.ncol
) * CHR
);
1444 memmove(Crtat
, Crtat
+ vs
.ncol
,
1445 (vs
.nchr
- vs
.ncol
) * CHR
);
1447 fillw((vs
.at
<< 8) | ' ',
1448 Crtat
+ vs
.nchr
- vs
.ncol
,
1457 /* the unshifted code for KB_SHIFT keys is used by X to distinguish between
1458 left and right shift when reading the keyboard map */
1459 static pccons_keymap_t scan_codes
[KB_NUM_KEYS
] = {
1460 /* type unshift shift control altgr shift_altgr scancode */
1461 { KB_NONE
, "", "", "", "", ""}, /* 0 unused */
1462 { KB_ASCII
, "\033", "\033", "\033", "", ""}, /* 1 ESCape */
1463 { KB_ASCII
, "1", "!", "!", "", ""}, /* 2 1 */
1464 { KB_ASCII
, "2", "@", "\000", "", ""}, /* 3 2 */
1465 { KB_ASCII
, "3", "#", "#", "", ""}, /* 4 3 */
1466 { KB_ASCII
, "4", "$", "$", "", ""}, /* 5 4 */
1467 { KB_ASCII
, "5", "%", "%", "", ""}, /* 6 5 */
1468 { KB_ASCII
, "6", "^", "\036", "", ""}, /* 7 6 */
1469 { KB_ASCII
, "7", "&", "&", "", ""}, /* 8 7 */
1470 { KB_ASCII
, "8", "*", "\010", "", ""}, /* 9 8 */
1471 { KB_ASCII
, "9", "(", "(", "", ""}, /* 10 9 */
1472 { KB_ASCII
, "0", ")", ")", "", ""}, /* 11 0 */
1473 { KB_ASCII
, "-", "_", "\037", "", ""}, /* 12 - */
1474 { KB_ASCII
, "=", "+", "+", "", ""}, /* 13 = */
1475 { KB_ASCII
, "\177", "\177", "\010", "", ""}, /* 14 backspace */
1476 { KB_ASCII
, "\t", "\t", "\t", "", ""}, /* 15 tab */
1477 { KB_ASCII
, "q", "Q", "\021", "", ""}, /* 16 q */
1478 { KB_ASCII
, "w", "W", "\027", "", ""}, /* 17 w */
1479 { KB_ASCII
, "e", "E", "\005", "", ""}, /* 18 e */
1480 { KB_ASCII
, "r", "R", "\022", "", ""}, /* 19 r */
1481 { KB_ASCII
, "t", "T", "\024", "", ""}, /* 20 t */
1482 { KB_ASCII
, "y", "Y", "\031", "", ""}, /* 21 y */
1483 { KB_ASCII
, "u", "U", "\025", "", ""}, /* 22 u */
1484 { KB_ASCII
, "i", "I", "\011", "", ""}, /* 23 i */
1485 { KB_ASCII
, "o", "O", "\017", "", ""}, /* 24 o */
1486 { KB_ASCII
, "p", "P", "\020", "", ""}, /* 25 p */
1487 { KB_ASCII
, "[", "{", "\033", "", ""}, /* 26 [ */
1488 { KB_ASCII
, "]", "}", "\035", "", ""}, /* 27 ] */
1489 { KB_ASCII
, "\r", "\r", "\n", "", ""}, /* 28 return */
1490 { KB_CTL
, "", "", "", "", ""}, /* 29 control */
1491 { KB_ASCII
, "a", "A", "\001", "", ""}, /* 30 a */
1492 { KB_ASCII
, "s", "S", "\023", "", ""}, /* 31 s */
1493 { KB_ASCII
, "d", "D", "\004", "", ""}, /* 32 d */
1494 { KB_ASCII
, "f", "F", "\006", "", ""}, /* 33 f */
1495 { KB_ASCII
, "g", "G", "\007", "", ""}, /* 34 g */
1496 { KB_ASCII
, "h", "H", "\010", "", ""}, /* 35 h */
1497 { KB_ASCII
, "j", "J", "\n", "", ""}, /* 36 j */
1498 { KB_ASCII
, "k", "K", "\013", "", ""}, /* 37 k */
1499 { KB_ASCII
, "l", "L", "\014", "", ""}, /* 38 l */
1500 { KB_ASCII
, ";", ":", ";", "", ""}, /* 39 ; */
1501 { KB_ASCII
, "'", "\"", "'", "", ""}, /* 40 ' */
1502 { KB_ASCII
, "`", "~", "`", "", ""}, /* 41 ` */
1503 { KB_SHIFT
, "\001", "", "", "", ""}, /* 42 shift */
1504 { KB_ASCII
, "\\", "|", "\034", "", ""}, /* 43 \ */
1505 { KB_ASCII
, "z", "Z", "\032", "", ""}, /* 44 z */
1506 { KB_ASCII
, "x", "X", "\030", "", ""}, /* 45 x */
1507 { KB_ASCII
, "c", "C", "\003", "", ""}, /* 46 c */
1508 { KB_ASCII
, "v", "V", "\026", "", ""}, /* 47 v */
1509 { KB_ASCII
, "b", "B", "\002", "", ""}, /* 48 b */
1510 { KB_ASCII
, "n", "N", "\016", "", ""}, /* 49 n */
1511 { KB_ASCII
, "m", "M", "\r", "", ""}, /* 50 m */
1512 { KB_ASCII
, ",", "<", "<", "", ""}, /* 51 , */
1513 { KB_ASCII
, ".", ">", ">", "", ""}, /* 52 . */
1514 { KB_ASCII
, "/", "?", "\037", "", ""}, /* 53 / */
1515 { KB_SHIFT
, "\002", "", "", "", ""}, /* 54 shift */
1516 { KB_KP
, "*", "*", "*", "", ""}, /* 55 kp * */
1517 { KB_ALT
, "", "", "", "", ""}, /* 56 alt */
1518 { KB_ASCII
, " ", " ", "\000", "", ""}, /* 57 space */
1519 { KB_CAPS
, "", "", "", "", ""}, /* 58 caps */
1520 { KB_FUNC
, "\033[M", "\033[Y", "\033[k", "", ""}, /* 59 f1 */
1521 { KB_FUNC
, "\033[N", "\033[Z", "\033[l", "", ""}, /* 60 f2 */
1522 { KB_FUNC
, "\033[O", "\033[a", "\033[m", "", ""}, /* 61 f3 */
1523 { KB_FUNC
, "\033[P", "\033[b", "\033[n", "", ""}, /* 62 f4 */
1524 { KB_FUNC
, "\033[Q", "\033[c", "\033[o", "", ""}, /* 63 f5 */
1525 { KB_FUNC
, "\033[R", "\033[d", "\033[p", "", ""}, /* 64 f6 */
1526 { KB_FUNC
, "\033[S", "\033[e", "\033[q", "", ""}, /* 65 f7 */
1527 { KB_FUNC
, "\033[T", "\033[f", "\033[r", "", ""}, /* 66 f8 */
1528 { KB_FUNC
, "\033[U", "\033[g", "\033[s", "", ""}, /* 67 f9 */
1529 { KB_FUNC
, "\033[V", "\033[h", "\033[t", "", ""}, /* 68 f10 */
1530 { KB_NUM
, "", "", "", "", ""}, /* 69 num lock */
1531 { KB_SCROLL
, "", "", "", "", ""}, /* 70 scroll lock */
1532 { KB_KP
, "7", "\033[H", "7", "", ""}, /* 71 kp 7 */
1533 { KB_KP
, "8", "\033[A", "8", "", ""}, /* 72 kp 8 */
1534 { KB_KP
, "9", "\033[I", "9", "", ""}, /* 73 kp 9 */
1535 { KB_KP
, "-", "-", "-", "", ""}, /* 74 kp - */
1536 { KB_KP
, "4", "\033[D", "4", "", ""}, /* 75 kp 4 */
1537 { KB_KP
, "5", "\033[E", "5", "", ""}, /* 76 kp 5 */
1538 { KB_KP
, "6", "\033[C", "6", "", ""}, /* 77 kp 6 */
1539 { KB_KP
, "+", "+", "+", "", ""}, /* 78 kp + */
1540 { KB_KP
, "1", "\033[F", "1", "", ""}, /* 79 kp 1 */
1541 { KB_KP
, "2", "\033[B", "2", "", ""}, /* 80 kp 2 */
1542 { KB_KP
, "3", "\033[G", "3", "", ""}, /* 81 kp 3 */
1543 { KB_KP
, "0", "\033[L", "0", "", ""}, /* 82 kp 0 */
1544 { KB_KP
, ",", "\177", ",", "", ""}, /* 83 kp , */
1545 { KB_NONE
, "", "", "", "", ""}, /* 84 0 */
1546 { KB_NONE
, "", "", "", "", ""}, /* 85 0 */
1547 { KB_NONE
, "", "", "", "", ""}, /* 86 0 */
1548 { KB_FUNC
, "\033[W", "\033[i", "\033[u", "", ""}, /* 87 f11 */
1549 { KB_FUNC
, "\033[X", "\033[j", "\033[v", "", ""}, /* 88 f12 */
1550 { KB_NONE
, "", "", "", "", ""}, /* 89 0 */
1551 { KB_NONE
, "", "", "", "", ""}, /* 90 0 */
1552 { KB_NONE
, "", "", "", "", ""}, /* 91 0 */
1553 { KB_NONE
, "", "", "", "", ""}, /* 92 0 */
1554 { KB_NONE
, "", "", "", "", ""}, /* 93 0 */
1555 { KB_NONE
, "", "", "", "", ""}, /* 94 0 */
1556 { KB_NONE
, "", "", "", "", ""}, /* 95 0 */
1557 { KB_NONE
, "", "", "", "", ""}, /* 96 0 */
1558 { KB_NONE
, "", "", "", "", ""}, /* 97 0 */
1559 { KB_NONE
, "", "", "", "", ""}, /* 98 0 */
1560 { KB_NONE
, "", "", "", "", ""}, /* 99 0 */
1561 { KB_NONE
, "", "", "", "", ""}, /* 100 */
1562 { KB_NONE
, "", "", "", "", ""}, /* 101 */
1563 { KB_NONE
, "", "", "", "", ""}, /* 102 */
1564 { KB_NONE
, "", "", "", "", ""}, /* 103 */
1565 { KB_NONE
, "", "", "", "", ""}, /* 104 */
1566 { KB_NONE
, "", "", "", "", ""}, /* 105 */
1567 { KB_NONE
, "", "", "", "", ""}, /* 106 */
1568 { KB_NONE
, "", "", "", "", ""}, /* 107 */
1569 { KB_NONE
, "", "", "", "", ""}, /* 108 */
1570 { KB_NONE
, "", "", "", "", ""}, /* 109 */
1571 { KB_NONE
, "", "", "", "", ""}, /* 110 */
1572 { KB_NONE
, "", "", "", "", ""}, /* 111 */
1573 { KB_NONE
, "", "", "", "", ""}, /* 112 */
1574 { KB_NONE
, "", "", "", "", ""}, /* 113 */
1575 { KB_NONE
, "", "", "", "", ""}, /* 114 */
1576 { KB_NONE
, "", "", "", "", ""}, /* 115 */
1577 { KB_NONE
, "", "", "", "", ""}, /* 116 */
1578 { KB_NONE
, "", "", "", "", ""}, /* 117 */
1579 { KB_NONE
, "", "", "", "", ""}, /* 118 */
1580 { KB_NONE
, "", "", "", "", ""}, /* 119 */
1581 { KB_NONE
, "", "", "", "", ""}, /* 120 */
1582 { KB_NONE
, "", "", "", "", ""}, /* 121 */
1583 { KB_NONE
, "", "", "", "", ""}, /* 122 */
1584 { KB_NONE
, "", "", "", "", ""}, /* 123 */
1585 { KB_NONE
, "", "", "", "", ""}, /* 124 */
1586 { KB_NONE
, "", "", "", "", ""}, /* 125 */
1587 { KB_NONE
, "", "", "", "", ""}, /* 126 */
1588 { KB_NONE
, "", "", "", "", ""} /* 127 */
1592 * Get characters from the keyboard. If none are present, return NULL.
1598 static u_char extended
= 0, shift_state
= 0;
1599 static u_char capchar
[2];
1603 dt
= kbd_data_read_1();
1606 case KBR_ACK
: case KBR_ECHO
:
1607 kb_oq_get
= (kb_oq_get
+ 1) & 7;
1608 if(kb_oq_get
!= kb_oq_put
) {
1609 kbd_data_write_1(kb_oq
[kb_oq_get
]);
1613 kbd_data_write_1(kb_oq
[kb_oq_get
]);
1618 #if defined(DDB) && defined(XSERVER_DDB)
1619 /* F12 enters the debugger while in X mode */
1626 * Check for locking keys.
1628 * XXX Setting the LEDs this way is a bit bogus. What if the
1629 * keyboard has been remapped in X?
1631 switch (scan_codes
[dt
& 0x7f].type
) {
1634 shift_state
&= ~KB_NUM
;
1637 if (shift_state
& KB_NUM
)
1639 shift_state
|= KB_NUM
;
1640 lock_state
^= KB_NUM
;
1645 shift_state
&= ~KB_CAPS
;
1648 if (shift_state
& KB_CAPS
)
1650 shift_state
|= KB_CAPS
;
1651 lock_state
^= KB_CAPS
;
1656 shift_state
&= ~KB_SCROLL
;
1659 if (shift_state
& KB_SCROLL
)
1661 shift_state
|= KB_SCROLL
;
1662 lock_state
^= KB_SCROLL
;
1663 if ((lock_state
& KB_SCROLL
) == 0)
1664 wakeup((void *)&lock_state
);
1679 * Check for cntl-alt-esc.
1681 if ((dt
== 1) && (shift_state
& (KB_CTL
| KB_ALT
)) == (KB_CTL
| KB_ALT
)) {
1682 /* XXX - check pccons_is_console */
1684 dt
|= 0x80; /* discard esc (ddb discarded ctl-alt) */
1689 * Check for make/break.
1696 switch (scan_codes
[dt
].type
) {
1698 shift_state
&= ~KB_NUM
;
1701 shift_state
&= ~KB_CAPS
;
1704 shift_state
&= ~KB_SCROLL
;
1707 shift_state
&= ~KB_SHIFT
;
1711 shift_state
&= ~KB_ALTGR
;
1713 shift_state
&= ~KB_ALT
;
1716 shift_state
&= ~KB_CTL
;
1723 switch (scan_codes
[dt
].type
) {
1728 if (shift_state
& KB_NUM
)
1730 shift_state
|= KB_NUM
;
1731 lock_state
^= KB_NUM
;
1735 if (shift_state
& KB_CAPS
)
1737 shift_state
|= KB_CAPS
;
1738 lock_state
^= KB_CAPS
;
1742 if (shift_state
& KB_SCROLL
)
1744 shift_state
|= KB_SCROLL
;
1745 lock_state
^= KB_SCROLL
;
1746 if ((lock_state
& KB_SCROLL
) == 0)
1747 wakeup((void *)&lock_state
);
1754 shift_state
|= KB_SHIFT
;
1758 shift_state
|= KB_ALTGR
;
1760 shift_state
|= KB_ALT
;
1763 shift_state
|= KB_CTL
;
1766 /* control has highest priority */
1767 if (shift_state
& KB_CTL
)
1768 capchar
[0] = scan_codes
[dt
].ctl
[0];
1769 else if (shift_state
& KB_ALTGR
) {
1770 if (shift_state
& KB_SHIFT
)
1771 capchar
[0] = scan_codes
[dt
].shift_altgr
[0];
1773 capchar
[0] = scan_codes
[dt
].altgr
[0];
1776 if (shift_state
& KB_SHIFT
)
1777 capchar
[0] = scan_codes
[dt
].shift
[0];
1779 capchar
[0] = scan_codes
[dt
].unshift
[0];
1781 if ((lock_state
& KB_CAPS
) && capchar
[0] >= 'a' &&
1782 capchar
[0] <= 'z') {
1783 capchar
[0] -= ('a' - 'A');
1785 capchar
[0] |= (shift_state
& KB_ALT
);
1789 printf("keycode %d\n",dt
);
1793 if (shift_state
& KB_SHIFT
)
1794 more_chars
= scan_codes
[dt
].shift
;
1795 else if (shift_state
& KB_CTL
)
1796 more_chars
= scan_codes
[dt
].ctl
;
1798 more_chars
= scan_codes
[dt
].unshift
;
1804 if (shift_state
& (KB_SHIFT
| KB_CTL
) ||
1805 (lock_state
& KB_NUM
) == 0 || extended
)
1806 more_chars
= scan_codes
[dt
].shift
;
1808 more_chars
= scan_codes
[dt
].unshift
;
1817 if ((kbd_cmd_read_1() & KBS_DIB
) == 0)
1823 pcmmap(dev_t dev
, off_t offset
, int nprot
)
1825 struct pccons_context
*pc
= &pccons_console_context
;
1828 if (offset
>= 0xa0000 && offset
< 0xc0000) {
1829 if (bus_space_paddr(pc
->pc_crt_memt
, pc
->pc_mono_memh
, &pa
))
1831 pa
+= offset
- pc
->pc_config
->pc_mono_memaddr
;
1832 return mips_btop(pa
);
1834 if (offset
>= 0x0000 && offset
< 0x10000) {
1835 if (bus_space_paddr(pc
->pc_crt_iot
, pc
->pc_mono_ioh
, &pa
))
1837 pa
+= offset
- pc
->pc_config
->pc_mono_iobase
;
1838 return mips_btop(pa
);
1840 if (offset
>= 0x40000000 && offset
< 0x40800000) {
1841 if (bus_space_paddr(pc
->pc_crt_memt
, pc
->pc_mono_memh
, &pa
))
1843 pa
+= offset
- 0x40000000 - pc
->pc_config
->pc_mono_memaddr
;
1844 return mips_btop(pa
);
1856 #ifdef XFREE86_BUG_COMPAT
1857 /* If still unchanged, get current shape. */
1858 if (cursor_shape
== 0xffff)
1870 #ifdef XFREE86_BUG_COMPAT
1871 /* XXX It would be hard to justify why the X server doesn't do this. */