Add keyboard testing
This commit is contained in:
parent
b3ee12fcc5
commit
766fc0f052
135
kernel.c
135
kernel.c
|
@ -1,3 +1,4 @@
|
|||
//#define PORT_DEBUG
|
||||
/* Based on Bare Bones tutorial on OSDev wiki */
|
||||
|
||||
#include <stdbool.h>
|
||||
|
@ -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("<out ");
|
||||
terminal_writehex(port >> 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("<in ");
|
||||
terminal_writehex(port >> 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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue