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

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

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

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

Видеопамять

Видеоадаптеры EGA и VGA содержат на своей плате до 256 Кбайт оперативной памяти, разделенной на четыре банка или, другими словами, на четыре цветовых слоя. Эти слои памяти размещаются в одном адресном пространстве. Таким образом, что по каждому адресу расположено четыре байта (по байту в каждом слое памяти). Какой из слоев памяти используется для записи или чтения данных процессором, определяется с помощью установки нескольких регистров адаптера.

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

Для операции чтения в каждый момент времени может быть разрешен только один цветовой слой. Читаемый слой определяется регистром выбора читаемого цветового слоя.

В большинстве режимов видеоадаптеров видеопамять состоит из нескольких страниц. При этом одна из них является активной и отображается на экране. Переключать активные страницы видеопамяти можно при помощи функций BIOS или путем непосредственного программирования регистров видеоадаптера.

Информацию можно записывать как в активную, так и в неактивные страницы памяти. Таким образом, можно заранее подготовить несколько страниц памяти (несколько экранов), а затем быстро сменять их на экране монитора.

Видеоадаптер SVGA обычно содержит значительно больше памяти и ее структура может быть сложнее, чем у адаптеров EGA и VGA. Однако при работе видеоадаптера в стандартных режимах можно считать что архитектура видеопамяти SVGA полностью соответствует VGA.

Организация видеопамяти адаптеров SVGA, для режимов с высоким разрешением и большим количеством одновременно отображаемых цветов значительно отличается от организации видеопамяти адаптеров EGA и VGA в стандартных режимах работы. Мы посвятили видеоадаптерам SVGA, в том числе организации видеопамяти, отдельную главу "Видеоадаптеры SVGA".

Текстовый режим

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

Стандартные текстовые режимы работы видеоадаптеров позволяют вывести на экран 25 строк по 40 или 80 символов. Если перепрограммировать некоторые регистры видеоадаптера, то можно увеличить число отображаемых строк для адаптера EGA до 43, а для VGA до 50. Если в компьютере установлен видеоадаптер SVGA, вам могут быть доступны другие текстовые режимы - 80x60, 132x25, 132x43, 132x50, 132x60 символов.

Для кодирования каждого знакоместа экрана (символа) используются два байта. Первый из них содержит ASCII-код отображаемого символа, а второй - атрибуты символа (рис. 3.3). Атрибуты символа определяют его цвет и цвет фона.

Рисунок 3.3 Структура видеопамяти в текстовых режимах

ASCII-коды символов экрана располагаются в нулевом цветовом слое, а их атрибуты - в первом цветовом слое. Благодаря такому режиму хранения информации достигается значительная экономия памяти. При отображении символа на экране происходит преобразование его из формата ASCII в двумерный массив пикселов, выводимых на экран. Для этого преобразования используется таблица трансляции символов (таблица знакогенератора). Таблица знакогенератора хранится во втором слое видеопамяти (рис. 3.4).

<

Рисунок 3.4 Преобразование кода ASCII в образ символа на экране

При непосредственном доступе к видеопамяти нулевой и первый цветовые слои отображаются на общее адресное пространство. При этом происходит чередование байтов из нулевого и первого слоев. Коды символов имеют четные адреса, а их атрибуты - нечетные (рис. 3.5).

Рисунок 3.5 Отображение цветовых слоев

Ниже приведен дамп видеопамяти в текстовом режиме с разрешением 80х25 символов:


Адрес           0  1   2   3  4   5   6   7  8   9   A  B   C   D  E  F    0123456789ABCDEF
-----------------------------------------------------------------------------
B800:0000  91 07 E2 07 E0 07 AE 07-AA 07 A0 07 20 07 AD 07   С.т.р.о.к.а. .н.
B800:0010  AE 07 AC 07 A5 07 E0 07-20 07 30 07 20 07 20 07   о.м.е.р. .0. . .
B800:0020  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:0030  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:0040  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:0050  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:0060  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:0070  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:0080  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:0090  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .

B800:00A0  91 07 E2 07 E0 07 AE 07-AA 07 A0 07 20 07 AD 07   С.т.р.о.к.а. .н.
B800:00B0  AE 07 AC 07 A5 07 E0 07-20 07 31 07 20 07 20 07   о.м.е.р. .1. . .
B800:00C0  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:00D0  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:00E0  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:00F0  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:0100  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:0110  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:0120  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .
B800:0130  20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07    . . . . . . . .

Байты кодов символов из нулевого цветового слоя видеопамяти чередуются с байтами атрибутов символов из первого цветового слоя. Байты кодов символов расположены по четным адресам, а байты атрибутов, которые для данного участка видеопамяти имеют значение 07h - по нечетным.

