memtest86plus/system/keyboard.c

247 lines
5.9 KiB
C

// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2020-2021 Martin Whitaker.
#include <stdint.h>
#include "io.h"
#include "usbhcd.h"
#include "keyboard.h"
//------------------------------------------------------------------------------
// Private Variables
//------------------------------------------------------------------------------
// Convert set 1 scancodes to characters.
static const char legacy_keymap[] = {
/* 0x00 */ 0,
/* 0x01 */ ESC,
/* 0x02 */ '1',
/* 0x03 */ '2',
/* 0x04 */ '3',
/* 0x05 */ '4',
/* 0x06 */ '5',
/* 0x07 */ '6',
/* 0x08 */ '7',
/* 0x09 */ '8',
/* 0x0a */ '9',
/* 0x0b */ '0',
/* 0x0c */ '-',
/* 0x0d */ '+',
/* 0x0e */ '\b',
/* 0x0f */ '\t',
/* 0x10 */ 'q',
/* 0x11 */ 'w',
/* 0x12 */ 'e',
/* 0x13 */ 'r',
/* 0x14 */ 't',
/* 0x15 */ 'y',
/* 0x16 */ 'u',
/* 0x17 */ 'i',
/* 0x18 */ 'o',
/* 0x19 */ 'p',
/* 0x1a */ '[',
/* 0x1b */ ']',
/* 0x1c */ '\n',
/* 0x1d */ 0,
/* 0x1e */ 'a',
/* 0x1f */ 's',
/* 0x20 */ 'd',
/* 0x21 */ 'f',
/* 0x22 */ 'g',
/* 0x23 */ 'h',
/* 0x24 */ 'j',
/* 0x25 */ 'k',
/* 0x26 */ 'l',
/* 0x27 */ ';',
/* 0x28 */ '\'',
/* 0x29 */ '`',
/* 0x2a */ 0,
/* 0x2b */ '\\',
/* 0x2c */ 'z',
/* 0x2d */ 'x',
/* 0x2e */ 'c',
/* 0x2f */ 'v',
/* 0x30 */ 'b',
/* 0x31 */ 'n',
/* 0x32 */ 'm',
/* 0x33 */ ',',
/* 0x34 */ '.',
/* 0x35 */ '/',
/* 0x36 */ 0,
/* 0x37 */ '*', // keypad
/* 0x38 */ 0,
/* 0x39 */ ' ',
/* 0x3a */ 0,
/* 0x3b */ '1', // F1
/* 0x3c */ '2', // F2
/* 0x3d */ '3', // F3
/* 0x3e */ '4', // F4
/* 0x3f */ '5', // F5
/* 0x40 */ '6', // F6
/* 0x41 */ '7', // F7
/* 0x42 */ '8', // F8
/* 0x43 */ '9', // F9
/* 0x44 */ '0', // F10
/* 0x45 */ 0,
/* 0x46 */ 0,
/* 0x47 */ '7', // keypad
/* 0x48 */ '8', // keypad
/* 0x49 */ '9', // keypad
/* 0x4a */ '-', // keypad
/* 0x4b */ '4', // keypad
/* 0x4c */ '5', // keypad
/* 0x4d */ '6', // keypad
/* 0x4e */ '+', // keypad
/* 0x4f */ '1', // keypad
/* 0x50 */ '2', // keypad
/* 0x51 */ '3', // keypad
/* 0x52 */ '0', // keypad
/* 0x53 */ '.', // keypad
};
// Convert USB HID keycodes to characters.
static const char usb_hid_keymap[] = {
/* 0x00 */ 0,
/* 0x01 */ 0,
/* 0x02 */ 0,
/* 0x03 */ 0,
/* 0x04 */ 'a',
/* 0x05 */ 'b',
/* 0x06 */ 'c',
/* 0x07 */ 'd',
/* 0x08 */ 'e',
/* 0x09 */ 'f',
/* 0x0a */ 'g',
/* 0x0b */ 'h',
/* 0x0c */ 'i',
/* 0x0d */ 'j',
/* 0x0e */ 'k',
/* 0x0f */ 'l',
/* 0x10 */ 'm',
/* 0x11 */ 'n',
/* 0x12 */ 'o',
/* 0x13 */ 'p',
/* 0x14 */ 'q',
/* 0x15 */ 'r',
/* 0x16 */ 's',
/* 0x17 */ 't',
/* 0x18 */ 'u',
/* 0x19 */ 'v',
/* 0x1a */ 'w',
/* 0x1b */ 'x',
/* 0x1c */ 'y',
/* 0x1d */ 'z',
/* 0x1e */ '1',
/* 0x1f */ '2',
/* 0x20 */ '3',
/* 0x21 */ '4',
/* 0x22 */ '5',
/* 0x23 */ '6',
/* 0x24 */ '7',
/* 0x25 */ '8',
/* 0x26 */ '9',
/* 0x27 */ '0',
/* 0x28 */ '\n',
/* 0x29 */ ESC,
/* 0x2a */ '\b',
/* 0x2b */ '\t',
/* 0x2c */ ' ',
/* 0x2d */ '-',
/* 0x2e */ '+',
/* 0x2f */ '[',
/* 0x30 */ ']',
/* 0x31 */ '\\',
/* 0x32 */ '#',
/* 0x33 */ ';',
/* 0x34 */ '\'',
/* 0x35 */ '`',
/* 0x36 */ ',',
/* 0x37 */ '.',
/* 0x38 */ '/',
/* 0x39 */ 0, // Caps Lock
/* 0x3a */ '1', // F1
/* 0x3b */ '2', // F2
/* 0x3c */ '3', // F3
/* 0x3d */ '4', // F4
/* 0x3e */ '5', // F5
/* 0x3f */ '6', // F6
/* 0x40 */ '7', // F7
/* 0x41 */ '8', // F8
/* 0x42 */ '9', // F9
/* 0x43 */ '0', // F10
/* 0x44 */ 0, // F11
/* 0x45 */ 0, // F12
/* 0x46 */ 0, // Print Screen
/* 0x47 */ 0, // Scroll Lock
/* 0x48 */ 0, // Pause
/* 0x49 */ 0, // Insert
/* 0x4a */ 0, // Delete
/* 0x4b */ 0, // Home
/* 0x4c */ 0, // Page Up
/* 0x4d */ 0, // Delete
/* 0x4e */ 0, // Page Down
/* 0x4f */ 0, // Cursor Right
/* 0x50 */ 0, // Cursor Left
/* 0x51 */ 0, // Cursor Down
/* 0x52 */ 0, // Cursor Up
/* 0x53 */ 0, // Number Lock
/* 0x54 */ '/', // keypad
/* 0x55 */ '*', // keypad
/* 0x56 */ '-', // keypad
/* 0x57 */ '+', // keypad
/* 0x58 */ '\n', // keypad
/* 0x59 */ '1', // keypad
/* 0x5a */ '2', // keypad
/* 0x5b */ '3', // keypad
/* 0x5c */ '4', // keypad
/* 0x5d */ '5', // keypad
/* 0x5e */ '6', // keypad
/* 0x5f */ '7', // keypad
/* 0x60 */ '8', // keypad
/* 0x61 */ '9', // keypad
/* 0x62 */ '0', // keypad
/* 0x63 */ '.', // keypad
/* 0x64 */ '\\', // Non-US
};
//------------------------------------------------------------------------------
// Public Variables
//------------------------------------------------------------------------------
keyboard_types_t keyboard_types = KT_LEGACY | KT_USB;
//------------------------------------------------------------------------------
// Public Functions
//------------------------------------------------------------------------------
void keyboard_init(bool pause_at_end)
{
if (keyboard_types & KT_USB) {
find_usb_keyboards(pause_at_end);
}
}
char get_key(void)
{
if (keyboard_types & KT_USB) {
uint8_t c = get_usb_keycode();
if (c > 0 && c < sizeof(usb_hid_keymap)) {
return usb_hid_keymap[c];
}
}
if (keyboard_types & KT_LEGACY) {
uint8_t c = inb(0x64);
if (c & 0x01) {
c = inb(0x60);
if (c < sizeof(legacy_keymap)) {
return legacy_keymap[c];
}
// Ignore keys we don't recognise and key up codes
}
}
return '\0';
}