Annotation of Gnu-Mach/i386/i386at/kd.c, revision 1.1.1.6

1.1.1.3   root        1: /*
1.1       root        2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
                      4:  * All Rights Reserved.
1.1.1.3   root        5:  *
1.1       root        6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
1.1.1.3   root       11:  *
1.1       root       12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.1.1.3   root       15:  *
1.1       root       16:  * Carnegie Mellon requests users of this software to return to
1.1.1.3   root       17:  *
1.1       root       18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
1.1.1.3   root       22:  *
1.1       root       23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
1.1.1.3   root       26: /*
1.1       root       27:  *     Olivetti Mach Console driver v0.0
                     28:  *     Copyright Ing. C. Olivetti & C. S.p.A. 1988, 1989
                     29:  *     All rights reserved.
                     30:  *
1.1.1.3   root       31:  */
1.1       root       32: /*
                     33:   Copyright 1988, 1989 by Olivetti Advanced Technology Center, Inc.,
                     34: Cupertino, California.
                     35: 
                     36:                All Rights Reserved
                     37: 
                     38:   Permission to use, copy, modify, and distribute this software and
                     39: its documentation for any purpose and without fee is hereby
                     40: granted, provided that the above copyright notice appears in all
                     41: copies and that both the copyright notice and this permission notice
                     42: appear in supporting documentation, and that the name of Olivetti
                     43: not be used in advertising or publicity pertaining to distribution
                     44: of the software without specific, written prior permission.
                     45: 
                     46:   OLIVETTI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
                     47: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
                     48: IN NO EVENT SHALL OLIVETTI BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
                     49: CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
                     50: LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
                     51: NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
                     52: WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     53: */
                     54: 
                     55: /*
                     56:   Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
                     57: 
                     58:                All Rights Reserved
                     59: 
                     60: Permission to use, copy, modify, and distribute this software and
                     61: its documentation for any purpose and without fee is hereby
                     62: granted, provided that the above copyright notice appears in all
                     63: copies and that both the copyright notice and this permission notice
                     64: appear in supporting documentation, and that the name of Intel
                     65: not be used in advertising or publicity pertaining to distribution
                     66: of the software without specific, written prior permission.
                     67: 
                     68: INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
                     69: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
                     70: IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
                     71: CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
                     72: LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
                     73: NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
                     74: WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     75: */
                     76: 
                     77: /* $ Header:  $ */
                     78: 
                     79: #include <sys/types.h>
1.1.1.4   root       80: #include <kern/debug.h>
                     81: #include <kern/mach_clock.h>
                     82: #include <kern/printf.h>
1.1       root       83: #include <device/conf.h>
                     84: #include <device/tty.h>
                     85: #include <device/io_req.h>
1.1.1.5   root       86: #include <device/buf.h>
1.1       root       87: #include <vm/vm_kern.h>
1.1.1.4   root       88: #include <i386/locore.h>
                     89: #include <i386/loose_ends.h>
                     90: #include <i386/vm_param.h>
1.1       root       91: #include <i386/machspl.h>
1.1.1.4   root       92: #include <i386/pio.h>
1.1       root       93: #include <i386at/cram.h>
                     94: #include <i386at/kd.h>
1.1.1.4   root       95: #include <i386at/kd_event.h>
                     96: #include <i386at/kd_mouse.h>
1.1       root       97: #include <i386at/kdsoft.h>
1.1.1.4   root       98: #include <device/cons.h>
                     99: #include <util/atoi.h>
1.1       root      100: 
                    101: #define DEBUG  1                       /* export feep() */
                    102: 
                    103: #if 0
                    104: #define BROKEN_KEYBOARD_RESET
                    105: #endif
                    106: 
                    107: struct tty       kd_tty;
1.1.1.5   root      108: extern boolean_t rebootflag;
1.1       root      109: 
                    110: static void charput(), charmvup(), charmvdown(), charclear(), charsetcursor();
1.1.1.5   root      111: static void kd_noopreset(void);
1.1       root      112: 
1.1.1.3   root      113: /*
1.1       root      114:  * These routines define the interface to the device-specific layer.
                    115:  * See kdsoft.h for a more complete description of what each routine does.
                    116:  */
                    117: void   (*kd_dput)()    = charput;      /* put attributed char */
                    118: void   (*kd_dmvup)()   = charmvup;     /* block move up */
                    119: void   (*kd_dmvdown)() = charmvdown;   /* block move down */
                    120: void   (*kd_dclear)()  = charclear;    /* block clear */
                    121: void   (*kd_dsetcursor)() = charsetcursor;
                    122:                                /* set cursor position on displayed page */
                    123: void   (*kd_dreset)() = kd_noopreset;  /* prepare for reboot */
                    124: 
                    125: /*
                    126:  * Globals used for both character-based controllers and bitmap-based
                    127:  * controllers.  Default is EGA.
                    128:  */
                    129: 
                    130: vm_offset_t kd_bitmap_start = (vm_offset_t)0xa0000; /* XXX - put in kd.h */
1.1.1.3   root      131: u_char         *vid_start      = (u_char *)EGA_START;
1.1       root      132:                                /* VM start of video RAM or frame buffer */
                    133: csrpos_t kd_curpos     = 0;    /* set indirectly by kd_setpos--see kdsoft.h */
                    134: short  kd_lines        = 25;
                    135: short  kd_cols         = 80;
                    136: char   kd_attr         = KA_NORMAL;    /* current attribute */
1.1.1.3   root      137: char   kd_color        = KA_NORMAL;
                    138: char   kd_attrflags    = 0;            /* Not reverse, underline, blink */
1.1       root      139: 
1.1.1.3   root      140: /*
                    141:  * kd_state shows the state of the modifier keys (ctrl, caps lock,
1.1       root      142:  * etc.)  It should normally be changed by calling set_kd_state(), so
                    143:  * that the keyboard status LEDs are updated correctly.
                    144:  */
                    145: int    kd_state        = KS_NORMAL;
                    146: int    kb_mode         = KB_ASCII;     /* event/ascii */
                    147: 
                    148: /*
                    149:  * State for the keyboard "mouse".
                    150:  */
                    151: int kd_kbd_mouse = 0;
                    152: int kd_kbd_magic_scale = 6;
                    153: int kd_kbd_magic_button  = 0;
                    154: 
1.1.1.3   root      155: /*
                    156:  * Some keyboard commands work by sending a command, waiting for an
                    157:  * ack (handled by kdintr), then sending data, which generates a
1.1       root      158:  * second ack.  If we are in the middle of such a sequence, kd_ack
                    159:  * shows what the ack is for.
1.1.1.3   root      160:  *
                    161:  * When a byte is sent to the keyboard, it is kept around in last_sent
1.1       root      162:  * in case it needs to be resent.
1.1.1.3   root      163:  *
1.1       root      164:  * The rest of the variables here hold the data required to complete
                    165:  * the sequence.
1.1.1.3   root      166:  *
1.1       root      167:  * XXX - the System V driver keeps a command queue, I guess in case we
                    168:  * want to start a command while another is in progress.  Is this
                    169:  * something we should worry about?
                    170:  */
                    171: enum why_ack {NOT_WAITING, SET_LEDS, DATA_ACK};
                    172: enum why_ack   kd_ack  = NOT_WAITING;
                    173: 
                    174: u_char last_sent = 0;
                    175: 
                    176: u_char kd_nextled      = 0;
                    177: 
                    178: /*
                    179:  * We don't provide any mutex protection for this flag because we know
                    180:  * that this module will have been initialized by the time multiple
                    181:  * threads are running.
                    182:  */
                    183: boolean_t kd_initialized       = FALSE;        /* driver initialized? */
                    184: boolean_t kd_extended  = FALSE;
                    185: 
                    186: /* Array for processing escape sequences. */
1.1.1.3   root      187: #define        K_MAXESC        32
1.1       root      188: u_char esc_seq[K_MAXESC];
                    189: u_char *esc_spt        = (u_char *)0;
                    190: 
                    191: /*
                    192:  * This array maps scancodes to Ascii characters (or character
1.1.1.3   root      193:  * sequences).
1.1       root      194:  * Each row corresponds to one key.  There are NUMOUTPUT bytes per key
                    195:  * state.  The states are ordered: Normal, SHIFT, CTRL, ALT,
                    196:  * SHIFT/ALT.
                    197:  */
1.1.1.2   root      198: 
                    199: /* This new keymap from Tudor Hulubei ([email protected]) makes the
                    200:    following changes to the keyboard driver:
                    201: 
                    202:    - Alt + key (m-key) returns `ESC key' instead of `ESC N key'.
                    203:    - Backspace returns 0x7f instead of 0x08.
                    204:    - Delete returns `ESC [ 9' instead of 0x7f.
                    205:    - Alt + function keys return key sequences that are different
                    206:      from the key sequences returned by the function keys alone.
1.1.1.5   root      207:      This is done with the idea of allowing a terminal server to
1.1.1.2   root      208:      implement multiple virtual consoles mapped on Alt+F1, Alt+F2,
                    209:      etc, as in Linux.
                    210: 
                    211:    -- Derek Upham 1997/06/25 */
                    212: 
1.1       root      213: unsigned char  key_map[NUMKEYS][WIDTH_KMAP] = {
1.1.1.2   root      214: {NC,NC,NC,      NC,NC,NC,       NC,NC,NC,      NC,NC,NC,      NC,NC,NC},
                    215: {K_ESC,NC,NC,   K_ESC,NC,NC,    K_ESC,NC,NC,   0x1b,K_ESC,NC, K_ESC,NC,NC},
1.1.1.4   root      216: {K_ONE,NC,NC,   K_BANG,NC,NC,   K_ONE,NC,NC,   0x1b,K_ONE,NC,  0x1b,0x4e,K_BANG},
                    217: {K_TWO,NC,NC,   K_ATSN,NC,NC,   K_NUL,NC,NC,   0x1b,K_TWO,NC,  0x1b,0x4e,K_ATSN},
                    218: {K_THREE,NC,NC, K_POUND,NC,NC,  K_THREE,NC,NC, 0x1b,K_THREE,NC,  0x1b,0x4e,K_POUND},
                    219: {K_FOUR,NC,NC,  K_DOLLAR,NC,NC, K_FOUR,NC,NC,  0x1b,K_FOUR,NC,  0x1b,0x4e,K_DOLLAR},
                    220: {K_FIVE,NC,NC,  K_PERC,NC,NC,   K_FIVE,NC,NC,  0x1b,K_FIVE,NC,  0x1b,0x4e,K_PERC},
                    221: {K_SIX,NC,NC,   K_CARET,NC,NC,  K_RS,NC,NC,    0x1b,K_SIX,NC,  0x1b,0x4e,K_CARET},
                    222: {K_SEVEN,NC,NC, K_AMPER,NC,NC,  K_SEVEN,NC,NC, 0x1b,K_SEVEN,NC,  0x1b,0x4e,K_AMPER},
                    223: {K_EIGHT,NC,NC, K_ASTER,NC,NC,  K_EIGHT,NC,NC, 0x1b,K_EIGHT,NC,  0x1b,0x4e,K_ASTER},
                    224: {K_NINE,NC,NC,  K_LPAREN,NC,NC, K_NINE,NC,NC,  0x1b,K_NINE,NC,  0x1b,0x4e,K_LPAREN},
                    225: {K_ZERO,NC,NC,  K_RPAREN,NC,NC, K_ZERO,NC,NC,  0x1b,K_ZERO,NC,  0x1b,0x4e,K_RPAREN},
                    226: {K_MINUS,NC,NC, K_UNDSC,NC,NC,  K_US,NC,NC,    0x1b,K_MINUS,NC,  0x1b,0x4e,K_UNDSC},
                    227: {K_EQL,NC,NC,   K_PLUS,NC,NC,   K_EQL,NC,NC,   0x1b,K_EQL,NC,  0x1b,0x4e,K_PLUS},
1.1.1.2   root      228: {K_DEL,NC,NC,   K_DEL,NC,NC,    K_DEL,NC,NC,   0x1b,K_DEL,NC, K_DEL,NC,NC},
                    229: {K_HT,NC,NC,    K_GS,NC,NC,     K_HT,NC,NC,    0x1b,K_HT,NC,  K_GS,NC,NC},
1.1.1.4   root      230: {K_q,NC,NC,     K_Q,NC,NC,      K_DC1,NC,NC,   0x1b,K_q,NC,  0x1b,0x4e,K_Q},
                    231: {K_w,NC,NC,     K_W,NC,NC,      K_ETB,NC,NC,   0x1b,K_w,NC,  0x1b,0x4e,K_W},
                    232: {K_e,NC,NC,     K_E,NC,NC,      K_ENQ,NC,NC,   0x1b,K_e,NC,  0x1b,0x4e,K_E},
                    233: {K_r,NC,NC,     K_R,NC,NC,      K_DC2,NC,NC,   0x1b,K_r,NC,  0x1b,0x4e,K_R},
                    234: {K_t,NC,NC,     K_T,NC,NC,      K_DC4,NC,NC,   0x1b,K_t,NC,  0x1b,0x4e,K_T},
                    235: {K_y,NC,NC,     K_Y,NC,NC,      K_EM,NC,NC,    0x1b,K_y,NC,  0x1b,0x4e,K_Y},
                    236: {K_u,NC,NC,     K_U,NC,NC,      K_NAK,NC,NC,   0x1b,K_u,NC,  0x1b,0x4e,K_U},
                    237: {K_i,NC,NC,     K_I,NC,NC,      K_HT,NC,NC,    0x1b,K_i,NC,  0x1b,0x4e,K_I},
                    238: {K_o,NC,NC,     K_O,NC,NC,      K_SI,NC,NC,    0x1b,K_o,NC,  0x1b,0x4e,K_O},
                    239: {K_p,NC,NC,     K_P,NC,NC,      K_DLE,NC,NC,   0x1b,K_p,NC,  0x1b,0x4e,K_P},
                    240: {K_LBRKT,NC,NC, K_LBRACE,NC,NC, K_ESC,NC,NC,   0x1b,K_LBRKT,NC,  0x1b,0x4e,K_LBRACE},
                    241: {K_RBRKT,NC,NC, K_RBRACE,NC,NC, K_GS,NC,NC,    0x1b,K_RBRKT,NC,  0x1b,0x4e,K_RBRACE},
1.1.1.2   root      242: {K_CR,NC,NC,    K_CR,NC,NC,     K_CR,NC,NC,    0x1b,K_CR,NC,  K_CR,NC,NC},
1.1.1.5   root      243: {K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC},
1.1.1.4   root      244: {K_a,NC,NC,     K_A,NC,NC,      K_SOH,NC,NC,   0x1b,K_a,NC,  0x1b,0x4e,K_A},
                    245: {K_s,NC,NC,     K_S,NC,NC,      K_DC3,NC,NC,   0x1b,K_s,NC,  0x1b,0x4e,K_S},
                    246: {K_d,NC,NC,     K_D,NC,NC,      K_EOT,NC,NC,   0x1b,K_d,NC,  0x1b,0x4e,K_D},
                    247: {K_f,NC,NC,     K_F,NC,NC,      K_ACK,NC,NC,   0x1b,K_f,NC,  0x1b,0x4e,K_F},
                    248: {K_g,NC,NC,     K_G,NC,NC,      K_BEL,NC,NC,   0x1b,K_g,NC,  0x1b,0x4e,K_G},
                    249: {K_h,NC,NC,     K_H,NC,NC,      K_BS,NC,NC,    0x1b,K_h,NC,  0x1b,0x4e,K_H},
                    250: {K_j,NC,NC,     K_J,NC,NC,      K_LF,NC,NC,    0x1b,K_j,NC,  0x1b,0x4e,K_J},
                    251: {K_k,NC,NC,     K_K,NC,NC,      K_VT,NC,NC,    0x1b,K_k,NC,  0x1b,0x4e,K_K},
                    252: {K_l,NC,NC,     K_L,NC,NC,      K_FF,NC,NC,    0x1b,K_l,NC,  0x1b,0x4e,K_L},
                    253: {K_SEMI,NC,NC,  K_COLON,NC,NC,  K_SEMI,NC,NC,  0x1b,K_SEMI,NC,  0x1b,0x4e,K_COLON},
                    254: {K_SQUOTE,NC,NC,K_DQUOTE,NC,NC, K_SQUOTE,NC,NC,0x1b,K_SQUOTE,NC,  0x1b,0x4e,K_DQUOTE},
                    255: {K_GRAV,NC,NC,  K_TILDE,NC,NC,  K_RS,NC,NC,    0x1b,K_GRAV,NC,  0x1b,0x4e,K_TILDE},
1.1.1.5   root      256: {K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC},
1.1.1.4   root      257: {K_BSLSH,NC,NC, K_PIPE,NC,NC,   K_FS,NC,NC,    0x1b,K_BSLSH,NC,  0x1b,0x4e,K_PIPE},
                    258: {K_z,NC,NC,     K_Z,NC,NC,      K_SUB,NC,NC,   0x1b,K_z,NC,  0x1b,0x4e,K_Z},
                    259: {K_x,NC,NC,     K_X,NC,NC,      K_CAN,NC,NC,   0x1b,K_x,NC,  0x1b,0x4e,K_X},
                    260: {K_c,NC,NC,     K_C,NC,NC,      K_ETX,NC,NC,   0x1b,K_c,NC,  0x1b,0x4e,K_C},
                    261: {K_v,NC,NC,     K_V,NC,NC,      K_SYN,NC,NC,   0x1b,K_v,NC,  0x1b,0x4e,K_V},
                    262: {K_b,NC,NC,     K_B,NC,NC,      K_STX,NC,NC,   0x1b,K_b,NC,  0x1b,0x4e,K_B},
                    263: {K_n,NC,NC,     K_N,NC,NC,      K_SO,NC,NC,    0x1b,K_n,NC,  0x1b,0x4e,K_N},
                    264: {K_m,NC,NC,     K_M,NC,NC,      K_CR,NC,NC,    0x1b,K_m,NC,  0x1b,0x4e,K_M},
                    265: {K_COMMA,NC,NC, K_LTHN,NC,NC,   K_COMMA,NC,NC, 0x1b,K_COMMA,NC,  0x1b,0x4e,K_LTHN},
                    266: {K_PERIOD,NC,NC,K_GTHN,NC,NC,   K_PERIOD,NC,NC,0x1b,K_PERIOD,NC,  0x1b,0x4e,K_GTHN},
                    267: {K_SLASH,NC,NC, K_QUES,NC,NC,   K_SLASH,NC,NC, 0x1b,K_SLASH,NC,  0x1b,0x4e,K_QUES},
1.1.1.5   root      268: {K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC},
1.1.1.4   root      269: {K_ASTER,NC,NC, K_ASTER,NC,NC,  K_ASTER,NC,NC, 0x1b,K_ASTER,NC, 0x1b,0x4e,K_ASTER},
1.1.1.5   root      270: {K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC},
1.1.1.2   root      271: {K_SPACE,NC,NC, K_SPACE,NC,NC,  K_NUL,NC,NC,   0x1b,K_SPACE,NC, K_SPACE,NC,NC},
1.1.1.5   root      272: {K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC},
1.1.1.2   root      273: {K_F1,  K_F1S,  K_F1,  K_F1A,  K_F1S},
                    274: {K_F2,  K_F2S,  K_F2,  K_F2A,  K_F2S},
                    275: {K_F3,  K_F3S,  K_F3,  K_F3A,  K_F3S},
                    276: {K_F4,  K_F4S,  K_F4,  K_F4A,  K_F4S},
                    277: {K_F5,  K_F5S,  K_F5,  K_F5A,  K_F5S},
                    278: {K_F6,  K_F6S,  K_F6,  K_F6A,  K_F6S},
                    279: {K_F7,  K_F7S,  K_F7,  K_F7A,  K_F7S},
                    280: {K_F8,  K_F8S,  K_F8,  K_F8A,  K_F8S},
                    281: {K_F9,  K_F9S,  K_F9,  K_F9A,  K_F9S},
                    282: {K_F10, K_F10S, K_F10, K_F10A, K_F10S},
1.1.1.5   root      283: {K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC},
1.1.1.2   root      284: {K_SCRL,         K_NUL,NC,NC,    K_SCRL,        K_SCRL,      K_NUL,NC,NC},
1.1.1.4   root      285: {K_HOME,         K_SEVEN,NC,NC,  K_HOME,        K_HOME,      0x1b,0x4e,K_SEVEN},
                    286: {K_UA,           K_EIGHT,NC,NC,  K_UA,          K_UA,        0x1b,0x4e,K_EIGHT},
                    287: {K_PUP,          K_NINE,NC,NC,   K_PUP,         K_PUP,       0x1b,0x4e,K_NINE},
1.1.1.5   root      288: {0x1b,0x5b,0x53, K_MINUS,NC,NC,  0x1b,0x5b,0x53, 0x1b,0x5b,0x53, 0x1b,0x4e,0x2d},
1.1.1.4   root      289: {K_LA,           K_FOUR,NC,NC,   K_LA,          K_LA,        0x1b,0x4e,K_FOUR},
1.1.1.5   root      290: {0x1b,0x5b,0x47, K_FIVE,NC,NC,   0x1b,0x5b,0x47, 0x1b,0x5b,0x47, 0x1b,0x4e,0x35},
1.1.1.4   root      291: {K_RA,           K_SIX,NC,NC,    K_RA,          K_RA,        0x1b,0x4e,K_SIX},
1.1.1.5   root      292: {0x1b,0x5b,0x54, K_PLUS,NC,NC,   0x1b,0x5b,0x54, 0x1b,0x5b,0x54, 0x1b,0x4e,0x2b},
1.1.1.4   root      293: {K_END,          K_ONE,NC,NC,    K_END,         K_END,       0x1b,0x4e,K_ONE},
                    294: {K_DA,           K_TWO,NC,NC,    K_DA,          K_DA,        0x1b,0x4e,K_TWO},
                    295: {K_PDN,          K_THREE,NC,NC,  K_PDN,         K_PDN,       0x1b,0x4e,K_THREE},
                    296: {K_INS,          K_ZERO,NC,NC,   K_INS,         K_INS,       0x1b,0x4e,K_ZERO},
                    297: {0x1b,0x5b,0x39, K_PERIOD,NC,NC, K_DEL,NC,NC,   K_DEL,NC,NC, 0x1b,0x4e,K_PERIOD},
1.1.1.2   root      298: {NC,NC,NC,       NC,NC,NC,       NC,NC,NC,      NC,NC,NC,    NC,NC,NC},
                    299: {NC,NC,NC,       NC,NC,NC,       NC,NC,NC,      NC,NC,NC,    NC,NC,NC},
                    300: {NC,NC,NC,       NC,NC,NC,       NC,NC,NC,      NC,NC,NC,    NC,NC,NC},
                    301: {K_F11,          K_F11S,         K_F11,         K_F11A,      K_F11S},
                    302: {K_F12,          K_F12S,         K_F12,         K_F12A,      K_F12S}
1.1       root      303: };
                    304: 
                    305: 
                    306: /*
                    307:  * Globals used only for character-based controllers.
                    308:  */
                    309: 
                    310: short  kd_index_reg    = EGA_IDX_REG;
                    311: short  kd_io_reg       = EGA_IO_REG;
                    312: 
                    313: 
                    314: /*
                    315:  * Globals used only for bitmap-based controllers.  See kdsoft.h for
                    316:  * an explanation of what some of these variables are used for.
                    317:  */
                    318: 
                    319: u_char *font_start     = 0;            /* starting addr of font */
                    320: 
                    321: short  fb_width        = 0;            /* bits in frame buffer scan line */
                    322: short  fb_height       = 0;            /* scan lines in frame buffer*/
                    323: short  char_width      = 0;            /* bit width of 1 char */
                    324: short  char_height     = 0;            /* bit height of 1 char */
                    325: short  chars_in_font   = 0;
                    326: short  cursor_height   = 0;            /* bit height of cursor */
                    327: 
                    328: /* These initial values are simply guesses. */
                    329: u_char char_black      = 0;
                    330: u_char char_white      = 0xff;
                    331: 
                    332: short  xstart          = 0;
                    333: short  ystart          = 0;
                    334: 
                    335: short  char_byte_width = 0;            /* char_width/NBBY */
                    336: short  fb_byte_width   = 0;            /* fb_width/NBBY */
                    337: short  font_byte_width = 0;            /* num bytes in 1 scan line of font */
                    338: 
                    339: /*
                    340:  * Switch for poll vs. interrupt.
                    341:  */
                    342: int    kd_pollc = 0;
                    343: 
                    344: #ifdef DEBUG
