Code: Select all
#ifndef _SCANCODE_H_
#define _SCANCODE_H_
char scancodes[] = {
0,
0, //ESC
'1','2', '3', '4', '5', '6', '7', '8', '9', '0',
'-', '=',
8, //BACKSPACE
'\t',//TAB
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
'\n', //ENTER
0, //CTRL
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
0, //LEFT SHIFT,
'\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/',
0, //RIGHT SHIFT,
'*', //NUMPAD
0, //ALT
' ', //SPACE
0, //CAPSLOCK
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //F1 - F10
0, //NUMLOCK
0, //SCROLLOCK
0, //HOME
0,
0, //PAGE UP
'-', //NUMPAD
0, 0,
0, //(r)
'+', //NUMPAD
0, //END
0,
0, //PAGE DOWN
0, //INS
0, //DEL
0, //SYS RQ
0,
0, 0, //F11-F12
0,
0, 0, 0, //F13-F15
0, 0, 0, 0, 0, 0, 0, 0, 0, //F16-F24
0, 0, 0, 0, 0, 0, 0, 0
};
char scancodes_shifted[] = {
0,
0, //ESC
'!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
'_', '+',
8, //BACKSPACE
'\t',//TAB
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}',
'\n', //ENTER
0, //CTRL
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
0, //LEFT SHIFT,
'|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?',
0, //RIGHT SHIFT,
'*', //NUMPAD
0, //ALT
' ', //SPACE
0, //CAPSLOCK
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //F1 - F10
0, //NUMLOCK
0, //SCROLLOCK
0, //HOME
0,
0, //PAGE UP
'-', //NUMPAD
0, 0,
0, //(r)
'+', //NUMPAD
0, //END
0,
0, //PAGE DOWN
0, //INS
0, //DEL
0, //SYS RQ
0,
0, 0, //F11-F12
0,
0, 0, 0, //F13-F15
0, 0, 0, 0, 0, 0, 0, 0, 0, //F16-F24
0, 0, 0, 0, 0, 0, 0, 0
};
#endif
Code: Select all
#include "scancode.h"
#define IRQ_HANDLER(func) void func (void);\
asm(#func ": pusha \n call _" #func " \n movb $0x20, %al \n outb %al, $0x20 \n popa \n iret \n");\
void _ ## func(void)
IRQ_HANDLER(irq_timer)
{
}
char shift = 0;
IRQ_HANDLER(irq_keyboard)
{
unsigned char scancode, ascii;
unsigned char creg;
scancode = inportb(0x60);
switch(scancode) {
case 0x36:
case 0x2A:
shift = 1;
break;
case 0x36 + 0x80:
case 0x2A + 0x80:
shift = 0;
break;
default:
if(scancode >= 0x80) {
} else {
if(shift){
ascii = scancodes_shifted[scancode];
} else {
ascii = scancodes[scancode];
}
if(ascii != 0) {
ungetc(ascii);
}
}
break;
}
creg = inportb(0x61);
creg |= 1;
outportb(0x61, creg);
}
void init_interrupts()
{
i_install(0x20, &irq_timer, 0x8e);
i_install(0x21, &irq_keyboard, 0x8e);
i_setup();
i_enable();
}
Code: Select all
#define IDT_TABLE 0x100000
#define IDT_REG 0x100800
#define SYS_CODE_SELECTOR 0x8
void i_install(unsigned char vector, void (*func)(), unsigned char type)
{
char * idt_table=IDT_TABLE;
unsigned char i;
unsigned char b[8];
b[0]= (unsigned int)func & 0x000000FF;
b[1]=( (unsigned int)func & 0x0000FF00) >> 8;
b[2]=SYS_CODE_SELECTOR;
b[3]=0;
b[4]=0;
b[5]=type;
b[6]=( (unsigned int)func & 0x00FF0000) >> 16;
b[7]=( (unsigned int)func & 0xFF000000) >> 24;
for(i=0;i<8;i++){
*(idt_table+vector*8+i)=b[i];
}
}
void i_setup()
{
unsigned short *table_limit = IDT_REG;
unsigned int *table_address = IDT_REG+2;
*table_limit = 256*8 - 1;
*table_address = IDT_TABLE;
asm("lidt 0(,%0,)"::"a"(IDT_REG));
}
void i_enable()
{
asm("sti");
}
void i_disable()
{
asm("cli");
}
Code: Select all
__inline__ void outportb(unsigned short port, unsigned char value)
{
asm("outb %b0,%w1":: "a"(value), "d"(port));
}
__inline__ char inportb(unsigned short port)
{
char value;
asm("inb %w1, %b0": "=a"(value): "d"(port));
return value;
}