Атрибуты символов (монохромный режим)
Назначение полей байта атрибутов в монохромном режиме сходно с их назначениями в цветном режиме (см. выше). Биты 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()
Содержание раздела