Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Программирование видеоадаптеров.

© Александр Фролов, Григорий Фролов
Том 21, М.: Диалог-МИФИ, 1993.

[Назад] [Содеожание] [Дальше]

Управление регистрами палитры - функция 10h

Функция 10h предоставляет возможность программирования регистров цветовой палитры, таблицы цветов (для видеоадаптеров VGA и SVGA), а также управляет некоторыми атрибутами символов. Вы можете использовать эту функцию и в текстовых и в графических режимах.

Для видеоадаптера EGA эта функция содержит четыре подфункции:

Номер подфункции

Назначение

0

Программирование одного регистра палитры

1

Программирование регистра цвета рамки

2

Программирование всех регистров палитры (таблицы цветов)

3

Управление атрибутом мигания и атрибутом интенсивности

Видеоадаптеры VGA и SVGA дополнительно поддерживают еще 10 подфункций:

Номер подфункции

Назначение

7

Чтение регистра палитры

8

Чтение регистра цвета рамки

9

Чтение всех регистров палитры

10h

Программирование регистра ЦАП

12h

Программирование нескольких регистров ЦАП

13h

Выбор подмножества цветов

15h

Чтение регистра ЦАП

17h

Чтение нескольких регистров ЦАП

1Ah

Чтение состояния страницы цветов

1Bh

Преобразование регистров ЦАП для работы в монохромном режиме

Установка регистра палитры - подфункция 00h

Функция выполняет запись в регистр палитры контроллера атрибутов:

На входе:

AH

10h

 

AL

00h - установка регистра палитры

 

BL

Номер регистра палитры для записи

 

BH

Данные, записываемые в регистр палитры

На выходе:

 

Не используются

Следующий фрагмент записывает в регистр палитры с номером reg_num содержимое переменной data:


mov	ah,10h		; Функция 10h
xor	al,al			; Подфункция 0h
mov	bl,num_reg	; Задаем номер регистра палитры
mov	bh,data		; Новое значение регистра
int	10h

Установка цвета рамки - подфункция 01h

Функция выполняет запись значения в регистр цвета рамки контроллера атрибутов. Надо иметь в виду, что эта функция не работает в некоторых режимах видеоадаптера EGA.

На входе:

AH

10h

 

AL

01h - установка цвета рамки

 

BH

Значение, записываемое в регистр (цвет)

На выходе:

 

Не используются

Программа BORDER, приведенная в листинге 5.4, использует подфункцию 01h для изменения цвета рамки экрана.

Листинг 5.4. Файл BORDER.C


#include <dos.h>
#include <stdio.h>
#include <conio.h>

void main(void);

// Главная функция
void main(void) {

	union REGS	inregs, outregs;
	unsigned char	i;

	// Пробуем 16 цветов для рамки
	for(i = 0; i < 16; i++) {

		// Функция управления контроллером атрибутов
		inregs.h.ah = 0x10;		

		// Подфункция установки цвета рамки
		inregs.h.al = 0x1;	

		// Номер нового цвета рамки
		inregs.h.bh = i;

		int86( 0x10, &inregs, &outregs );

		// Ожидаем нажатия на любую клавишу
		printf("\nДля изменения цвета рамки "
				 "нажмите любую клавишу...");
		getch();
	}
}

Установка всех регистров палитры - подфункция 02h

Функция обеспечивает быстрое заполнение новыми значениями всех регистров палитры и регистра цвета рамки. Новые значения регистров должны быть записаны перед вызовом функции в таблице размером 17 байт, расположенной в оперативной памяти компьютера. Байты 0 - 15 этой таблицы содержат новые значения для регистров палитры, а байт 16 новое значение для регистра цвета рамки.

На входе:

AH

10h

 

AL

02h - установка регистров палитры и регистра цвета рамки

 

ES:DX

Адрес таблицы с новыми значениями регистров

На выходе:

 

Не используются

Управление атрибутом мигания и атрибутом интенсивности - подфункция 03h

Управляет битом D7 байта атрибутов символа (см. главу "Атрибуты символов"):

На входе:

AH

10h

 

AL

03h - управление битом D7 байта атрибутов

 

BL

0 - бит D7 байта атрибутов управляет интенсивностью фона символов (символы не мигают),

1 - бит D7 байта атрибутов управляет миганием символов

На выходе:

 

Не используются

Функция ControlBlinkIntens, представленная листингом 5.4, иллюстрирует использование подфункции 03h для управления атрибутами символов.

Листинг 5.4. Файл CNRBLINK.C


//===========================================================
// void ControlBlinkIntens(unsigneg char  blink)
// Функция управляет назначением бита D7 байта атрибутов 
// символа
// Параметры:
// blink - если параметр функции равен нулю, то бит D7 
// 	будет определять интенсивность фона символа. Если 
// 	параметр равен единице, то бит D7 управляет миганием 
// 	символа
//===========================================================
ControlBlinkIntens(unsigneg char  blink) {

	union REGS   inregs, outregs;

	// Функция управления контроллером атрибутов
	inregs.h.ah = 0x10;

	// Подфункция управления атрибутом мигания/интенсивности
	inregs.h.al = 0x3;

	inregs.h.bl = blink;
	int86( 0x10, &inregs, &outregs );
}

