当前位置: 首页 > article >正文

使用控制台与键盘进行输入输出

1、控制台简介与初始化

计算机在上电启动后,显示器被默认配置成80x25列的文本显示模式 。其使用从0xb8000开始,一共32KB的显存用于显示。如要在屏幕上指定位置显示特定的字符,则只需找到该位置对应的显存地址,写入2字节的数据:ascii码和颜色属性字节。

由于一屏共8025个字符,每个字符占用2个字节,所以一屏字符显示需要约4000字节数据。而显存一共32KB,因此这些存储区域可以存储8块屏幕的显示数据。

后续可以通过切换对应的显存屏幕数据。

2、在控制台上显示字符串

采用老式屏幕显示方式,没有采用现在的显卡写。

显示字符,只需要往计算机的显存中写入数据即可。计算机上的显卡会自动从这块区域读取数据,完后控制屏幕显示。

具体显示时,如果需要往屏幕上写字符显示,需要使用两个字节来控制。一个字节用于显示字符,一个字节用于配置显示属性

3、处理换行和清屏

清屏:填入空白字符即可实现清屏功能。即只需要将当前屏幕对应的显存内容全部用空格符号清空,或者用前景色和后景色相同的字符清空

换行:当已经显示满屏时,整个屏幕需要上移滚屏。具体实现采用了非常简单的方式:将整个屏幕区域的数据往上复制一行。

3、设置光标

光标的主要作用是帮助用户感知下一字符显示的位置

在文本模式下,计算机显示硬件自动会提供一个光标,并且经BIOS设置后会显示在屏幕上。但是,当我们在显存上写入字符后,光标并不会自动调整位置。 因此,我们要做的只是随着显示的位置,调整光标的显示位置,无需再初始化。

光标的位置为在整个屏幕中显示的字符符号。在当前的显示模式下,显示范围为80列*25行,因此总共有2000个字符,如果以0开始进行编址,则光标的地址范围为0~1999。即屏幕左上角的位置为0,右下角的位置为1999.

4、保存并恢复光标位置

本小节实现光标位置的保存和恢复,其两个序列如下:

CSI sSCP – 保存光标位置(Save Cursor Position)保存光标的当前位置。
CSI uRCP – 恢复光标位置(Restore Cursor Position)恢复保存的光标位置。

示例:

int main (void) {
 printf("\0337Hello,word!\0338123\n");  // ESC 7,8 输出123lo,word!
 printf("\033[31;42mHello,word!\033[39;49m123\n");  // ESC [pn m, Hello,world红色,>其余绿色
 printf("123\033[2DHello,word!\n");  // 光标左移2,1Hello,word!
 printf("123\033[2CHello,word!\n");  // 光标右移2,123  Hello,word!

 printf("\033[31m");  // ESC [pn m, Hello,world红色,其余绿色
 printf("\033[10;10H test!\n");  // 定位到10, 10,test!
 printf("\033[20;20H test!\n");  // 定位到20, 20,test!
 printf("\033[32;25;39m123\n");  // ESC [pn m, Hello,world红色,其余绿色
}

5、更新显示字体的颜色

| CSI n m | SGR – 选择图形再现(Select Graphic Rendition) | 设置SGR参数 ,包括文字颜色

CSI后可以是0或者更多参数,用分号分隔。如果没有参数,则视为CSI 0 m(重置/常规)。

6、移动光标位置并清屏