1.1.1.3   root      345: /*
1.1       root      346:  * feep:
                    347:  *
1.1.1.3   root      348:  *     Ring the bell for a short time.
1.1       root      349:  *     Warning: uses outb(). You may prefer to use kd_debug_put.
                    350:  */
1.1.1.4   root      351: void
1.1.1.5   root      352: feep(void)
1.1       root      353: {
                    354:        int i;
                    355: 
                    356:        kd_bellon();
                    357:        for (i = 0; i < 50000; ++i)
                    358:                ;
1.1.1.4   root      359:        kd_belloff(NULL);
1.1       root      360: }
                    361: 
1.1.1.4   root      362: void
1.1.1.5   root      363: pause(void)
1.1       root      364: {
                    365:        int i;
                    366: 
                    367:        for (i = 0; i < 50000; ++i)
                    368:                ;
                    369: }
                    370: 
1.1.1.3   root      371: /*
1.1       root      372:  * Put a debugging character on the screen.
1.1.1.3   root      373:  * LOC=0 means put it in the bottom right corner, LOC=1 means put it
1.1       root      374:  * one column to the left, etc.
                    375:  */
1.1.1.4   root      376: void
1.1.1.5   root      377: kd_debug_put(
                    378:        int     loc,
                    379:        char    c)
1.1       root      380: {
                    381:        csrpos_t pos = ONE_PAGE - (loc+1) * ONE_SPACE;
                    382: 
                    383:        (*kd_dput)(pos, c, KA_NORMAL);
                    384: }
                    385: #endif /* DEBUG */
                    386: 
                    387: 
1.1.1.5   root      388: extern boolean_t       mouse_in_use;
                    389: int                    old_kb_mode;
1.1       root      390: 
1.1.1.4   root      391: void
1.1.1.5   root      392: cnpollc(boolean_t on)
1.1       root      393: {
                    394:        if (mouse_in_use) {
                    395:                if (on) {
                    396:                    /* switch into X */
                    397:                    old_kb_mode = kb_mode;
                    398:                    kb_mode = KB_ASCII;
                    399:                    X_kdb_enter();
                    400: 
                    401:                    kd_pollc++;
                    402:                } else {
                    403:                    --kd_pollc;
                    404: 
                    405:                    /* switch out of X */
                    406:                    X_kdb_exit();
                    407:                    kb_mode = old_kb_mode;
                    408:                }
                    409:        } else {
                    410:                if (on) {
                    411:                    kd_pollc++;
                    412:                } else {
                    413:                    --kd_pollc;
                    414:                }
                    415:        }
                    416: }
                    417: 
                    418: 
                    419: 
                    420: /*
                    421:  * kdopen:
                    422:  *
                    423:  *     This opens the console driver and sets up the tty and other
                    424:  *     rudimentary stuff including calling the line discipline for
                    425:  *     setting up the device independent stuff for a tty driver.
                    426:  *
                    427:  * input:      device number 'dev', and flag
                    428:  *
                    429:  * output:     device is opened and setup
                    430:  *
                    431:  */
1.1.1.4   root      432: int
1.1.1.5   root      433: kdopen(
                    434:        dev_t    dev,
                    435:        int      flag,
                    436:        io_req_t ior)
1.1       root      437: {
                    438:        struct  tty     *tp;
                    439:        spl_t   o_pri;
                    440: 
                    441:        tp = &kd_tty;
                    442:        o_pri = spltty();
                    443:        simple_lock(&tp->t_lock);
                    444:        if (!(tp->t_state & (TS_ISOPEN|TS_WOPEN))) {
                    445:                /* XXX ttychars allocates memory */
                    446:                simple_unlock(&tp->t_lock);
                    447:                ttychars(tp);
                    448:                simple_lock(&tp->t_lock);
                    449:                /*
                    450:                 *      Special support for boot-time rc scripts, which don't
                    451:                 *      stty the console.
1.1.1.3   root      452:                 */
1.1       root      453:                tp->t_oproc = kdstart;
                    454:                tp->t_stop = kdstop;
                    455:                tp->t_ospeed = tp->t_ispeed = B9600;
                    456:                tp->t_flags = ODDP|EVENP|ECHO|CRMOD|XTABS;
                    457:                kdinit();
                    458:        }
                    459:        tp->t_state |= TS_CARR_ON;
                    460:        simple_unlock(&tp->t_lock);
                    461:        splx(o_pri);
                    462:        return (char_open(dev, tp, flag, ior));
                    463: }
                    464: 
                    465: 
                    466: /*
                    467:  * kdclose:
                    468:  *
                    469:  *     This function merely executes the device independent code for
                    470:  *     closing the line discipline.
                    471:  *
                    472:  * input:      device number 'dev', and flag
1.1.1.3   root      473:  *
1.1       root      474:  * output:     device is closed
                    475:  *
                    476:  */
                    477: /*ARGSUSED*/
1.1.1.4   root      478: void
1.1       root      479: kdclose(dev, flag)
1.1.1.5   root      480: dev_t  dev;
1.1       root      481: int    flag;
                    482: {
                    483:        struct  tty     *tp;
                    484: 
                    485:        tp = &kd_tty;
                    486:        {
                    487:            spl_t s = spltty();
                    488:            simple_lock(&tp->t_lock);
                    489:            ttyclose(tp);
                    490:            simple_unlock(&tp->t_lock);
                    491:            splx(s);
                    492:        }
                    493: 
                    494:        return;
                    495: }
                    496: 
                    497: 
                    498: /*
                    499:  * kdread:
                    500:  *
                    501:  *     This function executes the device independent code to read from
                    502:  *     the tty.
                    503:  *
                    504:  * input:      device number 'dev'
                    505:  *
                    506:  * output:     characters are read from tty clists
                    507:  *
                    508:  */
                    509: /*ARGSUSED*/
1.1.1.4   root      510: int
1.1       root      511: kdread(dev, uio)
1.1.1.5   root      512: dev_t  dev;
                    513: io_req_t uio;
1.1       root      514: {
                    515:        struct  tty     *tp;
1.1.1.3   root      516: 
1.1       root      517:        tp = &kd_tty;
                    518:        tp->t_state |= TS_CARR_ON;
                    519:        return((*linesw[kd_tty.t_line].l_read)(tp, uio));
                    520: }
                    521: 
                    522: 
                    523: /*
                    524:  * kdwrite:
                    525:  *
                    526:  *     This function does the device independent write action for this
                    527:  *     console (tty) driver.
                    528:  *
                    529:  * input:      device number 'dev'
                    530:  *
                    531:  * output:     characters are written to tty clists
                    532:  *
                    533:  */
                    534: /*ARGSUSED*/
1.1.1.4   root      535: int
1.1       root      536: kdwrite(dev, uio)
1.1.1.5   root      537: dev_t  dev;
                    538: io_req_t uio;
1.1       root      539: {
                    540:        return((*linesw[kd_tty.t_line].l_write)(&kd_tty, uio));
                    541: }
                    542: 
1.1.1.3   root      543: /*
1.1       root      544:  * Mmap.
                    545:  */
                    546: 
                    547: /*ARGSUSED*/
                    548: int
                    549: kdmmap(dev, off, prot)
                    550:        dev_t dev;
1.1.1.5   root      551:        vm_offset_t off;
                    552:        vm_prot_t prot;
1.1       root      553: {
1.1.1.5   root      554:        if (off >= (128*1024))
1.1       root      555:                return(-1);
                    556: 
                    557:        /* Get page frame number for the page to be mapped. */
                    558:        return(i386_btop(kd_bitmap_start+off));
                    559: }
                    560: 
1.1.1.4   root      561: int
1.1.1.5   root      562: kdportdeath(
                    563:        dev_t           dev,
                    564:        mach_port_t     port)
1.1       root      565: {
1.1.1.4   root      566:        return (tty_portdeath(&kd_tty, (ipc_port_t)port));
1.1       root      567: }
                    568: 
                    569: /*ARGSUSED*/
1.1.1.5   root      570: io_return_t kdgetstat(
                    571:        dev_t           dev,
                    572:        int             flavor,
                    573:        int *           data,           /* pointer to OUT array */
                    574:        natural_t       *count)         /* OUT */
1.1       root      575: {
                    576:        io_return_t     result;
                    577: 
                    578:        switch (flavor) {
                    579:            case KDGSTATE:
                    580:                if (*count < 1)
                    581:                    return (D_INVALID_OPERATION);
                    582:                *data = kd_state;
                    583:                *count = 1;
                    584:                result = D_SUCCESS;
                    585:                break;
                    586: 
                    587:            case KDGKBENT:
                    588:                result = kdgetkbent((struct kbentry *)data);
                    589:                *count = sizeof(struct kbentry)/sizeof(int);
                    590:                break;
                    591: 
                    592:            default:
                    593:                result = tty_get_status(&kd_tty, flavor, data, count);
                    594:                break;
                    595:        }
                    596:        return (result);
                    597: }
                    598: 
                    599: /*ARGSUSED*/
1.1.1.5   root      600: io_return_t kdsetstat(
                    601:        dev_t           dev,
                    602:        int             flavor,
                    603:        int *           data,
                    604:        natural_t       count)
1.1       root      605: {
                    606:        io_return_t     result;
                    607: 
                    608:        switch (flavor) {
                    609:            case KDSKBENT:
                    610:                if (count < sizeof(struct kbentry)/sizeof(int)) {
                    611:                    return (D_INVALID_OPERATION);
                    612:                }
                    613:                result = kdsetkbent((struct kbentry *)data, 0);
                    614:                break;
                    615: 
                    616:            case KDSETBELL:
                    617:                if (count < 1)
                    618:                    return (D_INVALID_OPERATION);
                    619:                result = kdsetbell(*data, 0);
                    620:                break;
                    621: 
                    622:            default:
                    623:                result = tty_set_status(&kd_tty, flavor, data, count);
                    624:        }
                    625:        return (result);
                    626: }
                    627: 
                    628: 
                    629: 
1.1.1.3   root      630: /*
1.1       root      631:  * kdsetbell:
1.1.1.3   root      632:  *
                    633:  *     Turn the bell on or off.  Returns error code, if given bogus
1.1       root      634:  *     on/off value.
                    635:  */
1.1.1.4   root      636: int
1.1.1.5   root      637: kdsetbell(
                    638:        int     val,                            /* on or off */
                    639:        int     flags)                          /* flags set for console */
1.1       root      640: {
                    641:        int err = 0;
                    642: 
                    643:        if (val == KD_BELLON)
                    644:                kd_bellon();
                    645:        else if (val == KD_BELLOFF)
1.1.1.4   root      646:                kd_belloff(NULL);
1.1       root      647:        else
                    648:                err = D_INVALID_OPERATION;
                    649: 
                    650:        return(err);
                    651: }
                    652: 
1.1.1.3   root      653: /*
1.1       root      654:  * kdgetkbent:
1.1.1.3   root      655:  *
1.1       root      656:  *     Get entry from key mapping table.  Returns error code, if any.
                    657:  */
1.1.1.4   root      658: int
1.1.1.5   root      659: kdgetkbent(struct kbentry *kbent)
1.1       root      660: {
                    661:        u_char *cp;
                    662:        spl_t o_pri = SPLKD();          /* probably superfluous */
                    663: 
                    664:        cp = &key_map[kbent->kb_index][CHARIDX(kbent->kb_state)];
                    665:        kbent->kb_value[0] = *cp++;
                    666:        kbent->kb_value[1] = *cp++;
                    667:        kbent->kb_value[2] = *cp;
                    668:        (void)splx(o_pri);
                    669:        return(0);
                    670: }
                    671: 
                    672: 
1.1.1.3   root      673: /*
1.1       root      674:  * kdsetkbent:
1.1.1.3   root      675:  *
1.1       root      676:  *     Set entry in key mapping table.  Return error code, if any.
                    677:  */
                    678: int
1.1.1.5   root      679: kdsetkbent(
                    680:        struct kbentry  *kbent,
                    681:        int             flags)                          /* flags set for console */
1.1       root      682: {
                    683:        u_char *cp;
                    684:        spl_t o_pri;
                    685: 
                    686:        o_pri = SPLKD();
                    687:        cp = &key_map[kbent->kb_index][CHARIDX(kbent->kb_state)];
                    688:        *cp++ = kbent->kb_value[0];
                    689:        *cp++ = kbent->kb_value[1];
                    690:        *cp = kbent->kb_value[2];
                    691:        (void)splx(o_pri);
                    692:        return(0);
                    693: }
                    694: 
                    695: /*
                    696:  * kdintr:
                    697:  *
                    698:  *     This function is the interrupt code for the driver.  Since this is
                    699:  *     a special tty (console), interrupts are only for input, so we read in
1.1.1.3   root      700:  *     the character.  If in ascii mode, we then do the mapping translation
                    701:  *     from the keyboard switch table and place the characters on the tty's
1.1       root      702:  *     input switch table.  If in event mode, we create and queue a kd_event.
                    703:  *
                    704:  * input:      interrupt vector 'vec'
                    705:  *
                    706:  * output:     character or sequence is placed on appropriate queue
                    707:  *
                    708:  */
                    709: /*ARGSUSED*/
1.1.1.4   root      710: void
1.1.1.5   root      711: kdintr(int vec)
1.1       root      712: {
                    713:        struct  tty     *tp;
                    714:        unsigned char   c;
                    715:        unsigned char   scancode;
1.1.1.5   root      716:        unsigned int    char_idx;
1.1       root      717:        boolean_t       up = FALSE;             /* key-up event */
1.1.1.5   root      718: 
1.1       root      719:        if (kd_pollc)
                    720:            return;                             /* kdb polling kbd */
                    721: 
1.1.1.4   root      722:        if (!kd_initialized)
                    723:                return;
                    724: 
1.1       root      725:        tp = &kd_tty;
                    726: #ifdef old
1.1.1.5   root      727:        while ((inb(K_STATUS) & K_OBUF_FUL) == 0)
                    728:                ;       /* this should never loop */
1.1.1.3   root      729: #else  /* old */
1.1       root      730:        {
                    731:                /*
1.1.1.3   root      732:                 * Allow for keyboards that raise interrupt before
1.1       root      733:                 * the character gets to the buffer.  But don't wait
                    734:                 * forever if grabbing the character by polling leaves
                    735:                 * the interrupt on but buffer empty.
                    736:                 */
                    737:                /*
1.1.1.3   root      738:                 * Micronics VLB motherboard with 486DX2 can report keyboard
1.1       root      739:                 * interrupt before K_STATUS register indicates that the
                    740:                 * output buffer is full.  Moreover, the bus won't settle w
                    741:                 * while we poll K_STATUS at speed.  Temporary fix is to break
1.1.1.3   root      742:                 * out after safety runs out and pick up keyboard event.  This
                    743:                 * should be fixed eventually by putting a 1us timout between
                    744:                 * inb's to K_STATUS and fix the pic initialization order to
1.1       root      745:                 * avoid bootup keyboard wedging (ie make kd a real device)
                    746:                 */
                    747:                int safety = 1000;
                    748:                while ((inb(K_STATUS) & K_OBUF_FUL) == 0)
                    749:                        if (!safety--) break;  /* XXX */
                    750:        }
1.1.1.3   root      751: #endif /* old */
1.1       root      752:        /*
                    753:         * We may have seen a mouse event.
                    754:         */
                    755:        if ((inb(K_STATUS) & 0x20) == 0x20) {
                    756:                if (mouse_in_use) {
                    757:                        mouse_handle_byte((u_char)inb(K_RDWR));
                    758:                        return;
                    759:                } else {
                    760:                        printf("M%xI", inb(K_RDWR));
                    761:                        return;
                    762:                }
                    763:        }
                    764: 
                    765:        scancode = inb(K_RDWR);
1.1.1.3   root      766:        if (scancode == K_EXTEND && kb_mode != KB_EVENT) {
                    767:                kd_extended = TRUE;
1.1       root      768:                goto done;
                    769:        } else if (scancode == K_RESEND) {
                    770:                kd_resend();
                    771:                goto done;
                    772:        } else if (scancode == K_ACKSC) {
                    773:                kd_handle_ack();
                    774:                goto done;
                    775:        } else if (kd_kbd_mouse && kd_kbd_magic(scancode)) {
                    776:                goto done;
1.1.1.4   root      777:        } else if (kdcheckmagic(scancode)) {
1.1       root      778:                goto done;
                    779:        } else if (kb_mode == KB_EVENT) {
                    780:                kd_enqsc(scancode);
                    781:                goto done;
                    782:        } /* else... */
                    783: 
                    784:        if (scancode & K_UP) {
                    785:                up = TRUE;
                    786:                scancode &= ~K_UP;
                    787:        }
                    788:        if (scancode < NUMKEYS) {
                    789:                /* Lookup in map, then process. */
                    790:                char_idx = kdstate2idx(kd_state, kd_extended);
                    791:                c = key_map[scancode][char_idx];
                    792:                if (c == K_SCAN) {
                    793:                        c = key_map[scancode][++char_idx];
                    794:                        set_kd_state(do_modifier(kd_state, c, up));
                    795:                } else if (!up) {
                    796:                        /* regular key-down */
1.1.1.5   root      797:                        unsigned int max; /* max index for char sequence */
1.1       root      798: 
                    799:                        max = char_idx + NUMOUTPUT;
                    800:                        char_idx++;
                    801:                        if (!kd_extended) {
                    802:                                if (kd_state&KS_CLKED) {
                    803:                                        if (kd_isupper(c)) {
                    804:                                                c += ('a' - 'A');
                    805:                                                max = char_idx;
                    806:                                        }
                    807:                                        else if (kd_islower(c)) {
                    808:                                                c -= ('a' - 'A');
                    809:                                                max = char_idx;
                    810:                                        }
                    811:                                }
                    812:                                /*
                    813:                                 * Notice that even if the keypad is remapped,
                    814:                                 * NumLock only effects the keys that are
                    815:                                 * physically part of the keypad.  Is this
                    816:                                 * The Right Thing?
                    817:                                 */
                    818:                                if ((kd_state&KS_NLKED) &&
                    819:                                    (((K_HOMESC) <= scancode) &&
                    820:                                    (scancode <= (K_DELSC)))) {
                    821:                                        char_idx = CHARIDX(SHIFT_STATE);
                    822:                                        c = key_map[scancode][char_idx];
                    823:                                        max = char_idx + NUMOUTPUT;
                    824:                                        char_idx++;
                    825:                                }
                    826:                        }
                    827: 
1.1.1.3   root      828:                        /*
1.1       root      829:                         * here's where we actually put the char (or
                    830:                         * char sequence, for function keys) onto the
                    831:                         * input queue.
                    832:                         */
1.1.1.3   root      833:                        for ( ; (c != K_DONE) && (char_idx <= max);
                    834:                             c = key_map[scancode][char_idx++]) {
1.1       root      835:                                (*linesw[tp->t_line].l_rint)(c, tp);
                    836:                        }
                    837:                        kd_extended = FALSE;
                    838:                }
                    839:        }
                    840: 
                    841:  done:
                    842:        return;
                    843: }
                    844: 
1.1.1.3   root      845: /*
1.1       root      846:  * kd_handle_ack:
1.1.1.3   root      847:  *
                    848:  *     For pending commands, complete the command.  For data bytes,
1.1       root      849:  *     drop the ack on the floor.
                    850:  */
1.1.1.4   root      851: void
1.1.1.5   root      852: kd_handle_ack(void)
1.1       root      853: {
                    854:        switch (kd_ack) {
                    855:        case SET_LEDS:
                    856:                kd_setleds2();
                    857:                kd_ack = DATA_ACK;
                    858:                break;
                    859:        case DATA_ACK:
                    860:                kd_ack = NOT_WAITING;
                    861:                break;
                    862:        case NOT_WAITING:
                    863:                printf("unexpected ACK from keyboard\n");
                    864:                break;
                    865:        default:
                    866:                panic("bogus kd_ack\n");
                    867:                break;
                    868:        }
                    869: }
                    870: 
1.1.1.3   root      871: /*
1.1       root      872:  * kd_resend:
                    873:  *
                    874:  *     Resend a missed keyboard command or data byte.
                    875:  */
1.1.1.4   root      876: void
1.1.1.5   root      877: kd_resend(void)
1.1       root      878: {
1.1.1.3   root      879:        if (kd_ack == NOT_WAITING)
1.1       root      880:                printf("unexpected RESEND from keyboard\n");
                    881:        else
                    882:                kd_senddata(last_sent);
                    883: }
                    884: 
                    885: 
                    886: /*
                    887:  * do_modifier:
                    888:  *
                    889:  *     Change keyboard state according to which modifier key and
                    890:  *     whether it went down or up.
                    891:  *
1.1.1.3   root      892:  * input:      the current state, the key, and the key's direction.
1.1       root      893:  *             The key can be any key, not just a modifier key.
1.1.1.3   root      894:  *
1.1       root      895:  * output:     the new state
                    896:  */
1.1.1.4   root      897: int
1.1.1.5   root      898: do_modifier(
                    899:        int             state,
                    900:        Scancode        c,
                    901:        boolean_t       up)
1.1       root      902: {
                    903:        switch (c) {
                    904:        case (K_ALTSC):
                    905:                if (up)
                    906:                        state &= ~KS_ALTED;
                    907:                else
                    908:                        state |= KS_ALTED;
                    909:                kd_extended = FALSE;
                    910:                break;
                    911: #ifndef        ORC
                    912:        case (K_CLCKSC):
1.1.1.3   root      913: #endif /* ORC */
1.1       root      914:        case (K_CTLSC):
                    915:                if (up)
                    916:                        state &= ~KS_CTLED;
                    917:                else
                    918:                        state |= KS_CTLED;
                    919:                kd_extended = FALSE;
                    920:                break;
                    921: #ifdef ORC
                    922:        case (K_CLCKSC):
                    923:                if (!up)
                    924:                        state ^= KS_CLKED;
                    925:                break;
1.1.1.3   root      926: #endif /* ORC */
1.1       root      927:        case (K_NLCKSC):
                    928:                if (!up)
                    929:                        state ^= KS_NLKED;
                    930:                break;
                    931:        case (K_LSHSC):
                    932:        case (K_RSHSC):
                    933:                if (up)
                    934:                        state &= ~KS_SHIFTED;
                    935:                else
                    936:                        state |= KS_SHIFTED;
                    937:                kd_extended = FALSE;
                    938:                break;
                    939:        }
                    940: 
                    941:        return(state);
                    942: }
                    943: 
                    944: 
1.1.1.3   root      945: /*
1.1       root      946:  * kdcheckmagic:
1.1.1.3   root      947:  *
                    948:  *     Check for magic keystrokes for invoking the debugger or
1.1       root      949:  *     rebooting or ...
                    950:  *
                    951:  * input:      an unprocessed scancode
1.1.1.3   root      952:  *
                    953:  * output:     TRUE if a magic key combination was recognized and
1.1       root      954:  *             processed.  FALSE otherwise.
                    955:  *
1.1.1.3   root      956:  * side effects:
1.1       root      957:  *             various actions possible, depending on which keys are
1.1.1.3   root      958:  *             pressed.  If the debugger is called, steps are taken
                    959:  *             to ensure that the system doesn't think the magic keys
1.1       root      960:  *             are still held down.
                    961:  */
                    962: boolean_t
1.1.1.5   root      963: kdcheckmagic(Scancode scancode)
1.1       root      964: {
                    965:        static int magic_state = KS_NORMAL; /* like kd_state */
                    966:        boolean_t up = FALSE;
                    967: 
                    968:        if (scancode == 0x46)           /* scroll lock */
                    969: /*     if (scancode == 0x52)           ** insert key */
                    970:        {
                    971:                kd_kbd_mouse = !kd_kbd_mouse;
                    972:                kd_kbd_magic_button = 0;
                    973:                return(TRUE);
                    974:        }
                    975:        if (scancode & K_UP) {
                    976:                up = TRUE;
                    977:                scancode &= ~K_UP;
                    978:        }
                    979:        magic_state = do_modifier(magic_state, scancode, up);
                    980: 
                    981:        if ((magic_state&(KS_CTLED|KS_ALTED)) == (KS_CTLED|KS_ALTED)) {
                    982:                switch (scancode) {
                    983: #if    MACH_KDB
                    984:                case K_dSC:             /*  ctl-alt-d */
                    985:                        kdb_kintr();    /* invoke debugger */
                    986:                        /* Returned from debugger, so reset kbd state. */
                    987:                        (void)SPLKD();
                    988:                        magic_state = KS_NORMAL;
                    989:                        if (kb_mode == KB_ASCII)
                    990:                                kd_state = KS_NORMAL;
                    991:                                /* setting leds kills kbd */
                    992:                        else {
                    993:                                kd_enqsc(K_ALTSC | K_UP);
                    994:                                kd_enqsc(K_CTLSC | K_UP);
                    995:                                kd_enqsc(K_dSC | K_UP);
                    996:                        }
                    997:                        return(TRUE);
                    998:                        break;
1.1.1.3   root      999: #endif /* MACH_KDB */
1.1       root     1000:                case K_DELSC:           /* ctl-alt-del */
                   1001:                        /* if rebootflag is on, reboot the system */
                   1002:                        if (rebootflag)
                   1003:                                kdreboot();
                   1004:                        break;
                   1005:                }
                   1006:        }
                   1007:        return(FALSE);
                   1008: }
                   1009: 
                   1010: 
                   1011: /*
                   1012:  * kdstate2idx:
                   1013:  *
1.1.1.3   root     1014:  *     Return the value for the 2nd index into key_map that
1.1       root     1015:  *     corresponds to the given state.
                   1016:  */
