4.4.3 Рисование точки на экране (EGA).

  У EGA графика более сложная. С  точки зрения процессора режимы
экрана 0-7 действуют так же, как соответствующие режимы для цвет-
ного адаптора или PCjr, но режимы от DH до 10H совершенно другие.
Организация  памяти  для этих режимов меняется, в зависимости  от
числа используемых цветов и количества памяти, имеющейся на плате
дисплея. Смотрите рис. 4-4 в [4.4.0].
   В  режимах D, E и 10H память разбита на 4  битовые  плоскости.
Каждая плоскость организована таким же образом, как для черно-бе-
лого режима высокого разрешения цветного адаптора, который обсуж-
дался в [4.4.2]:  когда  байт  данных  посылается  в определенный
адрес  видеобуфера, то каждый бит соответствует точке на  экране,
причем весь байт соответствует  горизонтальному сегменту линии, а
бит  7 соответствует самой левой точке.  Выводятся  четыре  таких
битовых плоскости, относящиеся к  одним и тем же адресам в видео-
буфере. Это приводит к тому, что каждая точка описывается четырь-
мя битами (давая 16 цветов), причем каждый бит находится вотдель-
ном байте отдельной битовой плоскости.
   Но  как Вы можете записать 4 различных байта данных,  располо-
женных по одному и тому же адресу? Ответ на этот вопрос состоит в
том,  что  Вы не посылаете последовательно четыре байта по  этому
адресу.  Вместо этого один из трех режимов записи позволяет изме-
нить все 4 байта, на основании одного байта данных полученного от
процессора. Влияние данных посланных процессором зависит от уста-
новки  нескольких регистров, включающих два регистра маски, кото-
рые определяют на какие биты и  в  каких битовых плоскостях будут
изменяться биты.
   Для  понимания этих регистров мы должны сначала разобраться  с
четырьмя регистрами задвижки (latch register).  Они содержат дан-
ные для четырех битовых плоскостей в той позиции, к которой  было
последнее обращение. (Заметим,  что  термин битовая плоскость ис-
пользуется как для целой области видеобуфера, так и для однобайт-
ного буфера,  временно  хранящегося  в  регистре задвижки.) Когда
процессор  посылает данные по определенному адресу, то эти данные
могут изменить или полностью сменить  данные регистра задвижки, а
впоследствии  именно данные из регистра задвижки  записываются  в
видеобуфер. Каким  образом  данные  процессора  влияют на регистр
задвижки зависит от используемого режима записи, а также от уста-
новки некоторых других регистров. При чтении адреса из видеобуфе-
ра  регистры  задвижки заполняются четырьмя  байтами  из  четырех
битовых плоскостей по данному адресу.   Регистрами задвижки легко
манипулировать,  производя  их  содержимым  различные  логические
операции, что позволяет устраивать различные графические трюки.
   Регистр маски битов и регистр маски карты действуют на регист-
ры  задвижки, защищая определенные биты или битовые плоскости  от
изменения под действием данных,  поступающих  от процессора.  Ре-
гистр  маски  битов  это регистр только для записи,  адрес  порта
которого 3CFH.  Сначала надо послать 8 в порт 3CEH, чтобы указать
на этот регистр. Установка бита этого регистра в 1 маскирует этот
бит во всех четырех  битовых  плоскостях,  делая  соответствующую
точку  недоступной для изменения.  Однако, поскольку оборудование
работает  в  байтовых  терминах, то реально  "неизменяемые"  биты
перезаписываются в  четыре  битовые  плоскости.  Данные  для этих
маскируемых битов хранятся в регистрах задвижки, поэтому програм-


ма должна быть уверена, что текущее содержимое регистров задвижки
относится  к  правильному адресу памяти.  По этой  причине  перед
записью по данному адресу надо считывать из него.
   Регистр маски карты имеет адрес порта 3C5H. Этот регистр толь-