Знакогенератор

При установке текстовых режимов работы видеоадаптеров BIOS загружает таблицы знакогенератора из ПЗУ во второй цветовой слой видеопамяти. Впоследствии эти таблицы используются для отображения символов на экране монитора.

Благодаря этому, можно легко заменить стандартную таблицу знакогенератора своей собственной. Эта особенность, широко применяется при русификации компьютеров. У видеоадаптера CGA таблицы знакогенератора расположены в ПЗУ, поэтому изменить образы символов текстового режима нельзя.

Видеоадаптеры обеспечивают возможность одновременной загрузки в видеопамять нескольких различных таблиц знакогенератора. Видеоадаптер EGA позволяет загрузить четыре таблицы, а видеоадаптеры VGA и SVGA - восемь.

Каждая такая таблица знакогенератора содержит описание 256 символов. Активными могут быть одна или две таблицы знакогенератора. Это дает возможность одновременно отображать на экране до 512 различных символов.

Один бит из байта атрибутов указывает, какая из двух активных таблиц знакогенератора используется при отображении данного символа. Номера активных таблиц знакогенератора определяются регистром выбора знакогенератора. Этот регистр будет описан ниже.

Рисунок 3.6 иллюстрирует использование двух таблиц знакогенератора. В верхней части рисунка символ, имеющий код ASCII 31h, отображается на экране при помощи первой таблицы знакогенератора. В нижней части рисунка символ с тем же кодом ASCII отображается при помощи третей таблицы знакогенератора, и имеет другую форму.

Рисунок 3.6 Активные таблицы знакогенераторов

Видеоадаптер EGA поддерживает два размера для матриц символов - стандартный и улучшенный. Стандартный размер составляет 8 пикселов в ширину и 8 пикселов в высоту, а улучшенный - 8 пикселов в ширину и 14 пикселов в высоту. Один из этих наборов символов автоматически загружается BIOS в видеопамять при выборе текстового режима. Так как адаптеры VGA и SVGA имеют большую разрешающую способность, то их набор символов имеет в ширину 9 пикселов, а в высоту - 16.

Адреса таблиц знакогенератора для видеоадаптеров EGA, VGA и SVGA приведены в следующей таблице:

Первая таблица знакогенератора

Вторая таблица знакогенератора

Символ ASCII 0 0000h-001Fh

Символ ASCII 0 2000h-201Fh

Символ ASCII 1 0020h-003Fh

Символ ASCII 1 2020h-203Fh

Символ ASCII 2 0040h-005Fh

Символ ASCII 2 2040h-205Fh

... ...

... ...

Символ ASCII 255 1FE0h-1FFFh

Символ ASCII 255 3FE0h-3FFFh

Третья таблица знакогенератора

Четвертая таблица знакогенератора

Символ ASCII 0 4000h-401Fh

Символ ASCII 0 6000h-601Fh

Символ ASCII 1 4020h-403Fh

Символ ASCII 1 6020h-603Fh

Символ ASCII 2 4040h-405Fh

Символ ASCII 2 6040h-605Fh

... ...

... ...

Символ ASCII 255 5FE0h-1FFFh

Символ ASCII 255 7FE0h-7FFFh

Пятая таблица знакогенератора (только VGA)

Шестая таблица знакогенератора (только VGA)

Символ ASCII 0 8000h-801Fh

Символ ASCII 0 A000h-A01Fh

Символ ASCII 1 8020h-803Fh

Символ ASCII 1 A020h-A03Fh

Символ ASCII 2 8040h-805Fh

Символ ASCII 2 A040h-A05Fh

... ...

... ...

Символ ASCII 255 9FE0h-9FFFh

Символ ASCII 255 BFE0h-BFFFh

Седьмая таблица знакогенератора (только VGA)

Восьмая таблица знакогенератора (только VGA)

Символ ASCII 0 C000h-C01Fh

Символ ASCII 0 E000h-E01Fh

Символ ASCII 1 C020h-C03Fh

Символ ASCII 1 E020h-E03Fh

Символ ASCII 2 C040h-C05Fh

Символ ASCII 2 E040h-E05Fh

... ...

... ...

Символ ASCII 255 DFE0h-DFFFh

Символ ASCII 255 FFE0h-FFFFh

Как видно из этой таблицы, на каждый символ отводится 32 байта. Самый простой способ загрузки собственных таблиц знакогенератора во второй слой видеопамяти заключается в использовании функций BIOS. Мы продемонстрируем его позже в главе "Русификация видеоадаптера".

Атрибуты символов

Внешний вид символа, отображаемого на экране в текстовом режиме, определяется не только его кодом ASCII, но и байтом атрибутов. Атрибуты задают цвет символа, цвет фона, а также некоторые другие параметры:

Биты байта

атрибутов

Назначение

D2-D0

Цвет символа

D3

Интенсивность символа и выбор таблицы знакогенератора

D6-D4

Цвет фона символа

D7

Мигание символа или интенсивность фона символа

Биты D0-D2 байта атрибутов определяют цвет символа, а биты D4-D6 цвет фона, на котором отображается символ. Таким образом, можно независимо задавать до 23 = 8 различных цветов для текста и фона.

Бит D3 играет различную роль в зависимости от числа активных таблиц знакогенератора. Если активной является одна таблица, бит D3 используется для управления интенсивностью цвета символа, что позволяет увеличить количество воспроизводимых цветов от 8 до 16.

Если одновременно определены две таблицы знакогенератора, то бит D3 также задает таблицу знакогенератора, которая будет использована при отображении данного символа.

Бит D7 выполняет две различные функции в зависимости от состояния регистра режима контроллера атрибутов. Данный бит управляет либо интенсивностью цвета фона, увеличивая количество одновременно отображаемых цветов до 16, либо разрешением гашения символа, в результате чего символ на экране монитора будет мигать. По умолчанию D7 бит управляет разрешением гашения символа (миганием).

В следующей таблице представлено соответствие цвета символа и цвета фона значению поля цвета символа байта атрибутов:

Код цвета в байте атрибутов

Стандартный цвет

Цвет с повышенной интенсивностью

000

Черный

Серый

001

Синий

Светло-синий

010

Зеленый

Светло-зеленый

011

Морской волны

Голубой

100

Красный

Светло-красный

101

Фиолетовый

Малиновый

110

Коричневый

Желтый

111

Белый

Ярко-белый

Атрибуты символов (монохромный режим)

Назначение полей байта атрибутов в монохромном режиме сходно с их назначениями в цветном режиме (см. выше). Биты D0-D2 управляют типом символа, который может быть обычным, мигающим или подчеркнутым, биты D4-D6 могут выбрать обратный (инвертированный) символ.

Бит D3 играет различную роль в зависимости от того, сколько таблиц знакогенератора одновременно являются активными. Если активной является одна таблица, то бит D3 используется для управления интенсивностью символа.

Если одновременно определены две таблицы знакогенератора, тогда бит D3 также задает таблицу знакогенератора, которая будет использована при отображении данного символа.

Бит D7 выполняет две различные функции в зависимости от состояния регистра режима контроллера атрибутов. Он управляет либо интенсивностью фона, либо миганием символа. По умолчанию бит D7 управляет миганием символа.

Перечислим все возможные значения атрибутов символов в текстовом монохромном режиме:

Атрибут

Внешний вид символа

00000000b (00h)

Черный символ на черном фоне

00000001b (01h)

Подчеркнутый символ

00000111b (07h)

Обычный символ (светлый символ на черном фоне)

00001001b (09h)

Подчеркнутый символ с повышенной интенсивностью

00001111b (0Fh)

Символ с повышенной интенсивностью

01110000b (70h)

Обратное отображение символа (черный символ на светлом фоне)

10000001b (81h)

Подчеркнутый мигающий символ

10000111b (87h)

Мигающий символ

10001001b (89h)

Подчеркнутый мигающий символ с повышенной интенсивностью

11110000b (0F0h)

Мигающее обратное отображение символа

В случае использования других значений атрибутов результат зависит от конкретной модели видеоадаптера.

Теперь приведем программу TEXTATTR (листинг 3.1), иллюстрирующую непосредственный доступ к видеопамяти в текстовых режимах работы адаптера. При запуске программы TEXTATTR вы должны указать ей два числовых параметра.

Первый параметр определяет режим работы видеоадаптера. Вы можете задать любой текстовый режим. Второй параметр управляет атрибутами символов, отображаемых на экране монитора. Если второй параметр равен 0, то бит D7 байта атрибутов управляет интенсивностью фона символов, а если он равен 1, то бит D7 байта атрибутов управляет миганием символов.

Листинг 3.1. Файл TEXTATTR.C


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

// Файл для определения макрокоманды FP_MAKE 
#include	"sysp.h"

// Файл для определения структуры VIDEOBUF
#include	"sysgraph.h"

// Описание функций
void	SetVideoMode( unsigned char vmode );
void	SetBlinkIntensity( unsigned char mode );
int	GetColumn(void);
int	GetVideoBuf(int);
void	Hello(void);
int	main( int, char ** );

//======================================================
// Главная функция программы
//======================================================
int main( int argc, char * argv[] )
{
	union REGS	inregs, outregs;
	VIDEOBUF	_far *vbuf, _far *ptr_vbuf;

	unsigned char	background, foreground;
	unsigned char	char_attr;

	int	vmode, bl_in_mode;
	char	szText[4];

	// Проверка командной строки программы
	if( argc != 3 )
	{
		Hello();
		return -1;
	}

	// Разбор строки параметров
	sscanf(argv[1],"%d",&vmode);
	sscanf(argv[2],"%d",&bl_in_mode);

	// Если указан графический режим, завершаем программу
	if(vmode > 3 && vmode != 7)
		return(-2);

	// Если неправильно указан параметр <интенсивность>, 
	// завершаем программу
	if((bl_in_mode != 0)&&(bl_in_mode != 1))
		return(-3);

	// Устанавливаем новый режим работы видеоадаптера, 
	// указанный параметром <режим>
	SetVideoMode((unsigned char) vmode );

	// Выбираем как будут интерпритироваться атрибуты 
	// символов. Если параметр <интенсивность> равен 0 
	// атрибуты управляют интенсивностью цвета символов, 
	// если параметр равен 1 атрибуты управляют миганием 
	//символов
	SetBlinkIntensity((unsigned char) bl_in_mode );

	// Определяем адрес начала активной страницы 
	// видеопамяти
	ptr_vbuf = vbuf= (VIDEOBUF _far *) 
		FP_MAKE(GetVideoBuf((unsigned char) vmode ),0);

	// Отображаем на экране массив символов, имеющих 
	// различные атрибуты
	for( background=0; background<16; background++)
	{
		for( foreground=0; foreground<16; foreground++)
		{
			char_attr = 
					(unsigned char)((background<<4) | foreground);

			sprintf( szText, "%02X", char_attr );

			// Отображаем на экране символ. Записываем 
			// в видеопамять код символа и его атрибут
			ptr_vbuf->chr = 
				szText[0];	ptr_vbuf->attr = char_attr;

			ptr_vbuf++;

			ptr_vbuf->chr = 
				szText[1]; ptr_vbuf->attr = char_attr;

			ptr_vbuf++;
		}
		ptr_vbuf = vbuf = vbuf + GetColumn();
	}

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

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

	return 0;
}

//======================================================
// Функция возвращает сегментный адрес активной страницы
// видеопамяти (учитывается значение регистров смещения 
// адреса видеопамяти)
//======================================================
int GetVideoBuf(int vmode) {

	unsigned vbase;
	unsigned adr_CRT;
	unsigned high;
	unsigned low;
	unsigned offs;

	// В зависимости от режима видеоадаптера базовый адрес
	// видеопамяти может быть 0xb000 или 0xb800
	vbase = (vmode == 7) ? 0xb000 : 0xb800;

	// Определяем адрес порта контроллера ЭЛТ
	adr_CRT = *(unsigned _far *)(FP_MAKE(0x40,0x63));

	// Считываем содержимое регистров начального адреса
	outp(adr_CRT,0xc);
	high = inp(adr_CRT+1);

	outp(adr_CRT,0xd);
	low = inp(adr_CRT+1);

	offs = ((high << 8) + low) >> 4;

	// Добавляем к базовому адресу видеопамяти смещение,
	// взятое из регистров начального адреса 
	vbase += offs;

	return(vbase);
}

//======================================================
// Функция возвращает количество символов в строке
//======================================================
int GetColumn(void) {

	// Считываем содержимое переменной BIOS, расположенной по
	// адресу 0000:044Ah. В ней записано количество символов
	// в строке для текущего режима
	return(*(int _far *)(FP_MAKE(0x40,0x4a)));
}

//======================================================
// Функция устанавливает режим работы видеоадаптера, заданный
// параметром vmode
//======================================================
void SetVideoMode( unsigned char vmode ) {

	union  REGS    inregs, outregs;

	// Устанавливаем режим vmode
	inregs.h.ah = 0x0;
	inregs.h.al = vmode;
	int86( 0x10, &inregs, &outregs );
}

//======================================================
// Функция управляет назначением атрибутов символов.
//  mode = 0 атрибут управляет интенсивностью цвета символов
//  mode = 1 атрибут управляет миганием символов
//======================================================
void SetBlinkIntensity( unsigned char mode ) {

	union  REGS    inregs, outregs;

	inregs.h.ah = 0x10;
	inregs.h.al = 0x3;
	inregs.h.bl = mode;
	int86( 0x10, &inregs, &outregs );
}

//======================================================
// Функция выводит на экран краткую справку о программе
//======================================================
void Hello(void) {

	printf(	"\nCopyright (C)Frolov G.V.,1995. E-mail:" 
				"frolov@glas.apc.org\n"
			"\nФормат вызова: TEXTATTR <режим> <интенсивность>"
			"\n   <режим>: любые текстовые режимы"
			"\n   <интенсивность>: 0 - интенсивность цвета, "
			"1 - мигание символа" );
}

Исходный текст включаемого файла SYSP.H, который используется в примере TEXTATTR.C, а также в других примерах книги, представлен в листинге 3.2. Файл SYSP.H содержит определение макрокоманды FP_MAKE, служащей для получения дальнего указателя из сегмента и смещения.

Листинг 3.2. Файл SYSP.H


// Макрокоманда FP_MAKE составляет дальний указатель 
// из сегмента и смещения
#define FP_MAKE(seg,off) ((void far *)			\
	((((unsigned long) (unsigned)(seg)) << 16L) |	\
	((unsigned long) (unsigned) (off))))

Включаемый файл SYSGRAPH.H содержит определения нескольких типов структур, используемых в примерах нашей книги. Исходный текст файла SYSGRAPH.H представлен в листинге 3.3.

Листинг 3.2. Файл SYSGRAPH.H


#pragma pack(1)

// Структура для определения символа и его атрибута
typedef struct _VIDEOBUF_ {
	unsigned char chr;
	unsigned char attr;
} VIDEOBUF;

// Структура для доступа к переменным видеофункций BIOS
typedef struct _BIOS_VAR_ {
	unsigned char  bEquipFlags;
	unsigned char  bReserv1[0x38];
	unsigned char  bVideoMode;
	unsigned       wColumns;
	unsigned       wPageLength;
	unsigned       wVidStart;
	unsigned       w8CursorPos[8];
	unsigned       wCursorShape;
	unsigned char  bActivePage;
	unsigned       wAddrCRT;
	unsigned char  bRegMode;
	unsigned char  bRegPalette;
	unsigned char  bReserv2[0x1D];
	unsigned char  bRows;
	unsigned       wCharHigh;
	unsigned char  bInfo;
	unsigned char  bInfoTwo;
	unsigned char  bReserv3[0x1F];
	void far       dwSavePtr;
} BIOS_VAR;

// Структура для заполнения таблицы цветов (таблицы ЦАП)
typedef struct _RGB_ {
	unsigned char red;
	unsigned char green;
	unsigned char blue;
} RGB;

#pragma pack()

Видеопамять в графических режимах

Структура видеопамяти в графических режимах работы видеоадаптеров отличается от структуры видеопамяти в текстовых режимах. Если вы желаете в дальнейшем изучить программирование видеоадаптеров на уровне регистров, то вам необходимо полное понимание структуры видеопамяти.

Ниже рассмотрена структура видеопамяти отдельно для каждого графического режима.

Режимы 4 и 5

Это режимы низкого разрешения - 320х200 пикселов. Используются 4 цвета. Режимы поддерживаются видеоадаптерами CGA, EGA, VGA и SVGA. У адаптеров EGA, VGA и SVGA видеоданные расположены в нулевом цветовом слое. Остальные три слоя не используются.

Для совместимости с видеоадаптером CGA, отображение видеопамяти на экран не является непрерывным. Первая половина видеопамяти (начальный адрес B800:0000h) содержит данные обо всех нечетных линиях экрана, а вторая половина (начальный адрес B800:2000h) - относительно всех четных линий. Каждому пикселу изображения соответствуют два бита видеопамяти. За верхний левый пиксел экрана отвечают биты D7 и D6 нулевого байта видеопамяти. На рисунке 3.7 изображено соответствие видеопамяти пикселам экрана.

Рисунок 3.7 Структура видеопамяти для режимов 4 и 5

Если вы желаете выводить информацию на экран монитора непосредственно через видеопамять, то вам необходимо уметь определять биты, которые управляют каждым пикселом изображения. В общем случае по координатам пиксела нужно вычислить адрес байта видеопамяти и номера битов в нем, управляющие данным пикселом.

Следующие формулы позволяют определить смещение байта от начала станицы видеопамяти и номера битов в нем, управляющие пикселом с координатами (x,y):


Если y четное число, то смещение байта = 50h*(y/2)+(x/4)
Если y нечетное число, то смещение байта = 2000h+50h*((y-1)/2)+(x/4)

Номер первого бита = 7-mod(x/4)*2

В режимах 4 и 5 доступны два набора цветов - стандартный и альтернативный. Для выбора набора цветов можно воспользоваться функцией 0Bh прерывания INT 10h. Ниже представлена таблица соответствия значений битов, определяющих пиксел, его цвету:

Значение битов пиксела

Стандартный цвет

Альтернативный цвет

00

Черный

Черный

01

Светло-синий

Зеленый

10

Малиновый

Красный

11

Ярко-белый

Коричневый

Режим 6

Режим 6 (640х200) является режимом наибольшего разрешения для видеоадаптера CGA. В этом режиме видеоадаптеры EGA, VGA и SVGA используют для хранения информации только нулевой слой памяти.

На рисунке 3.8 представлено соответствие видеопамяти и пикселов экрана. Как и в режимах 4 и 5, первая половина видеопамяти содержит данные обо всех нечетных линиях экрана, а вторая половина - обо всех четных линиях.

В режиме 6 на один пиксел отводится один бит видеопамяти. Таким образом, каждый байт видеопамяти управляет восьмью пикселами. Если значение бита видеопамяти, отвечающего за данный пиксел, равно нулю, то пиксел имеет черный цвет, если единице - белый. За верхний левый пиксел экрана отвечает бит D7 в нулевом байте видеопамяти, то есть самый старший его бит.

Рисунок 3.8 Структура видеопамяти в режиме 6

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


Если y четное число, то смещение байта = 50h*(y/2)+(x/8)
Если y нечетное число, то смещение байта = 2000h+50h*((y-1)/2)+(x/8)

Номер бита = 7-mod(x/8)

Эти формулы позволяют определить для пиксела, имеющего координаты (x,y), смещение от начала станицы видеопамяти байта и номер бита в нем, управляющего данным пикселом.

Режимы 0Dh и 0Eh

Разрешающая способность в режиме 0Dh составляет 320 пикселов по горизонтали и 200 пикселов по вертикали, а в режиме 0Eh соответственно 640 и 200 пикселов.

Режимы 0Dh и 0Eh поддерживают только видеоадаптеры EGA и VGA. На рисунке 3.9 представлена структура видеопамяти для этого режима.

Для хранения видеоданных используются все четыре цветовых слоя. Каждому адресу видеопамяти соответствует четыре байта, которые вместе определяют восемь пикселов.

Каждому пикселу соответствует четыре бита - по одному биту из каждого цветового слоя. Четыре бита на пиксел, используемые в данных режимах, позволяют одновременно отображать пикселы 16 различных цветов.

Рисунок 3.9 Структура видеопамяти в режимах 0Dh и 0Eh

Следующие формулы позволяют определить смещение байта от начала станицы видеопамяти и номер бита в нем, управляющего пикселом с координатами (x,y):


Смещение байта = 50h*y+x/8

Номер бита = 7-mod(x/8)

Запись в каждый из четырех слоев видеопамяти можно разрешить или запретить при помощи регистра разрешения записи цветового слоя. Смотри раздел "Регистры видеоадаптеров EGA, VGA и SVGA".

Режим 0Fh

Графический монохромный режим с разрешением 640х350 пикселов. Данный режим поддерживают только видеоадаптеры EGA, VGA и SVGA.

Для хранения видеоданных используются два цветовых слоя - нулевой и первый. Каждому пикселу соответствует по одному биту из нулевого и первого цветовых слоев. Два бита на пиксел позволяют отображать его черным, белым, ярко-белым или мигающим. Запись в каждый из этих двух слоев можно разрешить или запретить при помощи регистра разрешения записи цветового слоя.

На рисунке 3.10 представлена структура видеопамяти для режима 0Fh.

Рисунок 3.10 Структура видеопамяти режима 0Fh

Следующие формулы позволяют определить смещение байта от начала станицы видеопамяти и номер бита в нем, управляющего пикселом с координатами (x,y):


Смещение байта = 50h*y+x/8

Номер бита = 7-mod(x/8)

Режим 10h

Графический цветной режим с разрешением 640х350 пикселов. Данный режим поддерживают только видеоадаптеры EGA, VGA и SVGA.

Для хранения видеоданных используются четыре цветовых слоя. Каждому пикселу соответствует по одному биту из каждого цветового слоя. Четыре бита на пиксел позволяют отображать 16 различных цветов. Запись в каждый из этих четырех слоев можно разрешить или запретить при помощи регистра разрешения записи цветового слоя.

На рисунке 3.11 представлена структура видеопамяти для режима 10h.

Рисунок 3.11 Структура видеопамяти режима 10h

Если вы желаете выводить информацию на экран монитора непосредственно через видеопамять, необходимо уметь определять биты, которые управляют каждым пикселом изображения. Следующие формулы позволяют определить смещение байта от начала станицы видеопамяти и номер бита в нем, управляющего пикселом с координатами (x,y):


Смещение байта = 50h*y+x/8

Номер бита = 7-mod(x/8)

Режим 11h

Графический цветной режим с разрешением 640х480 пикселов. Данный режим поддерживают только видеоадаптеры VGA и SVGA.

Для хранения видеоданных используется нулевой цветовой слой, остальные три слоя не используются. Каждому пикселу соответствует один бит, что позволяет отображать всего два цвета.

На рисунке 3.12 представлена структура видеопамяти для режима 11h.

Рисунок 3.12 Структура видеопамяти режима 11h

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


Смещение байта = 50h*y+x/8

Номер бита = 7-mod(x/8)

Формулы позволяют определить для пиксела, имеющего координаты (x,y), смещение от начала станицы видеопамяти байта и номер бита в нем, управляющего данным пикселом.

Режим 12h

Режим 12h похож на режим 10h, за исключением того, что он имеет большую разрешающую способность - 640х480 пикселов. В видеопамяти задействованы все четыре цветовых слоя. Структура видеопамяти показана на рисунке 3.13.

Рисунок 3.13 Структура видеопамяти режима 12h

Формулы, используемые для вычисления битов, управляющих данным пикселом экрана, соответствуют формулам режима 10h.

Режим 13h

Этот режим, как и режим 12h, поддерживается только видеоадаптерами VGA и SVGA. Он обеспечивает отображение 256 различных цветов при разрешающей способности 320х200 пикселов.

Структура видеопамяти приведена на рисунке 3.14. Как видно из рисунка, в этом режиме видеопамять организована линейно. Каждый пиксел определяется одним байтом.

Рисунок 3.14 Структура видеопамяти в режиме 13h

Следующая формула позволяет определить смещение от начала видеопамяти байта, управляющего пикселом с координатами (x,y):


Смещение байта = 140h*y+x

Графический контроллер

Графический контроллер осуществляет обмен данными между видеопамятью и процессором. Графический контроллер может выполнять над данными, поступающими в видеопамять, простейшие логические операции: И, ИЛИ, ИСКЛЮЧАЮЩЕЕ ИЛИ, операцию циклического сдвига.

Операция записи

При чтении процессором данных из видеопамяти они также запоминаются в регистрах-защелках, расположенных на плате видеоадаптера. Если затем выполняется цикл записи, то над данными, находящимися в этих регистрах, и над данными, поступающими от процессора могут выполняться следующие логические операции:

.   Запись данных процессора в видеопамять без изменения

.   Циклический сдвиг данных, записываемых процессором в видеопамять

.   Выполнение булевой операции И между данными, записываемыми в видеопамять и содержимым регистров-защелок. В видеопамять записывается результат операции

.   Выполнение булевой операции ИЛИ между данными, записываемыми в видеопамять и содержимым регистров-защелок. В видеопамять записывается результат операции

.   Выполнение булевой операции ИСКЛЮЧАЮЩЕЕ ИЛИ между данными, записываемыми в видеопамять и содержимым регистров-защелок. В видеопамять записывается результат операции

Таким образом, видеоадаптер может выполнять часть работы по обработке видеоданных. Рисунок 3.15 иллюстрирует выполнение графическим контроллером операции записи данных в видеопамять:

Рисунок 3.15 Запись данных в видеопамять

Байт, записываемый процессором в видеопамять (на нашем рисунке 11100001b), поступает в графический контроллер. В соответствии со значением регистра циклического сдвига и выбора функции (регистры адаптеров описаны в следующем разделе), происходит циклический сдвиг на один бит содержимого байта, записываемого в видеопамять.

Полученный результат складывается по логике ИЛИ с содержимым регистров-защелок. Какая булева функция используется - ИЛИ, И, ИСКЛЮЧАЮЩЕЕ ИЛИ также определяется регистром циклического сдвига и выбора функции.

Дальнейшие преобразования происходят в соответствии со значениями регистра разрешения установки/сброса и регистра установки/сброса:

.   Если бит регистра разрешения установки/сброса, управляющий данным цветовым слоем, равен нулю, тогда байт, записываемый в видеопамять не изменяется

.   Если бит регистра разрешения установки/сброса, управляющий данным цветовым слоем равен единице, то в видеопамять записывается байт, все биты которого устанавливаются в соответствии со значением регистра установки/сброса для данного цветового слоя

Затем в соответствии с состоянием регистра битовой маски происходит запись данных в видеопамять:

.   Если данный бит регистра битовой маски содержит единицу, то соответствующие биты для каждого из цветовых слоев поступают от центрального процессора

.   Если данный бит регистра битовой маски содержит ноль, то соответствующие биты для каждого из цветовых слоев поступают из регистров-защелок

Центральный процессор может одновременно прочитать данные только из одного цветового слоя, однако запись данных в регистры-защелки происходит из всех четырех цветовых слоев. Эту особенность можно использовать для быстрого копирования областей экрана.

Операция чтения

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

Графический контроллер сравнивает данные из всех четырех цветовых слоев (или из любого подмножества цветовых слоев) с данными в регистре сравнения цветов контроллера, и в случае совпадения вырабатывает определенный сигнал.

Последовательный преобразователь

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

Контроллер атрибутов

Контроллер атрибутов в графических и текстовых режимах работы видеоадаптера управляет цветом элементов изображения. Значениям цветовых атрибутов ставится в соответствие определенный цвет. Для этого используется таблица цветовой палитры (Color Lock-up Table). Таблица цветовой палитры ставит в соответствие четырем битам, взятым из видеопамяти, 6 битов цветовой информации. Изменяя данные, записанные BIOS в таблицу цветовой палитры, можно менять используемую палитру цветов.

Для видеоадаптера EGA эта информация поступает непосредственно на видеовход монитора. Если к видеоадаптеру EGA подключен цветной монитор, то используются только четыре младших бита из шести.

Видеоадаптеры VGA и SVGA выполняют более сложные операции по преобразованию цвета. Данные полученные от таблицы цветовой палитры преобразуются дальше в соответствии с таблицей цветов. В результате получаются три 6 битовых значения, представляющих красный, зеленый и синий компоненты цвета. Эти значения поступают на три цифро-аналоговых преобразователя и уже в аналоговом виде поступают в монитор.

На рисунках 3.16 и 3.17 показана работа контроллера атрибутов в графическом и текстовом режимах.

Рисунок 3.16 Контроллер атрибутов в текстовых режимах

В текстовых режимах видеоадаптеров, цвет символа и цвет фона символа определяется байтом атрибутов. Цвет фона символа задают четыре старших бита байта атрибутов. Значение этих четырех бит служит индексом в таблице цветовой палитры. Элемент таблицы с данным индексом впоследствии определяет цвет фона символа.

Аналогично битам, определяющим цвет фона символа, четыре младших бита задают цвет самого символа.

Рисунок 3.17 Контроллер атрибутов в графических режимах

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

Контроллер атрибутов подробно описан в разделе "Регистры видеоадаптеров EGA и VGA".

Контроллер ЭЛТ

Контроллер ЭЛТ выполняет следующие функции:

.   Вырабатывает сигналы, управляющие работой ЭЛТ (сигналы развертки и гашения)

.   Определяет формат экрана и формат символов текста (разрешающую способность экрана и размер символов)

.   Определяет форму курсора

.   Управляет световым пером

.   Управляет вертикальной сверткой (скроллингом) содержимого экрана

Так как контроллер ЭЛТ выполняет жизненно важные для монитора функции, то изменять содержимое регистров этого контроллера очень опасно. В некоторых случаях может даже произойти физическое повреждение экрана (например, повреждение люминофора).

Регистры контроллера ЭЛТ загружаются BIOS значениями, зависящими от типа монитора, видеоадаптера и текущего режима работы. Мы не рекомендуем вам без особой необходимости изменять содержимое этих регистров. Практически все что необходимо, можно сделать при помощи функций BIOS, не подвергая дорогостоящий видеоадаптер и монитор излишнему риску.

Синхронизатор

Синхронизатор управляет всеми временными параметрами видеоадаптера. С точки зрения программирования, наиболее полезной является функция синхронизатора, управляющая разрешением и запрещением доступа к отдельным цветовым слоям видеопамяти. Рисунок 3.18 иллюстрирует использование функции разрешения записи цветовых слоев.

Рисунок 3.18 Разрешение записи в цветовые слои

Процессор передает видеоадаптеру данные для записи в видеопамять. Они проходят через графический контроллер и попадают в синхронизатор. Графический контроллер выполняет над данными, записываемыми в видеопамять, операции, определяемые состоянием его регистров (смотри главу "Исполнение видеоадаптером операции записи" из раздела "Графический контроллер").

В зависимости от значения регистра разрешения записи цветового слоя синхронизатор может оставить данные в цветовом слое без изменения. Регистр разрешения записи цветового слоя содержит четыре бита, управляющие записью в цветовые слои видеопамяти. Если бит регистра управляющий цветовым слоем равен нулю, то данный цветовой слой не изменяется. Если бит регистра равен единице, то в данный слой видеопамяти записываются значения, поступившие от графического контроллера.

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