30天自制操作系统第14天

操作系统实验日志14

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

一、实验主要内容

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

因为在对前一天的程序进行性能检测时,效果并没有达到想要的结果,于是就想再重新检测看下程序的运行结果。

发现没有什么不同之后,于是考虑到,在前一个程序的改进的地方是消除了移位处理,要想看到程序上的速度有明显变化,应该是进行了大量的移位操作之后,而一直只使用了三个定时器,所以并没有什么不同。因此增加定时器的个数,增加到490个,也就是增加移位的操作,再次测试程序的性能。

在这里插入图片描述

测试结果:

在这里插入图片描述

测试结果分析:

①通过(1),追加定时器的情况下,取消移位、设置哨兵都会令程序更快。

②通过(2),定时器较少时,取消移位反而会令程序变慢,可能是因为if语句变多了,加上哨兵后和原来移位速度差不多。

③在有哨兵、没有移位的情况下,无论定时器的数量多少,对性能影响不大。

④(3)的情况和②描述的现象差不多,但是(3)更快。原因在这是因为C编译器的问题,因为跳转目标地址不同,CPU的JMP指令执行的时钟周期数也不一样。在程序中,循环执行count++的for循环虽然最终会被编译为JMP指令,但是前面还有个set490指令,会使得指令的地址都相应的错开几个字节,导致了JMP指令的地址也会变化,因此执行时间也就出现了延迟,结果变差了3%。这个问题的解决方法就是用nask来编写HariMain,但因为这个太麻烦了,就暂时不做了。

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

要利用高分辨率,就要考虑到显卡的因素,首先只考虑QEMU模拟器的显卡,等到这个可以用了,再去考虑其他的显卡。在画面切换中,需要使用BIOS,因此改写asmhead.nas的画面模式设定。

在这里插入图片描述

当给AX赋值0x4f02,给BX赋值画面模式号码时,就可以切换到高分辨率画面模式。在使用320x200的分辨率时,采用的是AH=0,AL=画面模式号码的方式,当切换到新画面时,就可以使用AX=0x4f02。以前的方式是不使用VBE的画面模式,切换到使用VBE的画面模式时,就要使用AX=0x4f02,BX=画面模式号码。

VBE的画面模式号码:(实际指定时,需要将上述的画面模式号码值加上0x4000,再复制到BX中去,不这样的话就不能顺利运行)

在这里插入图片描述

还可以将画面变得更大:

在这里插入图片描述

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

之前的高分辨率只能在模拟器中运行,而要在真机上运行的话,首先需要检测真机上的显卡能否使用VBE,如果不能的话,只能退回到原处,继续使用320x200的分辨率。

检测VBE:

在这里插入图片描述

这里将ES赋值为0x9000,将DI赋值为0,将AX赋值为0x4f00,再执行INT 0x10,将AX与0x004f进行比较;如果有VBE的话,AX将会变成0x004f,如果没有变化,则表示没有VBE,因此便无法切换画面模式。

对ES和DI进行赋值的原因是,显卡能利用的VBE信息是要写入到内存中以ES:DI开始的512字节中,赋值是为了指定写入地址。

在我们的系统中,要判断VBE的版本是否是2.0以上,如果不是的话,就不能使用高分辨率。

在这里插入图片描述

接下来要检测都哪些画面模式可以使用:

在这里插入图片描述

如果AX是0x004f以外的值,则表示所指定的画面模式不能使用。此次取得的画面模式的信息也会被写入内存中,从ES:DI开始的256字节中。因为ES和DI都保持之前的值不变,所以画面模式信息便会覆盖VBE版本的信息而导致其消失。

在这里插入图片描述

所以要确认以上3项信息:

在这里插入图片描述

当信息已经完成确认之后,就可以使用指定的VBE画面模式了,便可以将分辨率及VRAM的地址等信息赋值到BOOTINFO中。

在这里插入图片描述

4、 内容4:键盘输入1

以前我们按下键盘,显示的是其中断发生时的键码,现在我们想按下什么显示什么,就要根据其键码输出对应的符号。

对照表如下:

在这里插入图片描述
在这里插入图片描述

想要输出对应的符号,在入口函数中加入几个判断就可以了:

在这里插入图片描述

这样按下A就可以显示A了,其他字符同理:

在这里插入图片描述

5、 内容5:键盘输入2

如果用上面的方法,我们就要写很多个if语句来判断,会让我们的程序变慢,考虑到大多数按键的键码都是连续的,所以我们以键码的顺序,从0开始,将字符都写入到一个数组中,这样i是几,对应的字符就是数组中的第几个。

在这里插入图片描述

这里面的0表示的就是待分配的键码。

在这里插入图片描述

作者使用的是日式键盘,所以有的和我们不一样这很正常。

6、 内容6:追记内容1

现在我们修改程序使得能够输入并显示出多个字符,并且按下BackSpace能够实现删除的功能。

只需要修改入口函数:

在这里插入图片描述

其中cursor_x是用来记住光标显示位置的变量,当输入一个字符后,这个变量就递增8,因为一个字符的长度就是8。Cursor_c变量则表示光标的颜色,每0.5秒变化一次。Make_textb0x8函数是用来描绘文字输入背景的函数:

在这里插入图片描述

7、 内容7:追记内容2

这部分实现窗口的移动,鼠标点击屏幕的一个位置,窗口就出现在哪里,同时为了让窗口可以“飞出”屏幕,窗口移动到的位置不是鼠标的坐标,而是mx-80,my-8。
在这里插入图片描述

运行效果:

在这里插入图片描述

二、程序设计创新点

1、描述创新点1: 设计一个五子棋游戏,可以实现人机对战

在这里插入图片描述

三、实验心得体会

这一天做的事情就是实现了简略的文本编辑器,首先实现了打印键盘上的字母以及字符,然后利用定时器模拟了光标,今天比较简单,但是通过今天的学习我学会了使用定时器。

(附本次代码,开机密码是123456,鼠标双击左上角图标可进入游戏页面,点击游戏页面的右下角的开始后,就可以游戏啦)