TVGA彩色视频模式

时间:2022-08-08 13:07:38 阅读: 最新文章 文档下载
说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。
TVGA彩色视频模式

本文首先分析了TVGA的结构和其显示原理,然后进一步阐述了其256彩色模式下的存储模式,并给出了的实用编程技术,还附了一个在TVGA显示器上显示256色图像的源程序。

关键词 DAC彩色表

增强型视频图形阵列TVGA自从Trident公司开发出来,现在以成为IBM和其他兼容机上普遍适用的图形显示器。TVGA提供与VGA寄存器级兼容能力,并增强了几种显示模式,特别是它能很方便的显示256种颜色,为我们提供了丰富多彩的照片式图像显示。为了让读者能对TVGA256色模式有一个清楚而全面的认识,文章将从结构显示原理以及存储模式等方面来介绍,最后并给出TVGA256色模式下的编程技术。

一、TVGA视频模式

TVGA提供了与VGA寄存器级兼容能力,而且大大增强了图形、文本模式,支256K×4 DRAM、等离子体显示控制,它可以模拟VGAEGACGAMDA256图形方式,有640×400、640×480、800×6001024×768四种模式。

TVGA除拥有VGA标准图形模式外,还有扩展VGA模式。在配置512K视频缓冲区(DRAM)的系统中,256色的分辨率可达到800×600;若配置1MB DRAM,还可以达1024×768更高的分辨率。

1给出TVGA扩展图形模式的说明。 @@T5S10600.GIF;1@@

由表1可知TVGA提供4256色扩充模式: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地址(3C43C5)3C4是序号寄存器,用于选择工作寄存。数据输出到I/O地址为3C5的寄存器。

2.CRT控制器


CRT控制器通过产生显示器光栅的同步信号等来控制显示器,它也可以定义屏幕上显示数据的格式。 3.图形控制器

图形控制器位于存储器与系统处理器之间的数据通道中。在缺省状态下,图形控制器是透明的:数据在处理器之间直接进行逻辑操作,为图形算法提

供硬件支持。同样,图形控制器有两个I/O地址:3CE3CF,前者是序号寄存器,用于选择图形控制器各工作寄存器来驱动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@@

选择查找表2256个内部色彩寄存器,另有两个独立的寄存器,读序号寄存器仅用于读DAC颜色查找表,写序号寄存器仅用于写DAC颜色表。彩色寄存器宽18位,把8位序号写入3C8写序号寄存器,然后写6位数到数据寄存器(3C9),那么8位序号彩色寄存器的3个分量就得到修改。每写3个字节,3C8写寄存器自动加一,因此不必重复设置序号便可给一组寄存器赋值。同样,向读寄存器(3C7)写入8位序号,然后从3C9中读36位值,便可得到该序号彩色寄存器值。每读3字节,序号寄存器就自动加一,因此不必设置序号就可读出一组彩色寄存 器值。

DAC状态寄存器(3C7)可以知道彩色查找表当前是读还是写。D0D1位上的00值表示处于读模式,01值表示处于写模式。

三、TVGA 256视频模式的存储模式

TVGA256图形模式,包括模式5C5D5E62等。在这几种模式中,彩色查找表(调色板)的设置都是通过对端口3C73C83C9的读写达到重置彩色查找表的目的。这几种显示模式缓冲区的起始地址都是A0000,而所需缓存容量都大于TVGA基本的64KB,因此TVGA在控制卡上增加了一部缓存,它是通过3C43C5来存取。

1.TVGA存储映射方式


显示存储器DRAM在系统主存储空间的映射方式有两种,也就是两种页模式

(PAGEMODE),第一种允许CPU访问DRAM的地址范围为A0000―BFFFF,即128K式;另一种地址范围为A0000―AFFFF,即64K模式。前一种模式,在使用位平面存储方式下,一次可以访问128K的位平面;而后一种模式则需要另外一个I/O口位来选择读出的是哪一个64KTVGA的视频BIOS缺省置为64K模式。可根据需要选择页模式,页模式由图形控制器中的辅助寄存器控制。图形控制器有I/O地址3CE3CF3CE为索引端口地址,3CF为数据端口地址。而辅助寄存器则为3CE6号索引寄存器。该寄存器中存放着可修改的单字节数据,各位意义如下: 4567:保留:

23:DRAM在主存储区内的地址范围 00―A0000~BFFFF (128K) 01A0000AFFFF (64K) 10―B0000~B7FFF (32K) 11―B8FFF~BFFFF (32K) 1:置为0

0:若为0,表文本方式;若为1,表图形方式。

