Chinaunix首页 | 论坛 | 博客
  • 博客访问: 576539
  • 博文数量: 99
  • 博客积分: 3976
  • 博客等级: 中校
  • 技术积分: 1041
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-15 15:48
文章分类
文章存档

2009年(1)

2008年(5)

2007年(31)

2006年(58)

2005年(4)

分类: LINUX

2006-03-30 09:40:50

#define outb(value,port) \
__asm__ ("outb %%al,%%dx"::"a" (value),"d" (port))

#define inb(port) ({ \
unsigned char _v; \
__asm__ volatile ("inb %%dx,%%al":"=a" (_v):"d" (port)); \
_v; \
})
#define outb_p(value,port) \
__asm__ ("outb %%al,%%dx\n" \
  "\tjmp 1f\n" \
  "1:\tjmp 1f\n" \
  "1:"::"a" (value),"d" (port))
#define inb_p(port) ({ \
unsigned char _v; \
__asm__ volatile ("inb %%dx,%%al\n" \
 "\tjmp 1f\n" \
 "1:\tjmp 1f\n" \
 "1:":"=a" (_v):"d" (port)); \
_v; \
})
#define SIZE  64
static unsigned char e0;
static unsigned char mode = 0;
static unsigned char leds;
struct tty_queue {
  long head;
  long tail;
  char buf[SIZE];
};
struct tty_queue read_q;
/*
static unsigned char shift_map[] = {
  0,27,
  '!','@','#','$','%','^','&','*','(',')','_','+',
  127,9
  ,'Q','W','E','R','T','Y','U','I','O','P','{','}',
  10,0,
  'A','S','D','F','G','H','J','K','L',':','"',
  0,0
  ,'|','Z','X','C','V','B','N','M','<','>','?',
  0,'\'','*',0,32,  /* 36-39 */
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 3A-49 */
  '-',0,0,0,'+', /* 4A-4E */
  0,0,0,0,0,0,0 /* 4F-55 */
  ,'>',
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
 
};
*/
static unsigned char key_map[] = {
  0,27,
  '1','2','3','4','5','6','7','8','9','0','-','=',
  127,9,
  'q','w','e','r','t','y','u','i','o','p','[',
  0,10,0,
  'a','s','d','f','g','h','j','k','l',';','\'',
  0,0,
  '\\','z','x','c','v','b','n','m',',','.','/',
  0,'*',0,32,  /* 36-39 */
  16,1,0 , /* 3A-49 */
  '-',0,0,0,'+', /* 4A-4E */
  0,0,0,0,0,0,0, /* 4F-55 */
  '<',
  10,1,0
};
 
static unsigned char alt_map[] = {
  0,0,
  0,'@',0,'$',0,0,'{','[',']','}','\\',0,
  0,0,
  0,0,0,0,0,0,0,0,0,0,0,
  '~',10,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,  /* 36-39 */
  16,1,0,  /* 3A-49 */
  0,0,0,0,0,  /* 4A-4E */
  0,0,0,0,0,0,0, /* 4F-55 */
  '|',
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

static long func_table[] = {
  0x415b5b1b,0x425b5b1b,0x435b5b1b,0x445b5b1b,
  0x455b5b1b,0x465b5b1b,0x475b5b1b,0x485b5b1b,
  0x495b5b1b,0x4a5b5b1b,0x4b5b5b1b,0x4c5b5b1b
};
static int do_self(int scancode);
static int uncaps(int scancode);
static int caps(int scancode);
static int lshift(int scancode);
static int rshift(int scancode);
static int unctrl(int scancode);
static int ctrl(int scancode);
static int none(int scancode);
static int num(int scancode);
static int minus(int scancode);
static int cursor(int scancode);
static int func(int scancode);
static int scroll(int scancode);
static int alt(int scancode);
static int unalt(int scancode);
static int unlshift(int scancode);
static int unrshift(int scancode);
static int setleds(void);
static int put_queue(long);
static int kbd_wait(void);

typedef int (*keyfn_ptr)();
static keyfn_ptr key_tab[] = {
  none,do_self,do_self,do_self /* 00-03 s0 esc 1 2 */
  , do_self,do_self,do_self,do_self /* 04-07 3 4 5 6 */
  , do_self,do_self,do_self,do_self /* 08-0B 7 8 9 0 */
  , do_self,do_self,do_self,do_self /* 0C-0F + ' bs tab */
  , do_self,do_self,do_self,do_self /* 10-13 q w e r */
  , do_self,do_self,do_self,do_self /* 14-17 t y u i */
  , do_self,do_self,do_self,do_self /* 18-1B o p } ^ */
  , do_self,ctrl,do_self,do_self /* 1C-1F enter ctrl a s */
  , do_self,do_self,do_self,do_self /* 20-23 d f g h */
  , do_self,do_self,do_self,do_self /* 24-27 j k l | */
  , do_self,do_self,lshift,do_self /* 28-2B { para lshift , */
  , do_self,do_self,do_self,do_self /* 2C-2F z x c v */
  , do_self,do_self,do_self,do_self /* 30-33 b n m , */
  , do_self,minus,rshift,do_self /* 34-37 . - rshift * */
  , alt,do_self,caps,func  /* 38-3B alt sp caps f1 */
  , func,func,func,func  /* 3C-3F f2 f3 f4 f5 */
  , func,func,func,func  /* 40-43 f6 f7 f8 f9 */
  , func,num,scroll,cursor  /* 44-47 f10 num scr home */
  , cursor,cursor,do_self,cursor /* 48-4B up pgup - left */
  , cursor,cursor,do_self,cursor /* 4C-4F n5 right + end */
  , cursor,cursor,cursor,cursor /* 50-53 dn pgdn ins del */
  , none,none,do_self,func  /* 54-57 sysreq ? < f11 */
  , func,none,none,none  /* 58-5B f12 ? ? ? */
  , none,none,none,none  /* 5C-5F ? ? ? ? */
  , none,none,none,none  /* 60-63 ? ? ? ? */
  , none,none,none,none  /* 64-67 ? ? ? ? */
  , none,none,none,none  /* 68-6B ? ? ? ? */
  , none,none,none,none  /* 6C-6F ? ? ? ? */
  , none,none,none,none  /* 70-73 ? ? ? ? */
  , none,none,none,none  /* 74-77 ? ? ? ? */
  , none,none,none,none  /* 78-7B ? ? ? ? */
  , none,none,none,none  /* 7C-7F ? ? ? ? */
  , none,none,none,none  /* 80-83 ? br br br */
  , none,none,none,none  /* 84-87 br br br br */
  , none,none,none,none  /* 88-8B br br br br */
  , none,none,none,none  /* 8C-8F br br br br */
  , none,none,none,none  /* 90-93 br br br br */
  , none,none,none,none  /* 94-97 br br br br */
  , none,none,none,none  /* 98-9B br br br br */
  , none,unctrl,none,none  /* 9C-9F br unctrl br br */
  , none,none,none,none  /* A0-A3 br br br br */
  , none,none,none,none  /* A4-A7 br br br br */
  , none,none,unlshift,none  /* A8-AB br br unlshift br */
  , none,none,none,none  /* AC-AF br br br br */
  , none,none,none,none  /* B0-B3 br br br br */
  , none,none,unrshift,none  /* B4-B7 br br unrshift br */
  , unalt,none,uncaps,none  /* B8-BB unalt br uncaps br */
  , none,none,none,none  /* BC-BF br br br br */
  , none,none,none,none  /* C0-C3 br br br br */
  , none,none,none,none  /* C4-C7 br br br br */
  , none,none,none,none  /* C8-CB br br br br */
  , none,none,none,none  /* CC-CF br br br br */
  , none,none,none,none  /* D0-D3 br br br br */
  , none,none,none,none  /* D4-D7 br br br br */
  , none,none,none,none  /* D8-DB br ? ? ? */
  , none,none,none,none  /* DC-DF ? ? ? ? */
  , none,none,none,none  /* E0-E3 e0 e1 ? ? */
  , none,none,none,none  /* E4-E7 ? ? ? ? */
  , none,none,none,none  /* E8-EB ? ? ? ? */
  , none,none,none,none  /* EC-EF ? ? ? ? */
  , none,none,none,none  /* F0-F3 ? ? ? ? */
  , none,none,none,none  /* F4-F7 ? ? ? ? */
  , none,none,none,none  /* F8-FB ? ? ? ? */
  , none,none,none,none  /* FC-FF ? ? ? ? */
} ;

static unsigned char number_tab[] = { '7','8','9',' ','4','5','6',' ','1','2','3','0'};
static unsigned char cursos_tab[] =  "HA5 DGC YB623" ;
static int code ;
int keyboard_interrupt(void)
{
printk("<1> 1jjk give you a message!-------------init success\n");
 code = inb_p(0x60);
 if ( code == 0xe0 )  
  e0 = 1;
 else   if ( code == 0xe1 )
  e0 = 2;
 else {
  keyfn_ptr funp;
  funp = key_tab[code];
  funp(code) ;
  e0  = 0;
 }
 outb_p((inb_p(0x61))|0x80,0x61);
 outb_p((inb_p(0x61))&0x7f,0x61);
 
 return 0;
}

int do_self(int scancode)
{
 char *map;
 unsigned char ch;
 int shftflg = 0 ;
 if (mode & 0x20 )
  map = alt_map;
 else if ( (mode & 0x3) ){
  map = key_map;
  shftflg = 1;
 }
 else map = key_map;
 ch = map[scancode & 0xff];
 if ( ch == 0) return 0;
 if ((mode & 0x4c)){ 
  if ((ch <= 'z' && ch >= 'a' )) /
   ch -= 0x20 ; 
 if (mode & 0xc) 
   ch -= 0x40; 
 }
 if (mode & 0x10)
  ch |= 0x80 ;
 ch &= 0xff;
 put_queue(ch);
 return 0;
}

int alt(int scancode)
{
 if ( e0) 
  mode |= 0x20;
 else
  mode |= 0x10;
 return 0;
}
int unalt(int scancode)
{
 if (e0)
  mode &= 0xdf;
 else
  mode &= 0xef;
 return 0;
}
int ctrl(int scancode)
{
 if ( e0)
  mode |= 0x8;
 else
  mode |= 0x4;
 return 0;
}
int unctrl(int scancode)
{
 if ( e0)
  mode &= 0xF7;
 else
  mode &= 0xFB;
   return 0;
}
int lshift(int scancode)
{
 mode |= 0x1;
   return 0;
}
int rshift(int scancode)
{
 mode |= 0x2;
 return 0;
}
int unlshift(int scancode)
{
 mode &= 0xfe;
 return 0;
}
int unrshift(int scancode)
{
 mode &= 0xfd;
 return 0;
}
int caps(int scancode)
{
 if (!(mode & 0x80)){
  leds ^= 0x4;
  mode ^= 0x40;
  mode |= 0x80;
  setleds();
 }
 return 0;
}
int uncaps(int scancode)
{
 mode &= 0x7f;
 return 0;
}
int srcoll(int scancode)
{
 leds |= 0x1;
 setleds();
 return 0;
}
int num(int scancode)
{
 leds ^= 0x2;
 setleds();
 return 0;
}
int cursor(int scancode)
{
 int i;
 i =  code - 0x47 ;
 if ( i < 0 || i > 12) return 0;

 if ((e0 == 1 && !(leds & 0x2))|| (mode &0x3)){
  int ch;
  ch = cursos_tab[i];
  if ( ch <= '9' ) ch ='~';
  ch = ch<<16|0x5b1b;
  put_queue(ch);
 } else { 
  int ch;
  ch = number_tab[i];
  put_queue(ch);
 }
 return 0;
}
int func(int scancode)
{
 int i = scancode - 59;
 if ( i >= 0 && i <= 11) { 
  long ch ;
  ch = func_table[i];
  put_queue(ch);
 }
 return 0;
}

int minus (int scancode)
{
 if ( e0 != 1)
  do_self(scancode);
 else
  put_queue((long)'/');
 return 0;
}
int setleds(void)
{
 kbd_wait();
 outb(0xed,0x60);
 kbd_wait();
 outb(leds,0x60);
 return 0;
}
int kbd_wait(void)
{
 while (inb_p(0x64) & 0x2)
 return 0;
}

int none(int scancode)
{
 return 0;
}
int scroll(int scancode)
{
 leds ^= 0x1;
 setleds();
 return 0;
}
static int put_queue(long ch)
{
 struct tty_queue * q;
 while(ch){
  (q->buf)[q->head] = ch &0xff;
  q->head = (q->head +1)&(SIZE -1);
  if ( q->head == q->tail )  /* buf is full */
   return 0;
  ch >>= 8;
 }
 return 0;
}
 
 
 
 
 
linux0.01版的键盘驱动源代码!改了改,发出来,以后自己学习用。
阅读(2703) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~