1 1.63 andvar /* $NetBSD: pccons.c,v 1.63 2022/05/24 20:50:18 andvar 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.1 jonathan 5 1.1 jonathan /*- 6 1.1 jonathan * Copyright (c) 1990 The Regents of the University of California. 7 1.1 jonathan * All rights reserved. 8 1.1 jonathan * 9 1.1 jonathan * This code is derived from software contributed to Berkeley by 10 1.1 jonathan * William Jolitz and Don Ahn. 11 1.1 jonathan * 12 1.37 agc * modification, are permitted provided that the following conditions 13 1.37 agc * are met: 14 1.37 agc * 1. Redistributions of source code must retain the above copyright 15 1.37 agc * notice, this list of conditions and the following disclaimer. 16 1.37 agc * 2. Redistributions in binary form must reproduce the above copyright 17 1.37 agc * notice, this list of conditions and the following disclaimer in the 18 1.37 agc * documentation and/or other materials provided with the distribution. 19 1.37 agc * 3. Neither the name of the University nor the names of its contributors 20 1.37 agc * may be used to endorse or promote products derived from this software 21 1.37 agc * without specific prior written permission. 22 1.37 agc * 23 1.37 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 1.37 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 1.37 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 1.37 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 1.37 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 1.37 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 1.37 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 1.37 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 1.37 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 1.37 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 1.37 agc * SUCH DAMAGE. 34 1.37 agc * 35 1.37 agc * @(#)pccons.c 5.11 (Berkeley) 5/21/91 36 1.37 agc */ 37 1.37 agc 38 1.37 agc /*- 39 1.37 agc * Copyright (c) 1993, 1994, 1995 Charles M. Hannum. All rights reserved. 40 1.37 agc * 41 1.37 agc * This code is derived from software contributed to Berkeley by 42 1.37 agc * William Jolitz and Don Ahn. 43 1.37 agc * 44 1.11 mycroft * Copyright (c) 1994 Charles M. Hannum. 45 1.1 jonathan * Copyright (c) 1992, 1993 Erik Forsberg. 46 1.1 jonathan * 47 1.1 jonathan * Redistribution and use in source and binary forms, with or without 48 1.1 jonathan * modification, are permitted provided that the following conditions 49 1.1 jonathan * are met: 50 1.1 jonathan * 1. Redistributions of source code must retain the above copyright 51 1.1 jonathan * notice, this list of conditions and the following disclaimer. 52 1.1 jonathan * 2. Redistributions in binary form must reproduce the above copyright 53 1.1 jonathan * notice, this list of conditions and the following disclaimer in the 54 1.1 jonathan * documentation and/or other materials provided with the distribution. 55 1.1 jonathan * 3. All advertising materials mentioning features or use of this software 56 1.1 jonathan * must display the following acknowledgement: 57 1.1 jonathan * This product includes software developed by the University of 58 1.1 jonathan * California, Berkeley and its contributors. 59 1.1 jonathan * 4. Neither the name of the University nor the names of its contributors 60 1.1 jonathan * may be used to endorse or promote products derived from this software 61 1.1 jonathan * without specific prior written permission. 62 1.1 jonathan * 63 1.1 jonathan * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 64 1.1 jonathan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 65 1.1 jonathan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 66 1.1 jonathan * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 67 1.1 jonathan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 68 1.1 jonathan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 69 1.1 jonathan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 70 1.1 jonathan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 71 1.1 jonathan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 72 1.1 jonathan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 73 1.1 jonathan * SUCH DAMAGE. 74 1.1 jonathan * 75 1.1 jonathan * @(#)pccons.c 5.11 (Berkeley) 5/21/91 76 1.1 jonathan */ 77 1.1 jonathan 78 1.1 jonathan /* 79 1.1 jonathan * code to work keyboard & display for PC-style console 80 1.1 jonathan */ 81 1.36 lukem 82 1.36 lukem #include <sys/cdefs.h> 83 1.63 andvar __KERNEL_RCSID(0, "$NetBSD: pccons.c,v 1.63 2022/05/24 20:50:18 andvar Exp $"); 84 1.1 jonathan 85 1.14 soda #include "opt_ddb.h" 86 1.14 soda 87 1.1 jonathan #include <sys/param.h> 88 1.1 jonathan #include <sys/systm.h> 89 1.1 jonathan #include <sys/tty.h> 90 1.1 jonathan #include <sys/callout.h> 91 1.8 jonathan #include <sys/poll.h> 92 1.13 soda #include <sys/conf.h> 93 1.13 soda #include <sys/vnode.h> 94 1.13 soda #include <sys/kernel.h> 95 1.13 soda #include <sys/kcore.h> 96 1.27 soda #include <sys/device.h> 97 1.28 chs #include <sys/proc.h> 98 1.44 elad #include <sys/kauth.h> 99 1.1 jonathan 100 1.59 dyoung #include <sys/bus.h> 101 1.1 jonathan 102 1.45 tsutsui #include <dev/ic/pcdisplay.h> 103 1.1 jonathan #include <machine/pccons.h> 104 1.1 jonathan #include <machine/kbdreg.h> 105 1.1 jonathan 106 1.13 soda #include <dev/cons.h> 107 1.27 soda #include <dev/isa/isavar.h> 108 1.13 soda 109 1.27 soda #include <arc/arc/arcbios.h> 110 1.27 soda #include <arc/dev/pcconsvar.h> 111 1.20 soda 112 1.43 tsutsui #include "ioconf.h" 113 1.43 tsutsui 114 1.1 jonathan #define XFREE86_BUG_COMPAT 115 1.1 jonathan 116 1.1 jonathan #ifndef BEEP_FREQ 117 1.1 jonathan #define BEEP_FREQ 1600 118 1.1 jonathan #endif 119 1.1 jonathan #ifndef BEEP_TIME 120 1.1 jonathan #define BEEP_TIME (hz/5) 121 1.1 jonathan #endif 122 1.1 jonathan 123 1.1 jonathan #define PCBURST 128 124 1.1 jonathan 125 1.1 jonathan static u_short *Crtat; /* pointer to backing store */ 126 1.1 jonathan static u_short *crtat; /* pointer to current char */ 127 1.1 jonathan static u_char async, kernel, polling; /* Really, you don't want to know. */ 128 1.1 jonathan static u_char lock_state = 0x00, /* all off */ 129 1.1 jonathan old_lock_state = 0xff, 130 1.1 jonathan typematic_rate = 0xff, /* don't update until set by user */ 131 1.1 jonathan old_typematic_rate = 0xff; 132 1.1 jonathan static u_short cursor_shape = 0xffff, /* don't update until set by user */ 133 1.1 jonathan old_cursor_shape = 0xffff; 134 1.13 soda static pccons_keymap_t scan_codes[KB_NUM_KEYS];/* keyboard translation table */ 135 1.1 jonathan int pc_xmode = 0; 136 1.1 jonathan 137 1.1 jonathan /* 138 1.1 jonathan * Keyboard output queue. 139 1.1 jonathan */ 140 1.1 jonathan int kb_oq_put = 0; 141 1.1 jonathan int kb_oq_get = 0; 142 1.1 jonathan u_char kb_oq[8]; 143 1.1 jonathan 144 1.1 jonathan #define PCUNIT(x) (minor(x)) 145 1.1 jonathan 146 1.1 jonathan static struct video_state { 147 1.1 jonathan int cx, cy; /* escape parameters */ 148 1.1 jonathan int row, col; /* current cursor position */ 149 1.1 jonathan int nrow, ncol, nchr; /* current screen geometry */ 150 1.13 soda int offset; /* Saved cursor pos */ 151 1.1 jonathan u_char state; /* parser state */ 152 1.1 jonathan #define VSS_ESCAPE 1 153 1.1 jonathan #define VSS_EBRACE 2 154 1.1 jonathan #define VSS_EPARAM 3 155 1.1 jonathan char so; /* in standout mode? */ 156 1.1 jonathan char color; /* color or mono display */ 157 1.1 jonathan char at; /* normal attributes */ 158 1.1 jonathan char so_at; /* standout attributes */ 159 1.1 jonathan } vs; 160 1.1 jonathan 161 1.50 ad static callout_t async_update_ch; 162 1.17 thorpej 163 1.39 tsutsui void pc_xmode_on(void); 164 1.39 tsutsui void pc_xmode_off(void); 165 1.39 tsutsui static u_char kbc_get8042cmd(void); 166 1.39 tsutsui int kbd_cmd(u_char, u_char); 167 1.42 perry static inline int kbd_wait_output(void); 168 1.42 perry static inline int kbd_wait_input(void); 169 1.39 tsutsui void kbd_flush_input(void); 170 1.39 tsutsui void set_cursor_shape(void); 171 1.39 tsutsui void get_cursor_shape(void); 172 1.39 tsutsui void async_update(void); 173 1.39 tsutsui void do_async_update(u_char); 174 1.39 tsutsui 175 1.39 tsutsui void pccnputc(dev_t, int c); 176 1.39 tsutsui int pccngetc(dev_t); 177 1.39 tsutsui void pccnpollc(dev_t, int); 178 1.1 jonathan 179 1.30 gehenna dev_type_open(pcopen); 180 1.30 gehenna dev_type_close(pcclose); 181 1.30 gehenna dev_type_read(pcread); 182 1.30 gehenna dev_type_write(pcwrite); 183 1.30 gehenna dev_type_ioctl(pcioctl); 184 1.30 gehenna dev_type_tty(pctty); 185 1.30 gehenna dev_type_poll(pcpoll); 186 1.30 gehenna dev_type_mmap(pcmmap); 187 1.30 gehenna 188 1.30 gehenna const struct cdevsw pc_cdevsw = { 189 1.60 dholland .d_open = pcopen, 190 1.60 dholland .d_close = pcclose, 191 1.60 dholland .d_read = pcread, 192 1.60 dholland .d_write = pcwrite, 193 1.60 dholland .d_ioctl = pcioctl, 194 1.60 dholland .d_stop = nostop, 195 1.60 dholland .d_tty = pctty, 196 1.60 dholland .d_poll = pcpoll, 197 1.60 dholland .d_mmap = pcmmap, 198 1.60 dholland .d_kqfilter = ttykqfilter, 199 1.61 dholland .d_discard = nodiscard, 200 1.60 dholland .d_flag = D_TTY 201 1.30 gehenna }; 202 1.30 gehenna 203 1.1 jonathan #define CHR 2 204 1.1 jonathan 205 1.39 tsutsui char *sget(void); 206 1.47 matt void sput(const u_char *, int); 207 1.1 jonathan 208 1.39 tsutsui void pcstart(struct tty *); 209 1.39 tsutsui int pcparam(struct tty *, struct termios *); 210 1.42 perry static inline void wcopy(void *, void *, u_int); 211 1.39 tsutsui void pc_context_init(bus_space_tag_t, bus_space_tag_t, bus_space_tag_t, 212 1.39 tsutsui struct pccons_config *); 213 1.13 soda 214 1.39 tsutsui extern void fillw(int, uint16_t *, int); 215 1.1 jonathan 216 1.1 jonathan #define KBD_DELAY \ 217 1.1 jonathan DELAY(10); 218 1.1 jonathan 219 1.27 soda #define crtc_read_1(reg) \ 220 1.27 soda bus_space_read_1(pccons_console_context.pc_crt_iot, \ 221 1.27 soda pccons_console_context.pc_6845_ioh, reg) 222 1.27 soda #define crtc_write_1(reg, data) \ 223 1.27 soda bus_space_write_1(pccons_console_context.pc_crt_iot, \ 224 1.27 soda pccons_console_context.pc_6845_ioh, reg, data) 225 1.27 soda 226 1.27 soda struct pccons_context pccons_console_context; 227 1.27 soda 228 1.27 soda void 229 1.39 tsutsui kbd_context_init(bus_space_tag_t kbd_iot, struct pccons_config *config) 230 1.27 soda { 231 1.27 soda struct pccons_kbd_context *pkc = &pccons_console_context.pc_pkc; 232 1.27 soda 233 1.27 soda if (pkc->pkc_initialized) 234 1.27 soda return; 235 1.27 soda pkc->pkc_initialized = 1; 236 1.27 soda 237 1.27 soda pkc->pkc_iot = kbd_iot; 238 1.27 soda 239 1.27 soda bus_space_map(kbd_iot, config->pc_kbd_cmdp, 1, 0, 240 1.27 soda &pkc->pkc_cmd_ioh); 241 1.27 soda bus_space_map(kbd_iot, config->pc_kbd_datap, 1, 0, 242 1.27 soda &pkc->pkc_data_ioh); 243 1.27 soda } 244 1.27 soda 245 1.20 soda void 246 1.39 tsutsui pc_context_init(bus_space_tag_t crt_iot, bus_space_tag_t crt_memt, 247 1.39 tsutsui bus_space_tag_t kbd_iot, struct pccons_config *config) 248 1.20 soda { 249 1.27 soda struct pccons_context *pc = &pccons_console_context; 250 1.20 soda 251 1.27 soda if (pc->pc_initialized) 252 1.20 soda return; 253 1.27 soda pc->pc_initialized = 1; 254 1.27 soda 255 1.27 soda kbd_context_init(kbd_iot, config); 256 1.27 soda 257 1.27 soda pc->pc_crt_iot = crt_iot; 258 1.27 soda pc->pc_crt_memt = crt_memt; 259 1.20 soda 260 1.27 soda bus_space_map(crt_iot, config->pc_mono_iobase, 2, 0, 261 1.27 soda &pc->pc_mono_ioh); 262 1.27 soda bus_space_map(crt_memt, config->pc_mono_memaddr, 0x20000, 0, 263 1.27 soda &pc->pc_mono_memh); 264 1.27 soda bus_space_map(crt_iot, config->pc_cga_iobase, 2, 0, 265 1.27 soda &pc->pc_cga_ioh); 266 1.27 soda bus_space_map(crt_memt, config->pc_cga_memaddr, 0x20000, 0, 267 1.27 soda &pc->pc_cga_memh); 268 1.20 soda 269 1.27 soda /* 270 1.27 soda * pc->pc_6845_ioh and pc->pc_crt_memh will be initialized later, 271 1.27 soda * when `Crtat' is initialized. 272 1.27 soda */ 273 1.27 soda 274 1.27 soda pc->pc_config = config; 275 1.27 soda 276 1.27 soda (*config->pc_init)(); 277 1.20 soda } 278 1.20 soda 279 1.13 soda /* 280 1.13 soda * bcopy variant that only moves word-aligned 16-bit entities, 281 1.56 tsutsui * for stupid VGA cards. cnt is required to be an even value. 282 1.13 soda */ 283 1.42 perry static inline void 284 1.39 tsutsui wcopy(void *src, void *tgt, u_int cnt) 285 1.13 soda { 286 1.39 tsutsui uint16_t *from = src; 287 1.39 tsutsui uint16_t *to = tgt; 288 1.13 soda 289 1.13 soda cnt >>= 1; 290 1.13 soda if (to < from || to >= from + cnt) 291 1.39 tsutsui while (cnt--) 292 1.13 soda *to++ = *from++; 293 1.13 soda else { 294 1.13 soda to += cnt; 295 1.13 soda from += cnt; 296 1.39 tsutsui while (cnt--) 297 1.13 soda *--to = *--from; 298 1.13 soda } 299 1.13 soda } 300 1.13 soda 301 1.42 perry static inline int 302 1.39 tsutsui kbd_wait_output(void) 303 1.1 jonathan { 304 1.1 jonathan u_int i; 305 1.1 jonathan 306 1.1 jonathan for (i = 100000; i; i--) 307 1.27 soda if ((kbd_cmd_read_1() & KBS_IBF) == 0) { 308 1.1 jonathan KBD_DELAY; 309 1.1 jonathan return 1; 310 1.1 jonathan } 311 1.1 jonathan return 0; 312 1.1 jonathan } 313 1.1 jonathan 314 1.42 perry static inline int 315 1.39 tsutsui kbd_wait_input(void) 316 1.1 jonathan { 317 1.1 jonathan u_int i; 318 1.1 jonathan 319 1.1 jonathan for (i = 100000; i; i--) 320 1.27 soda if ((kbd_cmd_read_1() & KBS_DIB) != 0) { 321 1.1 jonathan KBD_DELAY; 322 1.1 jonathan return 1; 323 1.1 jonathan } 324 1.1 jonathan return 0; 325 1.1 jonathan } 326 1.1 jonathan 327 1.27 soda void 328 1.39 tsutsui kbd_flush_input(void) 329 1.1 jonathan { 330 1.39 tsutsui uint8_t c; 331 1.1 jonathan 332 1.27 soda while ((c = kbd_cmd_read_1()) & 0x03) 333 1.1 jonathan if ((c & KBS_DIB) == KBS_DIB) { 334 1.1 jonathan /* XXX - delay is needed to prevent some keyboards from 335 1.1 jonathan wedging when the system boots */ 336 1.1 jonathan delay(6); 337 1.39 tsutsui (void)kbd_data_read_1(); 338 1.1 jonathan } 339 1.13 soda } 340 1.13 soda 341 1.1 jonathan #if 1 342 1.1 jonathan /* 343 1.1 jonathan * Get the current command byte. 344 1.1 jonathan */ 345 1.1 jonathan static u_char 346 1.39 tsutsui kbc_get8042cmd(void) 347 1.1 jonathan { 348 1.1 jonathan 349 1.1 jonathan if (!kbd_wait_output()) 350 1.1 jonathan return -1; 351 1.27 soda kbd_cmd_write_1(K_RDCMDBYTE); 352 1.1 jonathan if (!kbd_wait_input()) 353 1.1 jonathan return -1; 354 1.27 soda return kbd_data_read_1(); 355 1.1 jonathan } 356 1.1 jonathan #endif 357 1.1 jonathan 358 1.1 jonathan /* 359 1.1 jonathan * Pass command byte to keyboard controller (8042). 360 1.1 jonathan */ 361 1.27 soda int 362 1.57 dsl kbc_put8042cmd(uint8_t val) 363 1.1 jonathan { 364 1.1 jonathan 365 1.1 jonathan if (!kbd_wait_output()) 366 1.1 jonathan return 0; 367 1.27 soda kbd_cmd_write_1(K_LDCMDBYTE); 368 1.1 jonathan if (!kbd_wait_output()) 369 1.1 jonathan return 0; 370 1.27 soda kbd_data_write_1(val); 371 1.1 jonathan return 1; 372 1.1 jonathan } 373 1.1 jonathan 374 1.1 jonathan /* 375 1.1 jonathan * Pass command to keyboard itself 376 1.1 jonathan */ 377 1.1 jonathan int 378 1.47 matt kbd_cmd(uint8_t val, uint8_t polled) 379 1.1 jonathan { 380 1.1 jonathan u_int retries = 3; 381 1.35 tsutsui u_int i; 382 1.1 jonathan 383 1.47 matt if (!polled) { 384 1.1 jonathan i = spltty(); 385 1.39 tsutsui if (kb_oq_get == kb_oq_put) { 386 1.27 soda kbd_data_write_1(val); 387 1.1 jonathan } 388 1.1 jonathan kb_oq[kb_oq_put] = val; 389 1.1 jonathan kb_oq_put = (kb_oq_put + 1) & 7; 390 1.1 jonathan splx(i); 391 1.39 tsutsui return 1; 392 1.1 jonathan } 393 1.47 matt 394 1.47 matt do { 395 1.1 jonathan if (!kbd_wait_output()) 396 1.1 jonathan return 0; 397 1.27 soda kbd_data_write_1(val); 398 1.1 jonathan for (i = 100000; i; i--) { 399 1.27 soda if (kbd_cmd_read_1() & KBS_DIB) { 400 1.39 tsutsui uint8_t c; 401 1.1 jonathan 402 1.1 jonathan KBD_DELAY; 403 1.27 soda c = kbd_data_read_1(); 404 1.1 jonathan if (c == KBR_ACK || c == KBR_ECHO) { 405 1.1 jonathan return 1; 406 1.1 jonathan } 407 1.1 jonathan if (c == KBR_RESEND) { 408 1.1 jonathan break; 409 1.1 jonathan } 410 1.1 jonathan #ifdef DIAGNOSTIC 411 1.6 christos printf("kbd_cmd: input char %x lost\n", c); 412 1.1 jonathan #endif 413 1.1 jonathan } 414 1.1 jonathan } 415 1.1 jonathan } while (--retries); 416 1.1 jonathan return 0; 417 1.1 jonathan } 418 1.1 jonathan 419 1.1 jonathan void 420 1.39 tsutsui set_cursor_shape(void) 421 1.1 jonathan { 422 1.39 tsutsui 423 1.27 soda crtc_write_1(0, 10); 424 1.27 soda crtc_write_1(1, cursor_shape >> 8); 425 1.27 soda crtc_write_1(0, 11); 426 1.27 soda crtc_write_1(1, cursor_shape); 427 1.1 jonathan old_cursor_shape = cursor_shape; 428 1.1 jonathan } 429 1.1 jonathan 430 1.1 jonathan void 431 1.39 tsutsui get_cursor_shape(void) 432 1.1 jonathan { 433 1.39 tsutsui 434 1.27 soda crtc_write_1(0, 10); 435 1.27 soda cursor_shape = crtc_read_1(1) << 8; 436 1.27 soda crtc_write_1(0, 11); 437 1.27 soda cursor_shape |= crtc_read_1(1); 438 1.1 jonathan 439 1.1 jonathan /* 440 1.1 jonathan * real 6845's, as found on, MDA, Hercules or CGA cards, do 441 1.1 jonathan * not support reading the cursor shape registers. the 6845 442 1.62 snj * tri-states its data bus. This is _normally_ read by the 443 1.38 wiz * CPU as either 0x00 or 0xff.. in which case we just use 444 1.1 jonathan * a line cursor. 445 1.1 jonathan */ 446 1.1 jonathan if (cursor_shape == 0x0000 || cursor_shape == 0xffff) 447 1.1 jonathan cursor_shape = 0x0b10; 448 1.1 jonathan else 449 1.1 jonathan cursor_shape &= 0x1f1f; 450 1.1 jonathan } 451 1.1 jonathan 452 1.1 jonathan void 453 1.39 tsutsui do_async_update(uint8_t poll) 454 1.1 jonathan { 455 1.1 jonathan int pos; 456 1.1 jonathan static int old_pos = -1; 457 1.1 jonathan 458 1.1 jonathan async = 0; 459 1.1 jonathan 460 1.1 jonathan if (lock_state != old_lock_state) { 461 1.1 jonathan old_lock_state = lock_state; 462 1.1 jonathan if (!kbd_cmd(KBC_MODEIND, poll) || 463 1.1 jonathan !kbd_cmd(lock_state, poll)) { 464 1.6 christos printf("pc: timeout updating leds\n"); 465 1.1 jonathan (void) kbd_cmd(KBC_ENABLE, poll); 466 1.1 jonathan } 467 1.1 jonathan } 468 1.1 jonathan if (typematic_rate != old_typematic_rate) { 469 1.1 jonathan old_typematic_rate = typematic_rate; 470 1.1 jonathan if (!kbd_cmd(KBC_TYPEMATIC, poll) || 471 1.1 jonathan !kbd_cmd(typematic_rate, poll)) { 472 1.6 christos printf("pc: timeout updating typematic rate\n"); 473 1.1 jonathan (void) kbd_cmd(KBC_ENABLE, poll); 474 1.1 jonathan } 475 1.1 jonathan } 476 1.1 jonathan 477 1.1 jonathan if (pc_xmode > 0) 478 1.1 jonathan return; 479 1.1 jonathan 480 1.1 jonathan pos = crtat - Crtat; 481 1.1 jonathan if (pos != old_pos) { 482 1.27 soda crtc_write_1(0, 14); 483 1.27 soda crtc_write_1(1, pos >> 8); 484 1.27 soda crtc_write_1(0, 15); 485 1.27 soda crtc_write_1(1, pos); 486 1.1 jonathan old_pos = pos; 487 1.1 jonathan } 488 1.1 jonathan if (cursor_shape != old_cursor_shape) 489 1.1 jonathan set_cursor_shape(); 490 1.1 jonathan } 491 1.1 jonathan 492 1.1 jonathan void 493 1.39 tsutsui async_update(void) 494 1.1 jonathan { 495 1.1 jonathan 496 1.1 jonathan if (kernel || polling) { 497 1.1 jonathan if (async) 498 1.17 thorpej callout_stop(&async_update_ch); 499 1.1 jonathan do_async_update(1); 500 1.1 jonathan } else { 501 1.1 jonathan if (async) 502 1.1 jonathan return; 503 1.1 jonathan async = 1; 504 1.17 thorpej callout_reset(&async_update_ch, 1, 505 1.17 thorpej (void(*)(void *))do_async_update, NULL); 506 1.1 jonathan } 507 1.1 jonathan } 508 1.1 jonathan 509 1.1 jonathan /* 510 1.1 jonathan * these are both bad jokes 511 1.1 jonathan */ 512 1.1 jonathan int 513 1.39 tsutsui pccons_common_match(bus_space_tag_t crt_iot, bus_space_tag_t crt_memt, 514 1.39 tsutsui bus_space_tag_t kbd_iot, struct pccons_config *config) 515 1.1 jonathan { 516 1.27 soda int i; 517 1.1 jonathan 518 1.27 soda pc_context_init(crt_iot, crt_memt, kbd_iot, config); 519 1.20 soda 520 1.1 jonathan /* Enable interrupts and keyboard, etc. */ 521 1.1 jonathan if (!kbc_put8042cmd(CMDBYTE)) { 522 1.13 soda printf("pcprobe: command error\n"); 523 1.1 jonathan return 0; 524 1.1 jonathan } 525 1.1 jonathan 526 1.1 jonathan #if 1 527 1.1 jonathan /* Flush any garbage. */ 528 1.1 jonathan kbd_flush_input(); 529 1.1 jonathan /* Reset the keyboard. */ 530 1.1 jonathan if (!kbd_cmd(KBC_RESET, 1)) { 531 1.13 soda printf("pcprobe: reset error %d\n", 1); 532 1.1 jonathan goto lose; 533 1.1 jonathan } 534 1.1 jonathan for (i = 600000; i; i--) 535 1.27 soda if ((kbd_cmd_read_1() & KBS_DIB) != 0) { 536 1.1 jonathan KBD_DELAY; 537 1.1 jonathan break; 538 1.1 jonathan } 539 1.27 soda if (i == 0 || kbd_data_read_1() != KBR_RSTDONE) { 540 1.13 soda printf("pcprobe: reset error %d\n", 2); 541 1.1 jonathan goto lose; 542 1.1 jonathan } 543 1.1 jonathan /* 544 1.1 jonathan * Some keyboards seem to leave a second ack byte after the reset. 545 1.1 jonathan * This is kind of stupid, but we account for them anyway by just 546 1.1 jonathan * flushing the buffer. 547 1.1 jonathan */ 548 1.1 jonathan kbd_flush_input(); 549 1.1 jonathan /* Just to be sure. */ 550 1.1 jonathan if (!kbd_cmd(KBC_ENABLE, 1)) { 551 1.13 soda printf("pcprobe: reset error %d\n", 3); 552 1.1 jonathan goto lose; 553 1.1 jonathan } 554 1.1 jonathan 555 1.1 jonathan /* 556 1.1 jonathan * Some keyboard/8042 combinations do not seem to work if the keyboard 557 1.1 jonathan * is set to table 1; in fact, it would appear that some keyboards just 558 1.1 jonathan * ignore the command altogether. So by default, we use the AT scan 559 1.1 jonathan * codes and have the 8042 translate them. Unfortunately, this is 560 1.63 andvar * known to not work on some PS/2 machines. We try desperately to deal 561 1.1 jonathan * with this by checking the (lack of a) translate bit in the 8042 and 562 1.1 jonathan * attempting to set the keyboard to XT mode. If this all fails, well, 563 1.1 jonathan * tough luck. 564 1.1 jonathan * 565 1.1 jonathan * XXX It would perhaps be a better choice to just use AT scan codes 566 1.1 jonathan * and not bother with this. 567 1.1 jonathan */ 568 1.1 jonathan if (kbc_get8042cmd() & KC8_TRANS) { 569 1.1 jonathan /* The 8042 is translating for us; use AT codes. */ 570 1.1 jonathan if (!kbd_cmd(KBC_SETTABLE, 1) || !kbd_cmd(2, 1)) { 571 1.13 soda printf("pcprobe: reset error %d\n", 4); 572 1.1 jonathan goto lose; 573 1.1 jonathan } 574 1.1 jonathan } else { 575 1.1 jonathan /* Stupid 8042; set keyboard to XT codes. */ 576 1.1 jonathan if (!kbd_cmd(KBC_SETTABLE, 1) || !kbd_cmd(1, 1)) { 577 1.13 soda printf("pcprobe: reset error %d\n", 5); 578 1.1 jonathan goto lose; 579 1.1 jonathan } 580 1.1 jonathan } 581 1.1 jonathan 582 1.1 jonathan lose: 583 1.1 jonathan /* 584 1.13 soda * Technically, we should probably fail the probe. But we'll be nice 585 1.1 jonathan * and allow keyboard-less machines to boot with the console. 586 1.1 jonathan */ 587 1.1 jonathan #endif 588 1.1 jonathan 589 1.1 jonathan return 1; 590 1.1 jonathan } 591 1.1 jonathan 592 1.39 tsutsui void pccons_common_attach(struct pc_softc *sc, bus_space_tag_t crt_iot, 593 1.39 tsutsui bus_space_tag_t crt_memt, bus_space_tag_t kbd_iot, 594 1.39 tsutsui struct pccons_config *config) 595 1.27 soda { 596 1.39 tsutsui 597 1.6 christos printf(": %s\n", vs.color ? "color" : "mono"); 598 1.50 ad callout_init(&async_update_ch, 0); 599 1.1 jonathan do_async_update(1); 600 1.1 jonathan } 601 1.1 jonathan 602 1.1 jonathan int 603 1.41 christos pcopen(dev_t dev, int flag, int mode, struct lwp *l) 604 1.1 jonathan { 605 1.1 jonathan struct pc_softc *sc; 606 1.1 jonathan struct tty *tp; 607 1.1 jonathan 608 1.54 cegger sc = device_lookup_private(&pc_cd, PCUNIT(dev)); 609 1.54 cegger if (sc == NULL) 610 1.1 jonathan return ENXIO; 611 1.1 jonathan 612 1.1 jonathan if (!sc->sc_tty) { 613 1.58 rmind tp = sc->sc_tty = tty_alloc(); 614 1.1 jonathan } 615 1.1 jonathan else { 616 1.1 jonathan tp = sc->sc_tty; 617 1.1 jonathan } 618 1.1 jonathan 619 1.1 jonathan tp->t_oproc = pcstart; 620 1.1 jonathan tp->t_param = pcparam; 621 1.1 jonathan tp->t_dev = dev; 622 1.48 elad 623 1.48 elad if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 624 1.48 elad return (EBUSY); 625 1.48 elad 626 1.1 jonathan if ((tp->t_state & TS_ISOPEN) == 0) { 627 1.1 jonathan ttychars(tp); 628 1.1 jonathan tp->t_iflag = TTYDEF_IFLAG; 629 1.1 jonathan tp->t_oflag = TTYDEF_OFLAG; 630 1.1 jonathan tp->t_cflag = TTYDEF_CFLAG; 631 1.1 jonathan tp->t_lflag = TTYDEF_LFLAG; 632 1.1 jonathan tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 633 1.1 jonathan pcparam(tp, &tp->t_termios); 634 1.1 jonathan ttsetwater(tp); 635 1.48 elad } 636 1.48 elad 637 1.1 jonathan tp->t_state |= TS_CARR_ON; 638 1.1 jonathan 639 1.39 tsutsui return (*tp->t_linesw->l_open)(dev, tp); 640 1.1 jonathan } 641 1.1 jonathan 642 1.1 jonathan int 643 1.41 christos pcclose(dev_t dev, int flag, int mode, struct lwp *l) 644 1.1 jonathan { 645 1.54 cegger struct pc_softc *sc = device_lookup_private(&pc_cd, PCUNIT(dev)); 646 1.1 jonathan struct tty *tp = sc->sc_tty; 647 1.1 jonathan 648 1.22 eeh (*tp->t_linesw->l_close)(tp, flag); 649 1.1 jonathan ttyclose(tp); 650 1.1 jonathan #ifdef notyet /* XXX */ 651 1.58 rmind tty_free(tp); 652 1.1 jonathan #endif 653 1.39 tsutsui return 0; 654 1.1 jonathan } 655 1.1 jonathan 656 1.1 jonathan int 657 1.39 tsutsui pcread(dev_t dev, struct uio *uio, int flag) 658 1.1 jonathan { 659 1.54 cegger struct pc_softc *sc = device_lookup_private(&pc_cd, PCUNIT(dev)); 660 1.1 jonathan struct tty *tp = sc->sc_tty; 661 1.1 jonathan 662 1.39 tsutsui return (*tp->t_linesw->l_read)(tp, uio, flag); 663 1.1 jonathan } 664 1.1 jonathan 665 1.1 jonathan int 666 1.39 tsutsui pcwrite(dev_t dev, struct uio *uio, int flag) 667 1.1 jonathan { 668 1.54 cegger struct pc_softc *sc = device_lookup_private(&pc_cd, PCUNIT(dev)); 669 1.1 jonathan struct tty *tp = sc->sc_tty; 670 1.1 jonathan 671 1.39 tsutsui return (*tp->t_linesw->l_write)(tp, uio, flag); 672 1.25 scw } 673 1.25 scw 674 1.25 scw int 675 1.41 christos pcpoll(dev_t dev, int events, struct lwp *l) 676 1.25 scw { 677 1.54 cegger struct pc_softc *sc = device_lookup_private(&pc_cd, PCUNIT(dev)); 678 1.25 scw struct tty *tp = sc->sc_tty; 679 1.32 tsutsui 680 1.41 christos return (*tp->t_linesw->l_poll)(tp, events, l); 681 1.1 jonathan } 682 1.1 jonathan 683 1.1 jonathan struct tty * 684 1.39 tsutsui pctty(dev_t dev) 685 1.1 jonathan { 686 1.54 cegger struct pc_softc *sc = device_lookup_private(&pc_cd, PCUNIT(dev)); 687 1.1 jonathan struct tty *tp = sc->sc_tty; 688 1.1 jonathan 689 1.39 tsutsui return tp; 690 1.1 jonathan } 691 1.1 jonathan 692 1.1 jonathan /* 693 1.1 jonathan * Got a console receive interrupt - 694 1.1 jonathan * the console processor wants to give us a character. 695 1.1 jonathan * Catch the character, and see who it goes to. 696 1.1 jonathan */ 697 1.1 jonathan int 698 1.39 tsutsui pcintr(void *arg) 699 1.1 jonathan { 700 1.1 jonathan struct pc_softc *sc = arg; 701 1.35 tsutsui struct tty *tp = sc->sc_tty; 702 1.39 tsutsui uint8_t *cp; 703 1.1 jonathan 704 1.27 soda if ((kbd_cmd_read_1() & KBS_DIB) == 0) 705 1.1 jonathan return 0; 706 1.1 jonathan if (polling) 707 1.1 jonathan return 1; 708 1.1 jonathan do { 709 1.1 jonathan cp = sget(); 710 1.1 jonathan if (!tp || (tp->t_state & TS_ISOPEN) == 0) 711 1.1 jonathan return 1; 712 1.1 jonathan if (cp) 713 1.1 jonathan do 714 1.22 eeh (*tp->t_linesw->l_rint)(*cp++, tp); 715 1.1 jonathan while (*cp); 716 1.27 soda } while (kbd_cmd_read_1() & KBS_DIB); 717 1.1 jonathan return 1; 718 1.1 jonathan } 719 1.1 jonathan 720 1.1 jonathan int 721 1.49 christos pcioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 722 1.1 jonathan { 723 1.54 cegger struct pc_softc *sc = device_lookup_private(&pc_cd, PCUNIT(dev)); 724 1.1 jonathan struct tty *tp = sc->sc_tty; 725 1.1 jonathan int error; 726 1.1 jonathan 727 1.41 christos error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); 728 1.29 atatat if (error != EPASSTHROUGH) 729 1.1 jonathan return error; 730 1.41 christos error = ttioctl(tp, cmd, data, flag, l); 731 1.29 atatat if (error != EPASSTHROUGH) 732 1.1 jonathan return error; 733 1.1 jonathan 734 1.1 jonathan switch (cmd) { 735 1.1 jonathan case CONSOLE_X_MODE_ON: 736 1.1 jonathan pc_xmode_on(); 737 1.1 jonathan return 0; 738 1.1 jonathan case CONSOLE_X_MODE_OFF: 739 1.1 jonathan pc_xmode_off(); 740 1.1 jonathan return 0; 741 1.1 jonathan case CONSOLE_X_BELL: 742 1.1 jonathan /* 743 1.1 jonathan * If set, data is a pointer to a length 2 array of 744 1.1 jonathan * integers. data[0] is the pitch in Hz and data[1] 745 1.1 jonathan * is the duration in msec. 746 1.1 jonathan */ 747 1.1 jonathan if (data) 748 1.1 jonathan sysbeep(((int*)data)[0], 749 1.1 jonathan (((int*)data)[1] * hz) / 1000); 750 1.1 jonathan else 751 1.1 jonathan sysbeep(BEEP_FREQ, BEEP_TIME); 752 1.1 jonathan return 0; 753 1.1 jonathan case CONSOLE_SET_TYPEMATIC_RATE: { 754 1.1 jonathan u_char rate; 755 1.1 jonathan 756 1.1 jonathan if (!data) 757 1.1 jonathan return EINVAL; 758 1.1 jonathan rate = *((u_char *)data); 759 1.1 jonathan /* 760 1.1 jonathan * Check that it isn't too big (which would cause it to be 761 1.1 jonathan * confused with a command). 762 1.1 jonathan */ 763 1.1 jonathan if (rate & 0x80) 764 1.1 jonathan return EINVAL; 765 1.1 jonathan typematic_rate = rate; 766 1.1 jonathan async_update(); 767 1.1 jonathan return 0; 768 1.1 jonathan } 769 1.13 soda case CONSOLE_SET_KEYMAP: { 770 1.13 soda pccons_keymap_t *map = (pccons_keymap_t *) data; 771 1.13 soda int i; 772 1.13 soda 773 1.13 soda if (!data) 774 1.13 soda return EINVAL; 775 1.13 soda for (i = 0; i < KB_NUM_KEYS; i++) 776 1.13 soda if (map[i].unshift[KB_CODE_SIZE-1] || 777 1.13 soda map[i].shift[KB_CODE_SIZE-1] || 778 1.13 soda map[i].ctl[KB_CODE_SIZE-1] || 779 1.13 soda map[i].altgr[KB_CODE_SIZE-1] || 780 1.13 soda map[i].shift_altgr[KB_CODE_SIZE-1]) 781 1.13 soda return EINVAL; 782 1.13 soda 783 1.56 tsutsui memcpy(scan_codes, data, sizeof(pccons_keymap_t[KB_NUM_KEYS])); 784 1.13 soda return 0; 785 1.13 soda } 786 1.13 soda case CONSOLE_GET_KEYMAP: 787 1.13 soda if (!data) 788 1.13 soda return EINVAL; 789 1.56 tsutsui memcpy(scan_codes, data, sizeof(pccons_keymap_t[KB_NUM_KEYS])); 790 1.13 soda return 0; 791 1.13 soda 792 1.1 jonathan default: 793 1.29 atatat return EPASSTHROUGH; 794 1.1 jonathan } 795 1.1 jonathan 796 1.1 jonathan #ifdef DIAGNOSTIC 797 1.1 jonathan panic("pcioctl: impossible"); 798 1.1 jonathan #endif 799 1.1 jonathan } 800 1.1 jonathan 801 1.1 jonathan void 802 1.39 tsutsui pcstart(struct tty *tp) 803 1.1 jonathan { 804 1.55 tsutsui struct clist *cl; 805 1.13 soda int s, len; 806 1.1 jonathan u_char buf[PCBURST]; 807 1.1 jonathan 808 1.1 jonathan s = spltty(); 809 1.1 jonathan if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) 810 1.1 jonathan goto out; 811 1.1 jonathan tp->t_state |= TS_BUSY; 812 1.1 jonathan splx(s); 813 1.1 jonathan /* 814 1.1 jonathan * We need to do this outside spl since it could be fairly 815 1.1 jonathan * expensive and we don't want our serial ports to overflow. 816 1.1 jonathan */ 817 1.55 tsutsui cl = &tp->t_outq; 818 1.1 jonathan len = q_to_b(cl, buf, PCBURST); 819 1.1 jonathan sput(buf, len); 820 1.1 jonathan s = spltty(); 821 1.1 jonathan tp->t_state &= ~TS_BUSY; 822 1.53 ad if (ttypull(tp)) { 823 1.1 jonathan tp->t_state |= TS_TIMEOUT; 824 1.52 joerg callout_schedule(&tp->t_rstrt_ch, 1); 825 1.1 jonathan } 826 1.1 jonathan out: 827 1.1 jonathan splx(s); 828 1.1 jonathan } 829 1.1 jonathan 830 1.13 soda /* ARGSUSED */ 831 1.39 tsutsui void pccons_common_cnattach(bus_space_tag_t crt_iot, bus_space_tag_t crt_memt, 832 1.39 tsutsui bus_space_tag_t kbd_iot, struct pccons_config *config) 833 1.1 jonathan { 834 1.1 jonathan int maj; 835 1.13 soda static struct consdev pccons = { 836 1.34 tsutsui NULL, NULL, pccngetc, pccnputc, pccnpollc, NULL, NULL, 837 1.34 tsutsui NULL, NODEV, CN_NORMAL 838 1.13 soda }; 839 1.13 soda 840 1.13 soda /* 841 1.13 soda * For now, don't screw with it. 842 1.13 soda */ 843 1.13 soda /* crtat = 0; */ 844 1.14 soda 845 1.27 soda pc_context_init(crt_iot, crt_memt, kbd_iot, config); 846 1.1 jonathan 847 1.1 jonathan /* locate the major number */ 848 1.30 gehenna maj = cdevsw_lookup_major(&pc_cdevsw); 849 1.13 soda pccons.cn_dev = makedev(maj, 0); 850 1.1 jonathan 851 1.13 soda cn_tab = &pccons; 852 1.1 jonathan } 853 1.1 jonathan 854 1.1 jonathan /* ARGSUSED */ 855 1.1 jonathan void 856 1.39 tsutsui pccnputc(dev_t dev, int c) 857 1.1 jonathan { 858 1.15 soda u_char cc, oldkernel = kernel; 859 1.1 jonathan 860 1.1 jonathan kernel = 1; 861 1.15 soda if (c == '\n') { 862 1.1 jonathan sput("\r\n", 2); 863 1.15 soda } else { 864 1.15 soda cc = c; 865 1.15 soda sput(&cc, 1); 866 1.15 soda } 867 1.1 jonathan kernel = oldkernel; 868 1.1 jonathan } 869 1.1 jonathan 870 1.1 jonathan /* ARGSUSED */ 871 1.13 soda int 872 1.39 tsutsui pccngetc(dev_t dev) 873 1.1 jonathan { 874 1.35 tsutsui char *cp; 875 1.1 jonathan 876 1.1 jonathan if (pc_xmode > 0) 877 1.1 jonathan return 0; 878 1.1 jonathan 879 1.1 jonathan do { 880 1.1 jonathan /* wait for byte */ 881 1.27 soda while ((kbd_cmd_read_1() & KBS_DIB) == 0); 882 1.1 jonathan /* see if it's worthwhile */ 883 1.1 jonathan cp = sget(); 884 1.1 jonathan } while (!cp); 885 1.1 jonathan if (*cp == '\r') 886 1.1 jonathan return '\n'; 887 1.1 jonathan return *cp; 888 1.1 jonathan } 889 1.1 jonathan 890 1.1 jonathan void 891 1.39 tsutsui pccnpollc(dev_t dev, int on) 892 1.1 jonathan { 893 1.1 jonathan 894 1.1 jonathan polling = on; 895 1.1 jonathan if (!on) { 896 1.1 jonathan int unit; 897 1.1 jonathan struct pc_softc *sc; 898 1.1 jonathan int s; 899 1.1 jonathan 900 1.1 jonathan /* 901 1.1 jonathan * If disabling polling on a device that's been configured, 902 1.1 jonathan * make sure there are no bytes left in the FIFO, holding up 903 1.1 jonathan * the interrupt line. Otherwise we won't get any further 904 1.1 jonathan * interrupts. 905 1.1 jonathan */ 906 1.1 jonathan unit = PCUNIT(dev); 907 1.2 thorpej if (pc_cd.cd_ndevs > unit) { 908 1.54 cegger sc = device_lookup_private(&pc_cd, unit); 909 1.54 cegger if (sc != NULL) { 910 1.1 jonathan s = spltty(); 911 1.1 jonathan pcintr(sc); 912 1.1 jonathan splx(s); 913 1.1 jonathan } 914 1.1 jonathan } 915 1.1 jonathan } 916 1.32 tsutsui } 917 1.1 jonathan 918 1.1 jonathan /* 919 1.1 jonathan * Set line parameters. 920 1.1 jonathan */ 921 1.1 jonathan int 922 1.39 tsutsui pcparam(struct tty *tp, struct termios *t) 923 1.1 jonathan { 924 1.1 jonathan 925 1.1 jonathan tp->t_ispeed = t->c_ispeed; 926 1.1 jonathan tp->t_ospeed = t->c_ospeed; 927 1.1 jonathan tp->t_cflag = t->c_cflag; 928 1.1 jonathan return 0; 929 1.1 jonathan } 930 1.1 jonathan 931 1.1 jonathan #define wrtchar(c, at) do {\ 932 1.47 matt char *cp0 = (char *)crtat; *cp0++ = (c); *cp0 = (at); crtat++; vs.col++; \ 933 1.1 jonathan } while (0) 934 1.1 jonathan 935 1.1 jonathan /* translate ANSI color codes to standard pc ones */ 936 1.1 jonathan static char fgansitopc[] = { 937 1.1 jonathan FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE, 938 1.1 jonathan FG_MAGENTA, FG_CYAN, FG_LIGHTGREY 939 1.1 jonathan }; 940 1.1 jonathan 941 1.1 jonathan static char bgansitopc[] = { 942 1.1 jonathan BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE, 943 1.1 jonathan BG_MAGENTA, BG_CYAN, BG_LIGHTGREY 944 1.1 jonathan }; 945 1.1 jonathan 946 1.1 jonathan static u_char iso2ibm437[] = 947 1.32 tsutsui { 948 1.1 jonathan 0, 0, 0, 0, 0, 0, 0, 0, 949 1.1 jonathan 0, 0, 0, 0, 0, 0, 0, 0, 950 1.1 jonathan 0, 0, 0, 0, 0, 0, 0, 0, 951 1.1 jonathan 0, 0, 0, 0, 0, 0, 0, 0, 952 1.1 jonathan 0xff, 0xad, 0x9b, 0x9c, 0, 0x9d, 0, 0x40, 953 1.1 jonathan 0x6f, 0x63, 0x61, 0xae, 0, 0, 0, 0, 954 1.1 jonathan 0xf8, 0xf1, 0xfd, 0x33, 0, 0xe6, 0, 0xfa, 955 1.1 jonathan 0, 0x31, 0x6f, 0xaf, 0xac, 0xab, 0, 0xa8, 956 1.1 jonathan 0x41, 0x41, 0x41, 0x41, 0x8e, 0x8f, 0x92, 0x80, 957 1.1 jonathan 0x45, 0x90, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 958 1.1 jonathan 0x81, 0xa5, 0x4f, 0x4f, 0x4f, 0x4f, 0x99, 0x4f, 959 1.1 jonathan 0x4f, 0x55, 0x55, 0x55, 0x9a, 0x59, 0, 0xe1, 960 1.1 jonathan 0x85, 0xa0, 0x83, 0x61, 0x84, 0x86, 0x91, 0x87, 961 1.1 jonathan 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, 962 1.1 jonathan 0, 0xa4, 0x95, 0xa2, 0x93, 0x6f, 0x94, 0x6f, 963 1.1 jonathan 0x6f, 0x97, 0xa3, 0x96, 0x81, 0x98, 0, 0 964 1.1 jonathan }; 965 1.1 jonathan 966 1.1 jonathan /* 967 1.1 jonathan * `pc3' termcap emulation. 968 1.1 jonathan */ 969 1.1 jonathan void 970 1.47 matt sput(const u_char *cp, int n) 971 1.1 jonathan { 972 1.27 soda struct pccons_context *pc = &pccons_console_context; 973 1.1 jonathan u_char c, scroll = 0; 974 1.1 jonathan 975 1.1 jonathan if (pc_xmode > 0) 976 1.1 jonathan return; 977 1.1 jonathan 978 1.1 jonathan if (crtat == 0) { 979 1.47 matt volatile u_short *dp; 980 1.1 jonathan u_short was; 981 1.1 jonathan unsigned cursorat; 982 1.1 jonathan 983 1.47 matt dp = bus_space_vaddr(pc->pc_crt_memt, pc->pc_cga_memh); 984 1.47 matt was = *dp; 985 1.47 matt *dp = 0xA55A; 986 1.47 matt if (*dp != 0xA55A) { 987 1.47 matt dp = bus_space_vaddr(pc->pc_crt_memt, 988 1.27 soda pc->pc_mono_memh); 989 1.27 soda pc->pc_6845_ioh = pc->pc_mono_ioh; 990 1.27 soda pc->pc_crt_memh = pc->pc_mono_memh; 991 1.1 jonathan vs.color = 0; 992 1.1 jonathan } else { 993 1.47 matt *dp = was; 994 1.27 soda pc->pc_6845_ioh = pc->pc_cga_ioh; 995 1.27 soda pc->pc_crt_memh = pc->pc_cga_memh; 996 1.1 jonathan vs.color = 1; 997 1.1 jonathan } 998 1.1 jonathan 999 1.1 jonathan #ifdef FAT_CURSOR 1000 1.1 jonathan cursor_shape = 0x0012; 1001 1.1 jonathan #else 1002 1.1 jonathan get_cursor_shape(); 1003 1.1 jonathan #endif 1004 1.1 jonathan 1005 1.13 soda bios_display_info(&vs.col, &vs.row, &vs.ncol, &vs.nrow); 1006 1.13 soda vs.nchr = vs.ncol * vs.nrow; 1007 1.13 soda vs.col--; 1008 1.13 soda vs.row--; 1009 1.13 soda cursorat = vs.ncol * vs.row + vs.col; 1010 1.13 soda vs.at = FG_LIGHTGREY | BG_BLACK; 1011 1.13 soda 1012 1.47 matt Crtat = (u_short *)__UNVOLATILE(dp); 1013 1.13 soda crtat = Crtat + cursorat; 1014 1.1 jonathan 1015 1.1 jonathan if (vs.color == 0) 1016 1.1 jonathan vs.so_at = FG_BLACK | BG_LIGHTGREY; 1017 1.1 jonathan else 1018 1.1 jonathan vs.so_at = FG_YELLOW | BG_BLACK; 1019 1.1 jonathan 1020 1.1 jonathan fillw((vs.at << 8) | ' ', crtat, vs.nchr - cursorat); 1021 1.1 jonathan } 1022 1.1 jonathan 1023 1.1 jonathan while (n--) { 1024 1.1 jonathan if (!(c = *cp++)) 1025 1.1 jonathan continue; 1026 1.1 jonathan 1027 1.1 jonathan switch (c) { 1028 1.1 jonathan case 0x1B: 1029 1.1 jonathan if (vs.state >= VSS_ESCAPE) { 1030 1.32 tsutsui wrtchar(c, vs.so_at); 1031 1.1 jonathan vs.state = 0; 1032 1.1 jonathan goto maybe_scroll; 1033 1.1 jonathan } else 1034 1.1 jonathan vs.state = VSS_ESCAPE; 1035 1.1 jonathan break; 1036 1.1 jonathan 1037 1.13 soda case 0x9B: /* CSI */ 1038 1.13 soda vs.cx = vs.cy = 0; 1039 1.13 soda vs.state = VSS_EBRACE; 1040 1.13 soda break; 1041 1.13 soda 1042 1.1 jonathan case '\t': { 1043 1.1 jonathan int inccol = 8 - (vs.col & 7); 1044 1.1 jonathan crtat += inccol; 1045 1.1 jonathan vs.col += inccol; 1046 1.1 jonathan } 1047 1.1 jonathan maybe_scroll: 1048 1.13 soda if (vs.col >= vs.ncol) { 1049 1.13 soda vs.col -= vs.ncol; 1050 1.1 jonathan scroll = 1; 1051 1.1 jonathan } 1052 1.1 jonathan break; 1053 1.1 jonathan 1054 1.13 soda case '\b': 1055 1.1 jonathan if (crtat <= Crtat) 1056 1.1 jonathan break; 1057 1.1 jonathan --crtat; 1058 1.1 jonathan if (--vs.col < 0) 1059 1.13 soda vs.col += vs.ncol; /* non-destructive backspace */ 1060 1.1 jonathan break; 1061 1.1 jonathan 1062 1.1 jonathan case '\r': 1063 1.1 jonathan crtat -= vs.col; 1064 1.1 jonathan vs.col = 0; 1065 1.1 jonathan break; 1066 1.1 jonathan 1067 1.1 jonathan case '\n': 1068 1.1 jonathan crtat += vs.ncol; 1069 1.1 jonathan scroll = 1; 1070 1.1 jonathan break; 1071 1.1 jonathan 1072 1.1 jonathan default: 1073 1.1 jonathan switch (vs.state) { 1074 1.1 jonathan case 0: 1075 1.1 jonathan if (c == '\a') 1076 1.1 jonathan sysbeep(BEEP_FREQ, BEEP_TIME); 1077 1.1 jonathan else { 1078 1.1 jonathan /* 1079 1.1 jonathan * If we're outputting multiple printed 1080 1.1 jonathan * characters, just blast them to the 1081 1.1 jonathan * screen until we reach the end of the 1082 1.1 jonathan * buffer or a control character. This 1083 1.1 jonathan * saves time by short-circuiting the 1084 1.1 jonathan * switch. 1085 1.1 jonathan * If we reach the end of the line, we 1086 1.1 jonathan * break to do a scroll check. 1087 1.1 jonathan */ 1088 1.1 jonathan for (;;) { 1089 1.1 jonathan if (c & 0x80) 1090 1.1 jonathan c = iso2ibm437[c&0x7f]; 1091 1.1 jonathan 1092 1.1 jonathan if (vs.so) 1093 1.1 jonathan wrtchar(c, vs.so_at); 1094 1.1 jonathan else 1095 1.1 jonathan wrtchar(c, vs.at); 1096 1.1 jonathan if (vs.col >= vs.ncol) { 1097 1.1 jonathan vs.col = 0; 1098 1.1 jonathan scroll = 1; 1099 1.1 jonathan break; 1100 1.1 jonathan } 1101 1.1 jonathan if (!n || (c = *cp) < ' ') 1102 1.1 jonathan break; 1103 1.1 jonathan n--, cp++; 1104 1.1 jonathan } 1105 1.1 jonathan } 1106 1.1 jonathan break; 1107 1.1 jonathan case VSS_ESCAPE: 1108 1.13 soda switch (c) { 1109 1.13 soda case '[': /* Start ESC [ sequence */ 1110 1.13 soda vs.cx = vs.cy = 0; 1111 1.13 soda vs.state = VSS_EBRACE; 1112 1.13 soda break; 1113 1.13 soda case 'c': /* Create screen & home */ 1114 1.13 soda fillw((vs.at << 8) | ' ', 1115 1.13 soda Crtat, vs.nchr); 1116 1.13 soda crtat = Crtat; 1117 1.13 soda vs.col = 0; 1118 1.13 soda vs.state = 0; 1119 1.13 soda break; 1120 1.13 soda case '7': /* save cursor pos */ 1121 1.13 soda vs.offset = crtat - Crtat; 1122 1.13 soda vs.state = 0; 1123 1.13 soda break; 1124 1.13 soda case '8': /* restore cursor pos */ 1125 1.13 soda crtat = Crtat + vs.offset; 1126 1.13 soda vs.row = vs.offset / vs.ncol; 1127 1.13 soda vs.col = vs.offset % vs.ncol; 1128 1.13 soda vs.state = 0; 1129 1.13 soda break; 1130 1.13 soda default: /* Invalid, clear state */ 1131 1.32 tsutsui wrtchar(c, vs.so_at); 1132 1.13 soda vs.state = 0; 1133 1.13 soda goto maybe_scroll; 1134 1.1 jonathan } 1135 1.1 jonathan break; 1136 1.13 soda 1137 1.1 jonathan default: /* VSS_EBRACE or VSS_EPARAM */ 1138 1.1 jonathan switch (c) { 1139 1.1 jonathan int pos; 1140 1.1 jonathan case 'm': 1141 1.1 jonathan if (!vs.cx) 1142 1.1 jonathan vs.so = 0; 1143 1.1 jonathan else 1144 1.1 jonathan vs.so = 1; 1145 1.1 jonathan vs.state = 0; 1146 1.1 jonathan break; 1147 1.1 jonathan case 'A': { /* back cx rows */ 1148 1.1 jonathan int cx = vs.cx; 1149 1.1 jonathan if (cx <= 0) 1150 1.1 jonathan cx = 1; 1151 1.1 jonathan else 1152 1.1 jonathan cx %= vs.nrow; 1153 1.1 jonathan pos = crtat - Crtat; 1154 1.1 jonathan pos -= vs.ncol * cx; 1155 1.1 jonathan if (pos < 0) 1156 1.1 jonathan pos += vs.nchr; 1157 1.1 jonathan crtat = Crtat + pos; 1158 1.1 jonathan vs.state = 0; 1159 1.1 jonathan break; 1160 1.1 jonathan } 1161 1.1 jonathan case 'B': { /* down cx rows */ 1162 1.1 jonathan int cx = vs.cx; 1163 1.1 jonathan if (cx <= 0) 1164 1.1 jonathan cx = 1; 1165 1.1 jonathan else 1166 1.1 jonathan cx %= vs.nrow; 1167 1.1 jonathan pos = crtat - Crtat; 1168 1.1 jonathan pos += vs.ncol * cx; 1169 1.32 tsutsui if (pos >= vs.nchr) 1170 1.1 jonathan pos -= vs.nchr; 1171 1.1 jonathan crtat = Crtat + pos; 1172 1.1 jonathan vs.state = 0; 1173 1.1 jonathan break; 1174 1.1 jonathan } 1175 1.1 jonathan case 'C': { /* right cursor */ 1176 1.1 jonathan int cx = vs.cx, 1177 1.1 jonathan col = vs.col; 1178 1.1 jonathan if (cx <= 0) 1179 1.1 jonathan cx = 1; 1180 1.1 jonathan else 1181 1.1 jonathan cx %= vs.ncol; 1182 1.1 jonathan pos = crtat - Crtat; 1183 1.1 jonathan pos += cx; 1184 1.1 jonathan col += cx; 1185 1.1 jonathan if (col >= vs.ncol) { 1186 1.1 jonathan pos -= vs.ncol; 1187 1.1 jonathan col -= vs.ncol; 1188 1.1 jonathan } 1189 1.1 jonathan vs.col = col; 1190 1.1 jonathan crtat = Crtat + pos; 1191 1.1 jonathan vs.state = 0; 1192 1.1 jonathan break; 1193 1.1 jonathan } 1194 1.1 jonathan case 'D': { /* left cursor */ 1195 1.1 jonathan int cx = vs.cx, 1196 1.1 jonathan col = vs.col; 1197 1.1 jonathan if (cx <= 0) 1198 1.1 jonathan cx = 1; 1199 1.1 jonathan else 1200 1.1 jonathan cx %= vs.ncol; 1201 1.1 jonathan pos = crtat - Crtat; 1202 1.1 jonathan pos -= cx; 1203 1.1 jonathan col -= cx; 1204 1.1 jonathan if (col < 0) { 1205 1.1 jonathan pos += vs.ncol; 1206 1.1 jonathan col += vs.ncol; 1207 1.1 jonathan } 1208 1.1 jonathan vs.col = col; 1209 1.1 jonathan crtat = Crtat + pos; 1210 1.1 jonathan vs.state = 0; 1211 1.1 jonathan break; 1212 1.1 jonathan } 1213 1.1 jonathan case 'J': /* Clear ... */ 1214 1.1 jonathan switch (vs.cx) { 1215 1.1 jonathan case 0: 1216 1.1 jonathan /* ... to end of display */ 1217 1.13 soda fillw((vs.at << 8) | ' ', 1218 1.13 soda crtat, 1219 1.1 jonathan Crtat + vs.nchr - crtat); 1220 1.1 jonathan break; 1221 1.1 jonathan case 1: 1222 1.1 jonathan /* ... to next location */ 1223 1.13 soda fillw((vs.at << 8) | ' ', 1224 1.13 soda Crtat, 1225 1.1 jonathan crtat - Crtat + 1); 1226 1.1 jonathan break; 1227 1.1 jonathan case 2: 1228 1.1 jonathan /* ... whole display */ 1229 1.13 soda fillw((vs.at << 8) | ' ', 1230 1.13 soda Crtat, 1231 1.1 jonathan vs.nchr); 1232 1.1 jonathan break; 1233 1.1 jonathan } 1234 1.1 jonathan vs.state = 0; 1235 1.1 jonathan break; 1236 1.1 jonathan case 'K': /* Clear line ... */ 1237 1.1 jonathan switch (vs.cx) { 1238 1.1 jonathan case 0: 1239 1.1 jonathan /* ... current to EOL */ 1240 1.13 soda fillw((vs.at << 8) | ' ', 1241 1.13 soda crtat, 1242 1.1 jonathan vs.ncol - vs.col); 1243 1.1 jonathan break; 1244 1.1 jonathan case 1: 1245 1.1 jonathan /* ... beginning to next */ 1246 1.1 jonathan fillw((vs.at << 8) | ' ', 1247 1.1 jonathan crtat - vs.col, 1248 1.1 jonathan vs.col + 1); 1249 1.1 jonathan break; 1250 1.1 jonathan case 2: 1251 1.1 jonathan /* ... entire line */ 1252 1.1 jonathan fillw((vs.at << 8) | ' ', 1253 1.1 jonathan crtat - vs.col, vs.ncol); 1254 1.1 jonathan break; 1255 1.1 jonathan } 1256 1.1 jonathan vs.state = 0; 1257 1.1 jonathan break; 1258 1.1 jonathan case 'f': /* in system V consoles */ 1259 1.1 jonathan case 'H': { /* Cursor move */ 1260 1.1 jonathan int cx = vs.cx, 1261 1.1 jonathan cy = vs.cy; 1262 1.1 jonathan if (!cx || !cy) { 1263 1.1 jonathan crtat = Crtat; 1264 1.1 jonathan vs.col = 0; 1265 1.1 jonathan } else { 1266 1.1 jonathan if (cx > vs.nrow) 1267 1.1 jonathan cx = vs.nrow; 1268 1.1 jonathan if (cy > vs.ncol) 1269 1.1 jonathan cy = vs.ncol; 1270 1.1 jonathan crtat = Crtat + 1271 1.1 jonathan (cx - 1) * vs.ncol + cy - 1; 1272 1.1 jonathan vs.col = cy - 1; 1273 1.1 jonathan } 1274 1.1 jonathan vs.state = 0; 1275 1.1 jonathan break; 1276 1.1 jonathan } 1277 1.1 jonathan case 'M': { /* delete cx rows */ 1278 1.1 jonathan u_short *crtAt = crtat - vs.col; 1279 1.1 jonathan int cx = vs.cx, 1280 1.1 jonathan row = (crtAt - Crtat) / vs.ncol, 1281 1.1 jonathan nrow = vs.nrow - row; 1282 1.1 jonathan if (cx <= 0) 1283 1.1 jonathan cx = 1; 1284 1.1 jonathan else if (cx > nrow) 1285 1.1 jonathan cx = nrow; 1286 1.1 jonathan if (cx < nrow) 1287 1.13 soda #ifdef PCCONS_FORCE_WORD 1288 1.13 soda wcopy(crtAt + vs.ncol * cx, 1289 1.13 soda crtAt, vs.ncol * (nrow - 1290 1.13 soda cx) * CHR); 1291 1.13 soda #else 1292 1.56 tsutsui memmove(crtAt, 1293 1.56 tsutsui crtAt + vs.ncol * cx, 1294 1.56 tsutsui vs.ncol * (nrow - cx) * 1295 1.56 tsutsui CHR); 1296 1.13 soda #endif 1297 1.1 jonathan fillw((vs.at << 8) | ' ', 1298 1.1 jonathan crtAt + vs.ncol * (nrow - cx), 1299 1.1 jonathan vs.ncol * cx); 1300 1.1 jonathan vs.state = 0; 1301 1.1 jonathan break; 1302 1.1 jonathan } 1303 1.1 jonathan case 'S': { /* scroll up cx lines */ 1304 1.1 jonathan int cx = vs.cx; 1305 1.1 jonathan if (cx <= 0) 1306 1.1 jonathan cx = 1; 1307 1.1 jonathan else if (cx > vs.nrow) 1308 1.1 jonathan cx = vs.nrow; 1309 1.1 jonathan if (cx < vs.nrow) 1310 1.13 soda #ifdef PCCONS_FORCE_WORD 1311 1.13 soda wcopy(Crtat + vs.ncol * cx, 1312 1.13 soda Crtat, vs.ncol * (vs.nrow - 1313 1.13 soda cx) * CHR); 1314 1.13 soda #else 1315 1.56 tsutsui memmove(Crtat, 1316 1.56 tsutsui Crtat + vs.ncol * cx, 1317 1.56 tsutsui vs.ncol * (vs.nrow - cx) * 1318 1.56 tsutsui CHR); 1319 1.13 soda #endif 1320 1.1 jonathan fillw((vs.at << 8) | ' ', 1321 1.1 jonathan Crtat + vs.ncol * (vs.nrow - cx), 1322 1.1 jonathan vs.ncol * cx); 1323 1.13 soda /* crtat -= vs.ncol * cx; XXX */ 1324 1.1 jonathan vs.state = 0; 1325 1.1 jonathan break; 1326 1.1 jonathan } 1327 1.1 jonathan case 'L': { /* insert cx rows */ 1328 1.1 jonathan u_short *crtAt = crtat - vs.col; 1329 1.1 jonathan int cx = vs.cx, 1330 1.1 jonathan row = (crtAt - Crtat) / vs.ncol, 1331 1.1 jonathan nrow = vs.nrow - row; 1332 1.1 jonathan if (cx <= 0) 1333 1.1 jonathan cx = 1; 1334 1.1 jonathan else if (cx > nrow) 1335 1.1 jonathan cx = nrow; 1336 1.1 jonathan if (cx < nrow) 1337 1.13 soda #ifdef PCCONS_FORCE_WORD 1338 1.13 soda wcopy(crtAt, 1339 1.13 soda crtAt + vs.ncol * cx, 1340 1.13 soda vs.ncol * (nrow - cx) * 1341 1.13 soda CHR); 1342 1.13 soda #else 1343 1.56 tsutsui memmove(crtAt + vs.ncol * cx, 1344 1.56 tsutsui crtAt, 1345 1.1 jonathan vs.ncol * (nrow - cx) * 1346 1.1 jonathan CHR); 1347 1.13 soda #endif 1348 1.1 jonathan fillw((vs.at << 8) | ' ', crtAt, 1349 1.1 jonathan vs.ncol * cx); 1350 1.1 jonathan vs.state = 0; 1351 1.1 jonathan break; 1352 1.1 jonathan } 1353 1.1 jonathan case 'T': { /* scroll down cx lines */ 1354 1.1 jonathan int cx = vs.cx; 1355 1.1 jonathan if (cx <= 0) 1356 1.1 jonathan cx = 1; 1357 1.1 jonathan else if (cx > vs.nrow) 1358 1.1 jonathan cx = vs.nrow; 1359 1.1 jonathan if (cx < vs.nrow) 1360 1.13 soda #ifdef PCCONS_FORCE_WORD 1361 1.13 soda wcopy(Crtat, 1362 1.13 soda Crtat + vs.ncol * cx, 1363 1.13 soda vs.ncol * (vs.nrow - cx) * 1364 1.13 soda CHR); 1365 1.13 soda #else 1366 1.56 tsutsui memmove(Crtat + vs.ncol * cx, 1367 1.56 tsutsui Crtat, 1368 1.1 jonathan vs.ncol * (vs.nrow - cx) * 1369 1.1 jonathan CHR); 1370 1.13 soda #endif 1371 1.1 jonathan fillw((vs.at << 8) | ' ', Crtat, 1372 1.1 jonathan vs.ncol * cx); 1373 1.13 soda /* crtat += vs.ncol * cx; XXX */ 1374 1.1 jonathan vs.state = 0; 1375 1.1 jonathan break; 1376 1.1 jonathan } 1377 1.1 jonathan case ';': /* Switch params in cursor def */ 1378 1.1 jonathan vs.state = VSS_EPARAM; 1379 1.1 jonathan break; 1380 1.1 jonathan case 'r': 1381 1.1 jonathan vs.so_at = (vs.cx & FG_MASK) | 1382 1.1 jonathan ((vs.cy << 4) & BG_MASK); 1383 1.1 jonathan vs.state = 0; 1384 1.1 jonathan break; 1385 1.13 soda case 's': /* save cursor pos */ 1386 1.13 soda vs.offset = crtat - Crtat; 1387 1.13 soda vs.state = 0; 1388 1.13 soda break; 1389 1.13 soda case 'u': /* restore cursor pos */ 1390 1.13 soda crtat = Crtat + vs.offset; 1391 1.13 soda vs.row = vs.offset / vs.ncol; 1392 1.13 soda vs.col = vs.offset % vs.ncol; 1393 1.13 soda vs.state = 0; 1394 1.13 soda break; 1395 1.1 jonathan case 'x': /* set attributes */ 1396 1.1 jonathan switch (vs.cx) { 1397 1.1 jonathan case 0: 1398 1.1 jonathan vs.at = FG_LIGHTGREY | BG_BLACK; 1399 1.1 jonathan break; 1400 1.1 jonathan case 1: 1401 1.1 jonathan /* ansi background */ 1402 1.1 jonathan if (!vs.color) 1403 1.1 jonathan break; 1404 1.1 jonathan vs.at &= FG_MASK; 1405 1.1 jonathan vs.at |= bgansitopc[vs.cy & 7]; 1406 1.1 jonathan break; 1407 1.1 jonathan case 2: 1408 1.1 jonathan /* ansi foreground */ 1409 1.1 jonathan if (!vs.color) 1410 1.1 jonathan break; 1411 1.1 jonathan vs.at &= BG_MASK; 1412 1.1 jonathan vs.at |= fgansitopc[vs.cy & 7]; 1413 1.1 jonathan break; 1414 1.1 jonathan case 3: 1415 1.1 jonathan /* pc text attribute */ 1416 1.1 jonathan if (vs.state >= VSS_EPARAM) 1417 1.1 jonathan vs.at = vs.cy; 1418 1.1 jonathan break; 1419 1.1 jonathan } 1420 1.1 jonathan vs.state = 0; 1421 1.1 jonathan break; 1422 1.32 tsutsui 1423 1.1 jonathan default: /* Only numbers valid here */ 1424 1.1 jonathan if ((c >= '0') && (c <= '9')) { 1425 1.1 jonathan if (vs.state >= VSS_EPARAM) { 1426 1.1 jonathan vs.cy *= 10; 1427 1.1 jonathan vs.cy += c - '0'; 1428 1.1 jonathan } else { 1429 1.1 jonathan vs.cx *= 10; 1430 1.1 jonathan vs.cx += c - '0'; 1431 1.1 jonathan } 1432 1.1 jonathan } else 1433 1.1 jonathan vs.state = 0; 1434 1.1 jonathan break; 1435 1.1 jonathan } 1436 1.1 jonathan break; 1437 1.1 jonathan } 1438 1.1 jonathan } 1439 1.1 jonathan if (scroll) { 1440 1.1 jonathan scroll = 0; 1441 1.1 jonathan /* scroll check */ 1442 1.1 jonathan if (crtat >= Crtat + vs.nchr) { 1443 1.1 jonathan if (!kernel) { 1444 1.1 jonathan int s = spltty(); 1445 1.13 soda if (lock_state & KB_SCROLL) 1446 1.13 soda tsleep(&lock_state, 1447 1.1 jonathan PUSER, "pcputc", 0); 1448 1.1 jonathan splx(s); 1449 1.1 jonathan } 1450 1.13 soda #if PCCONS_FORCE_WORD 1451 1.13 soda wcopy(Crtat + vs.ncol, Crtat, 1452 1.13 soda (vs.nchr - vs.ncol) * CHR); 1453 1.13 soda #else 1454 1.56 tsutsui memmove(Crtat, Crtat + vs.ncol, 1455 1.1 jonathan (vs.nchr - vs.ncol) * CHR); 1456 1.13 soda #endif 1457 1.1 jonathan fillw((vs.at << 8) | ' ', 1458 1.13 soda Crtat + vs.nchr - vs.ncol, 1459 1.13 soda vs.ncol); 1460 1.1 jonathan crtat -= vs.ncol; 1461 1.1 jonathan } 1462 1.1 jonathan } 1463 1.1 jonathan } 1464 1.1 jonathan async_update(); 1465 1.1 jonathan } 1466 1.1 jonathan 1467 1.13 soda /* the unshifted code for KB_SHIFT keys is used by X to distinguish between 1468 1.13 soda left and right shift when reading the keyboard map */ 1469 1.13 soda static pccons_keymap_t scan_codes[KB_NUM_KEYS] = { 1470 1.13 soda /* type unshift shift control altgr shift_altgr scancode */ 1471 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 0 unused */ 1472 1.13 soda { KB_ASCII, "\033", "\033", "\033", "", ""}, /* 1 ESCape */ 1473 1.13 soda { KB_ASCII, "1", "!", "!", "", ""}, /* 2 1 */ 1474 1.13 soda { KB_ASCII, "2", "@", "\000", "", ""}, /* 3 2 */ 1475 1.13 soda { KB_ASCII, "3", "#", "#", "", ""}, /* 4 3 */ 1476 1.13 soda { KB_ASCII, "4", "$", "$", "", ""}, /* 5 4 */ 1477 1.13 soda { KB_ASCII, "5", "%", "%", "", ""}, /* 6 5 */ 1478 1.13 soda { KB_ASCII, "6", "^", "\036", "", ""}, /* 7 6 */ 1479 1.13 soda { KB_ASCII, "7", "&", "&", "", ""}, /* 8 7 */ 1480 1.13 soda { KB_ASCII, "8", "*", "\010", "", ""}, /* 9 8 */ 1481 1.13 soda { KB_ASCII, "9", "(", "(", "", ""}, /* 10 9 */ 1482 1.13 soda { KB_ASCII, "0", ")", ")", "", ""}, /* 11 0 */ 1483 1.13 soda { KB_ASCII, "-", "_", "\037", "", ""}, /* 12 - */ 1484 1.13 soda { KB_ASCII, "=", "+", "+", "", ""}, /* 13 = */ 1485 1.13 soda { KB_ASCII, "\177", "\177", "\010", "", ""}, /* 14 backspace */ 1486 1.13 soda { KB_ASCII, "\t", "\t", "\t", "", ""}, /* 15 tab */ 1487 1.13 soda { KB_ASCII, "q", "Q", "\021", "", ""}, /* 16 q */ 1488 1.13 soda { KB_ASCII, "w", "W", "\027", "", ""}, /* 17 w */ 1489 1.13 soda { KB_ASCII, "e", "E", "\005", "", ""}, /* 18 e */ 1490 1.13 soda { KB_ASCII, "r", "R", "\022", "", ""}, /* 19 r */ 1491 1.13 soda { KB_ASCII, "t", "T", "\024", "", ""}, /* 20 t */ 1492 1.13 soda { KB_ASCII, "y", "Y", "\031", "", ""}, /* 21 y */ 1493 1.13 soda { KB_ASCII, "u", "U", "\025", "", ""}, /* 22 u */ 1494 1.13 soda { KB_ASCII, "i", "I", "\011", "", ""}, /* 23 i */ 1495 1.13 soda { KB_ASCII, "o", "O", "\017", "", ""}, /* 24 o */ 1496 1.13 soda { KB_ASCII, "p", "P", "\020", "", ""}, /* 25 p */ 1497 1.13 soda { KB_ASCII, "[", "{", "\033", "", ""}, /* 26 [ */ 1498 1.13 soda { KB_ASCII, "]", "}", "\035", "", ""}, /* 27 ] */ 1499 1.13 soda { KB_ASCII, "\r", "\r", "\n", "", ""}, /* 28 return */ 1500 1.13 soda { KB_CTL, "", "", "", "", ""}, /* 29 control */ 1501 1.13 soda { KB_ASCII, "a", "A", "\001", "", ""}, /* 30 a */ 1502 1.13 soda { KB_ASCII, "s", "S", "\023", "", ""}, /* 31 s */ 1503 1.13 soda { KB_ASCII, "d", "D", "\004", "", ""}, /* 32 d */ 1504 1.13 soda { KB_ASCII, "f", "F", "\006", "", ""}, /* 33 f */ 1505 1.13 soda { KB_ASCII, "g", "G", "\007", "", ""}, /* 34 g */ 1506 1.13 soda { KB_ASCII, "h", "H", "\010", "", ""}, /* 35 h */ 1507 1.13 soda { KB_ASCII, "j", "J", "\n", "", ""}, /* 36 j */ 1508 1.13 soda { KB_ASCII, "k", "K", "\013", "", ""}, /* 37 k */ 1509 1.13 soda { KB_ASCII, "l", "L", "\014", "", ""}, /* 38 l */ 1510 1.13 soda { KB_ASCII, ";", ":", ";", "", ""}, /* 39 ; */ 1511 1.13 soda { KB_ASCII, "'", "\"", "'", "", ""}, /* 40 ' */ 1512 1.13 soda { KB_ASCII, "`", "~", "`", "", ""}, /* 41 ` */ 1513 1.13 soda { KB_SHIFT, "\001", "", "", "", ""}, /* 42 shift */ 1514 1.13 soda { KB_ASCII, "\\", "|", "\034", "", ""}, /* 43 \ */ 1515 1.13 soda { KB_ASCII, "z", "Z", "\032", "", ""}, /* 44 z */ 1516 1.13 soda { KB_ASCII, "x", "X", "\030", "", ""}, /* 45 x */ 1517 1.13 soda { KB_ASCII, "c", "C", "\003", "", ""}, /* 46 c */ 1518 1.13 soda { KB_ASCII, "v", "V", "\026", "", ""}, /* 47 v */ 1519 1.13 soda { KB_ASCII, "b", "B", "\002", "", ""}, /* 48 b */ 1520 1.13 soda { KB_ASCII, "n", "N", "\016", "", ""}, /* 49 n */ 1521 1.13 soda { KB_ASCII, "m", "M", "\r", "", ""}, /* 50 m */ 1522 1.13 soda { KB_ASCII, ",", "<", "<", "", ""}, /* 51 , */ 1523 1.13 soda { KB_ASCII, ".", ">", ">", "", ""}, /* 52 . */ 1524 1.13 soda { KB_ASCII, "/", "?", "\037", "", ""}, /* 53 / */ 1525 1.13 soda { KB_SHIFT, "\002", "", "", "", ""}, /* 54 shift */ 1526 1.13 soda { KB_KP, "*", "*", "*", "", ""}, /* 55 kp * */ 1527 1.13 soda { KB_ALT, "", "", "", "", ""}, /* 56 alt */ 1528 1.13 soda { KB_ASCII, " ", " ", "\000", "", ""}, /* 57 space */ 1529 1.13 soda { KB_CAPS, "", "", "", "", ""}, /* 58 caps */ 1530 1.13 soda { KB_FUNC, "\033[M", "\033[Y", "\033[k", "", ""}, /* 59 f1 */ 1531 1.13 soda { KB_FUNC, "\033[N", "\033[Z", "\033[l", "", ""}, /* 60 f2 */ 1532 1.13 soda { KB_FUNC, "\033[O", "\033[a", "\033[m", "", ""}, /* 61 f3 */ 1533 1.13 soda { KB_FUNC, "\033[P", "\033[b", "\033[n", "", ""}, /* 62 f4 */ 1534 1.13 soda { KB_FUNC, "\033[Q", "\033[c", "\033[o", "", ""}, /* 63 f5 */ 1535 1.13 soda { KB_FUNC, "\033[R", "\033[d", "\033[p", "", ""}, /* 64 f6 */ 1536 1.13 soda { KB_FUNC, "\033[S", "\033[e", "\033[q", "", ""}, /* 65 f7 */ 1537 1.13 soda { KB_FUNC, "\033[T", "\033[f", "\033[r", "", ""}, /* 66 f8 */ 1538 1.13 soda { KB_FUNC, "\033[U", "\033[g", "\033[s", "", ""}, /* 67 f9 */ 1539 1.13 soda { KB_FUNC, "\033[V", "\033[h", "\033[t", "", ""}, /* 68 f10 */ 1540 1.13 soda { KB_NUM, "", "", "", "", ""}, /* 69 num lock */ 1541 1.13 soda { KB_SCROLL, "", "", "", "", ""}, /* 70 scroll lock */ 1542 1.13 soda { KB_KP, "7", "\033[H", "7", "", ""}, /* 71 kp 7 */ 1543 1.13 soda { KB_KP, "8", "\033[A", "8", "", ""}, /* 72 kp 8 */ 1544 1.13 soda { KB_KP, "9", "\033[I", "9", "", ""}, /* 73 kp 9 */ 1545 1.13 soda { KB_KP, "-", "-", "-", "", ""}, /* 74 kp - */ 1546 1.13 soda { KB_KP, "4", "\033[D", "4", "", ""}, /* 75 kp 4 */ 1547 1.13 soda { KB_KP, "5", "\033[E", "5", "", ""}, /* 76 kp 5 */ 1548 1.13 soda { KB_KP, "6", "\033[C", "6", "", ""}, /* 77 kp 6 */ 1549 1.13 soda { KB_KP, "+", "+", "+", "", ""}, /* 78 kp + */ 1550 1.13 soda { KB_KP, "1", "\033[F", "1", "", ""}, /* 79 kp 1 */ 1551 1.13 soda { KB_KP, "2", "\033[B", "2", "", ""}, /* 80 kp 2 */ 1552 1.13 soda { KB_KP, "3", "\033[G", "3", "", ""}, /* 81 kp 3 */ 1553 1.13 soda { KB_KP, "0", "\033[L", "0", "", ""}, /* 82 kp 0 */ 1554 1.13 soda { KB_KP, ",", "\177", ",", "", ""}, /* 83 kp , */ 1555 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 84 0 */ 1556 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 85 0 */ 1557 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 86 0 */ 1558 1.13 soda { KB_FUNC, "\033[W", "\033[i", "\033[u", "", ""}, /* 87 f11 */ 1559 1.13 soda { KB_FUNC, "\033[X", "\033[j", "\033[v", "", ""}, /* 88 f12 */ 1560 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 89 0 */ 1561 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 90 0 */ 1562 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 91 0 */ 1563 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 92 0 */ 1564 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 93 0 */ 1565 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 94 0 */ 1566 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 95 0 */ 1567 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 96 0 */ 1568 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 97 0 */ 1569 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 98 0 */ 1570 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 99 0 */ 1571 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 100 */ 1572 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 101 */ 1573 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 102 */ 1574 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 103 */ 1575 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 104 */ 1576 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 105 */ 1577 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 106 */ 1578 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 107 */ 1579 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 108 */ 1580 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 109 */ 1581 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 110 */ 1582 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 111 */ 1583 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 112 */ 1584 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 113 */ 1585 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 114 */ 1586 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 115 */ 1587 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 116 */ 1588 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 117 */ 1589 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 118 */ 1590 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 119 */ 1591 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 120 */ 1592 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 121 */ 1593 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 122 */ 1594 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 123 */ 1595 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 124 */ 1596 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 125 */ 1597 1.13 soda { KB_NONE, "", "", "", "", ""}, /* 126 */ 1598 1.13 soda { KB_NONE, "", "", "", "", ""} /* 127 */ 1599 1.1 jonathan }; 1600 1.1 jonathan 1601 1.1 jonathan /* 1602 1.1 jonathan * Get characters from the keyboard. If none are present, return NULL. 1603 1.1 jonathan */ 1604 1.1 jonathan char * 1605 1.39 tsutsui sget(void) 1606 1.1 jonathan { 1607 1.1 jonathan u_char dt; 1608 1.1 jonathan static u_char extended = 0, shift_state = 0; 1609 1.1 jonathan static u_char capchar[2]; 1610 1.1 jonathan 1611 1.1 jonathan top: 1612 1.1 jonathan KBD_DELAY; 1613 1.27 soda dt = kbd_data_read_1(); 1614 1.1 jonathan 1615 1.1 jonathan switch (dt) { 1616 1.1 jonathan case KBR_ACK: case KBR_ECHO: 1617 1.1 jonathan kb_oq_get = (kb_oq_get + 1) & 7; 1618 1.1 jonathan if(kb_oq_get != kb_oq_put) { 1619 1.27 soda kbd_data_write_1(kb_oq[kb_oq_get]); 1620 1.1 jonathan } 1621 1.1 jonathan goto loop; 1622 1.1 jonathan case KBR_RESEND: 1623 1.27 soda kbd_data_write_1(kb_oq[kb_oq_get]); 1624 1.1 jonathan goto loop; 1625 1.1 jonathan } 1626 1.1 jonathan 1627 1.1 jonathan if (pc_xmode > 0) { 1628 1.1 jonathan #if defined(DDB) && defined(XSERVER_DDB) 1629 1.1 jonathan /* F12 enters the debugger while in X mode */ 1630 1.1 jonathan if (dt == 88) 1631 1.1 jonathan Debugger(); 1632 1.1 jonathan #endif 1633 1.1 jonathan capchar[0] = dt; 1634 1.1 jonathan capchar[1] = 0; 1635 1.1 jonathan /* 1636 1.1 jonathan * Check for locking keys. 1637 1.1 jonathan * 1638 1.1 jonathan * XXX Setting the LEDs this way is a bit bogus. What if the 1639 1.1 jonathan * keyboard has been remapped in X? 1640 1.1 jonathan */ 1641 1.13 soda switch (scan_codes[dt & 0x7f].type) { 1642 1.13 soda case KB_NUM: 1643 1.1 jonathan if (dt & 0x80) { 1644 1.13 soda shift_state &= ~KB_NUM; 1645 1.1 jonathan break; 1646 1.1 jonathan } 1647 1.13 soda if (shift_state & KB_NUM) 1648 1.1 jonathan break; 1649 1.13 soda shift_state |= KB_NUM; 1650 1.13 soda lock_state ^= KB_NUM; 1651 1.1 jonathan async_update(); 1652 1.1 jonathan break; 1653 1.13 soda case KB_CAPS: 1654 1.1 jonathan if (dt & 0x80) { 1655 1.13 soda shift_state &= ~KB_CAPS; 1656 1.1 jonathan break; 1657 1.1 jonathan } 1658 1.13 soda if (shift_state & KB_CAPS) 1659 1.1 jonathan break; 1660 1.13 soda shift_state |= KB_CAPS; 1661 1.13 soda lock_state ^= KB_CAPS; 1662 1.1 jonathan async_update(); 1663 1.1 jonathan break; 1664 1.13 soda case KB_SCROLL: 1665 1.1 jonathan if (dt & 0x80) { 1666 1.13 soda shift_state &= ~KB_SCROLL; 1667 1.1 jonathan break; 1668 1.1 jonathan } 1669 1.13 soda if (shift_state & KB_SCROLL) 1670 1.1 jonathan break; 1671 1.13 soda shift_state |= KB_SCROLL; 1672 1.13 soda lock_state ^= KB_SCROLL; 1673 1.13 soda if ((lock_state & KB_SCROLL) == 0) 1674 1.49 christos wakeup((void *)&lock_state); 1675 1.1 jonathan async_update(); 1676 1.1 jonathan break; 1677 1.1 jonathan } 1678 1.1 jonathan return capchar; 1679 1.1 jonathan } 1680 1.1 jonathan 1681 1.1 jonathan switch (dt) { 1682 1.1 jonathan case KBR_EXTENDED: 1683 1.1 jonathan extended = 1; 1684 1.1 jonathan goto loop; 1685 1.1 jonathan } 1686 1.1 jonathan 1687 1.13 soda #ifdef DDB 1688 1.1 jonathan /* 1689 1.1 jonathan * Check for cntl-alt-esc. 1690 1.1 jonathan */ 1691 1.13 soda if ((dt == 1) && (shift_state & (KB_CTL | KB_ALT)) == (KB_CTL | KB_ALT)) { 1692 1.13 soda /* XXX - check pccons_is_console */ 1693 1.13 soda Debugger(); 1694 1.1 jonathan dt |= 0x80; /* discard esc (ddb discarded ctl-alt) */ 1695 1.1 jonathan } 1696 1.1 jonathan #endif 1697 1.1 jonathan 1698 1.1 jonathan /* 1699 1.1 jonathan * Check for make/break. 1700 1.1 jonathan */ 1701 1.1 jonathan if (dt & 0x80) { 1702 1.1 jonathan /* 1703 1.1 jonathan * break 1704 1.1 jonathan */ 1705 1.1 jonathan dt &= 0x7f; 1706 1.13 soda switch (scan_codes[dt].type) { 1707 1.13 soda case KB_NUM: 1708 1.13 soda shift_state &= ~KB_NUM; 1709 1.1 jonathan break; 1710 1.13 soda case KB_CAPS: 1711 1.13 soda shift_state &= ~KB_CAPS; 1712 1.1 jonathan break; 1713 1.13 soda case KB_SCROLL: 1714 1.13 soda shift_state &= ~KB_SCROLL; 1715 1.1 jonathan break; 1716 1.13 soda case KB_SHIFT: 1717 1.13 soda shift_state &= ~KB_SHIFT; 1718 1.1 jonathan break; 1719 1.13 soda case KB_ALT: 1720 1.1 jonathan if (extended) 1721 1.13 soda shift_state &= ~KB_ALTGR; 1722 1.1 jonathan else 1723 1.13 soda shift_state &= ~KB_ALT; 1724 1.1 jonathan break; 1725 1.13 soda case KB_CTL: 1726 1.13 soda shift_state &= ~KB_CTL; 1727 1.1 jonathan break; 1728 1.1 jonathan } 1729 1.1 jonathan } else { 1730 1.1 jonathan /* 1731 1.1 jonathan * make 1732 1.1 jonathan */ 1733 1.13 soda switch (scan_codes[dt].type) { 1734 1.1 jonathan /* 1735 1.1 jonathan * locking keys 1736 1.1 jonathan */ 1737 1.13 soda case KB_NUM: 1738 1.13 soda if (shift_state & KB_NUM) 1739 1.1 jonathan break; 1740 1.13 soda shift_state |= KB_NUM; 1741 1.13 soda lock_state ^= KB_NUM; 1742 1.1 jonathan async_update(); 1743 1.1 jonathan break; 1744 1.13 soda case KB_CAPS: 1745 1.13 soda if (shift_state & KB_CAPS) 1746 1.1 jonathan break; 1747 1.13 soda shift_state |= KB_CAPS; 1748 1.13 soda lock_state ^= KB_CAPS; 1749 1.1 jonathan async_update(); 1750 1.1 jonathan break; 1751 1.13 soda case KB_SCROLL: 1752 1.13 soda if (shift_state & KB_SCROLL) 1753 1.1 jonathan break; 1754 1.13 soda shift_state |= KB_SCROLL; 1755 1.13 soda lock_state ^= KB_SCROLL; 1756 1.13 soda if ((lock_state & KB_SCROLL) == 0) 1757 1.49 christos wakeup((void *)&lock_state); 1758 1.1 jonathan async_update(); 1759 1.1 jonathan break; 1760 1.1 jonathan /* 1761 1.1 jonathan * non-locking keys 1762 1.1 jonathan */ 1763 1.13 soda case KB_SHIFT: 1764 1.13 soda shift_state |= KB_SHIFT; 1765 1.1 jonathan break; 1766 1.13 soda case KB_ALT: 1767 1.1 jonathan if (extended) 1768 1.13 soda shift_state |= KB_ALTGR; 1769 1.1 jonathan else 1770 1.13 soda shift_state |= KB_ALT; 1771 1.1 jonathan break; 1772 1.13 soda case KB_CTL: 1773 1.13 soda shift_state |= KB_CTL; 1774 1.1 jonathan break; 1775 1.13 soda case KB_ASCII: 1776 1.13 soda /* control has highest priority */ 1777 1.13 soda if (shift_state & KB_CTL) 1778 1.13 soda capchar[0] = scan_codes[dt].ctl[0]; 1779 1.13 soda else if (shift_state & KB_ALTGR) { 1780 1.13 soda if (shift_state & KB_SHIFT) 1781 1.13 soda capchar[0] = scan_codes[dt].shift_altgr[0]; 1782 1.13 soda else 1783 1.13 soda capchar[0] = scan_codes[dt].altgr[0]; 1784 1.1 jonathan } 1785 1.13 soda else { 1786 1.13 soda if (shift_state & KB_SHIFT) 1787 1.13 soda capchar[0] = scan_codes[dt].shift[0]; 1788 1.13 soda else 1789 1.13 soda capchar[0] = scan_codes[dt].unshift[0]; 1790 1.13 soda } 1791 1.13 soda if ((lock_state & KB_CAPS) && capchar[0] >= 'a' && 1792 1.1 jonathan capchar[0] <= 'z') { 1793 1.1 jonathan capchar[0] -= ('a' - 'A'); 1794 1.1 jonathan } 1795 1.13 soda capchar[0] |= (shift_state & KB_ALT); 1796 1.1 jonathan extended = 0; 1797 1.1 jonathan return capchar; 1798 1.13 soda case KB_NONE: 1799 1.6 christos printf("keycode %d\n",dt); 1800 1.1 jonathan break; 1801 1.13 soda case KB_FUNC: { 1802 1.1 jonathan char *more_chars; 1803 1.13 soda if (shift_state & KB_SHIFT) 1804 1.13 soda more_chars = scan_codes[dt].shift; 1805 1.13 soda else if (shift_state & KB_CTL) 1806 1.13 soda more_chars = scan_codes[dt].ctl; 1807 1.1 jonathan else 1808 1.13 soda more_chars = scan_codes[dt].unshift; 1809 1.1 jonathan extended = 0; 1810 1.1 jonathan return more_chars; 1811 1.1 jonathan } 1812 1.13 soda case KB_KP: { 1813 1.1 jonathan char *more_chars; 1814 1.13 soda if (shift_state & (KB_SHIFT | KB_CTL) || 1815 1.13 soda (lock_state & KB_NUM) == 0 || extended) 1816 1.13 soda more_chars = scan_codes[dt].shift; 1817 1.1 jonathan else 1818 1.13 soda more_chars = scan_codes[dt].unshift; 1819 1.1 jonathan extended = 0; 1820 1.1 jonathan return more_chars; 1821 1.1 jonathan } 1822 1.1 jonathan } 1823 1.1 jonathan } 1824 1.1 jonathan 1825 1.1 jonathan extended = 0; 1826 1.1 jonathan loop: 1827 1.27 soda if ((kbd_cmd_read_1() & KBS_DIB) == 0) 1828 1.1 jonathan return 0; 1829 1.1 jonathan goto top; 1830 1.1 jonathan } 1831 1.1 jonathan 1832 1.21 simonb paddr_t 1833 1.39 tsutsui pcmmap(dev_t dev, off_t offset, int nprot) 1834 1.1 jonathan { 1835 1.27 soda struct pccons_context *pc = &pccons_console_context; 1836 1.27 soda paddr_t pa; 1837 1.1 jonathan 1838 1.27 soda if (offset >= 0xa0000 && offset < 0xc0000) { 1839 1.27 soda if (bus_space_paddr(pc->pc_crt_memt, pc->pc_mono_memh, &pa)) 1840 1.39 tsutsui return -1; 1841 1.27 soda pa += offset - pc->pc_config->pc_mono_memaddr; 1842 1.39 tsutsui return mips_btop(pa); 1843 1.27 soda } 1844 1.27 soda if (offset >= 0x0000 && offset < 0x10000) { 1845 1.27 soda if (bus_space_paddr(pc->pc_crt_iot, pc->pc_mono_ioh, &pa)) 1846 1.39 tsutsui return -1; 1847 1.27 soda pa += offset - pc->pc_config->pc_mono_iobase; 1848 1.39 tsutsui return mips_btop(pa); 1849 1.27 soda } 1850 1.27 soda if (offset >= 0x40000000 && offset < 0x40800000) { 1851 1.27 soda if (bus_space_paddr(pc->pc_crt_memt, pc->pc_mono_memh, &pa)) 1852 1.27 soda return (-1); 1853 1.27 soda pa += offset - 0x40000000 - pc->pc_config->pc_mono_memaddr; 1854 1.39 tsutsui return mips_btop(pa); 1855 1.13 soda } 1856 1.39 tsutsui return -1; 1857 1.1 jonathan } 1858 1.1 jonathan 1859 1.13 soda void 1860 1.39 tsutsui pc_xmode_on(void) 1861 1.1 jonathan { 1862 1.1 jonathan if (pc_xmode) 1863 1.1 jonathan return; 1864 1.1 jonathan pc_xmode = 1; 1865 1.1 jonathan 1866 1.1 jonathan #ifdef XFREE86_BUG_COMPAT 1867 1.1 jonathan /* If still unchanged, get current shape. */ 1868 1.1 jonathan if (cursor_shape == 0xffff) 1869 1.1 jonathan get_cursor_shape(); 1870 1.1 jonathan #endif 1871 1.1 jonathan } 1872 1.1 jonathan 1873 1.13 soda void 1874 1.39 tsutsui pc_xmode_off(void) 1875 1.1 jonathan { 1876 1.1 jonathan if (pc_xmode == 0) 1877 1.1 jonathan return; 1878 1.1 jonathan pc_xmode = 0; 1879 1.1 jonathan 1880 1.1 jonathan #ifdef XFREE86_BUG_COMPAT 1881 1.1 jonathan /* XXX It would be hard to justify why the X server doesn't do this. */ 1882 1.1 jonathan set_cursor_shape(); 1883 1.1 jonathan #endif 1884 1.1 jonathan async_update(); 1885 1.1 jonathan } 1886