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

Программирование видеоадаптеров CGA, EGA и VGA

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

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

7.6. Регистры контроллера атрибутов

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

Контроллер атрибутов содержит двадцать один регистр. Регистры перечисленны в таблице 8.17. Доступ к ним осуществляется через один порт - 3C0h (в отличие от предыдущих рассмотренных нами регистров). Этот порт совмещает в себе функции индексного порта и порта данных, регулируемые внутренним триггером. Триггер переключается при каждой операции записи в порт и записываемые данные воспринимаются либо как индекс регистра, либо как данные для обмена с регистром.

Установить триггер в исходное состояние можно, выполнив чтение из порта 3BAh для монохромного режима или из порта 3DAh - для цветного режима работы видеоадаптера. После установки триггера данные, записываемые в регистр 3C0h, будут восприниматься, как индекс регистра.

Индекс Регистры контроллера атрибутов
0 - 0Fh регистры цветовой палитры (0-15) (Color Palette Register's - CPR)
10h регистр управления режимом (Mode Control Register - MCR)
11h регистр цвета рамки экрана (Screen Border Color Register - SBCR)
12h регистр разрешения цветового слоя (Color Plane Enable Register - CPER)
13h регистр горизонтального панорамирования (Horizontal Panning Register - HPR)
14h регистр выбора цвета (Color Select Register - CSR)

Таблица 8.17 Регистры контроллера атрибутов.

Регистры цветовой палитры (0-15)
(Color Palette Register's - CPR)

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

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

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

Другие дисплеи - цветной (CD) и монохромный (MD), имеют меньшее число линий управления и регистр цветовой палитры также имеет другой формат.

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

Улучшенный цветной дисплей.

  • D0 Голубой.
  • D1 Зеленый.
  • D2 Краснй.
  • D3 Второй голубой.
  • D4 Второй зеленый.
  • D5 Второй красный.
  • D7-D6 Не используются.

Цветной дисплей.

  • D0 Голубой.
  • D1 Зеленый.
  • D2 Краснй.
  • D3 Не используется.
  • D4 Интенсивность.
  • D7-D5 Не используются.

Монохромный дисплей.

  • D2-D0 Не используются.
  • D3 Видео выход.
  • D4 Интенсивность.
  • D7-D5 Не используются.

Дисплей VGA.

  • D0 P0
  • D1 P1
  • D2 P2
  • D3 P3
  • D4 P4
  • D5 P5
  • D7-D6 Не используются.

Регистр управления режимом
(Mode Control Register - MCR) (индекс 10h)

Регистр управления режимом управляет контроллером атрибутов.

  • D0 ноль для текствых режимов, единица - для графических. Бит определяет спсособ раскодирования атрибутов.
  • D1 Бит определяет тип атрибутов. Для монохромных атрибутов он должен быть равен единице, а для цветных - нулю.
  • D2 Бит используется в монохромных режимах с разрешением по горизонтали 720 пикселов при расширении матриц символов псевдографики с 8 до 9 пикселов по горизонтали. Если бит равен 1, то девятый пиксел в каждой строке будет повторять восьмой. В противном случае девятый пиксел отображаетя цветом фона.
  • D3 Бит D3 управляет назначением седьмого бита в байте атртбутов. Если бит установлен, то бит D7 байта атрибутов управляет миганием символа. Если бит D3 равен нулю, то - интенсивностью фона.
  • D4 Не используется.
  • D5 Доступен только на VGA. Совместно с регистром разделения экрана дисплея контроллера ЭЛТ бит D5 управляет горизонтальным панорамированием экрана. При установке бита D5 запрещается горизонтальное панорамирование стационарной частью экрана.
  • D6 Доступен только на VGA. Бит должен быть равен нулю для режима видеоадаптера VGA с 256 цветами (режим 13h).
  • D7 Доступен только на VGA. Выбор источника сигнала для видеовыходов Р4 И Р5. Если D7 равен нулю, то линии Р4 и Р5 управляются регистрами палитры, иначе сигналы на Р4 и Р5 поступают из битов D0 и D1 регистра выбора цветов.

По умолчанию регистр содержит следующие значения:

Режим 0,1,2,3 4,5,6,D,E,10 7 F
Содержимое регистра 08 01 0Eh 0Bh

Регистр цвета рамки экрана
(Screen Border Color Register - SBCR) (индекс 11)

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

К сожалению операция установки цвета рамки работает не правильно на большинстве адаптеров EGA.

Регистр разрешения цветового слоя
(Color Plane Enable Register - CPER) (индекс 12)

  • D3-D0 Биты разешения цветовых слоем. Если бит равен нулю, то данные из соответствующего цветвого слоя не поступают в регистры цветовой палитры. Такаим образом достигается эффект маскирования отдельных цветовых слоев.
  • D5-D4 Исполььзуются вместе с диагностическими битами регистра состояния 1 для чтения регистров палитры.
  • D7-D6 Не используются.

При установке режима работы видеоадаптера BIOS записывает в регистр следующие значения:

Режим 0,1,2,3,7,D,E 4,5 6 F,10  
Содержимое регистра 0Fh 03 03 01 05

Регистр горизонтального панорамирования
(Horizontal Panning Register - HPR) (индекс 13)

Регистр позволяет сдвигать в горизонтальном направлении содержимое экрана на один пиксел. При использовании регистра HPR совместно с регистром начального адреса контроллера атрибутов можно производить горизонтальный сдвиг экрана влево на любое число пикселов.

Формат регистра горизонтального панорамирования представлен ниже:

  • D3-D0 Биты задают величину горизонтального сдвига. Соответствие содержимого регистра и величины сдвига для различных режимов приведены в таблице 8.18.
  • D7-D4 Не используются.
D3 D2 D1 D0 Величина сдвига содержимого экрана (в пикселах)
  монохромный текстовый VGA, режим 13h остальные режимы
0 0 0 0 8 0 0
0 0 0 1 0 - 1
0 0 1 0 1 1 2
0 0 1 1 2 - 3
0 1 0 0 3 2 4
0 1 0 1 4 - 5
0 1 1 0 5 3 6
0 1 1 1 6 - 7
1 0 0 0 7 - -
1 0 0 1 - - -
1 0 1 0 - - -
1 0 1 1 - - -
1 1 0 0 - - -
1 1 0 1 - - -
1 1 1 0 - - -
1 1 1 1 - - -

Таблица 8.18 Величина горизонтального сдвига в различных режимах работы видеоадаптера.

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

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

Рисунок 8.16 Горизонтальный сдвиг экрана.

Следующая программа позволяет перемещать содержимое экрана по горизонтали и вертикали. Функции HorScroll и VerScroll реализуют, соответственно, горизонтальный и вертикальный сдвиг экрана.

// смещение содержимого экрана по горизонтали и вертикали

#include "sysgraph.h"
#include <stdio.h>
#include <stdlib.h>
#include <graph.h>
#include "sysp.h"
#include <dos.h>

void HorScroll(unsigned, unsigned);
void VerScroll(unsigned);
void SetColumn(unsigned char);

void main(void) {

   struct videoconfig vc;
   unsigned char   i,j;

   // выбираем текстовый режим работы видеоадаптера,
   // принятый по умолчанию

   _setvideomode(_DEFAULTMODE);

   // устанавливаем логическую ширину экрана в 100 символов

   SetColumn(100);

   // отображаем на экране дисплея 24 строки текста

   for(i = 0; i < 24; i++)
      printf("\ntext text text");

   // производим горизонтальное смещение экрана
   // на i пикселов при каждом нажатии на клавиатуру

   for(i = 0; i < 13; i++) {
      getch();
      HorScroll(i,8);
   }

   // производим вертикальное смещение экрана
   // на i пикселов при каждом нажатии на клавиатуру


   for(i = 0; i < 13; i++) {
      getch();
      VerScroll(i);
   }
   getch();

_setvideomode(_DEFAULTMODE);
}


/**
*.Name   HorScroll
*
*.Title   Горизонтальный сдвиг содержимого экрана.
*
*.Descr   Функция смещает содержимое экрана влево на определенное
*      число пикселов.
*
*.Proto   void HorScroll(unsigned offset, unsigned wide)
*
*.Params   unsigned  offset - величина смещения в пикселах,
*
*      unsigned  wide   - ширина символов (8 или 9).
*
*.Return   Не используется.
*
*.Sample   scroll.c
**/
void HorScroll(unsigned offset, unsigned wide) {

   unsigned start_addr_reg, panning_reg;
   div_t res;

   res = div(offset,wide);

   start_addr_reg = res.quot;
   panning_reg = (wide == 9) ? 
            ((res.rem == 0) ? 8 : res.rem - 1 ) : res.rem;

   _asm {
      push   ds

; вычисляем адрес регистра состояния 1 (3BAh/3DAh)

      xor   ax,ax
      mov   es,ax
      mov   dx,es:[463h]
      add   dx,6

; ожидаем начало обратного вертикального хода луча

      in   al,dx
      nop
      nop
      test   al,08h
      jz   wait_on

   wait_off:

      in   al,dx
      nop
      nop
      test   al,08h
      jnz   wait_off

   wait_on:

      in   al,dx
      nop
      nop
      test   al,08h
      jz   wait_on

; вычисляем адрес порта индексного регистра контроллера ЭЛТ

      sub   dx,6

; выбираем для доступа младший байт регистра начального адреса

      mov   al,0Dh
      out   dx,al

; вычисляем адрес порта регистра данных контроллера ЭЛТ

      inc   dx

; устанавливаем новый начальный адрес

      mov   ax,start_addr_reg
      out   dx,al

; снова получаем адрес порта регистра состояния 1

      add   dx,5

; сбрасываем внутренний триггер контроллера атрибутов, управляющий
; адресацией его регистров

      in   al,dx
      nop
      nop

; выбираем регистр горизонтального панорамирования

      mov   dx,3C0h
      mov   al,13h
      out   dx,al

      mov   ax,panning_reg
      out   dx,al

      pop   ds
   }
}



/**
*.Name   VerScroll
*
*.Title   Вертикальный сдвиг содержимого экрана.
*
*.Descr   Функция смещает содержимое экрана вверх на определенное
*      число пикселов.
*
*.Proto   void VerScroll(unsigned offset)
*
*.Params   unsigned  offset - величина смещения в пикслах.
*
*.Return   Не используется.
*
*.Sample   scroll.c
**/
void VerScroll(unsigned offset) {

   unsigned start_addr_reg, preset_row_reg;
   div_t res;
   BIOS_VAR _far  *bios_var_ptr;


   bios_var_ptr = (BIOS_VAR _far *) FP_MAKE(0x0000, 0x0410);

   res = div(offset,bios_var_ptr -> char_height);

   start_addr_reg = res.quot * (bios_var_ptr -> columns);
   preset_row_reg = res.rem;


   _asm {
      push   ds

; вычисляем адрес регистра состояния 1 (3BAh/3DAh)

      xor   ax,ax
      mov   es,ax
      mov   dx,es:[463h]
      add   dx,6

; ожидаем начало обратного вертикального хода луча

      in   al,dx
      nop
      nop
      test   al,08h
      jz   wait_on

   wait_off:

      in   al,dx
      nop
      nop
      test   al,08h
      jnz   wait_off

   wait_on:

      in   al,dx
      nop
      nop
      test   al,08h
      jz   wait_on

; вычисляем адрес порта индексного регистра контроллера ЭЛТ

      sub   dx,6

; модифицируем младший байт регистра начального адреса

      mov   al,0Dh
      out   dx,al
      inc   dx
      mov   ax,start_addr_reg
      out   dx,al

      dec   dx

; модифицируем старший байт регистра начального адреса

      mov   al,0Ch
      out   dx,al
      inc   dx
      mov   al,ah
      out   dx,al

; вычисляем адрес порта регистра состояния 1

      add   dx,5

; ожидаем вертикальный обратный ход луча

wait_next:

      in   al,dx
      nop
      nop
      test   al,08h
      jz   wait_next

; определяем адрес порта индексного регистра контроллера ЭЛТ

      sub   dx,6

; устанавливаем регистр предустановки линии сканирования

      mov   al,8
      out   dx,al
      mov   ax,preset_row_reg
      inc   dx
      out   dx,al

      pop   ds
   }
}


/**
*.Name   SetColumn
*
*.Title   Установка логической ширины экрана.
*
*.Descr   Функция устанавливает логическую ширину экрана.
*
*.Proto   void SetColumn(unsigned char col)
*
*.Params   unsigned char  col - логическая ширина экрана (в символах).
*
*.Return   Не используется.
*
*.Sample   scroll.c
**/
void SetColumn(unsigned char col) {

   _asm {
      xor   ax,ax
      mov   es,ax

; получаем адрес порта индексного регистра
; контроллера ЭЛТ (3B4h/3D4h)
      mov   dx,es:[463h]

; выбираем для обмена регистр логической ширины экрана

      mov   al,13h
      out   dx,al

; вычисляем адрес порта регистра данных контроллера ЭЛТ (3B5h/3D5h)

      inc   dx

; модифицируем переменную BIOS, содержащую число символов в строке

      mov   al,col
      mov   es:[44Ah],al

; регистр логической ширины экрана в текстовых режимах содержит
; смещение между соседними строками текста в словах

      shr   al,1
      out   dx,al
   }
}

Регистр выбора цвета
(Color Select Register - CSR) (индекс 14)

Регистр используется только видеоадаптером VGA для управления цветом.

  • D0 Цвет Р4.
  • D1 Цвет Р5. Данные биты могут использоваться вместо линий Р5 и Р4 соответственно (см. регистры палитры и рисунок 6.18).
  • D2 Цвет Р6.
  • D3 Цвет Р7. Биты используются контроллером атрибутов в качестве двух старших битов, передаваемых ЦАП (см. рисунок 6.18). В режиме 256-цветном режиме VGA данные биты не используются.
  • D7-D4 Не используются.
[Назад] [Содеожание] [Дальше]