2 提高分辨率(1)(harib11d)

从着手“自制操作系统”到现在,不知不觉间已经过去2周了。有的读者朋友读到这里,可能已经花了更长的时间;也有的朋友,经过努力也可能只用了一周左右就读到了这里。

笔者认为,开发一个操作系统需要一些必备知识,像编程语言的知识,相关算法和技巧等。到现在为止,这些知识的介绍就结束了。知道了这些,今后只要灵活运用前几章的学习内容,就可以开发出不错的操作系统了。到现在为止的学习过程觉得怎么样?回过头来想一想,如果大家有什么不明白的内容,也许趁着现在就弄清楚比较好。

那么我们赶快把“纸娃娃操作系统”做得更像一个真正的操作系统吧。大家现在可以接触多任务了。可是按计划,我们是从第15天开始才学习多任务的,所以今天还是暂时不学习多任务吧。

笔者如果想休息了,可以跟大家说“今天就学到这里吧(笑)”,可读者朋友们肯定会觉得 “没什么意思呀”,所以还是学点儿别的吧。嗯,学点儿什么呢?好吧,就学提高画面分辨率吧。

从开发操作系统的角度来看,现在这样的320×200的画面也没什么问题,可毕竟还是大画面好。以前,我们特意创建了struct BOOTINFO,就是为了能在以后扩大画面。那时我们没有写成“320”,而是特意写成了“binfo —> xsize”这种很麻烦的方式。这种麻烦辛苦,现在终于得到了回报。

■■■■■

高分辨率的利用方法因显卡不同而不同。首先,为了能通过“make run”运行,我们只考虑支持QEMU模拟器的显卡。这个卡顺利运行以后,再去支持其他的显卡。

由于画面切换中我们要使用BIOS,所以就需要改写asmhead.nas的“画面模式设定”部分了。哦,好久没写汇编程序了。

本次的asmhead.nas节选

  1. ; 设定画面模式
  2. MOV BX,0x4101 ; VBE640x480x8bi彩色
  3. MOV AX,0x4f02
  4. INT 0x10
  5. MOV BYTE [VMODE],8 ; 记下画面模式(参考C语言)
  6. MOV WORD [SCRNX],640
  7. MOV WORD [SCRNY],480
  8. MOV DWORD [VRAM],0xe0000000

程序的构成几乎没什么变化。但是数值是0x4101或0x4f02,有点儿怪怪的。这些数字是怎样查出来的?笔者估计会有人问这个问题,可与其追问这样的问题,不如先看看画面扩大后的“纸娃娃操作系统”。所以,我们先运行“make run”。

2 提高分辨率(1)(harib11d) - 图1

哦,画面宽阔

因为大家已经习惯于以前的大文字显示,所以640×480看起来非常宽阔。高分辨率画面,嗯,感觉就是不一样,好像变成了另外一个操作系统。

大家肯定想在真机上演示这个程序吧。可这个程序只能在QEMU模拟器上执行。就像刚才说的,这个程序是专门面向QEMU创建的。所以,在真机上执行的时候,电脑还是有可能发生误动作。

■■■■■

下面来说明为什么这个程序能够在640×480画面上运行。

其实说起来也很简单。给AX赋值0x4f02,给BX赋值画面模式号码,这样就可以切换到高分辨率画面模式了。为什么呢?这个笔者也答不上来,原本就是这样的。这次我们只是正好使用到了这个功能。以前画面是320×200的时候,我们用的是“AH=0; AL=画面模式号码;”。现在切换到新画面时就使用“AX = 0x4f02;”。

大家是不是很纳闷:“画面模式有新旧之分吗?”是的,实际上是有新旧之分的。就说显卡吧,每当有新显卡面世时,性能就会提高,反过来想,以前的显卡,声音性能差,颜色数又少,分辨率又低。刚开始的时候,电脑规格是以IBM公司为中心决定的,他们也规定了画面模式的相关规格。而且各家显卡公司也都迎合IBM的规格来制作显卡。

可是过了一段时间,其他显卡公司的图像处理技术超越了IBM,在IBM制定规格前,就出现了具有各样画面模式的显卡。这造成了多家显卡公司的竞争,使得在各家公司之间,画面模式的设定方法和使用方法都各不相同。

这样的情况,我们这些普通程序员是难以应付的。显卡的种类太多,我们记不住那么多的设定方法,而且事实上,连参考资料都很难得到。这样一来,本应是高性能的显卡,却只能像老显卡一样,通过BIOS设定为320×200来使用。

有鉴于此,多家显卡公司经过协商,成立了VESA协会(Video Electronics Standards Association,视频电子标准协会)。此后,这个协会制定了虽然不能说完全兼容、但几乎可以通用的设定方法,制作了专用的BIOS。这个追加的BIOS被称作“VESA BIOS extension”(VESA-BIOS扩展,简略为VBE)。利用它,就可以使用显卡的高分辨率功能了。

因此,切换到不使用VBE的画面模式时用“AH = 0;AL=画面模式号码;”,而切换到使用VBE的画面模式时用“AX = 0x4f02;BX = 画面模式号码;”。而这种必须使用VBE才能利用的画面模式就称作“新”画面模式。

■■■■■

VBE的画面模式号码如下。

0x101……640× 480× 8bit彩色

0x103……800× 600× 8bit彩色

0x105……1024× 768× 8bit彩色

0x107……1280× 1024× 8bit彩色

还有其他一些画面模式,因为现在不需要,我们就省略了。另外,在QEMU中不能指定最下面的0x107。实际指定的时候,要像在asmhead.nas中所做的那样,将以上的画面模式号码值加上0x4000,再赋值到BX中去。不这样做就不能顺利运行。

所以,如果想要将画面扩展得特别大的话,请尝试运行以下程序。

  1. MOV BX,0x4105 ; VBE1024x768x8bit彩色
  2. MOV AX,0x4f02
  3. INT 0x10
  4. MOV BYTE [VMODE],8 ; 记下画面模式(参考C语言)
  5. MOV WORD [SCRNX],1024
  6. MOV WORD [SCRNY],768
  7. MOV DWORD [VRAM],0xe0000000

画面会变得特别宽哦。