提交 1bfdc7dd 编写于 作者: B Bernard Xiong 提交者: GitHub

Merge pull request #805 from parai/master

[bsp] x86: keyboad input bug fix
......@@ -8,6 +8,7 @@ all:floppy.img
clean:
scons -c clean
rm -fr build rtthread*
floppy.img:
wget https://github.com/bajdcc/tinix/raw/master/floppy.img
......
......@@ -17,16 +17,13 @@
#include <bsp.h>
//#include "serial.h"
static unsigned addr_6845;
static rt_uint16_t *crt_buf;
static rt_int16_t crt_pos;
//extern void rt_serial_init(void);
extern char rt_keyboard_getc(void);
//extern char rt_serial_getc(void);
extern void init_keyboard();
extern void rt_keyboard_isr(void);
extern rt_bool_t rt_keyboard_getc(char* c);
static void rt_console_putc(int c);
......@@ -217,39 +214,38 @@ static rt_size_t rt_console_read(rt_device_t dev, rt_off_t pos, void* buffer, rt
static void rt_console_isr(int vector, void* param)
{
char c;
rt_bool_t ret;
rt_base_t level;
while(1)
{
c = rt_keyboard_getc();
if(c == 0)
{
break;
}
else if(c > 0)
{
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* save character */
rx_buffer[save_index] = c;
save_index ++;
if (save_index >= CONSOLE_RX_BUFFER_SIZE)
save_index = 0;
/* if the next position is read index, discard this 'read char' */
if (save_index == read_index)
{
read_index ++;
if (read_index >= CONSOLE_RX_BUFFER_SIZE)
read_index = 0;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
}
rt_keyboard_isr();
ret = rt_keyboard_getc(&c);
if(ret == RT_FALSE)
{
/* do nothing */
}
else
{
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* save character */
rx_buffer[save_index] = c;
save_index ++;
if (save_index >= CONSOLE_RX_BUFFER_SIZE)
save_index = 0;
/* if the next position is read index, discard this 'read char' */
if (save_index == read_index)
{
read_index ++;
if (read_index >= CONSOLE_RX_BUFFER_SIZE)
read_index = 0;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
/* invoke callback */
if (console_device.rx_indicate != RT_NULL)
......@@ -258,10 +254,9 @@ static void rt_console_isr(int vector, void* param)
/* get rx length */
rx_length = read_index > save_index ?
CONSOLE_RX_BUFFER_SIZE - read_index + save_index :
save_index - read_index;
CONSOLE_RX_BUFFER_SIZE - read_index + save_index :
save_index - read_index;
// rt_kprintf("\r\nrx_length %d\r\n", rx_length);
if(rx_length > 0)
{
console_device.rx_indicate(&console_device, rx_length);
......@@ -269,7 +264,7 @@ static void rt_console_isr(int vector, void* param)
}
else
{
// rt_kprintf("\r\nconsole_device.rx_indicate == RT_NULL\r\n");
}
}
......@@ -280,6 +275,7 @@ static void rt_console_isr(int vector, void* param)
void rt_hw_console_init(void)
{
rt_cga_init();
init_keyboard();
/* install keyboard isr */
rt_hw_interrupt_install(INTKEYBOARD, rt_console_isr, RT_NULL, "kbd");
......
#ifndef _DMA_H
#define _DMA_H
#define MAX_DMA_CHANNELS 8
/* 8237 DMA controllers */
#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */
/* DMA controller registers */
#define DMA1_CMD_REG 0x08 /* command register (w) */
#define DMA1_STAT_REG 0x08 /* status register (r) */
#define DMA1_REQ_REG 0x09 /* request register (w) */
#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
#define DMA1_MODE_REG 0x0B /* mode register (w) */
#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
#define DMA2_CMD_REG 0xD0 /* command register (w) */
#define DMA2_STAT_REG 0xD0 /* status register (r) */
#define DMA2_REQ_REG 0xD2 /* request register (w) */
#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
#define DMA2_MODE_REG 0xD6 /* mode register (w) */
#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
#define DMA_ADDR_0 0x00 /* DMA address registers */
#define DMA_ADDR_1 0x02
#define DMA_ADDR_2 0x04
#define DMA_ADDR_3 0x06
#define DMA_ADDR_4 0xC0
#define DMA_ADDR_5 0xC4
#define DMA_ADDR_6 0xC8
#define DMA_ADDR_7 0xCC
#define DMA_CNT_0 0x01 /* DMA count registers */
#define DMA_CNT_1 0x03
#define DMA_CNT_2 0x05
#define DMA_CNT_3 0x07
#define DMA_CNT_4 0xC2
#define DMA_CNT_5 0xC6
#define DMA_CNT_6 0xCA
#define DMA_CNT_7 0xCE
#define DMA_PAGE_0 0x87 /* DMA page registers */
#define DMA_PAGE_1 0x83
#define DMA_PAGE_2 0x81
#define DMA_PAGE_3 0x82
#define DMA_PAGE_5 0x8B
#define DMA_PAGE_6 0x89
#define DMA_PAGE_7 0x8A
#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
/*
* 启用指定的DMA通道
*/
static __inline__ void EnableDma(unsigned int dmanr)
{
if (dmanr<=3)
outb(dmanr, DMA1_MASK_REG);
else
outb(dmanr & 3, DMA2_MASK_REG);
}
/*
* 禁用指定的DMA通道
*/
static __inline__ void DisableDma(unsigned int dmanr)
{
if (dmanr<=3)
outb(dmanr | 4, DMA1_MASK_REG);
else
outb((dmanr & 3) | 4, DMA2_MASK_REG);
}
/*
* 清空DMA 晶体计数器
*/
static __inline__ void ClearDmaFF(unsigned int dmanr)
{
if (dmanr<=3)
outb(0, DMA1_CLEAR_FF_REG);
else
outb(0, DMA2_CLEAR_FF_REG);
}
/*
* 清空DMA 晶体计数器
*/
static __inline__ void SetDmaMode(unsigned int dmanr, char mode)
{
if (dmanr<=3)
outb(mode | dmanr, DMA1_MODE_REG);
else
outb(mode | (dmanr&3), DMA2_MODE_REG);
}
/*
* 设定DMA 页面寄存器
*/
static __inline__ void SetDmaPage(unsigned int dmanr, char pagenr)
{
switch(dmanr) {
case 0:
outb(pagenr, DMA_PAGE_0);
break;
case 1:
outb(pagenr, DMA_PAGE_1);
break;
case 2:
outb(pagenr, DMA_PAGE_2);
break;
case 3:
outb(pagenr, DMA_PAGE_3);
break;
case 5:
outb(pagenr & 0xfe, DMA_PAGE_5);
break;
case 6:
outb(pagenr & 0xfe, DMA_PAGE_6);
break;
case 7:
outb(pagenr & 0xfe, DMA_PAGE_7);
break;
}
}
/*
* 设定DMA 传输高速缓冲区地址
*/
static __inline__ void SetDmaAddr(unsigned int dmanr, unsigned int a)
{
SetDmaPage(dmanr, a>>16);
if (dmanr <= 3) {
outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
} else {
outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
}
}
/*
* 设定DMA 传输块数
*/
static __inline__ void SetDmaCount(unsigned int dmanr, unsigned int count)
{
count--;
if (dmanr <= 3) {
outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
} else {
outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
}
}
/*
* 获得DMA 传输剩余块数
*/
static __inline__ int GetDmaResidue(unsigned int dmanr)
{
unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
: ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
/* using short to get 16-bit wrap around */
unsigned short count;
count = 1 + inb(io_port);
count += inb(io_port) << 8;
return (dmanr<=3)? count : (count<<1);
}
#endif
#include <rtthread.h>
#include <rthw.h>
#include <bsp.h>
typedef rt_uint8_t u8;
typedef rt_uint16_t u16;
typedef rt_uint32_t u32;
typedef rt_int8_t s8;
typedef rt_int16_t s16;
typedef rt_int32_t s32;
#include "floppy.h"
#include "dma.h"
#define panic(str) rt_kprintf("panic::" str)
#define _local_irq_save(level) level = rt_hw_interrupt_disable()
#define _local_irq_restore(level) rt_hw_interrupt_enable(level)
static u8 floppy_buffer[512]; /* 软盘高速缓冲区地址指针 */
#define MAX_REPLIES 7
static u8 floppy_reply_buffer[MAX_REPLIES]; /* 软驱回应缓冲区 */
#define ST0 (floppy_reply_buffer[0]) /* 软驱回应0号字节 */
#define ST1 (floppy_reply_buffer[1]) /* 软驱回应1号字节 */
#define ST2 (floppy_reply_buffer[2]) /* 软驱回应2号字节 */
#define ST3 (floppy_reply_buffer[3]) /* 软驱回应3号字节 */
static char *floppy_inc_name; /* 软驱型号名 */
static char *floppy_type;
static u32 floppy_motor=0; /* 软驱马达状态字节 */
/**********************功能函数***************************/
static void floppy_result(void); /* 获得软驱响应状态 */
static u32 floppy_sendbyte(u32); /* 向软驱控制寄存器发送一个控制字节 */
static u32 floppy_getbyte(void); /* 从软驱数据寄存器得到一个数据字节 */
static u32 floppy_get_info(void); /* 得到软驱信息 */
static void floppy_motorOn(void); /* 打开软驱马达 */
static void floppy_motorOff(void); /* 关闭软驱马达 */
static void floppy_setmode(void); /* 软驱模式设置 */
static void block_to_hts(u32, u32*, u32*, u32*); /* 逻辑块转为磁盘头、磁道号和扇区号 */
static void floppy_setupDMA(void); /* 设置软驱DMA通道 */
static void floppy_read_cmd(u32 blk); /* 从软盘上读取指定的逻辑块到缓冲区 */
void floppy_result(void)
{
u8 stat, i,count;
i=0;
for(count=0; count<0xFF; count++)
{
stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR|STATUS_BUSY); //读取状态寄存器
if (stat == STATUS_READY)
return;
if (stat == (STATUS_READY|STATUS_DIR|STATUS_BUSY))
{
if(i>7) break;
floppy_reply_buffer[i++]=inb_p(FD_DATA);
}
}
panic("Get floppy status times out !\n");
}
u32 floppy_sendbyte( u32 value )
{
u8 stat, i;
for ( i = 0; i < 128; i++ ) {
stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR); //读取状态寄存器
if ( stat == STATUS_READY )
{
outb( value ,FD_DATA); //将参数写入数据寄存器
return 1;
}
io_delay(); // 作一些延迟
}
return 0;
}
u32 floppy_getbyte(void)
{
u8 stat, i;
for ( i = 0; i < 128; i++ ) {
stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR|STATUS_BUSY); //读取状态寄存器
if (stat == STATUS_READY)
return -1;
if ( stat == 0xD0 )
return inb(FD_DATA);
io_delay();
}
return 0;
}
u32 floppy_get_info(void)
{
u32 i;
u8 CmType, FdType;
floppy_sendbyte(0x10);
i = floppy_getbyte();
switch (i)
{
case 0x80: floppy_inc_name = "NEC765A controller"; break;
case 0x90: floppy_inc_name = "NEC765B controller"; break;
default: floppy_inc_name = "Enhanced controller"; break;
}
CmType = readcmos(0x10); //read floppy type from cmos
FdType = (CmType>>4) & 0x07;
if ( FdType == 0 )
panic("Floppy driver not found!");
switch( FdType )
{
case 0x02: // 1.2MB
floppy_type = "1.2MB";
break;
case 0x04: // 1.44MB 标准软盘
floppy_type = "1.44MB";
break;
case 0x05: // 2.88MB
floppy_type = "2.88MB";
break;
}
return 1;
}
void floppy_motorOn( void )
{
u32 eflags;
if (!floppy_motor)
{
_local_irq_save(eflags);
outb(28,FD_DOR);
floppy_motor = 1;
_local_irq_restore(eflags);
}
return;
}
void floppy_motorOff( void )
{
u32 eflags;
if (floppy_motor)
{
_local_irq_save(eflags);
outb(12,FD_DOR);
floppy_motor = 0;
_local_irq_restore(eflags);
}
return;
}
void floppy_setmode(void)
{
floppy_sendbyte (FD_SPECIFY);
floppy_sendbyte (0xcf);
floppy_sendbyte (0x06);
outb (0,FD_DCR);
}
void block_to_hts(u32 block, u32 *head, u32 *track, u32 *sector )
{
*head = ( block % ( 18 * 2 ) ) /18;
*track = block / ( 18 * 2 );
*sector = block % 18 + 1;
}
void floppy_setupDMA(void)
{
u32 eflags;
_local_irq_save(eflags);
DisableDma(2);
ClearDmaFF(2);
SetDmaMode(2,DMA_MODE_READ);
SetDmaAddr(2,(unsigned long)floppy_buffer);
SetDmaCount(2,512);
EnableDma(2);
_local_irq_restore(eflags);
}
void floppy_read_cmd(u32 blk)
{
u32 head;
u32 track;
u32 sector;
block_to_hts(blk,&head,&track,&sector);
floppy_motorOn();
io_delay();
floppy_setupDMA();
io_delay();
floppy_setmode();
io_delay();
floppy_sendbyte (FD_READ); //send read command
floppy_sendbyte (head*4 + 0);
floppy_sendbyte (track); /* Cylinder */
floppy_sendbyte (head); /* Head */
floppy_sendbyte (sector); /* Sector */
floppy_sendbyte (2); /* 0=128, 1=256, 2=512, 3=1024, ... */
floppy_sendbyte (18);
//floppy_sendbyte (sector+secs-1); /* Last sector in track:here are sectors count */
floppy_sendbyte (0x1B);
floppy_sendbyte (0xff);
return;
}
void init_fd(void)
{
floppy_get_info();
rt_kprintf("Floppy Inc : %s Floppy Type : %s",floppy_inc_name,floppy_type);
}
#ifndef _FLOPPY_H
#define _FLOPPY_H
#define FD_STATUS 0x3f4 // 主状态寄存器端口。
#define FD_DATA 0x3f5 // 数据端口。
#define FD_DOR 0x3f2 // 数字输出寄存器(也称为数字控制寄存器)。
#define FD_DIR 0x3f7 // 数字输入寄存器。
#define FD_DCR 0x3f7 // 数据传输率控制寄存器。
/* 主状态寄存器各比特位的含义 */
#define STATUS_BUSYMASK 0x0F // 驱动器忙位(每位对应一个驱动器)。
#define STATUS_BUSY 0x10 // 软盘控制器忙。
#define STATUS_DMA 0x20 // 0 - 为DMA 数据传输模式,1 - 为非DMA 模式。
#define STATUS_DIR 0x40 // 传输方向:0 - CPU .. fdc,1 - 相反。
#define STATUS_READY 0x80 // 数据寄存器就绪位。
/*状态字节0(ST0)各比特位的含义 */
#define ST0_DS 0x03 // 驱动器选择号(发生中断时驱动器号)。
#define ST0_HA 0x04 // 磁头号。
#define ST0_NR 0x08 // 磁盘驱动器未准备好。
#define ST0_ECE 0x10 // 设备检测出错(零磁道校准出错)。
#define ST0_SE 0x20 // 寻道或重新校正操作执行结束。
#define ST0_INTR 0xC0 // 中断代码位(中断原因),00 - 命令正常结束;
// 01 - 命令异常结束;10 - 命令无效;11 - FDD 就绪状态改变。
/*状态字节1(ST1)各比特位的含义 */
#define ST1_MAM 0x01 // 未找到地址标志(ID AM)。
#define ST1_WP 0x02 // 写保护。
#define ST1_ND 0x04 // 未找到指定的扇区。
#define ST1_OR 0x10 // 数据传输超时(DMA 控制器故障)。
#define ST1_CRC 0x20 // CRC 检验出错。
#define ST1_EOC 0x80 // 访问超过一个磁道上的最大扇区号。
/*状态字节2(ST2)各比特位的含义 */
#define ST2_MAM 0x01 // 未找到数据地址标志。
#define ST2_BC 0x02 // 磁道坏。
#define ST2_SNS 0x04 // 检索(扫描)条件不满足。
#define ST2_SEH 0x08 // 检索条件满足。
#define ST2_WC 0x10 // 磁道(柱面)号不符。
#define ST2_CRC 0x20 // 数据场CRC 校验错。
#define ST2_CM 0x40 // 读数据遇到删除标志。
/*状态字节3(ST3)各比特位的含义 */
#define ST3_HA 0x04 // 磁头号。
#define ST3_TZ 0x10 // 零磁道信号。
#define ST3_WP 0x40 // 写保护。
/* 软盘命令码 */
#define FD_RECALIBRATE 0x07 // 重新校正(磁头退到零磁道)。
#define FD_SEEK 0x0F // 磁头寻道。
#define FD_READ 0xE6 // 读数据(MT 多磁道操作,MFM 格式,跳过删除数据)。
#define FD_WRITE 0xC5 // 写数据(MT,MFM)。
#define FD_SENSEI 0x08 // 检测中断状态。
#define FD_SPECIFY 0x03 // 设定驱动器参数(步进速率、磁头卸载时间等)。
/* DMA 命令 */
#define DMA_READ 0x46 // DMA 读盘,DMA 方式字(送DMA 端口12,11)。
#define DMA_WRITE 0x4A
extern void init_fd(void);
extern void fd_handler(void);
#endif
......@@ -101,6 +101,16 @@ extern "C" {
#define KBSTATP 0x64 /* kbd controller status port(I) */
#define KBS_DIB 0x01 /* kbd data in buffer */
#define KBDATAP 0x60 /* kbd data port(I) */
/* AT keyboard */
/* 8042 ports */
#define KB_DATA 0x60 /* I/O port for keyboard data
Read : Read Output Buffer
Write: Write Input Buffer(8042 Data&8048 Command) */
#define KB_CMD 0x64 /* I/O port for keyboard command
Read : Read Status Register
Write: Write Input Buffer(8042 Command) */
#define LED_CODE 0xED
#define KB_ACK 0xFA
/*******************************************************************/
/* Serial Register */
......
......@@ -11,6 +11,18 @@ static __inline unsigned char inb(int port)
__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
return data;
}
static __inline unsigned char inb_p(unsigned short port)
{
unsigned char _v;
__asm__ __volatile__ ("inb %1, %0\n\t"
// "outb %0,$0x80\n\t"
// "outb %0,$0x80\n\t"
// "outb %0,$0x80\n\t"
"outb %0,$0x80"
:"=a" (_v)
:"d" ((unsigned short) port));
return _v;
}
static __inline unsigned short inw(int port)
{
......@@ -39,11 +51,36 @@ static __inline void outb(int port, unsigned char data)
__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
}
static __inline void outb_p(char value, unsigned short port)
{
__asm__ __volatile__ ("outb %0,%1\n\t"
"outb %0,$0x80"
::"a" ((char) value),"d" ((unsigned short) port));
}
static __inline void outw(int port, unsigned short data)
{
__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
}
static __inline unsigned char readcmos(int reg)
{
outb(reg,0x70);
return (unsigned char) inb(0x71);
}
#define io_delay() \
__asm__ __volatile__ ("pushal \n\t"\
"mov $0x3F6, %dx \n\t" \
"inb %dx, %al \n\t" \
"inb %dx, %al \n\t" \
"inb %dx, %al \n\t" \
"inb %dx, %al \n\t" \
"popal")
/* Gate descriptors are slightly different*/
struct Gatedesc {
unsigned gd_off_15_0 : 16; // low 16 bits of offset in segment
......
......@@ -10,129 +10,357 @@
* Change Logs:
* Date Author Notes
* 2006-09-15 QiuYi the first version
* 2017-08-16 Parai the 2nd version
*/
#include <rtthread.h>
#include <rthw.h>
#include <bsp.h>
#include "keyboard.h"
#include "keymap.h"
#define NO 0
#define FALSE RT_FALSE
#define TRUE RT_TRUE
#define PRIVATE static
#define PUBLIC
#define t_bool rt_bool_t
#define t_8 rt_uint8_t
#define t_32 rt_uint32_t
#define SHIFT (1 << 0)
#define CTL (1 << 1)
#define ALT (1 << 2)
PRIVATE KB_INPUT kb_in;
PRIVATE t_bool code_with_E0 = FALSE;
PRIVATE t_bool shift_l; /* l shift state */
PRIVATE t_bool shift_r; /* r shift state */
PRIVATE t_bool alt_l; /* l alt state */
PRIVATE t_bool alt_r; /* r left state */
PRIVATE t_bool ctrl_l; /* l ctrl state */
PRIVATE t_bool ctrl_r; /* l ctrl state */
PRIVATE t_bool caps_lock; /* Caps Lock */
PRIVATE t_bool num_lock; /* Num Lock */
PRIVATE t_bool scroll_lock; /* Scroll Lock */
PRIVATE int column = 0; /* keyrow[column] is one value of keymap */
#define CAPSLOCK (1<<3)
#define NUMLOCK (1<<4)
#define SCROLLOCK (1<<5)
PRIVATE t_8 get_byte_from_kb_buf();
PRIVATE void set_leds();
PRIVATE void kb_wait();
PRIVATE void kb_ack();
static int shiftcode[256] =
PUBLIC void init_keyboard()
{
[29] CTL,
[42] SHIFT,
[54] SHIFT,
[56] ALT,
};
kb_in.count = 0;
kb_in.p_head = kb_in.p_tail = kb_in.buf;
static int togglecode[256] =
caps_lock = 0;
num_lock = 1;
scroll_lock = 0;
set_leds();
}
PUBLIC rt_bool_t keyboard_read(rt_uint32_t *pkey)
{
[58] CAPSLOCK,
[69] NUMLOCK,
[70] SCROLLOCK,
};
t_8 scan_code;
t_bool make; /* TRUE : make */
/* FALSE: break */
t_32 key = 0;
t_32* keyrow;
if(kb_in.count > 0){
code_with_E0 = FALSE;
scan_code = get_byte_from_kb_buf();
/* start scan */
if (scan_code == 0xE1) {
int i;
static const t_8 pausebreak_scan_code[] = {0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5};
t_bool is_pausebreak = TRUE;
for(i=1;i<6;i++){
if (get_byte_from_kb_buf() != pausebreak_scan_code[i]) {
is_pausebreak = FALSE;
break;
}
}
if (is_pausebreak) {
key = PAUSEBREAK;
}
}
else if (scan_code == 0xE0) {
code_with_E0 = TRUE;
scan_code = get_byte_from_kb_buf();
/* PrintScreen pressed */
if (scan_code == 0x2A) {
code_with_E0 = FALSE;
if ((scan_code = get_byte_from_kb_buf()) == 0xE0) {
code_with_E0 = TRUE;
if ((scan_code = get_byte_from_kb_buf()) == 0x37) {
key = PRINTSCREEN;
make = TRUE;
}
}
}
/* PrintScreen released */
else if (scan_code == 0xB7) {
code_with_E0 = FALSE;
if ((scan_code = get_byte_from_kb_buf()) == 0xE0) {
code_with_E0 = TRUE;
if ((scan_code = get_byte_from_kb_buf()) == 0xAA) {
key = PRINTSCREEN;
make = FALSE;
}
}
}
} /* if is not PrintScreen, scan_code is the one after 0xE0 */
if ((key != PAUSEBREAK) && (key != PRINTSCREEN)) {
/* is Make Code or Break Code */
make = (scan_code & FLAG_BREAK ? FALSE : TRUE);
keyrow = &keymap[(scan_code & 0x7F) * MAP_COLS];
column = 0;
t_bool caps = shift_l || shift_r;
if (caps_lock) {
if ((keyrow[0] >= 'a') && (keyrow[0] <= 'z')){
caps = !caps;
}
}
if (caps) {
column = 1;
}
if (code_with_E0) {
column = 2;
}
key = keyrow[column];
switch(key) {
case SHIFT_L:
shift_l = make;
break;
case SHIFT_R:
shift_r = make;
break;
case CTRL_L:
ctrl_l = make;
break;
case CTRL_R:
ctrl_r = make;
break;
case ALT_L:
alt_l = make;
break;
case ALT_R:
alt_l = make;
break;
case CAPS_LOCK:
if (make) {
caps_lock = !caps_lock;
set_leds();
}
break;
case NUM_LOCK:
if (make) {
num_lock = !num_lock;
set_leds();
}
break;
case SCROLL_LOCK:
if (make) {
scroll_lock = !scroll_lock;
set_leds();
}
break;
default:
break;
}
}
static char normalmap[256] =
if(make){ /* ignore Break Code */
t_bool pad = FALSE;
/* handle the small pad first */
if ((key >= PAD_SLASH) && (key <= PAD_9)) {
pad = TRUE;
switch(key) { /* '/', '*', '-', '+', and 'Enter' in num pad */
case PAD_SLASH:
key = '/';
break;
case PAD_STAR:
key = '*';
break;
case PAD_MINUS:
key = '-';
break;
case PAD_PLUS:
key = '+';
break;
case PAD_ENTER:
key = ENTER;
break;
default: /* keys whose value depends on the NumLock */
if (num_lock) { /* '0' ~ '9' and '.' in num pad */
if ((key >= PAD_0) && (key <= PAD_9)) {
key = key - PAD_0 + '0';
}
else if (key == PAD_DOT) {
key = '.';
}
}
else{
switch(key) {
case PAD_HOME:
key = HOME;
break;
case PAD_END:
key = END;
break;
case PAD_PAGEUP:
key = PAGEUP;
break;
case PAD_PAGEDOWN:
key = PAGEDOWN;
break;
case PAD_INS:
key = INSERT;
break;
case PAD_UP:
key = UP;
break;
case PAD_DOWN:
key = DOWN;
break;
case PAD_LEFT:
key = LEFT;
break;
case PAD_RIGHT:
key = RIGHT;
break;
case PAD_DOT:
key = DELETE;
break;
default:
break;
}
}
break;
}
}
key |= shift_l ? FLAG_SHIFT_L : 0;
key |= shift_r ? FLAG_SHIFT_R : 0;
key |= ctrl_l ? FLAG_CTRL_L : 0;
key |= ctrl_r ? FLAG_CTRL_R : 0;
key |= alt_l ? FLAG_ALT_L : 0;
key |= alt_r ? FLAG_ALT_R : 0;
key |= pad ? FLAG_PAD : 0;
*pkey = key;
return TRUE;
}
}
return FALSE;
}
PRIVATE t_8 get_byte_from_kb_buf()
{
NO, 033, '1', '2', '3', '4', '5', '6',
'7', '8', '9', '0', '-', '=', '\b', '\t',
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
'o', 'p', '[', ']', '\n', NO, 'a', 's',
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
'\'', '`', NO, '\\', 'z', 'x', 'c', 'v',
'b', 'n', 'm', ',', '.', '/', NO, '*',
NO, ' ', NO, NO, NO, NO, NO, NO,
NO, NO, NO, NO, NO, NO, NO, '7',
'8', '9', '-', '4', '5', '6', '+', '1',
'2', '3', '0', '.',
};
static char shiftmap[256] =
t_8 scan_code;
RT_ASSERT(kb_in.count>0);
scan_code = *(kb_in.p_tail);
kb_in.p_tail++;
if (kb_in.p_tail == kb_in.buf + KB_IN_BYTES) {
kb_in.p_tail = kb_in.buf;
}
kb_in.count--;
return scan_code;
}
PRIVATE void kb_wait() /* wait inpit cache of 8042 */
{
NO, 033, '!', '@', '#', '$', '%', '^',
'&', '*', '(', ')', '_', '+', '\b', '\t',
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
'O', 'P', '{', '}', '\n', NO, 'A', 'S',
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';',
'"', '~', NO, '|', 'Z', 'X', 'C', 'V',
'B', 'N', 'M', '<', '>', '?', NO, '*',
NO, ' ', NO, NO, NO, NO, NO, NO,
NO, NO, NO, NO, NO, NO, NO, '7',
'8', '9', '-', '4', '5', '6', '+', '1',
'2', '3', '0', '.',
};
#define C(x) (x-'@')
static char ctlmap[256] =
t_8 kb_stat;
do {
kb_stat = inb(KB_CMD);
} while (kb_stat & 0x02);
}
PRIVATE void kb_ack()
{
NO, NO, NO, NO, NO, NO, NO, NO,
NO, NO, NO, NO, NO, NO, NO, NO,
C('Q'), C('W'), C('E'), C('R'), C('T'), C('Y'), C('U'), C('I'),
C('O'), C('P'), NO, NO, '\r', NO, C('A'), C('S'),
C('D'), C('F'), C('G'), C('H'), C('J'), C('K'), C('L'), NO,
NO, NO, NO, C('\\'), C('Z'), C('X'), C('C'), C('V'),
C('B'), C('N'), C('M'), NO, NO, C('/'), NO, NO,
};
static char *charcode[4] =
t_8 kb_read;
do {
kb_read = inb(KB_DATA);
} while (kb_read != KB_ACK);
}
PRIVATE void set_leds()
{
normalmap,
shiftmap,
ctlmap,
ctlmap,
};
t_8 leds = (caps_lock << 2) | (num_lock << 1) | scroll_lock;
kb_wait();
outb(KB_DATA, LED_CODE);
kb_ack();
kb_wait();
outb(KB_DATA, leds);
kb_ack();
}
/**
* @addtogroup QEMU
*/
/*@{*/
/**
* This function get a char from the keyboard
*/
char rt_keyboard_getc(void)
void rt_keyboard_isr(void)
{
int c;
rt_uint8_t data;
static rt_uint32_t shift;
if ((inb(KBSTATP) & KBS_DIB) == 0)
return -1;
return ;
data = inb(KBDATAP);
if (data & 0x80)
{
/* key up */
shift &= ~shiftcode[data&~0x80];
return 0;
if (kb_in.count < KB_IN_BYTES) {
*(kb_in.p_head) = data;
kb_in.p_head++;
if (kb_in.p_head == kb_in.buf + KB_IN_BYTES) {
kb_in.p_head = kb_in.buf;
}
kb_in.count++;
}
}
/* generally, this should be called in task level for all key inpit support,
but here only support a key that is composed of 2 bytes */
rt_bool_t rt_keyboard_getc(char* c)
{
if(kb_in.count>=2)
{
rt_uint32_t key = 0;
rt_bool_t rv=keyboard_read(&key);
/* key down */
shift |= shiftcode[data];
shift ^= togglecode[data];
c = charcode[shift&(CTL|SHIFT)][data];
switch(key)
{
case TAB:
*c = '\t';
break;
case ENTER:
*c = '\n';
break;
case BACKSPACE:
*c = '\b';
break;
default:
*c = key;
break;
}
if (shift&CAPSLOCK)
{
if ('a' <= c && c <= 'z')
c += 'A' - 'a';
else if ('A' <= c && c <= 'Z')
c += 'a' - 'A';
return rv;
}
return c;
return RT_FALSE;
}
/*@}*/
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
keyboard.h
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#ifndef _TINIX_KEYBOARD_H_
#define _TINIX_KEYBOARD_H_
/************************************************************************/
/* Macros Declaration */
/************************************************************************/
#define KB_IN_BYTES 32 /* size of keyboard input buffer */
#define MAP_COLS 3 /* Number of columns in keymap */
#define NR_SCAN_CODES 0x80 /* Number of scan codes (rows in keymap) */
#define FLAG_BREAK 0x0080 /* Break Code */
#define FLAG_EXT 0x0100 /* Normal function keys */
#define FLAG_SHIFT_L 0x0200 /* Shift key */
#define FLAG_SHIFT_R 0x0400 /* Shift key */
#define FLAG_CTRL_L 0x0800 /* Control key */
#define FLAG_CTRL_R 0x1000 /* Control key */
#define FLAG_ALT_L 0x2000 /* Alternate key */
#define FLAG_ALT_R 0x4000 /* Alternate key */
#define FLAG_PAD 0x8000 /* keys in num pad */
#define MASK_RAW 0x01FF /* raw key value = code passed to tty & MASK_RAW
the value can be found either in the keymap column 0
or in the list below */
/* Special keys */
#define ESC (0x01 + FLAG_EXT) /* Esc */
#define TAB (0x02 + FLAG_EXT) /* Tab */
#define ENTER (0x03 + FLAG_EXT) /* Enter */
#define BACKSPACE (0x04 + FLAG_EXT) /* BackSpace */
#define GUI_L (0x05 + FLAG_EXT) /* L GUI */
#define GUI_R (0x06 + FLAG_EXT) /* R GUI */
#define APPS (0x07 + FLAG_EXT) /* APPS */
/* Shift, Ctrl, Alt */
#define SHIFT_L (0x08 + FLAG_EXT) /* L Shift */
#define SHIFT_R (0x09 + FLAG_EXT) /* R Shift */
#define CTRL_L (0x0A + FLAG_EXT) /* L Ctrl */
#define CTRL_R (0x0B + FLAG_EXT) /* R Ctrl */
#define ALT_L (0x0C + FLAG_EXT) /* L Alt */
#define ALT_R (0x0D + FLAG_EXT) /* R Alt */
/* Lock keys */
#define CAPS_LOCK (0x0E + FLAG_EXT) /* Caps Lock */
#define NUM_LOCK (0x0F + FLAG_EXT) /* Number Lock */
#define SCROLL_LOCK (0x10 + FLAG_EXT) /* Scroll Lock */
/* Function keys */
#define F1 (0x11 + FLAG_EXT) /* F1 */
#define F2 (0x12 + FLAG_EXT) /* F2 */
#define F3 (0x13 + FLAG_EXT) /* F3 */
#define F4 (0x14 + FLAG_EXT) /* F4 */
#define F5 (0x15 + FLAG_EXT) /* F5 */
#define F6 (0x16 + FLAG_EXT) /* F6 */
#define F7 (0x17 + FLAG_EXT) /* F7 */
#define F8 (0x18 + FLAG_EXT) /* F8 */
#define F9 (0x19 + FLAG_EXT) /* F9 */
#define F10 (0x1A + FLAG_EXT) /* F10 */
#define F11 (0x1B + FLAG_EXT) /* F11 */
#define F12 (0x1C + FLAG_EXT) /* F12 */
/* Control Pad */
#define PRINTSCREEN (0x1D + FLAG_EXT) /* Print Screen */
#define PAUSEBREAK (0x1E + FLAG_EXT) /* Pause/Break */
#define INSERT (0x1F + FLAG_EXT) /* Insert */
#define DELETE (0x20 + FLAG_EXT) /* Delete */
#define HOME (0x21 + FLAG_EXT) /* Home */
#define END (0x22 + FLAG_EXT) /* End */
#define PAGEUP (0x23 + FLAG_EXT) /* Page Up */
#define PAGEDOWN (0x24 + FLAG_EXT) /* Page Down */
#define UP (0x25 + FLAG_EXT) /* Up */
#define DOWN (0x26 + FLAG_EXT) /* Down */
#define LEFT (0x27 + FLAG_EXT) /* Left */
#define RIGHT (0x28 + FLAG_EXT) /* Right */
/* ACPI keys */
#define POWER (0x29 + FLAG_EXT) /* Power */
#define SLEEP (0x2A + FLAG_EXT) /* Sleep */
#define WAKE (0x2B + FLAG_EXT) /* Wake Up */
/* Num Pad */
#define PAD_SLASH (0x2C + FLAG_EXT) /* / */
#define PAD_STAR (0x2D + FLAG_EXT) /* * */
#define PAD_MINUS (0x2E + FLAG_EXT) /* - */
#define PAD_PLUS (0x2F + FLAG_EXT) /* + */
#define PAD_ENTER (0x30 + FLAG_EXT) /* Enter */
#define PAD_DOT (0x31 + FLAG_EXT) /* . */
#define PAD_0 (0x32 + FLAG_EXT) /* 0 */
#define PAD_1 (0x33 + FLAG_EXT) /* 1 */
#define PAD_2 (0x34 + FLAG_EXT) /* 2 */
#define PAD_3 (0x35 + FLAG_EXT) /* 3 */
#define PAD_4 (0x36 + FLAG_EXT) /* 4 */
#define PAD_5 (0x37 + FLAG_EXT) /* 5 */
#define PAD_6 (0x38 + FLAG_EXT) /* 6 */
#define PAD_7 (0x39 + FLAG_EXT) /* 7 */
#define PAD_8 (0x3A + FLAG_EXT) /* 8 */
#define PAD_9 (0x3B + FLAG_EXT) /* 9 */
#define PAD_UP PAD_8 /* Up */
#define PAD_DOWN PAD_2 /* Down */
#define PAD_LEFT PAD_4 /* Left */
#define PAD_RIGHT PAD_6 /* Right */
#define PAD_HOME PAD_7 /* Home */
#define PAD_END PAD_1 /* End */
#define PAD_PAGEUP PAD_9 /* Page Up */
#define PAD_PAGEDOWN PAD_3 /* Page Down */
#define PAD_INS PAD_0 /* Ins */
#define PAD_MID PAD_5 /* Middle key */
#define PAD_DEL PAD_DOT /* Del */
/************************************************************************/
/* Stucture Definition */
/************************************************************************/
/* Keyboard structure, 1 per console. */
typedef struct s_kb {
char* p_head; /* input cache pointer */
char* p_tail; /* read cache pointer */
int count;
char buf[KB_IN_BYTES];
}KB_INPUT;
#endif /* _TINIX_KEYBOARD_H_ */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
keymap.h
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/********************************************************************/
/* "scan code" <--> "key" map. */
/* It should be and can only be included by keyboard.c! */
/********************************************************************/
#ifndef _TINIX_KEYMAP_H_
#define _TINIX_KEYMAP_H_
/* Keymap for US MF-2 keyboard. */
rt_uint32_t keymap[NR_SCAN_CODES * MAP_COLS] = {
/* scan-code !Shift Shift E0 XX */
/* ==================================================================== */
/* 0x00 - none */ 0, 0, 0,
/* 0x01 - ESC */ ESC, ESC, 0,
/* 0x02 - '1' */ '1', '!', 0,
/* 0x03 - '2' */ '2', '@', 0,
/* 0x04 - '3' */ '3', '#', 0,
/* 0x05 - '4' */ '4', '$', 0,
/* 0x06 - '5' */ '5', '%', 0,
/* 0x07 - '6' */ '6', '^', 0,
/* 0x08 - '7' */ '7', '&', 0,
/* 0x09 - '8' */ '8', '*', 0,
/* 0x0A - '9' */ '9', '(', 0,
/* 0x0B - '0' */ '0', ')', 0,
/* 0x0C - '-' */ '-', '_', 0,
/* 0x0D - '=' */ '=', '+', 0,
/* 0x0E - BS */ BACKSPACE, BACKSPACE, 0,
/* 0x0F - TAB */ TAB, TAB, 0,
/* 0x10 - 'q' */ 'q', 'Q', 0,
/* 0x11 - 'w' */ 'w', 'W', 0,
/* 0x12 - 'e' */ 'e', 'E', 0,
/* 0x13 - 'r' */ 'r', 'R', 0,
/* 0x14 - 't' */ 't', 'T', 0,
/* 0x15 - 'y' */ 'y', 'Y', 0,
/* 0x16 - 'u' */ 'u', 'U', 0,
/* 0x17 - 'i' */ 'i', 'I', 0,
/* 0x18 - 'o' */ 'o', 'O', 0,
/* 0x19 - 'p' */ 'p', 'P', 0,
/* 0x1A - '[' */ '[', '{', 0,
/* 0x1B - ']' */ ']', '}', 0,
/* 0x1C - CR/LF */ ENTER, ENTER, PAD_ENTER,
/* 0x1D - l. Ctrl */ CTRL_L, CTRL_L, CTRL_R,
/* 0x1E - 'a' */ 'a', 'A', 0,
/* 0x1F - 's' */ 's', 'S', 0,
/* 0x20 - 'd' */ 'd', 'D', 0,
/* 0x21 - 'f' */ 'f', 'F', 0,
/* 0x22 - 'g' */ 'g', 'G', 0,
/* 0x23 - 'h' */ 'h', 'H', 0,
/* 0x24 - 'j' */ 'j', 'J', 0,
/* 0x25 - 'k' */ 'k', 'K', 0,
/* 0x26 - 'l' */ 'l', 'L', 0,
/* 0x27 - ';' */ ';', ':', 0,
/* 0x28 - '\'' */ '\'', '"', 0,
/* 0x29 - '`' */ '`', '~', 0,
/* 0x2A - l. SHIFT */ SHIFT_L, SHIFT_L, 0,
/* 0x2B - '\' */ '\\', '|', 0,
/* 0x2C - 'z' */ 'z', 'Z', 0,
/* 0x2D - 'x' */ 'x', 'X', 0,
/* 0x2E - 'c' */ 'c', 'C', 0,
/* 0x2F - 'v' */ 'v', 'V', 0,
/* 0x30 - 'b' */ 'b', 'B', 0,
/* 0x31 - 'n' */ 'n', 'N', 0,
/* 0x32 - 'm' */ 'm', 'M', 0,
/* 0x33 - ',' */ ',', '<', 0,
/* 0x34 - '.' */ '.', '>', 0,
/* 0x35 - '/' */ '/', '?', PAD_SLASH,
/* 0x36 - r. SHIFT */ SHIFT_R, SHIFT_R, 0,
/* 0x37 - '*' */ '*', '*', 0,
/* 0x38 - ALT */ ALT_L, ALT_L, ALT_R,
/* 0x39 - ' ' */ ' ', ' ', 0,
/* 0x3A - CapsLock */ CAPS_LOCK, CAPS_LOCK, 0,
/* 0x3B - F1 */ F1, F1, 0,
/* 0x3C - F2 */ F2, F2, 0,
/* 0x3D - F3 */ F3, F3, 0,
/* 0x3E - F4 */ F4, F4, 0,
/* 0x3F - F5 */ F5, F5, 0,
/* 0x40 - F6 */ F6, F6, 0,
/* 0x41 - F7 */ F7, F7, 0,
/* 0x42 - F8 */ F8, F8, 0,
/* 0x43 - F9 */ F9, F9, 0,
/* 0x44 - F10 */ F10, F10, 0,
/* 0x45 - NumLock */ NUM_LOCK, NUM_LOCK, 0,
/* 0x46 - ScrLock */ SCROLL_LOCK, SCROLL_LOCK, 0,
/* 0x47 - Home */ PAD_HOME, '7', HOME,
/* 0x48 - CurUp */ PAD_UP, '8', UP,
/* 0x49 - PgUp */ PAD_PAGEUP, '9', PAGEUP,
/* 0x4A - '-' */ PAD_MINUS, '-', 0,
/* 0x4B - Left */ PAD_LEFT, '4', LEFT,
/* 0x4C - MID */ PAD_MID, '5', 0,
/* 0x4D - Right */ PAD_RIGHT, '6', RIGHT,
/* 0x4E - '+' */ PAD_PLUS, '+', 0,
/* 0x4F - End */ PAD_END, '1', END,
/* 0x50 - Down */ PAD_DOWN, '2', DOWN,
/* 0x51 - PgDown */ PAD_PAGEDOWN, '3', PAGEDOWN,
/* 0x52 - Insert */ PAD_INS, '0', INSERT,
/* 0x53 - Delete */ PAD_DOT, '.', DELETE,
/* 0x54 - Enter */ 0, 0, 0,
/* 0x55 - ??? */ 0, 0, 0,
/* 0x56 - ??? */ 0, 0, 0,
/* 0x57 - F11 */ F11, F11, 0,
/* 0x58 - F12 */ F12, F12, 0,
/* 0x59 - ??? */ 0, 0, 0,
/* 0x5A - ??? */ 0, 0, 0,
/* 0x5B - ??? */ 0, 0, GUI_L,
/* 0x5C - ??? */ 0, 0, GUI_R,
/* 0x5D - ??? */ 0, 0, APPS,
/* 0x5E - ??? */ 0, 0, 0,
/* 0x5F - ??? */ 0, 0, 0,
/* 0x60 - ??? */ 0, 0, 0,
/* 0x61 - ??? */ 0, 0, 0,
/* 0x62 - ??? */ 0, 0, 0,
/* 0x63 - ??? */ 0, 0, 0,
/* 0x64 - ??? */ 0, 0, 0,
/* 0x65 - ??? */ 0, 0, 0,
/* 0x66 - ??? */ 0, 0, 0,
/* 0x67 - ??? */ 0, 0, 0,
/* 0x68 - ??? */ 0, 0, 0,
/* 0x69 - ??? */ 0, 0, 0,
/* 0x6A - ??? */ 0, 0, 0,
/* 0x6B - ??? */ 0, 0, 0,
/* 0x6C - ??? */ 0, 0, 0,
/* 0x6D - ??? */ 0, 0, 0,
/* 0x6E - ??? */ 0, 0, 0,
/* 0x6F - ??? */ 0, 0, 0,
/* 0x70 - ??? */ 0, 0, 0,
/* 0x71 - ??? */ 0, 0, 0,
/* 0x72 - ??? */ 0, 0, 0,
/* 0x73 - ??? */ 0, 0, 0,
/* 0x74 - ??? */ 0, 0, 0,
/* 0x75 - ??? */ 0, 0, 0,
/* 0x76 - ??? */ 0, 0, 0,
/* 0x77 - ??? */ 0, 0, 0,
/* 0x78 - ??? */ 0, 0, 0,
/* 0x78 - ??? */ 0, 0, 0,
/* 0x7A - ??? */ 0, 0, 0,
/* 0x7B - ??? */ 0, 0, 0,
/* 0x7C - ??? */ 0, 0, 0,
/* 0x7D - ??? */ 0, 0, 0,
/* 0x7E - ??? */ 0, 0, 0,
/* 0x7F - ??? */ 0, 0, 0
};
/*====================================================================================*
Appendix: Scan code set 1
*====================================================================================*
KEY MAKE BREAK ----- KEY MAKE BREAK ----- KEY MAKE BREAK
--------------------------------------------------------------------------------------
A 1E 9E 9 0A 8A [ 1A 9A
B 30 B0 ` 29 89 INSERT E0,52 E0,D2
C 2E AE - 0C 8C HOME E0,47 E0,C7
D 20 A0 = 0D 8D PG UP E0,49 E0,C9
E 12 92 \ 2B AB DELETE E0,53 E0,D3
F 21 A1 BKSP 0E 8E END E0,4F E0,CF
G 22 A2 SPACE 39 B9 PG DN E0,51 E0,D1
H 23 A3 TAB 0F 8F U ARROW E0,48 E0,C8
I 17 97 CAPS 3A BA L ARROW E0,4B E0,CB
J 24 A4 L SHFT 2A AA D ARROW E0,50 E0,D0
K 25 A5 L CTRL 1D 9D R ARROW E0,4D E0,CD
L 26 A6 L GUI E0,5B E0,DB NUM 45 C5
M 32 B2 L ALT 38 B8 KP / E0,35 E0,B5
N 31 B1 R SHFT 36 B6 KP * 37 B7
O 18 98 R CTRL E0,1D E0,9D KP - 4A CA
P 19 99 R GUI E0,5C E0,DC KP + 4E CE
Q 10 19 R ALT E0,38 E0,B8 KP EN E0,1C E0,9C
R 13 93 APPS E0,5D E0,DD KP . 53 D3
S 1F 9F ENTER 1C 9C KP 0 52 D2
T 14 94 ESC 01 81 KP 1 4F CF
U 16 96 F1 3B BB KP 2 50 D0
V 2F AF F2 3C BC KP 3 51 D1
W 11 91 F3 3D BD KP 4 4B CB
X 2D AD F4 3E BE KP 5 4C CC
Y 15 95 F5 3F BF KP 6 4D CD
Z 2C AC F6 40 C0 KP 7 47 C7
0 0B 8B F7 41 C1 KP 8 48 C8
1 02 82 F8 42 C2 KP 9 49 C9
2 03 83 F9 43 C3 ] 1B 9B
3 04 84 F10 44 C4 ; 27 A7
4 05 85 F11 57 D7 ' 28 A8
5 06 86 F12 58 D8 , 33 B3
6 07 87 PRTSCRN E0,2A E0,B7 . 34 B4
E0,37 E0,AA
7 08 88 SCROLL 46 C6 / 35 B5
8 09 89 PAUSE E1,1D,45 -NONE-
E1,9D,C5
-----------------
ACPI Scan Codes:
-------------------------------------------
Key Make Code Break Code
-------------------------------------------
Power E0, 5E E0, DE
Sleep E0, 5F E0, DF
Wake E0, 63 E0, E3
-------------------------------
Windows Multimedia Scan Codes:
-------------------------------------------
Key Make Code Break Code
-------------------------------------------
Next Track E0, 19 E0, 99
Previous Track E0, 10 E0, 90
Stop E0, 24 E0, A4
Play/Pause E0, 22 E0, A2
Mute E0, 20 E0, A0
Volume Up E0, 30 E0, B0
Volume Down E0, 2E E0, AE
Media Select E0, 6D E0, ED
E-Mail E0, 6C E0, EC
Calculator E0, 21 E0, A1
My Computer E0, 6B E0, EB
WWW Search E0, 65 E0, E5
WWW Home E0, 32 E0, B2
WWW Back E0, 6A E0, EA
WWW Forward E0, 69 E0, E9
WWW Stop E0, 68 E0, E8
WWW Refresh E0, 67 E0, E7
WWW Favorites E0, 66 E0, E6
*=====================================================================================*/
#endif /* _TINIX_KEYMAP_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册