1.1.1.5   root     1017: unsigned int
1.1       root     1018: kdstate2idx(state, extended)
1.1.1.5   root     1019: unsigned int   state;                  /* bit vector, not a state index */
1.1       root     1020: boolean_t      extended;
                   1021: {
                   1022:        int state_idx = NORM_STATE;
                   1023: 
                   1024:        if ((!extended) && state != KS_NORMAL) {
                   1025:                if ((state&(KS_SHIFTED|KS_ALTED)) == (KS_SHIFTED|KS_ALTED))
                   1026:                        state_idx = SHIFT_ALT;
1.1.1.2   root     1027:                 /* CTRL should have higher priority than SHIFT.  That
                   1028:                    way, CTRL-SHIFT-2 and CTRL-2 produce the same keycode.
                   1029:                    --Derek Upham 1997/06/25 */
                   1030:                else if (state&KS_CTLED)
                   1031:                        state_idx = CTRL_STATE;
1.1       root     1032:                else if (state&KS_SHIFTED)
                   1033:                        state_idx = SHIFT_STATE;
                   1034:                else if (state&KS_ALTED)
                   1035:                        state_idx = ALT_STATE;
                   1036:        }
                   1037: 
                   1038:        return (CHARIDX(state_idx));
                   1039: }
                   1040: 
                   1041: /*
                   1042:  * kdstart:
                   1043:  *
                   1044:  *     This function does the general processing of characters and other
                   1045:  *     operations for the device driver.  The device independent portion of
                   1046:  *     the tty driver calls this routine (it's setup in kdinit) with a
                   1047:  *     given command.  That command is then processed, and control is passed
                   1048:  *     back to the kernel.
                   1049:  *
                   1050:  * input:      tty pointer 'tp', and command to execute 'cmd'
                   1051:  *
                   1052:  * output:     command is executed
                   1053:  *
                   1054:  * Entered and left at spltty.  Drops priority to spl0 to display character.
                   1055:  * ASSUMES that it is never called from interrupt-driven code.
                   1056:  */
1.1.1.4   root     1057: void
1.1.1.5   root     1058: kdstart(struct tty *tp)
1.1       root     1059: {
                   1060:        spl_t   o_pri;
                   1061:        int     ch;
1.1.1.3   root     1062: 
1.1       root     1063:        if (tp->t_state & TS_TTSTOP)
                   1064:                return;
                   1065:        for ( ; ; ) {
1.1.1.3   root     1066:                tp->t_state &= ~TS_BUSY;
1.1       root     1067:                if (tp->t_state & TS_TTSTOP)
                   1068:                        break;
                   1069:                if ((tp->t_outq.c_cc <= 0) || (ch = getc(&tp->t_outq)) == -1)
                   1070:                        break;
                   1071:                /*
                   1072:                 * Drop priority for long screen updates. ttstart() calls us at
                   1073:                 * spltty.
                   1074:                 */
                   1075:                o_pri = splsoftclock();         /* block timeout */
1.1.1.6 ! root     1076:                kd_putc_esc(ch);
1.1       root     1077:                splx(o_pri);
                   1078:        }
                   1079:        if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
                   1080:                tt_write_wakeup(tp);
                   1081:        }
                   1082: }
                   1083: 
                   1084: /*ARGSUSED*/
1.1.1.4   root     1085: void
1.1.1.5   root     1086: kdstop(
                   1087:        struct tty      *tp,
                   1088:        int             flags)
1.1       root     1089: {
                   1090:        /*
                   1091:         * do nothing - all characters are output by one call to
                   1092:         * kdstart.
                   1093:         */
                   1094: }
                   1095: 
                   1096: /*
                   1097:  * kdinit:
                   1098:  *
                   1099:  *     This code initializes the structures and sets up the port registers
1.1.1.3   root     1100:  *     for the console driver.
1.1       root     1101:  *
                   1102:  *     Each bitmap-based graphics card is likely to require a unique
                   1103:  *     way to determine the card's presence.  The driver runs through
                   1104:  *     each "special" card that it knows about and uses the first one
                   1105:  *     that it finds.  If it doesn't find any, it assumes that an
                   1106:  *     EGA-like card is installed.
                   1107:  *
                   1108:  * input       : None. Interrupts are assumed to be disabled
                   1109:  * output      : Driver is initialized
                   1110:  *
                   1111:  */
1.1.1.4   root     1112: void
1.1.1.5   root     1113: kdinit(void)
1.1       root     1114: {
                   1115:        unsigned char   k_comm;         /* keyboard command byte */
                   1116: 
                   1117:        if (kd_initialized)
                   1118:                return;
                   1119: 
                   1120:        esc_spt = esc_seq;
                   1121:        kd_attr = KA_NORMAL;
                   1122: 
1.1.1.3   root     1123:        kd_attrflags = 0;
                   1124:        kd_color = KA_NORMAL;
1.1       root     1125:        /*
                   1126:         * board specific initialization: set up globals and kd_dxxx
                   1127:         * pointers, and synch displayed cursor with logical cursor.
                   1128:         */
1.1.1.4   root     1129:        kd_xga_init();
1.1       root     1130: 
                   1131:        /* get rid of any garbage in output buffer */
                   1132:        if (inb(K_STATUS) & K_OBUF_FUL)
                   1133:                (void)inb(K_RDWR);
                   1134: 
                   1135:        kd_sendcmd(KC_CMD_READ);        /* ask for the ctlr command byte */
                   1136:        k_comm = kd_getdata();
                   1137:        k_comm &= ~K_CB_DISBLE;         /* clear keyboard disable bit */
                   1138:        k_comm |= K_CB_ENBLIRQ;         /* enable interrupt */
                   1139:        kd_sendcmd(KC_CMD_WRITE);       /* write new ctlr command byte */
                   1140:        kd_senddata(k_comm);
                   1141:        kd_initialized = TRUE;
                   1142: 
1.1.1.6 ! root     1143: #if    ENABLE_IMMEDIATE_CONSOLE
1.1       root     1144:        /* Now that we're set up, we no longer need or want the
                   1145:            immediate console.  */
                   1146:        {
1.1.1.5   root     1147:                extern boolean_t immediate_console_enable;
                   1148:                immediate_console_enable = FALSE;
1.1       root     1149:        }
                   1150: 
                   1151:        /* The immediate console printed stuff at the bottom of the
                   1152:           screen rather than at the cursor position, so that's where
                   1153:           we should start.  */
                   1154:        kd_setpos(ONE_PAGE - ONE_LINE); printf("\n");
1.1.1.5   root     1155: #endif /* ENABLE_IMMEDIATE_CONSOLE */
1.1       root     1156: 
                   1157:        cnsetleds(kd_state = KS_NORMAL);
                   1158:                                        /* clear the LEDs AFTER we
                   1159:                                           enable the keyboard controller.
                   1160:                                           This keeps NUM-LOCK from being
                   1161:                                           set on the NEC Versa. */
1.1.1.4   root     1162: 
                   1163:        /* Allocate the input buffer.  */
                   1164:        ttychars(&kd_tty);
1.1       root     1165: }
                   1166: 
                   1167: /*
                   1168:  * kd_belloff:
                   1169:  *
                   1170:  *     This routine shuts the bell off, by sending the appropriate code
                   1171:  *     to the speaker port.
                   1172:  *
                   1173:  * input       : None
                   1174:  * output      : bell is turned off
                   1175:  *
                   1176:  */
1.1.1.5   root     1177: static boolean_t kd_bellstate = FALSE;
1.1.1.4   root     1178: 
                   1179: void
                   1180: kd_belloff(void * param)
1.1       root     1181: {
                   1182:        unsigned char status;
                   1183: 
                   1184:        status = (inb(K_PORTB) & ~(K_SPKRDATA | K_ENABLETMR2));
                   1185:        outb(K_PORTB, status);
1.1.1.5   root     1186:        kd_bellstate = FALSE;
1.1       root     1187:        return;
                   1188: }
                   1189: 
                   1190: 
                   1191: /*
                   1192:  * kd_bellon:
                   1193:  *
                   1194:  *     This routine turns the bell on.
                   1195:  *
                   1196:  * input       : None
                   1197:  * output      : bell is turned on
                   1198:  *
                   1199:  */
1.1.1.4   root     1200: void
1.1.1.5   root     1201: kd_bellon(void)
1.1       root     1202: {
                   1203:        unsigned char   status;
                   1204: 
                   1205:        /* program timer 2 */
                   1206:        outb(K_TMRCTL, K_SELTMR2 | K_RDLDTWORD | K_TSQRWAVE | K_TBINARY);
                   1207:        outb(K_TMR2, 1500 & 0xff);      /* LSB */
                   1208:        outb(K_TMR2, (int)1500 >> 8);   /* MSB */
                   1209: 
                   1210:        /* start speaker - why must we turn on K_SPKRDATA? */
                   1211:        status = (inb(K_PORTB)| K_ENABLETMR2 | K_SPKRDATA);
                   1212:        outb(K_PORTB, status);
                   1213:        return;
                   1214: }
                   1215: 
                   1216: /*
                   1217:  *
1.1.1.6 ! root     1218:  * Function kd_putc_esc():
        !          1219:  *
        !          1220:  *     This function puts a character on the screen, handling escape
        !          1221:  *     sequences.
        !          1222:  *
        !          1223:  * input       : character to be displayed (or part of an escape code)
        !          1224:  * output      : character is displayed, or some action is taken
        !          1225:  *
        !          1226:  */
        !          1227: void
        !          1228: kd_putc_esc(u_char c)
        !          1229: {
        !          1230:        if (c == (K_ESC)) {
        !          1231:                if (esc_spt == esc_seq) {
        !          1232:                        *(esc_spt++)=(K_ESC);
        !          1233:                        *(esc_spt) = '\0';
        !          1234:                } else {
        !          1235:                        kd_putc((K_ESC));
        !          1236:                        esc_spt = esc_seq;
        !          1237:                }
        !          1238:        } else {
        !          1239:                if (esc_spt - esc_seq) {
        !          1240:                        if (esc_spt - esc_seq > K_MAXESC - 1)
        !          1241:                                esc_spt = esc_seq;
        !          1242:                        else {
        !          1243:                                *(esc_spt++) = c;
        !          1244:                                *(esc_spt) = '\0';
        !          1245:                                kd_parseesc();
        !          1246:                        }
        !          1247:                } else {
        !          1248:                        kd_putc(c);
        !          1249:                }
        !          1250:        }
        !          1251: }
        !          1252: 
        !          1253: /*
        !          1254:  *
1.1       root     1255:  * Function kd_putc():
                   1256:  *
                   1257:  *     This function simply puts a character on the screen.  It does some
                   1258:  *     special processing for linefeed, carriage return, backspace and
                   1259:  *     the bell.
                   1260:  *
                   1261:  * input       : character to be displayed
                   1262:  * output      : character is displayed, or some action is taken
                   1263:  *
                   1264:  */
                   1265: int sit_for_0 = 1;
                   1266: 
1.1.1.4   root     1267: void
1.1.1.5   root     1268: kd_putc(u_char ch)
1.1       root     1269: {
                   1270:        if ((!ch) && sit_for_0)
                   1271:                return;
                   1272: 
1.1.1.3   root     1273:        switch (ch) {
1.1       root     1274:        case ((K_LF)):
                   1275:                kd_down();
                   1276:                break;
1.1.1.3   root     1277:        case ((K_CR)):
1.1       root     1278:                kd_cr();
                   1279:                break;
                   1280:        case ((K_BS)):
                   1281:                kd_left();
                   1282:                break;
                   1283:        case ((K_HT)):
                   1284:                kd_tab();
                   1285:                break;
                   1286:        case ((K_BEL)):
                   1287:                /*
                   1288:                 * Similar problem to K_BS here (behavior might depend
                   1289:                 * on tty setting).  Also check LF and CR.
                   1290:                 */
                   1291:                if (!kd_bellstate)
                   1292:                  {
                   1293:                    kd_bellon();
                   1294:                    timeout(kd_belloff, 0, hz/8 );
1.1.1.5   root     1295:                    kd_bellstate = TRUE;
1.1       root     1296:                  }
                   1297:                break;
                   1298:        default:
                   1299:                (*kd_dput)(kd_curpos, ch, kd_attr);
                   1300:                kd_right();
                   1301:                break;
                   1302:        }
                   1303:        return;
                   1304: }
                   1305: 
                   1306: 
                   1307: /*
                   1308:  * kd_setpos:
                   1309:  *
                   1310:  *     This function sets the software and hardware cursor position
                   1311:  *     on the screen, using device-specific code to actually move and
                   1312:  *     display the cursor.
                   1313:  *
                   1314:  * input       : position on (or off) screen to move the cursor to
                   1315:  * output      : cursor position is updated, screen has been scrolled
                   1316:  *               if necessary to bring cursor position back onto
                   1317:  *               screen.
                   1318:  *
                   1319:  */
1.1.1.4   root     1320: void
1.1.1.5   root     1321: kd_setpos(csrpos_t newpos)
1.1       root     1322: {
                   1323:        if (newpos > ONE_PAGE) {
                   1324:                kd_scrollup();
                   1325:                newpos = BOTTOM_LINE;
                   1326:        }
                   1327:        if (newpos < 0) {
                   1328:                kd_scrolldn();
                   1329:                newpos = 0;
                   1330:        }
                   1331: 
                   1332:        (*kd_dsetcursor)(newpos);
                   1333: }
                   1334: 
                   1335: 
                   1336: /*
                   1337:  * kd_scrollup:
                   1338:  *
                   1339:  *     This function scrolls the screen up one line using a DMA memory
                   1340:  *     copy.
                   1341:  *
                   1342:  * input       : None
                   1343:  * output      : lines on screen appear to be shifted up one line
                   1344:  *
                   1345:  */
1.1.1.4   root     1346: void
1.1.1.5   root     1347: kd_scrollup(void)
1.1       root     1348: {
                   1349:        csrpos_t to;
                   1350:        csrpos_t from;
                   1351:        int     count;
                   1352: 
                   1353:        /* scroll up */
                   1354:        to = 0;
                   1355:        from = ONE_LINE;
                   1356:        count = (ONE_PAGE - ONE_LINE)/ONE_SPACE;
                   1357:        (*kd_dmvup)(from, to, count);
                   1358: 
                   1359:        /* clear bottom line */
                   1360:        to = BOTTOM_LINE;
                   1361:        count = ONE_LINE/ONE_SPACE;
                   1362:        (*kd_dclear)(to, count, kd_attr);
                   1363:        return;
                   1364: }
                   1365: 
                   1366: 
                   1367: /*
                   1368:  * kd_scrolldn:
                   1369:  *
                   1370:  *     Scrolls the characters on the screen down one line.
                   1371:  *
                   1372:  * input       : None
                   1373:  * output      : Lines on screen appear to be moved down one line
                   1374:  *
                   1375:  */
1.1.1.4   root     1376: void
1.1.1.5   root     1377: kd_scrolldn(void)
1.1       root     1378: {
                   1379:        csrpos_t to;
                   1380:        csrpos_t from;
                   1381:        int     count;
                   1382: 
                   1383:        /* move down */
                   1384:        to      = ONE_PAGE - ONE_SPACE;
                   1385:        from    = ONE_PAGE - ONE_LINE - ONE_SPACE;
                   1386:        count   = (ONE_PAGE - ONE_LINE) / ONE_SPACE;
                   1387:        (*kd_dmvdown)(from, to, count);
                   1388: 
                   1389:        /* clear top line */
                   1390:        to      = 0;
                   1391:        count   = ONE_LINE/ONE_SPACE;
                   1392:        (*kd_dclear)(to, count, kd_attr);
                   1393:        return;
1.1.1.3   root     1394: 
1.1       root     1395: }
                   1396: 
                   1397: 
                   1398: /*
                   1399:  * kd_parseesc:
                   1400:  *
                   1401:  *     This routine begins the parsing of an escape sequence.  It uses the
1.1.1.3   root     1402:  *     escape sequence array and the escape spot pointer to handle
1.1       root     1403:  *     asynchronous parsing of escape sequences.
                   1404:  *
                   1405:  * input       : String of characters prepended by an escape
                   1406:  * output      : Appropriate actions are taken depending on the string as
                   1407:  *               defined by the ansi terminal specification
                   1408:  *
                   1409:  */
1.1.1.4   root     1410: void
1.1.1.5   root     1411: kd_parseesc(void)
1.1       root     1412: {
                   1413:        u_char  *escp;
                   1414: 
                   1415:        escp = esc_seq + 1;             /* point to char following ESC */
                   1416:        switch(*(escp)) {
                   1417:        case 'c':
                   1418:                kd_cls();
                   1419:                kd_home();
                   1420:                esc_spt = esc_seq;  /* reset spot in ESC sequence */
                   1421:                break;
                   1422:        case '[':
                   1423:                escp++;
                   1424:                kd_parserest(escp);
                   1425:                break;
                   1426:        case '\0':
                   1427:                break;                  /* not enough info yet  */
                   1428:        default:
                   1429:                kd_putc(*escp);
                   1430:                esc_spt = esc_seq;      /* inv sequence char, reset */
                   1431:                break;
                   1432:        }
                   1433:        return;
                   1434: 
                   1435: }
                   1436: 
                   1437: 
