C语言 键盘输入返回奇怪的符号|| Own Kernel



我们在学校做一个为期一年的项目。我和一个同事有一个想法,我们应该试着写一个简单的操作系统。我们在Asm和C语言方面没有那么丰富的经验,所以我们认为给自己设定一个任务并尝试解决它是最好的学习方法。

不幸的是,我们已经用键盘输入失败了…

操作系统按预期启动,并写入预期语句"Hello world"在屏幕上。但是只要你按下键盘上的键,屏幕上就会出现一些奇怪的符号。

如果你能解释我们做错了什么,并修复错误,我们将不胜感激

源代码在github上:https://github.com/Fabbboy/alpsos/tree/master/src/impl/kernel/drivers

谢谢你的帮助

EDIT -从github添加代码到stackoverflow

Keyboard.h


#ifndef ALPSOS_KEYBOARD_H
#define ALPSOS_KEYBOARD_H
#include <stdint.h>
uint8_t inb(uint16_t port);
//read from port 0x60
uint8_t keyboard_read_input();
//identify the key pressed
char keyboard_handle_input();

#endif //ALPSOS_KEYBOARD_H

And the keyboardc

#include <stdint.h>
uint8_t inb(uint16_t port){
uint8_t ret;
asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
};
//read from port 0x60
uint8_t keyboard_read_input(){
//if something is on port 0x60
while(!(inb(0x64) & 1));
return inb(0x60);
};
//identify the key pressed
char keyboard_handle_input(){
uint8_t input = keyboard_read_input();
if(input == 0x1C){
return 'A';
}
if(input == 0x1D){
return 'B';
}
if(input == 0x1E){
return 'C';
}
if(input == 0x1F){
return 'D';
}
if(input == 0x20){
return 'E';
}
if(input == 0x21){
return 'F';
}
if(input == 0x22){
return 'G';
}
if(input == 0x23){
return 'H';
}
if(input == 0x24){
return 'I';
}
if(input == 0x25){
return 'J';
}
if(input == 0x26){
return 'K';
}
if(input == 0x27){
return 'L';
}
if(input == 0x28){
return 'M';
}
if(input == 0x29){
return 'N';
}
if(input == 0x2A){
return 'O';
}
if(input == 0x2B){
return 'P';
}
if(input == 0x2C){
return 'Q';
}
if(input == 0x2D){
return 'R';
}
if(input == 0x2E){
return 'S';
}
if(input == 0x2F){
return 'T';
}
if(input == 0x30){
return 'U';
}
if(input == 0x31){
return 'V';
}
if(input == 0x32){
return 'W';
}
if(input == 0x33){
return 'X';
}
if(input == 0x34){
return 'Y';
}
if(input == 0x35){
return 'Z';
}
};

你从哪里得到的想法,键盘将返回从0x1C到0x35对应于'A'到'Z'的漂亮的连续范围?

接下来是字母表的键盘扫描码:

a 0x1E
b 0x30
c 0x2E
d 0x20
e 0x12
f 0x21
g 0x22
h 0x23
i 0x17
j 0x24
k 0x25
l 0x26
m 0x27
n 0x31
o 0x18
p 0x19
q 0x10
r 0x13
s 0x1F
t 0x14
u 0x16
v 0x2F
w 0x11
x 0x2d
y 0x15
z 0x2C

这些代码本身并不能告诉你关于字符大小写的任何信息!这是您的程序必须通过查看上按下的caps-lock和/或shift来提供的改进。
如果它是键盘发送的释放代码,则可以设置从端口0x60读取的最高位。大多数情况下,你会想忽略它们。

写一个像样的键盘处理程序不是微不足道的!这比仅仅从端口0x60读取要复杂得多。我相信你可以在网上找到很好的例子。

很可能你的键盘映射是错误的。一个简单的解决方案是制作一个测试版本,其中接收到的原始数字以十六进制显示,允许您创建how键映射。

应该尽可能避免使用if链,因为它们需要更多的时间和代码空间。使用switch会更好,但最好使用查找表。您可以将其实现为字符串:

char *keymap = "0123456789ABCDEF";

或作为数组(在我看来可读性更强):

char keymap[NUMBER_KEYS] = 
{
[0x00] = '',
[0x01] = '1',
/* ... */
[0x1C] = 'A',
[0x1D] = 'B',
[0x1E] = 'C',
[0x1F] = 'D',
[0x20] = 'E',
/* ... */
};

指定初始化器使键代码与其字符之间的关联更易于阅读,但它们不是强制性的。

最新更新