From 766fc0f052c2050b13fee6b39e79d82b8a3b8988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Sun, 23 Jan 2022 16:27:08 +0200 Subject: [PATCH] Add keyboard testing --- kernel.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 1 deletion(-) diff --git a/kernel.c b/kernel.c index f0ddbe3..b756085 100644 --- a/kernel.c +++ b/kernel.c @@ -1,3 +1,4 @@ +//#define PORT_DEBUG /* Based on Bare Bones tutorial on OSDev wiki */ #include @@ -112,9 +113,24 @@ void terminal_writestring(const char* data) terminal_write(data, strlen(data)); } +const char hex[] = "0123456789abcdef"; + +void terminal_writehex(uint8_t byte) { + terminal_putchar(hex[byte >> 4]); + terminal_putchar(hex[byte & 0xf]); +} + // (out|in)port from sortix, Copyright (c) 2014, 2015 Jonas 'Sortie' Termansen. void outport8(uint16_t port, uint8_t value) { +#ifdef PORT_DEBUG + terminal_writestring("> 8); + terminal_writehex(port); + terminal_writestring(" "); + terminal_writehex(value); + terminal_writestring(">"); +#endif asm volatile ("outb %1, %0" : : "dN" (port), "a" (value)); } @@ -122,6 +138,14 @@ uint8_t inport8(uint16_t port) { uint8_t result; asm volatile("inb %1, %0" : "=a" (result) : "dN" (port)); +#ifdef PORT_DEBUG + terminal_writestring("> 8); + terminal_writehex(port); + terminal_writestring(" "); + terminal_writehex(result); + terminal_writestring(">"); +#endif return result; } @@ -232,13 +256,122 @@ void disable_translation(void) { write_config_8042(config); } +uint8_t read_keyboard(void) { + while (!(status_8042() & (1<<0))); + return read_8042(); +} + +void enable_scanning(void) { + write_8042(0xf4); + if (read_keyboard() != 0xfa) + terminal_writestring("Enabling scanning failed\n"); + while (status_8042() & (1<<0)) + (void) read_8042(); +} + +void disable_scanning(void) { + write_8042(0xf5); + if (read_keyboard() != 0xfa) + terminal_writestring("Disabling scanning failed\n"); + while (status_8042() & (1<<0)) + (void) read_8042(); +} + +void set_scancode_set(uint8_t set) { + write_8042(0xf0); + write_8042(set); + if (read_keyboard() != 0xfa) + terminal_writestring("Setting scancode set failed\n"); + while (status_8042() & (1<<0)) + (void) read_8042(); +} + +uint8_t get_scancode_set(void) { + write_8042(0xf0); + write_8042(0); + if (read_keyboard() != 0xfa) + terminal_writestring("Getting scancode set failed\n"); + uint8_t set; + while ( (set = read_keyboard()) == 0xfa ); + return set; +} + +#define KEY_A_SET1 0x1e +#define KEY_A_SET2 0x1c +#define KEY_A_MISINTERPRET 0x03 + +void print_key(uint8_t code) { + switch (code) { + case KEY_A_SET1: terminal_writestring("Set 1 A"); break; + case KEY_A_SET2: terminal_writestring("Set 2 A"); break; + case KEY_A_MISINTERPRET: terminal_writestring("Set 1 A misinterpreted as set 2 A"); break; + default: + terminal_writestring("Unknown byte "); + terminal_writehex(code); + break; + } +} + +void key_prompt(uint8_t expect) { + enable_scanning(); + terminal_writestring("Press A... "); + uint8_t code = read_keyboard(); + if ( code == expect ) + terminal_setcolor(vga_entry_color(VGA_COLOR_GREEN, VGA_COLOR_BLACK)); + else + terminal_setcolor(vga_entry_color(VGA_COLOR_RED, VGA_COLOR_BLACK)); + print_key(code); + if ( code == expect ) + terminal_writestring("\n"); + else + terminal_writestring("(!)\n"); + terminal_setcolor(vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK)); + read_keyboard(); // Key up + disable_scanning(); +} + void kernel_main(void) { /* Initialize terminal interface */ terminal_initialize(); init_8042(); - if (single_channel) + terminal_writestring("Assuming keyboard is channel 1\n"); + + terminal_writestring("\nTranslation initially "); + if (translation_initially) + terminal_writestring("on\n"); + else + terminal_writestring("off\n"); + key_prompt(translation_initially ? KEY_A_SET1 : KEY_A_SET2); + + disable_translation(); + terminal_writestring("\nTranslation off, scancode set initially "); + uint8_t initial_scancode = get_scancode_set(); + terminal_writehex(initial_scancode); + terminal_writestring("\n"); + key_prompt(initial_scancode == 1 ? KEY_A_SET1 : KEY_A_SET2); + + set_scancode_set(1); + terminal_writestring("Translation off, trying set 1... scancode set set to "); + terminal_writehex(get_scancode_set()); + terminal_writestring("\n"); + key_prompt(KEY_A_SET1); + + set_scancode_set(2); + terminal_writestring("Translation off, trying set 2... scancode set set to "); + terminal_writehex(get_scancode_set()); + terminal_writestring("\n"); + key_prompt(KEY_A_SET2); + + set_scancode_set(1); + enable_translation(); + terminal_writestring("\nTranslation on, trying set 1\n"); + key_prompt(KEY_A_MISINTERPRET); + + set_scancode_set(2); + terminal_writestring("Translation on, trying set 2\n"); + key_prompt(KEY_A_SET1); terminal_writestring("\nHanging\n"); }