1.1.1.3   root     1438: /* kd_update_kd_attr:
                   1439:  *
                   1440:  *     Updates kd_attr according to kd_attrflags and kd_color.
                   1441:  * This code has its origin from console.c and selection.h in
                   1442:  * linux 2.2 drivers/char/.
                   1443:  * Modified for GNU Mach by Marcus Brinkmann.
                   1444:  */
                   1445: 
                   1446: #define reverse_video_char(a)       (((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77))
                   1447: void
                   1448: kd_update_kd_attr(void)
                   1449: {
                   1450:        kd_attr = kd_color;
                   1451:        if (kd_attrflags & KAX_UNDERLINE)
                   1452:                kd_attr = (kd_attr & 0xf0) | KAX_COL_UNDERLINE;
                   1453:        else if (kd_attrflags & KAX_DIM)
                   1454:                kd_attr = (kd_attr & 0xf0) | KAX_COL_DIM;
                   1455:        if (kd_attrflags & KAX_REVERSE)
                   1456:                kd_attr = reverse_video_char(kd_attr);
                   1457:        if (kd_attrflags & KAX_BLINK)
                   1458:                kd_attr ^= 0x80;
                   1459:        if (kd_attrflags & KAX_BOLD)
                   1460:                kd_attr ^= 0x08;
                   1461: }      
                   1462: 
                   1463: /* color_table added by Julio Merino to take proper color order.
                   1464:  * I get this code from Linux 2.2 source code in file: 
                   1465:  * linux/drivers/char/console.c
                   1466:  */
                   1467: unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
                   1468:                                       8,12,10,14, 9,13,11,15 };
1.1       root     1469: /*
                   1470:  * kd_parserest:
                   1471:  *
                   1472:  *     This function will complete the parsing of an escape sequence and
                   1473:  *     call the appropriate support routine if it matches a character.  This
                   1474:  *     function could be greatly improved by using a function jump table, and
                   1475:  *     removing this bulky switch statement.
                   1476:  *
                   1477:  * input       : An string
                   1478:  * output      : Appropriate action based on whether the string matches a
                   1479:  *               sequence acceptable to the ansi terminal specification
                   1480:  *
                   1481:  */
1.1.1.4   root     1482: void
1.1.1.5   root     1483: kd_parserest(u_char *cp)
1.1       root     1484: {
1.1.1.3   root     1485:        int     number[16], npar = 0, i;
1.1       root     1486:        csrpos_t newpos;
                   1487: 
1.1.1.3   root     1488:        for(i=0;i<=15;i++)
1.1.1.4   root     1489:                number[i] = MACH_ATOI_DEFAULT;
1.1.1.3   root     1490: 
                   1491:        do {
1.1.1.4   root     1492:                cp += mach_atoi(cp, &number[npar]);
1.1.1.3   root     1493:        } while (*cp == ';' && ++npar <= 15 && cp++);
                   1494:        
1.1       root     1495:        switch(*cp) {
                   1496:        case 'm':
1.1.1.3   root     1497:                for (i=0;i<=npar;i++)
                   1498:                        switch(number[i]) {
1.1.1.4   root     1499:                        case MACH_ATOI_DEFAULT:
1.1.1.3   root     1500:                        case 0:
                   1501:                                kd_attrflags = 0;
                   1502:                                kd_color = KA_NORMAL;
                   1503:                                break;
                   1504:                        case 1:
                   1505:                                kd_attrflags |= KAX_BOLD;
                   1506:                                kd_attrflags &= ~KAX_DIM;
                   1507:                                break;
                   1508:                        case 2:
                   1509:                                kd_attrflags |= KAX_DIM;
                   1510:                                kd_attrflags &= ~KAX_BOLD;
                   1511:                                break;
                   1512:                        case 4:
                   1513:                                kd_attrflags |= KAX_UNDERLINE;
                   1514:                                break;
                   1515:                        case 5:
                   1516:                                kd_attrflags |= KAX_BLINK;
                   1517:                                break;
                   1518:                        case 7:
                   1519:                                kd_attrflags |= KAX_REVERSE;
                   1520:                                break;
                   1521:                        case 8:
                   1522:                                kd_attrflags |= KAX_INVISIBLE;
                   1523:                                break;
                   1524:                        case 21:
                   1525:                        case 22:
                   1526:                                kd_attrflags &= ~(KAX_BOLD | KAX_DIM);
                   1527:                                break;
                   1528:                        case 24:
                   1529:                                kd_attrflags &= ~KAX_UNDERLINE;
                   1530:                                break;
                   1531:                        case 25:
                   1532:                                kd_attrflags &= ~KAX_BLINK;
                   1533:                                break;
                   1534:                        case 27:
                   1535:                                kd_attrflags &= ~KAX_REVERSE;
                   1536:                                break;
                   1537:                        case 38:
                   1538:                                kd_attrflags |= KAX_UNDERLINE;
                   1539:                                kd_color = (kd_color & 0xf0) | (KA_NORMAL & 0x0f);
                   1540:                                break;
                   1541:                        case 39:
                   1542:                                kd_attrflags &= ~KAX_UNDERLINE;
                   1543:                                kd_color = (kd_color & 0xf0) | (KA_NORMAL & 0x0f);
                   1544:                                break;
                   1545:                        default:
                   1546:                          if (number[i] >= 30 && number[i] <= 37) {
                   1547:                            /* foreground color */
                   1548:                            kd_color = (kd_color & 0xf0) | color_table[(number[i] - 30)];
                   1549:                          } else if (number[i] >= 40 && number[i] <= 47) {
                   1550:                            /* background color */
                   1551:                            kd_color = (kd_color & 0x0f) | (color_table[(number[i] - 40)] << 4);
                   1552:                          }
                   1553:                          break;
                   1554:                        }
                   1555:                kd_update_kd_attr();
1.1       root     1556:                esc_spt = esc_seq;
                   1557:                break;
                   1558:        case '@':
1.1.1.4   root     1559:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1560:                        kd_insch(1);
                   1561:                else
1.1.1.3   root     1562:                        kd_insch(number[0]);
1.1       root     1563:                esc_spt = esc_seq;
                   1564:                break;
                   1565:        case 'A':
1.1.1.4   root     1566:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1567:                        kd_up();
                   1568:                else
1.1.1.3   root     1569:                        while (number[0]--)
1.1       root     1570:                                kd_up();
                   1571:                esc_spt = esc_seq;
                   1572:                break;
                   1573:        case 'B':
1.1.1.4   root     1574:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1575:                        kd_down();
                   1576:                else
1.1.1.3   root     1577:                        while (number[0]--)
1.1       root     1578:                                kd_down();
                   1579:                esc_spt = esc_seq;
                   1580:                break;
                   1581:        case 'C':
1.1.1.4   root     1582:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1583:                        kd_right();
                   1584:                else
1.1.1.3   root     1585:                        while (number[0]--)
1.1       root     1586:                                kd_right();
                   1587:                esc_spt = esc_seq;
                   1588:                break;
                   1589:        case 'D':
1.1.1.4   root     1590:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1591:                        kd_left();
                   1592:                else
1.1.1.3   root     1593:                        while (number[0]--)
1.1       root     1594:                                kd_left();
                   1595:                esc_spt = esc_seq;
                   1596:                break;
                   1597:        case 'E':
                   1598:                kd_cr();
1.1.1.4   root     1599:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1600:                        kd_down();
                   1601:                else
1.1.1.3   root     1602:                        while (number[0]--)
1.1       root     1603:                                kd_down();
                   1604:                esc_spt = esc_seq;
                   1605:                break;
                   1606:        case 'F':
                   1607:                kd_cr();
1.1.1.4   root     1608:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1609:                        kd_up();
                   1610:                else
1.1.1.3   root     1611:                        while (number[0]--)
1.1       root     1612:                                kd_up();
                   1613:                esc_spt = esc_seq;
                   1614:                break;
                   1615:        case 'G':
1.1.1.4   root     1616:                if (number[0] == MACH_ATOI_DEFAULT)
1.1.1.3   root     1617:                        number[0] = 0;
1.1       root     1618:                else
1.1.1.3   root     1619:                        if (number[0] > 0)
                   1620:                                --number[0];    /* because number[0] is from 1 */
                   1621:                kd_setpos(BEG_OF_LINE(kd_curpos) + number[0] * ONE_SPACE);
1.1       root     1622:                esc_spt = esc_seq;
                   1623:                break;
1.1.1.3   root     1624:        case 'f':
                   1625:        case 'H':
1.1.1.4   root     1626:                if (number[0] == MACH_ATOI_DEFAULT && number[1] == MACH_ATOI_DEFAULT)
1.1.1.3   root     1627:                {
                   1628:                        kd_home();
                   1629:                        esc_spt = esc_seq;
                   1630:                        break;
                   1631:                }
1.1.1.4   root     1632:                if (number[0] == MACH_ATOI_DEFAULT)
1.1.1.3   root     1633:                        number[0] = 0;
                   1634:                else if (number[0] > 0)
                   1635:                        --number[0];            /* numbered from 1 */
                   1636:                newpos = (number[0] * ONE_LINE);   /* setup row */
1.1.1.4   root     1637:                if (number[1] == MACH_ATOI_DEFAULT)
1.1.1.3   root     1638:                        number[1] = 0;
                   1639:                else if (number[1] > 0)
                   1640:                        number[1]--;
                   1641:                newpos += (number[1] * ONE_SPACE);      /* setup column */
1.1       root     1642:                if (newpos < 0)
                   1643:                        newpos = 0;             /* upper left */
                   1644:                if (newpos > ONE_PAGE)
1.1.1.3   root     1645:                        newpos = (ONE_PAGE - ONE_SPACE); /* lower right */
                   1646:                kd_setpos(newpos);
                   1647:                esc_spt = esc_seq;
1.1       root     1648:                break;                          /* done or not ready */
                   1649:        case 'J':
1.1.1.3   root     1650:                switch(number[0]) {
1.1.1.4   root     1651:                case MACH_ATOI_DEFAULT:
1.1       root     1652:                case 0:
                   1653:                        kd_cltobcur();  /* clears from current
                   1654:                                           pos to bottom.
1.1.1.3   root     1655:                                           */
1.1       root     1656:                        break;
                   1657:                case 1:
                   1658:                        kd_cltopcur();  /* clears from top to
                   1659:                                           current pos.
1.1.1.3   root     1660:                                           */
1.1       root     1661:                        break;
                   1662:                case 2:
                   1663:                        kd_cls();
                   1664:                        break;
                   1665:                default:
                   1666:                        break;
                   1667:                }
                   1668:                esc_spt = esc_seq;              /* reset it */
                   1669:                break;
                   1670:        case 'K':
1.1.1.3   root     1671:                switch(number[0]) {
1.1.1.4   root     1672:                case MACH_ATOI_DEFAULT:
1.1       root     1673:                case 0:
                   1674:                        kd_cltoecur();  /* clears from current
                   1675:                                           pos to eoln.
1.1.1.3   root     1676:                                           */
1.1       root     1677:                        break;
                   1678:                case 1:
                   1679:                        kd_clfrbcur();  /* clears from begin
                   1680:                                           of line to current
                   1681:                                           pos.
                   1682:                                           */
                   1683:                        break;
                   1684:                case 2:
                   1685:                        kd_eraseln();   /* clear entire line */
                   1686:                        break;
                   1687:                default:
                   1688:                        break;
                   1689:                }
                   1690:                esc_spt = esc_seq;
                   1691:                break;
                   1692:        case 'L':
1.1.1.4   root     1693:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1694:                        kd_insln(1);
                   1695:                else
1.1.1.3   root     1696:                        kd_insln(number[0]);
1.1       root     1697:                esc_spt = esc_seq;
                   1698:                break;
                   1699:        case 'M':
1.1.1.4   root     1700:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1701:                        kd_delln(1);
                   1702:                else
1.1.1.3   root     1703:                        kd_delln(number[0]);
1.1       root     1704:                esc_spt = esc_seq;
                   1705:                break;
                   1706:        case 'P':
1.1.1.4   root     1707:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1708:                        kd_delch(1);
                   1709:                else
1.1.1.3   root     1710:                        kd_delch(number[0]);
1.1       root     1711:                esc_spt = esc_seq;
                   1712:                break;
                   1713:        case 'S':
1.1.1.4   root     1714:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1715:                        kd_scrollup();
                   1716:                else
1.1.1.3   root     1717:                        while (number[0]--)
1.1       root     1718:                                kd_scrollup();
                   1719:                esc_spt = esc_seq;
                   1720:                break;
                   1721:        case 'T':
1.1.1.4   root     1722:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1723:                        kd_scrolldn();
                   1724:                else
1.1.1.3   root     1725:                        while (number[0]--)
1.1       root     1726:                                kd_scrolldn();
                   1727:                esc_spt = esc_seq;
                   1728:                break;
                   1729:        case 'X':
1.1.1.4   root     1730:                if (number[0] == MACH_ATOI_DEFAULT)
1.1       root     1731:                        kd_erase(1);
                   1732:                else
1.1.1.3   root     1733:                        kd_erase(number[0]);
1.1       root     1734:                esc_spt = esc_seq;
1.1.1.3   root     1735:                break;
1.1       root     1736:        case '\0':
                   1737:                break;                  /* not enough yet */
                   1738:        default:
                   1739:                kd_putc(*cp);           /* show inv character */
                   1740:                esc_spt = esc_seq;      /* inv entry, reset */
                   1741:                break;
                   1742:        }
                   1743:        return;
                   1744: }
                   1745: 
1.1.1.4   root     1746: void
1.1.1.5   root     1747: kd_tab(void)
1.1       root     1748: {
                   1749:     int i;
                   1750: 
                   1751:     for (i = 8 - (CURRENT_COLUMN(kd_curpos) % 8); i > 0; i--) {
                   1752:        kd_putc(' ');
                   1753:     }
                   1754: 
                   1755: }
                   1756: 
                   1757: 
                   1758: /*
                   1759:  * kd_cls:
                   1760:  *
                   1761:  *     This function clears the screen with spaces and the current attribute.
                   1762:  *
                   1763:  * input       : None
                   1764:  * output      : Screen is cleared
                   1765:  *
                   1766:  */
1.1.1.4   root     1767: void
1.1.1.5   root     1768: kd_cls(void)
1.1       root     1769: {
                   1770:        (*kd_dclear)(0, ONE_PAGE/ONE_SPACE, kd_attr);
                   1771:        return;
                   1772: }
                   1773: 
                   1774: 
                   1775: /*
                   1776:  * kd_home:
                   1777:  *
                   1778:  *     This function will move the cursor to the home position on the screen,
                   1779:  *     as well as set the internal cursor position (kd_curpos) to home.
                   1780:  *
                   1781:  * input       : None
                   1782:  * output      : Cursor position is moved
                   1783:  *
                   1784:  */
1.1.1.4   root     1785: void
1.1.1.5   root     1786: kd_home(void)
1.1       root     1787: {
                   1788:        kd_setpos(0);
                   1789:        return;
                   1790: }
                   1791: 
                   1792: 
                   1793: /*
                   1794:  * kd_up:
                   1795:  *
                   1796:  *     This function moves the cursor up one line position.
                   1797:  *
                   1798:  * input       : None
                   1799:  * output      : Cursor moves up one line, or screen is scrolled
                   1800:  *
                   1801:  */
1.1.1.4   root     1802: void
1.1.1.5   root     1803: kd_up(void)
1.1       root     1804: {
                   1805:        if (kd_curpos < ONE_LINE)
                   1806:                kd_scrolldn();
                   1807:        else
                   1808:                kd_setpos(kd_curpos - ONE_LINE);
                   1809:        return;
                   1810: }
                   1811: 
                   1812: 
                   1813: /*
                   1814:  * kd_down:
                   1815:  *
                   1816:  *     This function moves the cursor down one line position.
                   1817:  *
                   1818:  * input       : None
                   1819:  * output      : Cursor moves down one line or the screen is scrolled
                   1820:  *
                   1821:  */
1.1.1.4   root     1822: void
1.1.1.5   root     1823: kd_down(void)
1.1       root     1824: {
                   1825:        if (kd_curpos >= (ONE_PAGE - ONE_LINE))
                   1826:                kd_scrollup();
                   1827:        else
                   1828:                kd_setpos(kd_curpos + ONE_LINE);
                   1829:        return;
                   1830: }
                   1831: 
                   1832: 
                   1833: /*
                   1834:  * kd_right:
                   1835:  *
                   1836:  *     This function moves the cursor one position to the right.
                   1837:  *
                   1838:  * input       : None
                   1839:  * output      : Cursor moves one position to the right
                   1840:  *
                   1841:  */
