TVGA彩色視頻模式論文
時(shí)間:2022-08-24 05:13:00
導(dǎo)語(yǔ):TVGA彩色視頻模式論文一文來源于網(wǎng)友上傳,不代表本站觀點(diǎn),若需要原創(chuàng)文章可咨詢客服老師,歡迎參考。
摘要本文首先分析了tvga的結(jié)構(gòu)和其顯示原理,然后進(jìn)一步闡述了其256彩色模式下的存儲(chǔ)模式,并給出了的實(shí)用編程技術(shù),還附了一個(gè)在TVGA顯示器上顯示256色圖像的源程序。
關(guān)鍵詞DAC彩色表
增強(qiáng)型視頻圖形陣列TVGA自從Trident公司開發(fā)出來,現(xiàn)在以成為IBM和其他兼容機(jī)上普遍適用的圖形顯示器。TVGA提供與VGA寄存器級(jí)兼容能力,并增強(qiáng)了幾種顯示模式,特別是它能很方便的顯示256種顏色,為我們提供了豐富多彩的照片式圖像顯示。為了讓讀者能對(duì)TVGA的256色模式有一個(gè)清楚而全面的認(rèn)識(shí),文章將從結(jié)構(gòu)顯示原理以及存儲(chǔ)模式等方面來介紹,最后并給出TVGA256色模式下的編程技術(shù)。
一、TVGA視頻模式
TVGA提供了與VGA寄存器級(jí)兼容能力,而且大大增強(qiáng)了圖形、文本模式,支持256K×4DRAM、等離子體顯示控制,它可以模擬VGA、EGA、CGA、MDA和256色圖形方式,有640×400、640×480、800×600和1024×768四種模式。
TVGA除擁有VGA標(biāo)準(zhǔn)圖形模式外,還有擴(kuò)展VGA模式。在配置512K視頻緩沖區(qū)(DRAM)的系統(tǒng)中,256色的分辨率可達(dá)到800×600;若配置1MBDRAM,還可以達(dá)到1024×768更高的分辨率。
表1給出TVGA擴(kuò)展圖形模式的說明。
@@T5S10600.GIF;表1@@
由表1可知TVGA提供4種256色擴(kuò)充模式:5CH(640×400)、5DH(640×480)、5EH(800×600)和62H(1024×768)。在此后的文中,所談及的TVGA256色的視頻模式就是上述四種模式。
二、TVGA結(jié)構(gòu)
TVGA主要由:定序器、CRT控制器、圖形控制器、屬性控制器、DAC支持邏輯、主總線接口及顯示寄存器接口等7部分組成,它們之間的邏輯關(guān)系如圖1所示。
@@T5S10601.GIF;圖1@@
1.定序器
定序器為DRAM接口提供基本的存儲(chǔ)器時(shí)序,為CRT提供字符時(shí)鐘,并執(zhí)行某些存儲(chǔ)器地址解碼。它通過5個(gè)可以讀寫的寄存器進(jìn)行控制。它們有兩個(gè)I/O地址(3C4和3C5)。3C4是序號(hào)寄存器,用于選擇工作寄存。數(shù)據(jù)輸出到I/O地址為3C5的寄存器。
2.CRT控制器
CRT控制器通過產(chǎn)生顯示器光柵的同步信號(hào)等來控制顯示器,它也可以定義屏幕上顯示數(shù)據(jù)的格式。
3.圖形控制器
圖形控制器位于存儲(chǔ)器與系統(tǒng)處理器之間的數(shù)據(jù)通道中。在缺省狀態(tài)下,圖形控制器是透明的:數(shù)據(jù)在處理器之間直接進(jìn)行邏輯操作,為圖形算法提
供硬件支持。同樣,圖形控制器有兩個(gè)I/O地址:3CE和3CF,前者是序號(hào)寄存器,用于選擇圖形控制器各工作寄存器來驅(qū)動(dòng)TVGA模擬顯示器
4.屬性控制寄存器
屬性控制寄存器把圖形控制器接收的數(shù)據(jù)格式化后進(jìn)行視頻顯示。它操作調(diào)色板、屏幕邊界(或過掃描區(qū))和背景色彩。光標(biāo)閃爍、下劃線和顯示邏輯地址也由它控制。在圖形模式下,屬性控制器把內(nèi)存中的數(shù)據(jù)轉(zhuǎn)化成彩色查找表的地址,并由視頻DAC轉(zhuǎn)換成模擬電平來驅(qū)動(dòng)TVGA模擬顯示器。
5.數(shù)模轉(zhuǎn)換器(DAC)
數(shù)模轉(zhuǎn)換器,是TVGA系統(tǒng)中的可編程控制設(shè)備。它把TVGA產(chǎn)生的二進(jìn)制彩色信息轉(zhuǎn)換成可由監(jiān)視器顯示的信號(hào),DAC含有256個(gè)顏色數(shù)據(jù)寄存器,每個(gè)含有可顯示的每種顏色。每個(gè)數(shù)據(jù)寄存器保存18位彩色信息,紅綠藍(lán)各占6位。這些基色位控制三色模擬顯示的驅(qū)動(dòng)。TVGA256模式時(shí),顯示緩沖區(qū)的每一項(xiàng)由18位組成,分成三部分,各6位,分別代表紅綠藍(lán)的值。查找表中每一項(xiàng)是可以設(shè)置的,因此可有256k種顏色可以設(shè)置,由于查找表最多只有256色,所以同時(shí)顯示的顏色只有256種。顯示緩沖區(qū)、視頻DAC和彩色查找表、顯示屏的關(guān)系可用圖2來表示。
@@T5S10602.GIF;圖2@@
用于訪問視頻DAC的寄存器有5個(gè),見表2。
@@T5S10603.GIF;表2@@
選擇查找表2中256個(gè)內(nèi)部色彩寄存器,另有兩個(gè)獨(dú)立的寄存器,讀序號(hào)寄存器僅用于讀DAC顏色查找表,寫序號(hào)寄存器僅用于寫DAC顏色表。彩色寄存器寬18位,把8位序號(hào)寫入3C8寫序號(hào)寄存器,然后寫6位數(shù)到數(shù)據(jù)寄存器(3C9),那么8位序號(hào)彩色寄存器的3個(gè)分量就得到修改。每寫3個(gè)字節(jié),3C8寫寄存器自動(dòng)加一,因此不必重復(fù)設(shè)置序號(hào)便可給一組寄存器賦值。同樣,向讀寄存器(3C7)寫入8位序號(hào),然后從3C9中讀3個(gè)6位值,便可得到該序號(hào)彩色寄存器值。每讀3個(gè)字節(jié),序號(hào)寄存器就自動(dòng)加一,因此不必設(shè)置序號(hào)就可讀出一組彩色寄存
器值。
讀DAC狀態(tài)寄存器(3C7)可以知道彩色查找表當(dāng)前是讀還是寫。D0,D1位上的00值表示處于讀模式,01值表示處于寫模式。
三、TVGA256視頻模式的存儲(chǔ)模式
TVGA256圖形模式,包括模式5C、5D、5E和62等。在這幾種模式中,彩色查找表(調(diào)色板)的設(shè)置都是通過對(duì)端口3C7、3C8、3C9的讀寫達(dá)到重置彩色查找表的目的。這幾種顯示模式緩沖區(qū)的起始地址都是A0000,而所需緩存容量都大于TVGA基本的64KB,因此TVGA在控制卡上增加了一部緩存,它是通過3C4,3C5來存取。
1.TVGA存儲(chǔ)映射方式
顯示存儲(chǔ)器DRAM在系統(tǒng)主存儲(chǔ)空間的映射方式有兩種,也就是兩種頁(yè)模式(PAGEMODE),第一種允許CPU訪問DRAM的地址范圍為A0000—BFFFF,即128K模式;另一種地址范圍為A0000—AFFFF,即64K模式。前一種模式,在使用位平面存儲(chǔ)方式下,一次可以訪問128K的位平面;而后一種模式則需要另外一個(gè)I/O端口位來選擇讀出的是哪一個(gè)64K。TVGA的視頻BIOS缺省置為64K模式??筛鶕?jù)需要選擇頁(yè)模式,頁(yè)模式由圖形控制器中的輔助寄存器控制。圖形控制器有I/O地址3CE和3CF,3CE為索引端口地址,3CF為數(shù)據(jù)端口地址。而輔助寄存器則為3CE的第6號(hào)索引寄存器。該寄存器中存放著可修改的單字節(jié)數(shù)據(jù),各位意義如下:
4,5,6,7位:保留:
2,3位:DRAM在主存儲(chǔ)區(qū)內(nèi)的地址范圍
00—A0000~BFFFF(128K)
01—A0000~AFFFF(64K)
10—B0000~B7FFF(32K)
11—B8FFF~BFFFF(32K)
1位:置為0;
0位:若為0,表文本方式;若為1,表圖形方式。
在64K頁(yè)模式下,由于一幅640×480的256色圖象至少需要240K緩存,這大大的超過了64K頁(yè)模式下的緩存,因此TVGA在VGA64K基礎(chǔ)上,利用定序器控制器的地址寄存器(索引號(hào)為0EH)來分別控制數(shù)據(jù)傳送到不同的幾個(gè)64KB緩存中。定序器控制器的索引端口地址為3C4,數(shù)據(jù)端口地址為3C5。而地址寄存器則為0E號(hào)索引,存放
著單字節(jié)數(shù)據(jù),各位意義如下:
4,5,6,7位:保留;
2,3位:0到3號(hào)存儲(chǔ)塊選擇;
1位:頁(yè)選擇:讀DRAM時(shí),若為1,表讀第一頁(yè);
若為0,表讀第零頁(yè);特別注意,寫DRAM時(shí),
若為1,表寫第零頁(yè);若為0,表寫第一頁(yè);
0位:段選擇。
2.TVGA像素尋址
圖形顯示模式下TVGA使用自然坐標(biāo)系對(duì)其存儲(chǔ)器進(jìn)行尋址,各像素根據(jù)坐標(biāo)在屏幕上定位,原點(diǎn)位于屏幕左上角,坐標(biāo)最大點(diǎn)(Xmax,Ymax)位于右下角。
屏幕像素地址為20位(不包括0XA0000基地址),格式為:
16,17,18,19位:意義同定序器控制器的地址寄存器的4,5,6,7位;
0..15位:表段內(nèi)偏移地址。
四、TVGA編程技術(shù)
在TVGA256色視頻模式下,主要用于顯示高質(zhì)量照片式點(diǎn)陣式圖像。原圖像可以從彩色圖像掃描儀中或電視攝像機(jī)中獲得,只要把原圖像格式轉(zhuǎn)換成TVGA的256彩色顯示格式,就可以直接把圖像送TVGA顯示存儲(chǔ)器。本節(jié)所有例程都是用TURBOC語(yǔ)言寫成,并都在微機(jī)上調(diào)試通過。
1.模式設(shè)置
用BIOS中的INT10H可完成模式設(shè)置,下面只討論256色圖形模式的設(shè)定。在每次模式設(shè)置前,還要設(shè)置緩沖區(qū)的存儲(chǔ)模式。
(1)緩沖區(qū)存儲(chǔ)模式設(shè)置
①128K模式
voidmode128K()
{unsignedchari;
outp(0x3ce,0x06);
i=0x01;
i=(i&0x0f);
outp(0x3cf,i);
}
②64K模式
voidmode64K()
{unsignedchari;
outp(0x3ce,0x06);
i=0x05;
i=(i&0x0f);
outp(0x3cf,i);
(2)圖形顯示模式設(shè)置
set-mode(intmode)
{unionREGSin,out;
in.h.al=(unsignedchar)mode;
in.h.ah=0;
int86(0x10,&in,&out);
}
2.畫點(diǎn)程序和讀點(diǎn)程序
不妨設(shè)當(dāng)前模式下的橫向和縱向的最大分辨率maxx,maxy已知。
putpixel(intx,inty,unsignedcharcolor)
{longaddress,offset;
unsignedcharsegnumber;
charfar*p;
address=y*maxx+x;
offset=(address&0x0000ffff);
segnumber=(address&0x000f0000;)
outp(0x3c4,0x0e);
in.h.al=segnumber;
in.h.al=(in.h.al&0x0f)^0x02;
outp(0x3c5,in.h.al);
p=(charfar*)0xA0000000;
*(offset+p)=color;
}
getpixel(intx,inty,unsignedcharcolor)
{longaddress,offset;
unsignedcharsegnumber;
charfar*p;
address=y*maxx+x;
offset=(address&0x0000ffff);
segnumber=(address&0x000f0000);
outp(0x3c4,0x0e);
outp(0x3c5,segnumber);
p=(charfar*)0xA0000000;
color=*(offset+p);
}
.調(diào)色板的讀寫
對(duì)于TVGA256色視頻模式,BIOS中常用的是置調(diào)色板寄存器10H,其中改寫和讀取DAC彩色寄
存器的功能如下。
①設(shè)置單個(gè)DAC彩色寄存器值
輸入?yún)?shù):AH=10H,AL=10H
BX=DAC寄存器號(hào)(0~255)
DH=紅色分量值(6位)
CH=綠色分量值(6位)
CL=藍(lán)色分量值(6位)
返回值:無
②設(shè)置DAC彩色寄存器組
輸入?yún)?shù):AH=10H,AL=12H
BX=寄存器組起始號(hào)(0~255)
CX=寄存器數(shù)目(1~256)
ES:DX=彩色表地址(每個(gè)彩色寄存器對(duì)應(yīng)3個(gè)字節(jié))
返回值:無
③讀單個(gè)DAC彩色寄存器值
輸入?yún)?shù):AH=10H,AL=15H
BX=DAC寄存器號(hào)(0~255)
返回值:DH=紅色分量值
CH=綠色分量值
CL=藍(lán)色分量值
④讀DAC彩色寄存器組
輸入?yún)?shù):AH=10H,AL=17H
BX=寄存器組起始號(hào)(0~255)
CX=寄存器組數(shù)目(1~256)
ES:DX=讀取數(shù)據(jù)的存放地址
返回值:彩色寄存器的彩色值(每個(gè)寄存器3個(gè)字節(jié))
為了討論方便,先給出以下公共變量:
unionREGSin,out;
structSREGSsregs;
unignedcharcolor-table[256][3];
于是就可以編寫出相應(yīng)的程序。
①單個(gè)DAC寄存器寫函數(shù)
voidwriteDAC(intregnumber,unsignedcharr,unsignedcharg,
unsignedcharb)
{in.x.ax=0x1010;
in.x.bx=regnumber;
in.h.dh=r;
in.h.ch=g;
in.h.cl=b;
int86(0x10,&in,&out);
}
②單個(gè)DAC寄存器讀函數(shù)
voidreadDAC(intregnumber,unsignedcharr,unsignedcharg,
unsignedcharb)
{in.x.ax=0x1015;
in.x.bx=regnumber;
int86(0x10,&in,&out);
out.h.dh=r;
out.h.ch=g;
out.h.cl=b;
}
③寫DAC寄存器組函數(shù)
voidwriteDACS(intregnumber,intregcount,unsignedcha
r
*color-tableb)
{in.x.ax=0x1012;
in.x.bx=regnumber;
in.x.cx=regcount;
sregs.es=FP-SEG(color-table);
sregs.dx=FP-OFF(color-table);
int86x(0x10,&in,&out,&sregs);
}
④讀DAC寄存器組函數(shù)
voidreadDACS(intregnumber,intregcount,unsignedchar
*color-table)
{in.x.ax=0x1017;
in.x.bx=regnumber;
in.x.cx=regcount;
sregs.es=FP-SEG(color-table);
sregs.dx=FP-OFF(color-table);
int86x(0x10,&in,&out,&sregs);
}
除了BIOS方式之外,訪問調(diào)色板還可用寄存器訪問方式。這里用到3個(gè)寄存器I/O地址寄存器
3C7彩色查找表讀操作索引號(hào)
3C8彩色查找表寫操作索引號(hào)
3C9彩色查找表數(shù)據(jù)寄存器
①獲取當(dāng)前調(diào)色板數(shù)據(jù)
voidreadcolors(unsignedcharcolor-table[256][3])
{inti,j;
for(i=0;i<256;i++)
{outp(0x3c7,i);
for(j=0;j<3;j++)
color-table[i][j]=(unsignedchar)inp(0x3c9);
}
}
②重新設(shè)置調(diào)色板
voidwritecolors(unsignedcharcolor-table[256][3])
{inti,j;
outp(0x3c8,0);
for(i=0;i<256;i++)
for(j=0;j<3;j++)
outp(0x3c9,color-table[i][j]>>2);
}
③讀取單個(gè)DAC數(shù)據(jù)
readcolor(unsignedcharcolornum,unsignedr,unsignedc
ha
rg,unsignedcharb);
{outp(0x3c7,colornum);
r=inp(0x3c9);
g=inp(0x3c9);
b=inp(0x3c9);
}
④改寫單個(gè)DAC數(shù)據(jù)
writecolor(unsignedcharcolornum,unsignedr,unsigned
ch
arg,unsignedcharb);
{outp(0x3c8,colornum);
outp(0x3c9,r);
outp(0x3c9,g);
outp(0x3c9,b);
}
最后需指出,TVGA256色視頻模式是TVGA中最引人注目的模式,根據(jù)VGA的標(biāo)準(zhǔn),可選擇多達(dá)256K種顏色,但一個(gè)顯示頁(yè)同時(shí)可顯示的顏色最多只有256色,對(duì)于模式62H,系統(tǒng)需配置1MBDRAM,而一般個(gè)人計(jì)算機(jī)上的TVGA顯示卡只有512KBDRAM,因而一般不能實(shí)現(xiàn)62H模式所提供的1024*768這種高分辨率。所以,用戶在使用TVGA256色視頻模式時(shí),最好使用5DH模式,即分辨率為640*480的256色模式。為了讓讀者能盡快熟悉TVGA256色的編程技術(shù),筆者特給出一個(gè)在5DH模式下顯示256彩色TIFF圖像格式文件的程序,程序用C語(yǔ)言寫成,并在TURBOC2.0下編譯,運(yùn)行通過。程序中的TIFF文件的讀取涉及到圖像格式文件的知識(shí),這里不再贅言。
附:源程序showtif.c
#include<dos.h>
#include<stdio.h>
#include<alloc.h>
unsignedcharbuff[640],pal-buf[3*512],pal-buff[256][3];
structHEAD
{
unsignedintbo;
unsignedintver;
unsignedlongnext;
}head;/*定義TIFF格式文件頭*/
structDIR
{
unsignedinttga;
unsignedinttype;
unsignedlonglen;
unsignedlongval;
}dir[20];/*定義TIFF格式文件目錄項(xiàng)*/
main(intargc,char*argv[])
{
unionREGSin,out;
unsignedcharcur-mode,cur-page;
in.h.ah=15;
int86(0x10,&in,&out);
cur-mode=out.h.al;
cur-page=out.h.bh;/*存儲(chǔ)當(dāng)前顯示模式*/
show(argv[1],atoi(argv[2],atoi(argv[3]));
in.h.ah=0;
in.h.al=cur-mode;
in.h.bl=cur-page;
int86(0x10,&in,&out);/*恢復(fù)成原顯示模式*/
}
show(char*filename,intx,inty)
{
unionREGSin,out;
FILE*pcx;
unsignedintlongcc=0,dd,star,palptr;
registerintm,j;
unsignedintnd,bitcount,with,hight,d;
inti,k=-1;
unsignedcharch,mode,seg-num=0;
charfar*pvdieo=(charfar*)0xa0000000;
if((pcx=fopen(filename,"rb+"))==NULL)
{printf("openfileerror!");exit(0);}
fread(&head,8,1,pcx);
fseek(pcx,head,next,SEEK-SET);
fread(&nd,2,1,pcx);
fread(dir,12*nd,1,pcx);
for(i=0;i<nd;i++)
switch(dir[i].tga)
{
case0x100:with=dir[i].val;break;
case0x101:hight=dir[i].val;break;
case0x102:bitcount=dir[i].val;break;
case0x111:star=dir[i].val;break;
case0x140:palptr=dir[i].val;break;
default:continue;
}
/*
star=圖像數(shù)據(jù)首地址with=圖像寬度
hight=圖像高度bitcount=圖像像素位數(shù)
palptr=調(diào)色板首地址
*/
in.h.ah=0;
in.h.al=0x5d;
int86(0x10,&in,&out);
/*設(shè)置當(dāng)前顯示模式為5DH*/
fseek(pck,palptr,SEEK-SET);
fread(pal-buf,512*3,1,pcx);
/*讀取調(diào)色板數(shù)據(jù)*/
outp(0x3c8,0);
for(j=0;j<256;j++)
for(i=0;i<3;i++)
outp(0x3c9,pal-buf[i*512+2*j+1]>>2);
/*設(shè)置當(dāng)前調(diào)色板*/
x=x%640;
y=y%480;
cc=(long)y*(long)640+(long)x;
while(cc>=65535){cc=cc-65535;seg-num++;}
if(seg-num==0){if(x<=254)k=-x-1;elsek=640-x-1;}
if(seg-num==1){if(x<=510)k=254-x;elsek=640-x+254;}
if(seg-num==2){if(x<=126)k=510-x;elsek=640-x+510;}
if(seg-num==3){if(x<=382)k=126-x;elsek=640-x+126;}
if(seg-num==4){if(x<=638)k=638-x;elsek=640-x+382;}
pvdieo+=cc;
outp(0x3c4,0x0e);
in.h.al=seg-num++;
in.h.al=(in.h.al&0x0f)^0x02;
outp(0x3c5,in.h.al);
/*設(shè)置當(dāng)前的存儲(chǔ)模式*/
fseek(pcx,star,SEEK-SET);
for(j=0;j<hight;j++)
{
fread(buff,1,with,pcx);
/*逐行讀出像素?cái)?shù)據(jù)*/
if((cc+640)<65536)
{
for(m=0;m<with;m++)
*pvdieo++=buff[m];
pvdieo+=640-with;
cc+=640;
}
else
{
k=(k+256)%640;
if(k<with)
{
for(m=0;m<=k;m++)
*pvdieo++=buff[m];
}
else
{
for(m=0;m<with;m++)
*pvdieo++=buff[m];
pvdieo+=k-with;
}
outp(0x3c4,0x0e);
in.h.al=seg-num++;
in.h.al=(in.h.al&0x0f)^0x02;
outp(0x3c5,in.h.al);
pvdieo=(charfar*)0xa0000000;
if(k<with)
{
for(i=m;i<with;i++)
*pvdieo++=buff[i];
pvdieo+=640-with;
co=640-k;
}
else
{
pvdieo+=639-k;
co=640-k;
}
}
}
fclose(pcx);
getch();