/**************************************************************************************
Copyright (c) 2002
The UbixOS Project
$Id$
**************************************************************************************/
#include <drivers/keyboard.h>
#include <drivers/8259.h>
#include <ubixos/idt.h>
#include <ubixos/gdt.h>
#include <ubixos/io.h>
#include <drivers/video.h>
unsigned int keystrokeBuffer[255];
unsigned int keystrokeBuffersize = 0;
unsigned int controlKeys = 0;
unsigned int keyMap = 0;
unsigned int ledStatus = 0;
unsigned int keyboardMap[][8] = {
/* Ascii, Shift, Ctrl, Alt, Num, Caps, Shift Caps, Shift Num */
{ 0, 0, 0, 0, 0, 0, 0, 0},
/* ESC */ { 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B},
/* 1,! */ { 0x31, 0x21, 0, 0, 0x31, 0x31, 0x21, 0x21},
/* 2,@ */ { 0x32, 0x40, 0, 0, 0x32, 0x32, 0x40, 0x40},
/* 3,# */ { 0x33, 0x23, 0, 0, 0x33, 0x33, 0x23, 0x23},
/* 4,$ */ { 0x34, 0x24, 0, 0, 0x34, 0x34, 0x24, 0x24},
/* 5,% */ { 0x35, 0x25, 0, 0, 0x35, 0x35, 0x25, 0x25},
/* 6,^ */ { 0x36, 0x5E, 0, 0, 0x36, 0x36, 0x5E, 0x5E},
/* 7,& */ { 0x37, 0x26, 0, 0, 0x37, 0x37, 0x26, 0x26},
/* 8,* */ { 0x38, 0x2A, 0, 0, 0x38, 0x38, 0x2A, 0x2A},
/* 9.( */ { 0x39, 0x28, 0, 0, 0x39, 0x39, 0x28, 0x28},
/* 0,) */ { 0x30, 0x29, 0, 0, 0x30, 0x30, 0x29, 0x29},
/* -,_ */ { 0x2D, 0x5F, 0, 0, 0x2D, 0x2D, 0x5F, 0x5F},
/* =,+ */ { 0x3D, 0x2B, 0, 0, 0x3D, 0x3D, 0x2B, 0x2B},
/* */ { 0x08, 0x08, 0, 0, 0x08, 0x08, 0x08, 0x08},
/* */ { 0x09, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x71, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x77, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x65, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x72, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x74, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x79, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x75, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x69, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x6F, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x70, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x5B, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x5D, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x0A, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x61, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x73, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x64, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x66, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x67, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x68, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x6A, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x6B, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x6C, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x3B, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x27, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x60, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x2A, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x5C, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x7A, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x78, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x63, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x76, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x62, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x6E, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x6D, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x2C, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x2E, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x2F, 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},
/* */ { 0x20, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x3B00, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x3C00, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x3D00, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x3E00, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x3F00, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4000, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4100, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4200, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4300, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4400, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4700, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4800, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4900, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x2D, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4B00, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4C00, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4D00, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x2B, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x4F00, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x5000, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x5100, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x5200, 0, 0, 0, 0, 0, 0, 0},
/* */ { 0x5300, 0, 0, 0, 0, 0, 0, 0}
};
void initKeyboard() {
setVector(keyboardIsr, mVec+1, dPresent + dInt + dDpl3); /* IRQ1 Handler */
setLeds();
enableIrq(1);
}
asm(
".globl keyboardIsr \n"
"keyboardIsr: \n"
" pusha \n" /* Save all registers */
" pushw %ds \n" /* Set up the data segment */
" pushw %es \n"
" pushw %ss \n" /* Note that ss is always valid */
" pushw %ss \n"
" popw %ds \n"
" popw %es \n"
" call keyboardHandler \n"
" popw %es \n"
" popw %ds \n" /* Restore registers */
" popa \n"
" iret \n" /* Exit interrupt */
);
void keyboardHandler() {
unsigned int key = inportByte(0x60);
/* Control Key */
if (key == 0x1D && !(controlKeys & controlKey)) {
controlKeys |= controlKey;
}
if (key == 0x80 + 0x1D) {
controlKeys &= (0xFF - controlKey);
}
/* ALT Key */
if (key == 0x38 && (!controlKeys & altKey)) {
controlKeys |= altKey;
}
if (key == 0x80 + 0x38) {
controlKeys &= (0xFF - altKey);
}
/* Shift Key */
if ((key == 0x2A || key == 0x36) && !(controlKeys & shiftKey)) {
controlKeys |= shiftKey;
}
if ((key == 0x80 + 0x2A) || (key == 0x80 + 0x36)) {
controlKeys &= (0xFF - shiftKey);
}
/* Caps Lock */
if (key == 0x3A) {
ledStatus ^= ledCapslock;
setLeds();
}
/* Num Lock */
if (key == 0x45) {
ledStatus ^= ledNumlock;
setLeds();
}
/* Scroll Lock */
if (key == 0x46) {
ledStatus ^= ledScrolllock;
setLeds();
}
/* Pick Which Key Map */
keystrokeBuffer[keystrokeBuffersize] = keyboardMap[key][keyMap];
keystrokeBuffersize++;
outportByte(mPic, eoi);
}
void setLeds() {
outportByte(0x60, 0xED);
while(inportByte(0x64) & 2);
outportByte(0x60, ledStatus);
while(inportByte(0x64) & 2);
}