/* $NetBSD: cons_zskbd.c,v 1.4 2008/04/28 20:23:18 martin Exp $ */ /*- * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by UCHIYAMA Yasushi. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``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 THE FOUNDATION 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. */ #include #include #include #include #include #include "console.h" struct zskbd zskbd; int zskbd_common_getc(int); void zskbd_busy(void); static const uint8_t map_normal[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '^', '\\', ':', '.', '/', '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', ',', ']', ';', 0x00, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00, '\r', '\r', 0x00, 0x00, '\r', 0x00, '-', '.', 0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x7f, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00, '+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static const uint8_t map_shift[] = { '0', '!', '\"', '#', '$', '%', '&', '\'', '(', ')', '=', '^', '|', '*', '>', '?', '~', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '<', '}', '+', '_', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00, '\r', '\r', 'B', 'C', '\r', 'E', '-', '.', 0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0b, 0x7f, 0x12, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00, '+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static const uint8_t map_ctrl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00, '\r', '\r', 0x00, 0x00, '\r', 0x00, '-', '.', 0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x7f, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00, '+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static const uint8_t map_capslock[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '^', '\\', ':', '.', '/', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', ',', ']', ';', 0x00, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00, '\r', '\r', 0x00, 0x00, '\r', 0x00, '-', '.', 0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x7f, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00, '+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; void zskbd_set_addr(uint32_t status, uint32_t data) { zskbd.status = (volatile uint8_t *)status; zskbd.data = (volatile uint8_t *)data; zskbd.normal = map_normal; zskbd.shift = map_shift; zskbd.ctrl = map_ctrl; zskbd.capslock = map_capslock; cons.getc = zskbd_getc; cons.scan = zskbd_scan; } void zskbd_print_keyscan(int on) { zskbd.print = on; } int zskbd_getc(void) { return zskbd_common_getc(0); } int zskbd_scan(void) { return zskbd_common_getc(1); } int zskbd_common_getc(int scan) { #ifdef CHECK_KEY_RELEASE static int released = 1; int push; #endif int v, c; for (;;) { if (scan) { if ((*zskbd.status & 0x01) != 0x01) return -1; } else { while ((*zskbd.status & 0x01) != 0x01) continue; } v = *zskbd.data; if (zskbd.print) printf("scancode = 0x%x\n", v); switch (v) { case 123: /* Shift-L */ /* FALLTHROUGH */ case 124: /* Shift-R */ zskbd.keymap |= 0x01; break; case 251: /* FALLTHROUGH */ case 252: zskbd.keymap &= ~0x01; break; case 120: /* Ctrl-L */ zskbd.keymap |= 0x02; break; case 248: zskbd.keymap &= ~0x02; break; case 121: /* CapsLock */ if (zskbd.keymap & 0x04) { zskbd.keymap &= ~0x04; zskbd_busy(); *zskbd.data = 0x90; /* LED */ } else { zskbd.keymap |= 0x04; zskbd_busy(); *zskbd.data = 0x92; /* LED */ } break; default: #ifdef CHECK_KEY_RELEASE push = (v & 0x80) == 0; if (push && released) { released = 0; goto exit_loop; } if (!push) released = 1; #else /* CHECK_KEY_RELEASE */ if ((v & 0x80) == 0) goto exit_loop; #endif /* CHECK_KEY_RELEASE */ break; } } exit_loop: c = v & 0x7f; if (zskbd.keymap & 0x01) /* Shift */ return *(zskbd.shift + c); if (zskbd.keymap & 0x02) /* Ctrl */ return *(zskbd.ctrl + c); if (zskbd.keymap & 0x04) /* CapsLock */ return *(zskbd.capslock + c); /* Normal */ return *(zskbd.normal + c); } void zskbd_busy(void) { #if 0 /* I misunderstand??? -uch */ do { while ((*zskbd.status & 0x20) != 0x20) ; } while ((*zskbd.status & 0x4) != 0x4); #endif }