TVGA彩色視頻模式論文

時間:2022-08-24 05:13:00

導語:TVGA彩色視頻模式論文一文來源于網友上傳,不代表本站觀點,若需要原創文章可咨詢客服老師,歡迎參考。

TVGA彩色視頻模式論文

摘要本文首先分析了tvga的結構和其顯示原理,然后進一步闡述了其256彩色模式下的存儲模式,并給出了的實用編程技術,還附了一個在TVGA顯示器上顯示256色圖像的源程序。

關鍵詞DAC彩色表

增強型視頻圖形陣列TVGA自從Trident公司開發出來,現在以成為IBM和其他兼容機上普遍適用的圖形顯示器。TVGA提供與VGA寄存器級兼容能力,并增強了幾種顯示模式,特別是它能很方便的顯示256種顏色,為我們提供了豐富多彩的照片式圖像顯示。為了讓讀者能對TVGA的256色模式有一個清楚而全面的認識,文章將從結構顯示原理以及存儲模式等方面來介紹,最后并給出TVGA256色模式下的編程技術。

一、TVGA視頻模式

TVGA提供了與VGA寄存器級兼容能力,而且大大增強了圖形、文本模式,支持256K×4DRAM、等離子體顯示控制,它可以模擬VGA、EGA、CGA、MDA和256色圖形方式,有640×400、640×480、800×600和1024×768四種模式。

TVGA除擁有VGA標準圖形模式外,還有擴展VGA模式。在配置512K視頻緩沖區(DRAM)的系統中,256色的分辨率可達到800×600;若配置1MBDRAM,還可以達到1024×768更高的分辨率。

表1給出TVGA擴展圖形模式的說明。

@@T5S10600.GIF;表1@@

由表1可知TVGA提供4種256色擴充模式:5CH(640×400)、5DH(640×480)、5EH(800×600)和62H(1024×768)。在此后的文中,所談及的TVGA256色的視頻模式就是上述四種模式。

二、TVGA結構

TVGA主要由:定序器、CRT控制器、圖形控制器、屬性控制器、DAC支持邏輯、主總線接口及顯示寄存器接口等7部分組成,它們之間的邏輯關系如圖1所示。

@@T5S10601.GIF;圖1@@

1.定序器

定序器為DRAM接口提供基本的存儲器時序,為CRT提供字符時鐘,并執行某些存儲器地址解碼。它通過5個可以讀寫的寄存器進行控制。它們有兩個I/O地址(3C4和3C5)。3C4是序號寄存器,用于選擇工作寄存。數據輸出到I/O地址為3C5的寄存器。

2.CRT控制器

CRT控制器通過產生顯示器光柵的同步信號等來控制顯示器,它也可以定義屏幕上顯示數據的格式。

3.圖形控制器

圖形控制器位于存儲器與系統處理器之間的數據通道中。在缺省狀態下,圖形控制器是透明的:數據在處理器之間直接進行邏輯操作,為圖形算法提

供硬件支持。同樣,圖形控制器有兩個I/O地址:3CE和3CF,前者是序號寄存器,用于選擇圖形控制器各工作寄存器來驅動TVGA模擬顯示器

4.屬性控制寄存器

屬性控制寄存器把圖形控制器接收的數據格式化后進行視頻顯示。它操作調色板、屏幕邊界(或過掃描區)和背景色彩。光標閃爍、下劃線和顯示邏輯地址也由它控制。在圖形模式下,屬性控制器把內存中的數據轉化成彩色查找表的地址,并由視頻DAC轉換成模擬電平來驅動TVGA模擬顯示器。

5.數模轉換器(DAC)

數模轉換器,是TVGA系統中的可編程控制設備。它把TVGA產生的二進制彩色信息轉換成可由監視器顯示的信號,DAC含有256個顏色數據寄存器,每個含有可顯示的每種顏色。每個數據寄存器保存18位彩色信息,紅綠藍各占6位。這些基色位控制三色模擬顯示的驅動。TVGA256模式時,顯示緩沖區的每一項由18位組成,分成三部分,各6位,分別代表紅綠藍的值。查找表中每一項是可以設置的,因此可有256k種顏色可以設置,由于查找表最多只有256色,所以同時顯示的顏色只有256種。顯示緩沖區、視頻DAC和彩色查找表、顯示屏的關系可用圖2來表示。

@@T5S10602.GIF;圖2@@

用于訪問視頻DAC的寄存器有5個,見表2。

