8.6.1. Адаптер монохромного дисплея и принтера

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

Черно-белая плата работает в одном режиме. Этот видео адаптер предназначен для вывода 25 строк символов по 80 символов в строке. Такое построение изображения называют режимом 80*25. Вы помещаете символы на экран, записывая коды ASCII в буфер дисплея. Буфер дисплея - это специальная область памяти, расположенная в адресном пространстве по адресу 0B0000H. Эта память - часть платы адаптера, а не системной памяти. Всякий раз, когда вы записываете символ в коде ASCII в буфер дисплея, он появляется в соответствующем месте экрана. Преобразование символа из кода ASCII в точки на экране выполняется аппаратно.

Каждый символ на дисплее имеет атрибут. Атрибуты символов определяют вид, в которым адаптер выводит символы на экран. На Фиг. 8.7 показаны атрибуты символов и их значения. Вам нужно знать эти значения, так как их тоже надо помещать в буфер дисплея. Позиция каждого символа в буфере дисплея занимает два байта. Четный байт пары содержит код символа, а нечетный - значение атрибута. По Фиг. 8.7 можно определить значение атрибута, с которым выводить на экран символ. Обычно выводится белый (на самом деле зеленый) символ на черном фоне. Для этого случая значение атрибута равно 07H. Чтобы сделать изображение негативным, нужно изменить значение атрибута на 70H. Атрибут 00H делает символ невидимым. Хотя код ASCII символа и записан в байт символа, значение атрибута не дает символу появиться на экране.

Дисплейный буфер черно-белой платы содержит 4K байта памяти. Этого достаточно, чтобы иметь байты символов и атрибутов для каждой из 2000 позиций экрана. Первый символ буфера дисплея появляется в верхнем левом углу экрана, следующие два байта изображают следующий символ справа, и так далее. Первый символ второй строки находится в байтах 160 и 161. Теперь можно определить адрес любого символа на экране. Сначала определим позицию в верхнем левом углу экрана, как находящуюся в строке 0 и колонке 0; нижний правый угол находится в строке 24 и колонке 79. Тогда формулой вычисления адреса для произвольной строки и позиции будет


адрес = 2*(строка*80 + колонка) + 0B0000H

Умножение на 2 выравнивает адрес к двум байтам на позицию. Прибавление значения 0B0000H отражает начальный адрес буфера дисплея. Обычно в программе либо регистр DS, либо регистр ES загружается значением 0B0000H, и в остальном программа работает со смещениями в буфере дисплея.

Значение Атрибут
00H ничего не выводится
01H подчеркнутые символы
07H белый символ на черном фоне
0FH ярко-белый символ, черный фон
70H черный символ, белый фон
80H при добавлении к любому другому символ мигает

Фиг. 8.7 Символьные атрибуты для монохромного адаптера

На Фиг. 8.8 в качестве примера для монохромного дисплея приведена программа, которая перемещает содержимое экрана на одну позицию вправо. Она выбрасывает крайнюю справа колонку, а слева помещает колонку из пробелов. Если вы хотите испытать эту программу, но имеете в своей системе только цветную плату, то программа работает при установке сегмента DISPLAY на адрес 0B800H. Оба видео адаптера очень похожи при работе в текстовом режиме, и различаются только адресами памяти и ввода-вывода.


Microsoft (R) Macro Assembler Version 5.00                  1/1/80 04:03:56
Фиг. 8.8 Горизонтальный сдвиг вправо                              Page  1-1
PAGE  ,132
                         TITLE    Фиг. 8.8 Горизонтальный сдвиг вправо

0000                     STACK    SEGMENT STACK
0000    0040[                     DW        64 DUP (?)
             ????
            ]
0080                     STACK    ENDS

0000                     DISPLAY  SEGMENT AT 0B800H
0000                     DISPLAY_START      LABEL   WORD

0FA0                              ORG       4000
0FA0                     DISPLAY_END        LABEL   WORD
0FA0                     DISPLAY  ENDS

0000                     CODE     SEGMENT

                                  ASSUME    CS:CODE
0000                     SIDE_SCROLL   PROC    FAR
0000    1E                        PUSH      DS
0001    B8 0000                   MOV       AX, 0
0004    50                        PUSH      AX
0005    B8 ---- R                 MOV       AX, DISPLAY
0008    8E D8                     MOV       DS, AX
000A    8E C0                     MOV       ES, AX
                                  ASSUME    DS:DISPLAY, ES:DISPLAY
                         ;-----        Заполнение столбца 79 пробелами
000C    B9 0019                   MOV       CX, 25
000F    8D 3E 004E R              LEA       DI, DISPLAY_START+78
0013    B8 0720                   MOV       AX, 720H
0016                     BLANK:
0016    89 05                     MOV       [DI], AX
0018    81 C7 00A0                ADD       DI, 160
001C    E2 F8                     LOOP      BLANK
                         ;-----        Сдвиг вправо
001E    B9 07D0                   MOV       CX, 2000
0021    8D 36 0F9E R              LEA       SI, DISPLAY_END-2
0025    8D 3E 0FA0 R              LEA       DI, DISPLAY_END
0029    FD                        STD
002A    F3/ A5                    REP       MOVSW
002C    A3 0000 R                 MOV       DISPLAY_START, AX
002F    CB                        RET
0030                     SIDE_SCROLL        ENDP

0030                     CODE     ENDS
                         END

                                  Фиг. 8.8 Горизонтальный сдвиг направо

Программа на Фиг. 8.8 делает этот горизонтальный сдвиг очень простым способом. Правая колонка заполняется пробелами в результате записи 25 пробелов через каждые 160 байт памяти. Затем программа сдвигает весь дисплейный буфер по памяти на один байт вверх. Поскольку буфер дисплея непрерывно продолжается строка за строкой, символ, который был в колонке 79 строки 0, после сдвига оказывается в колонке 0 строки 1. Наконец, программа заменяет первый символ буфера пробелом.

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

Монохромный адаптер порождает сигналы вертикальной и горизонтальной синхронизации, необходимые для нормального изображения, с помощью контроллера электронно-лучевой трубки 6845 фирмы Motorola. Эта микрсхема содержит два порта ввода-вывода, имеющих адреса 3B4H и 3B5H. Адаптер также имеет управляющий порт 3B8H и порт состояния 3BAH. После инициализации адаптера модифицировать коды в этих портах вряд ли стоит. Существуют и другие режимы работы, возможные для монохромной платы, но мы сконцентрируем наше внимание на цветной плате. Полное, детальное описание портов ввода-вывода монохромного адаптера можно найти в техническом описании.