Программирование видеоадаптеров.© Александр Фролов, Григорий ФроловТом 21, М.: Диалог-МИФИ, 1993. Управление регистрами палитры - функция 10hФункция 10h предоставляет возможность программирования регистров цветовой палитры, таблицы цветов (для видеоадаптеров VGA и SVGA), а также управляет некоторыми атрибутами символов. Вы можете использовать эту функцию и в текстовых и в графических режимах. Для видеоадаптера EGA эта функция содержит четыре подфункции:
Видеоадаптеры VGA и SVGA дополнительно поддерживают еще 10 подфункций:
Установка регистра палитры - подфункция 00hФункция выполняет запись в регистр палитры контроллера атрибутов:
Следующий фрагмент записывает в регистр палитры с номером reg_num содержимое переменной data: mov ah,10h ; Функция 10h xor al,al ; Подфункция 0h mov bl,num_reg ; Задаем номер регистра палитры mov bh,data ; Новое значение регистра int 10h Установка цвета рамки - подфункция 01hФункция выполняет запись значения в регистр цвета рамки контроллера атрибутов. Надо иметь в виду, что эта функция не работает в некоторых режимах видеоадаптера EGA.
Программа 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 новое значение для регистра цвета рамки.
Управление атрибутом мигания и атрибутом интенсивности - подфункция 03hУправляет битом 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. Она позволяет прочитать содержимое любого регистра палитры:
mov ah,10h mov al,7h mov bl,num_reg int 10h mov reg_value,bh Чтение регистра цвета рамки - подфункция 08hФункция поддерживается только видеоадаптерами VGA и SVGA. Позволяет прочитать содержимое регистра цвета рамки:
Чтение всех регистров палитры - подфункция 09hФункция позволяет прочитать значения всех регистров палитры и регистра цвета рамки. Для чтения регистров надо зарезервировать буфер в оперативной памяти размером 17 байт. После вызова функции байты 0 - 15 этого буфера будут содержать значения соответствующих регистров палитры, а байт 16 - значение регистра цвета рамки.
Приведем фрагмент программы, который считывает значения всех регистров палитры и регистра цвета рамки в буфер памяти buffer: ; Определяем адрес буфера для записи значений регистров ; палитры и регистра цвета рамки mov ax,SEG buffer mov es,ax mov dx,OFFSET buffer ; Считываем значения всех регистров палитры и регистра ; цвета рамки mov ah,10h mov al,9 int 10h Установка регистра таблицы цветов (регистров ЦАП) - подфункция 10hФункция производит запись 18-битной величины в один из 256 регистров таблицы цветов:
Пример использования функции установки одного регистра таблицы цветов приведен ниже: mov ah,10h ; Выбираем функцию установки регистра цветов mov al,ah ; Устанавливаем номер регистра таблицы цветов mov bx,num_reg ; Определяем величины красной, зеленой и синей составляющих mov dh,red mov ch,green mov cl,blue int 10h Установка нескольких регистров таблицы цветов (регистров ЦАП) - подфункция 12hФункция производит запись 18-битной величины в несколько последовательно расположенных регистров таблицы цветов:
Таблица цветов содержит по три байта на один регистр таблицы цветов. В каждом байте значимыми являются только 6 младших бит. Выбор подмножества цветов - подфункция 13h ???Функция предназначена для выбора числа подмножеств цветов и выбора активного подмножества:
Приведем фрагмент программы использующий данную функцию: ; Выбираем режим (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. Она выполняет чтение одного из регистров таблицы цветов:
Следующий пример позволяет считать значение регистра таблицы цветов с номером 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-битовых значений из нескольких последовательно расположенных регистров таблицы цветов:
Таблица цветов содержит по три байта на один регистр таблицы цветов. В каждом байте значащими являются только младшие 6 бит. Определение режима подмножества цветов - подфункция 1Ah ???Возвращает количество текущих цветовых подмножеств:
mov ah,10h mov al,1ah int 10h mov num_subset,bh Установка палитры из градаций серого цвета - подфункция 1BhФункция заполняет часть таблицы цветов значениями, соответствующими различным оттенкам серого цвета. Для каждого модифицируемого регистра таблицы цветов сначала читаются записанные в нем данные, а затем записываются обратно по следующему правилу: красного 30 - процентов, зеленого - 59 процентов и голубого - 11 процентов от считанного значения.
Следующий пример демонстрирует, как преобразовать таблицу цветов для отображения различных градаций серого цвета. Модифицируются значения регистров таблицы цветов, имеющих номера от 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, ®s, ®s); } //====================================================== // Функция загрузки таблицы цветов //====================================================== 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, ®s, ®s, &segregs); } //====================================================== // Функция преобразования таблицы цветов в серый цвет //====================================================== void GrayScale( void ) { union REGS regs; regs.x.ax = 0x101b; regs.x.cx = 256; regs.x.bx = 0x00; int86(0x10, ®s, ®s); } |