64K页模式下,由于一幅640×480256色图象至少需要240K缓存,这大大的超过了64K页模式下的缓存,因此TVGAVGA 64K基础上,利用定序器控制器的地址寄存器(索引号为0EH)来分别控制数据传送到不同的几个64KB缓存中。定序器控制器的索引端口地址为3C4,数据端口地址为3C5。而地址寄存器则为0E号索引,存放

着单字节数据,各位意义如下: 4567:保留;

23:03号存储块选择;

1:页选择:DRAM时,若为1,表读第一页; 若为0,表读第零页;特别注意,写DRAM时, 若为1,表写第零页;若为0,表写第一页; 0:段选择。 2.TVGA像素寻址

图形显示模式下TVGA使用自然坐标系对其存储器进行寻址,各像素根据坐标在屏幕上定位,原点位于屏幕左上角,坐标最大点(Xmax Ymax)位于右下角。 屏幕像素地址为20(不包括0XA0000基地址),格式为:

16171819:意义同定序器控制器的地址寄存器的4567位; 0..15 :表段内偏移地址。 四、TVGA编程技术

TVGA 256色视频模式下,主要用于显示高质量照片式点阵式图像。原图像可以从彩色图像扫描仪中或电视摄像机中获得,只要把原图像格式转换成TVGA256彩色显示格式,就可以直接把图像送TVGA显示存储器。本节所有例程都是用TURBO C语言写成,并都在微机上调试通过。 1.模式设置

BIOS中的INT10H可完成模式设置,下面只讨论256色图形模式的设定。在每次


模式设置前,还要设置缓冲区的存储模式。 (1) 缓冲区存储模式设置 ① 128K模式 void mode128K() { unsigned char i; outp(0x3ce0x06); i=0x01;

i=(i & 0x0f); outp(0x3cfi); }

② 64K模式 void mode64K()

