Электронная библиотека книг Александра Фролова и Григория Фролова.
 
Библиотека
Братьев
Фроловых
Электронная библиотека книг Александра Фролова и Григория Фролова.
Библиотека системного программиста
Программирование на JAVA
ПК. Шаг за шагом
Другие книги
Восстановление данных
Антивирусная защита
Статьи для
программистов
Пользователю компьютера

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

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

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

6.2. Регистры контроллера ЭЛТ

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

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

Для видеоадаптеров, построенных на основе микросхемы Motorola 6845 - MDA, CGA и Hercules, контроллер ЭЛТ содержит 18 регистров. В таблице 7.3 приведен список всех регистров контроллера ЭЛТ и их индексы, используемые для доступа к ним.

Индекс Регистр контроллера ЭЛТ
0 общая длина линии горизонтальной развертки (Horizontal Total Register - HTR)
1 длина отображаемой части горизонтальной развертки (Horizontal Displayed - HDR)
2 положение горизонтальной синхронизации (Horizontal Sync Position - HSR)
3 ширина горизонтального синхросигнала (Horizontal Sync Pulse Width Register - HSPWR)
4 число горизонтальных линий растра (Vertical Total Register - VTR)
5 выравнивание ратстра (Vertical Total Adjust Register - VTAR)
6 длина отображаемой части вертикальной развертки (Vertical Displayed - VDR)
7 положение вертикальной синхронизации (Vertical Sync Position Register - VSPR)
8 режим соединения (Interlase Mode Register - IMR)
9 высота символов текста (Max Scan Line Register - MSLR)
0Ah начальная линия курсора (Cursor Start Register - CSR)
0Bh конечная линия курсора (Cursor End Register - CER)
0Ch старший байт начального адреса (Start Address Register - SAR, high byte)
0Dh младший байт начального адреса (Start address Register - SAR, low byte)
0Eh старший байт позиции курсора (Cursor Location Register - CLR, high byte)
0Fh младший байт позиции курсора (Cursor Location Register - CLR, low byte)
10h старший байт адреса светового пера (Light Pen Address Register - LPAR, high byte)
11h младший байт адреса светового пера (Light Pen Address Register - LPAR, low byte)

Таблица 7.3 Регистры контроллеров ЭЛТ, построенных на основе микросхемы Motorola 6845 или ее аналогов.

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

Учтите, что у видеоадаптера CGA большинство регистров контроллера ЭЛТ являются доступными только для записи. Только регистры SAR и CLR доступны как для записи, так и для чтения.

У видеоадаптеров MDA и Hercules индексный порт имеет адрес 3B4h, а порт данных - адрес 3B5h. Для CGA адреса портов другие. Индексный порт имеет адрес 3D4h, а порт данных - адрес 3D5h.

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

Адрес порта индексного регистра записан в области переменных видеофункций BIOS, по адресу 0000:0463. Приведем фрагмент программы для получения адреса порта индексного регистра контроллера ЭЛТ:

; устанавливаем es на нулевой сегмент

xor   ax,ax
mov   es,ax

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

mov   dx,es:[463h]

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

Общая длина линии горизонтальной развертки (Horizontal Total Register - HTR) (индекс 0)

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

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

Для CGA количество знакомест по горизонтали будет на одно больше, чем значение, записанное в регистре.

Длина отображаемой части горизонтальной развертки (Horizontal Display Enable End Register - HDER) (индекс 1)

Данный регистр используется адаптерами CGA и Hercules. Регистр задает длину отображаемого участка горизонтальной развертки. Величина регистра равна числу символов в строке экрана.

Положение горизонтальной синхронизации (Horizontal Sync Position - SHBR) (индекс 2)

Регистр CGA, определяющий начало обратного хода луча. Изменяя содержимое регистра можно смещать изображение на экране влево и вправо.

Ширина горизонтального синхросигнала (Horizontal Sync Pulse Width Register - HSPWR) (индекс 3)

Для видеоадаптеров MDA, CGA и Hercules регистр определяет продолжительность обратного хода луча в символах.

Число горизонтальных линий растра (VTR) (индекс 4)

Определяет число текстовых строк в растре.

Выравнивание растра (Vertical Total Adjust Register - VTAR) (индекс 5)

Определяет количество текстовых строк в растре, отведенных под рамку экрана.

Длина отображаемой части вертикальной развертки (Vertical Displayed - VDR) (индекс 6)

Регистр CGA, задающий число отображаемых текстовых строк.

Положение вертикальной синхронизации (Vertical Sync Position Register - VSPR) (индекс 7)

Регистр видеоадаптера CGA, определяющий начало обратного вертикального хода луча.

Режим соединения (Interlase Mode Register - IMR) (индекс 8)

Регистр CGA. Биты D4 и D5 задают режим соединения. Биты D6 и D7 определяют отклонение экрана. Регистр всегда содержит 2.

Высота символов текста
(Max Scan Line Register - MSLR) (индекс 9)

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

Приведем формат регистра:

  • D4-D0 Эти биты задают высоту символа в пикселах минус один (см. рисунок 7.1).
  • D7-D5 Не используются.

Рисунок 7.1 Использование регистра высоты символов текста.

Начальная линия курсора
(Cursor Start Register - CSR) (индекс 0Ah)

Регистр задает верхнюю линию сканирования символа. С этой линии начинается курсор. Вместе с регистром конечной линии курсора (CER), он определяет размер и форму курсора.