CSI n ACUU – 光标上移(Cursor Up)光标向指定的方向移动(默认1)格。如果光标已在屏幕边缘,则无效。
CSI n BCUD – 光标下移(Cursor Down)
CSI n CCUF – 光标前移(Cursor Forward)
CSI n DCUB – 光标后移(Cursor Back)
CSI n ECNL – 光标移到下一行(Cursor Next Line)光标移动到下面第(默认1)行的开头。(非ANSI.SYS
CSI n FCPL – 光标移到上一行(Cursor Previous Line)光标移动到上面第(默认1)行的开头。(非ANSI.SYS)
CSI n GCHA – 光标水平绝对(Cursor Horizontal Absolute)光标移动到第(默认1)列。(非ANSI.SYS)
CSI n ; m HCUP – 光标位置(Cursor Position)光标移动到第n行、第m列。值从1开始,且默认为1(左上角)。例如CSI ;5H和CSI 1;5H含义相同;CSI 17;H、CSI 17H和CSI 17;1H三者含义相同。
CSI n JED – 擦除显示(Erase in Display)清除屏幕的部分区域。如果n是0(或缺失),则清除从光标位置到屏幕末尾的部分。如果n是1,则清除从光标位置到屏幕开头的部分。如果n是2,则清除整个屏幕(在DOS ANSI.SYS中,光标还会向左上方移动)。如果n是3,则清除整个屏幕,并删除回滚缓存区中的所有行(这个特性是xterm
添加的,其他终端应用程序也支持)。

7、键盘初始化

PC机中使用键盘控制器(KBC)处理键盘与鼠标的链接。键盘与鼠标通过KBC与CPU进行通信,并链接到中断控制器IRQ1和IRQ2

通过端口0x60和0x64对KBC进行配置以及读取相应的数据

IO Port读写功能
0x60读/写数据寄存器
0x64只读状态寄存器
0x64只写命令寄存器

其中状态寄存器的值如下

BitMeaning
0输出缓存寄存器(0 = 空,无数据, 1 = 满,有数据)
1输入缓存寄存器(0 = 空,无数据, 1 = 满,有数据)
2系统标志位
3命令或数据(0 = data written to input buffer is data for PS/2 device, 1 = data written to input buffer is data for PS/2 controller command)
4-
5-
6是否发生超时错误 (0 = no error, 1 = time-out error)
7是否发生奇偶校验错误 (0 = no error, 1 = parity error)

在计算机上电后,BIOS会自动完成对键盘相关的初始化,因此我们只需要使用缺省值即可,无需再次初始化

8、借助按键映射表进行键值转换

主要对读取的键值进行转码,并且处理shift健按下时大小写转换的问题

键盘扫描码

当按键按下时,将触发中断,可从中断中读取按键的键值,但是这个值并非按键上的字符丝印对应的字符,而是某种特定编码的数值,这套编码为键盘扫描码集1(Scan Code Set 1),如下表:

Scan codeKeyScan codeKeyScan codeKeyScan codeKey
0x01escape pressed0x021 pressed0x032 pressed
0x043 pressed0x054 pressed0x065 pressed0x076 pressed
0x087 pressed0x098 pressed0x0A9 pressed0x0B0 (zero) pressed
0x0C- pressed0x0D= pressed0x0Ebackspace pressed0x0Ftab pressed
0x10Q pressed0x11W pressed0x12E pressed0x13R pressed
0x14T pressed0x15Y pressed0x16U pressed0x17I pressed
0x18O pressed0x19P pressed0x1A[ pressed0x1B] pressed
0x1Center pressed0x1Dleft control pressed0x1EA pressed0x1FS pressed
0x20D pressed0x21F pressed0x22G pressed0x23H pressed
0x24J pressed0x25K pressed0x26L pressed0x27; pressed
0x28' (single quote) pressed0x29` (back tick) pressed0x2Aleft shift pressed0x2B\ pressed
0x2CZ pressed0x2DX pressed0x2EC pressed0x2FV pressed
0x30B pressed0x31N pressed0x32M pressed0x33, pressed
0x34. pressed0x35/ pressed0x36right shift pressed0x37(keypad) * pressed
0x38left alt pressed0x39space pressed0x3ACapsLock pressed0x3BF1 pressed
0x3CF2 pressed0x3DF3 pressed0x3EF4 pressed0x3FF5 pressed
0x40F6 pressed0x41F7 pressed0x42F8 pressed0x43F9 pressed
0x44F10 pressed0x45NumberLock pressed0x46ScrollLock pressed0x47(keypad) 7 pressed
0x48(keypad) 8 pressed0x49(keypad) 9 pressed0x4A(keypad) - pressed0x4B(keypad) 4 pressed
0x4C(keypad) 5 pressed0x4D(keypad) 6 pressed0x4E(keypad) + pressed0x4F(keypad) 1 pressed
0x50(keypad) 2 pressed0x51(keypad) 3 pressed0x52(keypad) 0 pressed0x53(keypad) . pressed
0x57F11 pressed
0x58F12 pressed
0x81escape released0x821 released0x832 released
0x843 released0x854 released0x865 released0x876 released
0x887 released0x898 released0x8A9 released0x8B0 (zero) released
0x8C- released0x8D= released0x8Ebackspace released0x8Ftab released
0x90Q released0x91W released0x92E released0x93R released
0x94T released0x95Y released0x96U released0x97I released
0x98O released0x99P released0x9A[ released0x9B] released
0x9Center released0x9Dleft control released0x9EA released0x9FS released
0xA0D released0xA1F released0xA2G released0xA3H released
0xA4J released0xA5K released0xA6L released0xA7; released
0xA8' (single quote) released0xA9` (back tick) released0xAAleft shift released0xAB\ released
0xACZ released0xADX released0xAEC released0xAFV released
0xB0B released0xB1N released0xB2M released0xB3, released
0xB4. released0xB5/ released0xB6right shift released0xB7(keypad) * released
0xB8left alt released0xB9space released0xBACapsLock released0xBBF1 released
0xBCF2 released0xBDF3 released0xBEF4 released0xBFF5 released
0xC0F6 released0xC1F7 released0xC2F8 released0xC3F9 released
0xC4F10 released0xC5NumberLock released0xC6ScrollLock released0xC7(keypad) 7 released
0xC8(keypad) 8 released0xC9(keypad) 9 released0xCA(keypad) - released0xCB(keypad) 4 released
0xCC(keypad) 5 released0xCD(keypad) 6 released0xCE(keypad) + released0xCF(keypad) 1 released
0xD0(keypad) 2 released0xD1(keypad) 3 released0xD2(keypad) 0 released0xD3(keypad) . released
0xD7F11 released
0xD8F12 released
0xE0, 0x10(multimedia) previous track pressed
0xE0, 0x19(multimedia) next track pressed
0xE0, 0x1C(keypad) enter pressed0xE0, 0x1Dright control pressed
0xE0, 0x20(multimedia) mute pressed0xE0, 0x21(multimedia) calculator pressed0xE0, 0x22(multimedia) play pressed
0xE0, 0x24(multimedia) stop pressed
0xE0, 0x2E(multimedia) volume down pressed
0xE0, 0x30(multimedia) volume up pressed0xE0, 0x32(multimedia) WWW home pressed
0xE0, 0x35(keypad) / pressed
0xE0, 0x38right alt (or altGr) pressed
0xE0, 0x47home pressed
0xE0, 0x48cursor up pressed0xE0, 0x49page up pressed0xE0, 0x4Bcursor left pressed
0xE0, 0x4Dcursor right pressed0xE0, 0x4Fend pressed
0xE0, 0x50cursor down pressed0xE0, 0x51page down pressed0xE0, 0x52insert pressed0xE0, 0x53delete pressed
0xE0, 0x5Bleft GUI pressed
0xE0, 0x5Cright GUI pressed0xE0, 0x5D"apps" pressed0xE0, 0x5E(ACPI) power pressed0xE0, 0x5F(ACPI) sleep pressed
0xE0, 0x63(ACPI) wake pressed
0xE0, 0x65(multimedia) WWW search pressed0xE0, 0x66(multimedia) WWW favorites pressed0xE0, 0x67(multimedia) WWW refresh pressed
0xE0, 0x68(multimedia) WWW stop pressed0xE0, 0x69(multimedia) WWW forward pressed0xE0, 0x6A(multimedia) WWW back pressed0xE0, 0x6B(multimedia) my computer pressed
0xE0, 0x6C(multimedia) email pressed0xE0, 0x6D(multimedia) media select pressed
0xE0, 0x90(multimedia) previous track released
0xE0, 0x99(multimedia) next track released
0xE0, 0x9C(keypad) enter released0xE0, 0x9Dright control released
0xE0, 0xA0(multimedia) mute released0xE0, 0xA1(multimedia) calculator released0xE0, 0xA2(multimedia) play released
0xE0, 0xA4(multimedia) stop released
0xE0, 0xAE(multimedia) volume down released
0xE0, 0xB0(multimedia) volume up released0xE0, 0xB2(multimedia) WWW home released
0xE0, 0xB5(keypad) / released
0xE0, 0xB8right alt (or altGr) released
0xE0, 0xC7home released
0xE0, 0xC8cursor up released0xE0, 0xC9page up released0xE0, 0xCBcursor left released
0xE0, 0xCDcursor right released0xE0, 0xCFend released
0xE0, 0xD0cursor down released0xE0, 0xD1page down released0xE0, 0xD2insert released0xE0, 0xD3delete released
0xE0, 0xDBleft GUI released
0xE0, 0xDCright GUI released0xE0, 0xDD"apps" released0xE0, 0xDE(ACPI) power released0xE0, 0xDF(ACPI) sleep released
0xE0, 0xE3(ACPI) wake released
0xE0, 0xE5(multimedia) WWW search released0xE0, 0xE6(multimedia) WWW favorites released0xE0, 0xE7(multimedia) WWW refresh released
0xE0, 0xE8(multimedia) WWW stop released0xE0, 0xE9(multimedia) WWW forward released0xE0, 0xEA(multimedia) WWW back released0xE0, 0xEB(multimedia) my computer released
0xE0, 0xEC(multimedia) email released0xE0, 0xED(multimedia) media select released
0xE0, 0x2A, 0xE0, 0x37print screen pressed
0xE0, 0xB7, 0xE0, 0xAAprint screen released
0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5pause pressed

9、

1)每个键按下和弹起时,都会产生扫描码(scan code)

