quinn-os/keyboard.c
2015-08-30 21:23:50 +10:00

187 lines
3.4 KiB
C

#include "interrupts.h"
#include "io.h"
#include "console.h"
#include "shell.h"
#define KEYBOARD_KEY_LSHIFT 0x2A
#define KEYBOARD_KEY_RSHIFT 0x36
#define KEYBOARD_KEY_ENTER 0x1C
#define KEYBOARD_KEY_BSPACE 0x66
#define KEYBOARD_KEY_LCTRL 0x14
#define KEYBOARD_KEY_CAPS 0x58
#define KEYBOARD_KEY_F9 0x01
#define KEYBOARD_KEY_F5 0x03
#define KEYBOARD_KEY_F3 0x04
#define KEYBOARD_KEY_F1 0x05
#define KEYBOARD_KEY_F2 0x06
#define KEYBOARD_KEY_F12 0x07
#define KEYBOARD_KEY_F10 0x09
#define KEYBOARD_KEY_F8 0x0A
#define KEYBOARD_KEY_F6 0x0B
#define KEYBOARD_KEY_F4 0x0C
#define KEYBOARD_KEY_TAB 0x0D
#define KEYBOARD_KEY_LALT 0x11
unsigned char ack;
unsigned char capslock;
unsigned char lshift;
unsigned char rshift;
void (*keyboard_dest)(char c);
static const char keyChars_set1[] = {
0, 27, '1', '2',
'3', '4', '5', '6',
'7', '8', '9', '0',
'-', '=', '\b', '\t',
'q', 'w', 'e', 'r',
't', 'y', 'u', 'i',
'o', 'p', '[', ']',
'\n', 0, 'a', 's',
'd', 'f', 'g', 'h',
'j', 'k', 'l', ';',
'\'', '`', 0, '\\',
'z', 'x', 'c', 'v',
'b', 'n', 'm', ',',
'.', '/', 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, 0,
0, 0, 0, 0
};
static const char keyChars_set1_s[] = {
0, 27, '!', '@',
'#', '$', '%', '^',
'&', '*', '(', ')',
'_', '+', '\b', '\t',
'Q', 'W', 'E', 'R',
'T', 'Y', 'U', 'I',
'O', 'P', '{', '}',
0, 0, 'A', 'S',
'D', 'F', 'G', 'H',
'J', 'K', 'L', ':',
'"', '~', 0, '|',
'Z', 'X', 'C', 'V',
'B', 'N', 'M', '<',
'>', '?', 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, 0,
0, 0, 0, 0
};
static const char keyChars_set2[] = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, '\t', '`', 0,
0, 0, 0, 0,
0, 'q', '1', 0,
0, 0, 'z', 0,
'a', 'w', '2', 0,
0, 'c', 'x', 'd',
'e', '4', '3', 0,
0, ' ', 'v', 'f',
't', 'r', '5', 0,
0, 'n', 'b', 'h',
'g', 'y', '6', 0,
0, 0, 'm', 'j',
'u', '7', '8', 0,
0, ',', 'k', 'i',
'o', '0', '9', 0,
0, '.', '/', 'l',
';', 'p', '-', 0,
0, 0, '\'', 0,
'[', '=', 0, 0,
0, 0, 0, ']',
0, '\\', 0, 0};
void keyboard_handler(struct regs *r) {
unsigned char scancode;
scancode = inportb(0x60);
if (scancode == 0xFA) {
ack = 1;
return;
}
if (scancode & 0x80) {
scancode &= 0x7F;
if (scancode == KEYBOARD_KEY_LSHIFT) {
lshift = 0;
}
if (scancode == KEYBOARD_KEY_RSHIFT) {
rshift = 0;
}
} else {
if (scancode == KEYBOARD_KEY_LSHIFT) {
lshift = 1;
}
if (scancode == KEYBOARD_KEY_RSHIFT) {
rshift = 1;
}
if (scancode > 0x00 && scancode < 0x57) {
if (lshift || rshift) {
if (keyChars_set1_s[scancode] != 0) {
if (keyboard_dest != (void *)0) {
keyboard_dest(keyChars_set1_s[scancode]);
} else {
kprintf("Keyboard dest == NULL");
}
}
} else {
if (keyChars_set1[scancode] != 0) {
if (keyboard_dest != (void *)0) {
keyboard_dest(keyChars_set1[scancode]);
} else {
kprintf("Keyboard dest == NULL");
}
}
}
} else {
kprintf("scancode %x\n", scancode);
}
}
}
void keyboard_scancode_set2(void) {
ack = 0;
outportb(0x60, 0xF0);
while (ack == 0);
ack = 0;
outportb(0x60, 0x02);
while (ack == 0);
ack = 0;
}
void keyboard_set_handler(void (*keyboard_d)(char c)) {
keyboard_dest = keyboard_d;
}
void init_keyboard() {
irq_install_handler(1, keyboard_handler, 0);
capslock = 0;
lshift = 0;
rshift = 0;
}