| 
 
hebecoco 
初级用户
 
  
 
  
  
积分 63 
发帖 25 
注册 2006-12-24 
状态 离线
 | 
『楼 主』:
 在DOS下如何用C实现键盘某键的按下
 
使用 LLM 解释/回答一下
  
例如,我希望用C语言写一程序实现CAPS LOCK,NUM LOCK,SCR LOCK键的按下,然后对应的灯会自动亮起 
大虾们知道的帮帮忙,小弟谢谢了,很急!!! 
 
    
 
  
 |   
 | 
  2006-12-24 04:04 | 
  
 | 
 | 
 
bill2241 
新手上路
 
 
 
  
  
积分 2 
发帖 1 
注册 2006-3-11 
状态 离线
 | 
『第 2 楼』:
 
 
使用 LLM 解释/回答一下
  
你可以自己去测试啦 
使用BIOSDISK函数可以 
使用BIOS中断~~~~ 
测试扫描码~~就可以啦 
 
    
 
  
 |   
 | 
  2006-12-24 10:28 | 
  
 | 
 | 
 
zyl910 
中级用户
 
   
 
  
  
积分 282 
发帖 126 
注册 2006-5-17 
状态 离线
 | 
『第 3 楼』:
 
 
使用 LLM 解释/回答一下
  
BIOS内存区: 
 
   40:17   byte   Keyboard flag byte 0 (see KB FLAGS) 
      |7|6|5|4|3|2|1|0| keyboard flag byte 0 
       | | | | | | | `--- right shift key depressed 
       | | | | | | `---- left shift key depressed 
       | | | | | `----- CTRL key depressed 
       | | | | `------ ALT key depressed 
       | | | `------- scroll-lock is active 
       | | `-------- num-lock is active 
       | `--------- caps-lock is active 
       `---------- insert is active 
   40:18   byte   Keyboard flag byte 1 (see KB FLAGS) 
      |7|6|5|4|3|2|1|0| keyboard flag byte 
       | | | | | | | `--- left CTRL key depressed 
       | | | | | | `---- left ALT key depressed 
       | | | | | `----- system key depressed and held 
       | | | | `------ suspend key has been toggled 
       | | | `------- scroll lock key is depressed 
       | | `-------- num-lock key is depressed 
       | `--------- caps-lock key is depressed 
       `---------- insert key is depressed 
 
    
 
  
  |  
                  
  
                    人类存在的目的就是试图理解人类为何存在 |   
 | 
  2006-12-24 23:08 | 
  
 | 
 | 
 
hebecoco 
初级用户
 
  
 
  
  
积分 63 
发帖 25 
注册 2006-12-24 
状态 离线
 | 
『第 4 楼』:
 
 
使用 LLM 解释/回答一下
  
感谢大家,问题已经解决了~我是直接从0x00400017H中进行位操作来实现的 
但现在我又面临一个新的测试,还是关于键盘测试的,有些特殊的键盘上面有一些很特别的键,如SONY笔记本中一些键盘上有播放/暂停,快近,后退,停止键等,这些键在WINDOWS下是可以的,现在我要在DOS下进行测试,在DOS中按下肯定是没有任何反应的,但是在BIOS中肯定有相应的响应,或者有相应的扫描码被存入到键盘缓冲区中,但是我现在不知道如何去抓,请教下有没有谁做过这样的测试. 
用BC和TC都可以,如果有汇编也可以,不过我汇编不是熟 
 
 Last edited by hebecoco on 2006-12-25 at 03:16 PM ] 
 
    
 
  
 |   
 | 
  2006-12-25 22:07 | 
  
 | 
 | 
 
hebecoco 
初级用户
 
  
 
  
  
积分 63 
发帖 25 
注册 2006-12-24 
状态 离线
 | 
『第 5 楼』:
 
 
使用 LLM 解释/回答一下
  
