30天自制操作系统(day14)

第14天:高分辨率及键盘输入

1、内容1:继续测试性能

因为在对前一天的程序进行性能检测时,效果并没有达到想要的结果,于是就想再重新检测看下程序的运行结果。
在这里插入图片描述
发现没有什么不同之后,考虑为啥做了不少修改之后,程序的速度也没有变快。于是考虑到,在前一个程序的改进的地方是消除了移位处理,要想看到程序上的速度有明显变化,应该是进行了大量的移位操作之后,而一直只使用了三个定时器,所以并没有什么不同。因此增加定时器的个数,也就是增加移位的操作,再次测试程序的性能。a-bootpack.c
在这里插入图片描述
mode代表着是否增加490个定时器。
根据不同的设定,可以看出性能上的变化。
在这里插入图片描述
在这里插入图片描述
从上述的测试中可以看出,线性表和哨兵都对程序的性能有所提升。但在(2)和(3)方案中,它们的处理完全一样,但是结果却相差十分巨大,这是因为C编译器的问题,因为跳转目标地址不同,CPU的JMP指令执行的时钟周期数也不一样。在程序中,循环执行count++,虽然for循环会被编译为JMP指令,但是前面还有个set490指令,会使得指令的地址都相应的错开几个字节,导致了JMP指令的地址也会变化,因此执行时间也就出现了延迟,结果变差了3%。这个问题的解决方法就是用nask来编写HariMain,但因为这个太麻烦了,就暂时不做了。

2、内容2:提高分辨率(1)

之前一直都用的是320*200的分辨率,什么东西都显得十分的大,因此就改改分辨率,使得分辨率高些,画面大些。要利用高分辨率,就要考虑到显卡的因素,首先只考虑QEMU模拟器的显卡,等到这个可以用了,再去考虑其他的显卡。在画面切换中,需要使用BIOS,因此改写asmhead.nas的画面模式设定。
在这里插入图片描述
当给AX赋值0x4f02,给BX赋值画面模式号码时,就可以切换到高分辨率画面模式。在使用320x200的分辨率时,采用的是AH=0,AL=画面模式号码的方式,当切换到新画面时,就可以使用AX=0x4f02。前一种方式是不使用VBE的画面模式,后者则是使用VBE的画面模式,即必须使用VBE才能利用的画面模式。
VBE的画面模式号码:
在这里插入图片描述
实际指定时,需要将上述的画面模式号码值加上0x4000,再复制到BX中去,不这样的话就不能顺利运行。
能将画面扩展得十分大的程序:
在这里插入图片描述
通过运行该段程序能将画面变宽。

3、内容3:提高分辨率(2)

之前的高分辨率只能在模拟器中运行,而要在真机上运行的话,首先需要检测真机上的显卡能否使用VBE,如果不能的话,只能退回到原处,继续使用320x200的分辨率。
检测VBE的程序:
在这里插入图片描述
将ES赋值为0x9000,将DI赋值为0,将AX赋值为0x4f00,再执行INT 0x10,将AX与0x004f进行比较;如果有VBE的话,AX将会变成0x004f,如果没有变化,则表示没有VBE,因此便无法切换画面模式。
这段程序运行的原理是,显卡能利用的VBE信息是要写入到内存中以ES:DI开始的512字节中,赋值是为了指定写入地址。
接下来判断VBE的版本是否是2.0以上,如果不是的话,就不能使用高分辨率。
在这里插入图片描述
如果AX比0x0200小的话,那么只能继续使用320x200的画面模式。
在这里插入图片描述
对画面信息进行确认,如果AX是0x004f以外的值,则表示所指定的画面模式不能使用。此次取得的画面模式的信息也会被写入内存中,从ES:DI开始的256字节中。因此ES和DI都保持之前的值不变,则画面模式信息便会覆盖VBE版本的信息。
在这里插入图片描述
在这里插入图片描述
当信息已经完成确认之后,就可以使用指定的VBE画面模式了。
当完成了画面模式的切换后,便可以将分辨率及VRAM的地址等信息赋值到BOOTINFO中。

4、内容4:键盘输入(1)

要实现键盘输入,只需要根据之前按下键时,窗口中所显示的数值,根据该值,对应输出所表示字母或者符号即可。
在这里插入图片描述
在这里插入图片描述

if (256 <= i && i <= 511) { /*当屏幕上的数值在此区间内时,即表示键盘上有键被按下*/
sprintf(s, "%02X", i - 256);//将其减去256表示,之前为了方便设定,将对应的值加上256了,要显示的话,需要减去该值 
putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2);//显示出来。 
if (i == 0x1e + 256) {//1e即为按下A时所对应的值 
putfonts8_asc_sht(sht_win, 40, 28, COL8_000000, COL8_C6C6C6, "A", 1);
}

实验结果:
在这里插入图片描述

5、内容5:键盘输入(2)

前一个只能输入一次,显示一个数值,这显然不满足要求。如果按照上一种的写法,要显示出所有的数值需要很长的一段程序,大大增加了程序的长度。因此选择另外一种显示的方法。
首先将要显示的字符都保存在一个字符数组中,然后根据按键按下所对应的值来得到按键对应的字符在数组中的位置,然后用显示函数显示出来即可。
在这里插入图片描述
但是书中在按下@键后会显示出W键,这是因为当@键被按下的时候,HariMain接收到了0x11的数据,这是QEMU的问题。但在我的电脑上,是没法只通过一个键按住@的,所以没有出现上述状况。

6、内容6:追记内容(1)

修改程序使得能够输入并显示出多个字符,并且按下BackSpace能够实现删除的功能。
其中cursor_x是用来记住光标显示位置的变量,当输入一个字符后,这个变量就递增8,因为一个字符的长度就是8。Cursor_c变量则表示光标的颜色,每0.5秒变化一次。
Make_textb0x8函数是用来描绘文字输入背景的函数。
在这里插入图片描述

7、内容7:追记内容(2)

实现窗口的移动,根据鼠标的位置,来确定移动后窗口的位置。
在这里插入图片描述
这样的话,可以一直按着左键来移动鼠标,或者让窗口四处移动。但鼠标点击其他位置时,窗口也会出现在想对应的位置。

发布了205 篇原创文章 · 获赞 110 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_40851744/article/details/103528496