ко для записи. Перед посылкой данных надо послать по этому адресу
2 как указатель. Биты 0-3  этого  регистра  соответствуют битовым
плоскостям  0-3; старшие 4 бита регистра не используются.   Когда
биты 0-3 равны 0, то  сответствующие  битовые  плоскости не изме-
няются при операциях записи. Это свойство используется по-разному
в различных режимах записи, как Вы увидите в дальнейшем.
   Три режима записи  устанавливаются  регистром  режима, который
является  регистром  только для записи, а адрес  порта  для  него
3CFH, который  индексируется  предварительной  засылкой  5 в этот
порт.  Режим записи устанавливается в битах 0 и 1, как число от 0
до 2.  Бит 2 должен быть равным  0, так же как и биты 4-7.  Бит 3
устанавливает  один из двух режимов чтения из видеобуфера.   Этот
бит может быть 0 или 1. BIOS EGA устанавливает режим записи в 00.

   Режим записи 0:
   В простейшем случае режим записи  0 копирует данные процессора
в каждую из четырех битовых плоскостей.  Например, пусть по опре-
деленному адресу видеобуфера  послано  11111111B  и разрешены все
биты и все битовые плоскости (т.е. ничто не маскировано описанны-
ми выше регистрами масок). Тогда каждый бит во всех четырех плос-
костях будет установлен в 1, так что цепочка битов для каждой  из
соответствующих точек  будет  1111B.   Это  означает, что 8 точек
будут выведены в цвете 15, который изначально соответствует ярко-
белому цвету, хотя  регистры  палетты  позволяют,  чтобы на самом
деле это был любой из допустимых цветов.
   Теперь  рассмотрим  тот  же  случай,  но  посылается  значение
00001000B. Цепочка битов для  точки 3 будет 1111, а для остальных
- 0000, что соответствует черному (изначально).  Поэтому в данном
случае только точка 3 появится на экране (яркобелая), а остальные
7  точек будут выключены.  Даже если остальные 7 точек перед этим
выводились в каком-то цвете, то теперь  все они будут переключены
на 0000.
   Теперь  рассмотрим другие цвета, кроме 1111B.  Если Вы пошлете
код палетты желаемого цвета  в  регистр  маски  карты, то регистр
маскирует определенные битовые плоскости таким образом, что будет
воспроизведен требуемый  цвет.  Например,  если  Вы хотите цвет с
кодом 0100, то пошлите 0100 в регистр маски карты.  Тогда битовые
плоскости 0, 1 и 3 не будут изменяться.  Когда Вы пошлете по нуж-
ному  адресу 11111111B, то это значение будет помещено  только  в
битовую плоскость 2 и цепочка  битов для каждой точки будет 0100.
Если Вы пошлете по этому адресу 00001000B, то точка 3 будет иметь
цепочку битов 0100, а остальные точки - 0000.
   Имеется, однако, одна сложность. Регистр маски карты запрещает
изменение битовых плоскостей, но не обнуляет их. Предположим, что
битовая плоскость 0 была заполнена единицами, а битовые плоскости
1  и 3 были заполнены нулями.  Если Вы запретите изменения в этих
трех плоскостях, а затем пошлете 11111111B по определенному адре-
су,  то битовая плоскость 2 будет заполнена 11111111B, а  битовая
плоскость 0 сохранит  свои  единицы,  поэтому  результирующий код
цвета  каждой точки станет 0101B.  Встречаются случаи, когда  это
свойство можно использовать для изменения цветов экрана. Но вооб-


ще говоря, необходимо очищать  все четыре битовые плоскости (т.е.
все  четыре  регистра задвижки) перед тем, как писать туда  любые
цвета кроме 1111B или 0000B.   Это  делается просто посылкой 0 по
указанному  адресу.  Необходимо чтобы при этом была разрешена за-
пись во все четыре битовые плоскости.
   Вышеприведенное  обсуждение   касалось  одновременного  вывода
восьми точек.  Ну а как вывести меньшее количество точек? В  этом
случае, конечно,  необходимо  сохранить  существующие  данные для
некоторых  точек,  а чтобы это было возможно  текущее  содержимое
данного адреса сохраняется в  регистрах  задвижки.  Затем исполь-
зуется регистр маски битов для маскирования тех точек, которые не
должны изменяться. Если бит этого регистра сброшен в 0, то данные
получаемые от процессора для этого бита игнорируются и вместо них
используются данные, хранящиеся  в  регистрах  задвижки. Равен ли
этот бит в данных процессора 0 или 1 - не имеет значения; если Вы
изменяете только бит 2, а все  остальные  маскированы, то данные,
которые  приходят от процессора могут быть 0FFH или 4H, или любое
другое значение, для которого бит  2 установлен. Если бит 2 сьро-
шен,  то 0 помещается в этой позиции во всех разрешенных  битовых
плоскостях.
   Вообще говоря, программа должна  сначала прочитать любую ячей-
ку, в которую она собирается записать меньше чем 8 точек. Имеются
два режима чтения (обсуждаемые в [4.4.4])  и безразлично какой из
них выбран.  Операция чтения загружает регистры задвижки четырьмя
байтами данных для данного  адреса  памяти.  Данные, возвращаемые
процессору операцией чтения, могут быть отброшены.
   До  сих пор были рассмотрены самые простые возможности  режима
записи 0. При  желании  Вы  можете  делать  намного более сложные
манипуляции. Одна из возможностей состоит в модификации регистров
задвижки с помощью логических операций перед записью.  Для реали-
зации этой возможности регистр вращения данных использует следую-
щие биты:

   биты 2-0        число вращений
        4-3        00     данные не модифицируются
                   01     логическое И с регистром задвижки
                   10     логическое ИЛИ с регистром задвижки
                   11     исключающее ИЛИ с регистром задвижки
        7-5        не используются

   Число  вращений,  которое  может  быть  от  0 до 7, показывает
сколько битов данных должны вращаться перед тем, как поместить их
в регистр задвижки.  Обычно это значение равно нулю.  Аналогично,
биты 4-3, как правило равны 00, кроме случаев, когда производятся
логические операции. За счет  манипуляций с этим регистром одни и
те  же данные могут давать различные цвета и изображения без  до-
полнительной  процессорной  обработки.   Регистр  вращения данных
индексируется  посылкой 3 в порт 3CEH; затем данные посылаются  в
3CFH.
   Наконец, режим записи 0 может  работать совсем по-другому если
разрешены  установка/сброс.  В этом случае определенные  цвета  в
младших четырех битах  регистра  установки/сброса  (который  тоже
имеет адрес порта 3CFH, а индексируется посылкой 0 в 3CEH).  Име-
ется соответствующий регистр разрешения установки/сброса, который
разрешает  любой из этих четырех битов, устанавливая свои младшие


биты в 1. Когда все 4 бита в регистре установки/сброса разрешены,
то они помещаются во все 8 адресов битовой плоскости при  получе-
нии данных от процессора, при  этом сами данные процессора отбра-
сываются.  Если разрешены не все биты установки/сброса, то данные
процессора помещаются для запрещенных точек. Отметим, что регистр
маски битов запрещает запись данных установки/сброса в определен-
ные точки, но  установка  регистра  маски  карты игнорируется при
использовании установки/сброса.  BIOS инициализирует регистр раз-
решения установки/сброса в  0,  так  что  он неактивен. Его адрес
порта 3CFH, а индексируется он посылкой 1 в порт 3CEH.

Режим записи 1:
   Режим записи 1 предназначен для специальных приложений. В этом
режиме текущее содержимое  регистра задвижки записывается по ука-
занному  адресу.  Напоминаем, что регистры  задвижки  заполняются
операцией чтения.  Этот режим очень полезен для быстрого переноса
данных при операциях сдвига экрана. Регистр маски битов и регистр
маски  карты не влияют на эту операцию.  Не имеет также  значения
какие данные посылает процессор  -  содержимое регистров задвижки
записывается в память без изменений.

Режим записи 2:
   Режим  записи 2 предоставляет альтернативный способ  установки