1.1.1.4   root     1842: void
1.1.1.5   root     1843: kd_right(void)
1.1       root     1844: {
                   1845:        if (kd_curpos < (ONE_PAGE - ONE_SPACE))
                   1846:                kd_setpos(kd_curpos + ONE_SPACE);
                   1847:        else {
                   1848:                kd_scrollup();
                   1849:                kd_setpos(BEG_OF_LINE(kd_curpos));
                   1850:        }
                   1851:        return;
                   1852: }
                   1853: 
                   1854: 
                   1855: /*
                   1856:  * kd_left:
                   1857:  *
                   1858:  *     This function moves the cursor one position to the left.
                   1859:  *
                   1860:  * input       : None
                   1861:  * output      : Cursor moves one position to the left
                   1862:  *
                   1863:  */
1.1.1.4   root     1864: void
1.1.1.5   root     1865: kd_left(void)
1.1       root     1866: {
                   1867:        if (0 < kd_curpos)
                   1868:                kd_setpos(kd_curpos - ONE_SPACE);
                   1869:        return;
                   1870: }
                   1871: 
                   1872: 
                   1873: /*
                   1874:  * kd_cr:
                   1875:  *
                   1876:  *     This function moves the cursor to the beginning of the current
                   1877:  *     line.
                   1878:  *
                   1879:  * input       : None
                   1880:  * output      : Cursor moves to the beginning of the current line
                   1881:  *
                   1882:  */
1.1.1.4   root     1883: void
1.1.1.5   root     1884: kd_cr(void)
1.1       root     1885: {
                   1886:        kd_setpos(BEG_OF_LINE(kd_curpos));
                   1887:        return;
                   1888: }
                   1889: 
                   1890: 
                   1891: /*
                   1892:  * kd_cltobcur:
                   1893:  *
                   1894:  *     This function clears from the current cursor position to the bottom
                   1895:  *     of the screen.
                   1896:  *
                   1897:  * input       : None
1.1.1.5   root     1898:  * output      : Screen is cleared from current cursor position to bottom
1.1       root     1899:  *
                   1900:  */
1.1.1.4   root     1901: void
1.1.1.5   root     1902: kd_cltobcur(void)
1.1       root     1903: {
                   1904:        csrpos_t start;
                   1905:        int     count;
                   1906: 
                   1907:        start = kd_curpos;
                   1908:        count = (ONE_PAGE - kd_curpos)/ONE_SPACE;
                   1909:        (*kd_dclear)(start, count, kd_attr);
                   1910:        return;
                   1911: }
                   1912: 
                   1913: 
                   1914: /*
                   1915:  * kd_cltopcur:
                   1916:  *
                   1917:  *     This function clears from the current cursor position to the top
                   1918:  *     of the screen.
                   1919:  *
                   1920:  * input       : None
1.1.1.5   root     1921:  * output      : Screen is cleared from current cursor position to top
1.1       root     1922:  *
                   1923:  */
1.1.1.4   root     1924: void
1.1.1.5   root     1925: kd_cltopcur(void)
1.1       root     1926: {
                   1927:        int     count;
                   1928: 
                   1929:        count = (kd_curpos + ONE_SPACE) / ONE_SPACE;
                   1930:        (*kd_dclear)(0, count, kd_attr);
                   1931:        return;
                   1932: }
                   1933: 
                   1934: 
                   1935: /*
                   1936:  * kd_cltoecur:
                   1937:  *
1.1.1.3   root     1938:  *     This function clears from the current cursor position to eoln.
1.1       root     1939:  *
                   1940:  * input       : None
                   1941:  * output      : Line is cleared from current cursor position to eoln
                   1942:  *
                   1943:  */
1.1.1.4   root     1944: void
1.1.1.5   root     1945: kd_cltoecur(void)
1.1       root     1946: {
                   1947:        csrpos_t i;
                   1948:        csrpos_t hold;
                   1949: 
                   1950:        hold = BEG_OF_LINE(kd_curpos) + ONE_LINE;
                   1951:        for (i = kd_curpos; i < hold; i += ONE_SPACE) {
                   1952:                (*kd_dput)(i, K_SPACE, kd_attr);
                   1953:        }
                   1954: }
                   1955: 
                   1956: 
                   1957: /*
                   1958:  * kd_clfrbcur:
                   1959:  *
                   1960:  *     This function clears from the beginning of the line to the current
                   1961:  *     cursor position.
                   1962:  *
                   1963:  * input       : None
                   1964:  * output      : Line is cleared from beginning to current position
                   1965:  *
                   1966:  */
1.1.1.4   root     1967: void
1.1.1.5   root     1968: kd_clfrbcur(void)
1.1       root     1969: {
                   1970:        csrpos_t i;
                   1971: 
                   1972:        for (i = BEG_OF_LINE(kd_curpos); i <= kd_curpos; i += ONE_SPACE) {
                   1973:                (*kd_dput)(i, K_SPACE, kd_attr);
                   1974:        }
                   1975: }
                   1976: 
                   1977: 
                   1978: /*
                   1979:  * kd_delln:
                   1980:  *
                   1981:  *     This function deletes 'number' lines on the screen by effectively
                   1982:  *     scrolling the lines up and replacing the old lines with spaces.
                   1983:  *
                   1984:  * input       : number of lines to delete
                   1985:  * output      : lines appear to be deleted
                   1986:  *
                   1987:  */
1.1.1.4   root     1988: void
1.1.1.5   root     1989: kd_delln(int number)
1.1       root     1990: {
                   1991:        csrpos_t to;
                   1992:        csrpos_t from;
                   1993:        int     delbytes;               /* num of bytes to delete */
                   1994:        int     count;                  /* num of words to move or fill */
                   1995: 
                   1996:        if (number <= 0)
                   1997:                return;
                   1998: 
                   1999:        delbytes = number * ONE_LINE;
                   2000:        to = BEG_OF_LINE(kd_curpos);
                   2001:        if (to + delbytes >= ONE_PAGE)
                   2002:                delbytes = ONE_PAGE - to;
                   2003:        if (to + delbytes < ONE_PAGE) {
                   2004:                from = to + delbytes;
                   2005:                count = (ONE_PAGE - from) / ONE_SPACE;
                   2006:                (*kd_dmvup)(from, to, count);
                   2007:        }
                   2008: 
                   2009:        to = ONE_PAGE - delbytes;
                   2010:        count = delbytes / ONE_SPACE;
                   2011:        (*kd_dclear)(to, count, kd_attr);
                   2012:        return;
                   2013: }
                   2014: 
                   2015: 
                   2016: /*
                   2017:  * kd_insln:
                   2018:  *
                   2019:  *     This function inserts a line above the current one by
                   2020:  *     scrolling the current line and all the lines below it down.
                   2021:  *
                   2022:  * input       : number of lines to insert
                   2023:  * output      : New lines appear to be inserted
                   2024:  *
                   2025:  */
1.1.1.4   root     2026: void
1.1.1.5   root     2027: kd_insln(int number)
1.1       root     2028: {
                   2029:        csrpos_t to;
                   2030:        csrpos_t from;
                   2031:        int     count;
                   2032:        csrpos_t top;                   /* top of block to be moved */
                   2033:        int     insbytes;               /* num of bytes inserted */
                   2034: 
                   2035:        if (number <= 0)
                   2036:                return;
                   2037: 
                   2038:        top = BEG_OF_LINE(kd_curpos);
                   2039:        insbytes = number * ONE_LINE;
                   2040:        if (top + insbytes > ONE_PAGE)
                   2041:                insbytes = ONE_PAGE - top;
                   2042:        to = ONE_PAGE - ONE_SPACE;
                   2043:        from = to - insbytes;
                   2044:        if (from > top) {
                   2045:                count = (from - top + ONE_SPACE) / ONE_SPACE;
                   2046:                (*kd_dmvdown)(from, to, count);
                   2047:        }
                   2048: 
                   2049:        count = insbytes / ONE_SPACE;
                   2050:        (*kd_dclear)(top, count, kd_attr);
                   2051:        return;
                   2052: }
                   2053: 
                   2054: 
                   2055: /*
                   2056:  * kd_delch:
                   2057:  *
1.1.1.3   root     2058:  *     This function deletes a number of characters from the current
1.1       root     2059:  *     position in the line.
                   2060:  *
                   2061:  * input       : number of characters to delete
                   2062:  * output      : characters appear to be deleted
                   2063:  *
                   2064:  */
1.1.1.4   root     2065: void
1.1.1.5   root     2066: kd_delch(int number)
1.1       root     2067: {
1.1.1.5   root     2068:        int      count;                 /* num words moved/filled */
                   2069:        int      delbytes;              /* bytes to delete */
                   2070:        csrpos_t to;
1.1       root     2071:        csrpos_t from;
                   2072:        csrpos_t nextline;              /* start of next line */
                   2073: 
                   2074:        if (number <= 0)
                   2075:                return;
                   2076: 
                   2077:        nextline = BEG_OF_LINE(kd_curpos) + ONE_LINE;
                   2078:        delbytes = number * ONE_SPACE;
                   2079:        if (kd_curpos + delbytes > nextline)
                   2080:                delbytes = nextline - kd_curpos;
                   2081:        if (kd_curpos + delbytes < nextline) {
                   2082:                from = kd_curpos + delbytes;
                   2083:                to = kd_curpos;
                   2084:                count = (nextline - from) / ONE_SPACE;
                   2085:                (*kd_dmvup)(from, to, count);
                   2086:        }
                   2087: 
                   2088:        to = nextline - delbytes;
                   2089:        count = delbytes / ONE_SPACE;
                   2090:        (*kd_dclear)(to, count, kd_attr);
                   2091:        return;
                   2092: 
                   2093: }
                   2094: 
                   2095: 
                   2096: /*
                   2097:  * kd_erase:
                   2098:  *
                   2099:  *     This function overwrites characters with a space starting with the
                   2100:  *     current cursor position and ending in number spaces away.
                   2101:  *
                   2102:  * input       : number of characters to erase
                   2103:  * output      : characters appear to be blanked or erased
                   2104:  *
                   2105:  */
1.1.1.4   root     2106: void
1.1.1.5   root     2107: kd_erase(int number)
1.1       root     2108: {
                   2109:        csrpos_t i;
                   2110:        csrpos_t stop;
                   2111: 
1.1.1.3   root     2112:        stop = kd_curpos + (ONE_SPACE * number);
1.1       root     2113:        if (stop > BEG_OF_LINE(kd_curpos) + ONE_LINE)
                   2114:                stop = BEG_OF_LINE(kd_curpos) + ONE_LINE;
                   2115:        for (i = kd_curpos; i < stop; i += ONE_SPACE) {
                   2116:                (*kd_dput)(i, K_SPACE, kd_attr);
                   2117:        }
                   2118:        return;
                   2119: }
                   2120: 
                   2121: 
                   2122: /*
                   2123:  * kd_eraseln:
                   2124:  *
                   2125:  *     This function erases the current line with spaces.
                   2126:  *
                   2127:  * input       : None
                   2128:  * output      : Current line is erased
                   2129:  *
                   2130:  */
1.1.1.4   root     2131: void
1.1.1.5   root     2132: kd_eraseln(void)
1.1       root     2133: {
                   2134:        csrpos_t i;
                   2135:        csrpos_t stop;
                   2136: 
                   2137:        stop = BEG_OF_LINE(kd_curpos) + ONE_LINE;
1.1.1.3   root     2138:        for (i = BEG_OF_LINE(kd_curpos); i < stop; i += ONE_SPACE) {
1.1       root     2139:                (*kd_dput)(i, K_SPACE, kd_attr);
                   2140:        }
                   2141:        return;
                   2142: }
                   2143: 
                   2144: 
                   2145: /*
                   2146:  * kd_insch:
                   2147:  *
                   2148:  *     This function inserts a blank at the current cursor position
                   2149:  *     and moves all other characters on the line over.
                   2150:  *
                   2151:  * input       : number of blanks to insert
                   2152:  * output      : Blanks are inserted at cursor position
                   2153:  *
                   2154:  */
1.1.1.4   root     2155: void
1.1.1.5   root     2156: kd_insch(int number)
1.1       root     2157: {
                   2158:        csrpos_t to;
                   2159:        csrpos_t from;
                   2160:        int     count;
                   2161:        csrpos_t nextline;              /* start of next line */
                   2162:        int     insbytes;               /* num of bytes inserted */
                   2163: 
                   2164:        if (number <= 0)
                   2165:                return;
                   2166: 
                   2167:        nextline = BEG_OF_LINE(kd_curpos) + ONE_LINE;
                   2168:        insbytes = number * ONE_SPACE;
                   2169:        if (kd_curpos + insbytes > nextline)
                   2170:                insbytes = nextline - kd_curpos;
                   2171: 
                   2172:        to = nextline - ONE_SPACE;
                   2173:        from = to - insbytes;
                   2174:        if (from >= kd_curpos) {
                   2175:                count = (from - kd_curpos + ONE_SPACE) / ONE_SPACE;
                   2176:                (*kd_dmvdown)(from, to, count);
                   2177:        }
                   2178: 
                   2179:        count = insbytes / ONE_SPACE;
                   2180:        (*kd_dclear)(kd_curpos, count, kd_attr);
                   2181:        return;
                   2182: }
                   2183: 
                   2184: 
                   2185: /*
                   2186:  * kd_isupper, kd_islower:
                   2187:  *
                   2188:  *     Didn't want to include ctype.h because it brings in stdio.h, and
                   2189:  *     only want to see if the darn character is uppercase or lowercase.
                   2190:  *
                   2191:  * input       : Character 'c'
                   2192:  * output      : isuuper gives TRUE if character is uppercase, islower
                   2193:  *               returns TRUE if character is lowercase
                   2194:  *
                   2195:  */
1.1.1.4   root     2196: boolean_t
1.1.1.5   root     2197: kd_isupper(u_char c)
1.1       root     2198: {
                   2199:        if (('A' <= c) && (c <= 'Z'))
                   2200:                return(TRUE);
                   2201:        return(FALSE);
                   2202: }
                   2203: 
1.1.1.4   root     2204: boolean_t
1.1.1.5   root     2205: kd_islower(u_char c)
1.1       root     2206: {
                   2207:        if (('a' <= c) && (c <= 'z'))
                   2208:                return(TRUE);
                   2209:        return(FALSE);
                   2210: }
                   2211: 
                   2212: /*
                   2213:  * kd_senddata:
                   2214:  *
                   2215:  *     This function sends a byte to the keyboard RDWR port, but
                   2216:  *     first waits until the input/output data buffer is clear before
                   2217:  *     sending the data.  Note that this byte can be either data or a
                   2218:  *     keyboard command.
                   2219:  *
                   2220:  */
1.1.1.4   root     2221: void
1.1.1.5   root     2222: kd_senddata(unsigned char ch)
1.1       root     2223: {
1.1.1.5   root     2224:        while (inb(K_STATUS) & K_IBUF_FUL)
                   2225:                ;
1.1       root     2226:        outb(K_RDWR, ch);
                   2227:        last_sent = ch;
                   2228:        return;
                   2229: }
                   2230: 
                   2231: /*
                   2232:  * kd_sendcmd:
                   2233:  *
                   2234:  *     This function sends a command byte to the keyboard command
                   2235:  *     port, but first waits until the input/output data buffer is
                   2236:  *     clear before sending the data.
                   2237:  *
                   2238:  */
1.1.1.4   root     2239: void
1.1.1.5   root     2240: kd_sendcmd(unsigned char ch)
1.1       root     2241: {
1.1.1.5   root     2242:        while (inb(K_STATUS) & K_IBUF_FUL)
                   2243:                ;
1.1       root     2244:        outb(K_CMD, ch);
                   2245:        return;
                   2246: }
                   2247: 
                   2248: 
1.1.1.3   root     2249: /*
1.1       root     2250:  * kd_getdata:
1.1.1.3   root     2251:  *
                   2252:  *     This function returns a data byte from the keyboard RDWR port,
                   2253:  *     after waiting until the port is flagged as having something to
                   2254:  *     read.
1.1       root     2255:  */
                   2256: unsigned char
1.1.1.5   root     2257: kd_getdata(void)
1.1       root     2258: {
1.1.1.5   root     2259:        while ((inb(K_STATUS) & K_OBUF_FUL) == 0)
                   2260:                ;
1.1       root     2261:        return(inb(K_RDWR));
                   2262: }
                   2263: 
1.1.1.4   root     2264: unsigned char
1.1.1.5   root     2265: kd_cmdreg_read(void)
1.1       root     2266: {
                   2267: int ch=KC_CMD_READ;
                   2268: 
1.1.1.5   root     2269:        while (inb(K_STATUS) & K_IBUF_FUL)
                   2270:                ;
1.1       root     2271:        outb(K_CMD, ch);
                   2272: 
1.1.1.5   root     2273:        while ((inb(K_STATUS) & K_OBUF_FUL) == 0)
                   2274:                ;
1.1       root     2275:        return(inb(K_RDWR));
                   2276: }
                   2277: 
