#include "asm_x86.h" #include "keyboard.h" #include "syscalls.h" #include "log.h" #include "e1000.h" #include "kmalloc.h" #include "interrupts.h" #include #include "net/inet.h" ringbuffer kb_in; static bool ctrl_l=false; static bool shift_l=false; static bool shift_r=false; static bool capslock=false; static uint32_t kb_stream; static char num_syms[]={')','!','@','#','$','%','^','&','*','('}; int hex_to_dec(char c) { if(c>='0'&&c<='9')return c-'0'; return c+10-'a'; } extern struct netdev e1000_dev; static void put(uint8_t c) { if(c=='p')net_packet(&e1000_dev); syscall_generic(SYSCALL_WRITE,kb_stream, (char *)&c , 1, 0); } uint32_t keyboard_interrupt(uint32_t esp) { ringbuffer_put(&kb_in,x86_inb(0x60)); return esp; } void keyboard_init(uint32_t s) { kb_in=ringbuffer_init(1);// 4096 bytes ringbuffer; interrupt_register(INTERRUPT_KEYBOARD,&keyboard_interrupt); kb_stream=s; } void keyboard_handle(uint8_t in) { // klog("kb_in 0x%x",in); uint8_t make_alpha[]={ 0x1e, // A 0x30, // B 0x2e, // C 0x20, // D 0x12, // E 0x21, // F 0x22, // G 0x23, // H 0x17, // I 0x24, // J 0x25, // K 0x26, // L 0x32, // M 0x31, // N 0x18, // O 0x19, // P 0x10, // Q 0x13, // R 0x1F, // S 0x14, // T 0x16, // U 0x2F, // V 0x11, // W 0x2D, // X 0x15, // Y 0x2c, // Z }; uint8_t break_alpha[]={ 0x9e, // A 0xb0, // B 0xae, // C 0xa0, // D 0x92, // E 0xa1, // F 0xa2, // G 0xa3, // H 0x97, // I 0xa4, // J 0xa5, // K 0xa6, // L 0xb2, // M 0xb1, // N 0x98, // O 0x99, // P 0x90, // Q 0x93, // R 0x9F, // S 0x94, // T 0x96, // U 0xaF, // V 0x91, // W 0xaD, // X 0x95, // Y 0xac, // Z }; uint8_t break_num[]={ 0x8b, //0 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, // 9 }; uint8_t break_key_enter=0x9c; uint8_t break_key_space=0xb9; uint8_t break_key_backspace=0x8e; uint8_t break_key_esc=0x81; uint8_t break_key_tab=0x8f; uint8_t make_key_shift_l=0x2a; uint8_t break_key_shift_l=0xaa; uint8_t make_key_shift_r=0x36; uint8_t break_key_shift_r=0xb6; uint8_t break_caps_lock=0xba; uint8_t break_slash=0xb5; uint8_t make_ctrl_l=0x1d; uint8_t break_ctrl_l=0x9d; if(make_key_shift_l==in)shift_l=true; if(break_key_shift_l==in)shift_l=false;; if(make_key_shift_r==in)shift_r=true; if(break_key_shift_r==in)shift_r=false;; if(make_ctrl_l==in)ctrl_l=true; if(break_ctrl_l==in)ctrl_l=false; if(break_caps_lock==in)capslock=!capslock; char ascii; bool match=false; // optimize this! if(ctrl_l) { if(in==0xa0) { ascii=4; //end of transmission ctrl-d match=true; } } if(break_slash==in) { ascii='/'; if(shift_l||shift_r||capslock) ascii='?'; match=true; } else if(break_key_space==in) { ascii=' '; match=true; } else if(in==0xB4) { ascii='.'; if(shift_l||shift_r||capslock) ascii='<'; match=true; } else if(in==0xB3) { ascii=','; if(shift_l||shift_r||capslock) ascii='>'; match=true; } else if(in==0x8D) { ascii='='; if(shift_l||shift_r||capslock) ascii='+'; match=true; } else if(in==0x8C) { ascii='-'; if(shift_l||shift_r||capslock) ascii='_'; match=true; } else if(in==0x9A) { ascii='['; if(shift_l||shift_r||capslock) ascii='{'; match=true; } else if(in==0x9B) { ascii=']'; if(shift_l||shift_r||capslock) ascii='}'; match=true; } else if(in==0xab) { ascii='\\'; if(shift_l||shift_r||capslock) ascii='|'; match=true; } else if(break_key_backspace==in) { ascii=0x08; match=true; } else if(break_key_esc==in) { ascii=0x1b; match=true; } else if(break_key_enter==in) { ascii='\n'; match=true; } else if(break_key_tab==in) { ascii='\t'; match=true; } else for(int i=0;i<26;i++) { if(match)break; if(break_alpha[i]==in) { ascii=('a'+i); if(shift_l||shift_r||capslock) // capslock makes trouble :( { ascii=('A'+i); } match=true; break; } } for(int i=0;i<10;i++) { if(break_num[i]==in) { ascii=('0'+i); if(shift_l||shift_r||capslock) // capslock makes trouble :( { ascii=num_syms[i]; } match=true; break; } } if(match) { put(ascii); } }