Merge pull request #805 from parai/master
[bsp] x86: keyboad input bug fix
This commit is contained in:
commit
1bfdc7dd30
|
@ -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();
|
||||
rt_keyboard_isr();
|
||||
|
||||
if(c == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(c > 0)
|
||||
{
|
||||
/* disable interrupt */
|
||||
level = rt_hw_interrupt_disable();
|
||||
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;
|
||||
/* 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;
|
||||
}
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
/* 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");
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
#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
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
|
||||
#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,§or);
|
||||
|
||||
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);
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#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;
|
||||
|
||||
static char normalmap[256] =
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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', '.',
|
||||
};
|
||||
t_8 scan_code;
|
||||
|
||||
static char shiftmap[256] =
|
||||
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', '.',
|
||||
};
|
||||
t_8 kb_stat;
|
||||
|
||||
#define C(x) (x-'@')
|
||||
do {
|
||||
kb_stat = inb(KB_CMD);
|
||||
} while (kb_stat & 0x02);
|
||||
}
|
||||
|
||||
static char ctlmap[256] =
|
||||
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,
|
||||
};
|
||||
t_8 kb_read;
|
||||
|
||||
static char *charcode[4] =
|
||||
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)
|
||||
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)
|
||||
{
|
||||
/* key up */
|
||||
shift &= ~shiftcode[data&~0x80];
|
||||
return 0;
|
||||
rt_uint32_t key = 0;
|
||||
rt_bool_t rv=keyboard_read(&key);
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case TAB:
|
||||
*c = '\t';
|
||||
break;
|
||||
case ENTER:
|
||||
*c = '\n';
|
||||
break;
|
||||
case BACKSPACE:
|
||||
*c = '\b';
|
||||
break;
|
||||
default:
|
||||
*c = key;
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* key down */
|
||||
shift |= shiftcode[data];
|
||||
shift ^= togglecode[data];
|
||||
c = charcode[shift&(CTL|SHIFT)][data];
|
||||
|
||||
if (shift&CAPSLOCK)
|
||||
{
|
||||
if ('a' <= c && c <= 'z')
|
||||
c += 'A' - 'a';
|
||||
else if ('A' <= c && c <= 'Z')
|
||||
c += 'a' - 'A';
|
||||
}
|
||||
|
||||
return c;
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
|
||||
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
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_ */
|
|
@ -0,0 +1,239 @@
|
|||
|
||||
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
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_ */
|
Loading…
Reference in New Issue