/* $NetBSD: kbd.c,v 1.1 1996/01/31 23:24:44 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 * Last updated : 21/05/95 * * $Id: kbd.c,v 1.1 1996/01/31 23:24:44 mark Exp $ */ #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, 0x00, 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 caddr_t kbd_wakeup = 0; static volatile int buffer_ins_ptr = 0; static volatile int buffer_rem_ptr = 0; static int kbdbuffer[BUFFER_SIZE]; int kbdinited = 0; static int autorepeatkey = -1; static struct kbd_autorepeat kbdautorepeat = { 5, 20 }; int rawkbd_device = 0; int modifiers; 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 *)); int key_buffer_insert __P((int)); struct cfdriver kbdcd = { NULL, "kbd", kbdprobe, kbdattach, DV_TTY, sizeof(struct kbd_softc) }; 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 */ if (id == RPC600_IOMD_ID) return(1); 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 >= kbdcd.cd_ndevs) return(ENXIO); sc = kbdcd.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 = kbdcd.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 = kbdcd.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 = kbdcd.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 = kbdcd.cd_devs[KBDUNIT(dev)];*/ struct kbd_autorepeat *kbdar = (void *)data; int *leds = (int *)data; 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);*/ 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; 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; { buffer_ins_ptr = 0; buffer_rem_ptr = 0; sc->sc_ih.ih_func = kbdintr; sc->sc_ih.ih_arg = sc; sc->sc_ih.ih_level = IPL_TTY; if (irq_claim(IRQ_KBDRX, &sc->sc_ih) == -1) panic("Cannot install keyboard handler\n"); kbdinited = 1; /* kbdstate = KBD_STATE_IDLE;*/ modifiers = 0; kbdsetleds((modifiers >> 3) & 7); } /* void testkbd(void) { int key; SetCPSR(I32_bit | F32_bit, F32_bit); splx((1 << IRQ_KBDRX)); do { printf("key: "); key = GetKey(); printf(" %02x\n", key); } while (key != 0x04); splhigh(); } */ /* Test routine to return raw keycodes */ /* int GetKey(void) { int code; char buffer[8]; do { code = ReadByte(IOMD_KBDDAT); sprintf(buffer, "%02x ", code); text(&display, buffer); } while(code != 0x29); return(0x04); } */ int KBD_Empty(void) { return(buffer_ins_ptr == buffer_rem_ptr); } /* Wait for a key in the keyboard buffer and returns am ASCII code */ int GetKey(void) { int key; /* Wait for something in the keyboard buffer */ while (buffer_ins_ptr == buffer_rem_ptr) { } /* Extract the keycode, updating the buffer pointer */ key = kbdbuffer[buffer_rem_ptr]; ++buffer_rem_ptr; if (buffer_rem_ptr >= BUFFER_SIZE) buffer_rem_ptr = 0; return(key); } int WaitForKey(ident) caddr_t ident; { int key; /* Wait for something in the keyboard buffer */ if (ident == 0) return(GetKey()); while (buffer_ins_ptr == buffer_rem_ptr) { kbd_wakeup = ident; tsleep(ident, PVM, "kdbwait", 0); } /* Extract the keycode, updating the buffer pointer */ key = kbdbuffer[buffer_rem_ptr]; ++buffer_rem_ptr; if (buffer_rem_ptr >= BUFFER_SIZE) buffer_rem_ptr = 0; 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) { if (kbddecodekey(sc, key)) { if (kbd_wakeup) { wakeup(kbd_wakeup); kbd_wakeup = 0; } } } 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; 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); } } else { key_buffer_insert(key); } 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); } int key_buffer_insert(byte) int byte; { int s; s = splimp(); kbdbuffer[buffer_ins_ptr] = byte; ++buffer_ins_ptr; if (buffer_ins_ptr >= BUFFER_SIZE) buffer_ins_ptr = 0; splx(s); return(0); } /* End of keys.c */