@@T5S10603.GIF;表2@@

選擇查找表2中256個內部色彩寄存器,另有兩個獨立的寄存器,讀序號寄存器僅用于讀DAC顏色查找表,寫序號寄存器僅用于寫DAC顏色表。彩色寄存器寬18位,把8位序號寫入3C8寫序號寄存器,然后寫6位數到數據寄存器(3C9),那么8位序號彩色寄存器的3個分量就得到修改。每寫3個字節,3C8寫寄存器自動加一,因此不必重復設置序號便可給一組寄存器賦值。同樣,向讀寄存器(3C7)寫入8位序號,然后從3C9中讀3個6位值,便可得到該序號彩色寄存器值。每讀3個字節,序號寄存器就自動加一,因此不必設置序號就可讀出一組彩色寄存

器值。

讀DAC狀態寄存器(3C7)可以知道彩色查找表當前是讀還是寫。D0,D1位上的00值表示處于讀模式,01值表示處于寫模式。

三、TVGA256視頻模式的存儲模式

TVGA256圖形模式,包括模式5C、5D、5E和62等。在這幾種模式中,彩色查找表(調色板)的設置都是通過對端口3C7、3C8、3C9的讀寫達到重置彩色查找表的目的。這幾種顯示模式緩沖區的起始地址都是A0000,而所需緩存容量都大于TVGA基本的64KB,因此TVGA在控制卡上增加了一部緩存,它是通過3C4,3C5來存取。

1.TVGA存儲映射方式

顯示存儲器DRAM在系統主存儲空間的映射方式有兩種,也就是兩種頁模式(PAGEMODE),第一種允許CPU訪問DRAM的地址范圍為A0000—BFFFF,即128K模式;另一種地址范圍為A0000—AFFFF,即64K模式。前一種模式,在使用位平面存儲方式下,一次可以訪問128K的位平面;而后一種模式則需要另外一個I/O端口位來選擇讀出的是哪一個64K。TVGA的視頻BIOS缺省置為64K模式。可根據需要選擇頁模式,頁模式由圖形控制器中的輔助寄存器控制。圖形控制器有I/O地址3CE和3CF,3CE為索引端口地址,3CF為數據端口地址。而輔助寄存器則為3CE的第6號索引寄存器。該寄存器中存放著可修改的單字節數據,各位意義如下:

4,5,6,7位:保留:

2,3位:DRAM在主存儲區內的地址范圍

00—A0000~BFFFF(128K)

01—A0000~AFFFF(64K)

10—B0000~B7FFF(32K)

11—B8FFF~BFFFF(32K)

1位:置為0;

0位:若為0,表文本方式;若為1,表圖形方式。

在64K頁模式下,由于一幅640×480的256色圖象至少需要240K緩存,這大大的超過了64K頁模式下的緩存,因此TVGA在VGA64K基礎上,利用定序器控制器的地址寄存器(索引號為0EH)來分別控制數據傳送到不同的幾個64KB緩存中。定序器控制器的索引端口地址為3C4,數據端口地址為3C5。而地址寄存器則為0E號索引,存放

著單字節數據,各位意義如下:

4,5,6,7位:保留;

2,3位:0到3號存儲塊選擇;

1位:頁選擇:讀DRAM時,若為1,表讀第一頁;

若為0,表讀第零頁;特別注意,寫DRAM時,

若為1,表寫第零頁;若為0,表寫第一頁;

0位:段選擇。

2.TVGA像素尋址

圖形顯示模式下TVGA使用自然坐標系對其存儲器進行尋址,各像素根據坐標在屏幕上定位,原點位于屏幕左上角,坐標最大點(Xmax,Ymax)位于右下角。

屏幕像素地址為20位(不包括0XA0000基地址),格式為:

16,17,18,19位:意義同定序器控制器的地址寄存器的4,5,6,7位;

0..15位:表段內偏移地址。

四、TVGA編程技術

在TVGA256色視頻模式下,主要用于顯示高質量照片式點陣式圖像。原圖像可以從彩色圖像掃描儀中或電視攝像機中獲得,只要把原圖像格式轉換成TVGA的256彩色顯示格式,就可以直接把圖像送TVGA顯示存儲器。本節所有例程都是用TURBOC語言寫成,并都在微機上調試通過。

1.模式設置

用BIOS中的INT10H可完成模式設置,下面只討論256色圖形模式的設定。在每次模式設置前,還要設置緩沖區的存儲模式。

