我试图在程序集中创建一些基本的绘图例程(NASM)。看看x86 BIOS中断表,我发现了10h中断,它提供了一些视频操作服务。
使用它,我成功地想出了一个例程来绘制一个正方形,配置了对编写图形像素 (AH = 0Ch)的中断调用。
这个正方形画得很准,但时间太长了,我可以看到它被填满了。顺便说一下,我正在QEMU上运行我的代码。
我认为屏幕刷新的速度比执行指令的速度快。经过一些研究,我没有找到任何有用的内容。主要的解决方案是调整垂直同步并直接写入视频存储器。
考虑到我使用的是视频模式12h (640x480-16颜色),我的问题是:
直接写入视频存储器比呼叫中断快吗?
2-在视频内存空间中字节是如何组织的?每个像素占用一个字节(从地址0xa 000开始)?
3-我怎样才能写到视频存储器?简单地写每一个像素的颜色顺序?
一般来说,当一个显示器正在刷新屏幕时,它只是不时地直接从视频存储器中读取?
发布于 2014-05-04 08:16:00
1)直接写入视频存储器要快得多。
2)对于只有16种颜色(4位)的图形视频模式,我们必须使用端口访问(对3 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位颜色的例子,计算像素的地址很简单。像素address= (Y_coordinate *水平分辨率)+ X_coordinate
使用8位颜色,每个地址表示屏幕上的一个像素。但另外,我们有一个调色板(查找表),用于确定每个颜色数字的红色、绿色和蓝色部分。只对15/16和24/32颜色的视频模式,颜色在像素地址中被完全编码,有两个字节,或者颜色有三个字节。
3)是的,对于8,15/16,24/32位颜色的视频模式,很容易用颜色填充屏幕。
4)我们不需要告诉图形卡刷新屏幕内容。但是,如果阴极射线在屏幕的末端,我们可以检查端口3DAh的状态寄存器,以最小化闪烁效应和屏幕内容的撕裂。
在第一次,我也尝试使用4位颜色的视频,但它不是那么简单的使用像其他图形模式更多的颜色。今天,带着我的Radeon 7950卡,我更喜欢使用我的28“宽屏显示器在19202x1200年的原生分辨率和32位的颜色,使用位于第四千兆字节的线性帧缓冲器。为了切换到这个分辨率,我使用VBE-bios和属于VBE-Bios的modenumbers模式。该页面的公共部分可以在vbe3.pdf (免费但需要注册/登录)中找到这些文档。
https://stackoverflow.com/questions/23451521
复制相似问题