Shitty broken keyboard driver BUT azerty-compatible
This commit is contained in:
230
src/kbd/ps2.c
Normal file
230
src/kbd/ps2.c
Normal file
@@ -0,0 +1,230 @@
|
||||
// PS/2 Keyboard support
|
||||
|
||||
#include "../io/serial.h"
|
||||
#include "../io/printf.h"
|
||||
#include "ps2.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// The key status bitfield will be used to see if ALT, CONTROL, or SHIFT is pressed
|
||||
uint8_t key_status = 0b00000000;
|
||||
|
||||
// Keymap pointers so we can change between different layouts
|
||||
unsigned char* keymap;
|
||||
unsigned char* keymap_shifted;
|
||||
|
||||
unsigned char kbdus[128] =
|
||||
{
|
||||
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
|
||||
'9', '0', '-', '=', '\b', /* Backspace */
|
||||
'\t', /* Tab */
|
||||
'q', 'w', 'e', 'r', /* 19 */
|
||||
't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */
|
||||
CTRL, /* 29 - Control */
|
||||
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */
|
||||
'\'', '`', SHIFT, /* Left shift */
|
||||
'\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */
|
||||
'm', ',', '.', '/', SHIFT, /* Right shift */
|
||||
'*',
|
||||
ALT, /* Alt */
|
||||
' ', /* Space bar */
|
||||
0, /* Caps lock */
|
||||
0, /* 59 - F1 key ... > */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, /* < ... F10 */
|
||||
0, /* 69 - Num lock*/
|
||||
0, /* Scroll Lock */
|
||||
0, /* Home key */
|
||||
0, /* Up Arrow */
|
||||
0, /* Page Up */
|
||||
'-',
|
||||
0, /* Left Arrow */
|
||||
0,
|
||||
0, /* Right Arrow */
|
||||
'+',
|
||||
0, /* 79 - End key*/
|
||||
0, /* Down Arrow */
|
||||
0, /* Page Down */
|
||||
0, /* Insert Key */
|
||||
0, /* Delete Key */
|
||||
0, 0, 0,
|
||||
0, /* F11 Key */
|
||||
0, /* F12 Key */
|
||||
0, /* All other keys are undefined */
|
||||
};
|
||||
|
||||
unsigned char kbdus_shifted[128] =
|
||||
{
|
||||
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', /* 9 */
|
||||
'(', ')', '_', '+', '\b', /* Backspace */
|
||||
'\t', /* Tab */
|
||||
'Q', 'W', 'E', 'R', /* 19 */
|
||||
'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', /* Enter */
|
||||
CTRL, /* 29 */
|
||||
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 39 */
|
||||
'"', '~', SHIFT, /* Left shift */
|
||||
'|', 'Z', 'X', 'C', 'V', 'B', 'N', /* 49 */
|
||||
'M', '<', '>', '?', SHIFT, /* Right shift */
|
||||
'*',
|
||||
ALT, /* Alt */
|
||||
' ', /* Space */
|
||||
0, /* Caps lock */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, /* F10 */
|
||||
0, /* Num lock */
|
||||
0, /* Scroll lock */
|
||||
0, 0, 0,
|
||||
'-',
|
||||
0, 0, 0,
|
||||
'+',
|
||||
0, 0, 0,
|
||||
0, 0,
|
||||
0, 0, 0,
|
||||
0, /* F11 */
|
||||
0 /* F12 */
|
||||
};
|
||||
|
||||
// NOT THE REAL FR KEYMAP!!
|
||||
// Some French keys have accents or weird symbols that aren't part of ASCII
|
||||
// so they won't fit in 1 char. As a substitute for now, these will be
|
||||
// changed to their ASCII counterparts (without accents, etc.)
|
||||
unsigned char kbdfr[128] =
|
||||
{
|
||||
0, 27, '&', 'e', '"', '\'', '(', '-', 'e', '_',
|
||||
'c', 'a', ')', '=', '\b',
|
||||
'\t',
|
||||
'a', 'z', 'e', 'r',
|
||||
't', 'y', 'u', 'i', 'o', 'p', '^', '$', '\n',
|
||||
CTRL,
|
||||
'q', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm',
|
||||
'u', '`', SHIFT,
|
||||
'*', 'w', 'x', 'c', 'v', 'b', 'n',
|
||||
',', ';', ':', '!', SHIFT,
|
||||
'*',
|
||||
ALT,
|
||||
' ',
|
||||
0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0,
|
||||
'-',
|
||||
0, 0, 0,
|
||||
'+',
|
||||
0, 0, 0,
|
||||
0, 0,
|
||||
0, 0, 0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
unsigned char kbdfr_shifted[128] =
|
||||
{
|
||||
0, 27, '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
'9', '0', '^', '+', '\b',
|
||||
'\t',
|
||||
'A', 'Z', 'E', 'R',
|
||||
'T', 'Y', 'U', 'I', 'O', 'P', '^', 'L', '\n',
|
||||
CTRL,
|
||||
'Q', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M',
|
||||
'%', '~', SHIFT,
|
||||
'u', 'W', 'X', 'C', 'V', 'B', 'N',
|
||||
'?', '.', '/', 'S', SHIFT,
|
||||
'*',
|
||||
ALT,
|
||||
' ',
|
||||
0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0,
|
||||
'-',
|
||||
0, 0, 0,
|
||||
'+',
|
||||
0, 0, 0,
|
||||
0, 0,
|
||||
0, 0, 0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
void keyboard_handler()
|
||||
{
|
||||
unsigned char scancode = inb(0x60);
|
||||
|
||||
// Key release (bit 7 set)
|
||||
if (scancode & 0x80)
|
||||
{
|
||||
if (key_status & SHIFT_PRESSED)
|
||||
{
|
||||
serial_kputs("SHIFT was released!\n");
|
||||
key_status &= ~(1 << 0); // Unset SHIFT bit
|
||||
}
|
||||
|
||||
if (key_status & ALT_PRESSED)
|
||||
{
|
||||
serial_kputs("ALT was released!\n");
|
||||
key_status &= ~(1 << 1); // Unset ALT bit
|
||||
}
|
||||
|
||||
if (key_status & CTRL_PRESSED)
|
||||
{
|
||||
serial_kputs("CTRL was released!\n");
|
||||
key_status &= ~(1 << 2); // Unset CTRL bit
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Key press
|
||||
unsigned char character;
|
||||
|
||||
switch (keymap[scancode])
|
||||
{
|
||||
case SHIFT:
|
||||
serial_kputs("SHIFT ");
|
||||
key_status |= (1 << 0); // SHIFT bit
|
||||
break;
|
||||
case ALT:
|
||||
serial_kputs("ALT ");
|
||||
key_status |= (1 << 1);
|
||||
break;
|
||||
case CTRL:
|
||||
serial_kputs("CTRL ");
|
||||
key_status |= (1 << 2);
|
||||
break;
|
||||
default:
|
||||
character = (key_status & SHIFT_PRESSED) ? keymap_shifted[scancode] : keymap[scancode];
|
||||
printf("%c", character);
|
||||
break;
|
||||
}
|
||||
|
||||
// Should we get a SHIFTED char or a regular one?
|
||||
serial_kputs("key pressed!\n");
|
||||
}
|
||||
|
||||
// End of Interrupt (to master PIC)
|
||||
outb(0x20, 0x20);
|
||||
}
|
||||
|
||||
void keyboard_init(unsigned char layout)
|
||||
{
|
||||
// Here we might go and select PS/2, USB, or other... (once we implement multiple keyboard protocols)
|
||||
|
||||
// Keyboard layout selection
|
||||
switch (layout)
|
||||
{
|
||||
case US:
|
||||
keymap = kbdus;
|
||||
keymap_shifted = kbdus_shifted;
|
||||
break;
|
||||
case FR:
|
||||
keymap = kbdfr;
|
||||
keymap_shifted = kbdfr_shifted;
|
||||
break;
|
||||
|
||||
default:
|
||||
serial_kputs("Unsupported layout.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user