отдельных точек.  Процессор посылает данные, у которых имеют зна-
чение  только  4 младших бита, которые рассматриваются  как  цвет
(индекс регистра палетты).  Можно  сказать, что эта цепочка битов
вставляется  поперек битовых плоскостей.  Цепочка дублируется  на
все восемь точек, относящихся к  данному  адресу, до тех пор пока
регистр маски битов не предохраняет определенные точки от измене-
ния. Регистр маски карты активен, как и в режиме записи 0. Конеч-
но процессор должен послать полный байт, но только младшие 4 бита
существенны.

   Высокий уровень.

   Бейсик поддерживает EGA в традиционных режимах цветного графи-
ческого адаптора. Ко времени выхода этой книги поддержки дополни-
тельных режимов EGA не  существовало.  Поэтому  у Вас нет другого
выхода,  кроме как использовать прямое отображение в  видеобуфер,
который начинается с  адреса  A000:0000.  Самая  тяжелая проблема
состоит  в установке режима дисплея.  Для ее решения  используйте
следующую процедуру на машинном языке:

10 S$ = CHR$(&H2A)+CHR$(&HE4)+CHR$(&HB0)+CHR$(&H0D)
        +CHR$(&HCD)+CHR$(&H10)+CHR$(&HCB)
20 DEF SEG                  'установка сегмента
30 Y = VARPTR(S$)           'указатель на строку
40 Z = PEEK(Y+1)+PEEK(Y+2)*256  'вычисление адреса строки
50 CALL Z                   'вызов процедуры

Четвертый байт S$ содержит номер режима, в данном случае режим D.
Вы можете выбрать другой режим.   В  приложении Г объясняется как
эта  процедура работает в Бейсике.  Она полностью завершенная, не
нужно никакой побочной памяти,  в  которой содержался бы машинный
код.   Не  забудьте восстановить режим дисплея  после  завершения
своих манипуляций.


   Затем надо установить  соответствующий  режим  записи. Вот как
устанавливается режим записи 2:

50 OUT &H3CE,5         'индексируем регистр режима записи
60 OUT &H3CF,2         'выбираем режим 2

Режим  записи  также должен быть  восстановлен  после  завершения
программы.
   Наконец, приведем образцы кода, реализующие прямое отображение
в видеобуфер:

Режим записи 0:

100 'рисуем красную точку в левом верхнем углу экрана
110 DEF SEG = &HA000     'указываем на видеобуфер
120 OUT &H3CE,8          'адресуем регистр маски битов
130 OUT &H3CF,128        'маскируем все биты, кроме седьмого
140 X = PEEK(0)          'читаем текущее значение в задвижку
150 POKE 0,0             'чистим
160 OUT &H3C4,2          'адресуем регистр маски карты
170 OUT &H3C5,4          'устанавливаем красный цвет
180 POKE 0,&HFF          'рисуем точку

Режим записи 1:

100 'копируем верхнюю строчку точек в следующую
110 DEF SEG = &HA000     'указываем на видеобуфер
120 FOR N = 0 TO 79      'для всех 80 байтов строки
130 X = PEEK(N)          'заполняем задвижки
140 POKE N+80,Y          'копируем в следующую строку
150 NEXT                 'переходим к следующему сегменту

Режим записи 2:

100 'рисуем красную точку в левом верхнем углу экрана
110 DEF SEG = &HA000     'указываем на видеобуфер
120 OUT &H3CE,8          'адресуем регистр маски битов
130 OUT &H3CF,128        'маскируем все биты, кроме седьмого
140 X = PEEK(0)          'читаем текущее значение в задвижку
150 POKE 0,4             'посылаем красный цвет

   Средний уровень.

   EGA поддерживает стандартные графические функции BIOS.   Можно
вывести точку с помощью функции CH прерывания 10H, так же как для
цветного  дисплея или PCjr.  При входе DX должен содержать  номер
строки, а CX - номер столбца, и  то  и другое отсчитывается от 0.
Код цвета помещается в AL.  Содержимое AX меняется при выполнении
прерывания.

