Два текстовых режима цветного графического адаптера дают
простой способ вывода символов на экран. В текстовых режимах
цветная плата аналогична монохромному адаптеру, но она позволяет
указать цвет каждого символа. Так же, как и в монохромной плате,
каждая символьная позиция цветной платы имеет байт атрибутов. Этот
Номер бита 7 6 5 4 3 2 1 0
ЪДДВДДДДДДДДВДДВДДДДДДДДї
і Мі Ф О Ні Яі СИМВОЛ і Фиг. 8.9 Байт атрибута
АДДБДДБДДБДДБДДБДДБДДБДДЩ для ЦГА
- 289 -
байт атрибутов определяет цвета символов и фона каждой позиции.
На Фиг.8.9 показана структура байта атрибутов в цветном
текстовом режиме. Три бита, помеченных Ф О Н, определяют один из
восьми возможных цветов фона. Три бита СИМВОЛ определяют цвет
символа. Бит Я также влияет на цвет символа: его установка делает
цвет символа более ярким. Тем самым обеспечивается выбор одного из
16 цветов символа. Байт атрибута управляет единственным символом,
позволяя выбрать любую комбинацию цветов фона и символа каждой
позиции. Старший бит, помеченный буквой М, обычно вызывает мигание
символа. Установка бита мигания равным 1 заставляет контроллер
дисплея переключать цвет символа между его цветом и цветом фона со
скоростью примерно четыре раза в секунду. Так как символ,
изображенный в цвете фона, невидим, то получается эффект мигания.
Можно заменить бит мигания четвертым битом цвета фона, разрешив при
этом 16 цветов фона и 16 цветов символа. Это делает один из битов
регистра выбора цветов. Еще надо обратить внимание на то, что
одинаковая установка цветов символа и фона означает, что вы не
видите символ. Символ есть, но это все равно что пытаться увидеть
северного медведя в пургу - все одного цвета. На Фиг. 8.10 показаны
все 16 цветов, возможных в текстовом режиме.
I R G B Цвет
-------------------------------------
0 0 0 0 черный
0 0 0 1 синий
0 0 1 0 зеленый
0 0 1 1 морской волны
0 1 0 0 красный
0 1 0 1 магента
0 1 1 0 коричневый
0 1 1 1 светло-серый
1 0 0 0 темно-серый
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.10 Цвета
(Фирма IBM, приоритет 1981 г.)
Если вы сравните байт атрибута для ЦГА с атрибутами для
монохромного адаптера на Фиг. 8.7, то увидите, что они аналогичны.
Конечно, вы не можете указать цвета монхромному адаптеру, но все
остальное совпадает. Поскольку цветная плата не поддерживает
атрибут подчеркивания, то установка монохромного атрибута
подчеркивания соответствует голубому символу на черном фоне.
Такая организация байта атрибутов является попыткой сделать два
видео адаптера по-возможности совпадающими. Каждый символ в буфере
дисплея находится по четному адресу, а байт атрибутов - по
нечетному. Память цветного дисплея находится на видео адаптере, но
по другому адресу: у монохромного дисплея она имеет адрес 0B0000H,
а у цветного - 0B8000H. О сходстве дисплеев говорит то, что если
при модификации программы для монохромного дисплея на Фиг. 8.8,
изменить содержимое указателя AT сегмента на значение 0B800H,
программа будет верно работать и на цветной плате. То есть одна и
та же программа работает на любом видео адаптере при минимуме
изменений.
Для управления адаптером на цветной плате также используется
контроллер ЭЛТ 6845 фирмы Motorola. Два порта ввода-вывода этого
контроллера имеют адреса ввода-вывода 3D4H и 3D5H. На самом деле
контроллер 6845 имеет 18 внутренних регистров. Доступ ко всем
регистрам осуществляется с помощью двух портов ввода-вывода и
косвенной адресации. Для обращения к регистру микросхемы 6845,
нужно сначала загрузить индекс регистра в порт 3D4H, а затем читать
этот регистр или записать в него данные через порт 3D5H.
Приведем пример, чтобы пояснить, как работает контроллер. На
Фиг. 8.11 перечислены все 18 регистров микросхемы 6845. В примере
мы используем только регистры R10 и R11. Эти регистры определяют
начальную и конечную строки растра одного знакоместа для курсора.
Каждый символ, порождаемый цветной платой, состоит из восьми строк
растра, имеющих номера от 0 до 7. Вы можете поместить курсор в
любых из этих восьми строк. Регистр R10 сообщает микросхеме 6845,
на какой строке начинается курсор, а регистр R11 определяет
последнюю строку курсора. ROM BIOS инициализирует курсор,
находящийся на строках 6 и 7; это делается загрузкой числа 6 в R10
и числа 7 в R11.
Прогамма на Фиг.8.12(а) модифицирует курсор цветной графической
платы. Она смещает курсор так, что он оказывается на верхних пяти
строках растра вместо нижних двух. Сначала программа загружает в
индексный регистр контроллера 6845 (3D4H) число 10, а затем
записывает номер начальной строки, равный 0, в регистр данных
(3D5H). Затем, поместив 11 в индексный регистр, она устанавливает
номер конечной строки равным 4. Теперь курсор имеет вид мигающего
блока в верхней части позиции символа, а не митающего
подчеркивания. Подобный этому способ модификации курсора
используется несколькими редактирующими программами (редакторами)
персональной ЭВМ, включая встроенный редактор интерпретатор языка
Бейсик. При установке режима вставки во время редактирования,
курсор становится жирнее; интерпретатор Бейсика делает это, меняя
параметры в микросхеме 6845.
Вернувшись к Фиг. 8.11, можно увидеть, что в микросхеме 6845
есть и другие регистры. Большинство из них управляет сигналами
горизонтальной и вертикальной синхронизации телевизионного растра.
Вы можете модифицировать коды в этих регистрах для каких-либо
действий дисплеем. Например, команда MODE системы DOS, которая
может сдвигать катринку на экране влево и вправо, модифицирует
регистр R2, задающий положение строчного синхроимпульса.
Если вы захотите поэкспериментировать с этими регистрами, вам
придется писать короткие программы, делающие требуемые изменения.
ЪДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДВДДДДДДДДВДДДДДДДДї
іРегистр і і Объект в і і і
і # і Регистр хранит і программе і чтение і запись і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R0 і Гориз. сумма і Символ і Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R1 і Выводимая горизонталь і Символ і Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R2 і Гориз. поз. синхронизации і Символ і Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R3 і Гориз. ширина синхронизации і Символ і Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R4 і Вертикальный итог і Симв. ряд і Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R5 і Общая вертикальн.коррекция іСкан.строкиі Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R6 і Выводимая вертикаль і Симв. ряд і Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R7 і Поз. вертикальной синхрон. і Симв. ряд і Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R8 і Режим совмещения і - і Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R9 і Макс.адрес скан. строки іСкан.строкиі Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R10 і Начало курсора іСкан.строкиі Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R11 і Конец курсора іСкан.строкиі Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R12 і Начальный адрес (гориз.) і - і Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R13 і Начальный адрес (строка) і - і Нет і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R14 і Курсор (Гориз.) і - і Да і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R15 і Курсор (Строка) і - і Да і Да і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R16 і Световое перо (гориз.) і - і Да і Нет і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДґ
і R17 і Световое перо(строка) і - і Да і Нет і
АДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДБДДДДДДДДБДДДДДДДДЩ
Фиг. 8.11 Регистры микросхемы 6845
(с разрешения фирмы Motorola)
Если попытаться изменять регистры с помощью утилиты DEBUG, то это
может не сработать. Регистры R14 и R15 управляют позицией курсора,
и если утилита DEBUG переместит курсор между вашими обращениями к
индексному регистру и к регистру данных, изменения не произойдет.
Так получилось потому, что утилита DEBUG изменила содержимое
индексного регистра микросхемы 6845, и он уже больше не указывает
на тот внутренний регистр, который вы хотели изменить.
Другая интересная регистровая пара микросхемы 6845 - пара
регистров начального адреса R12 и R13. Адаптер цветного
графического дисплея имеет 16K байт памяти, а монохромная плата 4K
байта. Дополнительная память в цветной плате используется для
графических режимов, но она целиком в вашем распоряжении и в
текстовых режимах. Для текстового режима 80*25 требуется 4K байта
памяти, так что в буфере есть место для четырех разных страниц
памяти. Сдвигать данные на экране можно переносом данных с одного
места на другое, как это делалось на Фиг. 8.8. В случае же
вертикального сдвига нужно лишь изменить начальный адрес в
микросхеме 6845. Обычно начальный адрес равен 0. Если вы измените
его на 80 (число символов в строке), отображение будет начинаться
со второй строки. Это даст немедленный эффект сдвига всех данных
экрана вверх на одну строку.
На самом деле вы не изменяли данные, а сдвинули начало
сканирования памяти дисплея. Можно рассматривать дисплей как окно
80*25, через которое мы смотрим в 8192-символьный буфер дисплея.
При использовании начального адреса для сдвига данных возникают
сложности, когда вы приближаетесь к границе 16K байт. В этой точке
отображение "заворачивается". Верхние строки извлекаются из конца
буфера, а нижние строки - из его начала. Вы, конечно, сможете
решить эту проблему, но для этого потребуются некоторые размышления
и эксперименты.
[Прим. перев.: стр. 252 текста оригинала в моей копии отсутствует.
Очевидно, на ней находится только начало Фиг. 8.12]
Microsoft (R) Macro Assembler Version 5.00 1/1/80 04:05:31
Фиг. 8.12 Программа управления цветным дисплеем Page 1-1
PAGE ,132
TITLE Фиг. 8.12 Программа управления цветным дисплеем
0000 STACK SEGMENT STACK
0000 0040[ DW 64 DUP (?)
????
]
0080 STACK ENDS
0000 DISPLAY_BUFFER SEGMENT AT 0B800H
0000 DISPLAY_START LABEL WORD
0000 DISPLAY_BUFFER ENDS
= 03D4 CRT_INDEX EQU 03D4H
= 03D5 CRT_DATA EQU 03D5H
= 03DA CRT_STATUS EQU 03DAH
= 000A CURSOR_START EQU 10 ; Регистры управления курсором
= 000B CURSOR_END EQU 11 ; в контроллере дисплея 6845
0000 CODE SEGMENT
ASSUME CS:CODE
0000 COLOR_GRAPHICS PROC FAR
0000 1E PUSH DS ; Адрес возврата в ДОС
0001 2B C0 SUB AX, AX
0003 50 PUSH AX
Фиг. 8.12 Программа управления цветным дисплеем (начало)
;----- Фиг. 8.12 (а) Изменение курсора
0004 BA 03D4 MOV DX, CRT_INDEX
0007 B0 0A MOV AL, CURSOR_START ; Установка индексного регистра
0009 EE OUT DX, AL ; 6845 на регистр начала курсора
000A 42 INC DX
000B B0 00 MOV AL, 0
000D EE OUT DX, AL ; Установка начала курсора
000E 4A DEC DX
000F B0 0B MOV AL, CURSOR_END
0011 EE OUT DX, AL ; Выбор регистра конца курсора
0012 42 INC DX
0013 B0 04 MOV AL, 4
0015 EE OUT DX, AL ; Установка конца курсора
;----- Фиг. 8.12 (б) Использование регистра состояния 6845
0016 B8 0002 MOV AX, 2
0019 CD 10 INT 10H ; Выбор символьного режима 80*25
001B B8 ---- R MOV AX, DISPLAY_BUFFER
001E 8E C0 MOV ES, AX ; Адрес буфера дисплейной памяти
0020 B8 0720 MOV AX, 0720H ; Вывод начинается с пробела
0023 NEXT_CHAR:
0023 BF 0000 MOV DI, 0
0026 B9 0050 MOV CX, 80
0029 F3/ AB REP STOSW ; Вывод строки из 80 символов
002B FE C0 INC AL ; Следующий символ
002D 75 F4 JNZ NEXT_CHAR
002F BB 0720 MOV BX, 0720H
0032 NEXT_CHAR_1:
0032 B9 0050 MOV CX, 80
0035 BF 0000 MOV DI, 0
0038 BA 03DA MOV DX, CRT_STATUS ; Порт состояния для адаптера
; цветного дисплея
003B WAIT_NO_RETRACE:
003B EC IN AL, DX ; Проверка на обратный ход луча
003C A8 01 TEST AL, 1
003E 75 FB JNZ WAIT_NO_RETRACE ; Запрещение прерываний
0040 FA CLI
0041 WAIT_RETRACE:
0041 EC IN AL, DX
0042 A8 01 TEST AL, 1
0044 74 FB JZ WAIT_RETRACE ; Ожидание обратного хода луча
0046 8B C3 MOV AX, BX ; Выборка символа
0048 AB STOSW ; Занесение в дисплейный буфер
0049 FB STI ; Разрешение прерываний
004A E2 EF LOOP WAIT_NO_RETRACE
004C FE C3 INC BL
004E 75 E2 JNZ NEXT_CHAR_1
;----- Фиг. 8.12 (в) Вывод линии по диагонали
Фиг. 8.12 Программа управления цветным дисплеем (продолжение)
0050 B8 0004 MOV AX, 4
0053 CD 10 INT 10H ; Установка графического
; режима 320*200
0055 06 PUSH ES
0056 1F POP DS
0057 B3 32 MOV BL, 50 ; Число групп строк
0059 B1 02 MOV CL, 2 ; Счетчик сдвига
005B BF 0000 MOV DI, 0
005E DOT_LOOP:
005E B0 C0 MOV AL, 0C0H ; В AL маска первой точки в байте
0060 88 05 MOV [DI], AL
0062 81 C7 2000 ADD DI, 2000H ; Переключение на нечетную строку
0066 D2 E8 SHR AL, CL ; Сдвиг до следующей точки в байте
0068 88 05 MOV [DI], AL
006A 81 EF 1FB0 SUB DI, 2000H-80 ; Переключение на четную строку
006E D2 E8 SHR AL, CL
0070 88 05 MOV [DI], AL
0072 81 C7 2000 ADD DI, 2000H ; Переключение на нечетную строку
0076 D2 E8 SHR AL, CL
0078 88 05 MOV [DI], AL
007A 81 EF 1FAF SUB DI, 2000H-81 ; Переключение на четную строку,
007E FE CB DEC BL ; следующий байт
0080 75 DC JNZ DOT_LOOP
;----- Возврат к символьному режиму 80*25
0082 B8 0002 MOV AX, 2
0085 CD 10 INT 10H
0087 CB RET
0088 COLOR_GRAPHICS ENDP
0088 CODE ENDS
END
Фиг. 8.12 Программа управления цветным дисплеем (продолжение)
Цветной графический адаптер имеет еще три регистра ввода-
вывода. Регистр режима находится по адресу ввода-вывода 03D8H. Этот
регистр устанавливает аппаратные переключатели различных режимов
отображения. Например, вы можете установить бит 5 этого регистра в
"0" и получить 16 цветов фона в текстовых режимах, а установка бита
5 в "1" переключает 7-й бит атрибута на функцию мигания. Полное
описание структуры этого регистра, и всех других, дано в
техническом описании.
Регистр выбора цвета находится по адресу ввода-вывода 03D8H.
Этот регистр устанавливает цвет окаймления в текстовых режимах.
Поскольку сам по себе текст не занимает весь экран, текст можно
окружить каким-либо выбираемым цветом. Кроме того, регистр выбора
цвета может управлять выбором палитр в графических режимов, как мы
увидим в следующем разделе. Младшие 4 бита этого регистра
устанавливают для окаймления один из 16 цветов, перечисленных на
Фиг. 8.10.
И наконец, регистр состояния по адресу ввода-вывода 3DAH
организует информационную обратную связь между цветной платой и
программой. Например, программа может использовать этот регистр для
определения текущего состояния светового пера, если оно подключено
к системе. Более важным является то, что регистр состояния
сообщает, когда безопасно читать или записывать данные в дисплейный
буфер.
Не вдаваясь в технические детали, заметим, что чтение или
запись данных в буфер дисплея цветной платы может вызвать "снег" на
экране, если вы будете это делать в неподходящие моменты времени.
Это случается только в текстовом режиме с высоким разрешением
80*25. Вспомните, что ранее приводился пример на Фиг. 8.12, в
котором постоянно записывались данные в буфер дисплея. Если для
этого примера использовать цветную плату, на экране появится масса
помех. Чтобы избежать этого, можно использовать регистр
состояния.
Существуют моменты, когда можно безопасно работать с данными в
буфере дисплея. В такие моменты бит 0 регистра состояния равен 1.
Нужно подождать, когда бит 0 станет равным 1, а затем читать или
записывать данные. На Фиг. 8.12б изображена программа, которая
записывает символ на экран дисплея. Первые строки этой программы
записывают данные в буфер, не используя регистр состояния. Эта
часть программы 224 раза записывает 80 симвлов в первую строку
буфера, что эквивалентно заполнению экрана около девяти раз. Когда
вы запустите программу, то увидите короткую вспышку помех в тот
момент, когда будут записываться данные.
Вторая часть программы на Фиг. 8.12б повторяет те же действия,
но на этот раз проверяя бит состояния. Обратите внимание, что эта
часть программы проверяет бит состояния двумя различными способами.
Сначала она ждет, пока бит состояния не станет равным 0. Затем, как
только он станет равен 1, программа записывает данные. Так сделано
потому, что интервал, в течение которого можно записывать данные,
очень мал, и если бы программа делала проверку только на равенство
1, она могла бы захватить бит состояния непосредственно перед его
обращением в 0. В этом случае, чтобы избежать помех, микропроцессор
уже не может записывать данные достаточно быстро, но такая
организация цикла гарантирует, что бит состояния захватывается в
первый же момент, когда он становится равным 1.
Используя бит состояния, вы уже не увидите на экране никаких
помех, но и заметите, что выполнение программы стало гораздо
медленнее. Выполняться медленнее программу заставляет
дополнительное время, затрачиваемое на ожидание бита состояния.
Если вам нужно записать на экране много данных - например,
организовать горизонтальный сдвиг, как на Фиг. 8.8, то потребуется
другой способ. Простейший способ - сбросить в нуль разряд
отображения в регистре режима. Бит 3 регистра режима (3D8H)
управляет отображением на дисплее. Если сбросить этот бит в 0,
экран погаснет. Чтобы переслать много данных в буфер цветного
дисплея, вы можете выключить отображение и переслать данные без
проверки бита состояния. Поскольку отображение выключено, на экране
не возникнут помехи. Когда пересылка блока закончится, включите
отображение. Вы заметите короткое мигание изображения в момент его
выключения и включения. Фирма IBM использует этот метод для
обслуживания вертикального сдвига цветного дисплея.