Приведем формат регистра:

  • D4-D0 Номер начальной линии курсора. Соответствует номеру первой линии курсора.
  • D7-D5 Не используются.

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


Режим                0,1,2,3            4,5,6

Содержимое регистра  6                  0

Конечная линия курсора
(Cursor End Register - CER) (индекс 0Bh)

Регистр задает нижнюю линию сканирования символа, в которой кончается курсор.

  • D4-D0 Соответствует номеру последней линии курсора.
  • D7-D5 Не используются.

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

Режим 0,1,2,3 4,5,6
Содержимое регистра 7 0

Изменяя значение регистров начальной и конечной линии курсора можно менять его положение и размер.

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

// изменение размеров курсора

#include <stdio.h>
#include "sysp.h"
#include "sysgraph.h"

void main(void) {

   char           top = 0, bottom = 0;
   unsigned       crt_address;
   BIOS_VAR _far  *bios_var_ptr;

   // получаем указатель на область переменных видеофункций BIOS

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

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

   crt_address = bios_var_ptr->crt_address;

   printf("Введите верхнюю границу курсора:");
   scanf("%d", &top);
   printf("Введите нижнюю границу курсора:");
   scanf("%d", &bottom);

   // изменение формы курсора

   // выбираем регистр начальной линии курсора

   WriteReg(crt_address++, 0x0A);

   // записываем в регистр значение переменной top

   WriteReg(crt_address--, (unsigned char) top);

   // выбираем регистр конечной линии курсора

   WriteReg(crt_address++, 0x0B);

   // записываем в регистр значение переменной bottom

   WriteReg(crt_address, (unsigned char)bottom);

   getch();
}

Данная программа, а также часть программ, приведенных ниже, использует для доступа к регистрам видеоадаптера функции ReadReg и WriteReg:

/**
*.Name   WriteReg
*
*.Title   Запись в порт.
*
*.Descr   Функция выводит данные в порт.
*
*.Proto   WriteReg(unsigned reg, unsigned char data)
*
*.Params   unsigned  reg - номер регистра,
*
*      unsigned char  data - данные, записываемые в регистр.
*
*.Return   Не ипользуется.
*
*.Sample   get_curs.c
**/

WriteReg(unsigned reg, unsigned char data) {
   _asm {
      mov   dx,reg
      mov   al,data
      out   dx,al
   }
}


/**
*.Name   ReadReg
*
*.Title   Чтение регистра.
*
*.Descr   Функция читает данные из определенного порта.
*
*.Proto   unsigned char ReadReg(unsigned reg)
*
*.Params   unsigned  reg - номер регистра.
*
*.Return   считанные данные.
*
*.Sample   get_curs.c
**/
unsigned char ReadReg(unsigned reg) {

   unsigned char  data;

   _asm {
      mov   dx,reg
      in   al,dx
      mov   data,al
   }
   return(data);
}

Вместо этих функций для доступа к регистрам можно использовать функции inp и outp, из стандартных библиотек трансляторов Microsoft Quick C 2.5 и C 6.0.

Регистры начального адреса

Это группа из двух регистров: регистр старшего байта начального адреса (Start Address Register - SAR, high byte) (индекс 0Ch) и регистр младшего байта начального адреса (Start Address Register - SAR, low byte) (индекс 0Dh).

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

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

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

Рисунок 7.2 Использование регистров начального адреса.

Регистры, определяющие положение курсора

Два регистра - регистр старшего байта положения курсора (Cursor Location Register - CLR_h, high byte) (индекс 0Eh) и регистр младшего байта положения курсора (Cursor Location Register - CLR_l, low byte) (индекс 0Fh) определяют положение курсора на экране (см. рисунок 7.3). Они содержат смещение относительно начала видеобуфера байта на котором установлен курсор.

Это единственные регистры видеоадаптера CGA, доступные как для записи, так и для чтения.

Рисунок 7.3 Отображение курсора на экране.

Программа, приведенная ниже, считывает значения из регистров положения курсора.

// чтение регистра положения курсора

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


void main(void) {

   int            crt_port;
   unsigned char  h_pos, l_pos;
   BIOS_VAR _far  *bios_var_ptr;


   // получаем указатель на область переменных видеофункций BIOS

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

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

   crt_port = bios_var_ptr -> crt_address;

   // выбираем старший байт регистра положения курсора

   WriteReg(crt_port, 0x0E);

   // считываем значение старшего байта регистра положения курсора

   h_pos = ReadReg(crt_port + 1);

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

   WriteReg(crt_port, 0x0F);

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

   l_pos = ReadReg(crt_port + 1);

   printf("\nТекущий адрес курсора %X:%X\n",
            (unsigned char) h_pos, (unsigned char) l_pos );
}

Регистр адреса светового пера (LPAR)

Это 16-битовый регистр, который имеется в видеоадаптерах CGA и EGA, доступен только для чтения. Регистр LPAR дает возможность определить положение светового пера на экране. Регистр содержащий старший байт адреса светового пера имеет индекс 10h, а регистр содержащий младший байт - индекс 11h.

LPAR сохраняет адрес видеопамяти, которая регенерировалась в момент включения светового пера.

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


Создание интернет-магазинов: http://www.shop2you.ru/ © Александр Фролов, Григорий Фролов, 1991-2016