提高分辨率
提高分辨率的内容,在harib11e文件夹内,感兴趣的同学可以尝试直接运行一下。
要完成提高分辨率的任务,要先保证自己的电脑里的显卡支持VBE 2.0,不然忙活半天可实现不了。
那么什么是VBE呢?
刚开始,IBM公司一家独大,电脑的各种规格都是以IBM公司为中心制定的,当然也包括画面模式的相关规格。后来出现了很多公司,显卡的性能、图像处理等方面都超过了IBM公司,而各家画面模式的设定方法都不相同。这就给我们开发带来了很多麻烦,总不可能把每个显卡的设定方式都记住吧。
为了解决这个问题,多家显卡公司共同成立了VESA协会。这个协会制定了一个几乎可以通用的设定方法,并为此制作了专用的BIOS,这个追加的BIOS就被成为VESA-BIOS扩展,简称VBE(VESA BIOS extension)。
VBE的画面模式号码如下:
先来确认一下电脑上用的是什么 显卡,如果不能使用VBE,就只能用之前的320×200的画面了。
我们在asmhead.nas里增加一下内容,这里先给ES赋值0x9000,再给DI赋值0、AX赋值0x4f00,接着执行“INT 0x10”。如果有VBE的话,AX就会变为0x004f。“CMP AX,0x004f”语句进行判断,要是不相等,就不能使用VBE。
对ES和DI进行赋值是为了指定写入的地址,显卡能够利用VBE信息写入到以ES:DI开始的512字节的内存中。
asmhead.nas节选:
; 确认VBE是否存在
MOV AX,0x9000
MOV ES,AX
MOV DI,0
MOV AX,0x4f00
INT 0x10
CMP AX,0x004f
JNE scrn320
asmhead.nas节选:
; 检查VBE的版本
MOV AX,[ES:DI+4]
CMP AX,0x0200
JB scrn320 ; if (AX < 0x0200) goto scrn320
下面要通过VBE来查看画面模式0x105能不能使用,首先设定VBEMODE。这里我们对AX的值进行判断,如果不等于0x004f,就意味着我们指定的画面模式不能使用。
asmhead.nas节选:
VBEMODE EQU 0x105
; 取得画面模式信息
MOV CX,VBEMODE
MOV AX,0x4f01
INT 0x10
CMP AX,0x004f
JNE scrn320
在画面模式信息中,有6个重要信息——
我们来确认下面的三项信息:
1.判断颜色数是否等于8;
2.判断颜色的指定方法是否是调色板模式(4);
3.画面模式号码能否加上0x4000再指定。
; 画面模式信息的确认
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中。
; 画面模式的切换
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
make run一下,现在画面模式是1024×768×8bit彩色,看起来更有操作系统的样子了呢。
键盘输入
高分辨率的支持已经完成了,字也变成正常大小了,看起来舒服多了。接下来我们开始下一个任务,在窗口中显示出我们键盘输入的值。
之前我们演示过按下键盘中的A健, 按下时显示 “1E",弹起时显示 “9E”。所以我们需要将按下键时的数值与实际需要显示的数相对应,而键弹起的数值在这个基础上加上0x80就可以了。
数值对照表量太大了,这里就不一一列举出来了,直接用给定的程序就可以了。
修改bootpack.c内容:
void HariMain(void)
{
(略)
int cursor_x, cursor_c;
make_textbox8(sht_win, 8, 28, 144, 16, COL8_FFFFFF);
cursor_x = 8;
cursor_c = COL8_FFFFFF;
(略)
for (;;) {
io_cli();
if