1.1.1.4   root     2278: void
1.1.1.5   root     2279: kd_cmdreg_write(int val)
1.1       root     2280: {
                   2281: int ch=KC_CMD_WRITE;
                   2282: 
1.1.1.5   root     2283:        while (inb(K_STATUS) & K_IBUF_FUL)
                   2284:                ;
1.1       root     2285:        outb(K_CMD, ch);
                   2286: 
1.1.1.5   root     2287:        while (inb(K_STATUS) & K_IBUF_FUL)
                   2288:                ;
1.1       root     2289:        outb(K_RDWR, val);
                   2290: }
                   2291: 
1.1.1.4   root     2292: void
1.1.1.5   root     2293: kd_mouse_drain(void)
1.1       root     2294: {
                   2295:        int i;
1.1.1.5   root     2296:        while(inb(K_STATUS) & K_IBUF_FUL)
                   2297:                ;
1.1       root     2298:        while((i = inb(K_STATUS)) & K_OBUF_FUL)
                   2299:                printf("kbd: S = %x D = %x\n", i, inb(K_RDWR));
                   2300: }
                   2301: 
1.1.1.3   root     2302: /*
1.1       root     2303:  * set_kd_state:
1.1.1.3   root     2304:  *
1.1       root     2305:  *     Set kd_state and update the keyboard status LEDs.
                   2306:  */
1.1.1.4   root     2307: void
1.1.1.5   root     2308: set_kd_state(int newstate)
1.1       root     2309: {
                   2310:        kd_state = newstate;
                   2311:        kd_setleds1(state2leds(newstate));
                   2312: }
                   2313: 
1.1.1.3   root     2314: /*
1.1       root     2315:  * state2leds:
1.1.1.3   root     2316:  *
                   2317:  *     Return a byte containing LED settings for the keyboard, given
1.1       root     2318:  *     a state vector.
                   2319:  */
                   2320: u_char
1.1.1.5   root     2321: state2leds(int state)
1.1       root     2322: {
                   2323:        u_char result = 0;
                   2324: 
                   2325:        if (state & KS_NLKED)
                   2326:                result |= K_LED_NUMLK;
                   2327:        if (state & KS_CLKED)
                   2328:                result |= K_LED_CAPSLK;
                   2329:        return(result);
                   2330: }
                   2331: 
1.1.1.3   root     2332: /*
1.1       root     2333:  * kd_setleds[12]:
1.1.1.3   root     2334:  *
                   2335:  *     Set the keyboard LEDs according to the given byte.
1.1       root     2336:  */
1.1.1.4   root     2337: void
1.1.1.5   root     2338: kd_setleds1(u_char val)
1.1       root     2339: {
                   2340:        if (kd_ack != NOT_WAITING) {
1.1.1.4   root     2341: #ifdef MACH_KBD
1.1       root     2342:                printf("kd_setleds1: unexpected state (%d)\n", kd_ack);
1.1.1.4   root     2343: #endif
1.1       root     2344:                return;
                   2345:        }
                   2346: 
                   2347:        kd_ack = SET_LEDS;
                   2348:        kd_nextled = val;
                   2349:        kd_senddata(K_CMD_LEDS);
                   2350: }
                   2351: 
1.1.1.4   root     2352: void
1.1.1.5   root     2353: kd_setleds2(void)
1.1       root     2354: {
                   2355:        kd_senddata(kd_nextled);
                   2356: }
                   2357: 
                   2358: 
1.1.1.3   root     2359: /*
1.1       root     2360:  * cnsetleds:
1.1.1.3   root     2361:  *
1.1       root     2362:  *     like kd_setleds[12], but not interrupt-based.
1.1.1.3   root     2363:  *     Currently disabled because cngetc ignores caps lock and num
1.1       root     2364:  *     lock anyway.
                   2365:  */
1.1.1.4   root     2366: void
1.1.1.5   root     2367: cnsetleds(u_char val)
1.1       root     2368: {
                   2369:        kd_senddata(K_CMD_LEDS);
                   2370:        (void)kd_getdata();             /* XXX - assume is ACK */
                   2371:        kd_senddata(val);
                   2372:        (void)kd_getdata();             /* XXX - assume is ACK */
                   2373: }
                   2374: 
1.1.1.4   root     2375: void
1.1.1.5   root     2376: kdreboot(void)
1.1       root     2377: {
                   2378:        (*kd_dreset)();
                   2379: 
                   2380: #ifndef BROKEN_KEYBOARD_RESET
                   2381:        kd_sendcmd(0xFE);               /* XXX - magic # */
                   2382:        delay(1000000);                 /* wait to see if anything happens */
                   2383: #endif
1.1.1.3   root     2384:        /*
1.1       root     2385:         * If that didn't work, then we'll just have to try and
1.1.1.3   root     2386:         * do it the hard way.
1.1       root     2387:         */
                   2388:        cpu_shutdown();
                   2389: }
                   2390: 
                   2391: static int which_button[] = {0, MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT};
                   2392: static struct mouse_motion moved;
                   2393: 
1.1.1.4   root     2394: int
1.1.1.5   root     2395: kd_kbd_magic(int scancode)
1.1       root     2396: {
                   2397: int new_button = 0;
                   2398: 
                   2399:        if (kd_kbd_mouse == 2)
                   2400:                printf("sc = %x\n", scancode);
                   2401: 
                   2402:        switch (scancode) {
                   2403: /* f1 f2 f3 */
                   2404:        case 0x3d:
                   2405:                new_button++;
                   2406:        case 0x3c:
                   2407:                new_button++;
                   2408:        case 0x3b:
                   2409:                new_button++;
                   2410:                if (kd_kbd_magic_button && (new_button != kd_kbd_magic_button)) {
                   2411:                                /* down w/o up */
                   2412:                        mouse_button(which_button[kd_kbd_magic_button], 1);
                   2413:                }
                   2414:                                /* normal */
                   2415:                if (kd_kbd_magic_button == new_button) {
                   2416:                        mouse_button(which_button[new_button], 1);
                   2417:                        kd_kbd_magic_button = 0;
                   2418:                } else {
                   2419:                        mouse_button(which_button[new_button], 0);
                   2420:                        kd_kbd_magic_button = new_button;
                   2421:                }
                   2422:                break;
                   2423: 
                   2424: /* right left up down */
                   2425:        case 0x4d:
                   2426:                moved.mm_deltaX = kd_kbd_magic_scale;
                   2427:                moved.mm_deltaY = 0;
                   2428:                mouse_moved(moved);
                   2429:                break;
                   2430:        case 0x4b:
                   2431:                moved.mm_deltaX = -kd_kbd_magic_scale;
                   2432:                moved.mm_deltaY = 0;
                   2433:                mouse_moved(moved);
                   2434:                break;
                   2435:        case 0x48:
                   2436:                moved.mm_deltaX = 0;
                   2437:                moved.mm_deltaY = kd_kbd_magic_scale;
                   2438:                mouse_moved(moved);
                   2439:                break;
                   2440:        case 0x50:
                   2441:                moved.mm_deltaX = 0;
                   2442:                moved.mm_deltaY = -kd_kbd_magic_scale;
                   2443:                mouse_moved(moved);
                   2444:                break;
                   2445: /* home pageup end pagedown */
                   2446:        case 0x47:
                   2447:                moved.mm_deltaX = -2*kd_kbd_magic_scale;
                   2448:                moved.mm_deltaY = 2*kd_kbd_magic_scale;
                   2449:                mouse_moved(moved);
                   2450:                break;
                   2451:        case 0x49:
                   2452:                moved.mm_deltaX = 2*kd_kbd_magic_scale;
                   2453:                moved.mm_deltaY = 2*kd_kbd_magic_scale;
                   2454:                mouse_moved(moved);
                   2455:                break;
                   2456:        case 0x4f:
                   2457:                moved.mm_deltaX = -2*kd_kbd_magic_scale;
                   2458:                moved.mm_deltaY = -2*kd_kbd_magic_scale;
                   2459:                mouse_moved(moved);
                   2460:                break;
                   2461:        case 0x51:
                   2462:                moved.mm_deltaX = 2*kd_kbd_magic_scale;
                   2463:                moved.mm_deltaY = -2*kd_kbd_magic_scale;
                   2464:                mouse_moved(moved);
                   2465:                break;
                   2466: 
                   2467:        default:
                   2468:                return 0;
                   2469:        }
                   2470:        return 1;
                   2471: }
                   2472: 
                   2473: 
                   2474: 
                   2475: /*
                   2476:  * Code specific to EGA/CGA/VGA boards.  This code relies on the fact
                   2477:  * that the "slam" functions take a word count and ONE_SPACE takes up
                   2478:  * 1 word.
                   2479:  */
                   2480: #define        SLAMBPW 2                       /* bytes per word for "slam" fcns */
                   2481: 
                   2482: 
                   2483: /*
                   2484:  * kd_xga_init:
                   2485:  *
                   2486:  *     Initialization specific to character-based graphics adapters.
                   2487:  */
                   2488: void
1.1.1.5   root     2489: kd_xga_init(void)
1.1       root     2490: {
                   2491:        csrpos_t        xga_getpos();
                   2492:        unsigned char   screen;
1.1.1.5   root     2493:        unsigned char   start, stop;
1.1       root     2494: 
                   2495:        outb(CMOS_ADDR, CMOS_EB);
                   2496:        screen = inb(CMOS_DATA) & CM_SCRMSK;
                   2497:        switch(screen) {
1.1.1.5   root     2498:        default:
                   2499:                printf("kd: unknown screen type, defaulting to EGA\n");
                   2500:                /* FALLTHROUGH */
1.1       root     2501:        case CM_EGA_VGA:
                   2502:                /*
                   2503:                 * Here we'll want to query to bios on the card
                   2504:                 * itself, because then we can figure out what
                   2505:                 * type we have exactly.  At this point we only
                   2506:                 * know that the card is NOT CGA or MONO.  For
                   2507:                 * now, however, we assume backwards compatibility
                   2508:                 * with 0xb8000 as the starting screen offset
                   2509:                 * memory location for these cards.
                   2510:                 *
                   2511:                 */
1.1.1.3   root     2512: 
1.1       root     2513:                vid_start = (u_char *)phystokv(EGA_START);
                   2514:                kd_index_reg = EGA_IDX_REG;
                   2515:                kd_io_reg = EGA_IO_REG;
                   2516:                kd_lines = 25;
                   2517:                kd_cols = 80;
                   2518:                kd_bitmap_start = 0xa0000; /* XXX - magic numbers */
                   2519:                {               /* XXX - is there a cleaner way to do this? */
                   2520:                    char *addr = (char *)phystokv(kd_bitmap_start);
                   2521:                    int i;
                   2522:                    for (i = 0; i < 200; i++)
                   2523:                        addr[i] = 0x00;
                   2524:                }
                   2525:                break;
1.1.1.5   root     2526: #if 0
                   2527:        /* XXX: some buggy BIOSes report these...  */
1.1       root     2528:        case CM_CGA_40:
                   2529:                vid_start = (u_char *)phystokv(CGA_START);
                   2530:                kd_index_reg = CGA_IDX_REG;
                   2531:                kd_io_reg = CGA_IO_REG;
                   2532:                kd_lines = 25;
                   2533:                kd_cols = 40;
                   2534:                break;
                   2535:        case CM_CGA_80:
                   2536:                vid_start = (u_char *)phystokv(CGA_START);
                   2537:                kd_index_reg = CGA_IDX_REG;
                   2538:                kd_io_reg = CGA_IO_REG;
                   2539:                kd_lines = 25;
                   2540:                kd_cols = 80;
                   2541:                break;
                   2542:        case CM_MONO_80:
                   2543:                vid_start = (u_char *)phystokv(MONO_START);
                   2544:                kd_index_reg = MONO_IDX_REG;
                   2545:                kd_io_reg = MONO_IO_REG;
                   2546:                kd_lines = 25;
                   2547:                kd_cols = 80;
                   2548:                break;
1.1.1.5   root     2549: #endif
                   2550:        }
                   2551: 
                   2552:        outb(kd_index_reg, C_START);
                   2553:        start = inb(kd_io_reg);
                   2554:        /* Make sure cursor is enabled */
                   2555:        start &= ~0x20;
                   2556:        outb(kd_io_reg, start);
                   2557:        outb(kd_index_reg, C_STOP);
                   2558:        stop = inb(kd_io_reg);
                   2559: 
                   2560:        if (!start && !stop)
                   2561:        {
                   2562:                /* Some firmware seem not to be initializing the cursor size
                   2563:                 * any more...  Try using standard values.  */
                   2564:                outb(kd_index_reg, C_START);
                   2565:                outb(kd_io_reg, 14);
                   2566:                outb(kd_index_reg, C_STOP);
                   2567:                outb(kd_io_reg, 15);
1.1       root     2568:        }
                   2569: 
                   2570:        kd_setpos(xga_getpos());
                   2571: }
                   2572: 
                   2573: 
                   2574: /*
                   2575:  * xga_getpos:
                   2576:  *
                   2577:  *     This function returns the current hardware cursor position on the
                   2578:  *     screen, scaled for compatibility with kd_curpos.
                   2579:  *
                   2580:  * input       : None
                   2581:  * output      : returns the value of cursor position on screen
                   2582:  *
                   2583:  */
                   2584: csrpos_t
1.1.1.5   root     2585: xga_getpos(void)
1.1       root     2586: 
                   2587: {
                   2588:        unsigned char   low;
                   2589:        unsigned char   high;
                   2590:        short pos;
                   2591: 
                   2592:        outb(kd_index_reg, C_HIGH);
                   2593:        high = inb(kd_io_reg);
                   2594:        outb(kd_index_reg, C_LOW);
                   2595:        low = inb(kd_io_reg);
                   2596:        pos = (0xff&low) + ((unsigned short)high<<8);
                   2597: 
                   2598:        return(ONE_SPACE * (csrpos_t)pos);
                   2599: }
                   2600: 
                   2601: 
                   2602: /*
                   2603:  * charput:
                   2604:  *
                   2605:  *     Put attributed character for EGA/CGA/etc.
                   2606:  */
                   2607: static void
                   2608: charput(pos, ch, chattr)
                   2609: csrpos_t pos;                          /* where to put it */
                   2610: char   ch;                             /* the character */
                   2611: char   chattr;                         /* its attribute */
                   2612: {
                   2613:        *(vid_start + pos) = ch;
                   2614:        *(vid_start + pos + 1) = chattr;
                   2615: }
                   2616: 
                   2617: 
                   2618: /*
                   2619:  * charsetcursor:
                   2620:  *
                   2621:  *     Set hardware cursor position for EGA/CGA/etc.
                   2622:  */
                   2623: static void
                   2624: charsetcursor(newpos)
                   2625: csrpos_t newpos;
                   2626: {
                   2627:        short curpos;           /* position, not scaled for attribute byte */
                   2628: 
                   2629:        curpos = newpos / ONE_SPACE;
                   2630:        outb(kd_index_reg, C_HIGH);
                   2631:        outb(kd_io_reg, (u_char)(curpos>>8));
                   2632:        outb(kd_index_reg, C_LOW);
                   2633:        outb(kd_io_reg, (u_char)(curpos&0xff));
                   2634: 
                   2635:        kd_curpos = newpos;
                   2636: }
                   2637: 
                   2638: 
                   2639: /*
                   2640:  * charmvup:
                   2641:  *
                   2642:  *     Block move up for EGA/CGA/etc.
                   2643:  */
                   2644: static void
                   2645: charmvup(from, to, count)
                   2646: csrpos_t from, to;
                   2647: int count;
                   2648: {
                   2649:        kd_slmscu(vid_start+from, vid_start+to, count);
                   2650: }
                   2651: 
                   2652: 
                   2653: /*
                   2654:  * charmvdown:
                   2655:  *
                   2656:  *     Block move down for EGA/CGA/etc.
                   2657:  */
                   2658: static void
                   2659: charmvdown(from, to, count)
                   2660: csrpos_t from, to;
                   2661: int count;
                   2662: {
                   2663:        kd_slmscd(vid_start+from, vid_start+to, count);
                   2664: }
                   2665: 
                   2666: 
                   2667: /*
                   2668:  * charclear:
                   2669:  *
                   2670:  *     Fast clear for CGA/EGA/etc.
                   2671:  */
                   2672: static void
                   2673: charclear(to, count, chattr)
                   2674: csrpos_t to;
                   2675: int    count;
                   2676: char   chattr;
                   2677: {
                   2678:        kd_slmwd(vid_start+to, count, ((unsigned short)chattr<<8)+K_SPACE);
                   2679: }
                   2680: 
                   2681: 
1.1.1.3   root     2682: /*
1.1       root     2683:  * kd_noopreset:
1.1.1.3   root     2684:  *
1.1       root     2685:  *     No-op reset routine for kd_dreset.
                   2686:  */
                   2687: static void