2)扫描码根据字节量可分为三种:

  • 单个字节
  • 以E0开头的2字节或4字节
  • 以E1开头的6字节(只有一两个键)、

3)扫描码根据按下和弹起,又分为:make code,break code,区别是扫描码的最高位第7位是否为1

例如:

  • 当A键按下时,产生扫描码0x1E(第7位为0);断开时,产生扫描码0x9E(第7位为1)

  • 当光标向左键按下时,产生扫描码0xE0, 0x4B(第7位为0);断开时,产生扫描码0xE0, 0xCB(第7位为1)

9、处理caplock键

这个键本身并不任何有效的字符输入,而是用于控制其它键输入的效果。

  • capslock:每按1次转换一下,键上方有对应的大小写指示灯(绿灯亮为大写字母输入模式,反之为小写字母输入模式)。如果shift键和Capslock键一起按时,是小写字母模式

10、其他特殊功能健

在不同的操作系统和应用程序下可能有不同的用户,例如在浏览器中,F1键可能是用于打开帮助页面。我们现在是在键盘驱动程序中编写代码,F1等功能键不对应于任何具体的字符,也不对应具体的功能;因此,目前只是在代码中将其识别出来,具体有什么用可以留等以后扩展。


http://www.kler.cn/a/284577.html

相关文章:

  • 大模型时代,呼叫中心部门如何自建一套大模型在线客服?
  • Elasticsearch 实战应用:高效搜索与数据分析
  • @ComponentScan:Spring Boot中的自动装配大师
  • 从0开始学习Linux——文件管理
  • 在linux中使用nload实时查看网卡流量
  • 冗余连接2 hard题 代随C#写法
  • 服务器数据恢复—光纤共享存储互斥设置不当导致数据丢失的数据恢复案例
  • NC 二分查找-II
  • SQL 中 LIKE 和 REGEXP 的相同点与不同点解析
  • 关于前端布局的基础知识
  • AI绘画【Stable Diffusion】抽卡必备!时间管理大师Agent Scheduler插件,一键设置任务,让你的休息时间充分利用起来!
  • 如何判断请求是否为跨域请求?——详细教程
  • Godot vscode c# 调试方法
  • Linux——用户和权限
  • 代理 IP 在工业物联网中的大作用
  • 自然灾害预警系统的重要性
  • FPGA概述
  • 算法训练营|图论第7天 prim算法 kruskal算法
  • HPM5301系列--VSCODE开发环境问题修复(一)
  • 深度学习100问18:什么是负采样
  • chat2DB体验
  • 安卓蓝牙技术的使用和场景
  • 零基础学习Redis(9) -- set类型命令使用
  • CF C. Candy Store
  • 探索Python的Excel力量:openpyxl库的奥秘
  • Git学习尚硅谷(002 git常用命令)