;---рисуем точку по адресу 50,100
   MOV  AH,0CH        ;функция вывода точки
   MOV  AL,12         ;выбираем регистр палетты 12
   MOV  CX,100        ;номер строки
   MOV  DX,50         ;номер столбца
   INT  10H           ;рисуем точку


   Низкий уровень.

   Ниже приведены примеры для  трех  режимов записи. Перед их ис-
пользованием  необходимо  установить режим дисплея,  использующий
видеобуфер с адреса A000:0000. Для этого можно использовать стан-
дартную функцию BIOS, например, для установки режима D:

   MOV  AH,0       ;функция установки режима
   MOV  AL,0DH     ;выбираем режим D
   INT  10H        ;устанавливаем режим

Не забудьте восстановить режим перед завершением программы. Кроме
того, Вам необходимо установить требуемый  режим записи. Вот при-
мер установки режима записи 2:

   MOV  DX,3CEH    ;указываем на регистр адреса
   MOV  AL,5       ;инедксируем регистр 5
   OUT  DX,AL      ;посылаем индекс
   INC  DX         ;указываем на регистр режима
   MOV  AL,2       ;выбираем режим записи 2
   OUT  DX,AL      ;устанавливаем режим

   И, наконец, примеры трех режимов записи:

Режим записи 0:

;---рисуем красную точку в левом верхнем углу экрана
   MOV  AX,0A000H      ;указываем на видеобуфер
   MOV  ES,AX          ;
   MOV  BX,0           ;указываем на первый байт буфера
;---маскируем все биты, кроме седьмого
   MOV  DX,3CEH        ;указываем на адресный регистр
   MOV  AL,8           ;номер регистра
   OUT  DX,AL          ;посылаем его
   INC  DX             ;указываем на регистр данных
   MOV  AL,10000000B   ;маска
   OUT  DX,AL          ;посылаем данные
;---чистим текущее содержимое задвижки
   MOV  AL,ES:[BX]     ;читаем содержимое в задвижку
   MOV  AL,0           ;готовимся к очистке
   MOV  ES:[BX],AL     ;чистим задвижку
;---установка регистра маски карты для красного цвета
   MOV  DX,3C4H        ;указываем на адресный регистр
   MOV  AL,2           ;индекс регистра маски карты
   OUT  DX,AL          ;установка адреса
   INC  DX             ;указываем на регистр данных
   MOV  AL,4           ;код цвета
   OUT  DX,AL          ;посылаем код цвета
;---рисуем точку
   MOV  AL,0FFH        ;любое значение с установленным 7 битом
   MOV  ES:[BX],AL     ;выводим точку


Режим записи 1:

;---копируем строку в следующую строку
          MOV  CX,80       ;число байтов в строке
          MOV  BX,0        ;начинаем с 1-го байта буфера
          MOV  AX,0A000H   ;адрес буфера
          MOV  ES,AX       ;
NEXT_BYTE:   MOV  AL,ES:[BX]   ;заполняем задвижку
          MOV  ES:[BX]+80,AL   ;выводим в следующую строку
          INC  BX          ;переходим к следующему байту
          LOOP NEXT_BYTE   ;

Режим записи 2:

;---рисуем красную точку в левом верхнем углу экрана
   MOV  AX,0A000H        ;адрес буфера
   MOV  ES,AX            ;
   MOV  BX,0             ;указываем на первый байт буфера
;---установка регистра маски битов
   MOV  DX,3CEH          ;указываем на адресный регистр
   MOV  AL,8             ;регистр маски битов
   OUT  DX,AL            ;адресуем регистр
   INC  DX               ;указываем на регистр данных
   MOV  AL,10000000B     ;маскируем все биты, кроме 7-го
   OUT  DX,AL            ;посылаем данные
;---рисуем красную точку
   MOV  AL,ES:[BX]       ;заполняем регистры задвижки
   MOV  AL,4             ;красный цвет
   MOV  ES:[BX],AL       ;рисуем точку

 

Вы находитесь в разделе: 
Также вам будет интересно:

Добавить коментарий