彩色显示器16种颜色都是红、绿、蓝3基色调和的结果,各颜色的3基色在VGA卡上分别占用一个18位的颜色寄存器,红、绿、蓝各占6位。系统开机时,各颜色3基色的值被设置成缺省值,改变3基色的比例,就可达到改变颜色显示效果的目的。
黑色的3基色均为0,如将所有颜色的基色值都置成0,则可达到关屏的效果,反之,恢复各颜色的基色缺省值,则可达到开屏的目的。由此推广,如将各颜色的基色值逐步减为零,则可使屏幕逐步变暗;如将绿、蓝两基色值先逐步减为零,再将红色减灭,则屏幕颜色先逐步转红,之后变暗……
16种颜色的3基色的缺省值为:
色号:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R 0 0 0 0 42 42 42 42 21 21 0 0 63 63 63 63
G 0 0 42 42 0 0 21 42 21 21 63 63 21 21 63 63
B 0 42 0 42 0 42 0 42 21 63 0 63 21 63 0 63
3基色的传送方法为:
out 03c8h, ptr
out 03c9h, r
out 03c9h, g
out 03c9h, b
其中:
ptr=n ; n=0,1,2,3,4,5,7
n+14 ; n=6
n+48 ; n=8,9,10,11,12,13,14,15
n为颜色号,ptr为相应的颜色寄存器号。
r, g, b分别为红、绿、蓝3基色值。
上述过程全在COMPAQ DESKPRO 386/33M上调试通过。
以下给出一个关屏实例,由TASM编译,TLINK连接生成.COM文件。本程序稍作修改即可作为过程用于其它应用程序上。
.model small
.code
.386
org 100h
start:
mov bp,cs:red-ptr
mov bl,[bp]
cmp bl,0;基色r为零吗?
je @@1;是,则跳
dec bl;否则,减1
mov [bp],bl
@@1: mov bl,[bp+1]
cmp bl,0;基色g为零吗?
je @@2;是,则跳
dec bl;否则,减1
mov [bp+1],bl
@@2: mov bl,[bp+2]
cmp bl,0 ;基色b为零吗?
je @@3 ;是,则跳
dec b1 ;否则,减1
mov [bp+2],bl
@@3: mov al,cs:c-num ;色号→al
call change ;改变al号颜色
call delay ;延时
cmp cs:c-num,15 ;色号小于15吗?
jl @@4;是,则跳
cmp cs:loop1,0 ;否则,色号,基色值指针复位
je @@5
mov cs:c-num,1
mov cs:red-ptr,offset red
dec cs:loop1 ;
jmp start
@@4: inc cs:c-num ;色号加1
add cs:red-ptr,3 ;基色值指针加3
jmp start
@@5: int 20h
delay:
mov cx,8760
@@6: dec cx
cmp cx,0
jnz @@6
ret
change:
cmp al,6
je @@7
cmp al,7
jle @@8
add al,48
jmp @@8
@@7: add al,14
@@8: mov dx,03c8h
out dx,al
mov dx,03c9h
mov bp,cs:red-ptr
mov al,[bp]
out dx,al
mov al,[bp+1]
out dx,al
mov al,[bp+2]
out dx,al
ret
c-num db 1
loop1 db 63
red-ptr dw offset red
red db 0
green db 0
blue db 42
db 0
db 42
db 0
db 0
db 42
db 42
db 42
db 0
db 0
db 42
db 0
db 42
db 42
db 42
db 0
db 42
db 42
db 42
db 21
db 21
db 21
db 21
db 21
db 63
db 0
db 63
db 0
db 0
db 63
db 63
db 63
db 21
db 21
db 63
db 21
db 63
db 63
db 63
db 0
db 63
db 63
db 63
ends
end start