汇编语言 x86 视频模式

6
我正在尝试使用汇编语言(NASM)创建一些基本的绘画例程。在查看x86 BIOS中断表时,我发现了提供一些视频操作服务的10h中断。
使用它,我已经成功地设计出一个绘制正方形的例程,并将中断调用配置为“写入图形像素”(Write a Graphics Pixel)(AH = 0Ch)
正方形被绘制正确,但是却花费了太长时间,我能看到它被填充。顺便说一下,我正在QEMU上运行我的代码。
我假设屏幕刷新速度比指令执行速度要快。经过一些研究,我没有找到任何有用的内容。主要的可能解决方案是调整垂直同步和直接写入视频内存。
考虑到我正在使用视频模式12h(640x480 - 16种颜色),我的问题是:
1-直接写入视频内存是否比调用中断更快?
2-视频内存空间中的字节是如何组织的?每个像素占据一个字节(从地址0xa000开始)吗?

3 - 如何写入视频内存?只需按顺序逐个写入每个像素的颜色即可。

4 - 一般来说,当显示器刷新屏幕时,它只是不时地直接从视频内存中读取。


1
不会将此作为答案发布,因为我已经超过10年没有进行VGA编程了,但我认为4位模式仅使用4位来存储像素。http://rosettacode.org/wiki/Video_display_modes - xxbbcc
1个回答

6


1)直接向视频内存写入数据速度更快。

2)对于仅有16种颜色(4位)的图形视频模式,我们需要使用端口访问(通过3CEh像素掩码寄存器)以及在目标位置进行虚拟读取,从而将一个像素设置到帧缓冲区。解释这个过程并不简单,但我可以给你举个例子,我的ET4000图形卡使用16种颜色的视频模式时的像素设置程序:

PIXEL:    pusha
          add    bp, XMIN
          add    bx, YMIN
          mov    cx, bp              ; Screen-Offset
          shr    cx, 3
          mov    ax, PS              ; Pixel of a line
          mul    bx                  ;    * Y
          add    ax, cx              ;        + (X/8)
          mov    di, ax              ;                = address
          cmp   BYTE PTR[FLAG_2], 5  ; SVGA ?
          jb  VGA
          mov    al, dl              ; Bank switch ET4000
          shl    al, 4               ; for SVGA: 1024x768 and 1280x1024
          add    al, dl              ; overflow 64K border
          mov    dx, 3CDh            ; Port address for bank switching ET4000
          out    dx, al
VGA:      inc    cx                  ; calculate Pixel
          shl    cx, 3
          sub    cx, bp
          dec    cx
          mov    ah, 1               ; 2 ^ (((X/8) + 1) * 8 - X) - 1
          shl    ah, cl              ;                      = Pixel pos.
          mov    dx, 3CEh            ; Pixel-Mask-Register
          mov    al, 8
          out    dx, ax
          mov    al, fs:[di]         ; Dummy-READ (get the address)
EBENE:    mov   BYTE PTR fs:[di], 1  ; set Pixel
          popa
          ret

但是,使用8、15/16、24/32位色彩的视频模式更容易不需要端口访问。例如,对于8位颜色,计算像素的地址很简单。像素地址=(Y坐标*水平分辨率)+ X坐标。
使用8位颜色,每个地址表示屏幕上的一个像素。但是,我们还有一个颜色调色板(查找表),用于确定每个颜色编号的红色、绿色和蓝色部分。仅对于具有15/16和24/32种颜色的视频模式,颜色完全编码在像素地址中,需要两个字节或三个字节来表示颜色。
3)是的,对于具有8、15/16、24/32位颜色的视频模式,很容易填充屏幕颜色。
4)我们不需要告诉显卡刷新屏幕内容。但是,我们可以检查端口3DAh的状态寄存器,以确定阴极射线是否在屏幕末端,以最小化屏幕内容的闪烁效果和撕裂现象。
起初,我也尝试使用4位颜色的视频模式,但是它不像其他具有更多颜色的图形模式那样简单易用。今天,使用我的Radeon 7950显卡,我更喜欢使用我的28英寸宽屏显示器的本机分辨率1920x1200,使用位于第四个千兆字节某处的线性帧缓冲区,颜色为32位。要切换到此分辨率,我使用VBE-Bios和modenumbers的模式表,在vesa.org(免费但需要注册/登录)的公共部分中可以找到有关此文档的文档vbe3.pdf。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接