РЕФЕРАТ Техническое описание содержит 52 страницы машинописного текста, 2 рисунка, 4 таблицы и 2 приложения. Ключевые слова: микропрограмма, базовая система ввода/ вывода, графический контроллер, видео-функции, EGA, BIOS. На основании нескольких литературных и программных источников обобщены и представлены описание графического адаптера EGA, описание видео функций EGA_BIOS, основные подпрограммы, реализующие видео функции. Приведены примеры подпрограмм, дающие представление о назначении регистров адаптера и направленные на эффективное использование возможностей графического контроллера. СОДЕРЖАНИЕ ВВЕДЕНИЕ . . . . . . . . . . . . . . . . . . . . . . . . 5 1. ОСНОВНЫЕ ХАРАКТЕРИСТИКИ АДАПТЕРА EGA 1.1. ОСНОВНЫЕ КОМПОНЕНТЫ АДАПТЕРА . . . . . . . . . . 6 1.2. РЕЖИМЫ РАБОТЫ АДАПТЕРА . . . . . . . . . . . . . 7 1.2.1. Алфавитно-цифровой режим . . . . . . . . 7 1.2.2. Графический режим . . . . . . . . . . . . 8 1.3. РЕГИСТРЫ АДАПТЕРА . . . . . . . . . . . . . . . 9 1.3.1. Внешние регистры адаптера . . . . . . . . 9 1.3.2. Регистры задатчика последовательностей . 10 1.3.3. Регистры видео-контроллера . . . . . . . 12 1.3.4. Регистры графического контроллера . . . . 13 1.3.5. Регистры контроллера атрибутов . . . . . 15 1.4. ИСХОДНЫЕ ЗНАЧЕНИЯ РЕГИСТРОВ АДАПТЕРА . . . . . . 17 1.5. КОНТАКТНАЯ КОЛОДКА АДАПТЕРА . . . . . . . . . . 18 2. ВИДЕО-ФУНКЦИИ BIOS . . . . . . . . . . . . . . . . . 19 3. ИСПОЛЬЗУЕМЫЕ АДРЕСА ОЗУ В ОБЛАСТИ ДАННЫХ BIOS . . . . 23 4. ОРГАНИЗАЦИЯ ВИДЕО-ОЗУ . . . . . . . . . . . . . . . . 25 4.1. Режим записи 0 . . . . . . . . . . . . . . . . . 25 4.2. Режим записи 2 . . . . . . . . . . . . . . . . . 26 4.3. Режимы чтения атрибутов точки . . . . . . . . . 27 ЗАКЛЮЧЕНИЕ . . . . . . . . . . . . . . . . . . . . . . . 28 СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ . . . . . . . . . . . . 29 ПРИЛОЖЕНИЕ 1. Примеры подпрограмм . . . . . . . . . . . 30 ПРИЛОЖЕНИЕ 2. Реализация основныx видео-функций . . . . 44 ВВЕДЕНИЕ Отсутствие информации в отечественной литературе о видео контроллере EGA персонального компьютера IBM PC/AT, а также естественное желание обнаружить непредставленные и неиспользованные возможности в стандартных графических библиотеках для ФОРТРАНА, ТУРБО-ПАСКАЛЯ, ТУРБО-СИ и других, побудили нас внимательно рассмотреть и обобщить имеющиеся литературные и программные источники, включая просмотр отладчиком программного обеспечения ПЗУ адаптера, а также на поиск дополнительного материала. Результаты этих усилий представлены в настоящем кратком техническом описании. - 2 - Наиболее существенным источником является, конечно, [1], однако по сравнению с имеющимся GENOA_EGA_BIOS 1986 года обнаружены серьезные отличия, проследить полностью которые потребовало бы значительно больше усилий. Кроме того, в [1] отражены не все режимы, описанные в [2] и заслуживающие применения. Значимость сведений о графическом адаптере EGA и видео функциях программного обеспечения BIOS, судя по источникам [3], где читаем "... программирование графики в OS/2 во многом то же самое, как и в DOS ...", и [4], где видим общность EGA и следующей разработки - VGA, утратится, по-видимому, еще не скоро. Неотъемлимой и наиболее информационной частью описания являются тексты документированных подпрограмм работы с регистрами графического контроллера и использования видео функций BIOS, приведенных в приложениях 1, 2. 1. ОСНОВНЫЕ ХАРАКТЕРИСТИКИ АДАПТЕРА EGA Графический адаптер EGA (Enhanced Graphics Adapter) обеспечивает вывод алфавитно-цифровой и графической информации на монохромные и цветные мониторы в различных режимах работы. К улучшенным свойствам контроллера по сравнению с предыдущим вариантом адаптера CGA отнесены возможная загрузка до 4-х знакогенераторов и графика, реализующая на двух страницах 640 на 350 точек, 16 цветов из 64 возможных. Здесь и далее речь преимущественно идет o режимах, реализованных в имеющейся конфигурации IBM PC/AT. 1.1. ОСНОВНЫЕ КОМПОНЕНТЫ АДАПТЕРА [1] Видео контроллер генерирует H и V синхросигналы и синхроимпульсы курсора, обеспечивает регенерацию динамической памяти адаптера и адресацию к видео буферу. Задатчик последовательностей генерирует основные временные последовательности обращения к динамической видео памяти. Позволяет процессору доступ к памяти во время активных интервалов вывода на дисплей. Регистры масок обеспечивают защиту памяти от изменений. Графический контроллер направляет данные из памяти контроллеру атрибутов и процессору. В графическом режиме данные памяти посылаются контроллеру атрибутов в последовательной форме, а в алфавитно-цифровом - параллельном виде. Графический контроллер форматирует данные для совместимости различных режимов и обеспечивает цветовое сравнение для выполнения операций закраски. Схемные особенности контроллера позволяют процессору писать 32 бита в один цикл обращения к памяти, (8 бит на плоскость) для быстрого отображения. Дополнительная логика позволяет процессору писать данные в формате, отличном от байта. Контроллер атрибутов - 3 - Контроллер управляет режимами мерцания и подчеркивания, обеспечивает цветовую палитру 16-ти цветов, каждый из которых может быть специфицирован отдельно. 6 цветовых выходов подаются на дисплей. Контроллер берет данные из памяти дисплея и преобразует их для представления на экране дисплея. Буфер дисплея Адрес дисплейного буфера может быть изменен для обеспечения совместимости с другими видео контроллерами и применяемым программным обеспечением. ПЗУ На плате адаптера находится ПЗУ с базовой системой ввода-вывода для связи с системным BIOS. ПЗУ содержит знакогенераторы и упрaвляющие коды. На адресном простанстве процессора ПЗУ начинается с С0000 (16К). Логика Логика платы выполнена на LSI микросхемах. Два источника синхросигналов 14 МГц и 16 МГц поддерживают битовую синхронизацию и мультиплексируются под управлением процессора. Режимы работы Следующая таблица 1.1 описывает режимы работы контроллера, поддерживаемые BIOS, с различными мониторами. Таблица 1.1 Режимы работы адаптера EGA +---------+-----+------+------+----------+-------+----------+ | Режим # |Цвета|Формат|Начало|Знакоместо|Страниц|Разрешение| +---------+-----+------+------+----------+-------+----------+ | IBM Color Display | | 0 a/ц | 16 | 40x25| B8000| 8x8 | 8 | 320x200 | | 1 a/ц | 16 | 40x25| B8000| 8x8 | 8 | 320x200 | | 2 a/ц | 16 | 80x25| B8000| 8x8 | 8 | 640x200 | | 3 a/ц | 16 | 80x25| B8000| 8x8 | 8 | 640x200 | | 4 граф | 4 | 40x25| B8000| 8x8 | 1 | 320x200 | | 5 граф | 4 | 40x25| B8000| 8x8 | 1 | 320x200 | | 6 граф | 2 | 80x25| B8000| 8x8 | 1 | 640x200 | | D граф | 16 | 40x25| A0000| 8x8 | 2/4/8 | 320x200 | | E graf | 16 | 80x25| A0000| 8x8 | 1/2/4 | 640x200 | +---------+-----+------+------+----------+-------+----------+ | IBM Monochrome Display | | 7 а/ц | 4 | 80x25| B0000| 9x14 | 8 | 720x350 | | F граф | 4 | 80x25| A0000| 8x14 | 1/2 | 640x350 | +---------+-----+------+------+----------+-------+----------+ | IBM Enchanced Color Display | | =========================== | | 0 a/ц |16/64| 40x25| B8000| 8x14 | 8 | 320x350 | | 1 a/ц |16/64| 40x25| B8000| 8x14 | 8 | 320x350 | | 2 a/ц |16/64| 80x25| B8000| 8x14 | 8 | 640x350 | | 3 a/ц |16/64| 80x25| B8000| 8x14 | 8 | 640x350 | | 10 граф |16/64| 80x25| A0000| 8x14 | 2 | 640x350 | +---------+-----+------+------+----------+-------+----------+ - 4 - 1.2. РЕЖИМЫ РАБОТЫ АДАПТЕРА 1.2.1. Алфавитно-цифровой режим Формат данных в алфавитно-цифровом режиме для EGA тот же, что и для CGA. В качестве дополнительной функции третий бит байта атрибута может быть переопределен в регистре выбора знакогенератора для переключения между установленными фонтами. 512 символов становятся доступными одновременно. Функция действительна лишь для расширенной памяти 128К и более. Когда выбран а/ц режим, BIOS посылает образ символа из ПЗУ в битовую плоскость 2. Процессор запоминает символьные данные в битовой плоскости 0, а атрибуты в плоскости 1. Видеоконтроллер генерирует последовательные адреса и принимает байты кода символа и кода атрибута за одно обращение. Код символа определяет адрес в битовой плоскости 2, которая содержит генераторы символов. Соответствующий графический образ посылается в контроллер атрибутов, где согласно атрибутам выбирается цвет. 1.2.2. Графический режим 320х200 два и четыре цвета в режимах 4 и 5. Адресация и формат данных аналогичны 320х200 режима CGA. Буфер дисплея начинается с адреса B8000. Образ битовых данных запоминается в битовых плоскостях 0 и 1. 640х200 два цвета в режиме 6. Адресация и формат данных аналогичен черно-белому режиму 640х200 адаптера CGA. Буфер дисплея начинается с адреса B8000. Образ битовых данных запоминается в битовой плоскости 0. 640х350 монохромный режим F. Режим поддерживается со следующими атрибутами: черный, видимый, мерцающий видимый и яркий видимый. Требует 56К байт. Связывая карты 0 и 1, а также 2 и 3, можно сформировать две 32К битные плоскости. Такое связывание выполняется, когда необходимо (графическая память меньше 128 К). Вторая битовая плоскость содержит биты интенсивностей. Обе плоскости расположены по адресу A0000. Два бита, один на каждую плоскость, определяют один графический элемент (pel - picture element) на экране. Определения элементов даны в следующей таблице 1.2, где C0,C2 обозначают биты плоскостей видео памяти (основной и интенсивностей соответственно). Таблица 1.2 Атрибуты монохромного режима +----+----+-------------------+-------------------+ | C2 | C0 | цвет точки | возможный атрибут | +----+----+-------------------+-------------------+ | 0 | 0 | черный | 0 | | 0 | 1 | видимый | 3 | | 1 | 0 | мерцающий видимый | C | | 1 | 1 | яркий видимый | F | +----+----+-------------------+-------------------+ - 5 - В памяти последовательная байтовая организация. Первые 8 графических элементов на экране определяются содержанием памяти A000:0H, вторые - A000:1H, и т.д. Первый графический элемент - крайний левый на экране, внутри байта определяется битом 7, последний - битом 0. Монохромная графика работает в четно/нечетном режиме, означающем, что четные адреса поступают на четную битовую плоскость, а нечетные - на нечетную битовую плоскость. Т.к. обе битовые плоскости расположены по адресу A0000, пользователь должен установить требуемую через масочный регистр задатчика последовательностей. 16/64 цветной графический режим 10h. Этот режим поддерживает 16-ти цветную графику на мониторах среднего или высокого разрешения. Режим используют все 4 битовые плоскости. Каждая битовая плоскость представляет цвет: C0 = синий ....... (B), C1 = зеленый ..... (G), C2 = красный ..... (R), C3 = интенсивность (I). Четыре бита (1 из каждой плоскости) определяют один графический элемент на экране. Комбинации цветов приведены в следующей таблице 1.3 Таблица 1.3 Возможный цвета режима 10h +---+---+---+---+--------------------+ | 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 | белый | +---+---+---+---+--------------------+ Дисплейный буфер начинается с адреса A0000. Масочный регистр используется для выбора какой-либо или всех битовых плоскостей для записи. 1.3. РЕГИСТРЫ АДАПТЕРА 1.3.1. Внешние регистры * В скобках () повторяется адрес регистра. Регистр общего назначения (3C2)* бит 7 6 5 4 3 2 1 0 | | | | | | | +-- выбор адреса, 1=3Dx;0=3Bx. - 6 - | | | | | | +---- 1=разрешает доступ процессору к ОЗУ. | | | | +-+------ 00=14МГц;01=16МГц; | | | | 10=внешний тактовый генератор. | | | +---------- 1=запрещает внутреннее управление видео, | | | управление с контактной колодки. | | +------------ 1=выбирает старшую страницу памяти в | | четно/нечетных режимах | | (режимы 0,1,2,3,7). | +-------------- 1=выбирает отрицательный импульс | горизонтального обратного хода. +---------------- 1=выбирает отрицательный импульс вертикального обратного хода. Регистр признаков  (3DA) бит 1 0 | +------------- вывод 19 контактной колодки адаптера +--------------- вывод 17 контактной колодки адаптера Входной статусный регистр 0. Только читается. (3C2) бит 7 4 | +------------ 1=позволяет процессору читать состояние | 4-х битного переключателя конфигурации | адаптера (в ОЗУ 40:88h). +--------------- бит прерывания: 1=происходит вывод на экран; 0=обратный ход луча по вертикали. Входной статусный регистр 1. Только читается. (3DA) бит 5 4 3 2 1 0 | | | | | +----- 0=свидетельствует об обратном | | | | | горизонтальном или вертикальном | | | | | ходе луча. | | | | +------- строб светового пера. | | | +--------- 0=кнопка пера нажата. | | +----------- 1=обратный вертикальный ход. Бит может | | быть использован для прерывания REQ2 | | (для XT) через биты 5 и 6 регистра 11h | | видео контроллера. +-+------------- разряды диагностики, подсоединяются к двум из 6-ти цветовых выходов контроллера атрибутов. Возможны комбинации: +---------+--------+---------+---------+ | Регистр цветовой | Входной статусный | | плоскости | регистр 1 | +---------+--------+---------+---------+ | бит 5 | бит 4 | бит 5 | бит 4 | +---------+--------+---------+---------+ | 0 | 0 | красный | синий | | 0 | 1 |яр.синий | зеленый | | 1 | 0 |яр.красн.|яр.зелен.| +---------+--------+---------+---------+ 1.3.2. Регистры задатчика последовательностей +------------------------+------+--------+ | Имя регистра | Порт | Индекс | +------------------------+------+--------+ - 7 - | Адрес | 3C4 | - | | Сброс | 3C5 | 0 | | Режим синхронизации | 3C5 | 1 | | Маска | 3C5 | 2 | | Выбор знакогенератора | 3C5 | 3 | | Режим памяти | 3C5 | 4 | +------------------------+------+--------+ Регистр сброса. (3C5/0) бит 1 0 | +--------- асинхронный сброс,0=перевод выходов в третье | состояние. +----------- синхронный сброс, используемый при смене ре- жимов синхронизации. Регистр режима синхронизации. (3C5/1) бит 3 2 1 0 | | | +----- 0=ширина символа 9 точек, действителен в | | | режиме 7, в остальных ширина 8 точек. | | +------- 0=обращение контроллера к ОЗУ занимает 4 | | цикла из 5-ти возможных, необходимы в | | режиме высокого разрешения. | | 1=обращение контроллера к ОЗУ занимает 2 | | цикла; в режиме среднего разрешения, когда | | объем передаваемых данных меньше, позволяет | | уменьшить время доступа процессора к видео- | | ОЗУ. | +--------- 1=параллельно-последовательный преобразователь | перезагружается лишь на каждый отличающийся | символ. | 0=перезагружается на каждый символ. +----------- 1=частота синхросигнала делится на 2. Регистр маски. (R/W) (3C5/2) бит 3 2 1 0 | | | +----- 1=разрешен доступ к плоскости 0. | | +------- 1=разрешен доступ к плоскости 1. | +--------- 1=разрешен доступ к плоскости 2. +----------- 1=разрешен доступ к плоскости 3. 0Fh в регистре диктует процессору производить за ОДИН цикл памяти 32-х разрядные операции. В четно/нечетном режиме карты 0-3 будут иметь одинаковые маски. Регистр выбора знакогенератора (3C5/3) бит 3 2 1 0 | | +-+----- выбор карты B; Когда бит_3 байта атрибутов=0, | | действительна следующая таблица | | +----------+---------------+--------------------+ | | | биты 1,0 | выбрана карта | расположение | | | +----------+---------------+--------------------+ | | | 0 0 | 0 | 1-e 8K пл.2,банк 0 | | | | 0 1 | 1 | 2-e 8K пл.2,банк 1 | | | | 1 0 | 2 | 3-e 8K пл.2,банк 2 | | | | 1 1 | 3 | 4-e 8K пл.2,банк 3 | | | +----------+---------------+--------------------+ +-+--------- выбор карты A; Когда бит_3 байта атрибутов=1, действительна следующая таблица - 8 - +----------+---------------+--------------------+ | биты 3,2 | выбрана карта | расположение | +----------+---------------+--------------------+ | 0 0 | 0 | 1-e 8K пл.2,банк 0 | | 0 1 | 1 | 2-e 8K пл.2,банк 1 | | 1 0 | 2 | 3-e 8K пл.2,банк 2 | | 1 1 | 3 | 4-e 8K пл.2,банк 3 | +----------+---------------+--------------------+ В текстовом режиме 3-й бит атрибутов обычно включает или выключает повышенную яркость символа, однако может быть использован в качестве переключателя между знакогенера- торами, когда выбраны различные значения для карт A и B. Бит 1 регистра режима памяти должен быть равен 1, иначе всегда выбирается банк 0. Для 128К возможны 2 знакогене- ратора, для 256К - 4. Пример переключения знакогенератора дан в приложении 1 программа two_Fonts. Регистр режима памяти (3C5/4) бит 2 1 0 | | +-------- 1=выбран текстовый режим, возможен выбор | | знакогенератора. | +---------- 1=используется расширенная память. +------------ 0=четные адреса процессора адресуют к картам 0 и 2, нечетные к 1 и 3, как в CGA. 1=последовательный доступ к данным в битовой плоскости. Доступ к плоскостям осуществляется в соответствии со значением в регистре масок. 1.3.3. Регистры видео контроллера (3C4/3C5) +-----------------------------------------+------+------+ | Имя регистра |единиц|Индекс| +-----------------------------------------+------+------+ | индексный | | - | | по горизонтали всего | сим | 00 | | размер отoбражаемого по горизонтали | сим | 01 | | начало невидимой области по горизонтали | сим | 02 | | конец невидимой области по горизонтали | сим | 03 | | начало строчного импульса | сим | 04 | | конец строчного ипмульса | сим | 05 | | по вертикали всего (младшие 8 разрядов) |строка| 06 | | регистр переполнений | | 07 | | начало видимой области по вертикали |строка| 08 | | размер символа по вертикали |строка| 09 | | начало курсора |строка| 0A | | конец курсора |строка| 0B | | начальный адрес видео (старший байт) | | 0C | | начальный адрес видео (младший байт) | | 0D | | положение курсора (старший байт) | | 0E | | положение курсора (младший байт) | | 0F | | начало кадрового имульса (младшие) |строка| 10 | | адрес светового пера (старший байт) | | 10 | - 9 - | конец кадрового импульса |строка| 11 | | адрес светового пера (младший байт) | | 11 | | конец видимой области по вертикали |строка| 12 | | логическая длина линии экрана | | 13 | | положение подчеркивания |строка| 14 | | начало невидимой области V (младшие) |строка| 15 | | конец невидимой области V(младшие 5 бит)|строка| 16 | | режим управления | | 17 | | сравнение строк | | 18 | +-----------------------------------------+------+------+ Регистры видеоконтроллера во многом аналогичны регистрам микросхемы 6845 адаптера CGA [5]. О регистре 11h следует сказать особо: разряды 5 4 | +-- 0=сброс прерывания, +---- 0=разрешение прерывания. 1.3.4. Регистры графического контроллера +-----------------------+------+--------+ | Имя регистра | Порт | Индекс | +-----------------------+------+--------+ | Позиционный 1 | 3CC | - | = 0 | Позиционный 2 | 3CA | - | = 1 | Индексный | 3CE | - | | Установка/Сброс | 3CF | 0 | | Разрешение установки | 3CF | 1 | | Сравнение цвета | 3CF | 2 | | Циклического сдвига | 3CF | 3 | | Масочный чтения | 3CF | 4 | | Регистр режима | 3CF | 5 | | Смешаный | 3CF | 6 | | Игнорирование цвета | 3CF | 7 | | Разрядная маска | 3CF | 8 | +-----------------------+------+--------+ Регистр установки/сброса (3CF/0) бит 3 2 1 0 | | | | +-+-+-+----- установка/сброс плоскостей 0,1,2,3 Регистр разрешения установки/сброса (3CF/1) бит 3 2 1 0 | | | | +-+-+-+----- разрешение установки/сброса плоскостей 0,1,2 3 Регистр сравнения цвета (3CF/2) бит 3 2 1 0 | | | | +-+-+-+----- 0,1,2,3 Если процессор устанавливает режим чтения 1 графического контроллера и читает память, данные, возвращаемые из памяти, содержат 1 в каждом бите, где значение 4-х битовой плоскости совпало со значением в регистре сравнения цветов. - 10 - Регистр циклического сдвига (3CF/3) бит 4 3 2 1 0 | | | | | | | +-+-+--- счетчики 0 1 2; содержат значение числа | | позиций, на которые сдвинутся данные про- | | цессора во время записи в память. Эта | | операция выполняется, когда режим записи 0. +-+--------- выбор функции логической операции с данными: 0 0 = данные не изменяются, 0 1 = AND, 1 0 = OR, 1 1 = XOR. Циклический сдвиг выполняется до логической операции. Регистр выбора карты чтения (3CF/4) бит 2 1 0 +-+-+------- карты 0,1,2; представляют значение номера плоскости, из которой процессор читает данные. Смотри пример check_Color. Регистр режима (3CF/5) бит 5 4 3 2 1 0 | | | | +-+- режим записи; | | | | 0 0 = каждая плоскость записывается данными | | | | процессора в соответствии с регистрами | | | | масок и циклического сдвига. Плоскости, | | | | для которых разрешены установка/сброс | | | | записываются 8 битами, значение которых | | | | содержится в соответствующем разряде | | | | регистра сброса/установки. | | | | 0 1 = каждая плоскость м.б. переписана в дру- | | | | гую через регистры-защелки, содержимое | | | | регистров масок игнорируется. | | | | 1 0 = альтернативный способ записи точки | | | | плоскости N(0..3) заполняются значениями | | | | бита N данных согласно регистр | | | | разрядной маски. | | | +----- 1=переводит выходы графического контроллера | | | в высокоимпедансное состояние для проверки. | | +------- 0=процессор читает данные из плоскости | | памяти, выбранной регистром выбора карты | | чтения. | | 1=процессор читает результат сравнения 4-х | | плоскостей и регистра сравнения цвета. | +--------- 1=выбирает четно/нечетный режим адресации, | используемый при эмуляции CGA. +----------- 1=регистры сдвига переключают поток данных на четные или нечетные плоскости. Использованию различных режимов чтения, записи посвящены подпрограммы Drow_point и check_Color. Смешаный регистр (3CF/6) бит 3 2 1 0 | | | +----- 1=выбирает графический режим, адресация к | | | знакогенератору запрещена. | | +------- 1=связывет четную карту с нечетной - 11 - +-+--------- 0 0 - A000 для 128 К, 0 1 - A000 для 64 К, 1 0 - B000 для 32 К, 1 1 - B800 для 32 К. Если адаптер адресуется с A0000 в системе не может быть использован дополнительный адаптер. Регистр игнорирования цвета (3CF/7) бит 3 2 1 0 +-+-+-+----- плоскости 0,1,2,3. 0=соответствующая плоскость игнорируется при сравнении (подпрограмма check_Color). Регистр маски (3CF/8) бит 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-- 0=предохраняет соответствующий бит от изменений при записи байта данных. Маска используется для всех плоскостей одновременно. 1.3.5. Регистры контроллера атрибутов +--------------------------------+------+--------+ | Имя регистра | Порт | Индекс | +--------------------------------+------+--------+ | Адресации | 3C0 | - | | Регистры палитры | 3C0 | 00-0F | | Управление режимом | 3C0 | 10 | | Регистр цвета окантовки | 3C0 | 11 | | Разрешение цвет. плоскости | 3C0 | 12 | | Горизонтальный сдвиг | 3C0 | 13 | +--------------------------------+------+--------+ Адресный регистр (3C0/0) бит 5 4 3 2 1 0 | +-+-+-+-+--- адрес атрибутов. | Контроллер атрибутов не имеет возможности | контролировать выбор адресного или регистра данных. | Внутренний триггер выбирает адресный регистр или | регистр данных. Обращение по адресу 3DA сбрасывает этот | триггер и выбирает адресный регистр (см. программу | Screen_Shock). Следующая инструкция OUT загружает | регистр данных. +------------- 1=доступ со стороны контроллера разрешен, 0=загрузка регистров данными. Регистры палитры (3C0/0-F) бит 5 4 3 2 1 0 | | | | | +--- B R,G,B == 2/3 интенсивности | | | | +----- G r,g,b == 1/3 интенсивности | | | +------- R | | +--------- b /при эмуляции MONO - подчеркивание, | +----------- g /при эмуляции - интенсивность, +------------- r Позволяют динамически переключать атрибуты - 12 - текста или цвет в графическом режиме. Для избежания мерцания изображения модифицировать регистры палитры необходимо во время вертикального обратного хода луча. Мониторы, имеющие 6 входов цветности, дают 64 цвета. Регистр режима. (3C0/10) бит 3 2 1 0 | | | +------- 0/1=выбирается текстовый/графический режим. | | +--------- 0/1=монохромный/цветной режим. | +----------- 0=9-я точка имеет цвет фона, | 1=разрешены специальные графические символы. +------------- 0=выбирает фоновую интенсивность, 1=разрешает мерцание в текстовом и графи- ческом режимах. Регистр цвета окантовки. (3C0/11) бит 5 4 3 2 1 0 | | | | | +--- B | | | | +----- G | | | +------- R | | +--------- b | +----------- g +------------- r Подпрограмма Edge задания цвета края экрана приведена в приложении 1. Регистр разрешения цветовой плоскости (3C0/12) бит 5 4 3 2 1 0 | | +-+-+-+--- 1=разрешает соответствующую плоскость +-+----------- выбирают 2 из 6-ти цветов для входного статусного региста. +--------------------+-------------------------+ | Регистр разрешения | Входной стат. регистр 1 | | разряды 5 4 | разряды 5 4 | +--------------------+-------------------------+ | 0 0 | R B | | 0 1 | b G | | 1 0 | r g | +--------------------+-------------------------+ Подпрограмма to_Blue выбора цветовой плоскости приведена в приложении 1. Регистр горизонтального сдвига (3C0/13) бит 3 2 1 0 +-+-+-+------- представляет число графических элементов сдвига видео данных влево: в монохромном режиме максимум на 9, в остальных на 8. Подпрограмма Screen_Shock использования регистра приведена в приложении 1. 1.4. ИСХОДНЫЕ ЗНАЧЕНИЯ РЕГИСТРОВ АДАПТЕРА Таблица 1.4 Значения регистров адаптера в режимах 3 и 10h, загружаемые по включению питания [1]. - 13 - +-----------------------------------------+--------+----+----+ | Внешние регистры 10h 03 +-----------------------------------------+--------+----+----+ | общего назначения | 3C2 | A7 | A7 | | признаков | 3DA | 00 | 00 | +-----------------------------------------+--------+----+----+ | Регистры задатчика последовательностей +-----------------------------------------+--------+----+----+ | сброса | 3C5/00 | 03 | 03 | | режим синхронизации | 3C5/01 | 01 | 01 | | маска карты | 3C5/02 | 0F | 03 | | выбор знакогенератора | 3C5/03 | 00 | 00 | | режим памяти | 3C5/04 | 06 | 03 | +-----------------------------------------+--------+----+----+ | Регистры видео контроллера +-----------------------------------------+--------+----+----+ | общий размер по горизонтали | 3D5/00 | 5B | 5B | | размер отображаемого по горизонтали | 3D5/01 | 4F | 4F | | начало невидимой области по горизонтали | 3D5/02 | 53 | 53 | | конец невидимой области по горизонтали | 3D5/03 | 37 | 37 | | начао строчного импульса | 3D5/04 | 52 | 51 | | конец строчного импульса | 3D5/05 | 00 | 5B | | общий размер по вертикали | 3D5/06 | 6C | 6C | | регистр переполнений | 3D5/07 | 1F | 1F | | начало видимой области по вертикали | 3D5/08 | 00 | 00 | | размер символа по вертикали | 3D5/09 | 00 | 0D | | начало курсора | 3D5/0A | 00 | 0B | | конец курсора | 3D5/0B | 00 | 0C | | начало кадрового импульса | 3D5/10 | 5E | 5E | | конец кадрового импульса | 3D5/11 | 2B | 2B | | конец видимой области по вертикали | 3D5/12 | 5D | 5D | | длина линии экрана | 3D5/13 | 28 | 28 | | положение подчеркивания | 3D5/14 | 0F | 0F | | начало невидимой области по вериткали | 3D5/15 | 5F | 5E | | конец невидимой области по вертикали | 3D5/16 | 0A | 0A | | режим управления | 3D5/17 | E3 | A3 | | сравнение строк | 3D5/18 | FF | FF | +-----------------------------------------+--------+----+----+ | Регистры графического контроллера +-----------------------------------------+--------+----+----+ | установка/сброс | 3CF/00 | 00 | 00 | | разрешение установки/сброса | 3CF/01 | 00 | 00 | | сравнение цвета | 3CF/02 | 00 | 00 | | циклический сдвиг | 3CF/03 | 00 | 00 | | выбор карты чтения | 3CF/04 | 00 | 00 | | режим | 3CF/05 | 00 | 10 | | общий | 3CF/06 | 05 | DE | | игнорирование цвета | 3CF/07 | 0F | 00 | | разрадная маска | 3CF/08 | FF | FF | +-----------------------------------------+--------+----+----+ | Регистр атрибутов +-----------------------------------------+--------+----+----+ | | 3C0/00 | 00 | 00 | | | 3C0/01 | 01 | 01 | | | 3C0/02 | 02 | 02 | | | 3C0/03 | 03 | 03 | - 14 - | | 3C0/04 | 04 | 04 | | | 3C0/05 | 05 | 05 | | | 3C0/06 | 14 | 14 | | | 3C0/07 | 07 | 07 | | | 3C0/08 | 38 | 38 | | | 3C0/09 | 39 | 39 | | | 3C0/0A | 3A | 3A | | | 3C0/0B | 3B | 3B | | | 3C0/0C | 3C | 3C | | | 3C0/0D | 3D | 3D | | | 3C0/0E | 3E | 3E | | | 3C0/0F | 3F | 3F | | управление режимом | 3C0/10 | 10 | 08 | | окантовка экрана | 3C0/11 | 00 | 00 | | цветовая плоскость | 3C0/12 | 0F | 0F | | горизонтальный сдвиг | 3C0/13 | 00 | 00 | +-----------------------------------------+--------+----+----+ 1.5. КОНТАКТНАЯ КОЛОДКА АДАПТЕРА 1 GND - общий 2 -12 3 +12 4 J1 - соединен с дополнительным разъемом 1 на панели 5 J2 - соединен с дополнительным разъемом 2 на панели 6 g_out - выход g 7 r_out - выход r 8 b_out - выход b 9 ATRS/L - синхро-сигнал загрузки сдвигового регистра 10 B_out - выход B 11 G_out - выход G 12 G - вход G 13 r - вход r 14 B - вход B 15 R - вход R 16 R_out - выход R 17 FEAT1 - состояние разряда 6 статусного регистра 0 18 BLANK - невидимая часть изображения 19 FEAT0 - состояние разряда 5 статусного регистра 0 20 FC1 - разряд 1 регистра признаков 21 FC0 - разряд 0 регистра признаков 22 g/I - g/ интенсивность (вход) 23 b/V - вход b/ видео монохромного дисплея 24 HIN - строчный синхроимпульс с видео контроллера 25 VIN - кадровый синхроимпульс с видео контроллера 26 14 MHz - с системной платы 27 internal - разряд 4 выходного регистра 28 EXT OSC - внешняя синхронизация 29 VOUT - кадровый синхроимпульс 30 HOUT - строчный синхроимпульс 31 GND - общий 32 +5 2. ВИДЕО-ФУНКЦИИ BIOS [2] Работа с видео-контроллером выполняется как правило с - 15 - использованием стандартного обеспечения BIOS, расположенного в ПЗУ контроллера в данном случае размером 16К байт с начальным адресом на шине процессора C0000h. Ниже представлены возможные видео-функции, вызываемые с помощью прерывания 10h [6,7,8]. 00h Установка режима AH=00h, AL=режим из приведенной выше таблицы 1.1. Функция не очищает экран, если старший бит AL установлен в 1. 01h Установка курсора в текстовом режиме AH=01h, CH=начало курсора (разряды 0-4), CL=конец курсора (разряды 0-4). Сделать курсор невидимым можно установив его на строку 25 или задав CH, равным высоте символа. Форма курсора устанавливается для всех страниц одинаковой (подпрограмма Cursor).  02h Позиционирование курсора AH=02h, BH=страница, DH=строка (0-24), DL=столбец (0-79). В графическом режиме определяется логическое положение курсора (подпрограмма VGA_cls). 03h Чтение координат и формы курсора AH=03h, DH=страница. Возвращает: CH=начало курсора, CL=конец курсора, DH=строка координата, DL=столбец координата. 05h Установка активной страницы AH=05h, AL=номер страницы (0-1 для режима 10h, (0-3 для режима 03h) 06h  Сдвиг окна вверх AH=06h, AL=число смещаемых строк, BH=значение атрибута для освобождаемой области, CH=верхняя строка окна, CL=левый столбец окна, DH=нижняя строка окна, DL=правый столбец окна. Подпрограмма VGA_cls. 07h Сдвиг окна вниз AH=07h, AL=число смещаемых строк, BH=значение атрибута для освобождаемой области, CH=верхняя строка окна, - 16 - CL=левый столбец окна, DH=нижняя строка окна, DL=правый столбец окна. 08h Чтение символа и атрибута, адресуемых курсором AH=08h, BH=страница. Возвращает: AH=атрибут символа, AL=символ. 09h Вывод адресуемого курсором символа с атрибутом AH=09h, AL=ASCII код символа, BH=страница, BL=атрибут, CX=число печатаемых символов. Курсор во время печати не перемещается. В текстовом режиме в конце строки выполняется переход на новую, управляющие коды (BELL,LF,CR) функций не выполняют, а печатаются. В графическом режиме если старший разряд байта атрибутов установлен, символ печатается с выполнением функции XOR. Близкая реализация дана в приложении 2 программе EGA. 0Ah Вывод символа, адресуемого курсором AH=0Ah, AL=ASCII код символа, BH=страница, CX=число печатаемых символов. Курсор во время печати не перемещается. Аналогична функции 09, за исключением использования атрибутов. 0Bh Установка цветовой палитры (для режима среднего разрешения) AH=0Bh, Близкая реализация дана в приложении 2 программе EGA. 0Ch Запись точки AH=0Ch, AL=цвет точки (0-15), CX=X-координата (0-639, для режима 10h), DX=Y-координата (0-349, для режима 10h), BH=страница (0-1, для режима 10h). Реализация функции представлена в приложении 2 программе EGA. 0Dh Чтение точки AH=0Dh, CX=X-координата, DX=Y-координата, BH=страница. Возвращает: AL=цвет точки. Близкая реализация функции представлена в приложении 2. - 17 - 0Eh Печать символа с продвижением курсора AH=0Eh, AL=ASCII код символа, BL=цвет в графическом режиме, BH=страница. Действительны символы управления BELL, BS, CR, LF. В текстовом режиме действительны атрибуты предыдущей печати на текущем знакоместе. В графическом - необходимо задание цвета в регистре BL. 0Fh Определение текущего режима AH=0Fh. Возвращает: AL=режим, AH=число символов в строке, BH=номер активной страницы. Смотри пример VGA_cls в приложении 1. 10h Загрузка палитры AH=10h, AL=0 - установка регистров палитры, BL=регистр, BH=значение: разряды 7 6 5 4 3 2 1 0 . . r g b R G B ----- ===== интенсивность 1/3 2/3 AL=1 - установка регистра окантовки, BH=значение. AL=2 - установка регистров палитры и окантовки, ES:DX - указатель на таблицу зачений длиной 17 байтов (последний - окантовка). AL=3 - переключатель интенсивность/мерцание значения разряда 7 атрибута, BL=0 -- определяет мерцание символа, BL=1 -- определяет интенсивность фона. Возможная реализация функции представлена в приложении 2.  11h Загрузка знакогенератора AH=11h, AL=00h-знакогенератор пользователя (текст), ES:BP=указатель на таблицу, CX=число символов, DX=смещение в таблице, BL=блок (0-3), BH=число байтов на символ. AL=01h-знакогенератор ROM 8х14 (моно), BL=блок (0-3). AL=02h-знакогенератор ROM 8х8 двойной (текст), BL=блок (0-3). AL=03h-установка определенного блока (текст), BL= разряды 3 2 1 0 === --- | +-- когда сброшен | бит_3 атрибута, +-- когда установлен бит_3 аттрибута AL=10h-знакогенератор пользователя (текст), - 18 - ES:BP=указатель на таблицу, CX=число символов, DX=смещение в таблице, BL=блок (0-3), BH=число байтов на символ. AL=11h-знакогенератор 8х14 (моно), BL=блок (0-3). AL=12h-знакогенератор 8х8 двойной (текст), BL=блок (0-3). AL=20h-знакогенератор пользователя 8х8 (граф), ES:BP=указатель на таблицу для символов 128-255 (INT 1Fh для режимов < 7). AL=21h-знакогенератор пользователя (граф), ES:BP=указатель на таблицу символов 0-255 (INT 43h для режимов > 7). CX=число байт на символ, BL=индекс: 00-DL=число строк, 01-14 строк, 02-25 строк, 03-43 строки. AL=22h-знакогенератор 8х8 (граф), BL=индекс. AL=23h-знакогенератор 8х8 двойной (граф), BL=индекс. AL=30h-возвращает информацию о знакогенераторе, BH=индекс указателя: 0-текущий для INT 1Fh, 1-текущий для INT 43h, 2-ROM 8x14, 3-ROM 8x8 двойной, 5-ROM 9x14 альтернативный. Возвращает: ES:BP=указатель, CX=число линий на символ, DL=число линий. Функции 10h, 11h и 12h перепрограммируют регистры видео-контроллера и поэтому должны следовать за установкой режима. Пример загрузки 2-х знакогенераторов в алфавитно/цифровом режиме и печать в одной строке двумя одновременно без потери управления яркостью представлен в приложении 1 (подпрограмма two_Fons). 13h Печать строки символов AH=13h, BH=страница, BL=атрибут (для AL=0,1), CX=длина строки, DH=строка координата, DL=столбец координата, ES:BP=указатель на строку, AL=0: все символы с атрибутами в BL, курсор не устанавливается; AL=1: все символы с атрибутами в BL, курсор устанавливается; AL=2: атрибуты в строке, - 19 - курсор не устанавливается; AL=3: атрибуты в строке, курсор устанавливается; Функция работает и в текстовом и графическом режимах, сохраняя за собой подгруженный в EGARUS знакогенератор. 15h Чтение характеристик дисплея AH=15h, Возвращает [8]: AX=индекс типа дисплея: 5153h-color, 5151h-mono. ES:DI=указатель на таблицу длиной 7 слов 1: номер модели дисплея, 2: точек на метр по вертикали, 3: точек на метр по горизонтали, 4: число точек по вертикали, 5: число точек по горизонтали, 6: высота точки в микрометрах, 7: ширина точки в микрометрах. 3. ИСПОЛЬЗУЕМЫЕ АДРЕСА ОЗУ В ОБЛАСТИ ДАННЫХ BIOS адрес байт функция а/ц --------------------------------------------------------------- 449 1 текущий режим адаптера (3) 44A 2 ширина экрана в символах (50h) 44C 2 длина видео буфера в байтах (1000h) 44E 2 смещение для активной страниц (0) 450 16 кординаты курсоров два байта на каждый: младший - столбец, старший - строка 460 2 форма курсора 462 1 текущая активная строка (0) 463 2 базовый адрес видео-контроллера (3D4h) 484 1 число строк на экране - 1 (18h) 485 2 высота символа (0Eh) 487 1 7 6 5 4 3 2 1 0 (60h) | === | | | +- 1=эмуляция курсора разрешена, | | | | +--- 1=монохромный дисплей, | | | +----- 1=включено ожидание обратного | | | хода, | | +------- 1=EGA не активна, | +------------ 11=256K байт ОЗУ, +--------------- старший бит байта режима. 488 1 7 6 5 4 3 2 1 0 (0F9h) ======= ------- | +---- состояние переключателя | адаптера, +------------ разряды признаков из статусных регистров. 4A8 4 указатель на блок данных адаптера: (C000:19FA) +00 -- адрес таблицы видео-параметров, (C000:1A60) длина таблица 1472 байт, по 64 на каждый режим работы адаптера, +04 -- адрес таблицы динамических параметров, - 20 - +08 -- адрес данных о дополнительном текстовом знакогенераторе, +0C -- адрес данных о дополнительном графическом знакогенераторе. 4. ОРГАНИЗАЦИЯ ВИДЕО ОЗУ В режиме 640х350 видео память представляет собой 4 битовых плоскости, расположенные в одном адресном пространстве, когда одному разряду байта соответствует одна точка. Организация отображения видео буфера на экран в режиме EGA 16 цветов следующая: адрес А0000 А0001 А0002.. +--------------------- разряд |765432107654321076543.. <= 1-я линия Запись и представление точки на экране определяется состоянием дополнительных регистров: регистра разрядной маски (8 бит), а также регистра Разрешения Установки/сброса (4 бита) и регистра Установки/сброса (4 бита) в режиме записи 0 (см. п.1.3.4). 4.1. Режим записи 0 Регистр разрядной маски (3CF/8) определяет разряды байта, которые могут быть изменены в видео ОЗУ при записи. Установленный разряд в регистре Разрешения Установки/сброса (3CF/1) при обращении к видео ОЗУ устанавливает или сбрасывает все 8 разрядов в зависимости от состояния соотвествующего разряда регистра Установки/Сброса (3CF0). Байт плоскости, не выбранной маской, останется неизменным (на рис.4.1 - плоскость, заполненная "u"), если установлен соответствующий разряд регистра Установки/сброса и не установлен регистр маски плоскости. Взаимодействие регистров граф.контроллера в режиме 0 [2] Плоскости 3 2 1 0 видео +-+ +-+ +-+ +-+ ОЗУ +-+ +-+ +-+ +-+ A000:0002 +-+ +-+ +-+ +-+ A000:0001 | | | | | | | | A000:0000 | | | | | | | | Адреса +-+ +-+ +-+ +-+ видео | | | | ОЗУ +-+ +-+ +-+ +-+ +-+ : |0|7 | | | | | | | | : останутся : |0| | | | | | | | | : неизменными |1| |0| |u| |1| |1| / 10111101B Регистр |1| |0| |u| |1| |1| < данные разрядной |1| |0| |u| |1| |1| < \ процессора маски ---------> |1| |0| |u| |1| |1| < 3CF/8 |1| |0| |u| |0| |0| < |1|0 |0| |u| |1| |1| < регистры-защелки +-+ +-+ +-+ +-+ +-+ - 21 - | | | | u-останется неизменным 00000000B-----> + + +<--10111101B / / / / \ \ \ \ 3CF/1 +---------+ +---------+ 3C5/2 Регистр Разрешения | 1 0 0 0 | | 0 0 1 1 | Регистр Установки/сброса +---------+ +---------+ маски цвета | | | | +---------+ 3CF/0 Регистр | 0 1 1 0 | Установки/сброса +---------+ Рис. 4.1 Важно отметить, что обмен с видео памятью происходит через регистры-защелки и требует независимо от производимой операции выполнять и чтение и запись. 4.2. Режим записи 2 Альтернативный режим установки цвета точки [2] безусловно окрашивает выбранные разрядной маской точки видео ОЗУ, при записи по выбранному адресу не байта данных, а 4-х разрядов атрибута. Взаимодействие регистров граф.контроллера в режиме 2 [2] Плоскость 3 2 1 0 видео +-+ +-+ +-+ +-+ ОЗУ +-+ +-+ +-+ +-+ A000:0002 +-+ +-+ +-+ +-+ A000:0001 | | | | | | | | A000:0000 | | | | | | | | +-+ +-+ +-+ +-+ Адреса | | | | видео +-+ +-+ +-+ +-+ +-+ ОЗУ : |0| | | | | | | | | : : |0| | | | | | | | | : <- останутся : |0| | | | | | | | | : неизменными : |0| | | | | | | | | : <= 1101B данные |1| |1| |1| |0| |1| < Регистр : |0| | | | | | | | | : < разрядной : |0| | | | | | | | | : < маски -------> : |0| | | | | | | | | : < регистры-защелки +-+ +-+ +-+ +-+ +-+ | | | | +--------------------+ | 1 1 1 1 | Регистр маски +--------------------+ цвета Рис. 4.2 - 22 - Пример по использованию режимов записи 0 и 2 Draw_Point дан в приложении 1. 4.3. Режимы чтения атрибутов точки Возможны 2 режима чтения атрибутов точки видео-буфера. В режиме чтения 0 последовательно могут быть прочитаны абсолютные значения разрядов каждой плоскости видео буфера. В режиме чтения 1, как правило, выполняется логическое чтение атрибутов точки, т.е. проверяется факт совпадения атрибута читаемой точки с установленным значением регистра цветового сравнения. В случае совпадения в соответствующем разряде байта при чтении возвращается единица. Дополнительно может использоваться регистр игнорирования цвета при сравнении, обеспечивающий функцию ИЛИ при этой логической операции. Подробно чтение в режиме 1 рассмотрено в приложении 1 программа Check_Color. ЗАКЛЮЧЕНИЕ На основании литературных и программных источников дано описание графического видео-адаптера EGA персональной ЭВМ IBM PC/AT, приведены тексты подпрограмм, иллюстрирующих назначение и использование регистров контроллера. Представлены подпрограммы, реализующие основные видео функции BIOS и дающие представление об организации видео ОЗУ и способах эффективной работы в графическом и текстовом режимах адаптера. В приложении 1 и 2 приведены тексты следующих программ: Screen_Shock -- использует регистр горизонтального сдвига; to_Blue -- иллюстрирует разрешение доступа контроллера к цветовой плоскости видео-ОЗУ; Edge -- устанавливает регистр окантовки экрана; Drow_Compare -- заполняет экран в двух различных режимах записи 0 и 2; Cursor -- устанавливает курсор невидимым; to_ -- с помощью прерывания 43h устанавливает новую таблицу символов и использует их в графическом режиме; two_Fonts -- в алфавитно-цифровом режиме загружает и использует 2 знакогенератора для печати в одной строке одновременно; VGA_cls -- используя программу для адаптера VGA, очищает экран, показывая преемственность программного обеспечения; g1 -- показывает взаимодействие регистров графического контроллера в режимах записи 0 и 1; g2 -- программа логического чтения атрибутов точки видео буфера; EGA -- подпрограммы, реализующие видео-функции BIOS: - построение точки (INT 0Ch), - чтение точки (INT 0Dh), - печать символа в а/ц режиме, - 23 - - печать символа в графическом режиме, - установка палитры. Автор с благодарностью примeт замечания любого характера и темперамента по телефону 6-19-49 или 6-19-43. СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 1. ENHANCED GRAPHICS ADAPTER BIOS. 1983. 2. Jourdain, Robert L. Programmer's problem solver for IBM PC, XT, and AT. - Nyw York: Prentice Hall Press, 1986. 3. McLain M.M. and Stevenson T.E. Writing OS/2 Graphics Programs. Byte, V13, No11, 1988. 4. Wilton R. VGA Video Modes. Byte, V13, No11, 1988. 5. Брэдли Д. Программирование на языке Ассемблера для ПЭВМ фирмы IBM - M.: Радио и связь, 1988, 229. 6. Norton P. Programmer's Guide to the IBM PC. Microsoft Press, USA, 1985. 7. TECH Help! Version 3.2a. Flambeaux Software, 1987. 8. The Assembly Language database. Peter Norton Computing Inc. 1987. ПРИЛОЖЕНИЕ 1 Подпрограммы, иллюстрирующие обращение к регистрам EGA: - Screen_Shock (reg1), - to_Blue (reg2), - Edge (reg3), - Draw_Compare (reg4), - move (reg5), - Draw_Points (g1), - Check_Color (g2). Подпрограммы, иллюстрирующие использование функций BIOS: - Cursor (bio1), - to_ (bio2), - two_Fonts (bio3), - VGA_cls (bio4). ; ;===пример горизонтального сдвига Screen_Shock ; .model small .stack 100h .data msg db 'После изображение пошатнется ...' db 10,13,'$' .code Include c:\masm\inc\dos.inc - 24 - Screen_Shock: mov ax, @data mov ds, ax @DispStr msg @GetKey mov al, 7 call shift_screen mov cx, 32000 delay: loop delay mov al, 0 call shift_screen @Exit ;---подпрограмма горизонтального сдвига shift_screen: push ax mov dx, 3DAh ;инициализация in al, dx ; регистра 3C0h mov dx, 3C0h mov al, 13h out dx, al ;адрес pop ax out dx, al ;данные=величина сдвига mov dx, 3DAh ;инициализация in al, dx ; регистра 3C0h mov dx, 3C0h mov al, 20h out dx, al ;разрешение доступа ret end Screen_Shock ; ;===Пример выбора цветовой плоскости to_Blue ; .model small .stack 100h .data msg db 'После выбрана лишь синяя плоскость ...' db 10,13,'$' .code Include c:\masm\inc\dos.inc to_Blue: mov ax, @data mov ds, ax @DispStr msg @GetKey mov al, 1 call enable_MAP @GetKey mov al, 0Fh call enable_MAP @Exit enable_MAP: push ax mov dx, 3DAh ;инициализация in al, dx ; регистра 3C0h - 25 - mov dx, 3C0h mov al, 12h out dx, al ;адрес pop ax out dx, al ;данные mov dx, 3DAh ;инициализация in al, dx ; регистра 3C0h mov dx, 3C0h mov al, 20h out dx, al ;разрешение доступа ret end to_Blue ; ;===Пример получения окантовки экрана Edge ; .model small .stack 100h .data msg db 'После появится окантовка экрана ...' db 10,13,'$' .code Include c:\masm\inc\dos.inc Edge: mov ax, @data mov ds, ax @DispStr msg @GetKey mov al, 1 call set_overscan @GetKey mov al, 0 call set_overscan @Exit set_overscan: push ax mov dx, 3DAh ;инициализация in al, dx ; регистра 3C0h mov dx, 3C0h mov al, 11h out dx, al ;адрес pop ax out dx, al ;данные mov dx, 3DAh ;инициализация in al, dx ; регистра 3C0h mov dx, 3C0h mov al, 20h out dx, al ;разрешение доступа ret end Edge ;===============|Draw_Compare|============\ ; Рисование горизонтальных линий в двух ; режимах записи 0 и 2 граф. контроллера - 26 - ; с целью сравнения скорости обращения ; Помним: цвет задается на каждый байт ! ;---------------|write_Mode|--------------/ .model small .stack 100h .data msg db 'Сравните скорости рисования линий в 2-х режимах ...' db 10,13,'$' .code Include c:\masm\inc\bios.inc Include c:\masm\inc\dos.inc Draw_Compare: ; рисуем в режиме записи 0 ; ------------------------ mov ax, @data mov ds, ax @DispStr msg @GetKey @SetMode 10h mov dx, 3CEh ;установка граф.контроллера mov ax, 0500h ; адаптера в режим call out_dx ; записи 0 mov ax, 0A000h ;настройка на начало видео буфера mov es, ax ; сегментного регистра ES mov cx, 28000 mov dx, 3CEh ;установка разрядной маски: mov ax, 08FFh ;будем рисовать каждую точку call out_dx loop1: mov dx, 3C4h ;регистр маски mov ah, 02 mov al, bl ;определяем цвет shl al, 1 ; полубайтом and al, 0Fh ; адреса call out_dx mov bx, cx mov al, es:[bx] ; mov al, 0FFh ;байт данных mov es:[bx], al loop loop1 @GetKey ; альтернативный способ рисования ; ------------------------------- mov dx, 3CEh ;установка граф.контроллера mov ax, 0502h ; адаптера в режим call out_dx ; записи 2 mov cx, 28000 mov dx, 3CEh ;установка разрядной маски: mov ax, 08FFh call out_dx loop2: mov bx, cx - 27 - mov al, es:[bx] mov al, bl ;определяем цвет shr al, 1 ; полубайтом and al, 0FFh ; адреса mov es:[bx], al loop loop2 @GetKey @SetMode 3 ;возвращаем а/ц режим @Exit ;---подпрограмма вывода байта (AL) в регистр (AH) ; контроллера (DX) адаптера EGA out_dx Proc near xchg al, ah out dx, al ;в индексный регистр inc dx xchg al, ah out dx, al ;в регистр данных ret out_dx endP end Draw_Compare ; ;===Переписывает в графическом режиме область в область move ; .model small .stack 100h .data msg db 'Программа переписывает область видео буфера',13,10 db 'в режиме граф.контроллера ЗАПИСЬ_1 быстрее ...' db 10,13,'$' .code Include c:\masm\inc\dos.inc Include c:\masm\inc\bios.inc move: mov ax, @data mov ds, ax @DispStr msg @GetKey @SetMode 10h mov cx, 400 wri: mov ah, 0Eh ;рисуем то, mov al, cl ; что будем and al, 1Fh ; add al, 'А' ; mov bh, 0 ; переписывать mov bl, cl ;цвет=4 разряда and bl, 0Fh ; адреса int 10h ; loop wri ; @GetKey mov dx, 3CEh ; mov al, 5 ; out dx, al ;устанавливаем inc dx ; - 28 - mov al, 1 ; режим записи 1 out dx, al ; mov ax, 0A000h ;начало видео буфера mov es, ax mov ds, ax mov cx, 80h*100 ;число переписываемых байтов mov bx, 0 ;смещение приемника mov bp, 80h*160 ;смещение источника inv: mov al, es:[bx] ;переписываем mov ds:[bp], al ; вверх ногами inc bx dec bp loop inv @GetKey @SetMode 3 @Exit end move ;===============|Hide_Cursor|==================\ ; Пример прячет курсор изменением его формы, ; хотя в [5] рекомендуется позиционировать на ; строку 25 с этой целью ; .model small .stack 100h .data curs_B db ? curs_E db ? msg db 'После курсор исчезнет ...' db 10,13,'$' .code Include c:\masm\inc\dos.inc cursor: mov ax, @data mov ds, ax mov ah, 03 int 10h ;чтение формы курсора в CX mov curs_B, ch ; и сохранение mov curs_E, cl ; @DispStr msg @GetKey mov cx, 0E00h ;если CH=высоте символа (0Eh) ; курсор становится невидимым call set_cursor @GetKey ;убедились ? mov ch, curs_B ;воостанавливаем mov cl, curs_E ; форму call set_cursor ; курсора @Exit set_cursor: mov ah, 01h int 10h ret - 29 - end cursor ;===============|to_|================================\ ; Определение знакогенератора в графическом режиме ; 10h с использованием вектора прерывания 43h (10C) ;---------------|character_Generator|----------------/ .model small .stack 100h .data char_data db 000h,018h,03Ch,03Ch,018h,07Ch,0BEh db 0BDh,0Bdh,01Ch,03Ch,066h,0C6h,0E3h db 000h,018h,03Ch,03Ch,018h,03Ch,03Eh db 03Eh,03Eh,01Ch,01Ch,01Ch,01Ch,01Eh db 000h,000h,000h,000h,000h,000h,000h db 000h,000h,000h,000h,000h,000h,000h x db ? ;столбец экрана y_max dw 20 ;число рядов one db 0 ;вороний признак msg db 'Эту программу лучше не запускать ...' db 10,13,'$' .code Include c:\masm\inc\bios.inc Include c:\masm\inc\dos.inc to_: ;---установка режима и вектора прерывания 43h mov ax, @data mov ds, ax @DispStr msg @GetKey @SetMode 10h ;граф. режим > 7 ; в случае < 7 use INT 1F mov dx, offset char_data mov ax, seg char_data mov ds, ax ;DS=Segment,DX=Offset mov ah, 25h ;функция настройки mov al, 43h ; вектора int 21h ; прерывания mov ax, @data mov ds, ax mov x, 0 mov one, 0 go: call delay mov cx, y_max y1: mov al, 2 ;пустой символ call write_sym ;стираем loop y1 inc x ;переносим mov cx, y_max y2: mov al, 0 ;активный call write_sym ;шаг loop y2 mov one, 1 ;для одного mov al, 1 ; mov cx, 3 ; - 30 - call write_sym ; mov one, 0 ; call delay ;придерживаем mov cx, y_max y3: mov al, 2 ;пустой символ call write_sym ;стираем loop y3 inc x ;переносим mov cx, y_max y4: mov al, 1 ;пассивный шаг call write_sym loop y4 mov one, 1 ;для одного mov cx, 3 ; mov al, 0 ; call write_sym ; mov one, 0 ; cmp x, 70 ;прошли ? ja end_ jmp go end_: @SetMode 3 @Exit write_sym: ;---позиционирование курсора: push cx ;сохраняем Y push ax ;сохраняем символ mov dl, x cmp one, 1 ;один jne any1 ;нет add dl, 1 ;его Х_координата не впереди any1: mov dh, cl ;Х mov ah, 2 ;функция позиционирования курсора mov bh, 0 ;страница int 10h ;устанавливаем ;---рисуем символ: pop ax ;AL=символ mov ah, 09h ;функция печати символа mov cx, 4 ;число символов mov bl, 4 ;основной цвет cmp one, 1 ;ворона ? jne any2 ;нет mov cx, 1 ;один mov bl, 7 ;цвет одного any2: mov bh, 0 ;страница int 10h ;рисуем pop cx exi: ret ;---вынуждены придерживать: delay: mov cx, 5 d_1: push cx - 31 - mov cx, 32700 d_2: loop d_2 pop cx loop d_1 ret end to_ ;=====================================================\ ; Программа иллюстрирует возможность одновременной ; печати двумя фонтами с помощью переключения бита_3 ; атрибута без потери возможности управления яркостью ; .model small .stack 100h .data msg db 'После печатает 2-мя фонтами' db ' в алфавитно/цифровом режиме ...',10,13,'$' str_1 db 'This string uses 8x8 Font' str_2 db ' and this string uses 9x14 Font' end_str db ? .code Include c:\masm\inc\bios.inc Include c:\masm\inc\dos.inc two_Fonts: mov ax, @data mov es, ax mov ds, ax @DispStr msg @GetKey mov ax, 1102h ;загружаем ROM_фонт 8х8 mov bl, 02 ; в знакогенератор 2 int 10h ; mov ax, 1103h ;устанавливаем режим ; с 512 символами mov bl, 08 ;если бит 3 атрибута=1 8х8_фонт ;если бит 3 атрибута=0 9х14_фонт int 10h ; mov ax, 1301h ;печать с продвижением курсора mov bx, 000Ah ;цвет ярко-зеленый. Бит_3=1 mov cx, str_2-str_1 ;длина строки_1 mov dx, 1600h ;координаты курсора mov bp, offset str_1;ES=segment,BP=offset string_1 int 10h ;печать фонтом 8х8, ; ОДНОВРЕМЕННО действует ; бит яркости ; режимы 512 символов знакогенератора и яркость ; НЕ альтернативны ! mov ax, 1301h ; mov bx, 0002h ;цвет зеленый. Бит_3=0 mov cx, end_str-str_2 mov dx, 1600h+str_2-str_1 ;в той же строке mov bp, offset str_2;ES=segment,BP=offset string_2 - 32 - int 10h ;печать фонтом 9х14 @GetKey ;убедились ? @Exit end two_Fonts ;===============|VGA_cls|=============================\ ; Очистка экрана с помощью видео функции Scroll Up. ; Текст приведен в журнале BYTE [7] и использован ; нами в качестве иллюстрации преемственности свойств ; адаптера EGA и следующей модели, ставшей стандартом ; для PS/2, - адаптера VGA. ; .model small .data msg db 'Стирает экран подпрограммой для VGA ...' db 10,13,'$' CodeSeg Segment byte Assume cs:CodeSeg, ss:StackSeg Include c:\masm\inc\bios.inc Include c:\masm\inc\dos.inc VGA_cls Proc far mov ax, @data mov ds, ax @DispStr msg @GetKey mov ah, 0Fh int 10h ;get video status: ; AH now = displayed char. columns ; AL now = video mode ; BH now = current video page push bx push ax mov ax, 1130h int 10h ;get char. generator info: ; DL = [displayed char rows]-1 pop ax mov dh, dl ;DH = last row on screen mov dl, ah dec dl ;DL = last column on screen sub cx, cx ;CH = 0 (first row ot screen) ;CL = 0 (first column on screen) mov bh, 7 ;BH = default alphanumeric attribute cmp al, 7 jle LO1 ;jump if alphanumeric mode xor bh, bh ;default graphics attribute LO1: mov ax, 0600h ;AH = 6 (function) ;AL = 0 (num of lines to scroll) int 10h ;Scroll up (clear screen) pop bx ;BH = current video page xor dx, dx ;DH=DL = 0 (nuw cursor location) mov ah, 2 int 10h ;Set cursor location to upper left mov ax, 4C00h int 21h ;call DOS to terminate program - 33 - VGA_cls ENDP CodeSeg EndS StackSeg Segment stack db 100h dup (?) StackSeg EndS END VGA_cls ;===============|Draw_Points|============================\ ; Иллюстрация взаимодействия регистров граф. контроллера ; в двух режимах записи 0 и 2. Выбор режима возможен при ; запуске программы с параметром [1], 2. ;---------------|write_mode_0_2|-------------------------/ .model small .stack 100h .data msg db 'Здесь вы можете обнаружить взаимодействие' db ' основных регистров Граф.контроллера ..$' .code Include c:\masm\inc\bios.inc Include c:\masm\inc\dos.inc Draw_Points: mov ax, @data ;настройка сегментного mov ds, ax ; регистра данных @DispStr msg @GetKey mov al, es:[82h] ;параметр, переданный из DOS cmp al, '2' jne write_mode_0 jmp write_mode_2 ;===рисуем в режиме записи 0 ; ; Взаимодействие регистров граф.контроллера кроме комментариев ; подпрограмм отражено на рисунке 4.1 технического описания ; write_mode_0: ;---установка режимов адаптера и графического контроллера mov ah, 00h ;функция установки режима mov al, 10h ;код графического режима int 10h ;установка со сбросом экрана mov dx, 3CEh ;установка граф.контроллера mov ax, 0500h ; адаптера в режим call out_dx ; записи 0 ;---готовим адрес байта в видео буфере mov ax, 0A000h ;настройка на начало видео буфера mov es, ax ; сегментного регистра ES mov bx, 0 ;указатель на первый байт в буфере ;---установка масочного регистра mov dx, 3CEh ;установка разрядной маски: mov ax, 0883h ; 83==можем менять цвет call out_dx ; разрядов 7,1,0 ;---загрузка регистрa Установки/сброса mov dx, 3CEh ;регистр Установки/сброса 3CF/0 mov ax, 000Fh ;AH=индекс регистра; AL=данные - 34 - call out_dx ;AL=F ==в случае Разрешения_установки ;разрешенные разрядной маской разряды ;всех 4-х плоскостей устанавливаются ;---загрузка регистрa Разрешения Установки/сброса mov dx, 3CEh ;регистр Разрешение сброса 3CF/1 mov ax, 010Fh ;AL=F == разрешает установку/сброс call out_dx ;разрядов всех 4-х плоскостей ;Независимо от данных процессора ;цвет выбранных разрадной маской ;точек становится белый. ;---сброс адресуемого в видео ОЗУ байта mov al, es:[bx] ;чтение содержимого (необходимо !) mov al, 0 ;сбрасываем mov es:[bx], al ;сброшенный записываем ;---загрузка регистра маски плоскостей mov dx, 3C4h ;регистр маски плоскостей 3C5/2 mov ax, 0203h ;выбран цвет 3 - зеленовато-голубой call out_dx ;загружаем ;---запись данных в видео ОЗУ mov al, 0AAh ;байт данных mov es:[bx], al ;записываем и ; убеждаемся что, независимо от записываемых данных (0AAh) ; точки, соответствующие 7,1,0 разрядам первого байта видео ; буфера, становятся белыми - таково опредеяющее действие ; регистров разрядной маски, Разрешения и Установки/сброса. @GetKey ;===смена условий записи байта ;---установка разрядной маски mov dx, 3CEh ;регистр разрядной маски 3CF/8 mov ax, 08FFh ; call out_dx ; ;---меняем для наглядности значения ; регистра Установки/сброса mov dx, 3CEh ;регистр установки 3CF/0 mov ax, 000Ch ; 3 2 1 0 <--- разряд call out_dx ; 1 1 0 0 ; регистра Разрешения Установки/сброса mov dx, 3CEh ;регистр разрешения 3CF/1 mov ax, 010Ah ; 3 2 1 0 <--- разряд call out_dx ; 1 0 1 0 ;---сброс адресуемого в видео ОЗУ байта mov al, es:[bx] ;чтение ;оставляем значение байта mov es:[bx], al ;и записываем ;---загрузка регистра маски плоскости mov dx, 3C4h ;регистр маски плоскости 3C5/2 mov ax, 0203h ;выбран цвет 3 - зеленовато-голубой call out_dx ; ;---запись данных в видео ОЗУ mov al, 0FFh ;меняем цвет всех 8-ми точек mov es:[bx], al ;записываем и ; убеждаемся, что точки, соответствующие разрядам 7,1,0 ; окрашены в светло-пурпурный цвет (0Dh), а остальные - ; в светло-голубой (09h). - 35 - @GetKey @SetMode 3 ;возвращаем а/ц режим @Exit ;===альтернативный способ рисования write_mode_2: ;---установка режимов адаптера и графического контроллера mov ah, 00h ;функция установки режима mov al, 10h ;код графического режима int 10h ;установка со сбросом экрана mov dx, 3CEh ;установка граф.контроллера mov ax, 0502h ; адаптера в режим call out_dx ; записи 2 ;---готовим адрес байта в видео буфере mov ax, 0A000h ;настройка на начало видео буфера mov es, ax ; сегментного регистра ES mov bx, 0 ;указатель на первый байт в буфере ;---установка масочного регистра mov dx, 3CEh ;установка разрядной маски: mov ax, 0883h ; 83==разрешаем менять цвет call out_dx ; для разрядов 7,1,0 ;---рисуем точки альтернативным методом mov al, es:[bx] mov al, 4 ;это цвет, а не данные mov es:[bx], al @GetKey @SetMode 3 ;возвращаем а/ц режим @Exit ;---подпрограмма вывода байта (AL) в регистр (AH) ; контроллера (DX) адаптера EGA out_dx Proc near xchg al, ah out dx, al ;в индексный регистр inc dx xchg al, ah out dx, al ;в регистр данных ret out_dx endP end Draw_Points ;===============|Check_Color|=================================\ ; Пример проверки цвета точки (точек байта) с использованием ; регистра игнорирования цвета в режиме граф. контроллера ; - чтение 1. Подпрограмма возвращает в DOS значение 2, если ; цвет точки (Х=6,Y=0) -- 0010B ИЛИ 1010B, а остальных -- 0. ;---------------|read_mode_0_1|-------------------------------/ .model small .stack 100h .data col db ? ;признак, возвращаемый в DOS msg db 'Использование регистра игнорирования цвета ..$' .code Include c:\masm\inc\bios.inc - 36 - Include c:\masm\inc\dos.inc Check_Color: mov ax, @data ;настройка сегментного mov ds, ax ; регистра данных @DispStr msg @GetKey @SetMode 10h ;установка граф.режима ;---предварительно рисуем точку mov ax, 0C02h ;функция и цвет mov cx, 06 ;разряд 1 байта 0/ X=6 xor dx, dx ;Y=0 xor bh, bh ;страница 0 int 10h ;---установка режима графического контроллера mov dx, 3CEh ;установка граф.контроллера mov ax, 0508h ; адаптера в режим call out_dx ; чтения 1 ;---готовим адрес байта в видео буфере mov ax, 0A000h ;настройка на начало видео буфера mov es, ax ; сегментного регистра ES mov bx, 0 ;указатель на первый байт в буфере ;---установка регистра сравнения цвета mov dx, 3CEh ;регистр граф.контроллера mov ah, 02 ;адрес регистра сравнения mov al, 0010B ;код цвета call out_dx ; ;---загрузка регистрa игнорирования цвета mov dx, 3CEh ; mov ah, 07 ;адрес регистра игнорирования mov al, 0111B ;принимаем или 1010B или 0010B call out_dx ; ;---проверяем цвета mov al, es:[bx] ;читаем байт видео буфера mov col, al ;сохраняем признак @GetKey @SetMode 3 ;возвращаем а/ц режим @Exit col ;возвращаем признак DOS, ; можем его проверить ; с помощью ERRORLEVEL ;---подпрограмма вывода байта (AL) в регистр (AH) ; контроллера (DX) адаптера EGA out_dx Proc near xchg al, ah out dx, al ;в индексный регистр inc dx xchg al, ah out dx, al ;в регистр данных ret out_dx endP end Check_Color - 37 - ПРИЛОЖЕНИЕ 2 Подпрограммы, реализующие основные видео функции BIOS page ,132 dosseg ;========================================================; ; Программа проверяет восстановленные из ПЗУ BIOS EGA, ; ; а также описания BIOS 83 года основные подпрограммы, ; ; дающие начальное представление об организации видео ; ; адаптера EGA. 9-mar-1989. Chan ; ; Запуск программы: >ega [parameter] ;========================================================; .model small .stack 100h abs0 SEGMENT at 00h ORG 43h*4 grx_set label dword ;адрес смещения знакогенератора ORG 449h crt_mode db ? ;текущий видео режим crt_cols dw ? ;ширина экрана в символах crt_len dw ? ;длина видео экрaна crt_start dw ? ;смещение в видео ОЗУ cursor_posn dw 8 dup(?);координаты курсора ; для восьми страниц ORG 484h rows db ? ;число строк - 1 points dw ? ;число байт на символ abs0 ENDS .data cur_mode db ? ;сохраняем текущий режим cols db ? ;атрибут точки wrk db ? .code Include c:\masm\inc\bios.inc Include c:\masm\inc\dos.inc Put_Chars MACRO sym,page,attr,num mov bh, page mov al, sym mov bl, attr mov cx, num call write_chars ENDM Put_Dot MACRO page,y,x,d mov bh, page mov dx, y mov cx, x mov al, d call write_dot ENDM Get_Dot MACRO page,y,x mov bh, page mov dx, y - 38 - mov cx, x call read_dot ENDM Set_Pal MACRO num, pall mov bl, num mov bh, pall call Set_Pal_Reg ENDM start: mov al, es:[82h] ;параметр, передаваемый из DOS cmp al, '1' je $1 ;печатать графический символ cmp al, '2' je $2 ;печатать символ в текстовом режиме cmp al, '3' je $3 ;установка палитры cmp al, '4' je $4 ;рисование точек и взятие атрибутов ;===проверка подпрограммы печати символа в граф.режиме $1: assume ds:abs0 call dds ;---позиционируем курсор @SetMode 10h mov ah, 02 mov bh, 0 mov dh, 10 mov dl, 05 int 10h ;---печатаем несколько раз символ mov al, 'ф' mov bh, 0 mov bl, 4 mov cx, 25 call grx_wrt ;--- @GetKey @SetMode 3 @exit ;===проверка пп. печати символов в текстовом режиме $2: assume ds:abs0 call dds Put_Chars '*',0,4,900 @Exit ;===проверка пп. установки палитры $3: assume ds:abs0 call dds Set_Pal 4,12h @GetKey Set_Pal 4,4 @Exit ;===проверка пп. рисования точек и чтения атрибутов. - 39 - ; возвращаемый цвет последней точки 7 можно проверить ; с помощью ERRERLEVEL $4: assume ds:abs0 call dds @getMode mov cur_mode, al @setMode 10h Put_Dot 0,150,80,1 Put_Dot 0,150,82,3 Put_Dot 0,150,84,4 Put_Dot 1,150,83,7 @GetKey Get_dot 1,150,83 mov cs:cols, al @setMode cur_mode @Exit cs:cols ;--------------------------------------------------\ ; Рисование точки Int 10h/ 0Ch ; вход: ; DX = строка (0-199) ; CX = столбец (0-639) ; AL = цвет (1,2 или 4 разряда ; в зависимости от режима). ; Для 10h режима 4 разряда !!! ; Разряд 7 - признак XOR ; bh = страница ; write_dot PROC near no_adj2: push ax mov ax, 0A000h ;начало видео буфера mov es, ax mov ax, dx ;строка call dot_sup_1 ;выход: BX=смещение, ;AL=разрядная маска mov dx, 3CEh ;установка mov ah, 08h ; регистра разрядной маски ; бит маски, равный 0 предохраняет ; от изменения call out_dx ; pop ax ;восстанавливаем цвет push ax ; test al, 080h ;проверяем на XOR jz no_xor ;не XOR mov ah, 03h ; - устанавливаем Fun в mov al, 018h ; в регистр циклического сдвига call out_dx ; jmp wd_b ; no_xor: ;стираем точку mov al, 0ffh ; во всех картах call set_seq mov al, es:[bx] ;загружаем регистр-защелку xor al, al mov es:[bx], al ;стираем wd_b: ;устанавливаем цвет - 40 - pop ax and al, 0fh ;значение 0-15 call set_seq ; mov al, es:[bx] ;загружаем регистр-защелку mov al, 0ffh ;записываемый байт mov es:[bx], al ; ставит точку call out_dx ;all maps on mov dx, 3CEh mov ah, 03h ;восстанавиливаем xor al, al ; регистр call out_dx ; циклического сдвига mov ah, 08h ; mov al, 0ffh ; и регистр call out_dx ; разрядной маски ret ; set_seq: push dx mov dx, 3C4h ;задатчик последовательностей mov ah, 02h ; call out_dx pop dx ret write_dot ENDP ;--------------------------------------\ ; вход: ; DX = строка = AX (pixels) ; CX = столбец (pixels) ; BH = страница ; выход: ; BX = смещение в видео ОЗУ ; AL = разрядная маска ; dot_sup_1 PROC near ;...... offset = page offset + row*bytes_at_row + column/8 push cx ;сохраняем столбец shr cx, 1 ;делим на 8 shr cx, 1 ; для определения байта, в котором shr cx, 1 ; расположена точка mul word ptr crt_cols ;AX=строка*число_символов_в_строке ; (8 bits/byte) add ax, cx ;смещение в видео странице cmp bh, 0 ;в какой странице ? jz ds_2 ;если в нулевой mov cx, crt_len ;длина одной страницы ds_3: add ax, cx ;добавляем столько раз, dec bh ; сколько страниц jnz ds_3 ds_2: pop cx ;столбец mov bx, ax ;смещение в видео ОЗУ and cl, 07h ;получаем счетчик сдвигов mov al, 080h ; то, что будем сдвигать shr al, cl ; маска рабочего разряда найдена ret - 41 - dot_sup_1 ENDP ;--------------------------------------\ out_dx PROC near ;ah=index;al=data;dx=port xchg al, ah ;get index value out dx, al ;set index reg inc dx ;set dx to data reg xchg al, ah ;get data value out dx, al ;set data reg dec dx ;set dx back to index ret out_dx ENDP ;----------------------------------------------\ ; Чтение точки Int 10h/ 0Dh ; Вход ; DX = строка (0-199) ; CX = столбец (0-639) ; bh = страница ; выход ; AL = результат-цвет ; Read_Dot PROC near call rd_s do4: call rd_1s ;читаем выбрынную плоскость mov cl, al shl ah, cl ;упаковываем бит or dl, ah ;сохраняем в DL inc al ;выбираем следующую плоскость cmp al, 4 ;она последняя ? jc do4 ;нет mov al, dl ;да, результат в AL ret Read_Dot ENDP ;---------------------------------------\ rd_s PROC near mov ax, 0a000h mov es, ax mov ax, dx call dot_sup_1 ;выход: BX=смещение, ; CL=счетчик сдигов. mov ch, 7 sub ch, cl ;сдвиг с другой стороны <-- xor dx, dx ;DL-здесь будет результат xor al, al ; ret rd_s ENDP ;---------------------------------------\ rd_1s PROC near push dx mov dx, 3CEh mov ah, 4 call out_dx ;выбираем маску чтения pop dx mov cl, ch mov ah, es:[bx] ;читаем байт - 42 - shr ah, cl and ah, 1 ;выделяем разряд ret rd_1s ENDP ;------------------------------------------\ ;Set_Pal_Reg int 10h/ 0Bh ; вход: ; AH = 0Bh ; BL = регистр палитры ; BH = устанавливаемое значение ; Set_Pal_Reg PROC near mov dx, 3DAh vert: in al, dx ;читаем статусный регистр test al, 08h ;ждем вертикального синхроимпульса jz vert ; mov dx, 3C0h mov al, bl out dx, al ;адресация mov al, bh out dx, al ;установка значения in al, dx ;инициализация mov al, 20h out dx, al ;разрешаем видео ret Set_Pal_Reg ENDP;.........../ ;-------------------------------\ ; Write_Chars PROC near call dds mov ah, crt_mode mov dx, 0B800h mov es, dx mov ah, bl ;атрибут push ax push cx call find_position mov di, bx ;address to DI pop cx ;write count pop ax ;char rep stosw ;put the char/attr ret Write_Chars endp;.........../ ;-------------------------------\ find_position Proc near mov cl, bh ;выводимая страница -> CX xor ch, ch mov si, cx ;готовим индекс sal si, 1 ;*2 - смещение в словах mov ax, [si+offset cursor_posn] ;берем координаты курсора ; в выбранной странице xor bx, bx ;стартовый адрес jcxz p5 ;страница нулевая ? p4: add bx, crt_len ;нет, добавляем длину страницы - 43 - loop p4 ;число раз = CX p5: call position ;определить адрес add bx, ax ; в видео ОЗУ ret find_position endp;.........../ ;-----------------------------------------\ ; Вычисляется адрес символа в а/ц формате ; input: AX=координаты курсора ; output: AX=смещение в видео области position Proc near push bx mov bx, ax mov al, ah ;строка в AL mul byte ptr crt_cols ;умножаем на число символов ; в строке (байт) xor bh, bh ; add ax, bx ;смещение в символах sal ax, 1 ;*2 учитываем байт атрибута pop bx ret position Endp;.........../ ;-------------------------------\ ; Подпрограмма печати символа в графическом режиме ; AL = код символа ; BH = страница ; BL = атрибут/цвет ; CX = число символов ; Grx_Wrt Proc near no_adj1: assume ds:abs0, es:nothing sub ah, ah ;очистим старший байт mul points ;смещение в таблице знакогенератора push ax ; call Gr_cur ;положение курсора в видео ОЗУ mov di, ax ; -- смещение mov bp, points ;число байт на символ mov dx, 0A000h ;готовим адресный сегмент mov es, dx ; lds si, grx_set ;смещение таблицы знакогенератора pop ax ; add si, ax ;адрес символа s20a: test bl, 080h ;режим атрибутов XOR ? jz no_xor_ ;нет mov dx, 3CEh ;устанавливаем mov ax, 318h ; регистр граф. call out_dx ; контроллера jmp f_2 ;пропускаем no_xor_: push di ;сохраняем положение курсора mov dx, 3C4h ;устанавливаем mov ax, 20Fh ; масочный регистр call out_dx ; плоскостей для выбора всех - 44 - sub ax, ax push cx ;сохраняем счетчик символов mov cx, bp ;счетчик=число байт на символ push ds call dds ;сегмент 0 s13a: stosb ;чистим add di, crt_cols ; знакоместо dec di ; для loop s13a ; символа pop ds ;возвращаем сегмент pop cx ; и счетчик символов pop di ; и указатель на символ f_2: mov dx, 3C4h ;устанавливаем mov ah, 02h ; цвет в масочном регистре mov al, bl ; задатчика call out_dx ; последовательностей push di ; push bx ;сохраняем цвет push cx ;число символов mov bx, bp ;число байт на символ push ds ; call dds ;сегмент 0 assume ds:abs0 mov cx, crt_cols ;число символов в строке pop ds assume ds:nothing s1k: ;=наконец, выводим символ mov al, ds:[si] ;байт знакогенератора mov ah, es:[di] ;так устроен контроллер, ; что надо сначала читать mov es:[di], al ;пишем байт образа символа inc si ;для следующего из фонта add di, cx ;для следующего в видео dec bx ;еще один байт образа передан jnz s1k ;весь образ символа ? (8,14..) pop cx ;возвращаем число символов pop bx ; и атрибут, sub si, bp ; указатель на начало знакогенератора, pop di ;курсор inc di ; на следующее знакоместо loop s20a ;на печать следующего символа mov dx, 3CEh mov ax, 300h call out_dx ;возвращаем значение mov dx, 3C4h mov ax, 20Fh ;выбраны все плоскости call out_dx ret grx_wrt endp;.................../ ;-------------------------------\ ; установка DS на сегмент данных dds proc near push ax xor ax, ax mov ds, ax pop ax - 45 - ret dds endp;.................../ ;-------------------------------\ ; определение адреса курсора ; вход: BH=страница ; AX=адрес курсора для выбранной страницы ; выход: AX=смещение в видео буфере ; gr_cur proc near assume ds:abs0 push bx mov bl, bh ;готовим для умножения xor bh, bh ; на 2 для определения sal bx, 1 ; смещения в словах mov ax, [bx+offset cursor_posn] ;координаты курсора push cx push dx sub ch, ch mov cl, bh ;CX=страница mov bx, ax ;BX=координаты курсора mov al, ah ;строка mul byte ptr crt_cols ;число символов до этой строки mul points ;число байт на символ sub bh, bh ; add ax, bx ;добавить столбец-координату mov bx, crt_len ;длина страницы jcxz gp_2 ;переход, если номер страницы 0 gp_3: add ax, bx ;длину страницы loop gp_3 ;и так число страниц раз gp_2: pop dx pop cx pop bx ret gr_cur endp end