我有试过用bioskey()函数,抓不出来 
现在主要的问题是我不知道在哪个地址位按那几个特殊键有变化,如果能知道哪个位的话,我直接用peek读出来就可以了,我有试过从键盘缓冲区0x401c中去读,也读不出来 
有知道的麻烦告知下,谢谢了~~~~ 
 
    
 
  
 |   
 | 
  2006-12-26 00:05 | 
  
 | 
 | 
 
AlwaysInherit 
初级用户
 
   征(武林高手||搞安全 ..
  
  
积分 112 
发帖 46 
注册 2005-9-28 
状态 离线
 | 
 | 
  2006-12-26 02:00 | 
  
 | 
 | 
 
hebecoco 
初级用户
 
  
 
  
  
积分 63 
发帖 25 
注册 2006-12-24 
状态 离线
 | 
『第 7 楼』:
 
 
使用 LLM 解释/回答一下
  
AlwaysInherit 
       感谢你提供的资料,我大概的看了一遍,其中提到MAKE/BREAK的问题,一个代表是键的按下,一个代表是键的释放,但我很想知道这2个值可以从从哪里读出来,是从0X64中吗? 
 
    
 
  
 |   
 | 
  2006-12-26 03:13 | 
  
 | 
 | 
 
hebecoco 
初级用户
 
  
 
  
  
积分 63 
发帖 25 
注册 2006-12-24 
状态 离线
 | 
 | 
  2006-12-26 03:17 | 
  
 | 
 | 
 
AlwaysInherit 
初级用户
 
   征(武林高手||搞安全 ..
  
  
积分 112 
发帖 46 
注册 2005-9-28 
状态 离线
 | 
『第 9 楼』:
 
 
使用 LLM 解释/回答一下
  
kb 的 scancode ?? 那好像在kb buffer 中 
 
我也不是清楚,你是问怎样读出kb 的 scancode吗? 还是加对应的scancode 到kb buffer中? 
 
    
 
  
 |   
 | 
  2006-12-26 03:55 | 
  
 | 
 | 
 
hebecoco 
初级用户
 
  
 
  
  
积分 63 
发帖 25 
注册 2006-12-24 
状态 离线
 | 
『第 10 楼』:
 
 
使用 LLM 解释/回答一下
  
我有试过在kb buffer中抓,但抓不出来,kb buffer的地址为0x0040001CH 
现在我是我想抓make code 和break code; 
 
    
 
  
 |   
 | 
  2006-12-26 04:10 | 
  
 | 
 | 
 
AlwaysInherit 
初级用户
 
   征(武林高手||搞安全 ..
  
  
积分 112 
发帖 46 
注册 2005-9-28 
状态 离线
 | 
 | 
  2006-12-26 04:53 | 
  
 | 
 | 
 
hebecoco 
初级用户
 
  
 
  
  
积分 63 
发帖 25 
注册 2006-12-24 
状态 离线
 | 
 | 
  2006-12-26 06:16 | 
  
 | 
 | 
 
hebecoco 
初级用户
 
  
 
  
  
积分 63 
发帖 25 
注册 2006-12-24 
状态 离线
 | 
『第 13 楼』:
 
 
使用 LLM 解释/回答一下
  
虽然理解了很多,但是还是没办法读那几个播放键,我有试过把键盘缓冲区里的值全部读出来,然后去按那几个BUTONN,发现BUFFER里面的32个字节没有任何变化,就是说那几个BUTONN是根本没有经过键盘BUFFER. 
但现在那几个BUTONN在资料里面有相应的make code 和break code,那肯定是可以读出来的,只是不知道在哪里读,这步才是最关键的, 
 
    
 
  
 |   
 | 
  2006-12-26 21:25 | 
  
 | 
 | 
 
hebecoco 
初级用户
 
  
 
  
  
积分 63 
发帖 25 
注册 2006-12-24 
状态 离线
 | 
『第 14 楼』:
 
 
使用 LLM 解释/回答一下
  
有人提到用键盘中断,本人还不是很会用中断,但我想就算是用中断,也要知道用什么值去中断,在DOS下,CPU是否又会响应这个中断,如果说CPU没做出相应的响应,我也是没办法去测的, 
用中断我觉得模拟一个键的按下可能容易点,但要去测的话实现起来应该不是很简单 
 
请教各路高手,有没有解决的办法,最主要的就是解决怎么去读那些BUTONN的make code和break code, 
 
    
 
  
 |   
 | 
  2006-12-26 21:32 | 
  
 | 
 | 
 
zyl910 
中级用户
 
   
 
  
  
积分 282 
发帖 126 
注册 2006-5-17 
状态 离线
 | 
『第 15 楼』:
 
 
使用 LLM 解释/回答一下
  
那几个播放键不是PC标准,不会进键盘缓冲区的 
你只有挂接键盘中断(IRQ1,INT9),从60h端口得到按键扫描码
 
而且注意,由于那几个播放键不是PC标准 
所以在Windows系统不会为这几个按键触发中断的(还包括Win键、快捷菜单键等等) 
也就是说,只有纯DOS下才能得知那几个按键的按下与释放
 
以前写的一个专用来研究按键扫描码的小程序:
  
#include <stdio.h> 
#include <conio.h> 
#include <dos.h> 
 
#ifdef __cplusplus 
    #define __CPPARGS ... 
#else 
    #define __CPPARGS 
#endif 
 
 
#define	MAXKEYQUEUE	0x40 
static	char	kqQueue;	// 队列 
static	int	kqFirst = 0;	// 指向首个数据 
static	int	kqLast = 0;	// 指向首个空位 
static	int	kqCount = 0;	// 该队列有多少元素 
 
#define KSC_PRESS	0x80 
#define KSC_DATAMASK	0x7F 
#define	KSC_EXTEND	0xE0 
 
#define	KSC_ESC	1 
 
void interrupt get_out(__CPPARGS);    /* interrupt prototype */ 
 
void interrupt (*oldfunc)(__CPPARGS); /* interrupt function pointer */ 
 
 
int main(void) 
{ 
	unsigned char	byKey; 
	int	iEscCount=0; 
 
	puts("Esc*3: Exit\n"); 
 
	/* save the old interrupt */ 
	oldfunc  = _dos_getvect(9); 
 
	/* install interrupt handler */ 
	_dos_setvect(9,get_out); 
 
	/* do nothing */ 
	while (iEscCount < 3){ 
		/* show key queue */ 
		while(kqCount > 0){ 
			/* get curent ScanCode */ 
			__asm	cli; 
				byKey = kqQueue; 
				if (kqFirst >= MAXKEYQUEUE)	kqFirst -= MAXKEYQUEUE; 
				kqCount--; 
			__asm	sti; 
 
			/* show */ 
			printf("%X\t", byKey); 
 
			/* check Esc */ 
			if (byKey & KSC_PRESS)	{ 
				if (KSC_ESC == (byKey & KSC_DATAMASK))	{ 
					iEscCount++; 
					if (2 == iEscCount){ 
						clrscr(); 
					} 
				}else	{ 
					iEscCount = 0; 
				} 
			} 
		} 
	}; 
 
	/* restore to original interrupt routine */ 
	_dos_setvect(9,oldfunc); 
 
	puts("Success"); 
	return 0; 
} 
 
void interrupt get_out(__CPPARGS) 
{ 
	{ 
		unsigned char byKey; 
 
		/* get ScanCode */ 
		byKey = inportb(0x60); 
 
		/* add to key queue */ 
		if (kqCount < MAXKEYQUEUE){ 
			kqQueue = byKey; 
			if (kqLast >= MAXKEYQUEUE)	kqLast -= MAXKEYQUEUE; 
			kqCount++; 
		} 
	} 
	oldfunc(__CPPARGS); 
} 
  
 
    
 
 
 
  
  |  
                  
  
                    人类存在的目的就是试图理解人类为何存在 |   
 | 
  2006-12-26 22:22 | 
  
 |