3 提高分辨率(2)(harib11e)
只能在模拟器上运行的操作系统实在没什么意思,还是想在真机上运行。所以,我们来把前一节的程序改写一下,让它能在真机上运行。
我们不能断定真机上使用的是什么样的显卡。有的公司尚未与VESA进行合作。如果是这种公司的产品,由于不能使用VBE,所以大家只能忍耐一下,使用320×200的画面了。
本次的asmhead.nas节选
; 确认VBE是否存在
MOV AX,0x9000
MOV ES,AX
MOV DI,0
MOV AX,0x4f00
INT 0x10
CMP AX,0x004f
JNE scrn320
在这里,我们给ES赋值为0x9000,给DI赋值为0,给AX赋值为0x4f00,再执行“INT 0x10”。如果有VBE的话,AX就会变为0x004f。要是AX没有变为这个值,很遗憾,就只能使用320×200的画面了。
至于为什么要对ES和DI进行赋值,是因为此显卡能利用的VBE信息要写入到内存中以ES:DI开始的512字节中,赋值是为了指定写入地址。
■■■■■
在“纸娃娃操作系统”中,如果VBE的版本不是2.0以上,就不能使用高分辨率。所以我们要先调查一下VBE的版本。
本次的asmhead.nas节选
; 检查VBE的版本
MOV AX,[ES:DI+4]
CMP AX,0x0200
JB scrn320 ; if (AX < 0x0200) goto scrn320
程序进行到这里,下一步要通过VBE来查看一下画面模式0x105能不能使用。即使VBE 的版本是VBE 2.0,也不能保证所有的画面模式都可以使用。真是麻烦呢。因为如果局限于画面模式0x105,那些想使用其他画面模式的人就要抱怨了。为了调查这种模式能否使用,我们首先这样设定:
- VBEMODE EQU 0x105
本次的asmhead.nas节选
; 取得画面模式信息
MOV CX,VBEMODE
MOV AX,0x4f01
INT 0x10
CMP AX,0x004f
JNE scrn320
在这里我们对AX的值也进行了确认。如果它是0x004f以外的值,就意味着所指定的画面模式不能使用。
此次取得的画面模式信息也被写入内存中从ES:DI开始的256字节中。因为ES和DI都保持刚才的值不变,所以画面模式信息会覆盖VBE版本信息从而导致其消失,但是只要版本能确认,后面就不需要这个信息了,所以大家不必在意。
■■■■■
在画面模式信息中,重要的信息有如下6个。
WORD [ES : DI+0x00]
: 模式属性……bit7
不是1
就不好办(能加上0x4000
)
WORD [ES : DI+0x12]
: X
的分辨率
WORD [ES : DI+0x14]
: Y
的分辨率
BYTE [ES : DI+0x19]
: 颜色数……必须为8
BYTE [ES : DI+0x1b]
: 颜色的指定方法……必须为4
(4
是调色板模式)
DWORD [ES : DI+0x28]
: VRAM
的地址
在这6项信息当中,我们来确认如下3项:
颜色数是否为8
是否为调色板模式
画面模式号码可否加上0x4000再进行指定
本次的asmhead.nas节选
; 画面模式信息的确认
CMP BYTE [ES:DI+0x19],8
JNE scrn320
CMP BYTE [ES:DI+0x1b],4
JNE scrn320
MOV AX,[ES:DI+0x00]
AND AX,0x0080
JZ scrn320 ; 模式属性的bit7是0,所以放弃
如果这些确认都完成的话,就可以跟大家说了:“恭喜。可以使用所指定的VBE画面模式了。那就尽情享受大画面的乐趣吧!”所以我们决定进行画面模式的切换。而一旦我们完成了切换,就可以将分辨率及VRAM的地址等信息复制到BOOTINFO中了。
本次的asmhead.nas节选
; 画面模式的切换
MOV BX,VBEMODE+0x4000
MOV AX,0x4f02
INT 0x10
MOV BYTE [VMODE],8 ; 记下画面模式(参考C语言)
MOV AX,[ES:DI+0x12]
MOV [SCRNX],AX
MOV AX,[ES:DI+0x14]
MOV [SCRNY],AX
MOV EAX,[ES:DI+0x28]
MOV [VRAM],EAX
JMP keystatus
最后的JMP指令,用来让程序跳过后面的scrn320,而让其跳转至在BIOS中查询键盘状态的地方。scrn320程序我们紧接着就要写。
■■■■■
那么当出现VBE不存在,版本不够,模式有问题的情况下,我们又该怎么办呢?没办法,我们只能使用迄今为止的320×200画面。
本次的asmhead.nas节选
scrn320:
MOV AL,0x13 ; VGA图、320x200x8bit彩色
MOV AH,0x00
INT 0x10
MOV BYTE [VMODE],8 ; 记下画面模式(参考C语言)
MOV WORD [SCRNX],320
MOV WORD [SCRNY],200
MOV DWORD [VRAM],0x000a0000
好,这样就大功告成了。首先要确认在模拟器上能否正常运行。运行“make run”。OK,运转正常。
下面确认在真机上能否正常运行。“make install”一下。完成以后,按下桌面上的开关。哦,顺利运行。
如果想试一试不能顺利运行是什么样,可以设定画面模式为0x107,再在模拟器上执行就可以了。画面还是320×200哦。
■■■■■
恭喜各位实现了高分辨率,不过在广大读者之中,可能有人还在使用不支持VBE 2.0的显卡,所以今后笔者还是要使用以前的320×200画面截图。而且这样的图片,文字和鼠标指针都显得比较大,容易看。
画面很宽
这次我们对于VBE的使用方法做了多方面的介绍,其中笔者参考了下面的网页。
http://community.osdev.info/?VESA
大家有兴趣的话也看一下吧。