(1)緩沖區存儲模式設置

①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)圖形顯示模式設置

set-mode(intmode)

{unionREGSin,out;

in.h.al=(unsignedchar)mode;

in.h.ah=0;

int86(0x10,&in,&out);

}

2.畫點程序和讀點程序

不妨設當前模式下的橫向和縱向的最大分辨率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);

}

.調色板的讀寫

對于TVGA256色視頻模式,BIOS中常用的是置調色板寄存器10H,其中改寫和讀取DAC彩色寄

存器的功能如下。

①設置單個DAC彩色寄存器值

輸入參數:AH=10H,AL=10H

BX=DAC寄存器號(0~255)

DH=紅色分量值(6位)

CH=綠色分量值(6位)

CL=藍色分量值(6位)

返回值:無

②設置DAC彩色寄存器組

輸入參數:AH=10H,AL=12H

BX=寄存器組起始號(0~255)

CX=寄存器數目(1~256)

ES:DX=彩色表地址(每個彩色寄存器對應3個字節)

返回值:無

③讀單個DAC彩色寄存器值

輸入參數:AH=10H,AL=15H

BX=DAC寄存器號(0~255)

返回值:DH=紅色分量值

CH=綠色分量值

CL=藍色分量值

④讀DAC彩色寄存器組

輸入參數:AH=10H,AL=17H

BX=寄存器組起始號(0~255)

CX=寄存器組數目(1~256)

ES:DX=讀取數據的存放地址

返回值:彩色寄存器的彩色值(每個寄存器3個字節)

為了討論方便,先給出以下公共變量:

unionREGSin,out;

structSREGSsregs;

unignedcharcolor-table[256][3];

于是就可以編寫出相應的程序。

①單個DAC寄存器寫函數

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);

}

②單個DAC寄存器讀函數

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寄存器組函數

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寄存器組函數

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方式之外,訪問調色板還可用寄存器訪問方式。這里用到3個寄存器I/O地址寄存器

3C7彩色查找表讀操作索引號

3C8彩色查找表寫操作索引號

3C9彩色查找表數據寄存器

①獲取當前調色板數據

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);

}

}

②重新設置調色板

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);

}

③讀取單個DAC數據

readcolor(unsignedcharcolornum,unsignedr,unsignedc

ha

rg,unsignedcharb);

{outp(0x3c7,colornum);

r=inp(0x3c9);

g=inp(0x3c9);

b=inp(0x3c9);

}

④改寫單個DAC數據

writecolor(unsignedcharcolornum,unsignedr,unsigned

ch

arg,unsignedcharb);

{outp(0x3c8,colornum);

outp(0x3c9,r);

outp(0x3c9,g);

outp(0x3c9,b);

}

最后需指出,TVGA256色視頻模式是TVGA中最引人注目的模式,根據VGA的標準,可選擇多達256K種顏色,但一個顯示頁同時可顯示的顏色最多只有256色,對于模式62H,系統需配置1MBDRAM,而一般個人計算機上的TVGA顯示卡只有512KBDRAM,因而一般不能實現62H模式所提供的1024*768這種高分辨率。所以,用戶在使用TVGA256色視頻模式時,最好使用5DH模式,即分辨率為640*480的256色模式。為了讓讀者能盡快熟悉TVGA256色的編程技術,筆者特給出一個在5DH模式下顯示256彩色TIFF圖像格式文件的程序,程序用C語言寫成,并在TURBOC2.0下編譯,運行通過。程序中的TIFF文件的讀取涉及到圖像格式文件的知識,這里不再贅言。

附:源程序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格式文件目錄項*/

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;/*存儲當前顯示模式*/

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);/*恢復成原顯示模式*/

}

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=圖像數據首地址with=圖像寬度

hight=圖像高度bitcount=圖像像素位數

palptr=調色板首地址

*/

in.h.ah=0;

in.h.al=0x5d;

int86(0x10,&in,&out);

/*設置當前顯示模式為5DH*/

fseek(pck,palptr,SEEK-SET);

fread(pal-buf,512*3,1,pcx);

/*讀取調色板數據*/

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);

/*設置當前調色板*/

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);

/*設置當前的存儲模式*/

fseek(pcx,star,SEEK-SET);

for(j=0;j<hight;j++)

{

fread(buff,1,with,pcx);

/*逐行讀出像素數據*/

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();