Чтение регистра палитры - подфункция 07h

Функция поддерживается только видеоадаптерами VGA и SVGA. Она позволяет прочитать содержимое любого регистра палитры:

На входе:

AH

10h

 

AL

07h - чтение регистра палитры

 

BL

Номер регистра палитры (0-15)

На выходе:

BH

Значение указанного регистра палитры


mov	ah,10h
mov	al,7h
mov	bl,num_reg
int	10h

mov	reg_value,bh

Чтение регистра цвета рамки - подфункция 08h

Функция поддерживается только видеоадаптерами VGA и SVGA. Позволяет прочитать содержимое регистра цвета рамки:

На входе:

AH

10h

 

AL

08h - чтение регистра цвета рамки

На выходе:

BH

Значение регистра цвета рамки

Чтение всех регистров палитры - подфункция 09h

Функция позволяет прочитать значения всех регистров палитры и регистра цвета рамки. Для чтения регистров надо зарезервировать буфер в оперативной памяти размером 17 байт. После вызова функции байты 0 - 15 этого буфера будут содержать значения соответствующих регистров палитры, а байт 16 - значение регистра цвета рамки.

На входе:

AH

10h

 

AL

9 - чтение всех регистров палитры

 

ES:DX

Указатель на буфер размером 17 байт

На выходе:

ES:DX

Указатель на буфер, заполненный значениями из регистров палитры и регистра цвета рамки

Приведем фрагмент программы, который считывает значения всех регистров палитры и регистра цвета рамки в буфер памяти buffer:


; Определяем адрес буфера для записи значений регистров 
; палитры и регистра цвета рамки	

mov	ax,SEG buffer
mov	es,ax
mov	dx,OFFSET buffer    

; Считываем значения всех регистров палитры и регистра
; цвета рамки

mov	ah,10h
mov	al,9				
int	10h

Установка регистра таблицы цветов (регистров ЦАП) - подфункция 10h

Функция производит запись 18-битной величины в один из 256 регистров таблицы цветов:

На входе:

AH

10h

 

AL

10h - установка регистра таблицы цветов

 

BX

Номер регистра таблицы цветов (0-255)

 

DH

Интенсивность красного цвета (6 бит)

 

CH

Интенсивность зеленого цвета (6 бит)

 

CL

Интенсивность синего цвета (6 бит)

На выходе:

 

Не используются

Пример использования функции установки одного регистра таблицы цветов приведен ниже:


mov	ah,10h

; Выбираем функцию установки регистра цветов
mov	al,ah

; Устанавливаем номер регистра таблицы цветов
mov	bx,num_reg

; Определяем величины красной, зеленой и синей составляющих
mov	dh,red
mov	ch,green
mov	cl,blue

int	10h

Установка нескольких регистров таблицы цветов (регистров ЦАП) - подфункция 12h

Функция производит запись 18-битной величины в несколько последовательно расположенных регистров таблицы цветов:

На входе:

AH

10h

 

AL

12h - установка нескольких регистров таблицы цветов

 

BX

Номер первого регистра таблицы цветов (0-255)

 

CX

Количество регистров для записи (1-256)

 

ES:DX

Адрес таблицы цветов

На выходе:

 

Не используются

Таблица цветов содержит по три байта на один регистр таблицы цветов. В каждом байте значимыми являются только 6 младших бит.

Выбор подмножества цветов - подфункция 13h ???

Функция предназначена для выбора числа подмножеств цветов и выбора активного подмножества:

На входе:

AH

10h

 

AL

13h - выбор подмножества цветов

 

BL

0 - выбор режима

 

BH

0 - 4 подмножества из 64 цветов

1 - 16 подмножеств из 16 цветов

 

BL

1 - выбор активного подмножества

 

BH

Номер подмножества (0-4 или 0-15)

На выходе:

 

Не используются

Приведем фрагмент программы использующий данную функцию:


; Выбираем режим (bh = 1)
mov	ah,10h
mov	al,13h
xor	bx,bx
inc	bh
int	10h

; Устанавливаем активное подмножество subset_num
mov	ah,10h
mov	al,13h
mov	bl,1
mov	bh,subset_num
int	10h

Чтение регистра таблицы цветов - подфункция 15h

Функция поддерживается только для видеоадаптеров VGA и SVGA. Она выполняет чтение одного из регистров таблицы цветов:

На входе:

AH

10h

 

AL

15h - чтение регистра таблицы цветов

 

BL

Номер регистра (0-255)

На выходе:

DH

Интенсивность красного цвета (6 бит)

 

CH

Интенсивность зеленого цвета (6 бит)

 

CL

Интенсивность синего цвета (6 бит)

Следующий пример позволяет считать значение регистра таблицы цветов с номером num_color_reg:


mov	ah,10h
mov	al,15h
mov	bx,num_color_reg
int	10h
mov	red_data,dh
mov	green_data,ch
mov	blue_data,cl

Чтение нескольких регистров таблицы цветов (регистров ЦАП) - подфункция 17h