{ unsigned char i; outp(0x3ce0x06); i=0x05;

i=(i & 0x0f); outp(0x3cf i);

(2) 图形显示模式设置 set-mode( int mode) { union REGS in out;

in.h.al=(unsigned char) mode; in.h.ah=0;

int86(0x10 &in &out); }

2.画点程序和读点程序

不妨设当前模式下的横向和纵向的最大分辨率maxxputpixel(int xint yunsigned char color) { long addressoffset; unsigned char segnumber; char far *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(0x3c5in.h.al);

p=(char far *) 0xA0000000; *(offset+p)=color; }

getpixel(int xint yunsigned char color)

已知。 maxy
{ long addressoffset; unsigned char segnumber; char far *p;

address=y*maxx+x;

offset=(address & 0x0000ffff); segnumber=(address & 0x000f0000); outp(0x3c40x0e);

outp(0x3c5segnumber); p=(char far *)0xA0000000; color=*(offset+p); }

3.调色板的读写

对于TVGA 256色视频模式,BIOS中常用的是置调色板寄存器10H,其中改写和读DAC彩色寄 存器的功能如下。

① 设置单个DAC彩色寄存器值 输入参数:AH=10HAL=10H BX=DAC寄存器号(0255) DH=红色分量值(6) CH=绿色分量值(6) CL=蓝色分量值(6) 返回值:

② 设置DAC彩色寄存器组 输入参数:AH=10HAL=12H BX=寄存器组起始号(0255) CX=寄存器数目(1256)

ES:DX=彩色表地址(每个彩色寄存器对应3个字节) 返回值:

③ 读单个DAC彩色寄存器值 输入参数:AH=10HAL=15H BX=DAC寄存器号(0255) 返回值:DH=红色分量值 CH=绿色分量值 CL=蓝色分量值

④ 读DAC彩色寄存器组 输入参数:AH=10HAL=17H BX=寄存器组起始号(0255) CX=寄存器组数目(1256) ES:DX=读取数据的存放地址

返回值:彩色寄存器的彩色值(每个寄存器3个字节)


为了讨论方便,先给出以下公共变量: union REGS in out; struct SREGS sregs;

unigned char color-table256][3; 于是就可以编写出相应的程序。 ① 单个DAC寄存器写函数

void writeDAC(int regnumber unsigned char r unsigned char g unsigned char b) { 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寄存器读函数

void readDAC(int regnumber unsigned char r unsigned charg unsigned char b) { 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寄存器组函数

void writeDACS(int regnumber int regcount unsigned cha 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寄存器组函数

void readDACS(int regnumber int regcount unsigned char *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彩色查找表数据寄存器 ① 获取当前调色板数据

void readcolors(unsigned char color-table256][3) { int i j;

for (i=0;i<256;i++) { outp(0x3c7i); for (j=0; j<3; j++)

color-tablei][j=(unsigned char)inp(0x3c9); } }

② 重新设置调色板

void writecolors(unsigned char color-table256][3) { int i j; outp(0x3c80);

for (i=0; i<256;i++) for (j=0; j<3; j++)

outp(0x3c9 color-tablei][j>>2); }

③ 读取单个DAC数据

readcolor(unsigned char colornum unsigned r unsigned c ha

rgunsigned char b); { outp(0x3c7 colornum); r=inp(0x3c9); g=inp(0x3c9); b=inp(0x3c9); }

④ 改写单个DAC数据

writecolor(unsigned char colornum unsigned r unsigned ch

argunsigned char b); { outp(0x3c8 colornum);


outp(0x3c9 r); outp(0x3c9 g); outp(0x3c9 b); }

最后需指出,TVGA 256色视频模式是TVGA中最引人注目的模式,根据VGA的标准,可选择多达256K种颜色,但一个显示页同时可显示的颜色最多只有256色,对于模式62H,系统需配置1MB DRAM,而一般个人计算机上的TVGA显示卡只有512KB DRAM,因而一般不能实现62H模式所提供的1024*768这种高分辨率。所以,用户在使用TVGA 256色视频模式时,最好使用5DH模式,即分辨率为

640*480256色模式。为了让读者能尽快熟悉TVGA256色的编程技术,笔者特给出一个在5DH模式下显示256彩色TIFF图像格式文件的程序,程序用C语言写成,并在TURBO C2.0下编译,运行通过。程序中的TIFF文件的读取涉及到图像格式文件的知识,这里不再赘言。 :源程序 showtif.c #include #include #include

unsigned char buff640],pal-buf3*512], pal-buff256][3; struct HEAD {

unsigned int bo; unsigned int ver; unsigned long next;

} head; /*定义TIFF格式文件头 */ struct DIR {

unsigned int tga; unsigned int type; unsigned long len; unsigned long val;

} dir20; /*定义TIFF格式文件目录项 */ main(int argcchar *argv[]) {

union REGS in out;

unsigned char cur-modecur-page; in.h.ah=15;

int86(0x10&in &out); cur-mode=out.h.al;

cur-page=out.h.bh; /*存储当前显示模式 */

show(argv1],atoi(argv2],atoi(argv3)); in.h.ah=0;


in.h.al=cur-mode; in.h.bl=cur-page;

int86(0x10&in&out); /*恢复成原显示模式 */ }

show(char *filenameint xint y) {

union REGS inout; FILE *pcx;

unsigned int long cc=0ddstarpalptr; register int m j;

unsigned int ndbitcount with hightint ik=-1;

unsigned char ch modeseg-num=0;

char far *pvdieo=(char far *)0xa0000000; if ((pcx=fopen(filename "rb+"))==NULL) {printf("open file error !");exit(0);} fread(&head81pcx);

fseek(pcxheadnextSEEK-SET); fread(&nd21pcx); fread(dir12*nd1pcx); for(i=0; iswitch(diri.tga) {

case 0x100: with=diri.val;break; case 0x101: hight=diri.val;break; case 0x102: bitcount=diri.val;break; case 0x111: star=diri.val;break; case 0x140: palptr=diri.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-buf512*31pcx);

d;
/* 读取调色板数据 */ outp(0x3c80);

for (j=0;j<256; j++) for (i=0; i<3; i++)

outp(0x3c9pal-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; else k=640-x-1;} if(seg-num==1) { if(x<=510) k=254-x; else k=640-x+254;} if(seg-num==2) { if(x<=126) k=510-x; else k=640-x+510;} if(seg-num==3) { if(x<=382) k=126-x; else k=640-x+126;} if(seg-num==4) { if(x<=638) k=638-x; else k=640-x+382;} pvdieo+=cc;

outp(0x3c40x0e); in.h.al=seg-num++;

in.h.al=(in.h.al & 0x0f)^0x02; outp(0x3c5in.h.al); /* 设置当前的存储模式 */

fseek(pcx star SEEK-SET); for(j=0;j{

fread(buff1withpcx); /* 逐行读出像素数据 */ if ((cc+640) <65536) {

for(m=0; m*pvdieo++=buffm; pvdieo+=640-with; cc+=640; } else {

k=(k+256)%640; if (k{

for(m=0;m<=k;m++) *pvdieo++=buffm; }


else {

for(m=0;m*pvdieo++=buffm; pvdieo+=k-with; }

outp(0x3c40x0e); in.h.al=seg-num++;

in.h.al=(in.h.al & 0x0f)^0x02; outp(0x3c5in.h.al);

pvdieo=(char far *)0xa0000000; if (k{

for(i=m; i*pvdieo++=buffi; pvdieo+=640-with; co=640-k; } else {

pvdieo+=639-k; co=640-k; } } }

fclose(pcx); getch(); }


本文来源:https://www.wddqw.com/doc/39dbe1115b0216fc700abb68a98271fe910eafd7.html