📄 keyboard.c
字号:
/*GazOS Operating SystemCopyright (C) 1999 Gareth Owen <gaz@athene.co.uk>This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/#include "keyboard.h"#include "io.h"#include "video.h"#include "idt.h"#include "8259.h"#include "gdt.h"void ulong_strcnv();#define LED_NUM_LOCK 2#define LED_SCROLL_LOCK 1#define LED_CAPS_LOCK 4unsigned char led_status = 0;/* keyboard_buffer stores every key typed */unsigned char keyboard_buffer[255];/* keyboard_buffer_size stores the number of keys in the buffer */unsigned char keyboard_buffer_size = 0;unsigned char control_keys = 0;#define CK_SHIFT 1#define CK_ALT 2#define CK_CTRL 4unsigned int scan2ascii_table[][8] = {/* ASCII - Shift - Ctrl - Alt - Num - Caps - Shift Caps - Shift Num */{ 0, 0, 0, 0, 0, 0, 0, 0},{ 0x1B, 0x1B, 0x1B, 0, 0x1B, 0x1B, 0x1B, 0x1B},/* 1 -> 9 */{ 0x31, 0x21, 0, 0x7800, 0x31, 0x31, 0x21, 0x21},{ 0x32, 0x40, 0x0300, 0x7900, 0x32, 0x32, 0x40, 0x40},{ 0x33, 0x23, 0, 0x7A00, 0x33, 0x33, 0x23, 0x23},{ 0x34, 0x24, 0, 0x7B00, 0x34, 0x34, 0x24, 0x24},{ 0x35, 0x25, 0, 0x7C00, 0x35, 0x35, 0x25, 0x25},{ 0x36, 0x5E, 0x1E, 0x7D00, 0x36, 0x36, 0x5E, 0x5E},{ 0x37, 0x26, 0, 0x7E00, 0x37, 0x37, 0x26, 0x26},{ 0x38, 0x2A, 0, 0x7F00, 0x38, 0x38, 0x2A, 0x2A},{ 0x39, 0x28, 0, 0x8000, 0x39, 0x39, 0x28, 0x28},{ 0x30, 0x29, 0, 0x8100, 0x30, 0x30, 0x29, 0x29},/* -, =, Bksp, Tab */{ 0x2D, 0x5F, 0x1F, 0x8200, 0x2D, 0x2D, 0x5F, 0x5F},{ 0x3D, 0x2B, 0, 0x8300, 0x3D, 0x3D, 0x2B, 0x2B},{ 0x08, 0x08, 0x7F, 0, 0x08, 0x08, 0x08, 0x08},{ 0x09, 0x0F00, 0, 0, 0x09, 0x09, 0x0F00, 0x0F00},/* QWERTYUIOP[] */{ 0x71, 0x51, 0x11, 0x1000, 0x71, 0x51, 0x71, 0x51},{ 0x77, 0x57, 0x17, 0x1100, 0x77, 0x57, 0x77, 0x57},{ 0x65, 0x45, 0x05, 0x1200, 0x65, 0x45, 0x65, 0x45},{ 0x72, 0x52, 0x12, 0x1300, 0x72, 0x52, 0x72, 0x52},{ 0x74, 0x54, 0x14, 0x1400, 0x74, 0x54, 0x74, 0x54},{ 0x79, 0x59, 0x19, 0x1500, 0x79, 0x59, 0x79, 0x59},{ 0x75, 0x55, 0x15, 0x1600, 0x75, 0x55, 0x75, 0x55},{ 0x69, 0x49, 0x09, 0x1700, 0x69, 0x49, 0x69, 0x49},{ 0x6F, 0x4F, 0x0F, 0x1800, 0x6F, 0x4F, 0x6F, 0x4F},{ 0x70, 0x50, 0x10, 0x1900, 0x70, 0x50, 0x70, 0x50},{ 0x5B, 0x7B, 0x1B, 0x0, 0x5B, 0x5B, 0x7B, 0x7B},{ 0x5D, 0x7D, 0x1D, 0, 0x5D, 0x5D, 0x7D, 0x7D},/* ENTER, CTRL */{ 0x0A, 0x0A, 0x0D, 0, 0x0A, 0x0A, 0x0D, 0x0D},{ 0, 0, 0, 0, 0, 0, 0, 0},/* ASDFGHJKL;'~ */{ 0x61, 0x41, 0x01, 0x1E00, 0x61, 0x41, 0x61, 0x41},{ 0x73, 0x53, 0x13, 0x1F00, 0x73, 0x53, 0x73, 0x53},{ 0x64, 0x44, 0x04, 0x2000, 0x64, 0x44, 0x64, 0x44},{ 0x66, 0x46, 0x06, 0x2100, 0x66, 0x46, 0x66, 0x46},{ 0x67, 0x47, 0x07, 0x2200, 0x67, 0x47, 0x67, 0x47},{ 0x68, 0x48, 0x08, 0x2300, 0x68, 0x48, 0x68, 0x48},{ 0x6A, 0x4A, 0x0A, 0x2400, 0x6A, 0x4A, 0x6A, 0x4A},{ 0x6B, 0x4B, 0x0B, 0x3500, 0x6B, 0x4B, 0x6B, 0x4B},{ 0x6C, 0x4C, 0x0C, 0x2600, 0x6C, 0x4C, 0x6C, 0x4C},{ 0x3B, 0x3A, 0, 0, 0x3B, 0x3B, 0x3A, 0x3A},{ 0x27, 0x22, 0, 0, 0x27, 0x27, 0x22, 0x22},{ 0x60, 0x7E, 0, 0, 0x60, 0x60, 0x7E, 0x7E},/* Left Shift*/{ 0x2A, 0, 0, 0, 0, 0, 0, 0},/* \ZXCVBNM,./ */{ 0x5C, 0x7C, 0x1C, 0, 0x5C, 0x5C, 0x7C, 0x7C},{ 0x7A, 0x5A, 0x1A, 0x2C00, 0x7A, 0x5A, 0x7A, 0x5A},{ 0x78, 0x58, 0x18, 0x2D00, 0x78, 0x58, 0x78, 0x58},{ 0x63, 0x43, 0x03, 0x2E00, 0x63, 0x43, 0x63, 0x43},{ 0x76, 0x56, 0x16, 0x2F00, 0x76, 0x56, 0x76, 0x56},{ 0x62, 0x42, 0x02, 0x3000, 0x62, 0x42, 0x62, 0x42},{ 0x6E, 0x4E, 0x0E, 0x3100, 0x6E, 0x4E, 0x6E, 0x4E},{ 0x6D, 0x4D, 0x0D, 0x3200, 0x6D, 0x4D, 0x6D, 0x4D},{ 0x2C, 0x3C, 0, 0, 0x2C, 0x2C, 0x3C, 0x3C},{ 0x2E, 0x3E, 0, 0, 0x2E, 0x2E, 0x3E, 0x3E},{ 0x2F, 0x3F, 0, 0, 0x2F, 0x2F, 0x3F, 0x3F},/* Right Shift */{ 0, 0, 0, 0, 0, 0, 0, 0},/* Print Screen */{ 0, 0, 0, 0, 0, 0, 0, 0},/* Alt */{ 0, 0, 0, 0, 0, 0, 0, 0},/* Space */{ 0x20, 0x20, 0x20, 0, 0x20, 0x20, 0x20, 0x20},/* Caps */{ 0, 0, 0, 0, 0, 0, 0, 0},/* F1-F10 */{ 0x3B00, 0x5400, 0x5E00, 0x6800, 0x3B00, 0x3B00, 0x5400, 0x5400},{ 0x3C00, 0x5500, 0x5F00, 0x6900, 0x3C00, 0x3C00, 0x5500, 0x5500},{ 0x3D00, 0x5600, 0x6000, 0x6A00, 0x3D00, 0x3D00, 0x5600, 0x5600},{ 0x3E00, 0x5700, 0x6100, 0x6B00, 0x3E00, 0x3E00, 0x5700, 0x5700},{ 0x3F00, 0x5800, 0x6200, 0x6C00, 0x3F00, 0x3F00, 0x5800, 0x5800},{ 0x4000, 0x5900, 0x6300, 0x6D00, 0x4000, 0x4000, 0x5900, 0x5900},{ 0x4100, 0x5A00, 0x6400, 0x6E00, 0x4100, 0x4100, 0x5A00, 0x5A00},{ 0x4200, 0x5B00, 0x6500, 0x6F00, 0x4200, 0x4200, 0x5B00, 0x5B00},{ 0x4300, 0x5C00, 0x6600, 0x7000, 0x4300, 0x4300, 0x5C00, 0x5C00},{ 0x4400, 0x5D00, 0x6700, 0x7100, 0x4400, 0x4400, 0x5D00, 0x5D00},/* Num Lock, Scrl Lock */{ 0, 0, 0, 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0, 0, 0, 0},/* HOME, Up, Pgup, -kpad, left, center, right, +keypad, end, down, pgdn, ins, del */{ 0x4700, 0x37, 0x7700, 0, 0x37, 0x4700, 0x37, 0x4700},{ 0x4800, 0x38, 0, 0, 0x38, 0x4800, 0x38, 0x4800},{ 0x4900, 0x39, 0x8400, 0, 0x39, 0x4900, 0x39, 0x4900},{ 0x2D, 0x2D, 0, 0, 0x2D, 0x2D, 0x2D, 0x2D},{ 0x4B00, 0x34, 0x7300, 0, 0x34, 0x4B00, 0x34, 0x4B00},{ 0x4C00, 0x35, 0, 0, 0x35, 0x4C00, 0x35, 0x4C00},{ 0x4D00, 0x36, 0x7400, 0, 0x36, 0x4D00, 0x36, 0x4D00},{ 0x2B, 0x2B, 0, 0, 0x2B, 0x2B, 0x2B, 0x2B},{ 0x4F00, 0x31, 0x7500, 0, 0x31, 0x4F00, 0x31, 0x4F00},{ 0x5000, 0x32, 0, 0, 0x32, 0x5000, 0x32, 0x5000},{ 0x5100, 0x33, 0x7600, 0, 0x33, 0x5100, 0x33, 0x5100},{ 0x5200, 0x30, 0, 0, 0x30, 0x5200, 0x30, 0x5200},{ 0x5300, 0x2E, 0, 0, 0x2E, 0x5300, 0x2E, 0x5300}};extern void keyb_ISR();asm ( ".globl keyb_ISR \n" "keyb_ISR: \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" " \n" " call keyb_handler \n" " \n" " popw %es \n" " popw %ds \n" /* Restore registers */ " popa \n" " iret \n" /* Exit interrupt */);void setleds(){ outportb(0x60, 0xED); while(inportb(0x64) & 2); outportb(0x60, led_status); while(inportb(0x64) & 2);}void InitKeyboard(){ set_vector(keyb_ISR, M_VEC+1, D_PRESENT + D_INT + D_DPL3); /* IRQ1 Handler */ enable_irq(1); led_status = 0; /* All leds off */ setleds();}void keyb_handler(void){ unsigned int key = inportb(0x60); unsigned int key_ascii = 0; if((control_keys & (CK_CTRL+CK_ALT)) && key==0x53) { while(inportb(0x64) & 2); outportb(0x64, 0xFE); asm ("cli;hlt"); } /* 'LED Keys', ie, Scroll lock, Num lock, and Caps lock */ if(key == 0x3A) /* Caps Lock */ { led_status ^= LED_CAPS_LOCK; setleds(); } if(key == 0x45) /* Num Lock */ { led_status ^= LED_NUM_LOCK; setleds(); } if(key == 0x46) /* Scroll Lock */ { led_status ^= LED_SCROLL_LOCK; setleds(); } if(key == 0x1D && !(control_keys & CK_CTRL)) /* Ctrl key */ control_keys |= CK_CTRL; if(key == 0x80 + 0x1D) /* Ctrl key depressed */ control_keys &= (0xFF - CK_CTRL); if((key == 0x2A || key == 0x36) && !(control_keys & CK_SHIFT)) /* Shift key */ control_keys |= CK_SHIFT; if((key == 0x80 + 0x2A) || (key == 0x80 + 0x36)) /* Shift key depressed */ control_keys &= (0xFF - CK_SHIFT); if(key == 0x38 && (!control_keys & CK_ALT)) control_keys |= CK_ALT; if(key == 0x80 + 0x38) control_keys &= (0xFF - CK_ALT); if((control_keys & CK_SHIFT) && (led_status & LED_CAPS_LOCK)) key_ascii = scan2ascii_table[key][6]; else if(control_keys & CK_SHIFT) key_ascii = scan2ascii_table[key][1]; else if(control_keys & CK_CTRL) key_ascii = scan2ascii_table[key][2]; else if(control_keys & CK_ALT) key_ascii = scan2ascii_table[key][3]; else if((control_keys & CK_SHIFT) && (led_status & LED_NUM_LOCK)) key_ascii = scan2ascii_table[key][7]; else if(led_status & LED_CAPS_LOCK) key_ascii = scan2ascii_table[key][5]; else if(led_status & LED_NUM_LOCK) key_ascii = scan2ascii_table[key][4]; else if(control_keys == 0) key_ascii = scan2ascii_table[key][0]; if(key_ascii != 0) { if(key_ascii <= 0xFF) { keyboard_buffer[keyboard_buffer_size] = key_ascii; keyboard_buffer_size++; } else { keyboard_buffer[keyboard_buffer_size] = (key_ascii & 0xFF); keyboard_buffer[keyboard_buffer_size+1] = (key_ascii & 0xFF00); keyboard_buffer_size += 2; } } outportb(M_PIC, EOI);}unsigned char getch(){ unsigned char ret_key=0; unsigned int loop=0; while(keyboard_buffer_size == 0); ret_key = keyboard_buffer[0]; keyboard_buffer_size--; for(loop=0; loop<254; loop++) keyboard_buffer[loop] = keyboard_buffer[loop+1]; return ret_key;}unsigned char kbhit(){ if(keyboard_buffer_size == 0) return 0; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -