babyos (四)—— SVGA、VBE基础与切换到髙分辨率模式

babyos (四)—— SVGA、VBE基础与切换到髙分辨率模式注 以下程序系原创 若有 bug 欢迎指正 若有问题欢迎交流 转载请注明出处 若能有益于一二访客 幸甚 1 VGAVGA VideoGraphic 即视频图形阵列 是 IBM 在 1987 年随 PS 2 机推出的 VGA 主要由七大块组成 图形控制器 显示存储器 定序器 CRT 控制器 数据串行发生器 属性控制器和数模转换器 DAC 2 VBEIBM 的 VGA 标准是显示卡

注:以下程序系原创,若有bug欢迎指正,若有问题欢迎交流,转载请注明出处。若能有益于一二访客,幸甚。

1.VGA

VGA(Video Graphics Array)即视频图形阵列,是IBM在1987年随PS/2机推出的。

VGA主要由七大块组成:图形控制器、显示存储器、定序器、CRT控制器、数据串行发生器、属性控制器和数模转换器DAC。

2.VBE

IBM的VGA标准是显示卡发展史上的一块丰碑。但后来无法满足人们的需要,于是市场上出现了TVGA、S3系列、Cirrus Logic、ET等为首的一批显示卡,提供了比VGA分辨率更高,颜色更丰富的显示模式,又兼容VGA显示卡,它们被统称为Super VGA(SVGA)。
各种不同的SVGA之间的显示控制各不相同,带来软件兼容性问题,为此视频电子学标准协会VESA(Video Electronics Standards Association)提出了一组附加的BIOS功能调用借口——VBE(VESA BIOS EXTENSION)标准,从而在软件接口层次上实现了各种SVGA显示卡之间的兼容性。时至今日,所有的显示卡OEM厂商都提供了符合VESA SUPER标准的扩展BIOS。通过一组INT 10H中断调用(AH=4FH),可以方便地使用VESA SVGA的扩展功能而不必了解各种显示卡的硬件细节。
Super VGA的扩充显示能力关键取决于对较大显示存储器的寻址能力。
各Super VGA 卡提供的分辨率远高于VGA,VESA VBE均赋予一个标准的16位模式号(实际上是9位,其他各位为标志位或留给以后扩充)。

3.VBE功能调用和返回值

VBE功能调用的共同点:
1)AH必须等于4FH,表明是VBE标准;
2)AL等于VBE功能号,0<= AL <= 0BH;
3)BL等于子功能号,也可以没有子功能;
4)调用INT 10H;
5)返回值

VBE返回值一般在AX中:
1)AL=4FH:支持该功能
2)AL!=4FH:不支持该功能;
3)AH=00H:调用成功;
4)AH=01H:调用失败;
5)AH=02H:当前硬件配置不支持该功能;
6)AH=03H:当前的显示模式不支持该功能;

4.VBE 功能

----------------------------------------------------------- 功能0x00:返回VBE信息 ------------------------------------------------------ 入口: AX 0x4F00 ES:DI 指向VBE信息块的指针 出口: AX VBE返回值 ------------------------------------------------------------ ----------------------------------------------------------- 功能0x01:返回VBE特定模式信息 ------------------------------------------------------ 入口: AX 0x4F01 CX 模式号 ES:DI 指向VBE特定模式信息块的指针 出口: AX VBE返回值 ------------------------------------------------------------ ----------------------------------------------------------- 功能0x02:设置VESA VBE 模式 ------------------------------------------------------ 入口: AX 0x4F02 BX 模式号 出口: AX VBE返回值 ------------------------------------------------------------ 当设置模式失败时,返回错误代码,一般返回AH=01H VESA 2.0以上增加了BX中D14,D15的位定义,完整定义如下: BX = 模式号 D0~D8:9位模式号 D9~D13:保留,必须为0 D14 = 0:使用普通的窗口页面缓存模式,用VBE功能05H切换显示页面 = 1:使用大的线性缓存区,其地址可从VBE功能01H的返回信息ModeInfo获得 D15 = 0:清除显示内存 = 1:不清除显示内存 ------------------------------------------------------------

5.示例

检查VBE可否使用、版本、模式0x103,并切换到模式0x103(800*600, 256色):

# 本程序测试VBE(VESA BIOS EXTENSION)显示模式,然后切换到1024*768 256色模式, # 并通过软盘读取Baby OS 的简单LOGO,显示在屏幕上 # 2012-12-28 21:03 #  .section .text .global _start .code16 _start: jmp main #-------------------------------------------------------------- # 清屏函数: # 设置屏幕背景色,调色板的索引0指代的颜色为背景色 clear_screen: # 清屏函数 movb $0x06, %ah # 功能号0x06 movb $0, %al # 上卷全部行,即清屏 movb $0, %ch # 左上角行 movb $0, %ch # 左上角列 movb $24, %dh # 右下角行 movb $79, %dl # 右下角列 movb $0x07, %bh # 空白区域属性 int $0x10 ret #---------------------------------------------------------------- # 设置VGA 0x13显示模式函数 set_video_mode_0x13: movb $0, %ah # 功能号0x0 movb $MODE_0x13, %al # 显示模式 int $0x10 movw $0x13, video_mode movw $320, screen_x movw $200, screen_y movl $0xb8000, video_ram ret #---------------------------------------------------------------- # 设置VBE 0x103显示模式 # 因第一次写此类程序,只考虑了可读性,未考虑效率,比如al、ah分开赋值等 set_video_mode_vbe_0x103: # 确认VBE是否存在 movw $BUFFER_SEG, %ax movw %ax, %es movw %ax, %ds xorw %di, %di # 下面检查是否支持VBE及VBE版本 movb $0x4f, %ah # VBE标准 movb $0x00, %al # 功能号 int $0x10 cmp $0x004f, %ax # 若有VBE,AX应该为0x004f jne 1f movw 0x04(%di), %ax cmp $0x0200, %ax # 若VBE版本不是2.0以上,不能使用髙分辨率 jb 1f # 下面检查MODE_VBE_0x13的参数 movw $MODE_VBE_0x103, %cx movb $0x4f, %ah # 表明VBE标准 movb $0x01, %al # 子功能号 int $0x10 cmpb $0x00, %ah # 是否调用成功 jne 1f cmpb $0x4f, %al # 是否支持该模式 jne 1f cmpb $8, 0x19(%di) # 颜色是否占8bit jne 1f cmpb $4, 0x1b(%si) # 颜色的指定方法是否为4,即调色板方式 jne 1f movw (%di), %ax andw $0x0080, %ax jz 1f # AX第7个比特是否为1,该位表示线性帧缓存是否有效 # 下面设置模式 movw $MODE_VBE_0x103, %bx addw $0x4000, %bx # BX第14个比特表示是否使用大的线性缓存区,故置位 movb $0x4f, %ah # 表示使用VBE标准 movb $0x02, %al # 功能号,表示设置模式 int $0x10 # 下面记录切换到的模式的一些参数信息 movw $MODE_VBE_0x103, video_mode movw 0x12(%di), %ax movw %ax, screen_x movw 0x02(%di), %ax movw %ax, screen_y movl 0x28(%di), %eax movl %eax, video_ram movw $1, %ax ret 1: movw $0, %ax ret #---------------------------------------------------------------- # 设置背景颜色为深蓝色 set_screen_bk_color: movw $VIDEO_PALLETE_PORT, %dx movb $PA_INDEX_BACKGROUND, %al outb %al, %dx movw $COLOR_SELECTION_PORT, %dx movb $0, %al # 红 outb %al, %dx movb $0, %al # 绿 outb %al, %dx movb $18, %al # 蓝(亮度18/63) outb %al, %dx ret #---------------------------------------------------------------- # 通过写显存绘制一些像素点: # 首先设置调色板索引1处的颜色为白色 # 然后通过写显存的方式,向ES:DI写入数据(PA_INDEX_WHITE) draw_some_pixels: # 把索引1处的颜色改为白色(63,63,63) movw $VIDEO_PALLETE_PORT, %dx movb $PA_INDEX_WHITE, %al outb %al, %dx movw $COLOR_SELECTION_PORT, %dx movb $63, %al # 红 outb %al, %dx movb $63, %al # 绿 outb %al, %dx movb $63, %al # 蓝 outb %al, %dx # 设置ES的值 movw $VIDEO_SEG_GRAPHIC, %ax movw %ax, %es # 设置要显示的像素位置的显存地址(目的地址) movw $(800*5), %di # 从第五行像素开始开始 movb $PA_INDEX_WHITE, %al movw $800, %cx # 画800个连续像素即一条直线 draw_a_pixel: stosb #addl $799, %edi loop draw_a_pixel ret main: movw %cx, %ax movw %ax, %ds movw %ax, %es call clear_screen # 清屏 call set_video_mode_vbe_0x103 # 设置显示模式 cmpw $0, %ax jne 1f call set_video_mode_0x13 1: call set_screen_bk_color # 设置背景颜色 call draw_some_pixels # 绘制像素 1: jmp 1b # 常量定义: VIDEO_SEG_TEXT = 0x0e00 VIDEO_SEG_GRAPHIC = 0xa000 BUFFER_SEG = 0x800 VIDEO_PALLETE_PORT = 0x3c8 COLOR_SELECTION_PORT= 0x3c9 MODE_0x13 = 0x13 MODE_VBE_0x105 = 0x0105 MODE_VBE_0x103 = 0x0103 PA_INDEX_BACKGROUND = 0x0 PA_INDEX_WHITE = 0x1 video_mode: .short 0 screen_x: .short 0 screen_y: .short 0 video_ram: .long 0 .org 0x1fe, 0x90 .word 0xaa55 

babyos (四)—— SVGA、VBE基础与切换到髙分辨率模式




















































版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225487.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 上午9:13
下一篇 2026年3月17日 上午9:13


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号