Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование видеоадаптеров EGA, VGA и SVGA.doc
Скачиваний:
138
Добавлен:
01.05.2014
Размер:
4.51 Mб
Скачать

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

Внешний вид символа, отображаемого на экране в текстовом режиме, определяется не только его кодом 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()