Регистр данных таблицы цветов (Look-up Table Data Register - LTDR)
Регистр используется для получения доступа к регистрам таблицы цветов. Для чтения и записи одного элемента таблицы цветов необходимо три раза прочитать (записать) содержимое регистра данных. При этом каждый раз считывается (записывается) шесть очередных битов. Первые шесть битов отвечают за интенсивность красного, вторые - зеленого и третьи - синего цвета.
Нельзя прерывать цикл чтения регистров таблицы цветов, состоящий из трех операций чтения, выполнением операции записи в другой регистр таблицы и наоборот. Во время доступа к регистру LTDR прерывания должны быть запрещены. Между операциями доступа к регистрам таблицы цвета необходимо выдержать временной интервал не менее 240 наносекунд.
D5-D0 Данные для обмена с регистрами таблицы цветов.
D7-D6 Не используется.
Программа VGA256 (листинг 4.13) записывает новые значения в таблицу цветов непосредственно через регистры цифро-аналогового преобразователя VGA. На экране монитора отображается пять вертикальных полос различного цвета. Каждая полоса состоит из 64 вертикальных линий. Интенсивность цвета этих линий плавно уменьшается слева на право.
Листинг 4.13. Файл VGA256.C
#include <stdio.h>
#include <conio.h>
#include "sysp.h"
#include "sysgraph.h"
#include <dos.h>
// Описания функций
int main( void );
void SetVideoMode( unsigned char );
void Hello(void);
// Функция SetVgaDAC определена в файле DACTABLE.ASM
void __pascal __far SetVgaDAC(unsigned, unsigned);
//===========================================================
// Главная функция
//===========================================================
int main( void )
{
RGB color_table[256];
int error, x_num, y_num;
unsigned i, j, iii;
unsigned seg_table,off_table;
unsigned char far *ptr;
// Записываем в массив color_table новые значения для
// регистров таблицы цветов
for(j = 0; j < 4; j++) {
for(i = 0; i < 64; i++) {
(color_table[i+j*64]).red =
(j == 0) ? i : 0;
(color_table[i+j*64]).green =
(j == 1) ? i : (j == 3) ? i : 0;
(color_table[i+j*64]).blue =
(j == 2) ? i : (j == 3) ? i : 0;
}
}
// Устанавливаем режим видеоадаптера номер 13h (256 цветов)
// данный режим поддерживается только VGA и Super VGA
SetVideoMode( 0x13 );
// Определяем сегмент и смешение массива color_table
ptr = (unsigned char far*) &color_table[0];
seg_table = FP_SEG(ptr);
off_table = FP_OFF(ptr);
// Загружаем новые значения в регистры таблицы цветов
SetVgaDAC(seg_table,off_table);
// Записываем в ptr указатель на начало видеопамяти
ptr = (unsigned char far*) (FP_MAKE(0xA000, 0x0));
// Выводим на экран вертикальные линии различного цвета,
// процессор записывает данные непосредственно в видеопамять
for(y_num = 0; y_num < 200; y_num++) {
for(x_num = 0; x_num < 320; x_num++) {
*ptr = (unsigned char) x_num;
ptr++;
}
}
// Ожидаем нажатие на клавишу
getch();
// Плавно гасим изображение на экране, уменьшая значения
// регистров таблицы цветов
for(i=0;i<320;i++){
for(iii=0;iii<256;iii++) {
(color_table[iii]).red =
((color_table[iii]).red>6) ?
color_table[iii].red-1 : 1;
(color_table[iii]).green =
((color_table[iii]).green>6) ?
color_table[iii].green-1 : 1;
(color_table[iii]).blue =
((color_table[iii]).blue>6) ?
color_table[iii].blue-1 : 1;
}
SetVgaDAC(seg_table,off_table);
}
// Ожидаем нажатие на клавишу
SetVideoMode( 0x3 );
Hello();
return 0;
}
//===========================================================
// Функция SetVideoMode устанавливает режим работы
// видеоадаптера, заданный параметром vmode
//===========================================================
void SetVideoMode( unsigned char vmode ) {
union REGS inregs, outregs;
inregs.h.ah = 0x0;
inregs.h.al = vmode;
int86( 0x10, &inregs, &outregs );
}
//===========================================================
// Функция Hello выводит на экран краткую справку о программе
//===========================================================
void Hello(void) {
printf("\nCopyright (C)Frolov G.V.,1995. "
"E-mail: frolov@glas.apc.org\n");
}
Функция SetVgaDAC, предназначенная для заполнения таблицы цветов, представлена в листинге 4.14.
Листинг 4.14. Файл DACTABLE.ASM
TITLE DACTABLE.ASM
NAME DACTABLE
PAGE 55,132
P286
IDEAL
NOWARN BRK
SEGMENT VGA_TEXT WORD PUBLIC 'CODE'
ASSUME cs:VGA_TEXT
;============================================================
; Функция
; void SetVgaDAC(unsigned seg_table, unsigned off_table)
;============================================================
off_table EQU [bp+6]
seg_table EQU [bp+8]
PUBLIC SETVGADAC
PROC SETVGADAC FAR
enter 0, 0
; Сохраняем регистры DS и ES
push ds
push es
; Устанавливаем регистр ES на начало оперативной памяти
xor ax,ax
mov es,ax
; Получаем адрес порта индексного регистра контроллера ЭЛТ
; (3B4h/3D4h), в монохромных режимах для адресации к
; индексному регистру используется порт с адресом 3B4h, а
; в цветных - порт 3D4h
mov dx,es:[463h]
; Вычисляем адрес порта регистра состояния 1, в
; монохромных режимах для адресации к регистру состояния 1
; используется порт с адресом 3BAh, а в цветных порт 3DAh
add dx,6
pop es
; Ожидаем начало обратного вертикального хода луча
in al,dx
nop
nop
; Если бит D3 равен единице, то происходит обратный
; вертикальный ход луча
test al,08h
jz wait_on
wait_off:
in al,dx
nop
nop
test al,08h
jnz wait_off
wait_on:
in al,dx
nop
nop
test al,08h
jz wait_on
; Устанавливаем индекс первого записываемого регистра
; таблицы цветов
mov dx,3C8h
; Начинаем модифицировать таблицу цветов с первого
; регистра
mov ax,1
out dx,al
; Задержка
nop
nop
; Устанавливаем DS:SI на массив данных, записываемых
; в регистры таблицы цветов
mov ax,seg_table
mov ds,ax
mov si,off_table
; Загружаем 256 регистров (по 3 байта на регистр)
mov cx,(256 * 3)
; Выбираем регистр данных таблицы цветов (порт 3C9h)
mov dx,3C9h
cld
; Загружаем все регистры таблицы цветов
get_reg:
lodsb
out dx,al
nop
nop
loop get_reg
; Восстанавливаем регистр DS
pop ds
leave
ret 4
ENDP SETVGADAC
ENDS VGA_TEXT
END
Содержание раздела