1.1.1.5   root     2688: kd_noopreset(void)
1.1       root     2689: {
                   2690: }
                   2691: 
                   2692: 
                   2693: /*
                   2694:  * bmpput: Copy a character from the font to the frame buffer.
                   2695:  */
                   2696: 
                   2697: void
1.1.1.5   root     2698: bmpput(
                   2699:        csrpos_t pos,
                   2700:        char     ch, 
                   2701:        char     chattr)
1.1       root     2702: {
                   2703:        short xbit, ybit;               /* u/l corner of char pos */
1.1.1.5   root     2704:        u_char *to, *from;
                   2705:        short i, j;
1.1       root     2706:        u_char mask = (chattr == KA_REVERSE ? 0xff : 0);
                   2707: 
                   2708:        if ((u_char)ch >= chars_in_font)
                   2709:                ch = K_QUES;
                   2710: 
                   2711:        bmpch2bit(pos, &xbit, &ybit);
                   2712:        to = bit2fbptr(xbit, ybit);
                   2713:        from = font_start + ch * char_byte_width;
                   2714:        for (i = 0; i < char_height; ++i) {
                   2715:                for (j = 0; j < char_byte_width; ++j)
                   2716:                        *(to+j) = *(from+j) ^ mask;
                   2717:                to += fb_byte_width;
                   2718:                from += font_byte_width;
                   2719:        }
                   2720: }
                   2721: 
                   2722: /*
                   2723:  * bmpcp1char: copy 1 char from one place in the frame buffer to
                   2724:  * another.
                   2725:  */
                   2726: void
1.1.1.5   root     2727: bmpcp1char(
                   2728:        csrpos_t from, 
                   2729:        csrpos_t to)
1.1       root     2730: {
                   2731:        short from_xbit, from_ybit;
                   2732:        short to_xbit, to_ybit;
1.1.1.5   root     2733:        u_char *tp, *fp;
                   2734:        short i, j;
1.1       root     2735: 
                   2736:        bmpch2bit(from, &from_xbit, &from_ybit);
                   2737:        bmpch2bit(to, &to_xbit, &to_ybit);
                   2738: 
                   2739:        tp = bit2fbptr(to_xbit, to_ybit);
                   2740:        fp = bit2fbptr(from_xbit, from_ybit);
                   2741: 
                   2742:        for (i = 0; i < char_height; ++i) {
                   2743:                for (j = 0; j < char_byte_width; ++j)
                   2744:                        *(tp+j) = *(fp+j);
                   2745:                tp += fb_byte_width;
                   2746:                fp += fb_byte_width;
                   2747:        }
                   2748: }
                   2749: 
                   2750: /*
                   2751:  * bmpvmup: Copy a block of character positions upwards.
                   2752:  */
                   2753: void
1.1.1.5   root     2754: bmpmvup(
                   2755:        csrpos_t        from, 
                   2756:        csrpos_t        to,
                   2757:        int             count)
1.1       root     2758: {
                   2759:        short from_xbit, from_ybit;
                   2760:        short to_xbit, to_ybit;
                   2761:        short i;
                   2762: 
                   2763:        bmpch2bit(from, &from_xbit, &from_ybit);
                   2764:        bmpch2bit(to, &to_xbit, &to_ybit);
                   2765: 
                   2766:        if (from_xbit == xstart && to_xbit == xstart && count%kd_cols == 0) {
                   2767:                /* fast case - entire lines */
                   2768:                from_xbit = to_xbit = 0;
                   2769:                bmppaintcsr(kd_curpos, char_black); /* don't copy cursor */
                   2770:                count /= kd_cols;       /* num lines */
                   2771:                count *= fb_byte_width * (char_height+cursor_height);
                   2772:                kd_slmscu(bit2fbptr(from_xbit, from_ybit),
1.1.1.3   root     2773:                          bit2fbptr(to_xbit, to_ybit),
1.1       root     2774:                          count/SLAMBPW);
                   2775:                bmppaintcsr(kd_curpos, char_white);
                   2776:        } else {
                   2777:                /* slow case - everything else */
                   2778:                for (i=0; i < count; ++i) {
                   2779:                        bmpcp1char(from, to);
                   2780:                        from += ONE_SPACE;
                   2781:                        to += ONE_SPACE;
                   2782:                }
                   2783:        }
                   2784: }
                   2785: 
                   2786: /*
                   2787:  * bmpmvdown: copy a block of characters down.
                   2788:  */
                   2789: void
1.1.1.5   root     2790: bmpmvdown(
                   2791:        csrpos_t        from, 
                   2792:        csrpos_t        to,
                   2793:        int             count)
1.1       root     2794: {
                   2795:        short from_xbit, from_ybit;
                   2796:        short to_xbit, to_ybit;
                   2797:        short i;
                   2798: 
                   2799:        bmpch2bit(from, &from_xbit, &from_ybit);
                   2800:        bmpch2bit(to, &to_xbit, &to_ybit);
                   2801: 
                   2802:        if (from_xbit == xstart + (kd_cols - 1) * char_width
                   2803:            && to_xbit == xstart + (kd_cols - 1) * char_width
                   2804:            && count%kd_cols == 0) {
                   2805:                /* fast case - entire lines*/
                   2806:                from_xbit = to_xbit = 8 * (fb_byte_width - 1);
                   2807:                                        /* last byte on line */
                   2808:                bmppaintcsr(kd_curpos, char_black); /* don't copy cursor */
                   2809:                count /= kd_cols;       /* num lines */
                   2810:                count *= fb_byte_width * (char_height+cursor_height);
                   2811:                kd_slmscd(bit2fbptr(from_xbit, from_ybit),
                   2812:                          bit2fbptr(to_xbit, to_ybit),
                   2813:                          count/SLAMBPW);
                   2814:                bmppaintcsr(kd_curpos, char_white);
                   2815:        } else {
                   2816:                /* slow case - everything else */
                   2817:                for (i=0; i < count; ++i) {
                   2818:                        bmpcp1char(from, to);
                   2819:                        from -= ONE_SPACE;
                   2820:                        to -= ONE_SPACE;
                   2821:                }
                   2822:        }
                   2823: }
                   2824: 
                   2825: /*
                   2826:  * bmpclear: clear one or more character positions.
                   2827:  */
                   2828: void
1.1.1.5   root     2829: bmpclear(
                   2830:        csrpos_t        to,                             /* 1st char */
                   2831:        int             count,                          /* num chars */
                   2832:        char            chattr)                         /* reverse or normal */
1.1       root     2833: {
1.1.1.5   root     2834:        short i;
1.1       root     2835:        u_short clearval;
                   2836:        u_short clearbyte = (chattr == KA_REVERSE ? char_white : char_black);
                   2837: 
                   2838:        clearval = (u_short)(clearbyte<<8) + clearbyte;
                   2839:        if (to == 0 && count >= kd_lines * kd_cols) {
                   2840:                /* fast case - entire page */
                   2841:                kd_slmwd(vid_start, (fb_byte_width * fb_height)/SLAMBPW,
                   2842:                         clearval);
1.1.1.3   root     2843:        } else
1.1       root     2844:                /* slow case */
                   2845:                for (i = 0; i < count; ++i) {
                   2846:                        bmpput(to, K_SPACE, chattr);
                   2847:                        to += ONE_SPACE;
                   2848:                }
                   2849: }
                   2850: 
                   2851: /*
                   2852:  * bmpsetcursor: update the display and set the logical cursor.
                   2853:  */
                   2854: void
1.1.1.5   root     2855: bmpsetcursor(csrpos_t pos)
1.1       root     2856: {
                   2857:        /* erase old cursor & paint new one */
                   2858:        bmppaintcsr(kd_curpos, char_black);
                   2859:        bmppaintcsr(pos, char_white);
                   2860:        kd_curpos = pos;
                   2861: }
                   2862: 
                   2863: /*
                   2864:  * bmppaintcsr: paint cursor bits.
                   2865:  */
                   2866: void
1.1.1.5   root     2867: bmppaintcsr(
                   2868:        csrpos_t        pos,
                   2869:        u_char          val)
1.1       root     2870: {
                   2871:        short xbit, ybit;
1.1.1.5   root     2872:        u_char *cp;
                   2873:        short line, byte;
1.1       root     2874: 
                   2875:        bmpch2bit(pos, &xbit, &ybit);
                   2876:        ybit += char_height;            /* position at bottom of line */
                   2877:        cp = bit2fbptr(xbit, ybit);
                   2878:        for (line = 0; line < cursor_height; ++line) {
                   2879:                for (byte = 0; byte < char_byte_width; ++byte)
                   2880:                        *(cp+byte) = val;
                   2881:                cp += fb_byte_width;
                   2882:        }
                   2883: }
                   2884: 
                   2885: /*
                   2886:  * bmpch2bit: convert character position to x and y bit addresses.
                   2887:  * (0, 0) is the upper left corner.
                   2888:  */
                   2889: void
1.1.1.5   root     2890: bmpch2bit(
                   2891:        csrpos_t        pos,
                   2892:        short           *xb, 
                   2893:        short           *yb)                    /* x, y bit positions, u/l corner */
1.1       root     2894: {
1.1.1.5   root     2895:        short xch, ych;
1.1       root     2896: 
                   2897:        xch = (pos / ONE_SPACE) % kd_cols;
                   2898:        ych = pos / (ONE_SPACE * kd_cols);
                   2899:        *xb = xstart + xch * char_width;
                   2900:        *yb = ystart + ych * (char_height + cursor_height);
                   2901: }
                   2902: 
                   2903: /*
                   2904:  * bit2fbptr: return a pointer into the frame buffer corresponding to
                   2905:  * the bit address (x, y).
                   2906:  * Assumes that xb and yb don't point to the middle of a
                   2907:  * byte.
                   2908:  */
                   2909: u_char *
1.1.1.5   root     2910: bit2fbptr(
                   2911:        short   xb, 
                   2912:        short   yb)
1.1       root     2913: {
                   2914:        return(vid_start + yb * fb_byte_width + xb/8);
                   2915: }
                   2916: 
                   2917: 
                   2918: /*
                   2919:  * console stuff
                   2920:  */
                   2921: 
                   2922: /*
                   2923:  * XXX we assume that pcs *always* have a console
                   2924:  */
                   2925: int
                   2926: kdcnprobe(struct consdev *cp)
                   2927: {
                   2928:        int maj, unit, pri;
                   2929: 
                   2930:        maj = 0;
                   2931:        unit = 0;
                   2932:        pri = CN_INTERNAL;
1.1.1.3   root     2933: 
1.1       root     2934:        cp->cn_dev = makedev(maj, unit);
                   2935:        cp->cn_pri = pri;
1.1.1.4   root     2936:        return 0;
1.1       root     2937: }
                   2938: 
                   2939: int
                   2940: kdcninit(struct consdev *cp)
                   2941: {
                   2942:        kdinit();
                   2943:        return 0;
                   2944: }
                   2945: 
                   2946: int
                   2947: kdcngetc(dev_t dev, int wait)
                   2948: {
                   2949:        if (wait) {
                   2950:                int c;
                   2951:                while ((c = kdcnmaygetc()) < 0)
                   2952:                        continue;
                   2953:                return c;
                   2954:        }
                   2955:        else
                   2956:                return kdcnmaygetc();
                   2957: }
                   2958: 
                   2959: int
                   2960: kdcnputc(dev_t dev, int c)
                   2961: {
                   2962:        if (!kd_initialized)
1.1.1.4   root     2963:                return -1;
1.1       root     2964: 
                   2965:        /* Note that tab is handled in kd_putc */
                   2966:        if (c == '\n')
                   2967:                kd_putc('\r');
1.1.1.6 ! root     2968:        kd_putc_esc(c);
1.1.1.4   root     2969: 
                   2970:        return 0;
1.1       root     2971: }
                   2972: 
1.1.1.3   root     2973: /*
1.1       root     2974:  * kdcnmaygetc:
1.1.1.3   root     2975:  *
                   2976:  *     Get one character using polling, rather than interrupts.  Used
1.1       root     2977:  *     by the kernel debugger.  Note that Caps Lock is ignored.
1.1.1.3   root     2978:  *     Normally this routine is called with interrupts already
                   2979:  *     disabled, but there is code in place so that it will be more
1.1       root     2980:  *     likely to work even if interrupts are turned on.
                   2981:  */
                   2982: int
                   2983: kdcnmaygetc(void)
                   2984: {
                   2985:        unsigned char   c;
                   2986:        unsigned char   scancode;
                   2987:        unsigned int    char_idx;
                   2988: #ifdef notdef
                   2989:        spl_t   o_pri;
                   2990: #endif
                   2991:        boolean_t       up;
                   2992: 
                   2993:        if (! kd_initialized)
                   2994:                return -1;
                   2995: 
                   2996:        kd_extended = FALSE;
                   2997: #ifdef notdef
                   2998:        o_pri = splhi();
                   2999: #endif
                   3000:        for ( ; ; ) {
                   3001:                if (!(inb(K_STATUS) & K_OBUF_FUL))
                   3002:                        return -1;
                   3003: 
                   3004:                up = FALSE;
                   3005:                /*
                   3006:                 * We'd come here for mouse events in debugger, if
                   3007:                 * the mouse were on.
                   3008:                 */
                   3009:                if ((inb(K_STATUS) & 0x20) == 0x20) {
                   3010:                        printf("M%xP", inb(K_RDWR));
                   3011:                        continue;
                   3012:                }
                   3013:                scancode = inb(K_RDWR);
                   3014:                /*
                   3015:                 * Handle extend modifier and
                   3016:                 * ack/resend, otherwise we may never receive
                   3017:                 * a key.
                   3018:                 */
                   3019:                if (scancode == K_EXTEND) {
                   3020:                        kd_extended = TRUE;
                   3021:                        continue;
                   3022:                } else if (scancode == K_RESEND) {
                   3023:   printf("cngetc: resend");
                   3024:                        kd_resend();
                   3025:                        continue;
                   3026:                } else if (scancode == K_ACKSC) {
                   3027:   printf("cngetc: handle_ack");
                   3028:                        kd_handle_ack();
                   3029:                        continue;
                   3030:                }
                   3031:                if (scancode & K_UP) {
                   3032:                        up = TRUE;
                   3033:                        scancode &= ~K_UP;
                   3034:                }
                   3035:                if (kd_kbd_mouse)
                   3036:                        kd_kbd_magic(scancode);
                   3037:                if (scancode < NUMKEYS) {
                   3038:                        /* Lookup in map, then process. */
                   3039:                        char_idx = kdstate2idx(kd_state, kd_extended);
                   3040:                        c = key_map[scancode][char_idx];
                   3041:                        if (c == K_SCAN) {
                   3042:                                c = key_map[scancode][++char_idx];
                   3043:                                kd_state = do_modifier(kd_state, c, up);
                   3044: #ifdef notdef
                   3045:                                cnsetleds(state2leds(kd_state));
                   3046: #endif
1.1.1.5   root     3047:                        } else if (! up
                   3048:                                   && c == K_ESC
                   3049:                                   && key_map[scancode][char_idx+1] == 0x5b) {
                   3050:                                /* As a convenience for the nice
                   3051:                                   people using our debugger, remap
                   3052:                                   some keys to the readline-like
                   3053:                                   shortcuts supported by dde.
                   3054: 
                   3055:                                   XXX This is a workaround for the
                   3056:                                   limited kernel getchar interface.
                   3057:                                   It is only used by the debugger.  */
                   3058:                                c = key_map[scancode][char_idx+2];
                   3059:                                switch (c) {
                   3060: #define _MAP(A,B,C)    (C)
                   3061: #define MAP(T)         _MAP(T)
                   3062: #define        CTRL(c)         ((c) & 0x1f)
                   3063:                                case MAP(K_HOME):       c = CTRL('a'); break;
                   3064:                                case MAP(K_UA):         c = CTRL('p'); break;
                   3065:                                case MAP(K_LA):         c = CTRL('b'); break;
                   3066:                                case MAP(K_RA):         c = CTRL('f'); break;
                   3067:                                case MAP(K_DA):         c = CTRL('n'); break;
                   3068:                                case MAP(K_END):        c = CTRL('e'); break;
                   3069:                                /* delete */
                   3070:                                case 0x39:              c = CTRL('d'); break;
                   3071: #undef CTRL
                   3072: #undef MAP
                   3073: #undef _MAP
                   3074:                                default:
                   3075:                                        /* Retain the old behavior.  */
                   3076:                                        c = K_ESC;
                   3077:                                }
                   3078: 
                   3079:                                return(c);
1.1       root     3080:                        } else if (!up) {
                   3081:                                /* regular key-down */
                   3082:                                if (c == K_CR)
                   3083:                                        c = K_LF;
                   3084: #ifdef notdef
                   3085:                                splx(o_pri);
                   3086: #endif
                   3087:                                return(c & 0177);
                   3088:                        }
                   3089:                }
                   3090:        }
                   3091: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.