/* $NetBSD: kbd.c,v 1.7 1996/03/28 21:55:15 mark Exp $ */ /* * Copyright (c) 1994 Mark Brinicombe. * Copyright (c) 1994 Brini. * All rights reserved. * * This code is derived from software written for Brini by Mark Brinicombe * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Brini. * 4. The name of the company nor the name of the author may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * RiscBSD kernel project * * kbd.c * * Keyboard driver functions * * Created : 09/10/94 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "vt.h" #include "kbd.h" /* Declare global variables */ /* Declare external variables */ /* Local function prototypes */ /* Now for the main code */ /* Define the key_struct structure */ typedef struct { int base_code; /* Base ASCII code */ int shift_code; /* Shifted ASCII code */ int ctrl_code; /* CTRL code */ int alt_code; /* Alt code */ int flags; /* Flags field */ } key_struct; /* Define mappings for each possible code */ key_struct keys[256] = { /* 0x00 - 0x0f */ { 0x00, 0x00, 0x00, 0x00, 0x80 }, { 0x89, 0x99, 0x00, 0x489, 0x00 }, { 0x8a, 0x9a, 0x00, 0x00, 0x00 }, { 0x85, 0x95, 0x00, 0x485, 0x00 }, { 0x83, 0x93, 0x00, 0x483, 0x00 }, { 0x81, 0x91, 0x00, 0x481, 0x00 }, { 0x82, 0x92, 0x00, 0x482, 0x00 }, { 0x8c, 0x9c, 0x00, 0x48c, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x88, 0x98, 0x00, 0x488, 0x00 }, { 0x86, 0x96, 0x00, 0x486, 0x00 }, { 0x84, 0x94, 0x00, 0x484, 0x00 }, { 0x09, 0x09, 0x09, 0x09, 0x00 }, { 0x60, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x10 - 0x1f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x84 }, { 0x00, 0x00, 0x00, 0x00, 0x82 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x81 }, { 0x71, 0x51, 0x11, 0x00, 0x40 }, { 0x31, 0x21, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x7a, 0x5a, 0x1a, 0x00, 0x40 }, { 0x73, 0x53, 0x13, 0x00, 0x40 }, { 0x61, 0x41, 0x01, 0x00, 0x40 }, { 0x77, 0x57, 0x17, 0x00, 0x40 }, { 0x32, 0x22, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x20 - 0x2f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x63, 0x43, 0x03, 0x00, 0x40 }, { 0x78, 0x58, 0x18, 0x00, 0x40 }, { 0x64, 0x44, 0x04, 0x00, 0x40 }, { 0x65, 0x45, 0x05, 0x00, 0x40 }, { 0x34, 0x24, 0x00, 0x00, 0x00 }, { 0x33, 0x23, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x20, 0x20, 0x20, 0x20, 0x00 }, { 0x76, 0x56, 0x16, 0x00, 0x40 }, { 0x66, 0x46, 0x06, 0x00, 0x40 }, { 0x74, 0x54, 0x14, 0x00, 0x40 }, { 0x72, 0x52, 0x12, 0x00, 0x40 }, { 0x35, 0x25, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x30 - 0x3f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x6e, 0x4e, 0x0e, 0x00, 0x40 }, { 0x62, 0x42, 0x02, 0x00, 0x40 }, { 0x68, 0x48, 0x08, 0x00, 0x40 }, { 0x67, 0x47, 0x07, 0x00, 0x40 }, { 0x79, 0x59, 0x19, 0x00, 0x40 }, { 0x36, 0x5e, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x6d, 0x4d, 0x0d, 0x00, 0x40 }, { 0x6a, 0x4a, 0x0a, 0x00, 0x40 }, { 0x75, 0x55, 0x15, 0x00, 0x40 }, { 0x37, 0x26, 0x00, 0x00, 0x00 }, { 0x38, 0x2a, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x40 - 0x4f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x2c, 0x3c, 0x00, 0x00, 0x00 }, { 0x6b, 0x4b, 0x0b, 0x00, 0x40 }, { 0x69, 0x49, 0x09, 0x00, 0x40 }, { 0x6f, 0x4f, 0x0f, 0x00, 0x40 }, { 0x30, 0x29, 0x00, 0x00, 0x00 }, { 0x39, 0x28, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x2e, 0x3e, 0x00, 0x00, 0x00 }, { 0x2f, 0x3f, 0x00, 0x00, 0x00 }, { 0x6c, 0x4c, 0x0c, 0x00, 0x40 }, { 0x3b, 0x3a, 0x00, 0x00, 0x00 }, { 0x70, 0x50, 0x10, 0x00, 0x40 }, { 0x2d, 0x5f, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x50 - 0x5f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x27, 0x40, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x5b, 0x7b, 0x00, 0x00, 0x00 }, { 0x3d, 0x2b, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0xa0 }, { 0x00, 0x00, 0x00, 0x00, 0x82 }, { 0x0d, 0x0d, 0x0d, 0x00, 0x00 }, { 0x5d, 0x7d, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x23, 0x7e, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x60 - 0x6f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x5c, 0x7c, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x08, 0x7f, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x31, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x34, 0x00, 0x00, 0x00, 0x00 }, { 0x37, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x70 - 0x7f */ { 0x30, 0x00, 0x00, 0x00, 0x00 }, { 0x2e, 0x00, 0x00, 0x00, 0x00 }, { 0x32, 0x00, 0x00, 0x00, 0x00 }, { 0x35, 0x00, 0x00, 0x00, 0x00 }, { 0x36, 0x00, 0x00, 0x00, 0x00 }, { 0x38, 0x00, 0x00, 0x00, 0x00 }, { 0x1b, 0x1b, 0x21b, 0x1b, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x90 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x2b, 0x00, 0x00, 0x22b, 0x00 }, { 0x33, 0x00, 0x00, 0x00, 0x00 }, { 0x2d, 0x00, 0x00, 0x22d, 0x00 }, { 0x2a, 0x00, 0x00, 0x00, 0x00 }, { 0x39, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x88 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x80 - 0x8f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x87, 0x97, 0x00, 0x487, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x90 - 0x9f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0xa0 - 0xaf */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0xb0 - 0xbf */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0xc0 - 0xcf */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0xd0 - 0xdf */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0xe0 - 0xef */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0xf0 - 0xff */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 } }; /* Define mappings for each possible code */ key_struct E0keys[128] = { /* 0x00 - 0x0f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x10 - 0x1f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x84 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x81 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x20 - 0x2f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x30 - 0x3f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x40 - 0x4f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x2f, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x50 - 0x5f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x0d, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x60 - 0x6f */ { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x10b, 0x00, 0x00, 0x20b, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x102, 0x00, 0x00, 0x202, 0x00 }, { 0x10a, 0x00, 0x00, 0x20a, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* 0x70 - 0x7f */ { 0x108, 0x00, 0x00, 0x208, 0x00 }, { 0x109, 0x00, 0x00, 0x209, 0x00 }, { 0x101, 0x105, 0x00, 0x201, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x103, 0x00, 0x00, 0x203, 0x00 }, { 0x100, 0x104, 0x00, 0x200, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x104, 0x100, 0x00, 0x204, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x105, 0x101, 0x00, 0x205, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 }, }; /* Special keycodes */ #define KEYCODE_UP 0x100 #define KEYCODE_DOWN 0x101 #define KEYCODE_LEFT 0x102 #define KEYCODE_RIGHT 0x103 #define KEYCODE_PGUP 0x104 #define KEYCODE_PGDN 0x105 #define KEYCODE_INSERT 0x108 #define KEYCODE_DELETE 0x109 #define KEYCODE_HOME 0x10a #define KEYCODE_END 0x10b /* Key modifiers flags */ #define MODIFIER_CTRL 0x01 #define MODIFIER_SHIFT 0x02 #define MODIFIER_ALT 0x04 #define MODIFIER_MASK 0x07 #define MODIFIER_CAPS 0x20 #define MODIFIER_NUM 0x10 #define MODIFIER_SCROLL 0x08 #define MODIFIER_LOCK_MASK 0x38 #define MODIFIER_CAPSLOCK 0x40 #define MODIFIER_NORETURN 0x80 /* Keyboard buffer variables */ #define BUFFER_SIZE 32 #define RAWKBD_BSIZE 128 static int autorepeatkey = -1; static struct kbd_autorepeat kbdautorepeat = { 5, 20 }; static int rawkbd_device = 0; int modifiers = 0; static int kbd_ack = 0; static int kbd_resend = 0; extern int pmap_debug_level; struct kbd_softc { struct device sc_device; irqhandler_t sc_ih; int sc_state; #define RAWKBD_OPEN 0x01 #define KBD_OPEN 0x02 #define RAWKBD_ASLEEP 0x04 int sc_iobase; struct clist sc_q; struct selinfo sc_rsel; struct proc *sc_proc; }; #define KBDUNIT(u) (minor(u) / 2) #define KBDFLAG(u) (minor(u) % 2) #define KBDFLAG_RAWUNIT 0 #define KBDFLAG_CONUNIT 1 int kbdprobe __P((struct device *, void *, void *)); void kbdattach __P((struct device *, struct device *, void *)); int kbdopen __P((dev_t, int, int, struct proc *)); int kbdclose __P((dev_t, int, int, struct proc *)); int kbdread __P((dev_t, struct uio *, int)); int kbdselect __P((dev_t, int, struct proc *)); int kbdioctl __P((dev_t, int, caddr_t, int, struct proc *)); void kbdinit __P((struct kbd_softc *sc)); void kbdsetleds __P((int /*leds*/)); int PollKeyboard __P((int)); int kbddecodekey __P((struct kbd_softc *, int)); int kbdintr __P((struct kbd_softc *)); void autorepeatstart __P((void *)); void autorepeat __P((void *)); struct cfattach kbd_ca = { sizeof(struct kbd_softc), kbdprobe, kbdattach }; struct cfdriver kbd_cd = { NULL, "kbd", DV_TTY }; int kbdprobe(parent, match, aux) struct device *parent; void *match; void *aux; { /* struct mainbus_attach_args *mb = aux;*/ int id; /* Make sure we have an IOMD we understand */ id = ReadByte(IOMD_ID0) | (ReadByte(IOMD_ID1) << 8); /* So far I only know about this IOMD */ switch (id) { case RPC600_IOMD_ID: case RC7500_IOC_ID: return(1); break; default: printf("kbd: Unknown IOMD id=%04x", id); break; } return(0); } void kbdattach(parent, self, aux) struct device *parent; struct device *self; void *aux; { struct kbd_softc *sc = (void *)self; struct mainbus_attach_args *mb = aux; sc->sc_iobase = mb->mb_iobase; kbdinit(sc); printf("\n"); } int kbdopen(dev, flag, mode, p) dev_t dev; int flag; int mode; struct proc *p; { struct kbd_softc *sc; int unit = KBDUNIT(dev); if (unit >= kbd_cd.cd_ndevs) return(ENXIO); sc = kbd_cd.cd_devs[unit]; if (!sc) return(ENXIO); switch (KBDFLAG(dev)) { case KBDFLAG_RAWUNIT : if (sc->sc_state & RAWKBD_OPEN) return(EBUSY); sc->sc_state |= RAWKBD_OPEN; if (clalloc(&sc->sc_q, RAWKBD_BSIZE, 0) == -1) return(ENOMEM); sc->sc_proc = p; rawkbd_device = 1; break; case KBDFLAG_CONUNIT : if (sc->sc_state & KBD_OPEN) return(EBUSY); sc->sc_state |= KBD_OPEN; break; } /* Kill any active autorepeat */ untimeout(autorepeatstart, &autorepeatkey); untimeout(autorepeat, &autorepeatkey); return(0); } int kbdclose(dev, flag, mode, p) dev_t dev; int flag; int mode; struct proc *p; { int unit = KBDUNIT(dev); struct kbd_softc *sc = kbd_cd.cd_devs[unit]; switch (KBDFLAG(dev)) { case KBDFLAG_RAWUNIT : if (!(sc->sc_state & RAWKBD_OPEN)) return(EINVAL); sc->sc_state &= ~RAWKBD_OPEN; clfree(&sc->sc_q); sc->sc_proc = NULL; rawkbd_device = 0; break; case KBDFLAG_CONUNIT : if (!(sc->sc_state & KBD_OPEN)) return(EINVAL); sc->sc_state &= ~KBD_OPEN; break; } return(0); } int kbdread(dev, uio, flag) dev_t dev; struct uio *uio; int flag; { struct kbd_softc *sc = kbd_cd.cd_devs[KBDUNIT(dev)]; int s; int error = 0; size_t length; u_char buffer[128]; if (KBDFLAG(dev) == KBDFLAG_CONUNIT) return(ENXIO); /* Block until keyboard activity occured. */ s = spltty(); while (sc->sc_q.c_cc == 0) { if (flag & IO_NDELAY) { splx(s); return EWOULDBLOCK; } sc->sc_state |= RAWKBD_ASLEEP; if ((error = tsleep((caddr_t)sc, PZERO | PCATCH, "kbdread", 0))) { sc->sc_state &= (~RAWKBD_ASLEEP); splx(s); return error; } } splx(s); /* Transfer as many chunks as possible. */ while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0) { length = min(sc->sc_q.c_cc, uio->uio_resid); if (length > sizeof(buffer)) length = sizeof(buffer); /* Remove a small chunk from the input queue. */ (void) q_to_b(&sc->sc_q, buffer, length); /* Copy the data to the user process. */ if ((error = (uiomove(buffer, length, uio)))) break; } return error; } int kbdselect(dev, rw, p) dev_t dev; int rw; struct proc *p; { struct kbd_softc *sc = kbd_cd.cd_devs[KBDUNIT(dev)]; int s; int ret; if (KBDFLAG(dev) == KBDFLAG_CONUNIT) return(ENXIO); if (rw == FWRITE) return 0; s = spltty(); if (!sc->sc_q.c_cc) { selrecord(p, &sc->sc_rsel); ret = 0; } else ret = 1; splx(s); return ret; } int kbdioctl(dev, cmd, data, flag, p) dev_t dev; int cmd; caddr_t data; int flag; struct proc *p; { /* struct kbd_softc *sc = kbd_cd.cd_devs[KBDUNIT(dev)];*/ struct kbd_autorepeat *kbdar = (void *)data; int *leds = (int *)data; int s; switch (cmd) { case KBD_GETAUTOREPEAT: /* if (KBDFLAG(dev) == KBDFLAG_RAWUNIT) return(EINVAL);*/ *kbdar = kbdautorepeat; break; case KBD_SETAUTOREPEAT: /* if (KBDFLAG(dev) == KBDFLAG_RAWUNIT) return(EINVAL);*/ s = spltty(); kbdautorepeat = *kbdar; if (kbdautorepeat.ka_rate < 1) kbdautorepeat.ka_rate = 1; if (kbdautorepeat.ka_rate > 50) kbdautorepeat.ka_rate = 50; if (kbdautorepeat.ka_delay > 50) kbdautorepeat.ka_delay = 50; if (kbdautorepeat.ka_delay < 1) kbdautorepeat.ka_delay = 1; (void)splx(s); break; case KBD_SETLEDS: kbdsetleds(*leds); break; default: return(ENXIO); } return(0); } void kbdsetleds(leds) int leds; { int loop; if ((ReadByte(IOMD_KBDCR) & 0x80)) { WriteByte(IOMD_KBDDAT, 0xed); loop = 10000; while ((ReadByte(IOMD_KBDCR) & 0x40) && loop > 0) --loop; if ((ReadByte(IOMD_KBDCR) & 0x80)) { WriteByte(IOMD_KBDDAT, leds); loop = 10000; while ((ReadByte(IOMD_KBDCR) & 0x40) && loop > 0) --loop; } } } void kbdsetstate(state) int state; { modifiers = state & MODIFIER_LOCK_MASK; } int kdbgetstate() { return(modifiers); } void kbdinit(sc) struct kbd_softc *sc; { sc->sc_ih.ih_func = kbdintr; sc->sc_ih.ih_arg = sc; sc->sc_ih.ih_level = IPL_TTY; sc->sc_ih.ih_name = "kbd rx"; if (irq_claim(IRQ_KBDRX, &sc->sc_ih)) panic("Cannot claim IRQ for kbd%d", sc->sc_device.dv_unit); modifiers = 0; kbdsetleds((modifiers >> 3) & 7); } int getkey_polled() { int code; int key; int up; key_struct *ks; int s; s = splhigh(); key = 0; do { while ((ReadByte(IOMD_KBDCR) & (1<<5)) == 0) ; /* Read the IOMD keyboard register and process the key */ code = PollKeyboard(ReadByte(IOMD_KBDDAT)); if (code != 0) { up = (code & 0x100); key = code & 0xff; /* printf("code=%04x mod=%04x\n", code, modifiers);*/ /* By default we use the main keycode lookup table */ ks = keys; /* If we have an E0 or E1 sqeuence we use the extended table */ if (code > 0x1ff) ks = E0keys; /* Is the key a temporary modifier ? */ if (ks[key].flags & MODIFIER_MASK) { if (up) modifiers &= ~ks[key].flags; else modifiers |= ks[key].flags; key = 0; continue; } /* Is the key a locking modifier ? */ if (ks[key].flags & MODIFIER_LOCK_MASK) { if (!up) { modifiers ^= ks[key].flags; kbdsetleds((modifiers >> 3) & 7); } key = 0; continue; } /* Lookup the correct key code */ if (modifiers & 0x01) key = ks[key].ctrl_code; else if (modifiers & 0x02) key = ks[key].shift_code; else if (modifiers & 0x04) key = ks[key].alt_code; else key = ks[key].base_code; if (modifiers & MODIFIER_CAPS) { if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z')) key ^= 0x20; } if (up) key = 0; if (!up && key >= 0x200) { #if (NVT > 0) if ((key & ~0x0f) == 0x480) console_switch((key & 0x0f) - 1); else #endif switch (key) { #if (NVT > 0) case 0x201: console_scrollforward(); break; case 0x200: console_scrollback(); break; #endif default: break; } key = 0; } } } while (key == 0); if (key == '\r') key = '\n'; splx(s); return(key); } /* Keyboard IRQ handler */ int kbdintr(sc) struct kbd_softc *sc; { int key; /* Read the IOMD keyboard register and process the key */ key = PollKeyboard(ReadByte(IOMD_KBDDAT)); /* If we have a raw keycode convert it to an ASCII code */ if (key != 0) kbddecodekey(sc, key); return(1); } /* Flags used to decode the raw keys */ #define FLAG_KEYUP 0x01 #define FLAG_E0 0x02 #define FLAG_E1 0x04 static int flags = 0; /* * This function is now misnamed. * It processes the raw key codes from the keyboard and generates * a unique code that can be decoded with the key translation array. */ int PollKeyboard(code) int code; { /* printf("%02x.", code);*/ /* * Set the keyup flag if this is the release code. */ if (code == 0xf0) { flags |= FLAG_KEYUP; return(0); } /* If it is a special code ignore it */ if (code == 0xff || code == 0x00) { flags = 0; return(0); } /* If it is a resend code note it down */ if (code == 0xfe) { printf("kbd:resend\n"); kbd_resend = 1; return(0); } /* If it is an ack code note it down */ if (code == 0xfa) { /* printf("kbd:ack\n");*/ kbd_ack = 1; return(0); } /* Flag the start of an E0 sequence. */ if (code == 0xe0) { flags |= FLAG_E0; return(0); } /* Flag the start of an E1 sequence. */ if (code == 0xe1) { flags |= FLAG_E1; return(0); } /* Ignore any other invalid codes */ if (code > 0x8f) { flags = 0; return(0); } /* printf("%02x:%02x.", code, flags);*/ /* Mark the code appropriately if it is part of an E0 sequence */ if (flags & FLAG_E0) { flags &= ~FLAG_E0; if (code == 0x12) { flags &= ~FLAG_KEYUP; return(0); } code |= 0x200; } /* Mark the key if it is the upcode */ if (flags & FLAG_KEYUP) { flags &= ~FLAG_KEYUP; code |= 0x100; } /* Mark the code appropriately if it is part of an E1 sequence */ if (flags & FLAG_E1) { if ((code & 0xff) == 0x14) { return(0); } flags &= ~FLAG_E1; code |= 0x400; flags &= ~FLAG_KEYUP; } return(code); } /* * This routine decodes the unique keycode and generates an ASCII code * if necessary. */ int kbddecodekey(sc, code) struct kbd_softc *sc; int code; { key_struct *ks; int up; int key; console_unblank(); /* Do we have the raw kbd device open ... */ if (rawkbd_device == 1 && code != 0) { struct kbd_data buffer; int s; /* Add this event to the queue. */ buffer.keycode = code; microtime(&buffer.event_time); s=spltty(); (void) b_to_q((char *)&buffer, sizeof(buffer), &sc->sc_q); splx(s); selwakeup(&sc->sc_rsel); if (sc->sc_state & RAWKBD_ASLEEP) { sc->sc_state &= ~RAWKBD_ASLEEP; wakeup((caddr_t)sc); } psignal(sc->sc_proc, SIGIO); return(1); } up = (code & 0x100); key = code & 0xff; /* By default we use the main keycode lookup table */ ks = keys; /* If we have an E0 or E1 sqeuence we use the extended table */ if (code > 0x1ff) ks = E0keys; /* Is the key a temporary modifier ? */ if (ks[key].flags & MODIFIER_MASK) { if (up) modifiers &= ~ks[key].flags; else modifiers |= ks[key].flags; return(0); } /* Is the key a locking modifier ? */ if (ks[key].flags & MODIFIER_LOCK_MASK) { if (!up) { modifiers ^= ks[key].flags; kbdsetleds((modifiers >> 3) & 7); } return(0); } /* Lookup the correct key code */ if (modifiers & 0x01) key = ks[key].ctrl_code; else if (modifiers & 0x02) key = ks[key].shift_code; else if (modifiers & 0x04) key = ks[key].alt_code; else key = ks[key].base_code; if (modifiers & MODIFIER_CAPS) { if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z')) key ^= 0x20; } /* If no valid code the key is not yet mapped so report error */ #ifdef DEBUG_TERM /* if (key == 0) { char err[80]; sprintf(err, "\n\rUnknown keycode %04x\n\r", code); dprintf(err); }*/ #endif /* If we have an ASCII code insert it into the keyboard buffer */ if (!up && key != 0) { if (key >= 0x200) { untimeout(autorepeatstart, &autorepeatkey); untimeout(autorepeat, &autorepeatkey); autorepeatkey = -1; #if (NVT > 0) if ((key & ~0x0f) == 0x480) console_switch((key & 0x0f) - 1); else #endif switch (key) { case 0x22b: pmap_debug(pmap_debug_level + 1); break; case 0x22d: pmap_debug(pmap_debug_level - 1); break; #if (NVT > 0) case 0x201: console_scrollforward(); break; case 0x200: console_scrollback(); break; case 0x202: console_switchdown(); break; case 0x203: console_switchup(); break; #endif case 0x204: --kbdautorepeat.ka_rate; if (kbdautorepeat.ka_rate < 1) kbdautorepeat.ka_rate = 1; break; case 0x205: ++kbdautorepeat.ka_rate; if (kbdautorepeat.ka_rate > 50) kbdautorepeat.ka_rate = 50; break; case 0x20a: ++kbdautorepeat.ka_delay; if (kbdautorepeat.ka_delay > 50) kbdautorepeat.ka_delay = 50; break; case 0x20b: --kbdautorepeat.ka_delay; if (kbdautorepeat.ka_delay < 1) kbdautorepeat.ka_delay = 1; break; #ifdef DDB case 0x208: Debugger(); break; #endif case 0x21b: printf("Kernel interruption\n"); boot(RB_HALT); break; case 0x209: printf("Kernel interruption - nosync\n"); boot(RB_NOSYNC | RB_HALT); break; default: printf("Special key %04x\n", key); break; } } else { if (physconkbd(key) == 0 && rawkbd_device == 0) { if (autorepeatkey != key) { untimeout(autorepeatstart, &autorepeatkey); untimeout(autorepeat, &autorepeatkey); autorepeatkey = key; timeout(autorepeatstart, &autorepeatkey, hz/kbdautorepeat.ka_delay); } } return(1); } } else { untimeout(autorepeatstart, &autorepeatkey); untimeout(autorepeat, &autorepeatkey); autorepeatkey = -1; } return(0); } void autorepeatstart(key) void *key; { physconkbd(*((int *)key)); timeout(autorepeat, key, hz/kbdautorepeat.ka_rate); } void autorepeat(key) void *key; { physconkbd(*((int *)key)); timeout(autorepeat, key, hz/kbdautorepeat.ka_rate); } /* End of kbd.c */