Функция производит чтение 18-битовых значений из нескольких последовательно расположенных регистров таблицы цветов:

На входе:

AH

10h

 

AL

17h - чтение нескольких регистров таблицы цветов

 

BL

Номер первого регистра таблицы цветов (0 -255)

 

CX

Количество регистров для чтения (1-256)

 

ES:DX

Адрес буфера для таблицы цветов

На выходе:

ES:DX

Данные прочитанные из таблицы цветов

Таблица цветов содержит по три байта на один регистр таблицы цветов. В каждом байте значащими являются только младшие 6 бит.

Определение режима подмножества цветов - подфункция 1Ah ???

Возвращает количество текущих цветовых подмножеств:

На входе:

AH

10h

 

AL

1Ah - определение числа цветовых подмножеств

На выходе:

BL

0 - используются 4 цветовых подмножества по 64 цвета;

1 - используются 16 цветовых подмножеств по 16 цветов

 

BH

Номер подмножества, используемого в данный момент


mov	ah,10h
mov	al,1ah
int	10h
mov	num_subset,bh

Установка палитры из градаций серого цвета - подфункция 1Bh

Функция заполняет часть таблицы цветов значениями, соответствующими различным оттенкам серого цвета. Для каждого модифицируемого регистра таблицы цветов сначала читаются записанные в нем данные, а затем записываются обратно по следующему правилу: красного 30 - процентов, зеленого - 59 процентов и голубого - 11 процентов от считанного значения.

На входе:

AH

10h

 

AL

1Bh - установка палитры из градаций серого цвета

 

BX

Номер первого регистра таблицы цветов

 

CX

Количество модифицируемых регистров

На выходе:

 

Не используются

Следующий пример демонстрирует, как преобразовать таблицу цветов для отображения различных градаций серого цвета. Модифицируются значения регистров таблицы цветов, имеющих номера от first_num до end_num:


mov	ah,10h
mov	al,1Bh

; Номер первого модифицируемого регистра
mov	bx,first_num 

; Номер последнего модифицируемого регистра
mov	cx,end_num

; Определяем число изменяемых регистров
sub	cx,bx
int	10h

Программа BIOSDAC демонстрирует использование функций BIOS для управления таблицей цветов. Исходный текст программы BIOSDAC представлен на листинге 5.5.

Листинг 5.5. Файл BIOSDAC.C


#include <conio.h>
#include <stdio.h>
#include <dos.h>
#include "sysp.h"

typedef struct _RGB_ {
	unsigned char red;
	unsigned char green;
	unsigned char blue;
} RGB;

// Объявление функций
void	main(void);
void	SetVideoMode(unsigned char);
void	SetVgaDAC(unsigned, unsigned);
void	GrayScale(void);

//======================================================
// Главная функция
//======================================================
void main(void)
{
	RGB color_table[256];
	unsigned char   i,j;
	unsigned char   far *ptr;
	int error, x_num, y_num;
	unsigned seg_table,off_table;

	// Формируем новые значения для таблицы цветов
	for(j = 0; j < 4; j++) {
		for(i = 0; i < 64; i++) {
			(color_table[i+j*64]).red =
				(j == 0) ? i : (j == 4) ? i : 0;

			(color_table[i+j*64]).green = 
				(j == 1) ? i : (j == 3) ? i : (j == 4) ? i : 0;

			(color_table[i+j*64]).blue = 
				(j == 2) ? i : (j == 3) ? i : (j == 4) ? i : 0;
		}
	}

	// Устанавливаем режим номер 13h
	SetVideoMode(0x13);

	ptr = (unsigned char far*) &color_table[0];
	seg_table = FP_SEG(ptr);
	off_table = FP_OFF(ptr);

	// Загружаем таблицу цветов
	SetVgaDAC(seg_table,off_table);

	// Записываем данные в видеопамять
	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();

	// Преобразовываем данные в таблице цветов к серому цвету
	GrayScale();

	// Ожидаем нажатие на клавишу клавиатуры
	getch();

	// Устанавливаем текстовый режим
	SetVideoMode(0x3);
}

//======================================================
// Функция установки режима
//======================================================
void SetVideoMode( unsigned char vmode ) {

	union REGS regs;

	regs.h.ah = 0x0;
	regs.h.al = vmode;

	int86(0x10, &regs, &regs);
}

//======================================================
// Функция загрузки таблицы цветов
//======================================================
void SetVgaDAC(unsigned seg_table, unsigned off_table) {

	union REGS regs;
	struct SREGS segregs;

	regs.x.ax = 0x1012;
	regs.x.cx = 256;
	regs.x.bx = 0x00;

	segregs.es = seg_table;
	regs.x.dx = off_table;

	int86x(0x10, &regs, &regs, &segregs);
}

//======================================================
// Функция преобразования таблицы цветов в серый цвет
//======================================================
void GrayScale( void ) {

	union REGS regs;

	regs.x.ax = 0x101b;
	regs.x.cx = 256;
	regs.x.bx = 0x00;

	int86(0x10, &regs, &regs);
}
[Назад] [Содеожание] [Дальше]