В. Фролов А. В. Фролов Г. - Программирование видеоадаптеров EGA, VGA и SVGA
---
Программирование видеоадаптеров EGA, VGA и SVGA,  0, , , 
Программирование 

***

 Книга представляет собой новую редакцию третьего тома "Библиотеки системного программиста" и посвящена программированию видеоадаптеров. В ней рассмотрены различные типы современных видеоадаптеров, в том числе адаптеров SVGA, описаны их регистры, организация видеопамяти. Представлены основные приемы программирования видеоадаптеров. Книга предназначена для специалистов по вычислительной технике, системных и прикладных программистов, студентов вузов, специализирующихся на вычислительной технике.
 

***		
 

Библиотека системного программиста

 

 Фролов А. В. Фролов Г. В. 

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

Введение

В третьем томе "Библиотеки системного программиста", который называется "Программирование видеоадаптеров CGA, EGA и VGA", мы уже рассказывали вам о видеоадаптерах. За несколько лет, прошедших с момента выхода в свет этого тома, появилось много новых моделей видеоадаптеров, обеспечивающих большую разрешающую способность и большее количество одновременно отображаемых цветов.
Сегодня видеоадаптеры MDA, CGA, Hercules и EGA вытеснены различными моделями адаптеров VGA и SVGA. Поэтому мы убрали материал, относящийся только к этим видеоадаптерам и добавили информацию о видеоадаптерах SVGA. В частности нами описан стандарт VESA, которому соответствуют многие адаптеры SVGA. Благодаря стандарту VESA вы сможете легко программировать видеоадаптеры в режимах с большим разрешением и большим количеством цветов.
Нами подробно описана архитектура видеоадаптеров, совместимых с VGA, их регистры. Воспроизводится формат регистров и описывается их назначение. В наиболее интересных случаях представлены программы, использующие непосредственный доступ к регистрам. Читатель сможет получить на экране своего компьютера видеоэффекты, недоступные при использовании только функций BIOS или функций библиотек трансляторов языков высокого уровня.
Читателю предоставляется возможность подробно рассмотреть стандартные режимы работы видеоадаптеров, структуру видеопамяти в этих режимах. Знание структуры видеопамяти позволяет создавать программы, отображающие информацию на экране путем непосредственного доступа к видеопамяти. А это, в свою очередь, важно при создании быстрых видеопрограмм, в частности, динамических игр и графических редакторов.
В качестве примера рассмотрены два не стандартных режима видеоадаптера VGA. Эти режимы не поддерживаются функциями BIOS и позволяют в режиме с 256 цветами иметь большую разрешающую способность.
Далее в книге излагаются традиционные методы управления видеоадаптерами. Приведен обзор всех прерываний и функций BIOS, предназначенных для работы с видеоадаптерами. Описываются наиболее важные функции стандартной библиотеки трансляторов Borland C++. Применение каждой группы функций иллюстрируется примерами программ.
Большое количество программ, составленных с использованием таких распространенных языков программирования, как Си и ассемблер, значительно облегчают понимание материала, изложенного в книге.
Дополнительно к книге можно купить дискету, содержащую исходные тексты всех разработанных нами программ, описанных в книге. Если вас интересуют сведения, которые были включены в третий том "Библиотеки системного программиста", но не вошли в это издание, вы можете отдельно приобрести дискету с гипертекстовой базой данных.
 
 

Как связаться с авторами

Авторы имеют собственный почтовый адрес в сети GlasNet. Все свои замечания и предложения по содержанию книг серий "Библиотека системного программиста" и "Персональный компьютер - шаг за шагом" вы можете присылать нам по следующему адресу:
frolov@glas.apc.org
Наш почтовый адрес доступен не только пользователям сети GlasNet. Абоненты других компьютерных сетей также могут передать нам сообщения. Ниже мы привели наш адрес в различных сетях:
Глобальная сеть
Наш адрес
CompuServe
" internet:frolov@glas.apc.org
GlasNet
frolov@glas.apc.org
Internet
frolov@glas.apc.org
Relcom
frolov@glas.apc.org
 
 

 UUCP 

uunet!cdp!glas!frolov
Вы также можете присылать свои пожелания почтой по адресу:
Издательский отдел АО "ДИАЛОГ-МИФИ"
Индекс 115409, город Москва, улица Москворечье, дом 31, корпус 2
 
 

Благодарности

Авторы выражают благодарность Фроловой Ольге Викторовне, Кустову Виктору. Мы также благодарим всех сотрудников издательского отдела АО "ДИАЛОГ-МИФИ": Голубева Олега Александровича, Дмитриеву Наталью, Виноградову Елену, Кузьминову Оксану.


 Замечания 


При описании регистров мы используем следующее соглашение о нумерации битов регистров: биты в байте нумеруются справа налево. Бит D7 является старшим, а бит D0 - младшим битами.
Если мы приводим значения переменных, регистров или адресов в шестнадцатиричной системе счисления, то после числа указывается символ 'h' (от слова Hexadecimal). Если число представлено в двоичной системе счисления, то после него указывается символ 'b' (от слова Binary).


 1. Видеоподсистема компьютера 


Видеоподсистема XE "Видеоподсистема" любого компьютера состоит из двух основных частей - видеоадаптера и монитора, подключаемого к видеоадаптеру.
Видеоадаптер может быть оформлен в виде отдельной платы, вставляемой в слот расширения компьютера, или может быть расположен непосредственно на системной плате компьютера.
Видеоадаптер включает в себя видеопамять, в которой хранится изображение, отображаемое на экране монитора, постоянное запоминающее устройство, в котором записаны наборы шрифтов, отображаемые видеоадаптером в текстовых и графических режимах, а также функции BIOS для работы с видеоадаптером. Кроме того, видеоадаптер содержит сложное управляющее устройство, обеспечивающее обмен данными с компьютером, формирование изображения и выполняющее некоторые другие действия.
Видеоадаптеры могут работать в различных текстовых и графических режимах, различающихся разрешением, количеством отображаемых цветов и некоторыми другими характеристиками.
Сам видеоадаптер не отображает данные. Для этого к видеоадаптеру необходимо подключить монитор. Изображение, создаваемое компьютером, формируется видеоадаптером и передается на монитор для предоставления ее конечному пользователю.
Существует несколько основных способов формирования изображения на экране монитора. Наиболее распространены так называемые мониторы с электронно-лучевыми трубками (ЭЛТ). Вы наверняка знакомы с электронно-лучевыми трубками. Они используются практически во всех бытовых телевизионных приемниках.
Применение ЭЛТ в блокнотных и переносных компьютерах XE "Блокнотные компьютеры" невозможно вследствие ее большого размера и большой потребляемой мощности. Поэтому для них используют жидкокристаллические и газоразрядные панели. В настоящее время разработаны и выпускаются компьютеры с цветными жидкокристаллическими экранами, не уступающие по качеству многим мониторам с электронно-лучевыми трубками.
Сейчас существует огромное количество всевозможных видеоадаптеров, начиная от простейших монохромных, не поддерживающих графические режимы, и кончая современными видеоадаптерами со специальными графическими процессорами, воспроизводящими порядка 16,7 миллионов различных цветов и подключаемых для повышения быстродействия непосредственно к локальной шине процессора.
Можно выделить несколько наиболее общих типов или подмножеств видеоадаптеров. Деление проводится по основным характеристикам видеоадаптеров, таким как поддержка текстовых и графических режимов, максимальное количество одновременно отображаемых цветов, максимальная разрешающая способность, наличие специализированных схем управления - акселераторов или графических сопроцессоров, а также по способу подключения к компьютеру и монитору.
Большинство видеоадаптеров может работать как в текстовых, так и в графических режимах. Возможность отображения графической информации отсутствует только у самого первого видеоадаптера фирмы IBM - MDA XE "Видеоадаптер:MDA". Он использовался вместе с монохромным монитором. Сегодня видеоадаптер MDA и монохромный монитор стали большой редкостью. Они не отвечают потребностям современных пользователей.
Отсутствие возможности отображения графической информации ограничивало сферу использования компьютеров и вскоре небольшая фирма Hercules Computer Technology, Inc. выпустила монохромный видеоадаптер Hercules, который уже мог выводить графику и обеспечивал большую разрешающую способность. Также как и адаптер MDA, видеоадаптер Hercules XE "Видеоадаптер:Hercules" можно было подключить к монохромному монитору.
Вскоре появился и первый видеоадаптер, позволяющий отображать не только монохромную, но и цветную информацию, как в текстовом, так и в графическом режиме. Этим видеоадаптером стал адаптер CGA XE "Видеоадаптер:CGA". С его помощью компьютер мог выводить 16-цветную текстовую и 4-цветную графическую информацию. Однако он имел очень низкую разрешающую способность - 320х200 пикселов (пиксел - элементарный элемент изображения, точка). В результате такой низкой разрешающей способности изображение на экране представляло собой совокупность видимых точек и быстро утомляло глаза пользователя.
Видеоадаптер CGA можно использовать с композитными мониторами (обычными цветными или черно-белыми бытовыми телевизорами), а также со специальными цифровыми цветными мониторами.
Затем прогресс пошел по пути увеличения разрешающей способности и количества одновременно отображаемых цветов. Были созданы видеоадаптеры EGA и VGA. Видеоадаптер EGA XE "Видеоадаптер:EGA" уже мог отображать 16-цветную графическую информацию с разрешением 640х350 пикселов, а VGA XE "Видеоадаптер:VGA" - даже с разрешением 800х600 пикселов. Кроме того, в видеоадаптере VGA появился графический режим с разрешением 320х200 пикселов при возможности одновременного отображения 256 различных цветов.
С видеоадаптером EGA можно было использовать либо цветной монитор, либо улучшенный цветной монитор. К видеоадаптерам VGA нужно подключать специальные многочастотные аналоговые мониторы.
Однако с появлением операционной системы Windows требования к видеоподсистеме компьютера многократно возросли. Ни видеоадаптер EGA, ни видеоадаптер VGA не обеспечивают необходимой разрешающей способности и количества одновременно отображаемых цветов. Поэтому многие фирмы приступили к выпуску собственных расширенных версий видеоадаптера VGA. Они получили общее название SVGA (Super VGA). Видеоадаптеры SVGA XE "Видеоадаптер:SVGA" не являются устоявшимся стандартом, наподобие EGA и VGA. Различные фирмы выпускают адаптеры SVGA, имеющие различные возможности. При этом они не всегда совместимы друг с другом.
Появились видеоадаптеры SVGA, которые работают в режимах High Color и True Color XE "Графические:режим:True Color". В режиме High Color XE "Графические:режим:High Color" видеоадаптер может одновременно отображать на экране 32768 или 65536 различных цветов. Режим True Color еще более многоцветный. В этом режиме видеоадаптер может одновременно отображать более чем 16,7 миллионов различных цветов. Качество изображения, достигаемое такими видеоадаптерами (при условии использования с ними соответствующих мониторов), почти не уступает качеству цветных слайдов.
Способность видеоадаптера отображать большое количество цветов с высоким разрешением тесно связана с объемом его видеопамяти. Чем больше объем видеопамяти адаптера, тем больше цветов он сможет отобразить и тем выше будет разрешающая способность.
Видеопамять адаптера CGA имела объем всего 16 Кбайт. На современных адаптерах устанавливают как минимум 256 Кбайт памяти. Такого объема видеопамяти достаточно для отображения 16 различных цветов при разрешении 800х600 пикселов. Режимы с большим разрешением или с большим количеством цветов недоступны.
Из следующей таблицы вы можете определить минимальный объем видеопамяти в Кбайтах, необходимый для данного разрешения и количества цветов:
Количество
Разрешение
цветов
640х480
800х600
1024х768
1280х1024
1600х1200
 
 

 16 


  150  



  235  



  384  



  640  



  938  



  256  



  300  



  469  



  768  



  1280  



  1875  



  65.536  



  600  



  938  



  1536  



  2560  



  3750  



  16777216  



  900  



  1407  



  2304  



  3840  



  5625  


Например, в режиме видеоадаптера, когда он одновременно отображает 16,7 миллионов цветов при разрешении 1024х768 пикселов, объем видеопамяти должен составлять 2304 Кбайт. Когда вы будете приобретать новый видеоадаптер, следите, чтобы он имел достаточный для вас объем видеопамяти.
Выпускаются адаптеры с видеопамятью двух типов - DRAM XE "Видеопамять:DRAM" (динамическая оперативная память) и VRAM XE "Видеопамять:VRAM" (специальная видеопамять). Различие между DRAM и VRAM состоит в том, что к памяти VRAM могут одновременно и независимо получить доступ два устройства. Поэтому VRAM иногда называют двух портовой памятью.
Видеоадаптеры, в которых установлена память VRAM обладают большей производительностью, по сравнению с видеоадаптерами, имеющими память DRAM. Однако стоимость таких видеоадаптеров значительно выше.
Для компьютерных систем, критичных к быстродействию видеоподсистемы, выпускаются специальные видеоадаптеры с графическими сопроцессорами. Такие видеоадаптеры могут брать на себя часть вычислительной работы, связанной с построением изображения. Например, они могут самостоятельно построить окружность, определенную ее центром и радиусом, могут аппаратно выполнять перемещение областей изображений на экране.
Для облегчения использования графических сопроцессоров вместе с ними поставляются драйверы к различным операционным системам и отдельным программам. Большинство видеоадаптеров продаются с драйверами для операционных систем Windows и OS/2, а также с драйверами для системы автоматизированного проектирования AutoCAD. Таким образом, в большинстве случаев у вас нет необходимости самим программировать графические сопроцессоры XE "Графические:сопроцессоры".
Частным случаем видеоадаптеров с графическими сопроцессорами являются графические акселераторы. Они специально предназначены для повышения производительности видеоподсистемы компьютера при работе в среде Windows (а также Windows NT, OS/2). Ориентация таких видеоадаптеров на Windows состоит в том, что они могут выполнять характерные для Windows операции с изображениями на аппаратном уровне. Например, они могут аппаратно реализовывать указатель (курсор) мыши размером 64х64 пиксела, могут аппаратно выполнять перемещение окон по экрану и т. д. Во всех этих случаях акселератор Windows, выполняет работу, которую при использовании обычных видеоадаптеров VGA и SVGA, делал центральный процессор компьютера.
Еще раз подчеркнем, что в отличие от более универсальных графических сопроцессоров, акселератор Windows ориентирован исключительно на использование совместно с Windows. Производительность графического акселератора Windows при использовании его с программами MS-DOS может быть даже ниже, чем у видеоадаптеров SVGA. Если вы предполагаете использовать компьютер для выполнения программ в среде Windows, вам крайне желательно приобрести графический акселератор Windows.
Чтобы увеличить производительность работы видеоадаптеров, на новых моделях видеоадаптеров устанавливают 64-разрядные графические сопроцессоры. Они значительно превосходят старые 16 и 32-разрядные модели адаптеров. Примером видеоадаптера с 64-разрядным графическим сопроцессором может служить плата Diamond Stealth 64.
Практически все платы графического акселератора и графические сопроцессоры могут работать в режимах High Color и True Color. Однако при таких объемах изображения, которые хранит видеопамять в режимах High Color и True Color, количество информации, передаваемое из оперативной памяти компьютера в видеопамять адаптера становится просто огромно. В этом случае замедление в отображении становиться видимым даже при использовании видеоадаптером прямого доступа к оперативной памяти компьютера.
Узким местом становиться системная шина компьютера. Пропускная способность системных шин компьютера EISA и ISA не превышает 10 Мбайт/с. Все современные видеоадаптеры подключаются к локальной шине XE "Локальная шина" процессора. Такой способ подключения видеоадаптера обеспечивает высокую скорость обмена информацией между оперативной памятью компьютера и центральным процессором с одной стороны и видеоадаптером XE "Видеоадаптер" с другой. Высокая скорость обмена информацией между компьютером и видеоадаптером, в свою очередь, гарантирует высокую производительность видеоподсистемы компьютера. Сегодня выпускаются видеоадаптеры, предназначенные для подключения к локальным шинам VLB и PCI.
 
 

Мониторы

Сегодня выпускается огромное количество всевозможных мониторов XE "Дисплей" различных фирм-производителей. Мы постараемся классифицировать мониторы по их основным характеристикам: типу интерфейса с видеоадаптером, разрешающей способности, которая тесно взаимодействует с частотой кадров, количеству цветов, которые может отображать монитор, и по размеру отдельных пикселов изображения.
По типу интерфейса с видеоадаптером мониторы можно разделить на композитные, цифровые и аналоговые RGB. Перечислим основные характеристики каждого из интерфейсов:
SYMBOL 119 \f "Wingdings" \s 10 \h Композитный. Монитор имеет один аналоговый вход. Видеосигнал поступает в монитор в стандарте NTSC (National Television System Commitete). Стандарт NTSC используется в бытовом телевидении. Композитный монитор обычно применяется совместно с видеоадаптером CGA
SYMBOL 119 \f "Wingdings" \s 10 \h Цифровой. Имеет от одной до шести входных линий. На цифровом мониторе может отображаться до 2n различных цветов, где n равно количеству входных линий. Данный тип мониторов используется вместе с видеоадаптерами CGA и EGA
SYMBOL 119 \f "Wingdings" \s 10 \h Аналоговый RGB. Имеет три аналоговые входные линии, управляющие красным, зеленым и синим цветами. Уровень напряжения на каждой линии отвечает за интенсивность соответствующего цвета на экране. Количество цветов, которые может отображать аналоговый монитор, ограничено практически только возможностями видеоадаптера. Аналоговый монитор используется совместно с адаптерами VGA, SVGA, графическими сопроцессорами, акселераторами Windows
Мониторы различаются по размеру зерна. Наибольшее распространение получили мониторы с зерном 0,28 мм, 0,31 мм и 0,39 мм. Мониторы с зерном 0,28 мм несколько дороже чем 0,39 мм, но зато обладают более высоким качеством. Мы рекомендуем приобретать мониторы с разрешением не больше 0,28 мм. На таких мониторах изображение более резкое и при работе за ними меньше устают глаза. Лучшие модели мониторов, например Sony Multiscan 15 SF, имеют зерно 0,25 мм.
Другими важными характеристиками монитора являются значения частот горизонтальной и вертикальной развертки, с которыми он может работать. Частота вертикальной развертки иногда также называется частотой кадров. В зависимости от этих частот и частоты синхросигнала видеоадаптера (описывается ниже) монитор может работать в режимах имеющих различное разрешение.
Мониторы старых моделей, например монохромные мониторы, могут работать только с фиксированными значениями частот горизонтальной и вертикальной развертки. Мониторы, предназначенные для подключения к видеоадаптерам VGA работают с несколькими фиксированными значениями частот развертки. Такие мониторы называют многочастотными. Большинство современных мониторов работают в некотором интервале частот развертки. Поэтому они получили название мультичастотных.
Следует учесть, что некоторые типы мониторов в режимах с большой разрешающей способностью используют метод чересстрочной развертки (Interlaced). При чересстрочной развертке XE "Черезстрочная развертка" сначала отображаются нечетные, а затем четные строки. Этот позволяет использовать в режимах с высоким разрешением мониторы, работающие с более низкой частотой развертки. К сожалению, использование чересстрочной развертки сопровождается слабым мерцанием изображения, раздражающим глаза. Более предпочтительно использование мониторов и видеоадаптеров, не применяющих метод чересстрочной развертки изображения (NonInterlaced).
Пожалуй, одной из самых трудных и долгих процедур при покупке компьютера является приобретение монитора. Наш опыт показывает, что если вы решили купить действительно хороший монитор, вам предстоит запастись терпением. Вероятней всего вам предстоит посетить не один магазин и оценить не один десяток изделий.
Проблема заключается в том, что если вы нашли подходящую модель монитора с маленьким размером зерна, например 0,28 мм, это не гарантирует что вам достанется отличный монитор. К сожалению, многие мониторы имеют такие дефекты, как искажение изображения, несведение лучей и т. д. Вам следует посмотреть на несколько мониторов, прежде чем остановить свой выбор.
Убедитесь что монитор имеет действительно маленькие размеры зерна. Проще всего это проверяется при отображении текстовой информации. Контуры символов должны быть четкие и хорошо проработанные. На экране высококачественных мониторов видно, что пикселы имеют квадратную форму. Если буквы "мохнатые", а пикселы отображаются как жирные точки, скорее всего, вам предлагают монитор с размером зерна 0,31 мм или 0,39 мм.
Теперь обратите внимание на дефект, называемый несведением лучей. Отобразите на экране монитора сетку из вертикальных и горизонтальных линий. Для этого можно воспользоваться тестами программы CheckIt. Посмотрите внимательно на границы линий. Их цвет должен соответствовать цвету линий. Если линии белые, а их границы синего или красного цвета - у этого монитора несведение лучей. Обычно несведение лучей наиболее выражено на границах экрана.
Несведение лучей можно наблюдать практически на всех мониторах, даже на очень высококачественных. Единственный простой и доступный способ борьбы с этим дефектом - просмотреть несколько мониторов, сравнить их и выбрать лучший.
Когда вы приобретаете монитор с размером экрана 17 дюймов, то ожидаете, что 17 дюймов это не размер корпуса монитора или электронно-лучевой трубки, а размер изображения на экране. Вооружитесь обычной линейкой и измерьте диагональ изображения на экране монитора. Она должна максимально соответствовать данным из паспорта данной модели. Если это не так, возможно лучше выбрать другой монитор.
Теперь поговорим об искажениях изображения. Они выражаются в том, что обычный прямоугольник на экране плохого монитора может приобрести самую неожиданную форму. Многие современные мониторы позволяют с помощью кнопок, ручек или других регуляторов исправить эти искажения.
SYMBOL 77 \f "Wingdings" Большинство дефектов мониторов, в том числе большой размер пикселов, несведение лучей и искажения изображения, заметны только когда на экране отображается графическое изображение состоящее из линий или прямоугольников. Часто на демонстрационных компьютерах показывают фрагменты игр, например, игры Doom или абстрактные разноцветные рисунки. В этом случае дефекты монитора незаметны
Современные видеоадаптеры и мониторы обладают возможностью временного отключения при длительном перерыве в работе с компьютером. В этом случае монитор переходит в экономичный режим и потребляет очень мало электроэнергии.
Фактически вы уже знакомы с возможностью отключения монитора. В серии "Персональный компьютер - шаг за шагом" мы рассказывали о программах сохранения экрана, которые могут гасить изображение.
Параметры наиболее распространенных мониторов, применяемых на компьютерах, совместимых с IBM PC/XT/AT, приведены в следующей таблице:
Монитор
Совместимый с монитором видеоадаптер
Количество цветов
Разрешение в текстовом режиме
Разрешение в графическом режиме
Монохромный (MD)
MDA, Hercules, EGA
 
 

 2 

80х25
640х350
720х350
720х348
Цветной (CD)


  CGA, EGA  



  16  


40x25
80x25
320x200
640x200
Улучшенный цветной (ECD)


  CGA, EGA  


16 из 64
80х25
320х200
640х200
640х350
Многочастотный цифровой


  CGA, EGA  


16 из 64
40x25
80х25
320x200
640х200
640х350
Многочастотный аналоговый


  VGA, SVGA  



  256  


80x25
640x480
800х600
Цветной VGA


  VGA  



  256  


40х25
80х25
320х400
640х400
Монохромный VGA


  VGA  



  256  


40х25
80х25
320х350
640х350
720х350
720х400
720х480
SYMBOL 119 \f "Wingdings" \s 10 \h Монохромный монитор
Первоначально компьютер IBM PC выпускался с монохромным монитором фирмы IBM (MD) и монохромным видеоадаптером (MDA). Видеоадаптер MDA не предоставляет возможности отображения графики и цвета, но за счет высокой разрешающей способности - 720х350 пикселов - он широко используется для приложений, работающих с текстами.
Монохромный монитор фирмы IBM и совместимые с ним видеоадаптеры используют частоту кадров, равную 50 Гц.
SYMBOL 119 \f "Wingdings" \s 10 \h Цветной монитор
Цветной монитор фирмы IBM (CD - Color Display) используется совместно с адаптером CGA и обеспечивает отображение четырех различных цветов для графики и восьми цветов для текста. Сам цветной монитор имеет возможность отображать шестнадцать различных цветов. Разрешение цветного монитора меньше, чем у монохромного - 640х200 и размер символов составляет 8 пикселов (пиксел - минимальный элемент изображения) по высоте и 8 пикселов по ширине. В результате заметно, что символы состоят из отдельных пикселов. С появлением улучшенного цветного монитора, имеющего большую разрешающую способность, этот недостаток был устранен.
Цветной монитор имеет частоту смены кадров, равную 60 Гц.
SYMBOL 119 \f "Wingdings" \s 10 \h Улучшенный цветной монитор
Улучшенный цветной монитор создан для использования совместно с видеоадаптером EGA. Он имеет большую разрешающую способность - 640х350 и может отображать большее количество цветов (любые 16 из 64), чем обычный цветной монитор. Символы имеют размер 8 пикселов по ширине и 14 пикселов по высоте.
SYMBOL 119 \f "Wingdings" \s 10 \h Многочастотный цветной монитор
Этот монитор имеет возможность работать с различной частотой кадров, что позволяет поддерживать режимы с различной разрешающей способностью. Обычно эти мониторы имеют разрешающую способность 640х350, (что соответствует EGA) и выше - 640х400, 640x480, 800x600, 1024x768. Последние два режима реализуются только видеоадаптерами SVGA.
Многочастотный цветной монитор может воспроизводить больше цветов, чем улучшенный цветной монитор. При работе в цифровом режиме он имеет те же 64 цвета, что и ECD, а при работе в аналоговом режиме он может отображать практически неограниченное число цветов. Большинство многочастотных мониторов можно использовать совместно с VGA. Первые модели многочастотного монитора фирмы NEC видеоадаптер VGA не поддерживали.
SYMBOL 119 \f "Wingdings" \s 10 \h Монитор VGA
Для видеоадаптера VGA фирмой IBM был разработан аналоговый RGB монитор с высоким разрешением, а также монохромный аналоговый монитор с высоким разрешением. На монохромном мониторе различные цвета изображаются различными градациями серого цвета. Эти два монитора (монохромный и цветной) являются взаимозаменяемыми - приложения, написанные для одного из монитора, могут работать с другим монитором.
 
 

2. Режимы работы видеоадаптеров

Режимы работы видеоадаптеров характеризуются типом информации, которую они отображают - текстовая или графическая, количеством используемых цветов, разрешающей способностью и размерами символов.
Существуют несколько стандартных режимов работы видеоадаптеров, поддерживаемых практически всеми адаптерами. Список стандартных режимов работы видеоадаптеров представлен в следующей таблице:
Режим работы
Тип информации
Количество цветов
Разрешение, пиксел x пиксел
Размер символов, пиксел x пиксел
 
 

 0, 1 

Текстовый цветной


  16  


40x25


  8x8  



  0*, 1*  


Текстовый цветной


  16  


40x25


  8x14  



  0+, 1+  


Текстовый цветной


  16  


40x25


  9x16  



  2, 3  


Текстовый цветной


  16  


80x25


  8x8  



  2*, 3*  


Текстовый цветной


  16  


80x25


  8x14  



  2+, 3+  


Текстовый цветной


  16  


80x25


  9x16  



  4, 5  


Графический цветной


  4  


320x200


  6  


Графический цветной


  2  


640x200


  7  


Текстовый монохромный


  2  


80x25


  9x14  



  7+  


Текстовый монохромный


  2  


80x25


  9x16  



  8, 9,  


0Ah
Используются видеоадаптерами компьютера PC jr, и в настоящее время интереса не представляют
0Bh, 0Ch Зарезервировано 0Dh Графический цветной 16 320x200 0Eh Графический цветной 16 640x200 0Fh Графический монохромный 2 640x350 10h Графический цветной 16 640x350 11h Графический цветной 2 640x480 12h Графический цветной 16 640x480 13h Графический цветной 256 320x200 Для видеоадаптеров EGA, VGA и SVGA режимы 0 и 1, 2 и 3, 4 и 5 не различаются. Отличие этих режимов существенно только для видеоадаптера CGA. В режимах 0, 2 и 5 не выполняется разбивка цветов (color burst) для композитного видеосигнала. В результате изображение на монохромных мониторах становиться более качественным. Стандартные режимы работы не включают в себя все режимы, в которых могут работать видеоадаптеры. Видеоадаптеры SVGA могут также работать в режимах, имеющих улучшенные характеристики. Характеристики этих режимов отличаются у видеоадаптеров разных фирм. Такие различия значительно усложняют программирование видеоадаптеров в режимах с высоким разрешением и большим количеством цветов. Вы должны позаботиться о том, чтобы программа распознавала тип видеоадаптера и использовала соответствующие методы работы с видеоадаптером. Примером может служить графический пакет CompuShow. Он содержит специальные драйверы для каждого типа видеоадаптеров. Во время установки пакета он определяет тип видеоадаптера и подключает соответствующий драйвер. Чтобы преодолеть несовместимость и избавить разработчиков программного обеспечения от необходимости создания собственных драйверов, ассоциация VESA (Video Electronics Standards Association) разработала одноименный стандарт VESA. Этот стандарт охватывает практически все возможности, предоставляемые современными видеоадаптерами. Приведем список режимов работы видеоадаптеров, соответствующих стандарту VESA: Режим работы Тип информации Количество цветов Разрешение, пиксел x пиксел Размер символов, пиксел x пиксел 100h Графический цветной 256 640x400 101h Графический цветной 256 640x480 8х16 102h Графический цветной 16 800x600 8х8 103h Графический цветной 256 800x600 8х8 104h Графический цветной 16 1024x768 105h Графический цветной 256 1024x768 8х16 106h Графический цветной 16 1280x1024 107h Графический цветной 256 1280x1024 108h Текстовый цветной 16 80x60 109h Текстовый цветной 16 132x25 9х16 10Ah Текстовый цветной 16 132x43 9х9 10Bh Текстовый цветной 16 132x50 10Ch Текстовый цветной 16 132x60 10Dh Графический цветной 32768 320x200 10Eh Графический цветной 65536 320x200 10Fh Графический цветной 16777216 320x200 110h Графический цветной 32768 640x480 111h Графический цветной 65536 640x480 112h Графический цветной 16777216 640x480 113h Графический цветной 32768 800x600 114h Графический цветной 65536 800x600 115h Графический цветной 16777216 800x600 116h Графический цветной 32768 1024x768 117h Графический цветной 65536 1024x768 118h Графический цветной 16777216 1024x768 119h Графический цветной 32768 1024x768 11Ah Графический цветной 65536 1280x1024 Более полную информацию о стандарте VESA мы привели в главе "Видеоадаптеры SVGA". В этой главе мы также поместили описание расширения BIOS, позволяющего легко программировать видеоадаптеры SVGA, совместимые со стандартом VESA. Режимы 0 и 1 При использовании видеоадаптеров EGA или VGA не существует функциональных различий между режимом 0 и режимом 1. В данных режимах монитор отображает цветную текстовую (алфавитно-цифровую) информацию - 25 строк и 40 столбцов. Из-за низкой разрешающей способности режимы 0 и 1 практически не применяются. Современные видеоадаптеры поддерживают эти режимы только для обеспечения совместимости с видеоадаптерами CGA и MDA. Для отображения каждого символа используется матрица пикселов размера 8x8 пикселов, что соответствует низкому качеству изображения. Можно различить отдельные пикселы из которых состоят символы отображаемого текста. Символы текста можно отображать в 8 основных и 8 дополнительных цветах. Дополнительные цвета имеют большую интенсивность, чем основные. Для каждого символа можно независимо задать его цвет и цвет фона. Список стандартных и дополнительных цветов представлен в следующей таблице: Стандартный цвет Дополнительный цвет Черный Серый Синий Светло-синий Зеленый Светло-зеленый Морской волны Голубой Красный Светло-красный Фиолетовый Малиновый Коричневый Желтый Белый Ярко-белый Для видеоадаптеров EGA, VGA и SVGA можно изменить используемую палитру цветов. Адаптер EGA с улучшенным цветным монитором позволяет выбрать 16 цветов из 64 возможных, а VGA и SVGA - 16 цветов из 262144 возможных. В режимах 0 и 1 адаптеры EGA, VGA и SVGA поддерживают восемь страниц видеопамяти. Страницей называется часть видеопамяти, полностью определяющая содержимое одного экрана монитора. Одна из этих восьми страниц является активной. Ее содержимое отображается на экране. Для изменения активной страницы можно вызвать соответствующую функцию BIOS или непосредственно изменить содержимое регистра начального адреса, расположенного в контроллере электронно лучевой трубки. Рисунок 2.1 демонстрирует страничную организацию видеопамяти. На мониторе отображается содержимое первой страницы памяти, расположенной по адресу B000:0800h. \s \* MERGEFORMAT PICTURE._FIG_02.PCX;6";4.308";PCX Рисунок 2.1 Страничная организация видеопамяти К каждой странице видеопамяти вы можете обратиться как через функции BIOS, так и напрямую. Во втором случае процессор записывает необходимую информацию непосредственно в видеопамять. Страницы видеопамяти располагаются по следующим адресам: Страница 0 - B800:0000h Страница 1 - B800:0800h Страница 2 - B800:1000h Страница 3 - B800:1800h Страница 4 - B800:2000h Страница 5 - B800:2800h Страница 6 - B800:3000h Страница 7 - B800:3800h Видеоадаптеры VGA и SVGA в режимах с низким разрешением используют двойное сканирование. Двойное сканирование заключается в том, что при работе видеоадаптера в режимах с разрешением 200 строк, каждая из строк отображается на экране дважды, увеличивая разрешение по вертикали до 400 строк. В результате улучшается восприятие текста на экране, так как фактически увеличивается разрешающая способность. Двойное сканирование реализуется в режимах 0, 1, 2, 3, 4, 5, 6, 0Dh и 0Eh. Режимы 0*, 1* Режимы EGA 0* и 1* являются расширенными версиями режимов 0 и 1 адаптера CGA. Эти режимы отличаются только размером матрицы пикселов, используемой для отображения символов текста. В режимах 0* и 1* матрица имеет большее число элементов - 8х14 пикселов. Из-за различий в размерности матриц символов ухудшается совместимость между видеоадаптерами CGA и EGA. В частности возникают трудности при установке формы курсора и положения линии подчеркивания символов. Режимы 0 +, 1 + Видеоадаптеры VGA и SVGA реализуют собственные расширенные версии режимов 0 и 1. Они обозначаются как 0 + и 1 +. Эти режимы отличаются от режимов 0 и 1 только размером матрицы пикселов, используемой при отображении символов текста. В режимах 0 + и 1 + матрица имеет большее число элементов - 9х16 пикселов. Как и для режимов 0* и 1*, отличие размерности матриц символов создает трудности при создании совместимых программ для адаптеров CGA, EGA, VGA и SVGA. Необходимо быть уверенным в правильности установки формы курсора и положения линии подчеркивания символов. Режимы 2 и 3 Во втором и третьем режимах монитор отображает цветную текстовую информацию. Количество строк, также как и в режимах 0 и 1, равно 25, а количество столбцов увеличено до 80. Для видеоадаптеров EGA, VGA и SVGA данные режимы не имеют различий. Символы текста можно отображать в 8 основных и 8 дополнительных цветах, имеющих большую интенсивность, чем основные. Для каждого символа можно независимо задать его цвет и цвет фона. Вы можете использовать те же цвета, что в режимах 0 и 1. В данных режимах работы видеоадаптеры EGA, VGA и SVGA поддерживают 8 страниц экрана. Исключение составляют конфигурации, в которых видеоадаптер EGA имеет только 64 Кбайт видеопамяти. В этом случае EGA поддерживает только первые 4 страницы видеопамяти. Одна из этих восьми страниц является активной. Страницы видеопамяти располагаются по следующим адресам: Страница 0 - B800:0000h Страница 1 - B800:1000h Страница 2 - B800:2000h Страница 3 - B800:3000h Страница 4 - B800:3000h Страница 5 - B800:5000h Страница 6 - B800:4000h Страница 7 - B800:7000h Режимы 2*, 3* Режимы EGA 2* и 3* являются расширенными версиями режимов 2 и 3 для CGA. Эти режимы отличаются только размером матрицы пикселов, используемой для отображения символов текста. В режимах 2* и 3* матрица имеет большее число элементов - 8х14 пикселов. Режимы 2 +, 3 + Видеоадаптеры VGA и SVGA реализуют собственные расширенные версии режимов 2 и 3. Они обозначаются как 2 + и 3 +. Эти режимы отличаются от режимов 2 и 3 только размером матрицы пикселов, используемой при отображении символов текста. В режимах 2 + и 3 + матрица имеет большее число элементов - 9х16 пикселов. Как указывалось выше, в режимах 2 и 3 видеоадаптеры VGA и SVGA используют двойное сканирование. Режимы 4 и 5 В этих режимах отображается цветная графическая информация. Экран монитора имеет разрешение 320 пикселов по горизонтали и 200 пикселов по вертикали. При отображении могут использоваться либо четыре основных, либо четыре альтернативных цвета: Стандартные цвета Альтернативные цвета Черный Черный Светло-синий Зеленый Малиновый Красный Белый Коричневый В отличие от предыдущих режимов поддерживается только одна страница видеопамяти. Ее начальный адрес равен B800:0000h. Режим 6 В этом режиме отображается графическая информация. Экран монитора имеет разрешение 640 пикселов по горизонтали и 200 пикселов по вертикали. Поддерживаются только два цвета. Для видеоадаптера CGA режим 6 является режимом с максимальным разрешением. Определена только одна страница видеопамяти, имеющая начальный адрес B800:0000h. Если видеоадаптеры VGA или SVGA работают в режиме 6, то они используют двойное сканирование. Режим 7 В этом режиме отображается монохромная текстовая информация. Экран монитора имеет разрешающую способность 25 строк на 80 столбцов. Матрица символов имеет ширину 9 пикселов, а высоту - 14 пикселов. Видеоадаптеры EGA, VGA и SVGA в режиме 7 практически полностью программно совместимы с видеоадаптером MDA. В режиме 7 видеоадаптеры EGA, VGA и SVGA поддерживают 8 страниц видеопамяти, за исключением конфигураций, в которых адаптер EGA имеет только 64 Кбайт памяти. В этом случае EGA поддерживает только первые 4 страницы. Страницы экрана располагаются в видеопамяти по следующим адресам: Страница 0 - B800:0000h Страница 1 - B800:1000h Страница 2 - B800:2000h Страница 3 - B800:3000h Страница 4 - B800:3000h Страница 5 - B800:5000h Страница 6 - B800:4000h Страница 7 - B800:7000h Режим 7 + Режим видеоадаптеров VGA и SVGA номер 7 +, является расширенной версией режима 7 адаптера EGA. Этот режим отличается только размером матрицы пикселов, используемой для отображения символов текста. В режиме 7 + матрица имеет большее число элементов - 9х16 пикселов. Режимы 8, 9, 0Ah Данные режимы используются только в компьютере PCjr и в нашей книге не рассматриваются. Режим 0Dh Режим 0Dh используется для отображения графической информации. При этом разрешающая способность составляет 320 пикселов по горизонтали и 200 пикселов по вертикали. Данный режим похож на режим 4, но в нем видеоадаптер может отображать 16 цветов. В зависимости от объема памяти видеоадаптера, поддерживается различное количество страниц видеопамяти: Объем видеопамяти Количество страниц видеопамяти 256 Кбайт 8 128 Кбайт 4 64 Кбайт 2 Страницы видеопамяти располагаются по следующим адресам: Страница 0 - B800:0000h Страница 1 - B800:1000h Страница 2 - B800:2000h Страница 3 - B800:3000h Страница 4 - B800:3000h Страница 5 - B800:5000h Страница 6 - B800:4000h Страница 7 - B800:7000h Если видеоадаптеры VGA и SVGA работают в режиме 0Dh, то для увеличения разрешающей способности они используют двойное сканирование. Режим 0Eh Режим 0Eh используется для отображения графической информации. Разрешающая способность составляет 640 пикселов по горизонтали и 200 пикселов по вертикали. В данном режиме видеоадаптер может одновременно отображать 16 различных цветов. В зависимости от объема видеопамяти поддерживается различное количество страниц видеопамяти: Объем видеопамяти Количество страниц видеопамяти 256 Кбайт 4 128 Кбайт 2 64 Кбайт 1 Страницы видеопамяти располагаются по следующим адресам: Страница 0 - A000:0000h Страница 1 - A000:4000h Страница 2 - A000:8000h Страница 3 - A000:C000h Если видеоадаптеры VGA и SVGA работают в режиме 0Eh, то они используют двойное сканирование. Режим 0Fh Монохромный графический режим с разрешением 640 пикселов по горизонтали и 350 пикселов по вертикали. Видеоадаптер EGA поддерживает две страницы экрана за исключением того случая, когда видеопамять ограничена 64 Кбайт. В этом случае доступна только одна страница. Страницы видеопамяти располагаются по следующим адресам: Страница 0 - A000:0000h Страница 1 - A000:8000h Каждый пиксел определяется двумя битами. Пикселы могут быть черного цвета, белого цвета, интенсивно белого цвета или могут отображаться постоянно мигающими. Режим 10h Цветной графический режим с разрешением 640 пикселов по горизонтали и 350 пикселов по вертикали. Данный режим обеспечивает отображение 16 цветов, кроме конфигураций, в которых видеоадаптер EGA укомплектован только 64 Кбайт видеопамяти. Адаптер EGA с 64 Кбайт видеопамяти обеспечивает отображение только четырех цветов. Стандартная цветовая палитра для данного режима представлена в следующей таблице: Полная палитра (объем видеопамяти не меньше 128 Кбайт) Неполная палитра (64 Кбайт видеопамяти) Черный Черный Голубой Голубой Зеленый Черный Синий Голубой Красный Красный Фиолетовый Белый Коричневый Красный Белый Белый Темно-серый Черный Светло-голубой Голубой Светло-зеленый Черный Светло-синий Голубой Светло-красный Красный Светло-малиновый Белый Желтый Красный Интенсивно-белый Белый Вы можете изменить цветовую палитру, переустановив регистры палитры в контроллере атрибутов. Как это сделать мы расскажем в главе "Контроллер атрибутов". Режим 11h Цветной графический режим с разрешением 640 пикселов по горизонтали и 480 пикселов по вертикали. Данный режим обеспечивает отображение только двух цветов. Видеопамять образует одну страницу. Начальный адрес видеопамяти A000:0000h. Режим 12h Цветной графический режим с разрешением 640 пикселов по горизонтали и 480 пикселов по вертикали. Данный режим обеспечивает отображение 16 цветов. Видеопамять образует одну страницу. Начальный адрес видеопамяти A000:0000h. Режим 13h Цветной графический режим с разрешением 320 пикселов по горизонтали и 200 пикселов по вертикали. Данный режим обеспечивает возможность одновременного отображения 256 цветов. Несмотря на низкую разрешающую способность монитора в этом режиме, изображение кажется более реалистичными, так как появляется возможность отображать мелкие детали другим цветом. Видеопамять образует одну страницу. Начальный адрес видеопамяти A000:0000h. 3. Архитектура видеоадаптеров EGA и VGA В этой главе мы расскажем об архитектуре видеоадаптеров EGA и VGA. Видеоадаптеры EGA и VGA можно условно разделить на шесть логических блоков: SYMBOL 119 \f "Wingdings" \s 10 \h Видеопамять В видеопамяти размещаются данные, отображаемые адаптером на экране монитора. Для видеоадаптеров EGA и VGA видеопамять, как правило, имеет объем 256 Кбайт. Видеоадаптеры SVGA оснащаются значительно большим объемом видеопамяти. В них может быть установлено больше 4 Мбайт памяти. Видеопамять находится в адресном пространстве процессора. Программы могут непосредственно производить с ней обмен данными. SYMBOL 119 \f "Wingdings" \s 10 \h Графический контроллер Используется при обмене данными между центральным процессором компьютера и видеопамятью. Аппаратура графического контроллера позволяет выполнять над данными, поступающими в видеопамять, простейшие логические операции (И, ИЛИ, ИСКЛЮЧАЮЩЕЕ ИЛИ, циклический сдвиг). SYMBOL 119 \f "Wingdings" \s 10 \h Последовательный преобразователь Выбирает из видеопамяти один или несколько байт, преобразует их в последовательный поток битов и передает контроллеру атрибутов. SYMBOL 119 \f "Wingdings" \s 10 \h Контроллер ЭЛТ Генерирует временные синхросигналы, управляющие ЭЛТ. SYMBOL 119 \f "Wingdings" \s 10 \h Контроллер атрибутов Преобразует информацию о цвете из формата, в котором она хранится в видеопамяти, в формат, необходимый для ЭЛТ. Преобразование цветов осуществляется в соответствии с таблицей цветовой палитры (Color Look-up Table). Модифицируя таблицу цветовой палитры, можно выбрать 16 цветов, поддерживаемых видеоадаптером EGA из 64 цветов, которые может отображать цветной улучшенный монитор. SYMBOL 119 \f "Wingdings" \s 10 \h Синхронизатор Определяет все временные параметры видеоадаптера. Синхронизатор также управляет доступом процессора к цветовым слоям видеопамяти На рисунке 3.1 представлена блок схема видеоадаптеров EGA и VGA, в которой отображены связи между их основными логическими блоками. \s \* MERGEFORMAT PICTURE._FIG_19.PCX;6";4.308";PCX Рисунок 3.1 Блок схема видеоадаптеров EGA/VGA Все сказанное нами остается верно и для видеоадаптеров SVGA. Однако устройство видеоадаптеров SVGA значительно сложнее. Большинство видеоадаптеров SVGA содержат специальный графический сопроцессор, который может выполнять различные функции, например, он может использоваться для рисования различных геометрических фигур, масштабирования участков изображения и т. д. Монитор В большинстве мониторов устройство отображения представляет собой электронно-лучевую трубку, газоразрядную или жидкокристаллическую панель. Для стационарных компьютеров обычно используются мониторы с ЭЛТ. Газоразрядные и жидкокристаллические панели применяют в переносных и блокнотных компьютерах. ЭЛТ состоит из электронной пушки (или из трех пушек для цветного монитора), отклоняющей системы и экрана, покрытого слоем люминофора. Все эти устройства помещены в вакуумный баллон. Электронная пушка служит источником электронов, направляемых при помощи отклоняющей системы в нужную часть экрана, где электроны взаимодействуют с покрытием экрана. В результате взаимодействия испускается видимый свет. Изображение формируется за счет пробега луча электронов слева направо по горизонтальным линиям экрана (строкам развертки). Чтобы глаз не замечал смены кадров, пробег луча по всему экрану происходит с частотой, большей чем 25 Гц. Луч электронов начинает пробегать по экрану с верхнего левого угла до правого верхнего угла. Когда луч доходит до правой стороны, он гасится и перемещается на следующую горизонтальную линию, находящуюся под предыдущей линией. После того как луч пробежит по всему экрану, он гасится и перемещается в верхний левый угол. Затем процесс повторяется снова. След от луча на экране образует растр (рис. 3.2). \s \* MERGEFORMAT PICTURE._FIG_20.PCX;6";4.308";PCX Рисунок 3.2 Экран электронно-лучевой трубки Изменяя силу тока в луче электронов при формировании им растра, можно менять интенсивность свечения отдельных элементов экрана - пикселов. Данные в видеопамяти как раз и определяют, как модулируется луч электронов во время сканирования экрана. Для решения задач управления лучом электронов служит большинство регистров контроллера электронно-лучевой трубки (контроллера ЭЛТ). Видеопамять Видеоадаптеры EGA и VGA содержат на своей плате до 256 Кбайт оперативной памяти, разделенной на четыре банка или, другими словами, на четыре цветовых слоя. Эти слои памяти размещаются в одном адресном пространстве. Таким образом, что по каждому адресу расположено четыре байта (по байту в каждом слое памяти). Какой из слоев памяти используется для записи или чтения данных процессором, определяется с помощью установки нескольких регистров адаптера. Так как все четыре слоя памяти находятся в одном адресном пространстве, то процессор может выполнять запись во все четыре слоя за один цикл записи. Благодаря этому некоторые операции, например заполнение экрана, происходят с большой скоростью. В том случае, когда запись во все четыре слоя памяти нежелательна, можно запретить или разрешить запись в отдельные слои памяти, соответствующим образом программируя регистр разрешения записи цветового слоя. Для операции чтения в каждый момент времени может быть разрешен только один цветовой слой. Читаемый слой определяется регистром выбора читаемого цветового слоя. В большинстве режимов видеоадаптеров видеопамять состоит из нескольких страниц. При этом одна из них является активной и отображается на экране. Переключать активные страницы видеопамяти можно при помощи функций BIOS или путем непосредственного программирования регистров видеоадаптера. Информацию можно записывать как в активную, так и в неактивные страницы памяти. Таким образом, можно заранее подготовить несколько страниц памяти (несколько экранов), а затем быстро сменять их на экране монитора. Видеоадаптер SVGA обычно содержит значительно больше памяти и ее структура может быть сложнее, чем у адаптеров EGA и VGA. Однако при работе видеоадаптера в стандартных режимах можно считать что архитектура видеопамяти SVGA полностью соответствует VGA. Организация видеопамяти адаптеров SVGA, для режимов с высоким разрешением и большим количеством одновременно отображаемых цветов значительно отличается от организации видеопамяти адаптеров EGA и VGA в стандартных режимах работы. Мы посвятили видеоадаптерам SVGA, в том числе организации видеопамяти, отдельную главу "Видеоадаптеры SVGA". Текстовый режим В текстовых режимах на экране могут отображаться только текстовые символы, а также символы псевдографики. Текстовые режимы работы видеоадаптеров рекомендуется использовать всегда, когда приложению не нужно выводить на экран графическую информацию. Стандартные текстовые режимы работы видеоадаптеров позволяют вывести на экран 25 строк по 40 или 80 символов. Если перепрограммировать некоторые регистры видеоадаптера, то можно увеличить число отображаемых строк для адаптера EGA до 43, а для VGA до 50. Если в компьютере установлен видеоадаптер SVGA, вам могут быть доступны другие текстовые режимы - 80x60, 132x25, 132x43, 132x50, 132x60 символов. Для кодирования каждого знакоместа экрана (символа) используются два байта. Первый из них содержит ASCII-код отображаемого символа, а второй - атрибуты символа (рис. 3.3). Атрибуты символа определяют его цвет и цвет фона. \s \* MERGEFORMAT PICTURE._FIG_21.PCX;6";4.308";PCX Рисунок 3.3 Структура видеопамяти в текстовых режимах ASCII-коды символов экрана располагаются в нулевом цветовом слое, а их атрибуты - в первом цветовом слое. Благодаря такому режиму хранения информации достигается значительная экономия памяти. При отображении символа на экране происходит преобразование его из формата ASCII в двумерный массив пикселов, выводимых на экран. Для этого преобразования используется таблица трансляции символов (таблица знакогенератора). Таблица знакогенератора хранится во втором слое видеопамяти (рис. 3.4). \s \* MERGEFORMAT PICTURE._FIG_06.PCX;6";4.308";PCX Рисунок 3.4 Преобразование кода ASCII в образ символа на экране При непосредственном доступе к видеопамяти нулевой и первый цветовые слои отображаются на общее адресное пространство. При этом происходит чередование байтов из нулевого и первого слоев. Коды символов имеют четные адреса, а их атрибуты - нечетные (рис. 3.5). \s \* MERGEFORMAT PICTURE._FIG_22.PCX;6";4.308";PCX Рисунок 3.5 Отображение цветовых слоев Ниже приведен дамп видеопамяти в текстовом режиме с разрешением 80х25 символов: Адрес 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
- ____________________ 
B800:0000 91 07 E2 07 E0 07 AE 07-AA 07 A0 07 20 07 AD 07 С.т.р.о.к.а..н.
B800:0010 AE 07 AC 07 A5 07 E0 07-20 07 30 07 20 07 20 07 о.м.е.р..0...
B800:0020 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:0030 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:0040 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:0050 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:0060 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:0070 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:0080 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:0090 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:00A0 91 07 E2 07 E0 07 AE 07-AA 07 A0 07 20 07 AD 07 С.т.р.о.к.а..н.
B800:00B0 AE 07 AC 07 A5 07 E0 07-20 07 31 07 20 07 20 07 о.м.е.р..1...
B800:00C0 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:00D0 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:00E0 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:00F0 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:0100 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:0110 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:0120 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07....
B800:0130 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07.... Байты кодов символов из нулевого цветового слоя видеопамяти чередуются с байтами атрибутов символов из первого цветового слоя. Байты кодов символов расположены по четным адресам, а байты атрибутов, которые для данного участка видеопамяти имеют значение 07h - по нечетным. Знакогенератор При установке текстовых режимов работы видеоадаптеров BIOS загружает таблицы знакогенератора из ПЗУ во второй цветовой слой видеопамяти. Впоследствии эти таблицы используются для отображения символов на экране монитора. Благодаря этому, можно легко заменить стандартную таблицу знакогенератора своей собственной. Эта особенность, широко применяется при русификации компьютеров. У видеоадаптера CGA таблицы знакогенератора расположены в ПЗУ, поэтому изменить образы символов текстового режима нельзя. Видеоадаптеры обеспечивают возможность одновременной загрузки в видеопамять нескольких различных таблиц знакогенератора. Видеоадаптер EGA позволяет загрузить четыре таблицы, а видеоадаптеры VGA и SVGA - восемь. Каждая такая таблица знакогенератора содержит описание 256 символов. Активными могут быть одна или две таблицы знакогенератора. Это дает возможность одновременно отображать на экране до 512 различных символов. Один бит из байта атрибутов указывает, какая из двух активных таблиц знакогенератора используется при отображении данного символа. Номера активных таблиц знакогенератора определяются регистром выбора знакогенератора. Этот регистр будет описан ниже. Рисунок 3.6 иллюстрирует использование двух таблиц знакогенератора. В верхней части рисунка символ, имеющий код ASCII 31h, отображается на экране при помощи первой таблицы знакогенератора. В нижней части рисунка символ с тем же кодом ASCII отображается при помощи третей таблицы знакогенератора, и имеет другую форму. \s \* MERGEFORMAT PICTURE._FIG_23.PCX;6";4.308";PCX Рисунок 3.6 Активные таблицы знакогенераторов Видеоадаптер EGA поддерживает два размера для матриц символов - стандартный и улучшенный. Стандартный размер составляет 8 пикселов в ширину и 8 пикселов в высоту, а улучшенный - 8 пикселов в ширину и 14 пикселов в высоту. Один из этих наборов символов автоматически загружается BIOS в видеопамять при выборе текстового режима. Так как адаптеры VGA и SVGA имеют большую разрешающую способность, то их набор символов имеет в ширину 9 пикселов, а в высоту - 16. Адреса таблиц знакогенератора для видеоадаптеров EGA, VGA и SVGA приведены в следующей таблице: Первая таблица знакогенератора Вторая таблица знакогенератора Символ ASCII 0 0000h-001Fh Символ ASCII 0 2000h-201Fh Символ ASCII 1 0020h-003Fh Символ ASCII 1 2020h-203Fh Символ ASCII 2 0040h-005Fh Символ ASCII 2 2040h-205Fh............ Символ ASCII 255 1FE0h-1FFFh Символ ASCII 255 3FE0h-3FFFh Третья таблица знакогенератора Четвертая таблица знакогенератора Символ ASCII 0 4000h-401Fh Символ ASCII 0 6000h-601Fh Символ ASCII 1 4020h-403Fh Символ ASCII 1 6020h-603Fh Символ ASCII 2 4040h-405Fh Символ ASCII 2 6040h-605Fh............ Символ ASCII 255 5FE0h-1FFFh Символ ASCII 255 7FE0h-7FFFh Пятая таблица знакогенератора (только VGA) Шестая таблица знакогенератора (только VGA) Символ ASCII 0 8000h-801Fh Символ ASCII 0 A000h-A01Fh Символ ASCII 1 8020h-803Fh Символ ASCII 1 A020h-A03Fh Символ ASCII 2 8040h-805Fh Символ ASCII 2 A040h-A05Fh............ Символ ASCII 255 9FE0h-9FFFh Символ ASCII 255 BFE0h-BFFFh Седьмая таблица знакогенератора (только VGA) Восьмая таблица знакогенератора (только VGA) Символ ASCII 0 C000h-C01Fh Символ ASCII 0 E000h-E01Fh Символ ASCII 1 C020h-C03Fh Символ ASCII 1 E020h-E03Fh Символ ASCII 2 C040h-C05Fh Символ ASCII 2 E040h-E05Fh............ Символ ASCII 255 DFE0h-DFFFh Символ ASCII 255 FFE0h-FFFFh Как видно из этой таблицы, на каждый символ отводится 32 байта. Самый простой способ загрузки собственных таблиц знакогенератора во второй слой видеопамяти заключается в использовании функций BIOS. Мы продемонстрируем его позже в главе "Русификация видеоадаптера". Атрибуты символов Внешний вид символа, отображаемого на экране в текстовом режиме, определяется не только его кодом ASCII, но и байтом атрибутов. Атрибуты задают цвет символа, цвет фона, а также некоторые другие параметры: Биты байта атрибутов Назначение D2-D0 Цвет символа D3 Интенсивность символа и выбор таблицы знакогенератора D6-D4 Цвет фона символа D7 Мигание символа или интенсивность фона символа Биты D0-D2 байта атрибутов определяют цвет символа, а биты D4-D6 цвет фона, на котором отображается символ. Таким образом, можно независимо задавать до 2 3 = 8 различных цветов для текста и фона. Бит D3 играет различную роль в зависимости от числа активных таблиц знакогенератора. Если активной является одна таблица, бит D3 используется для управления интенсивностью цвета символа, что позволяет увеличить количество воспроизводимых цветов от 8 до 16. Если одновременно определены две таблицы знакогенератора, то бит D3 также задает таблицу знакогенератора, которая будет использована при отображении данного символа. Бит D7 выполняет две различные функции в зависимости от состояния регистра режима контроллера атрибутов. Данный бит управляет либо интенсивностью цвета фона, увеличивая количество одновременно отображаемых цветов до 16, либо разрешением гашения символа, в результате чего символ на экране монитора будет мигать. По умолчанию D7 бит управляет разрешением гашения символа (миганием). В следующей таблице представлено соответствие цвета символа и цвета фона значению поля цвета символа байта атрибутов: Код цвета в байте атрибутов Стандартный цвет Цвет с повышенной интенсивностью 000 Черный Серый 001 Синий Светло-синий 010 Зеленый Светло-зеленый 011 Морской волны Голубой 100 Красный Светло-красный 101 Фиолетовый Малиновый 110 Коричневый Желтый 111 Белый Ярко-белый Атрибуты символов (монохромный режим) Назначение полей байта атрибутов в монохромном режиме сходно с их назначениями в цветном режиме (см. выше). Биты D0-D2 управляют типом символа, который может быть обычным, мигающим или подчеркнутым, биты D4-D6 могут выбрать обратный (инвертированный) символ. Бит D3 играет различную роль в зависимости от того, сколько таблиц знакогенератора одновременно являются активными. Если активной является одна таблица, то бит D3 используется для управления интенсивностью символа. Если одновременно определены две таблицы знакогенератора, тогда бит D3 также задает таблицу знакогенератора, которая будет использована при отображении данного символа. Бит D7 выполняет две различные функции в зависимости от состояния регистра режима контроллера атрибутов. Он управляет либо интенсивностью фона, либо миганием символа. По умолчанию бит D7 управляет миганием символа. Перечислим все возможные значения атрибутов символов в текстовом монохромном режиме: Атрибут Внешний вид символа 00000000b (00h) Черный символ на черном фоне 00000001b (01h) Подчеркнутый символ 00000111b (07h) Обычный символ (светлый символ на черном фоне) 00001001b (09h) Подчеркнутый символ с повышенной интенсивностью 00001111b (0Fh) Символ с повышенной интенсивностью 01110000b (70h) Обратное отображение символа (черный символ на светлом фоне) 10000001b (81h) Подчеркнутый мигающий символ 10000111b (87h) Мигающий символ 10001001b (89h) Подчеркнутый мигающий символ с повышенной интенсивностью 11110000b (0F0h) Мигающее обратное отображение символа В случае использования других значений атрибутов результат зависит от конкретной модели видеоадаптера. Теперь приведем программу TEXTATTR (листинг 3.1), иллюстрирующую непосредственный доступ к видеопамяти в текстовых режимах работы адаптера. При запуске программы TEXTATTR вы должны указать ей два числовых параметра. Первый параметр определяет режим работы видеоадаптера. Вы можете задать любой текстовый режим. Второй параметр управляет атрибутами символов, отображаемых на экране монитора. Если второй параметр равен 0, то бит D7 байта атрибутов управляет интенсивностью фона символов, а если он равен 1, то бит D7 байта атрибутов управляет миганием символов. Листинг 3.1. Файл TEXTATTR.C #include "stdio.h"
#include "conio.h"
#include "dos.h"
// Файл для определения макрокоманды FP_MAKE
#include "sysp.h"
// Файл для определения структуры VIDEOBUF
#include "sysgraph.h"
// Описание функций
void SetVideoMode( unsigned char vmode );
void SetBlinkIntensity( unsigned char mode );
int GetColumn(void);
int GetVideoBuf(int);
void Hello(void);
int main( int, char ** );
//- ____________________ 
// Главная функция программы
//- ____________________ 
int main( int argc, char * argv[] )
{
union REGS inregs, outregs;
VIDEOBUF _far *vbuf, _far *ptr_vbuf;
unsigned char background, foreground;
unsigned char char_attr;
int vmode, bl_in_mode;
char szText[4];
// Проверка командной строки программы
if( argc!= 3 )
{
Hello();
return - 1;
}
// Разбор строки параметров
sscanf(argv[1],"%d",vmode);
sscanf(argv[2],"%d",bl_in_mode);
// Если указан графический режим, завершаем программу
if(vmode" 3 vmode!= 7)
return(- 2);
// Если неправильно указан параметр "интенсивность",
// завершаем программу
if((bl_in_mode!= 0)(bl_in_mode!= 1))
return(- 3);
// Устанавливаем новый режим работы видеоадаптера,
// указанный параметром "режим"
SetVideoMode((unsigned char) vmode );
// Выбираем как будут интерпритироваться атрибуты
// символов. Если параметр "интенсивность" равен 0
// атрибуты управляют интенсивностью цвета символов,
// если параметр равен 1 атрибуты управляют миганием
//символов
SetBlinkIntensity((unsigned char) bl_in_mode );
// Определяем адрес начала активной страницы
// видеопамяти
ptr_vbuf = vbuf= (VIDEOBUF _far *)
FP_MAKE(GetVideoBuf((unsigned char) vmode ),0);
// Отображаем на экране массив символов, имеющих
// различные атрибуты
for( background=0; background "16; background++)
{
for( foreground=0; foreground "16; foreground++)
{
char_attr =
(unsigned char)((background "4) | foreground);
sprintf( szText, "%02X", char_attr );
// Отображаем на экране символ. Записываем
// в видеопамять код символа и его атрибут
ptr_vbuf- " chr =
szText[0]; ptr_vbuf-" attr = char_attr;
ptr_vbuf++;
ptr_vbuf- " chr =
szText[1]; ptr_vbuf-" attr = char_attr;
ptr_vbuf++;
}
ptr_vbuf = vbuf = vbuf + GetColumn();
}
// Ожидаем нажатие на любую клавишу клавиатуры
getch();
// Устанавливаем текстотвый режим номер 3
SetVideoMode(3);
return 0;
}
//- ____________________ 
// Функция возвращает сегментный адрес активной страницы
// видеопамяти (учитывается значение регистров смещения
// адреса видеопамяти)
//- ____________________ 
int GetVideoBuf(int vmode) {
unsigned vbase;
unsigned adr_CRT;
unsigned high;
unsigned low;
unsigned offs;
// В зависимости от режима видеоадаптера базовый адрес
// видеопамяти может быть 0xb000 или 0xb800
vbase = (vmode - 7)? 0xb000: 0xb800;
// Определяем адрес порта контроллера ЭЛТ
adr_CRT = *(unsigned _far *)(FP_MAKE(0x40,0x63));
// Считываем содержимое регистров начального адреса
outp(adr_CRT,0xc);
high = inp(adr_CRT+1);
outp(adr_CRT,0xd);
low = inp(adr_CRT+1);
offs = ((high "8) + low)" 4;
// Добавляем к базовому адресу видеопамяти смещение,
// взятое из регистров начального адреса
vbase += offs;
return(vbase);
}
//- ____________________ 
// Функция возвращает количество символов в строке
//- ____________________ 
int GetColumn(void) {
// Считываем содержимое переменной BIOS, расположенной по
// адресу 0000:044Ah. В ней записано количество символов
// в строке для текущего режима
return(*(int _far *)(FP_MAKE(0x40,0x4a)));
}
//- ____________________ 
// Функция устанавливает режим работы видеоадаптера, заданный
// параметром vmode
//- ____________________ 
void SetVideoMode( unsigned char vmode ) {
union REGS inregs, outregs;
// Устанавливаем режим vmode
inregs.h.ah = 0x0;
inregs.h.al = vmode;
int86( 0x10, inregs, outregs );
}
//- ____________________ 
// Функция управляет назначением атрибутов символов.
// mode = 0 атрибут управляет интенсивностью цвета символов
// mode = 1 атрибут управляет миганием символов
//- ____________________ 
void SetBlinkIntensity( unsigned char mode ) {
union REGS inregs, outregs;
inregs.h.ah = 0x10;
inregs.h.al = 0x3;
inregs.h.bl = mode;
int86( 0x10, inregs, outregs );
}
//- ____________________ 
// Функция выводит на экран краткую справку о программе
//- ____________________ 
void Hello(void) {
printf( "\nCopyright (C)Frolov G.V.,1995. E-mail:"
"frolov@glas.apc.org\n"
"\nФормат вызова: TEXTATTR "режим" "интенсивность" "
"\n "режим": любые текстовые режимы"
"\n "интенсивность": 0 - интенсивность цвета, "
"1 - мигание символа" );
} Исходный текст включаемого файла SYSP.H, который используется в примере TEXTATTR.C, а также в других примерах книги, представлен в листинге 3.2. Файл SYSP.H содержит определение макрокоманды FP_MAKE, служащей для получения дальнего указателя из сегмента и смещения. Листинг 3.2. Файл SYSP.H // Макрокоманда FP_MAKE составляет дальний указатель
// из сегмента и смещения
#define FP_MAKE(seg,off) ((void far *) \
((((unsigned long) (unsigned)(seg)) "16L) | \
((unsigned long) (unsigned) (off)))) Включаемый файл SYSGRAPH.H содержит определения нескольких типов структур, используемых в примерах нашей книги. Исходный текст файла SYSGRAPH.H представлен в листинге 3.3. Листинг 3.2. Файл SYSGRAPH.H #pragma pack(1)
// Структура для определения символа и его атрибута
typedef struct _VIDEOBUF_ {
unsigned char chr;
unsigned char attr;
} VIDEOBUF;
// Структура для доступа к переменным видеофункций BIOS
typedef struct _BIOS_VAR_ {
unsigned char bEquipFlags;
unsigned char bReserv1[0x38];
unsigned char bVideoMode;
unsigned wColumns;
unsigned wPageLength;
unsigned wVidStart;
unsigned w8CursorPos[8];
unsigned wCursorShape;
unsigned char bActivePage;
unsigned wAddrCRT;
unsigned char bRegMode;
unsigned char bRegPalette;
unsigned char bReserv2[0x1D];
unsigned char bRows;
unsigned wCharHigh;
unsigned char bInfo;
unsigned char bInfoTwo;
unsigned char bReserv3[0x1F];
void far dwSavePtr;
} BIOS_VAR;
// Структура для заполнения таблицы цветов (таблицы ЦАП)
typedef struct _RGB_ {
unsigned char red;
unsigned char green;
unsigned char blue;
} RGB;
#pragma pack() Видеопамять в графических режимах Структура видеопамяти в графических режимах работы видеоадаптеров отличается от структуры видеопамяти в текстовых режимах. Если вы желаете в дальнейшем изучить программирование видеоадаптеров на уровне регистров, то вам необходимо полное понимание структуры видеопамяти. Ниже рассмотрена структура видеопамяти отдельно для каждого графического режима. Режимы 4 и 5 Это режимы низкого разрешения - 320х200 пикселов. Используются 4 цвета. Режимы поддерживаются видеоадаптерами CGA, EGA, VGA и SVGA. У адаптеров EGA, VGA и SVGA видеоданные расположены в нулевом цветовом слое. Остальные три слоя не используются. Для совместимости с видеоадаптером CGA, отображение видеопамяти на экран не является непрерывным. Первая половина видеопамяти (начальный адрес B800:0000h) содержит данные обо всех нечетных линиях экрана, а вторая половина (начальный адрес B800:2000h) - относительно всех четных линий. Каждому пикселу изображения соответствуют два бита видеопамяти. За верхний левый пиксел экрана отвечают биты D7 и D6 нулевого байта видеопамяти. На рисунке 3.7 изображено соответствие видеопамяти пикселам экрана. \s \* MERGEFORMAT PICTURE._FIG_57.PCX;6";4.308";PCX Рисунок 3.7 Структура видеопамяти для режимов 4 и 5 Если вы желаете выводить информацию на экран монитора непосредственно через видеопамять, то вам необходимо уметь определять биты, которые управляют каждым пикселом изображения. В общем случае по координатам пиксела нужно вычислить адрес байта видеопамяти и номера битов в нем, управляющие данным пикселом. Следующие формулы позволяют определить смещение байта от начала станицы видеопамяти и номера битов в нем, управляющие пикселом с координатами (x,y): Если y четное число, то смещение байта = 50h*(y/2)+(x/4)
Если y нечетное число, то смещение байта = 2000h+50h*((y-1)/2)+(x/4)
Номер первого бита = 7-mod(x/4)*2 В режимах 4 и 5 доступны два набора цветов - стандартный и альтернативный. Для выбора набора цветов можно воспользоваться функцией 0Bh прерывания INT 10h. Ниже представлена таблица соответствия значений битов, определяющих пиксел, его цвету: Значение битов пиксела Стандартный цвет Альтернативный цвет 00 Черный Черный 01 Светло-синий Зеленый 10 Малиновый Красный 11 Ярко-белый Коричневый Режим 6 Режим 6 (640х200) является режимом наибольшего разрешения для видеоадаптера CGA. В этом режиме видеоадаптеры EGA, VGA и SVGA используют для хранения информации только нулевой слой памяти. На рисунке 3.8 представлено соответствие видеопамяти и пикселов экрана. Как и в режимах 4 и 5, первая половина видеопамяти содержит данные обо всех нечетных линиях экрана, а вторая половина - обо всех четных линиях. В режиме 6 на один пиксел отводится один бит видеопамяти. Таким образом, каждый байт видеопамяти управляет восьмью пикселами. Если значение бита видеопамяти, отвечающего за данный пиксел, равно нулю, то пиксел имеет черный цвет, если единице - белый. За верхний левый пиксел экрана отвечает бит D7 в нулевом байте видеопамяти, то есть самый старший его бит. \s \* MERGEFORMAT PICTURE._FIG_58.PCX;6";4.308";PCX Рисунок 3.8 Структура видеопамяти в режиме 6 При непосредственном доступе к видеопамяти вы можете воспользоваться следующими формулами: Если y четное число, то смещение байта = 50h*(y/2)+(x/8)
Если y нечетное число, то смещение байта = 2000h+50h*((y-1)/2)+(x/8)
Номер бита = 7-mod(x/8) Эти формулы позволяют определить для пиксела, имеющего координаты (x,y), смещение от начала станицы видеопамяти байта и номер бита в нем, управляющего данным пикселом. Режимы 0Dh и 0Eh Разрешающая способность в режиме 0Dh составляет 320 пикселов по горизонтали и 200 пикселов по вертикали, а в режиме 0Eh соответственно 640 и 200 пикселов. Режимы 0Dh и 0Eh поддерживают только видеоадаптеры EGA и VGA. На рисунке 3.9 представлена структура видеопамяти для этого режима. Для хранения видеоданных используются все четыре цветовых слоя. Каждому адресу видеопамяти соответствует четыре байта, которые вместе определяют восемь пикселов. Каждому пикселу соответствует четыре бита - по одному биту из каждого цветового слоя. Четыре бита на пиксел, используемые в данных режимах, позволяют одновременно отображать пикселы 16 различных цветов. \s \* MERGEFORMAT PICTURE._FIG_10.PCX;6";4.308";PCX Рисунок 3.9 Структура видеопамяти в режимах 0Dh и 0Eh Следующие формулы позволяют определить смещение байта от начала станицы видеопамяти и номер бита в нем, управляющего пикселом с координатами (x,y): Смещение байта = 50h*y+x/8
Номер бита = 7-mod(x/8) Запись в каждый из четырех слоев видеопамяти можно разрешить или запретить при помощи регистра разрешения записи цветового слоя. Смотри раздел "Регистры видеоадаптеров EGA, VGA и SVGA". Режим 0Fh Графический монохромный режим с разрешением 640х350 пикселов. Данный режим поддерживают только видеоадаптеры EGA, VGA и SVGA. Для хранения видеоданных используются два цветовых слоя - нулевой и первый. Каждому пикселу соответствует по одному биту из нулевого и первого цветовых слоев. Два бита на пиксел позволяют отображать его черным, белым, ярко-белым или мигающим. Запись в каждый из этих двух слоев можно разрешить или запретить при помощи регистра разрешения записи цветового слоя. На рисунке 3.10 представлена структура видеопамяти для режима 0Fh. \* MERGEFORMAT ICTURE._FIG_43.PCX;6";4.308";PCX Рисунок 3.10 Структура видеопамяти режима 0Fh Следующие формулы позволяют определить смещение байта от начала станицы видеопамяти и номер бита в нем, управляющего пикселом с координатами (x,y): Смещение байта = 50h*y+x/8
Номер бита = 7-mod(x/8) Режим 10h Графический цветной режим с разрешением 640х350 пикселов. Данный режим поддерживают только видеоадаптеры EGA, VGA и SVGA. Для хранения видеоданных используются четыре цветовых слоя. Каждому пикселу соответствует по одному биту из каждого цветового слоя. Четыре бита на пиксел позволяют отображать 16 различных цветов. Запись в каждый из этих четырех слоев можно разрешить или запретить при помощи регистра разрешения записи цветового слоя. На рисунке 3.11 представлена структура видеопамяти для режима 10h. \s \* MERGEFORMAT PICTURE._FIG_10.PCX;6";4.308";PCX Рисунок 3.11 Структура видеопамяти режима 10h Если вы желаете выводить информацию на экран монитора непосредственно через видеопамять, необходимо уметь определять биты, которые управляют каждым пикселом изображения. Следующие формулы позволяют определить смещение байта от начала станицы видеопамяти и номер бита в нем, управляющего пикселом с координатами (x,y): Смещение байта = 50h*y+x/8
Номер бита = 7-mod(x/8) Режим 11h Графический цветной режим с разрешением 640х480 пикселов. Данный режим поддерживают только видеоадаптеры VGA и SVGA. Для хранения видеоданных используется нулевой цветовой слой, остальные три слоя не используются. Каждому пикселу соответствует один бит, что позволяет отображать всего два цвета. На рисунке 3.12 представлена структура видеопамяти для режима 11h. \* MERGEFORMAT PICTURE._FIG_11.PCX;6";4.308";PCX Рисунок 3.12 Структура видеопамяти режима 11h При непосредственном доступе к видеопамяти вы можете воспользоваться следующими формулами: Смещение байта = 50h*y+x/8
Номер бита = 7-mod(x/8) Формулы позволяют определить для пиксела, имеющего координаты (x,y), смещение от начала станицы видеопамяти байта и номер бита в нем, управляющего данным пикселом. Режим 12h Режим 12h похож на режим 10h, за исключением того, что он имеет большую разрешающую способность - 640х480 пикселов. В видеопамяти задействованы все четыре цветовых слоя. Структура видеопамяти показана на рисунке 3.13. \* MERGEFORMAT PICTURE._FIG_10.PCX;6";4.308";PCX Рисунок 3.13 Структура видеопамяти режима 12h Формулы, используемые для вычисления битов, управляющих данным пикселом экрана, соответствуют формулам режима 10h. Режим 13h Этот режим, как и режим 12h, поддерживается только видеоадаптерами VGA и SVGA. Он обеспечивает отображение 256 различных цветов при разрешающей способности 320х200 пикселов. Структура видеопамяти приведена на рисунке 3.14. Как видно из рисунка, в этом режиме видеопамять организована линейно. Каждый пиксел определяется одним байтом. \s \* MERGEFORMAT PICTURE._FIG_12.PCX;6";4.308";PCX Рисунок 3.14 Структура видеопамяти в режиме 13h Следующая формула позволяет определить смещение от начала видеопамяти байта, управляющего пикселом с координатами (x,y): Смещение байта = 140h*y+x Графический контроллер Графический контроллер осуществляет обмен данными между видеопамятью и процессором. Графический контроллер может выполнять над данными, поступающими в видеопамять, простейшие логические операции: И, ИЛИ, ИСКЛЮЧАЮЩЕЕ ИЛИ, операцию циклического сдвига. Операция записи При чтении процессором данных из видеопамяти они также запоминаются в регистрах-защелках, расположенных на плате видеоадаптера. Если затем выполняется цикл записи, то над данными, находящимися в этих регистрах, и над данными, поступающими от процессора могут выполняться следующие логические операции: SYMBOL 119 \f "Wingdings" \s 10 \h Запись данных процессора в видеопамять без изменения SYMBOL 119 \f "Wingdings" \s 10 \h Циклический сдвиг данных, записываемых процессором в видеопамять SYMBOL 119 \f "Wingdings" \s 10 \h Выполнение булевой операции И между данными, записываемыми в видеопамять и содержимым регистров-защелок. В видеопамять записывается результат операции SYMBOL 119 \f "Wingdings" \s 10 \h Выполнение булевой операции ИЛИ между данными, записываемыми в видеопамять и содержимым регистров-защелок. В видеопамять записывается результат операции SYMBOL 119 \f "Wingdings" \s 10 \h Выполнение булевой операции ИСКЛЮЧАЮЩЕЕ ИЛИ между данными, записываемыми в видеопамять и содержимым регистров-защелок. В видеопамять записывается результат операции Таким образом, видеоадаптер может выполнять часть работы по обработке видеоданных. Рисунок 3.15 иллюстрирует выполнение графическим контроллером операции записи данных в видеопамять: \* MERGEFORMAT PICTURE._FIG_40.PCX;6";4.308";PCX Рисунок 3.15 Запись данных в видеопамять Байт, записываемый процессором в видеопамять (на нашем рисунке 11100001b), поступает в графический контроллер. В соответствии со значением регистра циклического сдвига и выбора функции (регистры адаптеров описаны в следующем разделе), происходит циклический сдвиг на один бит содержимого байта, записываемого в видеопамять. Полученный результат складывается по логике ИЛИ с содержимым регистров-защелок. Какая булева функция используется - ИЛИ, И, ИСКЛЮЧАЮЩЕЕ ИЛИ также определяется регистром циклического сдвига и выбора функции. Дальнейшие преобразования происходят в соответствии со значениями регистра разрешения установки/сброса и регистра установки/сброса: SYMBOL 119 \f "Wingdings" \s 10 \h Если бит регистра разрешения установки/сброса, управляющий данным цветовым слоем, равен нулю, тогда байт, записываемый в видеопамять не изменяется SYMBOL 119 \f "Wingdings" \s 10 \h Если бит регистра разрешения установки/сброса, управляющий данным цветовым слоем равен единице, то в видеопамять записывается байт, все биты которого устанавливаются в соответствии со значением регистра установки/сброса для данного цветового слоя Затем в соответствии с состоянием регистра битовой маски происходит запись данных в видеопамять: SYMBOL 119 \f "Wingdings" \s 10 \h Если данный бит регистра битовой маски содержит единицу, то соответствующие биты для каждого из цветовых слоев поступают от центрального процессора SYMBOL 119 \f "Wingdings" \s 10 \h Если данный бит регистра битовой маски содержит ноль, то соответствующие биты для каждого из цветовых слоев поступают из регистров-защелок Центральный процессор может одновременно прочитать данные только из одного цветового слоя, однако запись данных в регистры-защелки происходит из всех четырех цветовых слоев. Эту особенность можно использовать для быстрого копирования областей экрана. Операция чтения Во время цикла чтения данных из видеопамяти, графический контроллер может выполнять операцию сравнения цветов (Color Compare). Эта операция позволяет найти на экране пикселы определенного цвета. В отличие от обычной операции чтения, когда за один раз читается только один цветовой слой, при выполнении операции сравнения цветов графический контроллер имеет доступ ко всем четырем цветовым слоям одновременно. Графический контроллер сравнивает данные из всех четырех цветовых слоев (или из любого подмножества цветовых слоев) с данными в регистре сравнения цветов контроллера, и в случае совпадения вырабатывает определенный сигнал. Последовательный преобразователь Последовательный преобразователь запоминает данные, читаемые из видеопамяти в течение цикла регенерации, преобразует их в последовательный поток бит и передает контроллеру атрибутов. Контроллер атрибутов Контроллер атрибутов в графических и текстовых режимах работы видеоадаптера управляет цветом элементов изображения. Значениям цветовых атрибутов ставится в соответствие определенный цвет. Для этого используется таблица цветовой палитры (Color Lock-up Table). Таблица цветовой палитры ставит в соответствие четырем битам, взятым из видеопамяти, 6 битов цветовой информации. Изменяя данные, записанные BIOS в таблицу цветовой палитры, можно менять используемую палитру цветов. Для видеоадаптера EGA эта информация поступает непосредственно на видеовход монитора. Если к видеоадаптеру EGA подключен цветной монитор, то используются только четыре младших бита из шести. Видеоадаптеры VGA и SVGA выполняют более сложные операции по преобразованию цвета. Данные полученные от таблицы цветовой палитры преобразуются дальше в соответствии с таблицей цветов. В результате получаются три 6 битовых значения, представляющих красный, зеленый и синий компоненты цвета. Эти значения поступают на три цифро-аналоговых преобразователя и уже в аналоговом виде поступают в монитор. На рисунках 3.16 и 3.17 показана работа контроллера атрибутов в графическом и текстовом режимах. \s \* MERGEFORMAT PICTURE._FIG_16.PCX;6";4.308";PCX Рисунок 3.16 Контроллер атрибутов в текстовых режимах В текстовых режимах видеоадаптеров, цвет символа и цвет фона символа определяется байтом атрибутов. Цвет фона символа задают четыре старших бита байта атрибутов. Значение этих четырех бит служит индексом в таблице цветовой палитры. Элемент таблицы с данным индексом впоследствии определяет цвет фона символа. Аналогично битам, определяющим цвет фона символа, четыре младших бита задают цвет самого символа. \s \* MERGEFORMAT PICTURE._FIG_15.PCX;6";4.308";PCX Рисунок 3.17 Контроллер атрибутов в графических режимах В отличие от текстовых режимов, в графических режимах цвет каждого пиксела определяется отдельно. На рисунке 6.18 четыре бита, считанные из цветовых слоев видеопамяти определяют один пиксел. Значение этих бит служат индексом для таблицы цветовой палитры. Контроллер атрибутов подробно описан в разделе "Регистры видеоадаптеров EGA и VGA". Контроллер ЭЛТ Контроллер ЭЛТ выполняет следующие функции: SYMBOL 119 \f "Wingdings" \s 10 \h Вырабатывает сигналы, управляющие работой ЭЛТ (сигналы развертки и гашения) SYMBOL 119 \f "Wingdings" \s 10 \h Определяет формат экрана и формат символов текста (разрешающую способность экрана и размер символов) SYMBOL 119 \f "Wingdings" \s 10 \h Определяет форму курсора SYMBOL 119 \f "Wingdings" \s 10 \h Управляет световым пером SYMBOL 119 \f "Wingdings" \s 10 \h Управляет вертикальной сверткой (скроллингом) содержимого экрана Так как контроллер ЭЛТ выполняет жизненно важные для монитора функции, то изменять содержимое регистров этого контроллера очень опасно. В некоторых случаях может даже произойти физическое повреждение экрана (например, повреждение люминофора). Регистры контроллера ЭЛТ загружаются BIOS значениями, зависящими от типа монитора, видеоадаптера и текущего режима работы. Мы не рекомендуем вам без особой необходимости изменять содержимое этих регистров. Практически все что необходимо, можно сделать при помощи функций BIOS, не подвергая дорогостоящий видеоадаптер и монитор излишнему риску. Синхронизатор Синхронизатор управляет всеми временными параметрами видеоадаптера. С точки зрения программирования, наиболее полезной является функция синхронизатора, управляющая разрешением и запрещением доступа к отдельным цветовым слоям видеопамяти. Рисунок 3.18 иллюстрирует использование функции разрешения записи цветовых слоев. \* MERGEFORMAT PICTURE._FIG_17.PCX;6";4.308";PCX Рисунок 3.18 Разрешение записи в цветовые слои Процессор передает видеоадаптеру данные для записи в видеопамять. Они проходят через графический контроллер и попадают в синхронизатор. Графический контроллер выполняет над данными, записываемыми в видеопамять, операции, определяемые состоянием его регистров (смотри главу "Исполнение видеоадаптером операции записи" из раздела "Графический контроллер"). В зависимости от значения регистра разрешения записи цветового слоя синхронизатор может оставить данные в цветовом слое без изменения. Регистр разрешения записи цветового слоя содержит четыре бита, управляющие записью в цветовые слои видеопамяти. Если бит регистра управляющий цветовым слоем равен нулю, то данный цветовой слой не изменяется. Если бит регистра равен единице, то в данный слой видеопамяти записываются значения, поступившие от графического контроллера. 4. Регистры видеоадаптеров EGA, VGA и SVGA В этой главе мы опишем все основные регистры видеоадаптеров EGA, VGA и SVGA, которые могут быть полезны при написании программ. Программирование видеоадаптеров на уровне регистров позволяет увеличить скорость работы программ и решить некоторые задачи, которые нельзя решить только при помощи функций BIOS. Непосредственное использование регистров может вызвать ряд проблем при переносе ваших программ на другие машины. Дело в том, что не все адаптеры совместимы на уровне регистров. Например, оригинальный видеоадаптер CGA создан на основе микросхемы Motorola 6845, а видеоадаптеры EGA и VGA используют более совершенный аналог этой микросхемы. Некоторые регистры CGA располагаются по другим адресам и могут выполнять какие-либо дополнительные функции, чем регистры EGA и VGA. Кроме того, в каждом новом видеоадаптере SVGA расширяется набор используемых регистров. Существуют модели видеоадаптеров EGA, VGA и SVGA, поддерживающие режим совместимости, когда они эмулируют адаптеры более низкого уровня (например MDA, Hercules, CGA). Эмуляция обычно происходит на уровне регистров, что гарантирует полную их совместимость. Режимы совместимости, если они поддерживаются, описаны в руководстве данного видеоадаптера. На практике, для управления видеоадаптерами, рекомендуется преимущественно использовать функции BIOS. Это избавит вас от неприятных минут, когда ваша работающая программа, при переносе на другую машину перестанет правильно выполняться. Краткий обзор Видеоадаптеры EGA, VGA и SVGA имеют большое количество регистров. Адаптер EGA имеет около шестидесяти регистров, а VGA и SVGA еще больше. Большая часть регистров EGA доступна только для записи, что создает определенные проблемы, особенно для мультизадачных систем. Некоторые фирмы-изготовители видеоадаптеров выпускают платы видеоадаптеров совместимые с EGA, для регистров которых разрешена также и операция чтения. В адаптерах VGA и SVGA практически все регистры доступны как для записи, так и для чтения. SYMBOL 119 \f "Wingdings" \s 10 \h В тех случаях, когда видеоадаптеры SVGA и VGA имеют отличия от EGA, мы будем на это специально указывать. Доступ к большинству регистров видеоадаптеров осуществляется в два этапа: через один порт ввода/вывода выбирается номер интересующего вас регистра, а затем через другой порт ввода/вывода осуществляется обмен данными. Такая организация регистров позволяет сэкономить большое количество портов центрального процессора. Остальные регистры адресуются непосредственно через соответствующие порты ввода/вывода - каждому регистру соответствует один порт ввода/вывода. Заметим, что в различных режимах работы видеоадаптера, его регистры могут иметь различные адреса. Приведем список адресов регистров в монохромных режимах: Адрес Регистр 3C2h Регистр определения различных режимов работы (Miscellaneous Output Register - MOR), Регистр состояния 0 (Input Status Register 0 - ISR0) 3BAh Регистр управления дополнительным устройством (Feature Control Register), Регистр состояния 1 (Input Status Register 1 - ISR1) 3BBh Регистр очистки защелки светового пера (Clear Light Pen Latch Register- CLPLR) 3BCh Установка защелки светового пера (Set Light Pen Latch Register - SLPLR) 3C4h, 3C5h Регистры синхронизатора (Sequencer Register's - SR) 3B4h, 3B5h Регистры контроллера ЭЛТ (CRT Controller Register's - CRT_CR) 3CAh, 3CCh, 3CEh, 3CFh Регистры графического контроллера (Graphics Controller Register's - GCR) 3C0h Регистр контроллера атрибутов (Attribute Controller Register - ACR) 3C3h Регистр разрешения работы системы VGA (VGA Enable Register - VGA_ER) 3C6h, 3C7h, 3C8h, 3C9h Регистры цифро-аналогового преобразователя (ЦАП) VGA (VGA Video DAC Register - VGA_DAC_R) А теперь перечислим адреса тех же регистров, но уже для цветных режимов видеоадаптера: Адрес Регистр 3C2h Регистр определения различных режимов работы (Miscellaneous Output Register - MOR), Регистр состояния 0 (Input Status Register 0 - ISR0) 3DAh Регистр управления дополнительным устройством Feature Control Register), Регистр состояния 1 (Input Status Register 1 - ISR1) 3DBh Регистр очистки защелки светового пера (Clear Light Pen Latch Register- CLPLR) 3DCh Установка защелки светового пера (Set Light Pen Latch Register - SLPLR) 3C4h, 3C5h Регистры синхронизатора (Sequencer Register's - SR) 3D4h, 3D5h Регистры контроллера ЭЛТ (CRT Controller Register's - CRT_CR) 3CAh, 3CCh, 3CEh, 3CFh Регистры графического контроллера (Graphics Controller Register's - GCR) 3C0h Регистр контроллера атрибутов (Attribute Controller Register - ACR) 3C3h Регистр разрешения работы системы VGA (VGA Enable Register - VGA_ER) 3C6h, 3C7h, 3C8h, 3C9h Регистры ЦАП VGA (VGA Video DAC Register - VGA_DAC_R) В зависимости от режима работы видеопамять адаптера занимает различное адресное пространство: Номер режима работы Адрес памяти 0,1,2,3,4,5,6 B000:8000h-B000:FFFFh 7 B000:0000h-B000:7FFFh 0Dh,0Eh,0Fh,10h,11h,12h,13h A000:0000h-A000:FFFFh Ниже мы привели исходный текст функции Get_Seg_Vmem. Данная функция определяет текущий режим работы видеоадаптера и возвращает сегментный адрес начала видеопамяти. Если видеоадаптер работает в нестандартном режиме, функция возвращает нулевое значение. Чтобы узнать номер текущего режима видеоадаптера, используется функция 0Fh прерывания INT 10h. Пример вызова данной функции представлен в листинге 4.1. Листинг 4.1. Файл SEGVMEM.C // Файл SYSP.H представлен в листинге 3.2
#include "sysp.h"
unsigned GetSegVmem(void) {
unsigned char mode;
unsigned seg_address;
// Определяем текущий режим видеоадаптера
_asm {
mov ah,0Fh
int 10h
mov mode,al
}
// Если видеоадаптер находится в режимах 0, 1, 2, 3,
// 4, 5, 6 то видеопамять начинается с сегмента B800h
if((mode" = 0) (mode "= 6))
seg_address = 0xB800;
// Если видеоадаптер находится в режиме 7,
// то видеопамять начинается с сегмента B000h
else if(mode - 7)
seg_address = 0xB000;
// Если видеоадаптер находится в режимах 0Dh - 13h,
// то видеопамять начинается с сегмента A000h
else if((mode" = 0x0D) (mode "= 0x13))
seg_address = 0xA000;
// Если видеоадаптер не находится в стандартном режиме
// возвращаем ноль
else seg_address = 0x0;
return(seg_address);
} Ниже подробно рассмотрены регистры видеоадаптеров EGA и VGA. Мы выделили следующие группы регистров: SYMBOL 119 \f "Wingdings" \s 10 \h Внешние регистры SYMBOL 119 \f "Wingdings" \s 10 \h Регистры контроллера ЭЛТ SYMBOL 119 \f "Wingdings" \s 10 \h Регистры графического контроллера SYMBOL 119 \f "Wingdings" \s 10 \h Регистры контроллера атрибутов SYMBOL 119 \f "Wingdings" \s 10 \h Регистры синхронизатора SYMBOL 119 \f "Wingdings" \s 10 \h Регистры цифро-аналогового преобразователя VGA Внешние регистры Видеоадаптер EGA содержит большинство регистров внутри одной центральной микросхемы. В ней расположены контроллер атрибутов, контроллер ЭЛТ, графический контроллер и преобразователь последовательности. Только несколько регистров размешены в отдельной микросхеме. Они стали называться внешними. При разработке видеоадаптеров VGA и SVGA внешние регистры были объединены с остальными регистрами в одной микросхеме, но название внешние сохранилось. Каждому внешнему регистру соответствует порт ввода/вывода. Регистр определения различных режимов работы
(Miscellaneous Output Register - MOR) У видеоадаптера EGA данный регистр доступен только для записи. Вы можете записать в него новое значение через порт ввода/вывода с адресом 3C2h. Видеоадаптер VGA позволяет прочитать содержимое регистра MOR, но уже по адресу 3CCh. Ниже представлено описание отдельных битов регистра MOR: Биты Описание D0 Выбор адресов портов ввода/вывода D1 Разрешение доступа к видеопамяти D2, D3 Выбор частоты D4 Запрещение управления видеоадаптером D5 Бит четной/нечетной страницы D6 Полярность сигнала горизонтальной синхронизации D7 Полярность сигнала вертикальной синхронизации D7 Полярность сигнала вертикальной синхронизации. Нулевая величина для данного бита устанавливает положительную полярность сигнала, единичная - отрицательную. Монохромный, цветной и улучшенный цветной мониторы используют положительную полярность сигнала синхронизации. D6 Полярность сигнала горизонтальной синхронизации. Нулевая величина для данного бита устанавливает положительную полярность, единичная - отрицательную. Монохромный монитор использует отрицательную полярность сигнала синхронизации, а цветной - положительную. Улучшенный цветной монитор и аналоговый монитор используют биты D7 и D6 для определения частоты развертки. Следующая таблица содержит допустимые значения для этих битов: D7 D6 EGA VGA 00 200 линий Не используется 01 350 линий 350 линий 10 Не используется 400 линий 11 Не используется 480 линий D5 Бит четной/нечетной страницы используется для режимов, которые передают данные по четным адресам в нулевой цветовой слой, а по нечетным - в первый. Все текстовые режимы устанавливают этот бит. Бит D5 выбирает одну из двух страниц видеопамяти. D4 Управление видеоадаптером. Бит доступен только для видеоадаптера EGA. Видеоадаптеры VGA и SVGA этот бит не используют. Обычно бит D4 имеет значение 0. В этом случае управление монитором осуществляет видеоадаптер. Если бит D4 принимает значение 1, то монитор управляется сигналами, поступающими от разъема дополнительного устройства. D2, D3 Биты выбора частоты управляют тактовой частотой видеоадаптера. Таблица, расположенная ниже, представляет правильные варианты установки битов D3 и D2: D3 D2 Режим 0 0 640 пикселов в строке 0 1 720 пикселов в строке 1 0 Используется внешний генератор. Внешний генератор подключается через разъем дополнительного устройства) 1 1 Зарезервировано D1 Доступ к видеопамяти. Данный бит может запретить доступ процессора к видеопамяти. Если бит равен нулю, то доступ центрального процессора к видеопамяти запрещен. D0 Выбор адресов портов ввода/вывода. Бит D0 определяет адрес регистра управления дополнительным устройством (Feature Control Register), регистра состояния 1 (Input Status Register 1) и регистров контроллера ЭЛТ (CRT Controller). Когда бит D0 равен нулю, происходит выбор адресного пространства монохромного режима (адреса 3Bхh). Если бит равен единице, то используется адресное пространство цветного режима работы видеоадаптера (адреса 3Dхh). Данные, первоначально записываемые BIOS в этот регистр зависят от режима работы видеоадаптера: Режим 0-6,0Dh,0Eh 7 Fh 10h Содержимое регистра 23h 0A6h 0A2h 0A7h Регистр управления дополнительным устройством
(Feature Control Register - FCR) Для видеоадаптера EGA биты D1 и D0 данного регистра передают сигналы на разъем дополнительного устройства. Бит D0 соответствует линии FC0 (вывод 21 разъема дополнительного устройства), а бит D1 линии FC1 (вывод 20 разъема дополнительного устройства). Регистр не используется для видеоадаптеров VGA и SVGA, однако бит D3 в этом случае должен содержать ноль. Адрес порта ввода/вывода регистра FCR зависит от режима работы видеоадаптера. В монохромных режимах адрес порта 3BAh, а в цветных - 3DAh. У видеоадаптера EGA регистр FCR доступен только для записи. Видеоадаптеры VGA и SVGA позволяют прочитать его содержимое через порт 3CAh. Регистр состояния 0
(Input Status Register 0 - ISR0) Регистр ISR0 доступен через порт 3C2h только для чтения. Формат регистра приведен ниже: Биты Описание D3-D0 Не используются D4 Состояние переключателей D5 Бит 0 дополнительного устройства (FEAT0) D6 Бит 1 дополнительного устройства (FEAT1) D7 Бит прерывания от ЭЛТ D7 Бит установлен в 1, во время обратного вертикального хода луча (погашенный луч перемещается из правого нижнего угла экрана в левый верхний). Бит D7 устанавливается в начале обратного вертикального хода луча и сбрасывается при записи в регистр конца вертикального хода луча. D6 Бит 1 дополнительного устройства. Используется только видеоадаптерами EGA. Бит D6 регистра управляет уровнем сигнала FEAT0 (вывод 17 разъема дополнительного устройства). D5 Бит 0 дополнительного устройства. Используется только видеоадаптерами EGA. Бит регистра управляет уровнем сигнала FEAT1 (вывод 19 разъема дополнительного устройства). D4 Состояние переключателей. Проанализировав бит D4, функции BIOS EGA могут определить состояние четырех переключателей, находящихся на плате видеоадаптера. Номер считываемого переключателя задается двумя битами выбора частоты (D2 и D3) регистра определения различных режимов работы (MOR), согласно следующей таблице: Бит D3 Бит D2 Номер переключателя 0 0 1 0 1 2 1 0 3 1 1 4 Если бит D4 установлен в единицу, то переключатель, заданный битами D2 и D3 регистра определения различных режимов работы, находится в положении ON. Если бит сброшен в ноль, то переключатель находится в положении OFF. К компьютеру могут быть подключены две различные видеосистемы - два видеоадаптера и два монитора. На плате адаптеров EGA расположены четыре переключателя. Их положение определяет, какие видеоадаптеры и мониторы могут быть подключены одновременно. Если к компьютеру подключены два видеоадаптера, то один из них является первичным, а другой дополнительным. Первичный видеоадаптер используется по умолчанию сразу после включения компьютера. Ниже представлены правильные варианты установки переключателей для различных конфигураций видеосистемы компьютера. 4 3 2 1 ON SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Первичный: EGA с цветным монитором (40х25) OFF SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Дополнительный: MDA 4 3 2 1 ON SYMBOL 110 \f "Wingdings" Первичный: EGA с цветным монитором (80х25) OFF SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Дополнительный: MDA 4 3 2 1 ON SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Первичный: EGA с улучшенным цветным монитором OFF SYMBOL 110 \f "Wingdings" Дополнительный: MDA 4 3 2 1 ON SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Первичный: EGA с улучшенным цветным монитором OFF SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Дополнительный: MDA 4 3 2 1 ON SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Первичный: EGA с монохромным монитором OFF SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Дополнительный: CGA с цветным монитором (40х25) 4 3 2 1 ON SYMBOL 110 \f "Wingdings" Первичный: EGA с монохромным монитором OFF SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Дополнительный: CGA с цветным монитором (80х25) 4 3 2 1 ON SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Первичный: MDA OFF Дополнительный: EGA с цветным монитором (40х25) 4 3 2 1 ON SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Первичный: MDA OFF SYMBOL 110 \f "Wingdings" Дополнительный: EGA с цветным монитором (80х25) 4 3 2 1 ON SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Первичный: MDA OFF SYMBOL 110 \f "Wingdings" Дополнительный: EGA с цветным монитором (80х25) 4 3 2 1 ON SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Первичный: MDA OFF SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Дополнительный: EGA с цветным монитором 4 3 2 1 ON SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Первичный: CGA с цветным монитором 40х25 OFF SYMBOL 110 \f "Wingdings" Дополнительный: EGA с монохромным монитором 4 3 2 1 ON SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Первичный: CGA с цветным монитором 80х25 OFF SYMBOL 110 \f "Wingdings" SYMBOL 110 \f "Wingdings" Дополнительный: EGA с монохромным монитором Видеоадаптеры VGA и SVGA используют бит D4 для определения типа монитора (цветной или монохромный). Положение этих переключателей может быть считано из оперативной памяти по адресу 0000:0488h: Биты Описание D3-D0 Биты, соответствующие переключателям. Если бит установлен в единицу, то соответствующий переключатель находится в положении ON. Если бит сброшен в ноль, то переключатель находится в положении OFF D7-D4 Не используются Регистр состояния 1
(Input Status Register 1 - ISR0) Регистр позволяет получить различную информацию о состоянии видеоадаптера. Для видеоадаптера CGA содержимое регистра можно считать через порт, имеющий адрес 3DAh. Для адаптеров EGA, VGA и SVGA данный регистр, имеет адрес 3BAh в монохромных режимах и адрес 3DAh - в цветных. Регистр состояния 1 доступен только для чтения. Приведем формат регистра состояния 1: Биты Описание D0 Бит разрешения отображения D1 Бит триггера светового пера D2 Бит переключателя светового пера D3 Бит обратного вертикального хода D5-D4 Диагностические биты D7-D6 Биты не используются D7, D6 Биты не используются D5, D4 Диагностические биты позволяют проверить два из шести цветовых выходных сигналов передаваемых монитору (для видеоадаптера EGA). Для выбора проверяемых сигналов используют регистр разрешения цветового слоя контроллера атрибутов: Регистр разрешения цветового слоя Регистр состояния 1 D5 D4 D5 D4 0 0 Красный Синий 0 1 Второй красный Второй зеленый 1 0 Второй синий Зеленый 1 1 Не используется Не используется Следующая таблица показывает, как можно считать два из восьми цветовых сигналов, вырабатываемых контроллером атрибутов видеоадаптера VGA: Регистр разрешения цветового слоя Регистр состояния 1 D5 D4 D5 D4 0 0 P2 P0 0 1 P5 P4 1 0 P3 P1 1 1 P7 P6 Биты D5 и D4 позволяют прочитать содержимое регистров таблицы цветовой палитры видеоадаптера EGA. Следует отметить, что некоторые адаптеры, совместимые с EGA, не поддерживают эти биты. Поэтому их использование может наложить ограничения на работу программы. D3 Бит обратного вертикального хода луча. Бит принимает значение 1 в течение обратного вертикального хода луча по кадру. Данный бит также установлен в случае, если разрешено прерывание IRQ2, и любое устройство компьютера выдает запрос на это прерывание. Биты D2 и D1 управляют световым пером. Видеоадаптеры VGA и SVGA не поддерживают световое перо, поэтому биты D2 и D1 не используются. D2 Бит переключателя светового пера. Если переключатель светового пера находится в положении ON (включено), то бит D2 равен единице. Если переключатель находится в положении OFF (выключено), то бит D2 равен нулю. D1 Бит триггера светового пера. Бит равен единице, если триггер светового пера установлен. Сброс бита происходит при записи нуля через порт с адресом 3BBh для монохромного режима, или через порт 3DBh - для цветного режима. D0 Бит разрешения отображения. Бит принимает значение единицы во время интервала активности монитора (когда адаптер читает данные из видеопамяти), и равен нулю во время горизонтального и вертикального обратного хода луча. Во многих случаях возникает необходимость синхронизовать программирование регистров видеоадаптера с периодом вертикального или горизонтального обратного хода луча. Этого можно достичь периодической проверкой регистра состояния 1. Листинг 4.2 содержит программу, использующую функцию WaitVert для определения частоты кадров. Функция WaitVert задерживает выполнение программы до начала обратного вертикального хода луча. Листинг 4.2. Файл RASTR.C // Программа определения частоты кадров
#include "time.h"
#include "stdio.h"
#include "bios.h"
#define NUM 200
// Описания функций. Смотри файл DISPLAY.ASM
void __pascal __far WaitVert(void);
unsigned __pascal __far HorByVer(void);
//- ____________________ =
// Главная функция
//- ____________________ =
void main() {
time_t t_start, t_end;
int i;
float fr;
unsigned vert_fr;
// Определяем начальное время
t_start = clock();
// Ожидаем исполнения NUM вертикальных разверток
for(i = 0; i "NUM; i++) WaitVert();
// Определяем конечное время
t_end = clock();
// Вычисляем частоту кадров
fr = NUM/(((float)t_end - t_start) / CLK_TCK);
printf( "\nЧастота кадров = %4.1f \n", (float)fr );
} Исходный текст функции WaitVert представлен в листинге 4.3. Функция WaitVert периодически проверяет регистр состояния 1 (ISR1), ожидая начало обратного вертикального хода луча по экрану монитора. Листинг 4.3. Файл DISPLAY.ASM TITLE DISPLAY.ASM
 
 

 NAME DISPLAY 


  PAGE 55,132  



  P286  



  IDEAL  



  NOWARN BRK  



  SEGMENT WAIT_TEXT WORD PUBLIC 'CODE'  


ASSUME cs:WAIT_TEXT
;- ____________________ =
; Функция void WaitVert(void)
;- ____________________ =


  PUBLIC WAITVERT  



  PROC WAITVERT FAR  


enter 0, 0
mov ax,0h
mov es,ax
; Определяем адрес порта индексного регистра контроллера
; ЭЛТ (3B4h/3D4h)
mov dx,es:[463h]
; Вычисляем адрес порта регистра состояния 1 (ISR1)
add dl,6
; Читаем содержимое порта регистра состояния 1
in al,dx
; Тестируем бит D3 регистра состояния 1
; бит D3 = 1 при обратном вертикальном ходе луча
test al,8
jz wait_on
wait_off:
in al,dx
; Тестируем бит D3
test al,8
; Ожидаем конец обратного вертикального хода луча
jnz wait_off
wait_on:
in al,dx
test al,8
; Ожидаем начало обратного вертикального хода луча
jz wait_on
; +- ____________________ +
; Здесь могут распологаться операции, которые необходимо
; выполнить во время обратного вертикального хода луча
; +- ____________________ +
leave
ret


  ENDP WAITVERT  



  ENDS WAIT_TEXT  


END Регистр разрешения работы системы VGA
(VGA Enable Register - VGA_ER) Данный регистр имеет адрес 3С3h. Регистр используется только видеоадаптерами VGA и SVGA. Биты D1-D7 зарезервированы, а бит D0 управляет работой адаптера. Если бит D0 равен нулю, тогда запрещен доступ к видеопамяти и портам ввода/вывода видеоадаптера (кроме регистра VGA_ER). Регистр сброса триггера-защелки светового пера (Light Pen Latch Reset Register - LPLRR) В цветных режимах регистр LPLRR доступен через порт 3DBh, а в монохромных режимах через порт 3BBh. Регистр используется только видеоадаптерами CGA и EGA. Любая операция записи в регистр LPLRR сбрасывает триггер-защелку светового пера. Регистр установки триггера-защелки светового пера (Light Pen Latch Set Register - LPLSR) В цветных режимах регистр LPLSR доступен через порт 3DCh, а в монохромных режимах через порт 3BCh. Регистр используется только видеоадаптерами CGA и EGA. Любая операция записи в этот регистр вызывает установку триггера-защелки светового пера. Регистры контроллера ЭЛТ Регистры контроллера ЭЛТ управляют сигналами синхронизации, необходимыми для формирования растра, определяют формат данных на экране и форму курсора. Для видеоадаптеров CGA и EGA регистры контроллера ЭЛТ также управляют световым пером. Большинство из регистров ЭЛТ не представляют интереса. Более того, их неправильное использование может послужить причиной физического разрушения монитора. Поэтому мы подробно рассмотрим лишь наиболее полезные и безопасные регистры контроллера. Назначение и формат ряда регистров контроллера ЭЛТ различаются для видеоадаптеров EGA, VGA, SVGA и для видеоадаптеров MDA, Hercules, CGA. При программировании регистров контроллера ЭЛТ используется понятие одного знакоместа (characters) и времени необходимого для отображения одного символа (character clock). При вычислении значений регистров следует учесть, что ширина одного символа составляет 8 пикселов. Растр состоит из совокупности строк развертки, следующих одна за другой. Электронный луч включается в начале каждой строки и выключается в конце. Включение и выключение электронного луча выполняется сигналом разрешения отображения (Display Enable), вырабатываемым контроллером ЭЛТ. Когда электронный луч включен (разрешено отображение) видеоадаптер читает данные из видеопамяти и соответствующим образом модулирует интенсивность и цвет электронного луча. После того как луч прочертит весь экран монитора справа налево, он перемещается в начало следующей строки. Контроллер ЭЛТ снова включает электронный луч, в ответ на сигнал разрешения отображения и выводит на экран следующую строку видеоинформации. Промежуток времени между окончанием отображения видеоинформации на одной строке и началом отображения следующей строки называется горизонтальным неотображаемым интервалом. Промежуток времени отводимый для обратного хода луча меньше горизонтального неотображаемого интервала. Поэтому на правой и левой границе экрана образуются неотображаемые области. Контроллер ЭЛТ позволяет оставить электронный луч включенным во время перемещения по не отражаемой области. При этом вокруг изображения образуется цветная рамка. Размер и цвет рамки вы можете задавать сами. После того как электронный луч прочертит все горизонтальные линии растра, контроллер ЭЛТ отключает сигнал разрешения отображения (электронный луч гаснет) и вырабатывает сигнал вертикального обратного хода луча. Электронный луч перемещается с нижней части экрана в верхний левый угол. Продолжительность вертикального обратного хода луча меньше, чем период вертикального неотображаемого интервала. В результате в нижней и верхней части экрана возникают неотображаемые области. Одной из основополагающих величин, определяющих разрешающую способность режимов видеоадаптера, является частота вывода пикселов на экран монитора. Эта частота определяется генератором синхросигналов видеоадаптера. Чем выше частота вывода, тем больше пикселов может уместиться на экране при известной частоте кадров и частоте строчной развертки. Генераторы синхросигналов видеоадаптеров MDA, CGA и Hercules работают только на одной частоте. Для видеоадаптеров EGA, VGA и SVGA доступно несколько различных частот. Старые модели мониторов могут работать только с фиксированными значениями частоты горизонтальной и вертикальной развертки. Практически все современные мониторы могут работать в некотором диапазоне частот. Поэтому они называются мультичастотными. Видеоадаптер Режим Частота вывода пикселов, Мгц Частота горизонтальной развертки, Кгц Частота вертикальной развертки, Гц MDA 720х350 16257 18430 50 CGA 640х200 14318 15750 60 EGA 640х200 14318 15750 60 640х350 16257 21850 60 720х350 16257 18430 50 VGA 640х400 25175 31500 70 720х400 28322 31500 70 640х480 25175 31500 60 640х350 25175 31500 70 SVGA 640х480 31500 37861 72,809 800х600 40000 37879 60,317 800х600 50000 48077 72,187 1024х768 65000 48363 60,000 1024х768 75000 56476 70,069 Чтобы вычислить, сколько пикселов помещается на каждой строке развертки разделите частоту вывода точек на частоту горизонтальной развертки. Затем разделите полученное значение на 8 и вы узнаете, сколько символов помещается в строке развертки. Если вы самостоятельно программируете регистры ЭЛТ видеоадаптеров VGA или SVGA вы должны отнять от полученной величины число 5 (для адаптера EGA следует отнять 2) и записать результат в регистр общей длинны линии горизонтальной развертки (Horizontal Total Register - HTR). Во время выполнения горизонтальной развертки отображаются только пикселы в рабочей области экрана. Например, для режима VGA 640х480 пикселов, на одной линии горизонтальной развертки отображается только 640 пикселов. Разделите количество пикселов отображаемых в одной строке на 8 и вы узнаете, сколько символов выводится в каждой строке. Полученное значение записывается при выборе режима работы адаптера в регистр длины отображаемой части горизонтальной развертки (Horizontal Display Enable End Register - HDER). Вы видите, что общая длина горизонтальной развертки больше длины отображаемой части горизонтальной развертки. Разница между этими двумя значениями определяет, сколько времени отводится на обратный ход луча и на нерабочую область развертки. Регистры начала импульса гашения луча горизонтальной развертки (Start Horizontal Blank Register - SHBR) и конца импульса гашения луча горизонтальной развертки (End Horizontal Blank Register - EHBR) определяют размер нерабочей области горизонтальной развертки. Регистры начала горизонтального обратного хода луча (Start Horizontal Retrace Register - SHRR) и конца импульса горизонтального обратного хода луча (End Horizontal Retrace Register - EHRR) определяют момент начала и окончания горизонтального обратного хода луча. При вычислении значений регистров SHRR и EHRR следует учитывать, что для большинства мониторов, совместимых с видеоадаптерами VGA требуется отвести на горизонтальный обратный ход луча 2-4 микросекунды. Значения регистров SHRR и EHRR, как и других регистров контроллера ЭЛТ, необходимо записать в символах. Вычислим промежуток времени, в течение которого отображается один символ. Для этого следует разделить 1 на частоту вывода точек и умножить полученное число на 8 (горизонтальный размер символа в пикселах). Если частота вывода точек составляет 25,175 Мгц, тогда на отображение одного символа затрачивается 8/25175 = 0,318 микросекунд. Отсюда вычисляем, что для горизонтального обратного хода луча достаточно времени затрачиваемого на отображение 7 (2/0,318) символов. Выберите значение для регистра начала горизонтального обратного хода луча (SHRR) таким образом, чтобы растр был отцентрован на экране. Участки нерабочей области до и после горизонтального обратного хода луча должны иметь одинаковый размер. Всего в строке развертки 100 символов. Из них 80 символов отводится для видимой области строки растра и 12 символов для горизонтального обратного хода луча. Остаток - 8 символов (100-80-12) относится к нерабочей области строки развертки. Значит горизонтальный обратный ход луча должен начинаться по прошествии времени, необходимого для отображения 80+8/2=84 символов. Регистры контроллера ЭЛТ составляют самую многочисленную группу регистров видеоадаптеров. Для видеоадаптеров EGA и VGA группа содержит 24 регистра. В следующей таблице приведен список всех регистров контроллера ЭЛТ и их индексы, используемые для доступа к ним. Индекс Регистр контроллера ЭЛТ 0 Общая длина линии горизонтальной развертки (Horizontal Total Register - HTR) 1 Длина отображаемой части горизонтальной развертки (Horizontal Display Enable End Register - HDER) 2 Начало импульса гашения луча горизонтальной развертки (Start Horizontal Blank Register - SHBR) 3 Конец импульса гашения луча горизонтальной развертки (End Horizontal Blank Register - EHBR) 4 Начало импульса горизонтального обратного хода луча (Start Horizontal Retrace Register - SHRR) 5 Конец импульса горизонтального обратного хода луча (End Horizontal Retrace Register - EHRR) 6 Количество горизонтальных линий растра (Vertical Total Register - VTR) 7 Дополнительный регистр (Overflow Register - OVR) 8 Предварительная установка горизонтальной развертки (Preset Row Scan Register - PRSR) 9 Высота символов текста (Max Scan Line Register - MSLR) 0Ah Начальная линия курсора (Cursor Start Register - CSR) 0Bh Конечная линия курсора (Cursor End Register - CER) 0Ch Старший байт начального адреса (Start Address Register - SAR, high byte) 0Dh Младший байт начального адреса (Start address Register - SAR, low byte) 0Eh Старший байт позиции курсора (Cursor Location Register - CLR, high byte) 0Fh Младший байт позиции курсора (Cursor Location Register - CLR, low byte) 10h Начало обратного вертикального хода луча (Vertical Retrace Start Register - VRSR) 11h Конец обратного вертикального хода луча (Vertical Retrace End Register - VRER) 10h Старший байт адреса светового пера (Light Pen Address Register - LPAR, high byte) 11h Младший байт адреса светового пера (Light Pen Address Register - LPAR, low byte) 12h Начало гашения вертикальной развертки (Vertical Display End Register - VDER) 13h Логическая ширина экрана (Offset Register - OFR) 14h Положение подчеркивания символа (Underline Location Register - ULR) 15h Начало импульса гашения вертикальной развертки (Start Vertical Blank Register - SVBR) 16h Конец импульса гашения вертикальной развертки (End Vertical Blank Register - EVBR) 17h Управление режимом (Mode Control Register - MCR) 18h Регистр сравнения линий (Line Compare Register - LCR) В отличие от внешних регистров, адресация к регистрам контроллера ЭЛТ происходит через два порта. В первый порт (индексный) записывается индекс регистра, к которому осуществляется доступ, а через второй порт (порт данных) можно выполнять обмен данными (запись или чтение). SYMBOL 77 \f "Wingdings" Большинство регистров контроллера ЭЛТ видеоадаптера EGA доступны только для записи. Прочитать значение этих регистров нельзя У видеоадаптеров MDA и Hercules индексный порт имеет адрес 3B4h, а порт данных - адрес 3B5h. Для CGA адреса портов другие. Индексный порт имеет адрес 3D4h, а порт данных - адрес 3D5h. Адреса портов контроллера ЭЛТ для видеоадаптеров EGA и VGA зависят от режима работы видеоадаптера (монохромный или цветной). В монохромном режиме адрес порта индексного регистра равен 3B4h, а регистра данных - 3B5h. В цветном режиме адреса соответственно равны 3D4h и 3D5h: Видеоадаптер Адрес порта индексного регистра Адрес порта регистра данных CGA 3D4h 3D5h EGA, VGA, SVGA (монохромный режим) 3B4h 3B5h EGA, VGA, SVGA (цветной режим) 3D4h 3D5h MDA, Hercules 3B4h 3B5h Так как в монохромных и цветных режимах регистры адресуются через различные порты ввода/вывода, то к компьютеру можно одновременно подключить два видеоадаптера. Адрес порта индексного регистра записан в области переменных BIOS, по адресу 0000:0463h. Приведем фрагмент программы, определяющей адрес индексного порта контроллера ЭЛТ:; Устанавливаем регистр ES на нулевой сегмент памяти
xor ax,ax
mov es,ax
; Записываем в регистр DX адрес порта индексного
; регистра контроллера ЭЛТ
mov dx,es:[463] Так как адреса портов индексного регистра и регистра данных контроллера ЭЛТ является смежными, то адрес порта регистра данных можно легко получить, прибавив единицу к адресу порта индексного регистра. Общая длина линии горизонтальной развертки (Horizontal Total Register - HTR) (индекс 0) Регистр HTR относится к группе регистров контроллера ЭЛТ, которые управляют генерацией синхросигналов монитора. Необходимость модификации данной группы регистров возникает только при программировании нестандартных режимов работы видеоадаптера. Кроме регистров, контроллер ЭЛТ использует при генерации синхросигналов два внутренних счетчика. Счетчик числа горизонтальных знакомест экрана увеличивается при выводе очередного символа на экран (регенерация экрана) и сбрасывается, когда его значение становится равным регистру общей длины линии горизонтальной развертки. Счетчик числа горизонтальных линий развертки увеличивается после окончания обратного горизонтального хода луча и сбрасывается, когда достигает величины, хранящейся в регистре числа горизонтальных линий растра. Регистр HTR определяет число знакомест в одной строке развертки, включая обратный ход луча и нерабочую область развертки (рамку экрана). Для видеоадаптера EGA число знакомест по горизонтали на два, а для адаптеров VGA и SVGA на пять больше, чем значение, хранящееся в регистре. При установке режима работы видеоадаптера, BIOS загружает в регистр HTR следующие значения: Режим 0,1,4,5,D 2,3,6,E 7, F 10 Содержимое регистра 37h 70h 60h 5Bh Если используется улучшенный цветной монитор, то эти значения отличаются: Режим 0,1 2,3 Содержимое регистра 2Dh 5Bh Длина отображаемой части горизонтальной развертки (Horizontal Display Enable End Register - HDER) (индекс 1) Регистр задает длину отображаемого участка горизонтальной развертки. Величина, записанная в регистр должна быть единицу меньше, чем количество символов в строке экрана. При установке режима работы видеоадаптера, BIOS загружает в регистр HDER следующие значения: Режим 0,1,4,5,D 2,3,6,7,E,F,10 Содержимое регистра 27h 4Fh Начало импульса гашения луча горизонтальной развертки (Start Horizontal Blank Register - SHBR) (индекс 2) Регистр используется видеоадаптерами EGA, VGA и SVGA для определения начала импульса гашения луча горизонтальной развертки. При установке режима работы видеоадаптера, BIOS загружает в регистр SHBR следующие значения: Режим 0,1,4,5,D 2,3 6,E 7,F 10 Содержимое регистра 2Dh 5Ch 59h 56h 53h Если используется улучшенный цветной монитор, то эти значения отличаются: Режим 0,1 2,3 Содержимое регистра 2Bh 53h Конец импульса гашения луча горизонтальной развертки (End Horizontal Blank Register - EHBR) (индекс 3) D4-D0 Конец импульса гашения луча горизонтальной развертки. Гашение луча горизонтальной развертки происходит, когда биты D4-D0 равны счетчику длины отображаемой части горизонтальной развертки. D6-D5 Биты смещения используются в текстовых режимах, чтобы разрешить отображение символов до разрешения вывода. Если величина битов смещения слишком маленькая, то символы на левой стороне экрана могут быть потеряны, а если она слишком большая, то символы на левой стороне экрана могут дублироваться по несколько раз.
 
 

 D6 D5 

0 0 - нет смещения
0 1 - смещение на один символ
1 0 - смещение на два символа
1 1 - смещение на три символа D7 Бит D7 равен единице для видеоадаптера VGA и нулю для EGA. При установке режима работы видеоадаптера, BIOS загружает в регистр EHBR следующие значения: Режим 0,1,4,5,D 2,3 6,E 7 F 10 Содержимое регистра 37h 2Fh 2Dh 3Ah 1Fh 17h Если используется улучшенный цветной монитор, то эти значения отличаются: Режим 0,1 2,3 Содержимое регистра 2Dh 37h Начало импульса горизонтального обратного хода луча (Start Horizontal Retrace Register - SHRR) (индекс 4) Для видеоадаптеров EGA, VGA и SVGA регистр задает момент начала импульса горизонтального обратного хода луча. При установке режима работы видеоадаптера, BIOS загружает в регистр SHRR следующие значения: Режим 0,1 4,5,D 2,3 6,E 7 F,10 Содержимое регистра 31h 30h 5Fh 5Eh 51h 50h Если используется улучшенный цветной монитор, то эти значения отличаются: Режим 0,1 2,3 Содержимое регистра 28h 51h Конец импульса горизонтального обратного хода луча (End Horizontal Retrace Register - EHRR) (индекс 5) D4-D0 Конец импульса горизонтального обратного хода луча. Обратный горизонтальный хода луча завершается, когда значение счетчика символов в строке становится равным битам D4-D0. D6-D5 Смещение импульса горизонтального обратного хода луча относительно отображаемого участка горизонтальной развертки. Биты используются видеоадаптером EGA.


  D6 D5  


0 0 - нет смещения
0 1 - смещение на один символ
1 0 - смещение на два символа
1 1 - смещение на три символа D7 Для адаптера EGA с объемом видеопамяти меньшим 256 Кбайт, бит D7 используется для управления горизонтальной сверткой экрана (горизонтальным панорамированием), когда слои видеопамяти сцеплены. Если бит D7 равен нулю, то после обратного хода луча первый адрес видеопамяти для обновления экрана будет четным. Для видеоадаптеров VGA и SVGA бит D7 является пятым битом регистра конца импульса гашения луча горизонтальной развертки (EHBR). Число горизонтальных линий растра (Vertical Total Register - VTR) (индекс 6) Регистр определяет общее число линий горизонтальной развертки в кадре вертикальной развертки, включая гашение вертикального хода луча и обратный вертикальный ход луча. Для видеоадаптера EGA, регистр VTR содержит девять битов. Девятый бит находится в дополнительном регистре (OVR). Регистр VTR видеоадаптеров VGA и SVGA содержит десять битов. Десятый бит, также как и девятый, расположен в дополнительном регистре (OVR). Дополнительный регистр (Overflow Register - OVR) (индекс 7) Многие регистры контроллера ЭЛТ, видеоадаптера EGA, имеют по девять, а для адаптеров VGA и SVGA по десять битов. Дополнительный регистр содержит биты, которые не помещаются в восьмиразрядную сетку основных регистров видеоадаптера. D0 Бит 8 регистра числа горизонтальных линий растра (VTR). D1 Бит 8 регистра начала гашения вертикальной развертки (VDER). D2 Бит 8 регистра начала обратного вертикального хода луча (VRSR). D3 Бит 8 регистра начала импульса гашения вертикальной развертки (SVBR). D4 Бит 8 регистра сравнения линий (LCR). D5 Бит 9 регистра количества горизонтальных линий в растре (VTR). D6 Бит 9 регистра начала гашения вертикальной развертки (VDER). D7 Бит 9 регистра начала обратного вертикального хода луча (VRSR). Предварительная установка горизонтальной развертки
(Preset Row Scan Register - PRSR) (индекс 8) Регистр позволяет в текстовых режимах выполнить плавную вертикальную свертку текста на экране монитора. В графических режимах регистр должен содержать нулевое значение. D4-D0 Биты предварительной установки строчной развертки. Эти биты определяют номер линии развертки, начиная с которой начинают отображаться символы (рис. 8.1). Как видно из рисунка самая верхняя строка текста отображается только частично. Вы можете плавно перемешать изображение на экране увеличивая или уменьшая значение этих битов. D6-D5 Биты управления побайтовой сверткой. Используются видеоадаптерами VGA и SVGA. Биты D6 D5 являются двумя дополнительными битами регистра горизонтального панорамирования контроллера атрибутов и позволяют сдвигать изображение на экране более чем на 8 пикселов. D7 Не используется. Рисунок 4.1 иллюстрирует использование регистра предварительной установки горизонтальной развертки для вертикальной свертки содержимого экрана. В левой части рисунка показано начальное состояние экрана монитора, когда биты D0-D4 регистра PRSR содержит нулевые значения. Справа представлен экран монитора после увеличения значения регистра PRSR до трех. Изображение на экране сдвигается на три пиксела вверх, в результате чего часть верхней строки пропадает. \* MERGEFORMAT PICTURE._FIG_32.PCX;6";4.308";PCX Рисунок 4.1 Плавная свертка экрана После установки режима работы видеоадаптера регистр PRSR содержит нулевое значение. Высота символов текста
(Max Scan Line Register - MSLR) (индекс 9) Регистр MSLR определяет высоту символов в пикселах. Значение регистра на единицу меньше, чем высота символов отображаемых на экране. Регистр MSLR используется только в текстовых режимах работы видеоадаптеров. D4-D0 Биты задают высоту символа в пикселах (рис. 8.2 и 8.3). D5 Бит 9 регистра начала импульса гашения вертикальной развертки (SVBR - индекс 15h). Используется только для видеоадаптеров VGA и SVGA. D6 Бит 9 регистра сравнения линий (LCR индекс 18h). Используется только для видеоадаптеров VGA и SVGA. D7 Бит управления двойным сканированием. Поддерживается только адаптерами VGA и SVGA. Если бит D7 равен единице, то в режимах, имеющих разрешение по вертикали 200 пикселов используется двойное сканирование. Это увеличивает разрешающую способность по вертикали до 400 пикселов. Рисунок 4.2 демонстрирует использование регистра высоты символов текста. На левой половине рисунка символы шрифта имеют размер 8х8 пикселов, а регистр высоты символов содержит число семь. На правой половине рисунка, символы шрифта имеют размер 8х14, а значение регистра высоты символов текста равно тринадцати. \* MERGEFORMAT PICTURE._FIG_33.PCX;6";4.308";PCX Рисунок 4.2 Высота символов текста 8 пикселов Начальная линия курсора
(Cursor Start Register - CSR) (индекс 0Ah) Регистр CSR является доступным как для чтения, так и для записи. Регистр определяет линию сканирования символа, в которой начинается курсор. Вместе с регистром конечной линии курсора (CER) регистр CSR определяет размер и форму курсора. D4-D0 Начальная линия курсора. (Рис. 4.3). D5 Бит гашения курсора. Реализован только для видеоадаптеров VGA и SVGA. Если бит D5 содержит единицу, тогда текстовый курсор гаснет. D7-D6 Не используются. При установке режима работы видеоадаптера, BIOS загружает в регистр CSR следующие значения: Режим 0,1,2,3 4,5,6,D,E,F,10 7 Содержимое регистра 06 00 0Bh Конечная линия курсора
(Cursor End Register - CER) (индекс 0Bh) Этот регистр, также как и регистр CSR, является доступным для чтения и для записи. Регистр задает линию сканирования символа, в которой кончается курсор. D4-D0 Соответствует номеру последней линии курсора для видеоадаптеров VGA и SVGA (рис. 4.3). Для видеоадаптера EGA - номеру следующей линии. D6-D5 Отклонение курсора. Задает смещение курсора относительно позиции, определенной регистром CLR.
00 - нет отклонения
01 - отклонение вправо на один символ
10 - отклонение вправо на два символа
11 - отклонение вправо на три символа D7 Не используется. При установке режима работы видеоадаптера BIOS загружает в регистр конечной линии курсора следующие значения: Режим 0,1,2,3 4,5,6,D,E,F,10 7 Содержимое регистра 07 00 0Ch Изменяя значение регистров начальной и конечной линии курсора, можно менять его положение и размер (рис. 4.3). На левой части рисунка, приведенного ниже, регистр начальной линии курсора равен 0Ah, регистр конечной линии курсора равен 0Bh. На правой части рисунка значение регистров изменено. Регистр начальной линии равен 4, а регистр конечной линии - 5. \* MERGEFORMAT PICTURE._FIG_35.PCX;6";4.308";PCX Рисунок 4.3 Изменение положения курсора Следующая программа позволяет прочитать значение регистров начальной и конечной линии курсора: Листинг 4.4. Файл GETCURS.C #include "stdio.h"
#include "conio.h"
#include "sysp.h" // см. листинг 3.2
#include "sysgraph.h" // см. листинг 3.3
// Описания функций
void main(void);
void WriteReg(unsigned reg, unsigned char data);
unsigned char ReadReg(unsigned reg);
// Главная функция
void main(void) {
char top = 0, bottom = 0;
unsigned crt_address;
BIOS_VAR _far *bios_var_ptr;
// Получаем указатель на область переменных BIOS
bios_var_ptr = (BIOS_VAR _far *) FP_MAKE(0x0000, 0x0410);
// Определяем адрес индексного регистра контроллера ЭЛТ
crt_address = bios_var_ptr-" wAddrCRT;
// Считываем значения регистров начальной и конечной линии
// курсора
// Выбираем регистр начальной линии курсора
WriteReg(crt_address++, 0x0A);
// Считываем значение регистра
top = (unsigned char) ReadReg(crt_address-);
// Выбираем регистр конечной линии курсора
WriteReg(crt_address++, 0x0B);
// Считываем значение регистра
bottom = (unsigned char) ReadReg(crt_address);
// Отображаем на экране значение регистров
printf("\nРегистр начальной линии курсора содержит: %d\n"
"\nРегистр конечной линии курсора содержит: %d\n",
top, bottom);
getch();
} Для доступа к регистрам видеоадаптера мы пользуемся функциями WriteReg и ReadReg, определенными в файле DESIGN.C (листинг 4.5). Листинг 4.5. Файл DESIGN.C // ____________________ =
// WriteReg(unsigned reg, unsigned char data)
// Функция выводит данные в порт
//
// Параметры:
// reg - номер порта
// data - данные, записываемые в порт reg
//- ____________________ =
void WriteReg(unsigned reg, unsigned char data) {
_asm {
mov dx,reg
mov al,data
out dx,al
}
}
//- ____________________ =
// unsigned char ReadReg(unsigned reg)
// Функция читает данные из определенного порта
//
// Параметры:
// reg - номер порта
//
// Возвращаемое значение:
// данные, считанные из порта reg
//- ____________________ =
unsigned char ReadReg(unsigned reg) {
unsigned char data;
_asm {
mov dx,reg
in al,dx
mov data,al
}
return(data);
} Регистры начального адреса Это группа из двух регистров: регистр старшего байта начального адреса (Start Address Register - SAR, high byte) (индекс 0Ch) и регистр младшего байта начального адреса (Start Address Register - SAR, low byte) (индекс 0Dh). В регистрах SAR записан адрес видеоданных, которые отображаются в верхнем левом углу экрана монитора. Регистры начального адреса можно использовать для перемещения изображения по экрану (свертки) и для переключения активной страницы видеопамяти. Если вы желаете использовать регистры для переключения страниц видеопамяти, то в регистры SAR надо записать смещение страницы видеопамяти (относительно начала видеопамяти), которую необходимо отобразить на экране. На рисунке 4.4 показано, как происходит свертка экрана при изменении регистров начального адреса. В верхней части рисунка регистры начального адреса содержат ноль. Видеопамять отображается на экране с начала. В нижней части значение регистров начального адреса увеличено до 77h. В этом случае видеопамять отображается на экране начиная с данных, имеющих смещение 77h от начала видеопамяти. В нижней части экрана появляется изображение, ранее не помещающееся на экране. \* MERGEFORMAT PICTURE._FIG_36.PCX;6";4.308";PCX Рисунок 4.4 Свертка изображения на экране Регистры начального адреса доступны для чтения и для записи. При выборе режима работы видеоадаптера регистры обнуляются. Регистры, определяющие положение курсора Два регистра - регистр старшего байта позиции курсора (Cursor Location Register - CLR_h, high byte) (индекс 0Eh) и регистр младшего байта позиции курсора (Cursor Location Register - CLR_l, low byte) (индекс 0Fh) определяют положение курсора на экране (рис. 4.5). Регистры доступны как для записи, так и для чтения. \s \* MERGEFORMAT PICTURE._FIG_37.PCX;6";4.308";PCX Рисунок 4.5 Отображение курсора на экране Программа CURSLOC, приведенная в листинге 4.6 переводит видеоадаптер в текстовый режим, устанавливает курсор в позицию 5 строки 10. Затем программа считывает значения регистров позиции курсора (на момент запуска программы) и отображает их на экране монитора. Вы должны получить значение 0325h (80 * 10 + 5 = 805 = 0325h). Листинг 4.6. Файл CURSLOC.C // Чтение регистра положения курсора
#include "stdio.h"
#include "sysp.h"
#include "sysgraph.h"
// Описания функций
void main(void);
// Функции WriteReg и ReadReg определены в файле
// DESIGN.C. Смотри листинг 4.5
void WriteReg(unsigned reg, unsigned char data);
unsigned char ReadReg(unsigned reg);
// Главная функция
void main(void) {
int crt_port;
unsigned char h_pos, l_pos;
BIOS_VAR _far *bios_var_ptr;
_asm {
// Устанавливаем режим 3
mov ah,0
mov al,3
int 10h
// Выбираем страницу видеоапамяти 0
mov ah,5
mov al,0
int 10h
// Устанавливаем курсор в положение (20,10)
mov ah,2
mov dh,10 //
mov dl,5 // строка 10, позиция 5:
// CLR = 80 * 10 + 5 = 805 = 325h
xor bh,bh
int 10h
}
// Получаем указатель на область переменных видеофункций BIOS
bios_var_ptr = (BIOS_VAR _far *) FP_MAKE(0x0000, 0x0410);
// Определяем адрес порта индексного регистра контроллера ЭЛТ
crt_port = bios_var_ptr -" wAddrCRT;
// Выбираем старший байт регистра положения курсора
WriteReg(crt_port, 0x0E);
// Читаем значение старшего байта регистра
h_pos = ReadReg(crt_port + 1);
// Выбираем младший байт регистра положения курсора
WriteReg(crt_port, 0x0F);
// Считываем значение младшего байта регистра
l_pos = ReadReg(crt_port + 1);
// Отображаем полученные значения
printf("\nТекущий адрес курсора %2.2X%2.2Xh\n",
(unsigned char) h_pos, (unsigned char) l_pos );
return;
} Начало обратного вертикального хода луча (Vertical Retrace Start Register - VRSR) (индекс 10h) Регистр определяет начало обратного вертикального хода луча. У видеоадаптера EGA регистр имеет 9, а для видеоадаптеров VGA и SVGA - 10 разрядов. Дополнительные биты регистра VRSR расположены в регистре OVR. Регистр VRSR доступен только для записи. Конец обратного вертикального хода луча (Vertical Retrace End Register - VRER) (индекс 11h) Регистр устанавливает конец обратного вертикального хода луча, а также выполняет некоторые другие функции. Данный регистр доступен только для записи. Биты Описание D3-D0 Конец обратного вертикального хода луча D4 Сброс вертикального прерывания D5 Разрешения вертикального прерывания D6 Изменение скорости регенерации экрана (видеоадаптеры VGA и SVGA) D7 Защита от записи (видеоадаптеры VGA и SVGA) D7 Если бит D7 равен единице, то регистры контроллера ЭЛТ, имеющие индексы от 0 до 7, будут защищены от записи. Защита от записи позволяет решить некоторые проблемы совместимости между адаптером VGA и видеоадаптерами, построенными на основе микросхемы 6845 (например CGA). D6 Если бит D6 равен единице, то во время обратного горизонтального хода луча будет генерироваться пять циклов регенерации видеопамяти вместо обычных трех. D5 Если бит равен нулю, то при каждом обратном вертикальном ходе луча на линии IRQ2 будет возникать прерывание. Сигнал прерывания сбрасывается при записи нуля в бит D4 данного регистра. D4 Запись нуля в данный бит вызывает сброс прерывания на линии IRQ2 и переустановку флага незаконченного вертикального прерывания. D3-D0 Сигнал обратного вертикального хода луча завершается, когда значение четырех младших бита счетчика горизонтальных линий совпадает с битами D3-D0 Регистр адреса светового пера (Light Pen Address Register - LPAR) Это 16-битовый регистр видеоадаптеров CGA и EGA, доступный только для чтения. Регистр LPAR позволяет определить положение светового пера на экране монитора. Регистр, содержащий старший байт адреса светового пера, имеет индекс 10h, а регистр, содержащий младший байт, индекс 11h. Регистр LPAR сохраняет адрес видеопамяти, которая регенерировалась в момент включения светового пера. Завершение отображения вертикальной развертки (Vertical Display End Register - VDER) (индекс 12h) Регистр определяет момент, когда заканчивается видимая часть вертикальной развертки и происходит гашение луча. Регистр содержит число, на единицу меньшее, чем количество горизонтальных линий растра. У видеоадаптера EGA регистр VDER имеет 9, а у адаптеров VGA и SVGA - 10 разрядов. Девятый и десятый биты регистра доступны через дополнительный регистр (OVR). Логическая ширина экрана (Offset Register - OFR) (индекс 13h) Регистр позволяет отобразить на экране больше символов в строке, чем в стандартных текстовых режимах. Например, вы можете воспользоваться регистром OFR при переводе видеоадаптера в режим отображения 132 символов в строке. В текстовых режимах регистр содержит смещение между соседними строками экрана, заданное в 16-битных словах. В графических режимах регистр OFR задает логическую длину (в 16-битных словах или 32-битных двойных словах) горизонтальной линии развертки. Если линия Num развертки начинается по адресу Adr, то следующая линия развертки Num+1 начинается по адресу Adr+Offset, где Offset является значением регистра OFR. Использование регистра OFR иллюстрируется рисунком 4.6. На верхней части рисунка видеоадаптер находится в стандартном текстовом режиме с разрешением 80 символов в строке. При этом значение регистра логической ширины экрана равно 40. На нижней части рисунка представлен результат увеличения содержимого регистра до 41. Логическая ширина экрана в этом случае увеличивается до 82 символов в строке. Последние два символа каждой строки не помещаются на экране. Для их отображения надо выполнить горизонтальную свертку экрана. \* MERGEFORMAT PICTURE._FIG_38.PCX;6";4.308";PCX Рисунок 4.6 Логическая ширина экрана Положение подчеркивания символа (Underline Location Register - ULR) (индекс 14h) Регистр ULR используется только в текстовых режимах. Он определяет положение подчеркивания символа. Подчеркивание представляет собой одну из линий в матрице символа. Подчеркивание отображается, если установлен атрибут подчеркивания. Подчеркивание можно запретить, записав в регистр ULR величину большую, чем высота символов. D4-D0 Определяют положение подчеркивания символа. D5 Для видеоадаптеров VGA и SVGA установка этого бита означает, что для каждого знакоместа счетчик адреса регенерации будет увеличиваться на 4 вместо 1. D6 Установка для видеоадаптеров VGA и SVGA этого бита выбирает адресацию видеопамяти по двойным словам. D7 Не используется. Программа, приведенная ниже, использует регистры контроллера ЭЛТ для перевода видеоадаптеров EGA и VGA в нестандартный текстовый режим, имеющий разрешение по вертикали 43 строки. Данная программа переводит видеоадаптер в текстовый режим с разрешением по вертикали 43 символа и затем отображает на экране монитора 43 строки текста. Листинг 4.7. Файл MORESTR.ASM #include "conio.h"
// Описания функций
void main(void);
// Функция Set43Line опреелена в файле SET43.ASM
// (листинг 4.8)
void __pascal _far Set43Line(void);
// Главная функция
void main(void) {
int i;
// Увеличиваем количество отображаемых строк текста
Set43Line();
// Отображаем на экране монитора несколько текстовых строк
for(i = 0; i "50; i++)
printf("Text line number %d\n", i);
getch();
return;
} Основная функция программы MORESTR - функция Set43Line определена в файле SET43.ASM. Исходный текст файла помещен в листинге 4.8. Листинг 4.8. Файл SET43.ASM TITLE SET43.ASM
 
 

 NAME SET43 


  PAGE 55,132  



  P286  



  IDEAL  



  NOWARN BRK  



  SEGMENT LINE_TEXT WORD PUBLIC 'CODE'  


ASSUME cs:LINE_TEXT
;- ____________________ 
; void Set43Line(void)
; Переводит адаптеры EGA и VGA в режим отображения 43
; строк текста.
;- ____________________ 


  CHAR_SIZE EQU 8  



  PUBLIC SET43LINE  



  PROC SET43LINE FAR  


enter 0, 0
; Устанавливаем регистр es на начало оперативной памяти
xor ax,ax
mov es,ax
; Получаем адрес порта индексного регистра контроллера ЭЛТ
; (3B4h/3D4h), в монохромных режимах для адресации к
; индексному регистру используется порт с адресом 3B4h,
; а в цветных - порт 3D4h
mov dx,es:[463h]
; Выбираем для обмена регистр максимальной линии
; сканирования этот регистр задает высоту символов на
; экране дисплея
mov al,9
out dx,al
; Вычисляем адрес порта регистра данных контроллера ЭЛТ,
; в монохромных режимах для адресации к регистру данных
; используется порт с адресом 3B5h, в цветных - порт 3D5h
inc dx
; Биты D4-D0, регистра максимальной линии сканирования
; содержат число, меньшее на единицу, чем высота символов
; в пикселах
mov al,CHAR_SIZE-1
out dx,al
; Вычисляем адрес порта индексного регистра
; контроллера ЭЛТ
dec dx
; Выбираем для обмена регистр положения подчеркивания
mov al,14h
out dx,al
; Вычисляем адрес порта регистра данных контроллера ЭЛТ
inc dx
; Определяем положение подчеркивания символов
mov al,CHAR_SIZE
out dx,al
; Вычисляем адрес порта индексного регистра
; контроллера ЭЛТ
dec dx
; Выбираем для обмена регистр завершения отображения
; вертикальной развертки
; Регистр завершения отображения вертикальной развертки
; содержит восемь младших бит, определяющих число
; отображаемых горизонтальных линий растра минус один
mov al,12h
out dx,al
; Вычисляем адрес порта регистра данных контроллера ЭЛТ
inc dx
; Для отображения 43 текстовых символов, при высоте
; символов 8 пикселов, необходимо иметь 43 * 8 = 344
; горизонтальных линий растра
; Помещаем в регистр завершения отображения вертикальной
; развертки младшие 8 бит числа 344
mov al,(43 * CHAR_SIZE - 1 - 256)
out dx,al
; Устанавливаем новые значения переменных BIOS
; Количество символов в строке равно восьмидесяти
mov WORD PTR es:[44Ah],80
; Количество строк текста минус один
mov BYTE PTR es:[484h],(350/CHAR_SIZE)-1
; Высота символов в пикселах
mov WORD PTR es:[485h],CHAR_SIZE
; Загружаем нулевую таблицу знакогенератора набором
; символов (размер 8х8) из ПЗУ BIOS
mov ax,1112h
xor bl,bl
int 10h
leave
ret
 
 

 ENDP SET43LINE 


  ENDS LINE_TEXT  


END Начало импульса гашения вертикальной развертки (Start Vertical Blank Register - SVBR) (индекс 15h) Регистр определяет момент гашения луча в процессе вертикальной развертки. У видеоадаптера EGA регистр имеет 9, а у видеоадаптера VGA - 10 разрядов. Девятый бит регистра SVBR расположен в дополнительном регистре (OVR). Десятый бит расположен в регистре высоты символов текста (MSLR). Конец импульса гашения вертикальной развертки (End Vertical Blank Register - EVBR) (индекс 16h) Сигнал гашения вертикальной развертки завершается, когда счетчик горизонтальных линий соответствует значению регистра EVBR. Для видеоадаптера EGA регистр имеет 5 разрядов, а для VGA и SVGA 8 разрядов. Управление режимом (Mode Control Register - MCR) (индекс 17h) Регистр содержит набор битов, управляющих контроллером ЭЛТ. D7 Бит D7 запрещает горизонтальный и вертикальный обратный ход луча. D6 Если бит D6 равен единице, то установлен байтовый режим, а если он равен нулю - двухбайтовый. Двухбайтовый режим поддерживает разделение данных между двумя цветовыми слоями. Видеоадаптеры VGA и SVGA дополнительно поддерживают четырехбайтовый режим (см. регистр ULR). Биты D6 D5 1х 00 01 MA0 MA13 MA15 MA1 MA0 MA0 MA2 MA1 MA1 MA3 MA2 MA2 MA4 MA3 MA3 MA5 MA4 MA4 MA6 MA5 MA5 MA7 MA6 MA6 MA8 MA7 MA7 MA9 MA8 MA8 MA10 MA9 MA9 MA11 MA10 MA10 MA12 MA11 MA11 MA13 MA12 MA12 MA14 MA13 MA13 MA15 MA14 MA14 Бит D5 равен нулю только для видеоадаптеров EGA с объемом видеопамяти 64 Кбайт. В этом случае происходит сцепление слоев в графических режимах с высоким разрешением. D4 Если бит D4 равен единице, то все выходные линии контроллера ЭЛТ переводятся в третье состояние. Этот бит используется при тестировании видеоадаптера. D3 Если бит D3 равен нулю, то счетчик адреса регенерации изображения увеличивается на единицу на каждое знакоместо экрана, а если бит равен единице, то на каждые два знакоместа. D2 Бит D2 может использоваться для увеличения в два раза вертикальной разрешающей способности. Если бит равен нулю, то счетчик числа линий экрана увеличивается после каждого обратного горизонтального хода луча, а если бит равен единице, то после двух обратных горизонтальных ходов луча. D1 Используется для эмуляции графических режимов видеоадаптера Hercules. Запись нуля в этот бит приводит к замещению бита D14 адресного регистра битом D1 из регистра счетчика горизонтальных линий. D0 Используется для эмуляции графических режимов CGA. Запись нуля в этот бит приводит к выделению в видеопамяти двух областей по 8 Кбайт каждая. Одна область соответствует четным, а другая нечетным строкам экрана. Такое отображение видеопамяти достигается в результате замещения бита D13 адресного регистра битом D0 из регистра счетчика горизонтальных строк. Регистр сравнения линий (Line Compare Register - LCR) (индекс 18h) Позволяет разделить изображение на две независимые части. При этом одну из них можно свертывать. Содержимое другой части экрана остается на месте. Регистр LCR используют совместно с регистром начального адреса. Когда счетчик горизонтальных линий сканирования достигает значения, записанного в регистре LCR, происходит сброс счетчика адреса регенерируемой видеопамяти в ноль. В результате экран разбивается на две части. В верхней части экрана отображаются данные, на которые указывает регистр начального адреса, а в нижней - данные, находящиеся в начале видеопамяти. Процесс разделения экрана иллюстрируется рисунком 4.7. \s \* MERGEFORMAT PICTURE._FIG_39.PCX;6";4.308";PCX Рисунок 4.7 Процесс разделения экрана Изображение в верхней части экрана можно перемещать, изменяя содержимое регистра начального адреса. У видеоадаптера EGA регистр сравнения линий имеет 9 разрядов. Девятый бит регистра доступен через дополнительный регистр (OVR) контроллера ЭЛТ. Регистр сравнения линий видеоадаптера VGA имеет 10 разрядов. Десятый бит регистра LCR расположен в регистре MSLR. При изменении режима работы видеоадаптера, BIOS записывает в регистр сравнения линий значение 0FFh. Программа, представленная ниже, выводит на экран монитора 25 строк текста, а затем, после нажатия любой клавиши, разделяет изображение на две части. Листинг 4.9. Файл SCRSPLIT.C #include "dos.h"
#include "stdio.h"
#include "conio.h"
void __pascal __far Split(unsigned);
void main(void);
// Главная функция
void main(void) {
int i;
for(i = 0; i "25; i++)
printf("Строка номер %d.\n",i);
getch();
// Разделяем экран по линии 200
Split(200);
// Ожидаем нажатие на клавиши клавиатуры
getch();
// После завершения программы значения регистров не
// восстанавливеются!
} Для разделения изображения на экране монитора предназначена функция Split. Исходный текст этой функции представлен в листинге 4.10. Листинг 4.10. Файл SPLIT.ASM TITLE SPLIT.ASM
 
 

 NAME SPLIT 


  PAGE 55,132  



  P286  



  IDEAL  



  NOWARN BRK  



  SEGMENT SPLIT_TEXT WORD PUBLIC 'CODE'  


ASSUME cs:SPLIT_TEXT
;- ____________________ =
; void Split(unsigned split_line)
; Функция разделяет экран на две части. Функция работает
; только на видеоадаптерах EGA и VGA.
; Параметр split_line определяет линию горизонтальной
; развертки, в которой происходит разделение экрана монитора
;- ____________________ =
split_line EQU [bp+6]


  PUBLIC SPLIT  



  PROC SPLIT FAR  


enter 0, 0
; Устанавливаем регистр ES на начало оперативной памяти
xor ax,ax
mov es,ax
; Получаем адрес порта индексного регистра контроллера ЭЛТ
; (3B4h/3D4h), в монохромных режимах для адресации к
; индексному регистру используется порт с адресом 3B4h, а
; в цветных - порт 3D4h
mov dx,es:[463h]
; Вычисляем адрес порта регистра состояния 1, в
; монохромных режимах для адресации к регистру состояния 1
; используется порт с адресом 3BAh, в цветных - порт 3DAh
add dx,6
; Ожидаем начало обратного вертикального хода луча
in al,dx
nop
; Если бит D3 равен единице, то происходит обратный
; вертикальный ход луча
test al,8
jz wait_on
wait_off:
in al,dx
nop
test al,8
jnz wait_off
wait_on:
in al,dx
nop
test al,8
jz wait_on
; Вычисляем адрес порта индексного регистра
; контроллера ЭЛТ (3B4h/3D4h)
sub dx,6
; Выбираем для обмена регистр сравнения линий
mov al,18h
out dx,al
; Вычисляем адрес порта регистра данных контроллера ЭЛТ,
; в монохромных режимах для адресации к регистру данных
; используется порт с адресом 3B5h, а в цветных порт 3D5h
inc dx
; Определяем линию горизонтальной развертки, в которой
; происходит разделение экрана дисплея
mov ax,split_line
; У видеоадаптера EGA регистр сравнения линий состоит из 9
; бит, доступ к девятому биту происходит через
; дополнительный регистр контроллера ЭЛТ; видеоадаптер
; VGA имеет еще и десятый бит, расположенный в регистре
; высоты символов текста
; Записываем младшие 8 битов в регистр сравнения линий
out dx,al
; Вычисляем адрес порта индексного регистра
; контроллера ЭЛТ
dec dx
; Вызываем функцию чтения конфигурации видеосистемы
mov ax,1A00h
int 10h
; Если после вызова функции регистр AL не равен 1Ah, то
; используемый видеодаптер не VGA
cmp al,1Ah
je vga
jmp ega
vga:
; Считываем в AL состояние дополнительнго регистра
mov al,7
out dx,al
inc dx
in al,dx
; Модифицируем бит D4 дополнительного ргистра
mov bx,split_line
mov cl,4
shl bh,cl
and bh,00010000b
and al,11101111b
or al,bh
out dx,al
; Сбрасываем бит D6 регистра высоты символов текста
dec dx
mov al,9
out dx,al
inc dx
in al,dx
and al,10111111b
out dx,al
jmp quit_split
ega:
mov bx,split_line
mov cl,4
shl bh,cl
and bh,00010000b
cmp dx,3B4h; монохромный режим?
je default_1Fh
; Определяем наличие улучшенного цветного дисплея по
; положению переключателей на плате EGA
mov al,es:[488h]
and al,0Fh
; Положение переключателей "OFF OFF ON ON"?
cmp al,3
je default_1Fh
; Положение переключателей "OFF ON ON OFF"?
cmp al,9
je default_1Fh
; Для видиосистем с монохромным или цветным дисплеями,
; дополнительный регистр по умолчанию содержит 11h
or bh,1
jmp set_overflow
; Для видиосистем с улучненным цветным дисплеем или в
; монохромных текстовых режимах дополнительный регистр по
; умолчанию содержит 1Fh
default_1Fh:
or bh,0Fh
; Устанавливаем дополнительный регистр
set_overflow:
mov al,07h
out dx,al
inc dx
mov al,bh
out dx,al
quit_split:
leave
ret 2
 
 

 ENDP SPLIT 


  ENDS SPLIT_TEXT  


END Регистры синхронизатора Синхронизатор управляет всеми временными параметрами видеоадаптера, а также разрешением и запрещением доступа к отдельным цветовым слоям видеопамяти. Синхронизатор содержит пять регистров. Их названия перечислены в таблице 4.12. У видеоадаптера EGA все пять регистров доступны только для записи, а у видеоадаптеров VGA и SVGA также и для чтения. Индекс регистра Регистр синхронизатора 0 Регистр сброса синхронизатора (Reset Register - RR) 1 Регистр режима синхронизации (Clock Mode Register - CMR) 2 Регистр разрешения записи цветового слоя (Color Plane Write Enable Register - CPWER) 3 Регистр выбора знакогенератора (Character Generator Select Register - CGSR) 4 Регистр определения структуры памяти (Memory Mode Register - MMR) Доступ к регистрам осуществляется через индексный порт с адресом 3C4h и через порт данных с адресом 3C5h. Регистр сброса синхронизатора (Reset Register - RR) (индекс 0) Если регистр переведен в состояние сброса, то все процессы видеоадаптера приостанавливаются. В результате могут быть разрушены данные в видеопамяти. D0 Бит асинхронного сброса. После записи в этот бит нуля происходит немедленный сброс и остановка синхронизатора. В результате информация из видеопамяти может быть потеряна. D1 Бит синхронного сброса. Нулевое значение сбрасывает и останавливает синхронизатор в конце исполняемого цикла. D7-D2 Не используются. Для нормальной работы видеоадаптера биты D0 и D1 должны быть равны единице. Перед доступом к регистру режима синхронизации синхронизатор должен быть переведен в состояние синхронного сброса (бит D1 равен 0). Регистр режима синхронизации (Clock Mode Register - CMR) (индекс 1) Регистр управляет временными циклами синхронизатора. При изменении его содержимого необходимо соблюдать осторожность. Меняя отдельные биты регистра, оставляйте значения остальных битов без изменения. Перед модификацией регистра CMR надо сбросить бит D1 в регистре сброса синхронизатора, переведя, таким образом, синхронизатор в режим синхронного сброса и остановки. D0 Бит определяет ширину символов в текстовых монохромных режимах с разрешением 720 пикселов по горизонтали. Если бит D0 равен нулю, то ширина матрицы символов составляет 9 пикселов, если единице - 8 пикселов. D1 Бит используется видеоадаптером EGA для определения числа циклов, отводимых центральному процессору, для доступа к видеопамяти. При D1 равном единице, процессор может получить три из каждых пяти циклов, а при D1 равном нулю - только один из пяти циклов. Остальные циклы используются адаптером для регенерации видеопамяти. D4-D2 Не используются. D5 Используется только видеоадаптерами VGA и SVGA. Если бит D5 равен единице, то экран монитора гаснет и центральный процессор получает монополию на доступ к видеопамяти. Это несколько ускоряет процесс обмена процессора с видеопамятью. D7-D6 Не используются. Ниже приведены значения регистра CMR, устанавливаемые BIOS при установке режима работы адаптера: Режим 00,01,04,05,0Dh 02,03,06,0Eh 0Fh,10h Содержимое регистра 0Bh 01 05 Регистр разрешения записи цветового слоя
(Color Plane Write Enable - CPWE) (индекс 2) При помощи данного регистра можно запретить запись данных в любые цветовые слои видеопамяти. На рисунке 4.8 показан механизм запрещения записи данных в отдельные слои видеопамяти. Рассмотрим процесс записи данных процессором в видеопамять: ПЕРВЫЙ ШАГ Процессор передает видеоадаптеру данные для записи в видеопамять. Они проходят через графический контроллер и попадают в синхронизатор. Графический контроллер выполняет над данными, записываемыми в видеопамять, операции, определяемые состоянием его регистров (смотри главу "Исполнение видеоадаптером операции записи" из раздела "Графический контроллер"). ВТОРОЙ ШАГ Синхронизатор записывает данные в видеопамять в соответствии с содержимым регистра разрешения записи цветового слоя. Регистр разрешения записи цветового слоя содержит четыре бита, управляющие записью в цветовые слои видеопамяти. Если бит этого регистра, управляющий цветовым слоем равен нулю, то данный цветовой слой не изменяется. Если бит регистра равен единице, то в данный слой видеопамяти записываются значения, поступившие от графического контроллера. \* MERGEFORMAT PICTURE._FIG_17.PCX;6";4.308";PCX Рисунок 4.8 Разрешение записи в цветовые слои Биты регистра разрешения записи цветового слоя имеют следующие значения: D0 Если бит D0 равен единице, то можно записывать данные в нулевой цветовой слой. D1 Если бит D1 равен единице, то можно записывать данные в первый цветовой слой. D2 Если бит D2 равен единице, то можно записывать данные в второй цветовой слой. D3 Если бит D3 равен единице, то можно записывать данные в третий цветовой слой. D7-D4 Не используются. При установке режима работы адаптера BIOS загружает в регистр CPWE следующие значения: Режим 0,1,2,3,4,5,7 6 D,E,F,10 Содержимое регистра 03 01 0Fh Регистр выбора знакогенератора (Character Generator Select Register - CGSR) (индекс 3) Видеоадаптер EGA позволяет загрузить в память четыре, а VGA и SVGA - восемь таблиц знакогенератора, каждая из которых определяет 256 символов. Одновременно могут использоваться символы одной или двух таблиц знакогенератора. Это позволяет одновременно отображать на экране монитора до 512 различных символов. Если разрешено одновременное использование двух различных таблиц знакогенератора, тогда бит D3 байта атрибутов указывает, какая таблица будет использоваться при отображении символа с этим атрибутом. Регистр выбора знакогенератора определяет два активных набора символов, расположенных во втором цветовом слое, символы которых могут одновременно отображаться на экране. Данный регистр используется только в текстовых режимах. D1-D0 Выбор первой активной таблицы знакогенератора. Эта таблица используется для вывода символа на экран, если бит D3 байта атрибутов символа содержит ноль. D3-D2 Выбор второй активной таблицы знакогенератора. Вторая таблица используется для вывода символа на экран, если бит D3 байта атрибутов символа содержит единицу. D4 Дополнительный бит, доступный на видеоадаптерах VGA и SVGA. Используется для выбора первой таблицы знакогенератора. D5 Дополнительный бит, доступный на видеоадаптерах VGA и SVGA. Используется для выбора второй таблицы знакогенератора. D7-D6 Не используются. Для выбора активных таблиц знакогенератора надо установить биты D0-D5 в соответствии со следующей таблицей: D5 D3 D2 Номер таблицы знакогенератора, используемой, если бит D3 байта атрибутов равен 1 D4 D1 D0 Номер таблицы знакогенератора, используемой если бит D3 байта атрибутов равен 0 0 0 0 Первая таблица знакогенератора 0 0 1 Вторая таблица знакогенератора 0 1 0 Третья таблица знакогенератора 0 1 1 Четвертая таблица знакогенератора 1 0 0 Пятая таблица знакогенератора (видеоадаптеры VGA и SVGA) 1 0 1 Шестая таблица знакогенератора (видеоадаптеры VGA и SVGA) 1 1 0 Седьмая таблица знакогенератора (видеоадаптеры VGA и SVGA) 1 1 1 Восьмая таблица знакогенератора (видеоадаптеры VGA и SVGA) Если нужна только одна активная таблица знакогенератора, то значения битов D5 D3 D2 и битов D4 D1 D0 должны совпадать. SYMBOL 119 \f "Wingdings" \s 10 \h Для выбора активных таблиц знакогенератора рекомендуется использовать соответствующую функцию BIOS. Регистр определения структуры памяти (Memory Mode Register - MMR) (индекс 4) Регистр инициализируется BIOS во время выбора режима работы видеоадаптера и определяет структуру видеопамяти в этом режиме. D0 Для видеоадаптера EGA бит D0 содержит единицу, при использовании в текстовом режиме функции выбора знакогенератора. Для адаптера VGA этот бит обычно сброшен в ноль. D1 Для видеоадаптера EGA бит D1 равен единице, если объем видеопамяти больше 64 Кбайт. D2 Если бит D2 содержит ноль, то доступ по четным адресам происходит к нулевому цветовому слою, а по нечетным - к первому. D7-D3 Не используются. При выборе режима работы адаптера, BIOS загружает в регистр CPWE следующие значения: Режим 0,1,2,3,7 4,5 6,0Dh,0Eh 0Fh,10h Содержимое регистра 03 02 06 00 Регистры графического контроллера Графический контроллер поддерживает обмен данными между центральным процессором и видеопамятью. При этом он может выполнять простейшие логические операции над данными записываемыми в видеопамять. В графических режимах работы видеоадаптера графический контроллер передает данные из цветовых слоев видеопамяти контроллеру атрибутов. Графический контроллер содержит девять регистров. Обращение к ним происходит через индексный порт с адресом 3CEh и порт данных с адресом 3CFh. Адаптер EGA имеет два дополнительных порта с адресами 3CAh и 3CCh, используемых при инициализации видеоадаптера. Список регистров представлен в следующей таблице: Индекс регистра Регистр графического контроллера 0 Регистр установки/сброса (Set/Reset Register - SRR) 1 Регистр разрешения установки/сброса (Set/Reset Enable Register - SRER) 2 Регистр сравнения цветов (Color Compare Register - CCR) 3 Регистр циклического сдвига и выбора функции (Data Rotate Function Select - DRFS) 4 Регистр выбора читаемого слоя (Read Plane Select Register - RPSR) 5 Регистр режима работы (Mode Register - MDR) 6 Регистр смешанного назначения (Miscellaneous Register - MIR) 7 Регистр маскирования цветовых слоев (Color Don't Care Register - CDCR) 8 Регистр битовой маски (Bit Mask Register - BMR) На рисунке 4.9, демонстрируются функции, выполняемые графическим контроллером. Рассмотрим функционирование графического адаптера. Байт, записываемый центральным процессором в видеопамять (11100001b), поступает в графический контроллер. В соответствии со значением регистра циклического сдвига и выбора функции, происходит циклический сдвиг на один бит содержимого байта, записываемого в видеопамять. Полученный результат складывается по логике ИЛИ с содержимым регистров-защелок. Вы можете применить другие булевы функции - И, ИСКЛЮЧАЮЩЕЕ ИЛИ. Используемая булева функция выбирается регистром циклического сдвига и выбора функции. Дальнейшие преобразования происходят в соответствии со значениями регистра разрешения установки/сброса и регистра установки/сброса: SYMBOL 119 \f "Wingdings" \s 10 \h Если бит регистра разрешения установки/сброса, управляющий данным цветовым слоем, равен нулю, то байт, записываемый в видеопамять не изменяется. SYMBOL 119 \f "Wingdings" \s 10 \h Если бит регистра разрешения установки/сброса, управляющий данным цветовым слоем, равен единице, то в него записывается байт, все биты которого устанавливаются в соответствии со значением регистра установки/сброса для данного цветового слоя. Затем в зависимости от состояния регистра битовой маски происходит запись данных в видеопамять: SYMBOL 119 \f "Wingdings" \s 10 \h Если бит регистра битовой маски содержит единицу, то соответствующие биты для каждого из цветовых слоев поступают из видеопамяти. SYMBOL 119 \f "Wingdings" \s 10 \h Если бит регистра битовой маски содержит ноль, то соответствующие биты для каждого из цветовых слоев поступают от регистров-защелок. \* MERGEFORMAT PICTURE._FIG_40.PCX;6";4.308";PCX Рисунок 4.9 Функции графического контроллера Теперь рассмотрим регистры графического контроллера более подробно. Регистр установки/сброса
(Set/Reset Register - SRR) (индекс 0) Регистр SRR совместно с регистром разрешения установки/сброса (Set/Reset Enable Register), управляет записью данных в видеопамять. Возможности использования регистра SRR разъясняются при описании регистра разрешения установки/сброса. Приведем формат регистра установки/сброса: D0 Данные, записываемые в цветовой слой 0. D1 Данные, записываемые в цветовой слой 1. D2 Данные, записываемые в цветовой слой 2. D3 Данные, записываемые в цветовой слой 3. D7-D4 Зарезервировано. По умолчанию во все биты регистра записываются нулевые значения. Регистр разрешения установки/сброса
(Set/Reset Enable Register - SRER) (индекс 1) Регистр разрешения установки/сброса позволяет при записи в видеопамять для одних цветовых слоев использовать данные от центрального процессора, а для других - из регистра установки/сброса (рис. 4.10). Если биты регистра, управляющие цветовыми слоями, содержат единицы, то при выполнении операции записи, в соответствующие цветовые слои записывается информация из регистра установки/сброса. В остальные слои видеопамяти заносятся данные процессора. Теперь приведем формат регистра разрешения установки/сброса: D0 Разрешение использования данных из регистра установки/сброса для цветового слоя 0. D1 Разрешение использования данных из регистра установки/сброса для цветового слоя 1. D2 Разрешение использования данных из регистра установки/сброса для цветового слоя 2. D3 Разрешение использования данных из регистра установки/сброса для цветового слоя 3. D7-D4 Зарезервировано. По умолчанию во все биты регистра записываются нулевые значения. Заметим, что возможность использования регистров установки/сброса можно реализовать только в нулевом режиме записи. Режим записи устанавливается регистром режима работы графического контроллера (Mode Register, индекс 5). В нулевом режиме записи, если запрещено выполнение операции маскирования пикселов (регистр битовой маски содержит значение 0FFh), то каждый байт, записываемый процессором в видеопамять определяет 8 пикселов в одном или нескольких цветовых слоях. Рассмотрим на рисунке 4.10 применение регистров установки/сброса. Пусть графический контроллер находится в нулевом режиме работы, и регистр битовой маски равен 0FFh (используются только данные от процессора). В этом случае можно использовать регистры установки/сброса. Допустим, что после преобразования данных, записываемых процессором в видеопамять, в соответствии со значением регистра циклического сдвига и выбора функций, данные имеют следующий вид: байт 11110000b передается в третий слой видеопамяти, байт 00000011b передается во второй слой видеопамяти, байт 00110011b передается в первый слой видеопамяти, байт 00110011b передается в нулевой слой видеопамяти. Данные, записываемые в видеопамять зависят от значения регистра разрешения установки/сброса. Биты D3 и D0, регистра разрешения установки/сброса равны нулю, поэтому в третий слой и нулевой слой видеопамяти данные заносятся без изменения. Биты D2 и D1 регистра разрешения установки/сброса равны единице, значит во второй и первый слои видеопамяти записываются данные в соответствии со значением битов D2 и D1 регистра установки/сброса. То есть во второй слой записывается байт 00000000b, а в первый - 11111111b. \* MERGEFORMAT PICTURE._FIG_24.PCX;6";4.308";PCX Рисунок 4.10 Использование регистров установки/сброса Регистр сравнения цветов
(Color Compare Register - CCR) (индекс 2) Регистр CCR можно использовать для поиска на экране пикселов с определенным цветом. Без использования регистра CCR за один цикл чтения видеопамяти процессор может считать данные только из одного цветового слоя. Программирование регистра CCR позволяет за один цикл чтения прочитать все четыре цветовых слоя, сравнить считанные значения с искомыми и возвратить результат. Ниже представлен формат регистра сравнения цветов: D0 Искомая величина для нулевого цветового слоя. D1 Искомая величина для первого цветового слоя. D2 Искомая величина для второго цветового слоя. D3 Искомая величина для третьего цветового слоя. D7-D4 Не используются. После выполнения BIOS установки режима работы видеоадаптера все биты регистра содержат нулевые значения. Операция поиска пикселов данного цвета иллюстрируется рисунком 4.11. \* MERGEFORMAT PICTURE._FIG_25.PCX;6";4.308";PCX Рисунок 4.11 Использование регистра CCR Как видно из рисунка, в случае совпадения сравниваемых битов соответствующий бит результата равен единице. Перед использованием регистра CCR для выполнения операции поиска пикселов определенного цвета необходимо установить регистр режима работы (Mode Register - MDR) и регистр маскирования цветовых слоев (Color Don't Care Register - CDCR), описанные ниже. Регистр циклического сдвига и выбора функции
(Data Rotate Function Select - DRFS) (индекс 3) Регистр DRFS выполняет две различные функции, отраженные в его названии: SYMBOL 119 \f "Wingdings" \s 10 \h Циклический сдвиг данных, записываемых центральным процессором в видеопамять. Чтобы разрешить операцию циклического сдвига надо использовать нулевой режим записи. SYMBOL 119 \f "Wingdings" \s 10 \h Выполнение логических операций над данными записываемыми в видеопамять и содержимым регистров-защелок. D2-D0 Счетчик сдвига. D4-D3 Биты выбора логической функции. D7-D5 Не используются. После выполнения BIOS установки режима работы видеоадаптера биты регистра DRFS содержат нулевые значения. При выполнении операции циклического сдвига биты счетчика сдвига могут иметь следующие значения: D2 D1 D0 Данные циклически сдвигаются вправо на следующее количество битов 0 0 0 Ноль, сдвиг не происходит 0 0 1 Один бит 0 1 0 Два бита 0 1 1 Три бита 1 0 0 Четыре бита 1 0 1 Пять бит 1 1 0 Шесть бит 1 1 1 Семь бит Во время выполнения процессором операции чтения из видеопамяти одновременно происходит запись данных из всех четырех цветовых слоев (по считываемому адресу) в регистры-защелки. Каждому цветовому слою видеопамяти соответствует один 8-битовый регистр-защелка. Когда процессор начнет записывать данные в видеопамять (возможно уже по другому адресу), адаптер может комбинировать их с данными из регистров-защелок. Вид выполняемой логической операции будет зависеть от содержимого битов выбора логической функции: D4 D3 Логическая операция 0 0 Запись не модифицированных данных 0 1 И 1 0 ИЛИ 1 1 ИСКЛЮЧАЮЩЕЕ ИЛИ Следует отметить, что операция циклического сдвига выполняется до выполнения логических функций. Регистр DRFS можно использовать для быстрого копирования областей видеопамяти с возможной их модификацией. Рисунок 4.12 иллюстрирует выполнение логической операции ИЛИ. Регистр циклического сдвига и выбора функции содержит число 00010000b. После операции чтения данные из всех четырех слоев записываются в регистры-защелки. Затем выполняется операция записи. Данные процессора в соответствии с состоянием регистра циклического сдвига и выбора функции складываются по логике ИЛИ со значением регистров-защелок и помещаются в видеопамять. \* MERGEFORMAT PICTURE._FIG_26.PCX;6";4.308";PCX Рисунок 4.12 Логические операции и операция циклического сдвига SYMBOL 77 \f "Wingdings" Логические операции можно выполнять только в нулевом и втором режиме записи. Регистр выбора читаемого слоя
(Read Plane Select Register - RPSR) (индекс 4) Регистр определяет номер цветового слоя видеопамяти, из которого процессор может читать данные. При выполнении операции сравнения цветов значение этого регистра безразлично. Приведем формат регистра выбора читаемого слоя. Биты Описание D1-D0 Номер читаемого цветового слоя видеопамяти D7-D2 Не используется При установке режима работы видеоадаптера BIOS заполняет все биты регистра нулями, что соответствует нулевому цветовому слою. Чтение центральным процессором данных из видеопамяти иллюстрируется на рисунке 4.13. На этом рисунке регистр выбора читаемого слоя разрешает чтение второго слоя видеопамяти. Таким образом, при чтении процессором данных из видеопамяти, процессор считывает данные только из второго слоя. Остальные слои видеопамяти недоступны для чтения процессором, пока вы не измените состояние регистра читаемого слоя. \* MERGEFORMAT PICTURE._FIG_41.PCX;6";4.308";PCX Рисунок 4.13 Операция чтения видеопамяти Регистр режима работы
(Mode Register - MDR) (индекс 5) Регистр управляет несколькими функциями графического контроллера. В частности он управляет режимом записи в видеопамять и режимом сравнения цветов (см. регистр сравнения цветов графического контроллера). Биты Описание D1-D0 Режим записи D2 Не используется D3 Разрешение режима сравнения цветов D4 Четный/нечетный режим D5 Режим регистра сдвига D6 Управление режимом VGA с 256 цветами (режим номер 13h) D7 Не используется Ниже подробно рассмотрены отдельные биты регистра MDR. Изменение битов D4-D7, может привести к потере изображения на экране монитора. Обычно эти биты загружаются только при установке режима работы видеоадаптера. D1, D0 Данные биты устанавливают режим записи в видеопамять. Вы можете выбрать один из трех режимов записи: D1 D0 Номер режима Режим записи 0 0 0 Режим непосредственной записи 0 1 1 Использование для записи регистров-защелок 1 0 2 Заполнение N-ого цветового слоя битом номер N из данных, записываемых процессором 1 1 - Не используется SYMBOL 119 \f "Wingdings" \s 10 \h Режим 0 (рис. 4.14). Режим непосредственной записи. Процессор имеет доступ к видеопамяти. Видеоадаптер может выполнять следующие операции: установка/сброс, циклический сдвиг, вызов логических функций. В этом режиме также возможно использование регистра битовой маски. \* MERGEFORMAT PICTURE._FIG_27.PCX;6";4.308";PCX PICTURE._FIG_28.PCX;6";4.308";PCX Рисунок 4.14 Режим записи 0 SYMBOL 119 \f "Wingdings" \s 10 \h Режим 1 (рис. 4.15). Режим записи, использующий регистры-защелки. При чтении данных из видеопамяти происходит запись восьми битов из каждого цветового слоя в регистры-защелки. Затем, при выполнении операции записи, содержимое регистров-защелок может быть записано обратно в видеопамять, но уже по другому адресу. Этот режим можно использовать для быстрого копирования данных из одной области видеопамяти в другую. \* MERGEFORMAT PICTURE._FIG_27.PCX;6";4.308";PCX PICTURE._FIG_28.PCX;6";4.308";PCX Рисунок 4.15 Режим записи 1 SYMBOL 119 \f "Wingdings" \s 10 \h Режим 2 (рис. 4.16). В режиме 2 происходит заполнение N-ого цветового слоя битом с порядковым номером N из байта данных, переданного процессором видеоадаптеру для записи. Содержимое четырех старших битов записываемого байта (то есть битов D4-D7) значения не имеет. \* MERGEFORMAT PICTURE._FIG_27.PCX;6";4.308";PCX PICTURE._FIG_28.PCX;6";4.308";PCX Рисунок 4.16 Режим записи 2 D3 Бит D3 управляет режимом сравнения цветов (см. регистр сравнения цветов графического контроллера). Для перевода видеоадаптера в режим сравнения цветов бит D3 должен содержать единицу. Остальные биты регистра модифицировать не рекомендуется. D4 Бит D4 устанавливается в текстовых режимах. В этом случае доступ по четным адресам происходит к четным цветовым слоям, а по нечетным адресам - к нечетным цветовым слоям видеопамяти (см. видеопамять в текстовых режимах). D5 Бит D5 используется в режимах видеоадаптера номер 4 и 5 для обработки видеоданных в формате "два бита на пиксел". D6 Бит D6 используется видеоадаптерами VGA и SVGA в режиме с 256 цветами (режим 13h). При установке режима работы видеоадаптера BIOS загружает в регистр MDR следующие значения, в зависимости от режима работы видеоадаптера: Режим 0,1,2,3,7,F,10 4,5 6,D,E Содержимое регистра 10h 30h 00 Регистр смешанного назначения
(Miscellaneous Register - MIR) (индекс 6) Регистр управляет различными характеристиками видеоадаптера. В результате ошибочной модификации регистра возможна неправильная работа некоторых функций BIOS и конфликты между видеоадаптерами в системе с двумя мониторами. D0 Бит разрешения графического режима. Бит должен содержать 1 для графического и 0 для текстового режима. В графическом режиме запрещается генерация символов и разрешается адресация к отдельным пикселам. D1 Используется видеоадаптерами EGA, имеющими 64 Кбайт памяти. Если бит D1 установлен, то четыре слоя видеопамяти по 16 Кбайт каждый объединяются в два слоя по 32 Кбайт. D3-D2 Биты D3 и D2 устанавливают начальный и конечный адреса, на которые отображается видеопамять адаптера EGA:
D3 D2 Адреса видеопамяти
0 0 A000:0000h-B000:FFFFh
0 1 A000:0000h-A000:FFFFh
1 0 B000:0000h-B000:7FFFh
0 1 B800:0000h-B000:FFFFh D7-D4 Не используются. При установке режима работы видеоадаптера BIOS загружает в регистр MIR следующие значения, в зависимости от режима работы видеоадаптера: Режим 3 7 F 10 Содержимое регистра Eh Ah 07 05 Регистр маскирования цветовых слоев
(Color Don't Care Register - CDCR) (индекс 7) Регистр используется в режиме сравнения цветов (см. регистр сравнения цветов - CCR). Если какие-либо биты D3-D0 содержат ноль, то при операции сравнения цветов соответствующие цветовые слои в рассмотрение не принимаются. D0 Управление нулевым цветовым слоем. D1 Управление первым цветовым слоем. D2 Управление вторым цветовым слоем. D3 Управление третьим цветовым слоем. D7-D4 Не используются. При установке режима работы в регистр заносятся следующие значения: Режим 3 7 F 10 Содержимое регистра 00 00 0Fh 0Fh Регистр битовой маски
(Bit Mask Register - BMR) (индекс 8) Регистр управляет записью данных в видеопамять. Если бит регистра BMR содержит ноль, то соответствующий бит будет записываться в видеопамять из регистра-защелки. В противном случае данный бит поступает от центрального процессора (рис. 4.17). Регистр BMR используется только в нулевом режиме записи. \* MERGEFORMAT PICTURE._FIG_29.PCX;6";4.308";PCX Рисунок 4.17 Использование регистра битовой маски Напомним, что занести данные в регистр-защелку можно, если выполнить операцию чтения из видеопамяти. Во время выполнения операции чтения в каждый регистр-защелку записывается один байт из соответствующего цветового слоя видеопамяти. По умолчанию, во всех режимах регистр BMR хранит число 0FFh. Регистры контроллера атрибутов Контроллер атрибутов управляет цветовыми характеристиками изображений. Контроллер атрибутов содержит двадцать один регистр. Названия регистров перечислены в следующей таблице: Индекс Регистры контроллера атрибутов 0 - 0Fh Шестнадцать регистров цветовой палитры (Color Palette Register's - CPR) 10h Регистр управления режимом (Mode Control Register - MCR) 11h Регистр цвета рамки экрана (Screen Border Color Register - SBCR) 12h Регистр разрешения цветового слоя (Color Plane Enable Register - CPER) 13h Регистр горизонтального панорамирования (Horizontal Panning Register - HPR) 14h Регистр выбора цвета (Color Select Register - CSR) Доступ ко всем регистрам осуществляется через единственный порт с адресом 3C0h (в отличие от предыдущих рассмотренных нами регистров). Этот порт совмещает в себе функции индексного порта и порта данных, регулируемые внутренним триггером. Триггер переключается каждый раз записи данных в порт. В зависимости от состояния триггера записываемые данные воспринимаются либо как индекс регистра, либо как данные для обмена с регистром. Установить триггер в исходное состояние можно, выполнив чтение из порта 3BAh для монохромного режима или из порта 3DAh - для цветного режима работы видеоадаптера. После установки триггера в исходное состояние данные, записываемые в регистр 3C0h, будут восприниматься, как индекс регистра. Регистры цветовой палитры (0-15)
(Color Palette Register's - CPR) Четыре цветовых слоя видеоадаптера EGA позволяют закодировать 16 различных цветов, однако улучшенный цветной монитор обеспечивает возможность отображения 64 цветов. С помощью 16 регистров цветовой палитры можно выбрать любые 16 цветов из 64 возможных. Эти цвета будут использоваться для отображения на экране. Если к видеоадаптеру EGA подключен улучшенный цветной монитор, то каждый регистр цветовой палитры содержит шесть битов, соответствующих шести линиям управления монитора. Цветной и монохромный мониторы имеют меньшее число линий управления и регистр цветовой палитры также имеет другой формат. Форматы регистров цветовой палитры для различных мониторов приведены ниже: Улучшенный цветной монитор D0 Голубой. D1 Зеленый. D2 Красный. D3 Второй голубой. D4 Второй зеленый. D5 Второй красный. D7-D6 Не используются. Цветной монитор D0 Голубой. D1 Зеленый. D2 Красный. D3 Не используется. D4 Интенсивность. D7-D5 Не используются. Монохромный монитор D2-D0 Не используются. D3 Видео выход. D4 Интенсивность. D7-D5 Не используются. Монитор VGA D0 P0 D1 P1 D2 P2 D3 P3 D4 P4 D5 P5 D7-D6 Не используются. Регистр управления режимом
(Mode Control Register - MCR) (индекс 10h) Регистр управления режимом управляет контроллером атрибутов. D0 Бит D0 содержит ноль для текстовых режимов, единицу - для графических. Бит определяет метод интерпретации атрибутов. D1 Бит D1 определяет тип атрибутов. Для монохромных режимов он должен быть равен единице, а для режимов - нулю. D2 Бит используется в монохромных режимах с разрешением по горизонтали 720 пикселов для расширения горизонтального размера матриц символов псевдографики с 8 до 9 пикселов. Если бит D2 равен 1, то девятый пиксел в каждой строке будет повторять восьмой. В противном случае девятый пиксел отображается цветом фона. D3 Бит D3 управляет назначением седьмого бита в байте атрибутов. Если бит установлен, то бит D7 байта атрибутов управляет миганием символа. Если бит D3 равен нулю, то - интенсивностью фона. D4 Не используется. D5 Доступен только для видеоадаптеров VGA и SVGA. Совместно с регистром разделения экрана монитора (регистр контроллера ЭЛТ) бит D5 управляет горизонтальной сверткой экрана. При установке бита D5 запрещается горизонтальная свертка стационарной части экрана. D6 Бит D6 используется только видеоадаптерами VGA и SVGA. Бит должен быть равен нулю для режима с 256 цветами (режим 13h). D7 Доступен только для видеоадаптеров VGA и SVGA. Выбор источника сигнала для видеовыходов Р4 И Р5. Если D7 равен нулю, то линии Р4 и Р5 управляются регистрами палитры. В противном случае сигналы на линии Р4 и Р5 поступают из битов D0 и D1 регистра выбора цветов. По умолчанию регистр содержит следующие значения: Режим 0,1,2,3 4,5,6,D,E,10 7 F Содержимое регистра 08 01 0Eh 0Bh Регистр цвета рамки экрана
(Screen Border Color Register - SBCR) (индекс 11) В текстовых режимах работы видеоадаптеров регистр SBCR определяет цвет рамки, расположенной вокруг текста. Назначение битов регистра соответствует регистрам цветовой палитры. По умолчанию регистр цвета рамки содержит нулевые значения для всех режимов работы. Операция установки цвета рамки не работает на большинстве адаптеров EGA. Регистр разрешения цветового слоя
(Color Plane Enable Register - CPER) (индекс 12) D3-D0 Биты разрешения цветовых слоем. Если бит равен нулю, то данные из соответствующего цветового слоя не поступают в регистры цветовой палитры. Таким образом, достигается эффект маскирования отдельных цветовых слоев. D5-D4 Используются вместе с диагностическими битами регистра состояния 1 для чтения регистров палитры. D7-D6 Не используются. При установке режима работы видеоадаптера BIOS записывает в регистр следующие значения: Режим 0,1,2,3,7,D,E 4,5 6 F,10 Содержимое регистра 0Fh 03 03 01 05 Регистр горизонтального панорамирования
(Horizontal Panning Register - HPR) (индекс 13) Регистр позволяет сдвинуть изображение на экране в горизонтальном направлении. При использовании регистра HPR совместно с регистром начального адреса контроллера атрибутов можно сдвигать изображение на любое количество пикселов. Формат регистра горизонтального панорамирования представлен ниже: D3-D0 Биты определяют величину горизонтального сдвига: Биты Величина сдвига содержимого экрана (в пикселах) D3 D2 D1 D0 Монохромный текстовый режим Режим 13h Остальные режимы 0 0 0 0 8 0 0 0 0 0 1 0 - 1 0 0 1 0 1 1 2 0 0 1 1 2 - 3 0 1 0 0 3 2 4 0 1 0 1 4 - 5 0 1 1 0 5 3 6 0 1 1 1 6 - 7 1 0 0 0 7 - - 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 - - - D7-D4 Не используются. По умолчанию для всех режимов работы видеоадаптера регистр горизонтального панорамирования содержит нулевые значения для всех битов. На рисунке 8.18 иллюстрируется операция горизонтального сдвига содержимого экрана при различных значениях регистра HPR. На левой части рисунка регистр горизонтального панорамирования содержит ноль, а на правой части рисунка значение регистра увеличено до трех. Изображение на экране сдвигается на три пиксела влево. \* MERGEFORMAT PICTURE._FIG_30.PCX;6";4.308";PCX Рисунок 4.18 Горизонтальный сдвиг экрана Программа SCRSPLIT позволяет перемещать содержимое экрана по горизонтали и вертикали. Исходный текст программы представлен в листинге 4.11. Листинг 4.11. Файл SCRSPLIT.C // Смещение содержимого экрана по горизонтали и вертикали
#include "sysgraph.h"
#include "stdio.h"
#include "stdlib.h"
#include "graph.h"
#include "sysp.h"
#include "dos.h"
void HorScroll(unsigned, unsigned);
void VerScroll(unsigned);
void SetColumn(unsigned char);
void main(void) {
struct videoconfig vc;
unsigned char i,j;
// выбираем текстовый режим работы видеоадаптера,
// принятый по умолчанию
_setvideomode(_DEFAULTMODE);
// устанавливаем логическую ширину экрана в 100 символов
SetColumn(100);
// отображаем на экране монитора 24 строки текста
for(i = 0; i "24; i++)
printf("\ntext text text");
// производим горизонтальное смещение экрана
// на i пикселов при каждом нажатии на клавиатуру
for(i = 0; i "13; i++) {
getch();
HorScroll(i,8);
}
// производим вертикальное смещение экрана
// на i пикселов при каждом нажатии на клавиатуру
for(i = 0; i "13; i++) {
getch();
VerScroll(i);
}
getch();
_setvideomode(_DEFAULTMODE);
} Сдвиг изображения на экране монитора выполняют функции HorScroll и VerScroll. Функция HorScroll сдвигает изображение в горизонтальном направлении, а функция VerScroll в вертикальном. Исходный текст функций представлен в листинге 4.12. Листинг 4.12. Файл SPLIT.ASM /**
*.Name HorScroll
 
 

 * 

*.Title Горизонтальный сдвиг содержимого экрана.


  *  


*.Descr Функция смещает содержимое экрана влево на определенное
* число пикселов.


  *  


*.Proto void HorScroll(unsigned offset, unsigned wide)


  *  


*.Params unsigned offset - величина смещения в пикселах,


  *  


* unsigned wide - ширина символов (8 или 9).


  *  


*.Return Не используется.


  *  


*.Sample scroll.c


  **/  


void HorScroll(unsigned offset, unsigned wide) {
unsigned start_addr_reg, panning_reg;
div_t res;
res = div(offset,wide);
start_addr_reg = res.quot;
panning_reg = (wide - 9)?
((res.rem - 0)? 8: res.rem - 1 ): res.rem;
_asm {
push ds
; вычисляем адрес регистра состояния 1 (3BAh/3DAh)
xor ax,ax
mov es,ax
mov dx,es:[463h]
add dx,6
; ожидаем начало обратного вертикального хода луча
in al,dx
nop
nop
test al,08h
jz wait_on
wait_off:
in al,dx
nop
nop
test al,08h
jnz wait_off
wait_on:
in al,dx
nop
nop
test al,08h
jz wait_on
; вычисляем адрес порта индексного регистра контроллера ЭЛТ
sub dx,6
; выбираем для доступа младший байт регистра начального адреса
mov al,0Dh
out dx,al
; вычисляем адрес порта регистра данных контроллера ЭЛТ
inc dx
; устанавливаем новый начальный адрес
mov ax,start_addr_reg
out dx,al
; снова получаем адрес порта регистра состояния 1
add dx,5
; сбрасываем внутренний триггер контроллера атрибутов, управляющий
; адресацией его регистров
in al,dx
nop
nop
; выбираем регистр горизонтального панорамирования
mov dx,3C0h
mov al,13h
out dx,al
mov ax,panning_reg
out dx,al
pop ds
}
}
/**
*.Name VerScroll


  *  


*.Title Вертикальный сдвиг содержимого экрана.


  *  


*.Descr Функция смещает содержимое экрана вверх на определенное
* число пикселов.


  *  


*.Proto void VerScroll(unsigned offset)


  *  


*.Params unsigned offset - величина смещения в пикслах.


  *  


*.Return Не используется.
 
 

 * 

*.Sample scroll.c


  **/  


void VerScroll(unsigned offset) {
unsigned start_addr_reg, preset_row_reg;
div_t res;
BIOS_VAR _far *bios_var_ptr;
bios_var_ptr = (BIOS_VAR _far *) FP_MAKE(0x0000, 0x0410);
res = div(offset,bios_var_ptr -" wCharHigh);
start_addr_reg = res.quot * (bios_var_ptr -" wColumns);
preset_row_reg = res.rem;
_asm {
push ds
; вычисляем адрес регистра состояния 1 (3BAh/3DAh)
xor ax,ax
mov es,ax
mov dx,es:[463h]
add dx,6
; ожидаем начало обратного вертикального хода луча
in al,dx
nop
nop
test al,08h
jz wait_on
wait_off:
in al,dx
nop
nop
test al,08h
jnz wait_off
wait_on:
in al,dx
nop
nop
test al,08h
jz wait_on
; вычисляем адрес порта индексного регистра контроллера ЭЛТ
sub dx,6
; модифицируем младший байт регистра начального адреса
mov al,0Dh
out dx,al
inc dx
mov ax,start_addr_reg
out dx,al
dec dx
; модифицируем старший байт регистра начального адреса
mov al,0Ch
out dx,al
inc dx
mov al,ah
out dx,al
; вычисляем адрес порта регистра состояния 1
add dx,5
; ожидаем вертикальный обратный ход луча
wait_next:
in al,dx
nop
nop
test al,08h
jz wait_next
; определяем адрес порта индексного регистра контроллера ЭЛТ
sub dx,6
; устанавливаем регистр предустановки линии сканирования
mov al,8
out dx,al
mov ax,preset_row_reg
inc dx
out dx,al
pop ds
}
}
/**
*.Name SetColumn


  *  


*.Title Установка логической ширины экрана.


  *  


*.Descr Функция устанавливает логическую ширину экрана.


  *  


*.Proto void SetColumn(unsigned char col)


  *  


*.Params unsigned char col - логическая ширина экрана (в символах).


  *  


*.Return Не используется.


  *  


*.Sample scroll.c


  **/  


void SetColumn(unsigned char col) {
_asm {
xor ax,ax
mov es,ax
; получаем адрес порта индексного регистра
; контроллера ЭЛТ (3B4h/3D4h)
mov dx,es:[463h]
; выбираем для обмена регистр логической ширины экрана
mov al,13h
out dx,al
; вычисляем адрес порта регистра данных контроллера ЭЛТ (3B5h/3D5h)
inc dx
; модифицируем переменную BIOS, содержащую число символов в строке
mov al,col
mov es:[44Ah],al
; регистр логической ширины экрана в текстовых режимах содержит
; смещение между соседними строками текста в словах
shr al,1
out dx,al
}
} Регистр выбора цвета
(Color Select Register - CSR) (индекс 14) Регистр используется видеоадаптерами VGA и SVGA для управления цветом. D0 Цвет Р4. D1 Цвет Р5. Данные биты могут использоваться вместо линий Р5 и Р4 соответственно (см. регистры палитры и рис. 6.18). D2 Цвет Р6. D3 Цвет Р7. Биты используются контроллером атрибутов в качестве двух старших битов, передаваемых ЦАП (рис. 6.18). В режиме 13h биты D2 и D3 не используются. D7-D4 Не используются. Регистры цифро-аналогового преобразователя VGA Видеоадаптеры VGA и SVGA предназначены для подключения к аналоговым мониторам, имеющим три раздельных видеовхода. Сигнал на каждом из них управляет, соответственно, интенсивностью красного, зеленого и синего цвета изображения. Аналоговое напряжение для монитора формируется из двоичной цветовой информации при помощи трех ЦАП. Цветовая 8-битовая информация, поступающая от контроллера атрибутов (рис. 4.19), преобразуется согласно таблице цветов в три 6-битовые сигнала для трех ЦАП. Такая схема позволяет одновременно отображать на экране 256 различных цветов, каждый из которых можно отдельно выбрать из 2 6+6+6 = 2 18 = 262144 возможных цветов. \* MERGEFORMAT PICTURE._FIG_31.PCX;6";4.308";PCX Рисунок 4.19 Схема управления цветами видеоадаптера VGA Таблица цветов фактически является набором из 256 18-битовых регистров. Используя регистры ЦАП, можно получить доступ для чтения и для записи к каждому регистру таблицы цветов. ЦАП видеоадаптера VGA управляется пятью регистрами, перечисленными в следующей таблице: Адрес Регистр 3C6h Регистр маскирования пикселов (Pixel Mask Register - PMR) 3C7h Регистр состояния ЦАП (для чтения) (DAC State Register - DAC_SR) 3C7h Индекс читаемого регистра таблицы цветов (для записи) (Look-up Table Read Index Register - LTRIR) 3C8h Индекс записываемого регистра таблицы цветов (Look-up Table Write Index Register - LTWIR) 3C9h Регистр данных таблицы цветов (Look-up Table Data Register - LTDR) Регистр маскирования пикселов
(Pixel Mask Register - PMR) Фирма IBM в руководстве видеоадаптера VGA предупреждает, что доступ к регистру нежелателен. В противном случае могут разрушиться данные в таблице цветов. Регистр состояния ЦАП
(DAC State Register - DAC_SR) Регистр адресуется при помощи порта с адресом 3C7h и доступен только для чтения. Прочитав данные из регистра, можно определить, доступны регистры цветовой таблицы для чтения или же они доступны для записи. D1-D0 Если биты D0 D1 содержат двоичное число 11b, то регистры цветовой таблицы доступны для записи, если D0 D1 содержат двоичное число 00b (шестнадцатиричное 0), то регистры цветовой таблицы доступны для чтения. D7-D2 Не используются. Индекс читаемого регистра таблицы цветов
(Look- up Table Read Index Register -LTRIR) Этот индексный регистр доступен через порт 3C7h только для записи. Запись в данный регистр индекса элемента цветовой таблицы позволяет прочитать его через регистр данных цветовой таблицы. D7-D0 Индекс регистра таблицы цветов (0-255). Данные из регистров таблицы цветов читаются через порт 3C9h, как три 6-битовых числа. После чтения третьего числа значение индексного регистра (LTRIR) автоматически увеличивается на единицу, что позволяет прочитать всю таблицу цветов, загрузив регистр индекса только один раз. Во время операций чтения или записи таблицы цветов прерывания должны быть запрещены. Индекс записываемого регистра таблицы цветов
(Look- up Table Write Index Register -LTWIR) После записи в регистр LTWIR индекса регистра таблицы цветов можно записать в него новое значение через регистр данных таблицы цветов (см. ниже). D7-D0 Индекс регистра таблицы цветов (0-255). Данные записываются в регистры таблицы цветов через порт 3C9h, как три 6-битовых числа. После записи третьего числа значение индексного регистра (LTWIR) автоматически увеличивается на единицу, что позволяет прочитать таблицу цветов, загрузив регистр индекса только один раз. Регистр данных таблицы цветов
(Look- up Table Data Register -LTDR) Регистр используется для получения доступа к регистрам таблицы цветов. Для чтения и записи одного элемента таблицы цветов необходимо три раза прочитать (записать) содержимое регистра данных. При этом каждый раз считывается (записывается) шесть очередных битов. Первые шесть битов отвечают за интенсивность красного, вторые - зеленого и третьи - синего цвета. Нельзя прерывать цикл чтения регистров таблицы цветов, состоящий из трех операций чтения, выполнением операции записи в другой регистр таблицы и наоборот. Во время доступа к регистру LTDR прерывания должны быть запрещены. Между операциями доступа к регистрам таблицы цвета необходимо выдержать временной интервал не менее 240 наносекунд. D5-D0 Данные для обмена с регистрами таблицы цветов. D7-D6 Не используется. Программа VGA256 (листинг 4.13) записывает новые значения в таблицу цветов непосредственно через регистры цифро-аналогового преобразователя VGA. На экране монитора отображается пять вертикальных полос различного цвета. Каждая полоса состоит из 64 вертикальных линий. Интенсивность цвета этих линий плавно уменьшается слева на право. Листинг 4.13. Файл VGA256.C #include "stdio.h"
#include "conio.h"
#include "sysp.h"
#include "sysgraph.h"
#include "dos.h"
// Описания функций
int main( void );
void SetVideoMode( unsigned char );
void Hello(void);
// Функция SetVgaDAC определена в файле DACTABLE.ASM
void __pascal __far SetVgaDAC(unsigned, unsigned);
//- ____________________ =
// Главная функция
//- ____________________ =
int main( void )
{
RGB color_table[256];
int error, x_num, y_num;
unsigned i, j, iii;
unsigned seg_table,off_table;
unsigned char far *ptr;
// Записываем в массив color_table новые значения для
// регистров таблицы цветов
for(j = 0; j "4; j++) {
for(i = 0; i "64; i++) {
(color_table[i+j*64]).red =
(j - 0)? i: 0;
(color_table[i+j*64]).green =
(j - 1)? i: (j - 3)? i: 0;
(color_table[i+j*64]).blue =
(j - 2)? i: (j - 3)? i: 0;
}
}
// Устанавливаем режим видеоадаптера номер 13h (256 цветов)
// данный режим поддерживается только VGA и Super VGA
SetVideoMode( 0x13 );
// Определяем сегмент и смешение массива color_table
ptr = (unsigned char far*) color_table[0];
seg_table = FP_SEG(ptr);
off_table = FP_OFF(ptr);
// Загружаем новые значения в регистры таблицы цветов
SetVgaDAC(seg_table,off_table);
// Записываем в ptr указатель на начало видеопамяти
ptr = (unsigned char far*) (FP_MAKE(0xA000, 0x0));
// Выводим на экран вертикальные линии различного цвета,
// процессор записывает данные непосредственно в видеопамять
for(y_num = 0; y_num "200; y_num++) {
for(x_num = 0; x_num "320; x_num++) {
*ptr = (unsigned char) x_num;
ptr++;
}
}
// Ожидаем нажатие на клавишу
getch();
// Плавно гасим изображение на экране, уменьшая значения
// регистров таблицы цветов
for(i=0;i "320;i++){
for(iii=0;iii "256;iii++) {
(color_table[iii]).red =
((color_table[iii]).red" 6)?
color_table[iii].red-1: 1;
(color_table[iii]).green =
((color_table[iii]).green" 6)?
color_table[iii].green-1: 1;
(color_table[iii]).blue =
((color_table[iii]).blue" 6)?
color_table[iii].blue-1: 1;
}
SetVgaDAC(seg_table,off_table);
}
// Ожидаем нажатие на клавишу
SetVideoMode( 0x3 );
Hello();
return 0;
}
//- ____________________ =
// Функция SetVideoMode устанавливает режим работы
// видеоадаптера, заданный параметром vmode
//- ____________________ =
void SetVideoMode( unsigned char vmode ) {
union REGS inregs, outregs;
inregs.h.ah = 0x0;
inregs.h.al = vmode;
int86( 0x10, inregs, outregs );
}
//- ____________________ =
// Функция Hello выводит на экран краткую справку о программе
//- ____________________ =
void Hello(void) {
printf("\nCopyright (C)Frolov G.V.,1995. "
"E- mail: frolov@glas.apc.org\n");
} Функция SetVgaDAC, предназначенная для заполнения таблицы цветов, представлена в листинге 4.14. Листинг 4.14. Файл DACTABLE.ASM TITLE DACTABLE.ASM
 
 

 NAME DACTABLE 


  PAGE 55,132  



  P286  



  IDEAL  



  NOWARN BRK  



  SEGMENT VGA_TEXT WORD PUBLIC 'CODE'  


ASSUME cs:VGA_TEXT
;- ____________________ 
; Функция
; void SetVgaDAC(unsigned seg_table, unsigned off_table)
;- ____________________ 
off_table EQU [bp+6]
seg_table EQU [bp+8]


  PUBLIC SETVGADAC  



  PROC SETVGADAC FAR  


enter 0, 0
; Сохраняем регистры DS и ES
push ds
push es
; Устанавливаем регистр ES на начало оперативной памяти
xor ax,ax
mov es,ax
; Получаем адрес порта индексного регистра контроллера ЭЛТ
; (3B4h/3D4h), в монохромных режимах для адресации к
; индексному регистру используется порт с адресом 3B4h, а
; в цветных - порт 3D4h
mov dx,es:[463h]
; Вычисляем адрес порта регистра состояния 1, в
; монохромных режимах для адресации к регистру состояния 1
; используется порт с адресом 3BAh, а в цветных порт 3DAh
add dx,6
pop es
; Ожидаем начало обратного вертикального хода луча
in al,dx
nop
nop
; Если бит D3 равен единице, то происходит обратный
; вертикальный ход луча
test al,08h
jz wait_on
wait_off:
in al,dx
nop
nop
test al,08h
jnz wait_off
wait_on:
in al,dx
nop
nop
test al,08h
jz wait_on
; Устанавливаем индекс первого записываемого регистра
; таблицы цветов
mov dx,3C8h
; Начинаем модифицировать таблицу цветов с первого
; регистра
mov ax,1
out dx,al
; Задержка
nop
nop
; Устанавливаем DS:SI на массив данных, записываемых
; в регистры таблицы цветов
mov ax,seg_table
mov ds,ax
mov si,off_table
; Загружаем 256 регистров (по 3 байта на регистр)
mov cx,(256 * 3)
; Выбираем регистр данных таблицы цветов (порт 3C9h)
mov dx,3C9h
cld
; Загружаем все регистры таблицы цветов
get_reg:
lodsb
out dx,al
nop
nop
loop get_reg
; Восстанавливаем регистр DS
pop ds
leave
ret 4


  ENDP SETVGADAC  



  ENDS VGA_TEXT  


END Нестандартные режимы видеоадаптера VGA В этой главе на примере видеоадаптера VGA мы рассмотрим программирование нестандартных режимов. Так как программирование нестандартных режимов видеоадаптеров требует непосредственного доступа к его регистрам, то перед чтением этой главы вам необходимо подробно изучить назначение регистров адаптера. Мы рассмотрим два наиболее интересных с нашей точки зрения нестандартных режимов VGA: 320х400 и 360х480 пикселов при возможности одновременного отображения 256 цветов. Нестандартные режимы нельзя установить на обычных видеоадаптерах VGA с помощью функций BIOS. С помощью BIOS можно установить только один режим с 256-цветной палитрой - режим номер 13h (разрешение 320х200 пикселов, 256 цветов). Однако если вы воспользуетесь возможностью непосредственного программирования адаптера через регистры, то любой адаптер VGA можно перевести в эти режимы. Программирование всех трех описанных ниже нестандартных режимов мы будем проводить в два этапа: SYMBOL 119 \f "Wingdings" \s 10 \h устанавливаем при помощи BIOS стандартный режим номер 13h (320х200 пикселов, 256 цветов), SYMBOL 119 \f "Wingdings" \s 10 \h изменяем содержимое некоторых регистров видеоадаптера, отвечающих за структуру видеопамяти и разрешающую способность адаптера. Такой подход к установке нестандартных режимов позволяет программировать не все регистры адаптера, а только те, которые нуждаются в изменении. Организация видеопамяти Режим 13h использует простую линейную организацию видеопамяти, в которой по каждому адресу видеопамяти находится один байт данных, управляющий одним пикселом. Такая организация видеопамяти хотя и облегчает программирование, но не позволяет увеличить разрешающую способность. Дело в том, что в режиме 13h адресное пространство видеопамяти ограничено 64 Кбайт, которых хватает как раз для того, чтобы получить разрешающую способность 200х320 точек при 256 цветах (200*320 = 64000). Кроме того, такая организация видеопамяти не позволяет использовать для копирования видеоданных регистры-защелки, что может существенно повысить скорость работы программ. Исходя из вышесказанного для нашего нестандартного режима используется другая структура видеопамяти, более схожая со структурой видеопамяти режимов 10h и 12h. На рисунке 4.20 представлена структура видеопамяти используемая нами во всех описываемых нестандартных режимах: \s \* MERGEFORMAT PICTURE._HRESVGA.PCX;6";4.308";PCX Рисунок 4.20 Структура видеопамяти в нестандартных, 256-цветовых режимах Как видно из рисунка, первый пиксел экрана, отображаемый в левом верхнем углу, определяется байтом со смещением 0 из нулевого цветового слоя. Второй пиксел определяется байтом со смещением 0 из первого слоя, третий пиксел - байтом со смещением 0 из второго слоя, четвертый пиксел - байтом со смещением 0 из третьего слоя. Пятый пиксел определяется байтом со смещением 1 из нулевого слоя и так далее. Таким образом, цвет пиксела с координатами x и y определяет байт видеопамяти, который расположен со смещением (x + y * PIXEL_PER_LINE) / 4, в цветовой плоскости (x + y * PIXEL_PER_LINE) mod 4. В этой формуле константа PIXEL_PER_LINE должна определять горизонтальную разрешающую способность экрана в данном режиме. Такая организация видеопамяти неудобна для вычисления адреса пикселов, но дает другие неоспоримые преимущества. Во первых, в режиме с разрешением 320х400 пикселов мы можем использовать две страницы видеопамяти. Первая из них имеет нулевое смещение, а вторая смещение 8000h от начала видеопамяти. Режим с разрешением 360х480 пикселов позволяет иметь только одну страницу, но так как он использует только 172800 байт из 256 Кбайт, то неиспользуемую память можно использовать для хранения пиктограмм и шрифтов. Во вторых, организация видеопамяти в виде отдельных цветовых слоев позволяет использовать для операций копирования и заполнения областей видеопамяти регистры-защелки. Это дает возможность одновременно копировать четыре байта, и, следовательно, значительно увеличить скорость работы программ. Режим 320х400 пикселов, 256 цветов Мы начнем рассмотрение нестандартных режимов с режима, имеющего разрешение 320х400 пикселов. Программирование этого режима является самым простым и безопасным, так как при его установке нам не придется изменять содержимое регистров контроллера ЭЛТ. Как мы указывали при описании режимов видеоадаптеров, в режиме 13h используется двойное сканирование. То есть в этом режиме - 320х200 пикселов на самом деле отображается не 200, а 400 линий сканирования. Перепрограммировав несколько регистров адаптера можно перевести его в режим 320х400 пикселов. Рассмотрим последовательность действий, необходимую для перевода видеоадаптера в нестандартный режим с разрешением 320х400 пикселов: SYMBOL 119 \f "Wingdings" \s 10 \h Устанавливаем при помощи функций BIOS стандартный режим номер 13h (320х200 пикселов, 256 цветов). При этом программируются все регистры видеоадаптера и нам останется только изменить содержимое нескольких регистров. SYMBOL 119 \f "Wingdings" \s 10 \h Изменяем структуру видеопамяти, чтобы иметь возможность адресовать 256 Кбайт памяти. Для этого в регистре определения структуры памяти синхронизатора запрещаем режимы в которых доступ по разным адресам (кратным двум и/или кратным четырем) осуществляется к различным цветовым слоям памяти. А в регистре режима работы графического контроллера сбрасываем в ноль бит управления четным/нечетным режимом. Это запрещает доступ по четным адресам к четным цветовым слоям, а по нечетным адресам - к нечетным цветовым слоям видеопамяти. Затем в регистре смешанного назначения графического контроллера сбрасываем бит управляющий сцеплением четных и нечетных слоев памяти. После этих действий видеопамять по своей структуре напоминает режим 10h, за исключением того, что каждый пиксел управляется одним байтом, расположенным в одном из слоев видеопамяти. SYMBOL 119 \f "Wingdings" \s 10 \h Очищаем видеопамять (для одной или двух страниц по необходимости), так как при установке режима 13h BIOS очищает только первые 64 Кбайт из 256 Кбайт. Остальная часть видеопамяти может содержать данные, которые появятся на экране монитора после перепрограммирования контроллера ЭЛТ. SYMBOL 119 \f "Wingdings" \s 10 \h Выключаем режим двойного сканирования. Для этого сбрасываем бит управления двойным сканированием и устанавливаем высоту символов равную единице. SYMBOL 119 \f "Wingdings" \s 10 \h Переводим контроллер ЭЛТ в режим побайтовой адресации видеопамяти. Для этого выключаем режим адресации по двойным словам в регистре положения подчеркивания символа и включаем режим адресации по байтам в регистре управления режимом работы. Теперь по каждому адресу расположено четыре байта в различных цветовых слоях видеопамяти. Приведем программу E256MRES, реализующую изложенный алгоритм. Данная программа переводит видеоадаптер в режим отображающий 256 цветов при разрешающей способности 320х400 пикселов (листинг 4.15). Листинг 4.15. Файл E256MRES.C #include "conio.h"
#include "stdlib.h"
#include "stdio.h"
#include "dos.h"
// Описание функций
void SetVideoMode(unsigned char);
// Следующие функции определены в файле EVGAM.ASM
void __pascal __far Set320x400Mode( void );
void __pascal __far FullScr(unsigned char);
void __pascal __far
WritePixel(unsigned, unsigned, unsigned char);
unsigned char __pascal __far
ReadPixel(unsigned, unsigned, unsigned char);
// Главная функция
void main( void ){
unsigned i;
char ch = 13;
// Устанавливаем режим 320х400 пикселов, 256 цветов
Set320x400Mode();
// Загружаем регистры ЦАП VGA
// LoadVGA256();
for(i = 0; i "400; i++)
WritePixel(160, (unsigned) i, (unsigned char)(i%256));
for(i = 0; i "320; i++)
WritePixel((unsigned) i, 200, (unsigned char)(i%256));
ch = getch();
if( ch - 27 ) exit(1);
for(i = 0; i "320; i++)
WritePixel((unsigned) i,(unsigned) i,
(unsigned char)(i%256));
ch = getch();
for(i = 0; ((i "256) (ch!= 27)); i++) {
FullScr( (unsigned char) i );
ch = getch();
}
// Возвращаемся в текстовый режим
SetVideoMode(3);
printf("\n (C) Frolov G.V., 1992-1995 \n\n");
}
//- ____________________ =
// Функция устанавливает режим работы видеоадаптера, заданный
// параметром vmode
//- ____________________ =
void SetVideoMode( unsigned char vmode ) {
union REGS inregs, outregs;
inregs.h.ah = 0x0;
inregs.h.al = vmode;
int86( 0x10, inregs, outregs );
} Основные функции, предназначенные для выбора нестандартного режима, записи и чтения пикселов, а также заполнения экрана монитора, написаны на языке ассемблера. Исходный текст этих функций содержится в листинге 4.16. Листинг 4.16. Файл EVGAM.ASM TITLE EVGAM.ASM
 
 

 NAME EVGAM 


  PAGE 55,132  



  P286  



  IDEAL  



  NOWARN BRK  


INCLUDE "evga.inc"


  SEGMENT EVGA_TEXT WORD PUBLIC 'CODE'  


ASSUME cs:EVGA_TEXT
;- ____________________ 
; void Set320x400Mode( void )
; Установка режима 320х400 пикселов, 256 цветов.
;- ____________________ 


  PUBLIC SET320X400MODE  



  PROC SET320X400MODE FAR  


enter 0, 0
; Сохраняем регистр di
push di
; Устанавливаем стандартный режим 13h
; (320x200 пикселов, 256 цветов)
mov ax,0013h
int 10h
; Выбираем регистр определенияя структуры памяти
mov dx,SC_INDEX
mov al,MMR
out dx,al
; Считываем значение регистра определения структуры памяти
inc dx
in al,dx
; Сбрасываем бит D4
and al,11110111b
; Устанавливаем бит D3, при этом выключается режим
; адресации по четным и нечетным адресам к разным слоям
; памяти
or al,00000100b
; Записываем в регистр новое значение
out dx,al
; После загрузки в этот регистр нового значения структура
; видеопамяти соответствует режимам 10h и 12h за
; исключением того, что каждому пикселу соответствует один
; байт видеопамяти
; Выбираем регистр режима работы графического контроллера
mov dx,GC_INDEX
mov al,MDR
out dx,al
; Считываем его значение
inc dx
in al,dx
; Выключаем доступ по четным адресам к четным слоям, а по
; нечетным адресам к нечетным слоям
and al,11101111b
out dx,al
; Выбираем регистр смешанного назначения графического
; контроллера
dec dx
mov al,MIR
out dx,al
; Считываем его значение
inc dx
in al,dx
; Сбрасываем бит управляющий сцеплением четных и нечетных
; слоев
and al,11111101b
out dx,al
; Разрешаем запись днных во все четыре цветовых слоя,
; записывая число 0fh в регистр разрешения записи
; цветового слоя
mov dx,SC_INDEX
mov al,CPWER
out dx,al
inc dx
mov al,00001111b
out dx,al
; Очищаем первую страницу видеопамяти, так как установка
; ржима 13h очищает только первые 64K
mov ax,VGA_SEGMENT
mov es,ax
xor di,di
mov ax,di
mov cx,8000h
cld
rep stosb
; Выбираем регистр высоты символов текста контроллера ЭЛТ
mov dx,CRTC_INDEX
mov al,MSLR
out dx,al
inc dx
in al,dx
; Устанавливаем высоту символа равную нулю
;!!! and al,not 1fh
; Запрещаем двойное сканирование
and al,01100000b
out dx,al
; Выбираем регистр положения подчеркивания символа
dec dx
mov al,ULR
out dx,al
; Выключаем режим адресации видеопамяти по двойным словам
inc dx
in al,dx
and al,10111111b
out dx,al
; Выбираем регистр управления режимом
dec dx
mov al,MCR
out dx,al
; Включаем байтовый режим адресации
inc dx
in al,dx
or al,01000000b
out dx,al
pop di
leave
ret
 
 

 ENDP SET320X400MODE 

;- ____________________ 
; void WritePixel(unsigned x, unsigned y,
; unsigned char color)
;
; Функция отображает на экране пиксел в заданных координатах,
; определенного цвета.
; x - x-координата пиксела (0-319),
; y - y-координата пиксела (0-399),
; color - цвет пиксела (0-255).
;- ____________________ 
color EQU [bp+6]
y EQU [bp+8]
x EQU [bp+10]


  PUBLIC WRITEPIXEL  



  PROC WRITEPIXEL FAR  


enter 0, 0
push di
mov cx,x
mov dx,y
mov bl,color
mov ax,VGA_SEGMENT
mov es,ax
mov ax,( SCREEN_WIDTH / 4 )
mul dx
push cx
shr cx,1
shr cx,1
add ax,cx
mov di,ax
pop cx
and cl,3
mov ah,1
shl ah,cl
mov dx,SC_INDEX
mov al,CPWER
out dx,ax
mov es:[di],bl
pop di
leave
ret 6


  ENDP WRITEPIXEL  


;- ____________________ 
; unsigned char ReadPixel(unsigned x, unsigned y, unsigned char color)
; Функция возвращает значение байта видеопамяти, определяющего пиксел
; с заданными координатами.
; x - x-координата пиксела (0-319),
; y - y-координата пиксела (0-399).
; Return цвет пиксела (0-255).
;- ____________________ 
color EQU [bp+6]
y EQU [bp+8]
x EQU [bp+10]


  PUBLIC READPIXEL  



  PROC READPIXEL FAR  


enter 0, 0
push si
mov cx,x
mov dx,y
mov ax,VGA_SEGMENT
mov es,ax
mov ax,( SCREEN_WIDTH / 4 )
mul dx
push cx
shr cx,1
shr cx,1
add ax,cx
mov si,ax
pop ax
and al,3
mov ah,al
mov dx,GC_INDEX
mov al,RPSR
out dx,ax
mov al,es:[si]
xor ah,ah
pop si
leave
ret 6


  ENDP READPIXEL  


;- ____________________ 
; void FullScr( unsigned char color )
; Закрашивает экран заданным цветом.
; color - цвет экрана (0-255).
;- ____________________ 
color EQU [bp+6]


  PUBLIC FULLSCR  



  PROC FULLSCR FAR  


enter 0, 0
;разрешаем запись данных во все четыре цветовых слоя
push di
mov dx,SC_INDEX
mov al,CPWER
out dx,al
inc dx
mov al,0fh
out dx,al
mov ax,VGA_SEGMENT
mov es,ax
xor di,di
mov al,color
mov cx,32000
cld
rep stosb
pop di
leave
ret 2
 
 

 ENDP FULLSCR 


  ENDS EVGA_TEXT  


END Включаемый файл EVGA.INC, в котором определены различные константы для нестандартных режимов видеоадаптера, представлен в листинге 4.17. Листинг 4.17. Файл EVGA.INC; Сегмент видеопамяти для режима 13h
VGA_SEGMENT EQU 0a000h
; Адрес индексного порта синхронизатора
SC_INDEX EQU 3c4h
; Регистр разрешения записи цветового слоя


  CPWER EQU 2  


; Регистр определения структуры памяти


  MMR EQU 4  


; Адрес индексного порта графического контроллера
GC_INDEX EQU 3ceh
; Регистр выбора читаемого слоя


  RPSR EQU 4  


; Регистр режима работы


  MDR EQU 5  


; Регистр смешанного назначения


  MIR EQU 6  


; Адрес индексного порта контроллера ЭЛТ (цветной режим)
CRTC_INDEX EQU 3d4h
; Регистр высоты символов текста


  MSLR EQU 9  


; Регистр начального адреса
SAR_h EQU 0ch
; Регистр положения подчеркивания символа
ULR EQU 14h
; Регистр управления режимом
MCR EQU 17h
; Регистр определения различных режимов работы
MOR EQU 3c2h
; Режим 320х400 пикселов
; Количество пикселов по вертикали


  SCREEN_HEIGHT EQU 400  


; Количество пикселов по горизонтали


  SCREEN_WIDTH EQU 320  


; РЕЖИМ 360х480 пикселов
; Количество пикселов по вертикали (режим 320х400)


  SCREEN_HEIGHT_H EQU 480  


; Количество пикселов по горизонтали (режим 360х480)
SCREEN_WIDTH_H EQU 360 Режим 360х480 пикселов, 256 цветов Второй нестандартный режим, который мы рассмотрим, может отображать 256 цветов при разрешающей способности 360х480 пикселов. Ниже приведена программа E256HRES, которая переводит видеоадаптер в нестандартный режим с разрешением 360х480 пикселов (листинг 4.18): Листинг 4.18. Файл E256HRES.C #include "conio.h"
#include "stdlib.h"
#include "stdio.h"
#include "dos.h"
#include "vga_new.h"
// Описание функций
void main( void );
void SetVideoMode(unsigned char);
// Следующие функции определены в файле EVGAH.ASM
void __pascal __far Set360x480Mode( void );
void __pascal __far FullScrH(unsigned char);
void __pascal __far
WritePixelH(unsigned, unsigned, unsigned char);
unsigned char __pascal __far
ReadPixelH(unsigned, unsigned, unsigned char);
// Главная функция
void main( void ){
unsigned i;
char ch = 13;
// Устанавливаем режим 360х480 пикселов, 256 цветов
Set360x480Mode();
// загружаем регистры ЦАП VGA
// LoadVGA256();
for(i = 0; i "480; i++)
WritePixelH(180, (unsigned) i, (unsigned char)(i%256));
for(i = 0; i "360; i++)
WritePixelH((unsigned) i, 240, (unsigned char)(i%256));
ch = getch();
if( ch - 27 ) exit(1);
for(i = 0; i "360; i++)
WritePixelH((unsigned) i, (unsigned) i,
(unsigned char) (i % 256) );
ch = getch();
for(i = 0; ((i "256) (ch!= 27)); i++) {
FullScrH( (unsigned char) i );
ch = getch();
}
// Возвращаемся в текстовый режим
SetVideoMode(3);
printf("\n (C) Frolov G.V., 1992\n\n");
}
//- ____________________ =
// Функция устанавливает режим работы видеоадаптера, заданный
// параметром vmode
//- ____________________ =
void SetVideoMode( unsigned char vmode ) {
union REGS inregs, outregs;
inregs.h.ah = 0x0;
inregs.h.al = vmode;
int86( 0x10, inregs, outregs );
} Основные функции, предназначенные для выбора нестандартного режима с разрешением 360х480 пикселов, записи и чтения пикселов, а также заполнения экрана монитора, написаны на языке ассемблера. Исходный текст этих функций представлен в листинге 4.19. Листинг 4.19. Файл EVGAH.ASM TITLE EVGAH.ASM
 
 

 NAME EVGAH 


  PAGE 55,132  



  P286  



  IDEAL  



  NOWARN BRK  


INCLUDE "evga.inc" // Смотри листинг 4.17


  SEGMENT EVGA_TEXT WORD PUBLIC 'CODE'  


ASSUME cs:EVGA_TEXT
;- ____________________ 
; void Set360x480Mode( void )
; Установка режима 360х480 пикселов, 256 цветов.
;- ____________________ 


  PUBLIC SET360X480MODE  



  PROC SET360X480MODE FAR  


enter 0, 0
; Устанавливаем режим 12h, чтобы очистить видеопамять
mov ax,12h
int 10h
; Устанавливаем стандартный режим 13h
; (320x200 пикселов, 256 цветов)
mov ax,0013h
int 10h
; Перепрограммируем регистр определения структуры памяти:
; запрещаем адресацию к разным слоям памяти в зависимости
; от кратности адреса памяти четырем (бит D4 chain4)
mov dx,SC_INDEX
mov ax,0604h
out dx,ax
; Производим синхронный сброс и остановку синхронизатора
mov ax,0100h
out dx,ax
; Адресуемся к регистру определения различных режимов
; работы
mov dx,MOR
; Устанавливаем частоту кадров 60Кц
mov al,0e7h
out dx,al
; Запускаем синхронизатор
mov dx,SC_INDEX
mov ax,0300h
out dx,ax
; Выбираем регистр режима работы графического контроллера
mov dx,GC_INDEX
mov al,MDR
out dx,al
; Считываем его значение
inc dx
in al,dx
; Выключаем доступ по четным адресам к четным слоям, а по
; нечетным адресам к нечетным слоям
and al,11101111b
out dx,al
; Выбираем регистр смешанного назначения графического
; контроллера
dec dx
mov al,MIR
out dx,al
; Считываем его значение
inc dx
in al,dx
; Сбрасываем бит управляющий сцеплением четных и нечетных
; слоев
and al,11111101b
out dx,al
; Выбираем регистр конца обратного вертикального хода луча
mov dx,3d4h
mov al,11h
out dx,al
; Снимаем защиту от записи с регистров контроллера ЭЛТ,
; имеющих индексы от 0 до 7
inc dx
in al,dx
and al,7fh
out dx,al
dec dx
; Программируем регистры контроллера ЭЛТ, втом числе
; регистры, определяющие временные параметры режима
; Устанавливаем регистр общей длины линии горизонтальной
; развертки
mov ax,06b00h
out dx,ax
; Устанавливаем регистр длины отображаемой части
; горизонтальной развертки
mov ax,05901h
out dx,ax
; Устанавливаем регистр начала импульса гашения луча
; горизонтальной развертки
mov ax,05a02h
out dx,ax
; Устанавливаем регистр конца импульса гашения луча
; горизонтальной развертки
mov ax,08e03h
out dx,ax
; Устанавливаем регистр начала импульса горизонтального
; обратного хода луча
mov ax,05e04h
out dx,ax
; Устанавливаем регистр конца импульса горизонтального
; обратного хода луча
mov ax,08a05h
out dx,ax
; Устанавливаем регистр числа горизонтальных линий
; растра
mov ax,0d06h
out dx,ax
; Устанавливаем дополнительный регистр
mov ax,03e07h
out dx,ax
; Устанавливаем регистр высоты символов текста
mov ax,04009h
out dx,ax
; Устанавливаем регистр начала обратного
; вертикального хода луча
mov ax,0ea10h
out dx,ax
; Устанавливаем регистр конца обратного
; вертикального хода луча
mov ax,0ac11h
out dx,ax
; Устанавливаем регистр начала гашения вертикальной
; развертки
mov ax,0df12h
out dx,ax
; Устанавливаем регистр логической ширины экрана
mov ax,02d13h
out dx,ax
; Устанавливаем регистр положения подчеркивания символа
mov ax,014h
out dx,ax
; Устанавливаем регистр начала импульса гашения
; вертикальной развертки
mov ax,0e715h
out dx,ax
; Устанавливаем регистр конца импульса гашения
; вертикальной развертки
mov ax,0616h
out dx,ax
; Устанавливаем регистр управления режимом
mov ax,0e317h
out dx,ax
leave
ret
 
 

 ENDP SET360X480MODE 

;- ____________________ 
; void
; WritePixelH(unsigned x, unsigned y, unsigned char color)
; Функция отображает на экране пиксел в заданных координатах,
; определенного цвета.
; x - x-координата пиксела (0-319),
; y - y-координата пиксела (0-399),
; color - цвет пиксела (0-255).
;- ____________________ 
color EQU [bp+6]
y EQU [bp+8]
x EQU [bp+10]


  PUBLIC WRITEPIXELH  



  PROC WRITEPIXELH FAR  


enter 0, 0
push di
mov cx,x
mov dx,y
mov bl,color
mov ax,VGA_SEGMENT
mov es,ax
mov ax,( SCREEN_WIDTH_H / 4 )
mul dx
push cx
shr cx,1
shr cx,1
add ax,cx
mov di,ax
pop cx
and cl,3
mov ah,1
shl ah,cl
mov dx,SC_INDEX
mov al,CPWER
out dx,ax
mov es:[di],bl
pop di
leave
ret 6


  ENDP WRITEPIXELH  


;- ____________________ 
; unsigned char
; ReadPixelH(unsigned x, unsigned y, unsigned char color)
; Функция возвращает значение байта видеопамяти,
; определяющего пиксел с заданными координатами.
; x - x-координата пиксела (0-319),
; y - y-координата пиксела (0-399).
; Функция возвращает цвет пиксела (0-255).
;- ____________________ 
color EQU [bp+6]
y EQU [bp+8]
x EQU [bp+10]


  PUBLIC READPIXELH  



  PROC READPIXELH FAR  


enter 0, 0
push si
mov cx,x
mov dx,y
mov ax,VGA_SEGMENT
mov es,ax
mov ax,( SCREEN_WIDTH_H / 4 )
mul dx
push cx
shr cx,1
shr cx,1
add ax,cx
mov si,ax
pop ax
and al,3
mov ah,al
mov dx,GC_INDEX
mov al,RPSR
out dx,ax
mov al,es:[si]
mov color,al
xor ah,ah
pop si
leave
ret 6


  ENDP READPIXELH  


;- ____________________ 
; void FullScrH( unsigned char color )
; Закрашивает экран заданным цветом.
; color - цвет экрана (0-255).
;- ____________________ 
color EQU [bp+6]


  PUBLIC FULLSCRH  



  PROC FULLSCRH FAR  


enter 0, 0
;Разрешаем запись данных во все четыре цветовых слоя
push di
;Разрешаем запись данных во все четыре цветовых слоя
mov dx,SC_INDEX
mov al,CPWER
out dx,al
inc dx
mov al,0fh
out dx,al
mov ax,VGA_SEGMENT
mov es,ax
xor di,di
mov al,color
mov cx,43200
cld
rep stosb
pop di
leave
ret 2
 
 

 ENDP FULLSCRH 


  ENDS EVGA_TEXT  


END 5. Использование функций BIOS для работы с видеоадаптерами У всех компьютеров, совместимых с IBM PC/XT/AT и PS/2, на системной плате установлена микросхема ПЗУ BIOS. В ней записан набор различных программ или функций, предназначенных для управления различными подсистемами компьютера: дисковой подсистемой, асинхронными последовательными и параллельными портами ввода/вывода, видеоадаптером. Нас в первую очередь будут интересовать функции, предназначенные для управления видеоподсистемой компьютера. Микросхема ПЗУ BIOS, расположенная на системной плате содержит функции для управления видеоадаптерами. Однако практически все видеоадаптеры имеют собственную микросхему ПЗУ BIOS, расположенную на самой плате адаптера. На практике для управления видеоадаптером используются функции, записанные в его ПЗУ BIOS. Использование функций BIOS для управления видеоадаптерами имеет как преимущества, так и недостатки. Основным преимуществом функций BIOS является то, что они скрывают всю кропотливую работу по программированию регистров видеоадаптера и видеопамяти, предоставляя программисту достаточно простой интерфейс. Но это еще не все. Так как функции BIOS создаются самими разработчиками видеоадаптера, то они учитывают все особенности конкретной модели адаптера, выравнивая все различия. Как вы узнаете позже, это особенно важно для программирования видеоадаптеров SVGA, так как набор регистров и организация видеопамяти разных моделей может сильно различаться. К недостаткам функций BIOS можно отнести невысокую скорость их работы. Отчасти это вызвано тем, что доступ к данным, записанным в ПЗУ происходит медленнее, чем к оперативной памяти. Многие системные платы позволяют перенести содержимое медленного ПЗУ BIOS в более быструю оперативную память. Эта область оперативной памяти получила название теневой памяти, так как ее содержимое полностью повторяет соответствующую область ПЗУ. Подключение теневой памяти выполняется с помощью программы BIOS Setup. Отметим, что ПЗУ BIOS видеоадаптера обычно занимает адресное пространство начиная с адреса C000:0000h до адреса C000:7FFFh. Второй недостаток функций ПЗУ BIOS состоит в том, что большинство их нереентерабельно. То есть пока не завершится вызов функции BIOS нельзя вызвать другую функцию BIOS. Вследствие этого вы не можете как обычно пользоваться функциями BIOS в резидентных программах. Практически ни одна функция BIOS видеоадаптера не проверяет результат своего выполнения и не сообщает о произошедших ошибках. Поэтому любая неточность в исходном тексте программы может привести к ошибке, причину которой будет трудно выявить. И, наконец, последний недостаток функций BIOS состоит в том, что они предназначены только для работы в реальном режиме процессора. При вызове функций BIOS из защищенного режима процессора будет происходить переключение процессора в реальный режим. Для доступа к функциям BIOS видеоадаптера предназначено прерывание INT 10h. Загрузите в регистр AH номер функции BIOS видеоадаптера, которую необходимо вызвать, загрузите остальные регистры процессора в соответствии с вызываемой функцией и выполните прерывание INT 10h. Большинство функций BIOS видеоадаптера не изменяют содержимое неиспользуемых регистров процессора, однако рекомендуется сохранить наиболее важные регистры. Выбор режима работы - функция 00h Функция 00h прерывания 10h позволяет задать любой стандартный режим работы видеоадаптера: На входе: AH 00h AL Номер устанавливаемого режима работы видеоадаптера, если бит D7 = 1, то при установке режима видеопамять не очищается На выходе: Не используются Приведем пример выбора режима видеоадаптера: mov ah, 0
mov al, 3; Выбираем режим номер 3 (16 цветной, текстовый,
int 10h; разрешение 25х80 символов) Изменение формы курсора - функция 01h Функция 01h позволяет изменить вертикальные размеры курсора путем задания верхней и нижней границ курсора (рис. 5.1). Горизонтальные размеры курсора всегда одинаковы и равны ширине одного символа. Курсор отображается только в текстовых режимах работы видеоадаптера. На входе: AH 00h CH Верхняя граница курсора. Если регистр CH содержит значение 20h курсор не отображается CL Нижняя граница курсора На выходе: Не используются При выборе режима работы видеоадаптера BIOS устанавливает следующие значения для верхней и нижней границ курсора: SYMBOL 119 \f "Wingdings" \s 10 \h Для монохромного и улучшенного цветного монитора верхняя граница = 11h, а нижняя = 12h. SYMBOL 119 \f "Wingdings" \s 10 \h Для цветного монитора верхняя граница = 6h, а нижняя = 7h. \* MERGEFORMAT PICTURE._FIG_35.PCX;6";4.308";PCX Рисунок 5.1 Изменение положения курсора Изменение положения курсора - функция 02h Функция 02h задает текущее положение курсора на экране монитора. Если видеопамять разделена на несколько страниц, то каждая из них имеет свой курсор, координаты которого можно устанавливать отдельно. Координаты курсора определяют не только место на экране, где он отображается, но также и позицию, начиная с которой соответствующие функции BIOS будут выводить на экран строки или отдельные символы. На входе: AH 02h BH Номер страницы видеопамяти DH Номер строки DL Номер столбца На выходе: Не используются Определение положения и формы курсора - функция 03h Функция 03h позволяет узнать размер и текущие координаты курсора для любой страницы видеопамяти: На входе: AH 03h BH Номер страницы видеопамяти На выходе: CH Верхняя граница курсора CL Нижняя граница курсора DH Позиция текущей строки курсора DL Позиция текущего столбца курсора Данная функция предназначена для использования только в текстовых режимах видеоадаптера. Использование светового пера - функция 04h Функция 04h позволяет определить подключено ли к видеоадаптеру световое перо или нет. Если световое перо подключено, можно определить его координаты. Функция позволяет узнать позицию светового пера в текстовых и в графических координатах. Световое перо видеоадаптера EGA программно не полностью совместимо с CGA, в результате чего программы поддерживающие возможность использования светового пера для видеоадаптера CGA будут работать неправильно с видеоадаптером EGA. Видеоадаптеры VGA и SVGA не имеют светового пера. На входе: AH 04h На выходе: AH 0 - световое перо не подключено (все остальные регистры не содержат полезной информации); 1 - световое перо подключено CH Координаты вертикальной позиции курсора в пикселах (графические режимы с низким разрешением - 04h, 05h, 06h) CX Координаты вертикальной позиции курсора в пикселах (графические режимы с высоким разрешением) BX Координаты горизонтальной позиции курсора в пикселах DH Номер строки, на которой расположен курсор DL Номер столбца на котором расположен курсор Выбор активной страницы видеопамяти - функция 05h Функция 05h позволяет изменить активную страницу видеопамяти. Активная страница видеопамяти отображается на экране монитора. Функция не проверяет физического наличия выбранной страницы видеопамяти. Если вы неправильно указали номер страницы результат работы функции не определен. На входе: AH 05h AL Номер страницы видеопамяти, которая станет активной На выходе: Не используются Свертка окна вверх - функция 06h Свернуть содержимое окна экрана вверх можно при помощи функции 06h. Окно задается координатами верхнего левого и нижнего правого углов. При свертке окна снизу появляются новые пустые строки (строки, заполненные пробелами). Верхние строки исчезают. Область экрана вне окна не изменяется. Функция позволяет работать только с активной страницей видеопамяти. На входе: AH 06h AL Количество свертываемых линий. Если оно равно нулю, то окно прокручивается целиком BH Атрибут, используемый для символов строк, возникающих снизу окна CH Номер строки верхнего левого угла окна CL Номер столбца верхнего левого угла окна DH Номер строки нижнего правого угла окна DL Номер столбца нижнего правого угла окна На выходе: Не используются Функцию 06h можно использовать не только в текстовых, но и в графических режимах работы видеоадаптера. Если вы используете функцию в графическом режиме, то цвет области, появляющийся внизу окна после его свертки зависит от значения регистра BH и номера режима видеоадаптера. В монохромном графическом режиме с разрешением 640х200 пикселов значение регистра BH определяет цвет 8-и последовательно расположенных пикселов. Задав разный цвет пикселов вы можете закрасить свертываемую область вертикальными штрихами. В 4-х цветном графическом режиме с разрешением 320х200 пикселов значение регистра BH определяет цвет 4-х последовательно расположенных пикселов. Благодаря этому вы можете закрасить свертываемую область вертикальными штрихами различного цвета. В остальных графических режимах значение регистра BH определяет цвет всех пикселов в свертываемой области экрана. Тот факт, что при свертке в нижней части окна возникают чистые строки, впоследствии заполняющие все окно, можно использовать для быстрой очистки экрана. Для этого достаточно задать размеры окна, равные размерам экрана и прокрутить его вверх на 25 или 0 строк. Приведем фрагмент программы на языке ассемблера, который можно использовать для очистки экрана монитора: push es; Сохраняем содержимое регистра ES
xor ax,ax; Устанавливаем регистр ES на нулевой
mov es,ax; сегмент памяти
mov ah,6; Функция свертки экрана вверх
mov al,0; Очищаем все окно
mov bh,7; Устанавливаем нормальный атрибут
xor cx,cx; Устанавливаем левый верхний угол окна в (0,0)
; Определяем число строк в данном режиме
mov dh,es:[484h]
; Определяем число символов в строке
mov dl,es:[44Ah]
dec dl
; Вызываем свертку экрана вверх
int 10h
; Восстанавливаем регистр ES
pop es Для определения размеров экрана используется содержимое переменных видеофункций BIOS. Ячейка памяти, расположенная по адресу 0000:0484h содержит число, на единицу меньшее, чем количество строк на экране. По адресу 0000:044Ah находится переменная, определяющая число символов в строке. Более подробно переменные видеофункциий BIOS будут рассмотрены позже. Свертка текстового окна вниз - функция 07h Свернуть активное окно экрана вниз можно при помощи функции 07h. Окно задается координатами верхнего левого и нижнего правого углов. При свертке в верхней части окна появляются новые пустые строки, а нижние строки исчезают. Область экрана вне окна не изменяется. На входе: AH 07h - свертка окна вниз AL Число свертываемых линий, если оно равно нулю, то окно прокручивается целиком BH Атрибут, используемый для строк, возникающих в верхней части окна CH Номер строки левого верхнего угла окна CL Номер столбца левого верхнего угла окна DH Номер строки правого нижнего угла окна DL Номер столбца правого нижнего угла окна На выходе: Не используются Функция работает аналогично функции 06h (за исключением направления свертки). Чтение символа и его атрибутов - функция 08h Данная функция позволяет прочитать символ и его атрибуты из позиции экрана, определенной текущим положением курсора. Чтение можно производить как из активной, так и из неактивных страниц памяти: На входе: AH 08h BH Номер страницы видеопамяти На выходе: AL ASCII-код символа AH Байт атрибутов символа для текстовых режимов Следующий пример считывает символ и его атрибут из текущей позиции курсора на странице page: mov ah,8
mov bh,page; Выбираем страницу видеопамяти page
int 10h; Считываем символ и его атрибут
mov char,al; Сохраняем полученный ASCII-код символа
mov attr,ah; и его атрибут Что удивительно данная функция может работать не только в текстовых, но также и в графических режимах. В этом случае она сравнивает пикселы в текущей позиции курсора с записями в таблице определения символов графического режима. Пикселы, значение которых не равно нулю, воспринимаются как пикселы символа. Остальные пикселы рассматриваются в качестве фона. Если соответствующий образ символа не обнаружен, функция возвращает в регистре AL значение 0. Если символ определен, в регистре AL возвращается его ASCII-код. В качестве таблицы определения символов графического режима используется таблица, на которую указывает вектор прерывания 43h. Для графических режимов низкого разрешения (режимы номер 4, 5, 6) используется таблица символов, на которую указывает вектор прерывания 1Fh. Эта таблица содержит определение символов с ASCII-кодами 80h - FFh. Запись символа с атрибутами в текущей позиции курсора - функция 09h Функция позволяет записать один или несколько одинаковых символов в текущей позиции курсора. Запись может происходить как в активную, так и в неактивные страницы видеопамяти. После выполнения операции записи положение курсора не изменяется. Управляющие символы, такие как возврат каретки и перевод строки, не действуют и записываются в видеопамять, как обычные символы. Данная функция работает как в текстовых, так и в графических режимах. На входе: AH 09h AL ASCII-код записываемого символа BH Номер страницы видеопамяти или цвет пикселов фона (для графического режима номер 13h) BL Атрибут символов (для текстового режима) или цвет пикселов символа (для графического режима); CX Количество записываемых символов На выходе: Не используются Если бит D7 регистра BL содержит единицу, то записываемый символ накладывается на текущее содержимое экрана по логике булевой операции ИСКЛЮЧАЮЩЕЕ ИЛИ. Естественно, за исключением режима номер 13h, в котором все биты регистра BL используются для задания цвета пикселов символа. Ниже приведен пример (листинг 5.1), использующий рассмотренные функции BIOS для выбора режима работы видеоадаптера, выбора активной страницы видеопамяти, изменения формы и координат курсора и отображения символов на экране монитора. Листинг 5.1. Файл BIOSFUN.ASM TITLE BIOS_FUNCTION
.MODEL small
 
 

 DOSSEG 

.STACK 100h
.DATA
message DB "INT 10h", 0
video_page DB 2
.CODE
.STARTUP
; Выбираем режим 3 видеоадаптера
xor ah,ah
mov al,3
int 10h
; Изменяем форму курсора
mov ah,1
mov ch,0; начало курсора - линия 0
mov cl,7; конец курсора - линия 7
int 10h
; Выбираем активную страницу видеопамяти
mov ah,5
mov al,video_page; выбираем страницу video_page
int 10h
mov ah,6
mov al,0
mov bh,0ffh
mov cl,10
mov ch,5
mov dl,30
mov dh,15
int 10h
; Устанавливаем координаты курсора
mov ah,2
mov bh,video_page; выбираем страницу video_page
mov dh,12; строка 12
mov dl,20; колонка 20
int 10h
; Отображаем на активной странице экрана строку message
mov si,OFFSET message
call WriteString
.EXIT 0
; Процедура WriteString выводит на экран строку, имеющую
; смещение si в сегменте ds
WriteString PROC
; Определяем текущую активную страницу экрана
mov ah,0Fh
int 10h; номер активной страницы в регистре bh
; Получаем в dx координаты курсора
mov ah,3
int 10h
; В цикле выводим на экран символы строки
next_char:
mov ah,9
lodsb
cmp al,0; находим конец строки
; Если достигнут конец строки оканчиваем процедуру
je exit_proc
; Для отображаемых символов используем атрибут 7
; символы строки выводятся без повтора
mov bl,7;
mov cx,1;
int 10h
; Перемещаем курсор в следующую позицию строки
mov ah,2
inc dl
int 10h
jmp next_char
exit_proc:
ret
WriteString ENDP
END Запись символа в текущей позиции курсора - функция 0Ah Функция позволяет записать символ в текущей позиции курсора на любой странице видеопамяти. Как и в предыдущей функции, можно производить запись сразу нескольких одинаковых символов. Атрибуты символа не задаются, а используются их старые значения из предыдущих операций записи. После операции записи положение курсора не изменяется. Управляющие символы, такие как возврат каретки и перевод строки, не действуют и записываются в видеопамять, как обычные символы. На входе: AH 10h AL ASCII-код записываемого символа BH Номер страницы видеопамяти или цвет пикселов фона (для графического режима номер 13h) BL Цвет пикселов символа (для графического режима) CX Количество записываемых символов На выходе: Не используются Во всех режимах (за исключением режима номер 13h) если бит D7 регистра BL содержит единицу, то записываемый символ накладывается на текущее содержимое экрана по логике булевой операции ИСКЛЮЧАЮЩЕЕ ИЛИ. Установка цветовой палитры (режимы 4,5,6) - функция 0Bh Данная функция позволяет выбрать одну из двух стандартных цветовых палитр (см. таблицу 9.1). Функция используется для обеспечения совместимости с видеоадаптером CGA и предназначена для использования в текстовых режимах и графических режимах с низким разрешением. Функция 0Bh имеет следующий формат вызова: На входе: AH 0Bh BH 0, тогда BL Цвет фона и рамки (для графического режима) или цвет рамки (для текстового режима) BH 1, тогда BL Номер палитры (0 или 1) На выходе: Не используются В следующей таблице описаны стандартные цветовые палитры для режимов 4, 5, 6: Номер цвета Палитра 0 Палитра 1 0 Цвет фона Цвет фона 1 Зеленый Синий 2 Красный Фиолетовый 3 Желтый Белый Вывод пиксела - функция 0Ch Использование функций BIOS для создания изображений, в частности для отображения отдельных пикселов, хотя и медленнее, чем прямая запись в видеопамять и программирование регистров, но более надежно с точки зрения совместимости для различных режимов и видеоадаптеров. Функция используется в графических режимах для записи пиксела заданного цвета в любую страницу видеопамяти. Необходимо отметить, что у видеоадаптера CGA в графических режимах определена только одна страница видеопамяти. Формат вызова функции 0Ch представлен ниже: На входе: AH 0Ch AL Номер цвета (значение ячейки видеопамяти, соответствующее пикселу) BH Номер страницы (для видеоадаптера CGA не используется) CX Координата X пиксела DX Координата Y пиксела На выходе: Не используются Во всех режимах (кроме режима номер 13h) если бит D7 регистра AL содержит единицу, то новый пиксел накладывается на текущее содержимое экрана по логике булевой операции ИСКЛЮЧАЮЩЕЕ ИЛИ. Номера цветов, которые можно использовать в различных режимах, перечислены в таблице, приведенной ниже. Цвета, соответствующие номерам цветов в таблице можно посмотреть в главе "Режимы работы видеоадаптеров". Номер режима Используемые номера цветов 4, 5 0 - 3 6 0 и 1 0Dh 0 - 15 0Eh 0 - 15 0Fh 0 и 1 10h 0 - 15 Начало системы координат находится в левом верхнем углу экрана. Оси координат направлены следующим образом: ось X - вправо, ось Y - вниз. Далее, если особо не оговорено, мы всегда будем использовать эту систему координат. Программа, представленная в листинге 5.2, демонстрирует использование функций выбора цветовой палитры и вывода пиксела. Листинг 5.2. Файл BIOS_C.C #include "dos.h"
#include "stdio.h"
#include "conio.h"
void main(void);
void main(void) {
union REGS inregs, outregs;
unsigned char i, j;
// Устанавливаем режим 4 видеоадаптера
// (графический - 320х200 пикселов, 4 цвета)
inregs.h.ah = 0x0;
inregs.h.al = 0x4;
int86( 0x10, inregs, outregs );
// Устанавливаем цвет фона
inregs.h.ah = 0x0B;
inregs.h.bh = 0x0; // устанавливаем цвет фона
inregs.h.bl = 0x6; // номер устанавливаемого цвета фона
int86( 0x10, inregs, outregs );
for(i = 0; i "2; i++) {
// Устанавливаем цветовую палитру
inregs.h.ah = 0x0B;
inregs.h.bh = 0x1; // установка палитры
inregs.h.bl = i; // номер палитры
int86( 0x10, inregs, outregs );
// Выводим массив точек
for(j = 0; j "64; j++) {
inregs.h.ah = 0x0C;
// Номер цвета
inregs.h.al = (unsigned char)(j / 16);
// X- координата точки
inregs.x.cx = 0x10 + j;
// Y- координата точки
inregs.x.dx = 0x10 + j;
int86( 0x10, inregs, outregs );
}
getch();
}
} Чтение пиксела - функция 0Dh Функция позволяет определить цвет любого пиксела экрана по его координатам. Функция используется только в графических режимах работы видеоадаптеров. На входе: AH 0Dh BH Номер страницы (для видеоадаптера CGA не используется) CX Координата X пиксела DX Координата Y пиксела На выходе: AL = номер цвета пиксела Приведем фрагмент программы, который определяет номер цвета пиксела, имеющего координаты x_pos и y_pos: mov ah,0Dh
mov cx,x_pos
mov dx,y_pos
int 10h
; Сохраняем полученную величину
mov color_number Запись символа в режиме телетайпа - функция 0Eh Функция обеспечивает запись символа на экран в режиме телетайпа: символ отображается в текущей позиции курсора, после чего курсор сдвигается вправо на одну позицию. При необходимости курсор автоматически перемещается на новую строку, а когда весь экран заполняется, происходит вертикальная свертка экрана. В последнем случае верхняя строка экрана исчезает, а снизу возникает новая пустая строка и курсор помещается в ее начало. В текстовых режимах цветовые атрибуты строк, возникающих из-за свертки экрана соответствуют атрибутам отображаемых символов. Данная функция обрабатывает следующие управляющие символы: звуковой сигнал (7 - BELL), возврат курсора назад на одну позицию (8 - BACKSPACE), возврат каретки (0Dh - CARRIAGE RETURN) и перевод строки (0Ah - LINEFEED). В текстовых режимах символы отображаются с атрибутами, использованными ранее. Атрибуты символов экрана не меняются и определяют цвет отображаемых символов. Если вам надо отобразить на экране символы различных цветов, вы должны предварительно установить атрибуты всех символов на экране. В графических режимах цвет отображаемого символа задается регистром BL. Если бит D7 регистра AL содержит единицу, то пикселы символа накладываются на текущее содержимое экрана по логике булевой операции ИСКЛЮЧАЮЩЕЕ ИЛИ (за исключением режима 13h). Ниже приведен формат вызова функции 0Eh: На входе: AH 0Eh - запись символа в режиме телетайпа AL ASCII-код записываемого символа BH Номер страницы видеопамяти (только в текстовых режимах)? BL Цвет символа (в графических режимах) На выходе: Не используются Приведем текст процедуры WriteStringT, которая выводит на экран строку, имеющую смещение SI в сегменте DS, при помощи функции 0Eh прерывания INT 10h (листинг 5.3). Листинг 5.3. Файл WRITESTR.C WriteStringT PROC
; Определяем текущую активную страницу экрана
mov ah,0Fh
int 10h; Номер активной страницы в регистре BH
; В цикле выводим на экран символы строки
next_char:
mov ah,0Eh
lodsb; Получаем следующий символ строки
cmp al,0; Находим конец строки
je exit_proc; Если конец строки достигнут, то
; оканчиваем процедуру
int 10h
jmp next_char
exit_proc:
ret
WriteStringT ENDP Определение текущего режима работы видеоадаптера - функция 0Fh Функция позволяет определить номер текущего режима работы видеоадаптера, номер активной страницы и количество символов в строке экрана. Список различных режимов приведен в таблице 3.1. Формат функции имеет следующий вид: На входе: AH 0Fh На выходе: AH Количество символов в строке AL Номер текущего режима BH Номер активной страницы видеопамяти Бит D7 регистра AL соответствует значению бита D7 регистра AL, использованному при предыдущем выборе режима работы видеоадаптера (см. функцию 0). Управление регистрами палитры - функция 10h Функция 10h предоставляет возможность программирования регистров цветовой палитры, таблицы цветов (для видеоадаптеров VGA и SVGA), а также управляет некоторыми атрибутами символов. Вы можете использовать эту функцию и в текстовых и в графических режимах. Для видеоадаптера EGA эта функция содержит четыре подфункции: Номер подфункции Назначение 0 Программирование одного регистра палитры 1 Программирование регистра цвета рамки 2 Программирование всех регистров палитры (таблицы цветов) 3 Управление атрибутом мигания и атрибутом интенсивности Видеоадаптеры VGA и SVGA дополнительно поддерживают еще 10 подфункций: Номер подфункции Назначение 7 Чтение регистра палитры 8 Чтение регистра цвета рамки 9 Чтение всех регистров палитры 10h Программирование регистра ЦАП 12h Программирование нескольких регистров ЦАП 13h Выбор подмножества цветов 15h Чтение регистра ЦАП 17h Чтение нескольких регистров ЦАП 1Ah Чтение состояния страницы цветов 1Bh Преобразование регистров ЦАП для работы в монохромном режиме Установка регистра палитры - подфункция 00h Функция выполняет запись в регистр палитры контроллера атрибутов: На входе: AH 10h AL 00h - установка регистра палитры BL Номер регистра палитры для записи BH Данные, записываемые в регистр палитры На выходе: Не используются Следующий фрагмент записывает в регистр палитры с номером reg_num содержимое переменной data: mov ah,10h; Функция 10h
xor al,al; Подфункция 0h
mov bl,num_reg; Задаем номер регистра палитры
mov bh,data; Новое значение регистра
int 10h Установка цвета рамки - подфункция 01h Функция выполняет запись значения в регистр цвета рамки контроллера атрибутов. Надо иметь в виду, что эта функция не работает в некоторых режимах видеоадаптера EGA. На входе: AH 10h AL 01h - установка цвета рамки BH Значение, записываемое в регистр (цвет) На выходе: Не используются Программа BORDER, приведенная в листинге 5.4, использует подфункцию 01h для изменения цвета рамки экрана. Листинг 5.4. Файл BORDER.C #include "dos.h"
#include "stdio.h"
#include "conio.h"
void main(void);
// Главная функция
void main(void) {
union REGS inregs, outregs;
unsigned char i;
// Пробуем 16 цветов для рамки
for(i = 0; i "16; i++) {
// Функция управления контроллером атрибутов
inregs.h.ah = 0x10;
// Подфункция установки цвета рамки
inregs.h.al = 0x1;
// Номер нового цвета рамки
inregs.h.bh = i;
int86( 0x10, inregs, outregs );
// Ожидаем нажатия на любую клавишу
printf("\nДля изменения цвета рамки "
"нажмите любую клавишу...");
getch();
}
} Установка всех регистров палитры - подфункция 02h Функция обеспечивает быстрое заполнение новыми значениями всех регистров палитры и регистра цвета рамки. Новые значения регистров должны быть записаны перед вызовом функции в таблице размером 17 байт, расположенной в оперативной памяти компьютера. Байты 0 - 15 этой таблицы содержат новые значения для регистров палитры, а байт 16 новое значение для регистра цвета рамки. На входе: AH 10h AL 02h - установка регистров палитры и регистра цвета рамки ES:DX Адрес таблицы с новыми значениями регистров На выходе: Не используются Управление атрибутом мигания и атрибутом интенсивности - подфункция 03h Управляет битом D7 байта атрибутов символа (см. главу "Атрибуты символов"): На входе: AH 10h AL 03h - управление битом D7 байта атрибутов BL 0 - бит D7 байта атрибутов управляет интенсивностью фона символов (символы не мигают), 1 - бит D7 байта атрибутов управляет миганием символов На выходе: Не используются Функция ControlBlinkIntens, представленная листингом 5.4, иллюстрирует использование подфункции 03h для управления атрибутами символов. Листинг 5.4. Файл CNRBLINK.C // ____________________ =
// void ControlBlinkIntens(unsigneg char blink)
// Функция управляет назначением бита D7 байта атрибутов
// символа
// Параметры:
// blink - если параметр функции равен нулю, то бит D7
// будет определять интенсивность фона символа. Если
// параметр равен единице, то бит D7 управляет миганием
// символа
//- ____________________ =
ControlBlinkIntens(unsigneg char blink) {
union REGS inregs, outregs;
// Функция управления контроллером атрибутов
inregs.h.ah = 0x10;
// Подфункция управления атрибутом мигания/интенсивности
inregs.h.al = 0x3;
inregs.h.bl = blink;
int86( 0x10, inregs, outregs );
} Чтение регистра палитры - подфункция 07h Функция поддерживается только видеоадаптерами VGA и SVGA. Она позволяет прочитать содержимое любого регистра палитры: На входе: AH 10h AL 07h - чтение регистра палитры BL Номер регистра палитры (0-15) На выходе: BH Значение указанного регистра палитры mov ah,10h
mov al,7h
mov bl,num_reg
int 10h
mov reg_value,bh Чтение регистра цвета рамки - подфункция 08h Функция поддерживается только видеоадаптерами VGA и SVGA. Позволяет прочитать содержимое регистра цвета рамки: На входе: AH 10h AL 08h - чтение регистра цвета рамки На выходе: BH Значение регистра цвета рамки Чтение всех регистров палитры - подфункция 09h Функция позволяет прочитать значения всех регистров палитры и регистра цвета рамки. Для чтения регистров надо зарезервировать буфер в оперативной памяти размером 17 байт. После вызова функции байты 0 - 15 этого буфера будут содержать значения соответствующих регистров палитры, а байт 16 - значение регистра цвета рамки. На входе: AH 10h AL 9 - чтение всех регистров палитры ES:DX Указатель на буфер размером 17 байт На выходе: ES:DX Указатель на буфер, заполненный значениями из регистров палитры и регистра цвета рамки Приведем фрагмент программы, который считывает значения всех регистров палитры и регистра цвета рамки в буфер памяти buffer:; Определяем адрес буфера для записи значений регистров
; палитры и регистра цвета рамки
mov ax,SEG buffer
mov es,ax
mov dx,OFFSET buffer
; Считываем значения всех регистров палитры и регистра
; цвета рамки
mov ah,10h
mov al,9
int 10h Установка регистра таблицы цветов (регистров ЦАП) - подфункция 10h Функция производит запись 18-битной величины в один из 256 регистров таблицы цветов: На входе: AH 10h AL 10h - установка регистра таблицы цветов BX Номер регистра таблицы цветов (0-255) DH Интенсивность красного цвета (6 бит) CH Интенсивность зеленого цвета (6 бит) CL Интенсивность синего цвета (6 бит) На выходе: Не используются Пример использования функции установки одного регистра таблицы цветов приведен ниже: mov ah,10h
; Выбираем функцию установки регистра цветов
mov al,ah
; Устанавливаем номер регистра таблицы цветов
mov bx,num_reg
; Определяем величины красной, зеленой и синей составляющих
mov dh,red
mov ch,green
mov cl,blue
int 10h Установка нескольких регистров таблицы цветов (регистров ЦАП) - подфункция 12h Функция производит запись 18-битной величины в несколько последовательно расположенных регистров таблицы цветов: На входе: AH 10h AL 12h - установка нескольких регистров таблицы цветов BX Номер первого регистра таблицы цветов (0-255) CX Количество регистров для записи (1-256) ES:DX Адрес таблицы цветов На выходе: Не используются Таблица цветов содержит по три байта на один регистр таблицы цветов. В каждом байте значимыми являются только 6 младших бит. Выбор подмножества цветов - подфункция 13h??? Функция предназначена для выбора числа подмножеств цветов и выбора активного подмножества: На входе: AH 10h AL 13h - выбор подмножества цветов BL 0 - выбор режима BH 0 - 4 подмножества из 64 цветов 1 - 16 подмножеств из 16 цветов BL 1 - выбор активного подмножества BH Номер подмножества (0-4 или 0-15) На выходе: Не используются Приведем фрагмент программы использующий данную функцию:; Выбираем режим (bh = 1)
mov ah,10h
mov al,13h
xor bx,bx
inc bh
int 10h
; Устанавливаем активное подмножество subset_num
mov ah,10h
mov al,13h
mov bl,1
mov bh,subset_num
int 10h Чтение регистра таблицы цветов - подфункция 15h Функция поддерживается только для видеоадаптеров VGA и SVGA. Она выполняет чтение одного из регистров таблицы цветов: На входе: AH 10h AL 15h - чтение регистра таблицы цветов BL Номер регистра (0-255) На выходе: DH Интенсивность красного цвета (6 бит) CH Интенсивность зеленого цвета (6 бит) CL Интенсивность синего цвета (6 бит) Следующий пример позволяет считать значение регистра таблицы цветов с номером num_color_reg: mov ah,10h
mov al,15h
mov bx,num_color_reg
int 10h
mov red_data,dh
mov green_data,ch
mov blue_data,cl Чтение нескольких регистров таблицы цветов (регистров ЦАП) - подфункция 17h Функция производит чтение 18-битовых значений из нескольких последовательно расположенных регистров таблицы цветов: На входе: AH 10h AL 17h - чтение нескольких регистров таблицы цветов BL Номер первого регистра таблицы цветов (0 -255) CX Количество регистров для чтения (1-256) ES:DX Адрес буфера для таблицы цветов На выходе: ES:DX Данные прочитанные из таблицы цветов Таблица цветов содержит по три байта на один регистр таблицы цветов. В каждом байте значащими являются только младшие 6 бит. Определение режима подмножества цветов - подфункция 1Ah??? Возвращает количество текущих цветовых подмножеств: На входе: AH 10h AL 1Ah - определение числа цветовых подмножеств На выходе: BL 0 - используются 4 цветовых подмножества по 64 цвета; 1 - используются 16 цветовых подмножеств по 16 цветов BH Номер подмножества, используемого в данный момент mov ah,10h
mov al,1ah
int 10h
mov num_subset,bh Установка палитры из градаций серого цвета - подфункция 1Bh Функция заполняет часть таблицы цветов значениями, соответствующими различным оттенкам серого цвета. Для каждого модифицируемого регистра таблицы цветов сначала читаются записанные в нем данные, а затем записываются обратно по следующему правилу: красного 30 - процентов, зеленого - 59 процентов и голубого - 11 процентов от считанного значения. На входе: AH 10h AL 1Bh - установка палитры из градаций серого цвета BX Номер первого регистра таблицы цветов CX Количество модифицируемых регистров На выходе: Не используются Следующий пример демонстрирует, как преобразовать таблицу цветов для отображения различных градаций серого цвета. Модифицируются значения регистров таблицы цветов, имеющих номера от first_num до end_num: mov ah,10h
mov al,1Bh
; Номер первого модифицируемого регистра
mov bx,first_num
; Номер последнего модифицируемого регистра
mov cx,end_num
; Определяем число изменяемых регистров
sub cx,bx
int 10h Программа BIOSDAC демонстрирует использование функций BIOS для управления таблицей цветов. Исходный текст программы BIOSDAC представлен на листинге 5.5. Листинг 5.5. Файл BIOSDAC.C #include "conio.h"
#include "stdio.h"
#include "dos.h"
#include "sysp.h"
typedef struct _RGB_ {
unsigned char red;
unsigned char green;
unsigned char blue;
} RGB;
// Объявление функций
void main(void);
void SetVideoMode(unsigned char);
void SetVgaDAC(unsigned, unsigned);
void GrayScale(void);
//- ____________________ 
// Главная функция
//- ____________________ 
void main(void)
{
RGB color_table[256];
unsigned char i,j;
unsigned char far *ptr;
int error, x_num, y_num;
unsigned seg_table,off_table;
// Формируем новые значения для таблицы цветов
for(j = 0; j "4; j++) {
for(i = 0; i "64; i++) {
(color_table[i+j*64]).red =
(j - 0)? i: (j - 4)? i: 0;
(color_table[i+j*64]).green =
(j - 1)? i: (j - 3)? i: (j - 4)? i: 0;
(color_table[i+j*64]).blue =
(j - 2)? i: (j - 3)? i: (j - 4)? i: 0;
}
}
// Устанавливаем режим номер 13h
SetVideoMode(0x13);
ptr = (unsigned char far*) color_table[0];
seg_table = FP_SEG(ptr);
off_table = FP_OFF(ptr);
// Загружаем таблицу цветов
SetVgaDAC(seg_table,off_table);
// Записываем данные в видеопамять
ptr = (unsigned char far*) (FP_MAKE(0xA000, 0x0));
for(y_num = 0; y_num "200; y_num++) {
for(x_num = 0; x_num "320; x_num++) {
*ptr = (unsigned char) x_num;
ptr++;
}
}
// Ожидаем нажатие на клавишу клавиатуры
getch();
// Преобразовываем данные в таблице цветов к серому цвету
GrayScale();
// Ожидаем нажатие на клавишу клавиатуры
getch();
// Устанавливаем текстовый режим
SetVideoMode(0x3);
}
//- ____________________ 
// Функция установки режима
//- ____________________ 
void SetVideoMode( unsigned char vmode ) {
union REGS regs;
regs.h.ah = 0x0;
regs.h.al = vmode;
int86(0x10, regs, regs);
}
//- ____________________ 
// Функция загрузки таблицы цветов
//- ____________________ 
void SetVgaDAC(unsigned seg_table, unsigned off_table) {
union REGS regs;
struct SREGS segregs;
regs.x.ax = 0x1012;
regs.x.cx = 256;
regs.x.bx = 0x00;
segregs.es = seg_table;
regs.x.dx = off_table;
int86x(0x10, regs, regs, segregs);
}
//- ____________________ 
// Функция преобразования таблицы цветов в серый цвет
//- ____________________ 
void GrayScale( void ) {
union REGS regs;
regs.x.ax = 0x101b;
regs.x.cx = 256;
regs.x.bx = 0x00;
int86(0x10, regs, regs);
} Загрузка таблиц знакогенератора - функция 11h Функция 11h прерывания 10h предназначена для загрузки в видеопамять таблиц знакогенератора (наборов символов). При помощи данной функции можно загружать как стандартные таблицы знакогенератора, так и таблицы, самостоятельно разработанные программистом. Загружается либо вся таблица, либо ее часть. Функция позволяет легко русифицировать видеоадаптер (если это не видеоадаптер CGA или Hercules). Функция 11h имеет одиннадцать различных подфункций, перечисленных ниже: Номер подфункции Назначение 0 Загрузка таблиц знакогенератора 1 Загрузка стандартного монохромного набора символов 2 Загрузка стандартного набора символов видеоадаптера CGA 3 Выбор активных таблиц знакогенератора (EGA) 4 Загрузка стандартного набора символов видеоадаптера VGA и SVGA 20h Установка вектора прерывания 1Fh 21h Использование графического режима для отображения символов пользователя 22h Использование набора символов 8х14 из ПЗУ 23h Использование набора символов 8х8 из ПЗУ 24h Использование набора символов 8х16 из ПЗУ 30h Получение информации об используемом наборе символов Для подфункций 0, 1, 2, 3 и 4 установка бита D4 в регистре AL вызывает перезагрузку регистров контроллера ЭЛТ. Вновь устанавливаются значения принятые по умолчанию для регистров формы курсора и регистра высоты символа текста. Если используется эта возможность, вызов функции должен происходить сразу после выбора режима работы видеоадаптера. В противном случае вызов функции 11h может привести к непредсказуемым последствиям. Загрузка набора символов пользователя - подфункция 00h Функция заменяет текущий набор символов знакогенератора или его часть набором символов, определенных пользователем. Таблица знакогенератора пользователя должна быть загружена в буфер оперативной памяти до вызова функции. После вызова она может быть удалена из памяти. На входе: AH 11h AL 00h, 10h - загрузка набора символов пользователя CX Количество загружаемых символов. Может принимать значение от 1 до 256 DX ASCII-код первого загружаемого символа. Используется для загрузки части набора символов BL Номер загружаемой таблицы знакогенератора - для видеоадаптера EGA доступны таблицы 0 - 3, для VGA и SVGA 0 - 7 BH Количество байт, определяющих один символ в таблице символов ES:BP Адрес буфера, содержащего определение символов, загружаемых в таблицу знакогенератора На выходе: Не используются Загрузка набора символов из BIOS - подфункция 01h Функция загружает стандартный набор символов размера 8х14 пикселов из ПЗУ BIOS во второй цветовой слой видеопамяти: На входе: AH 11h AL 01h, 11h - загрузка набора символов 8х14 BL Номер загружаемой таблицы знакогенератора (для видеоадаптера EGA доступны таблицы 0 - 3, для VGA 0 - 7) На выходе: Не используются Загрузка набора символов из BIOS - подфункция 02h Функция загружает стандартный набор символов CGA размера 8х8 пикселов из ПЗУ BIOS во второй цветовой слой видеопамяти: На входе: AH 11h AL 02h, 12h - загрузка набора символов размера 8х8 пикселов BL Номер загружаемой таблицы знакогенератора (для видеоадаптера EGA доступны таблицы 0 - 3, для VGA 0 - 7) На выходе: Не используются Выбор активных таблиц знакогенератора - подфункция 03h Программа через эту функцию может установить активные таблицы знакогенератора. Напомним, что видеоадаптер EGA имеет четыре таблицы, одна или две из которых могут быть активными, а VGA - восемь. Каждая таблица содержит 256 символов. Одновременно могут отображаться 512 символов. Номер используемой таблицы определяется битом D3 байта атрибутов символа. На входе: AH 11h AL 03h - выбор активных таблиц знакогенератора BL Выбирает активные таблицы: D1-D0 номер таблицы, используемой, когда бит D3 атрибута равен нулю; D3-D2 номер таблицы используемой, когда бит D3 атрибута равен единице; D4 только для VGA. Расширение для битов D0 и D1; D5 только для VGA. Расширение для битов D2 и D3; D7-D6 не используются На выходе: Не используются Загрузка набора символов из BIOS - подфункция 04h Функция загружает стандартный набор символов VGA размера 8х16 пикселов из ПЗУ BIOS во второй цветовой слой видеопамяти: На входе: AH 11h AL 04h, 14h - загрузка набора символов размера 8х16 пикселов BL Номер загружаемой таблицы знакогенератора (для видеоадаптера VGA доступны таблицы 0 - 7) На выходе: Не используются Установка вектора прерывания 1Fh - подфункция 20h Используется в графических режимах 4, 5 и 6 (совместимых с CGA), если необходимо отображать одновременно больше 128 символов. Вектор 1Fh указывает на таблицу с дополнительными 128 символами, имеющими коды ASCII от 127 до 255. Программа должна поддерживать таблицы для дополнительных символов. Размер символов должен быть 8х8 пикселов. На входе: AH 11h AL 20h - установка вектора прерывания 1Fh, который хранит адрес таблицы дополнительных символов ES:BP Адрес таблицы дополнительных символов, определенной пользователем На выходе: Не используются Установка набора символов для графических режимов - подфункция 21h Позволяет установить собственный набор символов для отображения текста в графических режимах видеоадаптера. На входе: AH 11h AL 21h - установка вектора прерывания 43h ES:BP Адрес таблицы символов, определенной пользователем CX Количество байт, кодирующих один символ в таблице символов BL Количество строк текста, отображаемых на экране монитора: 0 - количество строк определяется регистром DL; 1 - 14 строк; 2 - 25 строк; 3 - 43 строки DL Количество строк текста, отображаемых на экране. Используется только если регистр BL равен нулю На выходе: Не используются Установка набора символов 8х14 из ПЗУ BIOS На входе: AH 11h AL 22h - установка вектора прерывания 43h BL Количество строк текста, отображаемых на экране монитора: 0 - количество строк определяется регистром DL; 1 - 14 строк; 2 - 25 строк; 3 - 43 строки DL Количество строк текста, отображаемых на экране. Используется только если регистр BL равен нулю На выходе: Не используются Установка набора символов 8х8 из ПЗУ BIOS На входе: AH 11h AL 23h установка вектора прерывания 43h BL Количество строк текста, отображаемых на экране монитора: 0 - количество строк определяется регистром DL; 1 - 14 строк; 2 - 25 строк; 3 - 43 строки DL Количество строк текста, отображаемых на экране. Используется только если регистр BL равен нулю На выходе: Не используются Установка набора символов 8х16 из ПЗУ BIOS На входе: AH 11h AL 24h установка вектора прерывания 43h BL Количество строк текста, отображаемых на экране монитора: 0 - количество строк определяется регистром DL; 1 - 14 строк; 2 - 25 строк; 3 - 43 строки DL Количество строк текста, отображаемых на экране. Используется только если регистр BL равен нулю На выходе: Не используются Получение информации об используемом наборе символов - подфункция 30h Функция позволяет получить информацию об используемом наборе символов - высоту символа, число текстовых строк на экране и т.д. На входе: AH 11h AL 30h BH Тип запрашиваемой информации: 0 - вернуть содержимое вектора INT 1Fh; 1 - вернуть содержимое вектора INT 43h; 2 - вернуть указатель на набор символов размера 8х14 пикселов, расположенный в ПЗУ BIOS; 3 - вернуть указатель на набор символов размера 8х8 пикселов, расположенный в ПЗУ BIOS; 4 - вернуть указатель на символы с ASCII кодами от 127 до 255 (размера 8х8 пикселов), расположенные в ПЗУ BIOS; 5 - вернуть указатель на альтернативный набор символов размером 9х14 пикселов, расположенный в ПЗУ BIOS; 6 - вернуть указатель на набор символов размером 8х16 пикселов, расположенный в ПЗУ BIOS; 7 - вернуть указатель на альтернативный набор символов размером 9х16 пикселов, расположенный в ПЗУ BIOS На выходе: CL Высота символов в пикселах DL Количество текстовых строк на экране - 1 ES:BP Указатель на таблицу символов (значение зависит от значения регистра BH) Определение конфигурации и выбор программы распечатки экрана - функция 12h Функция 12h содержит девять различных подфункций: Номер подфункции Назначение 10h Определение конфигурации видеоадаптера 20h Выбор программы печати экрана 30h Выбор количества линий развертки в текстовом режиме 31h Запрещение загрузки палитры цветов, принятой по умолчанию 32h Управление доступом к видеопамяти и регистрам видеоадаптера 33h Управление преобразованием серого цвета 34h Управление эмуляцией курсора видеоадаптера CGA 35h Выбор активного монитора (PS/2) 36h Гашение экрана монитора Определение конфигурации видеоадаптера - подфункция 10h Проверяет наличие видеоадаптеров EGA/VGA, а также позволяет получить данные о текущем состоянии видеоадаптера: На входе: AH 12h BL 10h - определение конфигурации EGA/VGA На выходе: BH Режим видеоадаптера устанавливаемый по умолчанию: 0 - цветной режим, 1 - монохромный режим BL Объем видеопамяти (для видеоадаптера EGA): 0 - 64 Кбайт, 1 - 128 Кбайт, 2 - 192 Кбайт, 3 - 256 Кбайт CH Биты управления дополнительным устройством CL Положение переключателей на плате видеоадаптера EGA Если видеоадаптер, установленный на компьютере, не является видеоадаптером EGA, VGA или SVGA, то регистр BX не изменяет своего значения. Это можно использовать для проверки наличия видеоадаптеров EGA/VGA: mov ah, 12h
; Определение конфигурации EGA/VGA
mov bl, 10h
mov bh, 55h
int 10h
; Изменился ли регистр BX
cmp bx, 5510h
; Если нет, то видеоадаптеры EGA/VGA не обнаружены
je ega_vga_not_found Выбор программы печати экрана - подфункция 20h Программа, распечатывающая содержимое экрана монитора по нажатию клавиши "Print Screen", не работает в режиме 43 текстовых строк. Если вы желает иметь эту возможность, можете выбрать альтернативную программу печати экрана, воспользовавшись подфункцией номер 20h: На входе: AH 12h BL 20h - выбор альтернативной программы печати экрана монитора На выходе: Не используются Выбор количества линий развертки в текстовом режиме - подфункция 30h Функция используется для получения на видеоадаптере VGA текстовых режимов, внешне не отличающихся от CGA или MDA. На входе: AH 12h BL 30h - выбор числа линий развертки AL Количество строк развертки: 0 - 200 строк развертки, размер символа 8х8 пикселов, 1 - 350 строк развертки, размер символа 8х14 пикселов, 2 - 400 строк развертки, размер символа 8х16 пикселов На выходе: AL 12h Функция 30h возвращает в регистре AL значение 12h, если компьютер имеет видеоадаптер VGA или SVGA. Эта особенность может использоваться для определения типа видеоадаптера. Запрещение переустановки палитры - подфункция 31h Функция применяется для предотвращения перезагрузки таблицы цветов при выполнении операции выбора режима работы видеоадаптера VGA: На входе: AH 12h BL 31h - запрещение переустановки палитры AL Разрешение/запрещение переустановки: 0 - разрешить загрузку палитры при выполнении операции выбора режима видеоадаптера, 1 - запретить загрузку палитры при выполнении операции выбора режима видеоадаптера На выходе: AL 12h Управление доступом к видеоадаптеру - подфункция 32h Вызов функции позволяет запретить (разрешить) доступ к видеопамяти и регистрам адаптера VGA/SVGA. На входе: AH 12h BL 32h - управление доступом к видеоадаптеру AL Разрешение/запрещение доступа: 0 - разрешить доступ, 1 - запретить доступ На выходе: AL 12h Управление преобразованием серого цвета - подфункция 33h Поддерживается только видеоадаптерами VGA и SVGA. Если разрешено преобразование, то при загрузке регистров таблицы цветов (операцией выбора режима работы видеоадаптера или непосредственным вызовом функции загрузки этих регистров) происходит корректировка записываемых значений. После этого содержимое регистров будет соответствовать различным градациям серого цвета. На входе: AH 12h BL 33h - управление преобразованием серого цвета AL Разрешение/запрещение преобразования: 0 - разрешить преобразование, 1 - запретить преобразование На выходе: AL 12h Приведем фрагмент программы, использующий функцию 33h для управления преобразованием серого цвета: enable:
; Разрешение преобразования содержимого регистров
; таблицы цветов в шкалу градаций серого цвета
xor al,al
jmp conversion
disable:
; Запрещение преобразования содержимого регистров
; таблицы цветов
mov al,1
conversion:
mov ah,12h
mov bl,33h
int 10h Эмуляция курсора CGA - подфункция 34h Функция 34h управляет режимом эмуляции курсора CGA. При разрешении эмуляции курсора CGA, его размеры устанавливаются, исходя из того, что символы имеют высоту 8 пикселов. На входе: AH 12h BL 34h - управление эмуляцией курсора CGA AL Разрешение/запрещение эмуляции курсора: 0 - разрешить эмуляцию, 1 - запретить эмуляцию На выходе: AL 12h Выбор активного монитора - подфункция 35h Используется в системе PS/2 для переключения между видеоадаптером VGA, расположенным на системной плате компьютера, и дополнительным видеоадаптером. Функция работает даже если между видеоадаптерами существует конфликт по адресам видеопамяти или адресам портов ввода/вывода. Система PS/2 после загрузки в качестве первичного видеоадаптера использует дополнительный. Программа, выполняющая переключение видеоадаптеров должна поддерживать 128-байтовый буфер для сохранения информации о состоянии неактивного видеоадаптера. На входе: AH 12h BL 35h - выбор активного монитора для PS/2 ES:DX Адрес буфера. Размер буфера должен составлять 128 байт AL 0 - выключить дополнительный видеоадаптер (должно быть использовано при первом вызове функции), 1 - включить видеоадаптера VGA, расположенный на системной плате (должно быть использовано при втором вызове функции), 2 - выключить активный видеоадаптер (используется в последующих вызовах функции), 3 - включить неактивный видеоадаптер (используется в последующих вызовах функции) На выходе: AL 12h Гашение экрана монитора - подфункция 36h Видеоадаптеры VGA и SVGA имеют возможность гашения экрана монитора: На входе: AH 12h BL 36h - управление гашением экрана монитора AL 0 - включить отображение информации на экране монитора, 1 - погасить экран монитора На выходе: AL 12h Функция возвращает в регистре AL значение 12h, если компьютер имеет видеоадаптер VGA. Вывод текстовой строки - функция 13h Функция 13h предоставляет широкие возможности для вывода текстовых строк на экран монитора. В зависимости от параметров функции, можно определять атрибуты как строки в целом (атрибуты всех символов одинаковы), так и отдельных символов строки. После вывода строки на экран, курсор может либо оставаться на месте, либо переместиться в позицию за последним символом только что выведенной строки. Данная функция обрабатывает следующие управляющие символы: звуковой сигнал (BELL), перевод курсора на одну позицию назад (BACKSPACE), возврат каретки (CARRIAGE RETURN) и перевод строки (LINEFEED). На входе: AH 13h - вывод строки на экран AL Режим отображения строки: 0 - курсор не перемещается, атрибуты символов в строке одинаковы и определяются значением регистра BL, 1 - курсор перемещается за конец отображаемой строки, атрибуты символов в строке одинаковы и определяются значением регистра BL, 2 - курсор не перемещается, атрибуты каждого символа задаются отдельно, 3 - курсор перемещается, атрибуты каждого символа задаются отдельно BH Номер страницы видеопамяти BL Атрибуты символов отображаемого текста. Используется если регистр AL содержит 0 или 1 CX Длина отображаемой строки DH Номер строки экрана, в которой отображается текстовая строка DL Позиция в строке экрана с которой отображается текстовая строка ES:BP Адрес строки в оперативной памяти На выходе: Не используются В режимах 2 и 3 атрибуты каждого символа задаются вперемежку с самими символами строки. Сначала идет ASCII-код символа, а затем его атрибут. Чтение/запись конфигурации видеосистемы - функция 1Ah Функция содержит две подфункции для чтения и записи текущей конфигурации видеосистемы компьютера. Функция 1Ah реализована только для видеоадаптеров VGA и SVGA. Если после вызова функции регистр AL не содержит число 1Ah, это значит, что функция не поддерживается данным видеоадаптером и для определения конфигурации надо использовать другие способы. Чтение конфигурации видеосистемы - подфункция 00h При помощи этой функции можно определить конфигурацию видеосистемы компьютера: На входе: AH 1Ah AL 00h - чтение конфигурации видеосистемы На выходе: AL 1Ah BL Тип первичного видеоадаптера: 0 - монитор отсутствует, 1 - MDA с монохромным монитором, 2 - CGA с цветным монитором, 3 - EGA с улучшенным цветным монитором, 4 - EGA с цветным монитором, 5 - EGA с монохромным монитором, 6 - PGC (профессиональный графический контроллер); 7 - VGA с монохромным аналоговым монитором, 8 - VGA с цветным аналоговым монитором, 0Ah - MCGA с цветным цифровым монитором. 0Bh - MCGA с монохромным аналоговым монитором, 0Ch - MCGA с цветным аналоговым монитором BH Тип дополнительного видеоадаптера (см. регистр BL) Запись конфигурации видеосистемы - подфункция 01h Данная функция позволяет изменить информацию о конфигурации видеосистемы компьютера: На входе: AH 1Ah AL 01h - запись конфигурации видеосистемы BL Тип первичного видеоадаптера (см. подфункцию 00h) BH Тип дополнительного видеоадаптера (см. подфункцию 00h) На выходе: AL 1Ah Получение данных о состоянии VGA - функция 1Bh Функция позволяет получить различную информацию о видеоадаптере и мониторе. Программа, вызывающая данную функцию, должна зарезервировать буфер с размером 64 байта для получаемых данных. На входе: AH 1Bh - получение данных о видеосистеме BX 00h ES:DI Адрес буфера для записи данных, 64 байта На выходе: AL 1Bh ES:DI Буфер заполненный данными (см. таблицу ниже) Формат буфера представлен в следующей таблице: Смещение, байт Размер Содержание 0 Двойное слово Адрес статической таблицы функций (см. ниже) 4 Байт Номер текущего режима работы видеоадаптера 5 Слово Количество символов в строке 7 Слово Размер отображаемой области видеоданных (в байтах) 9 Слово Начальный адрес отображаемой области видеоданных 0Bh 8 слов Позиции курсоров для каждой из 8 страниц видеопамяти (одно слово на страницу). В старшем байте записан номер колонки, в младшем байте номер строки курсора 1Bh Байт Нижняя линия курсора 1Ch Байт Верхняя линия курсора 1Dh Байт Номер активной страницы видеопамяти 1Eh Слово Адрес индексного порта контроллера ЭЛТ (3B4/3D4) 20h Байт Состояние регистра 3x8h 21h Байт Состояние регистра 3x9h 22h Байт Количество текстовых строк на экране 23h Байт Высота символов текста в пикселах 25h Байт Код первичного видеоадаптера (см. функцию 1Ah подфункция 0h) 26h Байт Код дополнительного видеоадаптера (см. функцию 1Ah подфункция 0h) 27h Слово Количество одновременно отображаемых цветов в текущем режиме 29h Байт Количество страниц видеопамяти, доступных в текущем режиме 2Ah Байт Количество строк развертки в текущем режиме: 0 - 200; 1 - 350; 2 - 400; 3 - 480 2Bh Байт Номер первой таблицы знакогенератора 2Ch Байт Номер второй таблицы знакогенератора 2Dh Байт Байт, содержащий различные данные: D0 не используется; D1 бит равен единице, если разрешено преобразование палитры в серый цвет; D2 бит равен единице, если подключен монохромный монитор; D3 запрещена перезагрузка регистров палитры при выборе режима видеоадаптера; D4 бит равен единице, если разрешена эмуляция курсора CGA; D5 определяет назначение бита D3 байта атрибутов: если бит равен 1, то он управляет миганием символа, если бит равен нулю, то бит D3 управляет интенсивностью фона символа; D7-D6 не используется 2Eh Байт Зарезервировано 2Fh Байт Зарезервировано 31h Байт Объем видеопамяти адаптера: 0 - 64 Кбайт, 1 - 128 Кбайт, 2 - 192 Кбайт, 3 - 256 Кбайт 32h Байт Состояние области сохранения:??? D0 бит равен единице, если используется набор из 512 символов; D1 бит равен единице, если используется область сохранения цветовой палитры; D2 бит равен единице, если используется текстовый набор символов пользователя; D3 бит равен единице, если используется графический набор символов пользователя; D4 бит равен единице, если используется цветовая палитра, определенная пользователем; D7-D5 зарезервировано 33h - 3Fh Зарезервировано Далее следует описание статической функциональной таблицы: Смещение, байт Размер Содержание 0 Байт Таблица режимов работы видеоадаптера. Если бит равен единице, то режим поддерживается: D0 Режим 00h; D1 режим 01h; D2 режим 02h; D3 режим 03h; D4 режим 04h; D5 режим 05h; D6 режим 06h; D7 режим 07h 1 Байт D0 Режим 08h; D1 режим 09h; D2 режим 0Ah; D3 режим 0Bh; D4 режим 0Ch; D5 режим 0Dh; D6 режим 0Eh; D7 режим 0Fh 2 Байт D0 Режим 10h; D1 режим 11h; D2 режим 12h; D3 режим 13h; D7-D4 Не используются 3 4 байта Зарезервировано 7 Байт Количество строк растра в текстовых режимах. Если бит равен единице, то режим поддерживается: D0 200 строк растра; D1 350 строк растра; D2 400 строк растра; D7-D3 не используются 8 Байт Количество таблиц знакогенератора, которые можно одновременно использовать (для текстовых режимов) 9 Байт Количество таблиц знакогенератора, доступных в текстовом режиме 0Ah Байт Биты имеют различное назначение:??? D0 не используется; D1 поддерживается преобразование таблицы цветов в серые цвета; D2 поддерживается загрузка шрифтов пользователя; D3 поддерживается загрузка цветовой палитры по умолчанию; D4 поддерживается эмуляция курсора CGA; D5 присутствует палитра EGA; D6 присутствует таблица цветов; D7 поддерживается функция выбора множества цветов 0Bh Байт Биты имеют различное назначение:??? D0 поддерживается световое перо; D1 сохранение/восстановление видеосостояний, поддерживается функция 1Ch; D2 управление битом D3 байта атрибутов; D3 код конфигурации монитора D7-D4 не используются 0Ch 2 байта Зарезервировано 0Eh Байт Состояние указателя:??? D0 бит равен единице, если поддерживается набор из 512 символов D1 бит равен единице, если поддерживается область сохранения цветовой палитры D2 бит равен единице, если поддерживается текстовый набор символов пользователя D3 бит равен единице, если поддерживается графический набор символов пользователя D4 бит равен единице, если поддерживается цветовая палитра, определенная пользователем D7-D5 зарезервировано 0Fh Байт Зарезервировано Сохранение/восстановление состояния видеоадаптера - функция 1Ch Функция имеет три подфункции, при помощи которых программа может быстро переключать режимы работы видеоадаптера: Номер подфункции Назначение 00h Определение размера буфера, необходимого для сохранения текущего состояния видеоадаптера 01h Сохранение текущего состояния видеоадаптера 02h Восстановление текущего состояния видеоадаптера Необходимо отметить, что данная функция поддерживается только для видеоадаптеров VGA и SVGA. Функцию можно использовать при переключении режима видеоадаптера в резидентных программах и мультизадачных системах. Определение размера буфера - подфункция 00h Функция определяет размер буфера, необходимый для сохранения текущего состояния видеоадаптера. Буфер должен быть зарезервирован до вызова функции сохранения состояния видеоадаптера. На входе: AH 1Ch AL 00h - определение размера буфера CX Тип данных, который необходимо сохранить (1 - надо сохранять, 0 - не надо сохранять): D0 - регистры видеоадаптера, D1 - область переменных BIOS, D2 - таблица цветов (регистры ЦАП) На входе: AL 1Ch BX Размер буфера в 64-байтных блоках Сохранение текущего состояния видеоадаптера - подфункция 01h Функция записывает данные состояния видеоадаптера в буфер, размер которого определяется подфункцией 00h. На входе: AH 1Ch AL 01h - сохранение состояния видеоадаптера CX Тип данных, который необходимо сохранить: D0 - регистры видеоадаптера, D1 - область переменных BIOS, D2 - таблица цветов (регистры ЦАП) ES:BX Адрес буфера для сохраняемых данных На выходе: AL 1Ch Восстановление текущего состояния видеоадаптера - подфункция 02h Функция восстанавливает состояние видеоадаптера из буфера, заполненного подфункцией 01h. На входе: AH 1Ch AL 02h - восстановление состояния видеоадаптера CX Тип восстанавливаемых данных: D0 - регистры видеоадаптера, D1 - область переменных BIOS, D2 - таблица цветов (регистры ЦАП) ES:BX Адрес буфера данных состояния видеоадаптера На выходе: AL 1Ch Русификация видеоадаптеров Видеоадаптеры поддерживают стандартную расширенную таблицу ASCII символов. Если эта таблица не содержит образов символов кириллицы, то ваш компьютер не может отображать их на экране. Однако в некоторых случаях стандартную таблицу символов можно перекодировать, заменив образы некоторых символов на образы символов кириллицы. В этом приложении мы рассмотрим вопрос "русификации" видеоадаптеров CGA, EGA и VGA. У видеоадаптера CGA таблицы знакогенератора, определяющие символы, которые можно отобразить на экране монитора в текстовых режимах находятся в ПЗУ, которое расположено вне адресного пространства процессора. Программы не имеют возможности изменить или даже считать информацию из этих таблиц. Поэтому для "русификации" текстовых режимов видеоадаптера CGA необходимо перепрограммировать ПЗУ знакогенератора. Единственной возможностью отобразить на CGA русские буквы не перепрограммируя ПЗУ является использование графических режимов работы адаптера. В графических режимах вы можете сами определить образы символов с ASCII кодами от 128 до 255. Образы символов с ASCII кодами от 0 до 127 изменить не перепрограммируя ПЗУ нельзя. Как определить образы символов с кодами 128 - 255? Для этого надо составить таблицу шрифтов в которой описаны образы символов с кодами 128 - 255. Для видеоадаптера CGA, размеры символов которого равны 8х8 пикселов описание образа каждого символа состоит из восьми байт. Первый байт описывает первую линию символа, второй - вторую и так далее. Если биты данных, описывающих символы, равны единице, соответствующие пикселы на линии символа будут отображаться светлыми пикселами. Остальные пикселы будут темными. На рисунке 5.2 приведен пример определения образа символа 'А'. \* MERGEFORMAT Рисунок 5.2 Определение образа символа В этом примере образ символа 'А' определяется байтами 00h, 0Eh, 12h, 22h, 3Eh, 22h, 22h, 22h. Составив таблицу шрифтов надо записать адрес этой таблицы в векторе прерывания 1Fh. После этого можно выводить определенные вами символы на экран. Для видеоадаптеров EGA и VGA задача русификации облегчается, так как вы имеете доступ к таблицам шрифтов и можете изменять их. При установке текстовых режимов работы видеоадаптеров EGA и VGA, BIOS загружает таблицы знакогенератора из ПЗУ во второй цветовой слой видеопамяти. Впоследствии эти таблицы используются при отображении символов на экране. Благодаря этому, можно легко заменить стандартную таблицу знакогенератора своей собственной. BIOS видеоадаптеров EGA и VGA содержит специальную функцию прерывания 10h, которая управляет загрузкой шрифтов. Это функция номер 11h. Таблица шрифтов для текстовых режимов видеоадаптеров EGA и VGA имеет тот же формат что и таблица шрифтов графических режимов для CGA за исключением того, что образ каждого символа задается не восемью байтами, а четырнадцатью для EGA и шестнадцатью для VGA. В графических режимах вы можете полностью заменить образы всех символов, а не только символов, имеющих ASCII коды от 128 до 255. В этом случае вместо вектора 1Fh на таблицу символов должен указывать вектор 43h. Теперь мы приведем небольшую резидентную программу для "русификации" видеоадаптеров. Эта программа активизируется при изменении прикладной программой режима работы видеоадаптера и при загрузке шрифтов из ПЗУ. В этих случаях перед возвратом в прикладную программу она заново загружает свои таблицы шрифтов. После запуска этой программы вы можете отображать символы кириллицы как в графических, так и в текстовых режимах. Итак текст программы: Листинг 5.6. Файл RUS_DRV.ASM TITLE RUS_DRV
.MODEL tiny
 
 

 DOSSEG 

; Сегмент кода
.CODE
; Выполняем инициализацию сегментных регистров
.STARTUP
jmp start
; Файл CGA_FONT.INC содержит описание шрифта 8х8 пикселов
include CGA_FONT.INC
; Файл EGA_FONT.INC содержит описание шрифта 8х14 пикселов
include EGA_FONT.INC
; Файл VGA_FONT.INC содержит описание шрифта 8х16 пикселов
include VGA_FONT.INC
; Информация о программе, отображается на экране при
; ее запуске
hello_msg DB 254, " Драйвер русских букв.", 13, 10
DB 254, " Copyright (C) Фролов Г.В., 1992-1995"


  DB 13, 10, "$"  


; В следующие две переменные будет записан старый вектор
; прерывания 10h
off_int_10h DW?
seg_int_10h DW?
not_clr DB?
; Начало программы
start:
; Получаем и сохраняем старый вектор прерывания 10h
mov ax,3510h
int 21h
mov off_int_10h,bx
mov seg_int_10h,es
; Устанавливаем новый обработчик прерывания 10h
mov dx,OFFSET int_10h
mov ax,2510h
int 21h
; Устанавливаем режим 3 видеоадаптера
; при этом сразу загружаются новые шрифты
mov ax,3
int 10h
; Выводим сообщение о программе
; Данная функция описана в главе "Использование функций
; MS- DOS для управления видеоадаптерами"
mov ah, 9h
mov dx, OFFSET hello_msg
int 21h
; Завершаем программу, и оставляем ее резидентной в памяти
mov ax,3100h
mov dx,OFFSET resident
shr dx,1
shr dx,1
shr dx,1
shr dx,1
inc dx
int 21h
;- ____________________ 
; Новый обработчик прерывания INT 10h
;- ____________________ 
int_10h:
; Проверяем, вызвана ли функция установки режима адаптера
or ah,ah
jz set_mode; да
jmp char_gen; нет
set_mode:
; Когда вызвана функция установки режима адаптера, то
; записываем в переменную not_clr 0h, если при установке
; нового режима надо очистить видеопамять и 80h в
; противном случае
mov cs:not_clr,0
test al,80h
jz test_mode
mov cs:not_clr,80h
; Сбрасываем бит D8, его содержимое находится в not_clr
and al,7Fh
test_mode:
; Затем сохраняем значения регистров процессора
push ax
push bx
push dx
push bp
push es
push ds
push cs
pop ds
; Определяем, какой режим надо установить
; Текстовые режимы 0 - 3
cmp al,3
jbe text_0_3
; Текстовый режим 7
cmp al,7
je text_7
; Графические режимы 4 - 0Eh
cmp al,0Eh
jbe graph_Eh
; Графический режим 13h
cmp al,13h
je graph_13h
; Графические режимы 0Eh - 10h
cmp al,10h
jbe graph_10h
; Графические режимы 11h и 12h
cmp al,12h
jbe graph_12h
; Если режим нестандартный, передаем управление BIOS
; для его установки и не загружаем свой шрифт
jmp old_int_10h
; Текстовые режимы 0, 1, 2, 3, 7
text_0_3:
text_7:
; Восстанавливаем регистр AX
or al,cs:not_clr
; Вызываем старый обработчик прерывания 10h
; для установки нового режима
pushf
call DWORD PTR cs:off_int_10h
; Получаем в BX высоту символов текста в пикселах
; для установленного выше режима
; Высота символов записывается BIOS при выборе нового
; режима в переменную по адресу 0000:0485h
xor dx,dx
mov es,dx
mov bx,es:[485h]
; В соответствии с полученной нами высотой символа
; выбираем шрифт 8х8, 8х14 или 8х16 пикселов
cmp bx,8; высота символов 8 пикселов
jne line_14
; Загружаем в регистр BP смещение таблицы шрифтов 8х8,
; таблица шрифтов 8х8 пикселов определена в файле
; CGA_FONT.INC
mov bp,OFFSET fon8_ascii0
jmp set_text_font
line_14:
cmp bx,14; высота символов 14 пикселов
jne line_16
; Загружаем в регистр BP смещение таблицы шрифтов 8х14,
; таблица шрифтов 8х14 пикселов определена в файле
; EGA_FONT.INC
mov bp,OFFSET fon14_ascii0
jmp set_text_font
line_16:
cmp bx,16
; Если полученная высота символов не равна 8, 14 и 16
; завершаем обработку
jne exit_int_10h
; Загружаем в регистр BP смещение таблицы шрифтов 8х16,
; таблица шрифтов 8х16 пикселов определена в файле
; VGA_FONT.INC
mov bp,OFFSET fon16_ascii0
set_text_font:
; Загружаем наш шрифт в память
mov ax,1100h
push cs
pop es
xchg bl,bh
mov cx,256
old_int_10h:
; Вызываем старый обработчик прерывания 10h
pushf
call DWORD PTR cs:off_int_10h
exit_int_10h:
; Восстанавливаем содержимое регистров процессора
pop ds
pop es
pop bp
pop dx
pop bx
pop ax
; Завершаем обработку прерывания, возвращаем
; управление вызывающей программе
iret
; Вызывющая программа устанавливает
; графические режимы 4, 5, 6, 0Dh, 0Eh
graph_Eh:
graph_13h:
; Вызываем старый обработчик прерывания 10h
; для установки нового режима
pushf
call DWORD PTR cs:off_int_10h
; Подготавливаем регистры для выбора шрифта 8х8
mov dx,OFFSET fon8_ascii0
mov bp,OFFSET fon8_ascii128
jmp set_gr_font
; Вызывющая программа устанавливает графические режимы
; 0Fh, 10h
graph_10h:
; Вызываем старый обработчик прерывания 10h
; Для установки нового режима
pushf
call DWORD PTR cs:off_int_10h
; Подготавливаем регистры для выбора шрифта 8х8
mov dx,OFFSET fon14_ascii0
mov bp,OFFSET fon14_ascii128
jmp set_gr_font
; Вызывющая программа устанавливает графические режимы
; 11Dh, 12h
graph_12h:
; Вызываем старый обработчик прерывания 10h
; для установки нового режима
pushf
call DWORD PTR cs:off_int_10h
; Подготавливаем регистры для выбора шрифта 8х8
mov dx,OFFSET fon16_ascii0
mov bp,OFFSET fon16_ascii128
set_gr_font:
; Устанавливаем наши графические шрифты,
; изменяя векторы прерываний 1Fh и 43h
mov ax,2543h
int 21h
mov dx,bp
mov ax,251Fh
int 21h
; Завершаем обработку прерывания
jmp exit_int_10h
; Если вызывающая программа вызвала не функцию
; установки режима, проверяем вызвана ли
; функция выбора нового шрифта
char_gen:
cmp ah,11h
je gen_func
; Если нет, передаем управление старому обработчику
go_int_10h:
pushf
call DWORD PTR cs:off_int_10h
iret
gen_func:
; Если вызывается функция установки нового шрифта, то
; смотрим какая вызывается подфункция
; Вызывается подфункция загрузки шрифта 8х8 из BIOS
cmp al,1
je text_rom_8_14
; Вызывается подфункция загрузки шрифта 8х8 из BIOS
; с переустановкой контроллера ЭЛТ
cmp al,11h
je text_rom_8_14
; Вызывается подфункция загрузки шрифта 8х14 из BIOS
cmp al,2
je text_rom_8_8
; Вызывается подфункция загрузки шрифта 8х14 из BIOS
; с переустановкой контроллера ЭЛТ
cmp al,12h
je text_rom_8_8
; Вызывается подфункция загрузки шрифта 8х16 из BIOS
cmp al,4
je text_rom_8_16
; Вызывается подфункция загрузки шрифта 8х16 из BIOS
; с переустановкой контроллера ЭЛТ
cmp al,14h
je text_rom_8_16
; Если вызывается другая подфункция, то передаем
; управление старому обработчику прерываний
jmp go_int_10h
text_rom_8_8:
; Выбираем шрифт 8х8 пикселов
mov bp,OFFSET fon8_ascii0
mov bh,8
jmp set_our_text_font
text_rom_8_14:
; Выбираем шрифт 8х14 пикселов
mov bp,OFFSET fon14_ascii0
mov bh,14
jmp set_our_text_font
text_rom_8_16:
; Выбираем шрифт 8х16 пикселов
mov bp,OFFSET fon16_ascii0
mov bh,16
set_our_text_font:
; Устанавливаем свой шрифт
and al,0f0h
push cs
pop es
mov cx,256
xor dx,dx
; Вызываем старый обработчик прерывания 10h
pushf
call DWORD PTR cs:off_int_10h
iret
resident:
END Теперь приведем таблицы шрифтов с описаниями образов символов, имеющих размер 8х8, 8х14 и 8х16 пикселов. Эти таблицы содержат описания русских символов согласно стандартной расширенной кодовой таблице ASCII символов номер 437. Символы с ASCII-кодами от 248 до 255 не соответствуют этой таблице. В листинге 5.7 представлена таблица шрифтов размера 8х8 пикселов, содержащая русские символы. Каждый символ определяется восемью байтами. Листинг 5.7. Файл CGA_FONT.INC fon8_ascii0 DB 000h,000h,000h,000h,000h,000h,000h,000h
fon8_ascii1 DB 07Eh,081h,0A5h,081h,0BDh,099h,081h,07Eh
fon8_ascii2 DB 07Eh,0FFh,0DBh,0FFh,0C3h,0E7h,0FFh,07Eh
fon8_ascii3 DB 06Ch,0FEh,0FEh,0FEh,07Ch,038h,010h,000h
fon8_ascii4 DB 010h,038h,07Ch,0FEh,07Ch,038h,010h,000h
fon8_ascii5 DB 038h,07Ch,038h,0FEh,0FEh,07Ch,038h,07Ch
fon8_ascii6 DB 010h,010h,038h,07Ch,0FEh,07Ch,038h,07Ch
fon8_ascii7 DB 000h,000h,018h,03Ch,03Ch,018h,000h,000h
fon8_ascii8 DB 0FFh,0FFh,0E7h,0C3h,0C3h,0E7h,0FFh,0FFh
fon8_ascii9 DB 000h,03Ch,066h,042h,042h,066h,03Ch,000h
fon8_ascii10 DB 0FFh,0C3h,099h,0BDh,0BDh,099h,0C3h,0FFh
fon8_ascii11 DB 00Fh,007h,00Fh,07Dh,0CCh,0CCh,0CCh,078h
fon8_ascii12 DB 03Ch,066h,066h,066h,03Ch,018h,07Eh,018h
fon8_ascii13 DB 03Fh,033h,03Fh,030h,030h,070h,0F0h,0E0h
fon8_ascii14 DB 07Fh,063h,07Fh,063h,063h,067h,0E6h,0C0h
fon8_ascii15 DB 099h,05Ah,03Ch,0E7h,0E7h,03Ch,05Ah,099h
fon8_ascii16 DB 080h,0E0h,0F8h,0FEh,0F8h,0E0h,080h,000h
fon8_ascii17 DB 002h,00Eh,03Eh,0FEh,03Eh,00Eh,002h,000h
fon8_ascii18 DB 018h,03Ch,07Eh,018h,018h,07Eh,03Ch,018h
fon8_ascii19 DB 066h,066h,066h,066h,066h,000h,066h,000h
fon8_ascii20 DB 07Fh,0DBh,0DBh,07Bh,01Bh,01Bh,01Bh,000h
fon8_ascii21 DB 03Eh,063h,038h,06Ch,06Ch,038h,0CCh,078h
fon8_ascii22 DB 000h,000h,000h,000h,07Eh,07Eh,07Eh,000h
fon8_ascii23 DB 018h,03Ch,07Eh,018h,07Eh,03Ch,018h,0FFh
fon8_ascii24 DB 018h,03Ch,07Eh,018h,018h,018h,018h,000h
fon8_ascii25 DB 018h,018h,018h,018h,07Eh,03Ch,018h,000h
fon8_ascii26 DB 000h,018h,00Ch,0FEh,00Ch,018h,000h,000h
fon8_ascii27 DB 000h,030h,060h,0FEh,060h,030h,000h,000h
fon8_ascii28 DB 000h,000h,0C0h,0C0h,0C0h,0FEh,000h,000h
fon8_ascii29 DB 000h,024h,066h,0FFh,066h,024h,000h,000h
fon8_ascii30 DB 000h,018h,03Ch,07Eh,0FFh,0FFh,000h,000h
fon8_ascii31 DB 000h,0FFh,0FFh,07Eh,03Ch,018h,000h,000h
fon8_ascii32 DB 000h,000h,000h,000h,000h,000h,000h,000h
fon8_ascii33 DB 030h,078h,078h,030h,030h,000h,030h,000h
fon8_ascii34 DB 06Ch,06Ch,06Ch,000h,000h,000h,000h,000h
fon8_ascii35 DB 06Ch,06Ch,0FEh,06Ch,0FEh,06Ch,06Ch,000h
fon8_ascii36 DB 030h,07Ch,0C0h,078h,00Ch,0F8h,030h,000h
fon8_ascii37 DB 000h,0C6h,0CCh,018h,030h,066h,0C6h,000h
fon8_ascii38 DB 038h,06Ch,038h,076h,0DCh,0CCh,076h,000h
fon8_ascii39 DB 060h,060h,0C0h,000h,000h,000h,000h,000h
fon8_ascii40 DB 018h,030h,060h,060h,060h,030h,018h,000h
fon8_ascii41 DB 060h,030h,018h,018h,018h,030h,060h,000h
fon8_ascii42 DB 000h,066h,03Ch,0FFh,03Ch,066h,000h,000h
fon8_ascii43 DB 000h,030h,030h,0FCh,030h,030h,000h,000h
fon8_ascii44 DB 000h,000h,000h,000h,000h,030h,030h,060h
fon8_ascii45 DB 000h,000h,000h,0FCh,000h,000h,000h,000h
fon8_ascii46 DB 000h,000h,000h,000h,000h,030h,030h,000h
fon8_ascii47 DB 006h,00Ch,018h,030h,060h,0C0h,080h,000h
fon8_ascii48 DB 07Ch,0C6h,0CEh,0DEh,0F6h,0E6h,07Ch,000h
fon8_ascii49 DB 030h,070h,030h,030h,030h,030h,0FCh,000h
fon8_ascii50 DB 078h,0CCh,00Ch,038h,060h,0CCh,0FCh,000h
fon8_ascii51 DB 078h,0CCh,00Ch,038h,00Ch,0CCh,078h,000h
fon8_ascii52 DB 01Ch,03Ch,06Ch,0CCh,0FEh,00Ch,01Eh,000h
fon8_ascii53 DB 0FCh,0C0h,0F8h,00Ch,00Ch,0CCh,078h,000h
fon8_ascii54 DB 038h,060h,0C0h,0F8h,0CCh,0CCh,078h,000h
fon8_ascii55 DB 0FCh,0CCh,00Ch,018h,030h,030h,030h,000h
fon8_ascii56 DB 078h,0CCh,0CCh,078h,0CCh,0CCh,078h,000h
fon8_ascii57 DB 078h,0CCh,0CCh,07Ch,00Ch,018h,070h,000h
fon8_ascii58 DB 000h,030h,030h,000h,000h,030h,030h,000h
fon8_ascii59 DB 000h,030h,030h,000h,000h,030h,030h,060h
fon8_ascii60 DB 018h,030h,060h,0C0h,060h,030h,018h,000h
fon8_ascii61 DB 000h,000h,0FCh,000h,000h,0FCh,000h,000h
fon8_ascii62 DB 060h,030h,018h,00Ch,018h,030h,060h,000h
fon8_ascii63 DB 078h,0CCh,00Ch,018h,030h,000h,030h,000h
fon8_ascii64 DB 07Ch,0C6h,0DEh,0DEh,0DEh,0C0h,078h,000h
fon8_ascii65 DB 030h,078h,0CCh,0CCh,0FCh,0CCh,0CCh,000h
fon8_ascii66 DB 0FCh,066h,066h,07Ch,066h,066h,0FCh,000h
fon8_ascii67 DB 03Ch,066h,0C0h,0C0h,0C0h,066h,03Ch,000h
fon8_ascii68 DB 0F8h,06Ch,066h,066h,066h,06Ch,0F8h,000h
fon8_ascii69 DB 0FEh,062h,068h,078h,068h,062h,0FEh,000h
fon8_ascii70 DB 0FEh,062h,068h,078h,068h,060h,0F0h,000h
fon8_ascii71 DB 03Ch,066h,0C0h,0C0h,0CEh,066h,03Eh,000h
fon8_ascii72 DB 0CCh,0CCh,0CCh,0FCh,0CCh,0CCh,0CCh,000h
fon8_ascii73 DB 078h,030h,030h,030h,030h,030h,078h,000h
fon8_ascii74 DB 01Eh,00Ch,00Ch,00Ch,0CCh,0CCh,078h,000h
fon8_ascii75 DB 0E6h,066h,06Ch,078h,06Ch,066h,0E6h,000h
fon8_ascii76 DB 0F0h,060h,060h,060h,062h,066h,0FEh,000h
fon8_ascii77 DB 0C6h,0EEh,0FEh,0FEh,0D6h,0C6h,0C6h,000h
fon8_ascii78 DB 0C6h,0E6h,0F6h,0DEh,0CEh,0C6h,0C6h,000h
fon8_ascii79 DB 038h,06Ch,0C6h,0C6h,0C6h,06Ch,038h,000h
fon8_ascii80 DB 0FCh,066h,066h,07Ch,060h,060h,0F0h,000h
fon8_ascii81 DB 078h,0CCh,0CCh,0CCh,0DCh,078h,01Ch,000h
fon8_ascii82 DB 0FCh,066h,066h,07Ch,06Ch,066h,0E6h,000h
fon8_ascii83 DB 078h,0CCh,0E0h,070h,01Ch,0CCh,078h,000h
fon8_ascii84 DB 0FCh,0B4h,030h,030h,030h,030h,078h,000h
fon8_ascii85 DB 0CCh,0CCh,0CCh,0CCh,0CCh,0CCh,0FCh,000h
fon8_ascii86 DB 0CCh,0CCh,0CCh,0CCh,0CCh,078h,030h,000h
fon8_ascii87 DB 0C6h,0C6h,0C6h,0D6h,0FEh,0EEh,0C6h,000h
fon8_ascii88 DB 0C6h,044h,06Ch,038h,038h,06Ch,0C6h,000h
fon8_ascii89 DB 0CCh,0CCh,0CCh,078h,030h,030h,078h,000h
fon8_ascii90 DB 0FEh,0C6h,08Ch,018h,032h,066h,0FEh,000h
fon8_ascii91 DB 078h,060h,060h,060h,060h,060h,078h,000h
fon8_ascii92 DB 0C0h,060h,030h,018h,00Ch,006h,002h,000h
fon8_ascii93 DB 078h,018h,018h,018h,018h,018h,078h,000h
fon8_ascii94 DB 010h,038h,06Ch,0C6h,000h,000h,000h,000h
fon8_ascii95 DB 000h,000h,000h,000h,000h,000h,000h,0FFh
fon8_ascii96 DB 030h,030h,018h,000h,000h,000h,000h,000h
fon8_ascii97 DB 000h,000h,078h,00Ch,07Ch,0CCh,07Ch,000h
fon8_ascii98 DB 060h,060h,060h,07Ch,066h,066h,07Ch,000h
fon8_ascii99 DB 000h,000h,078h,0CCh,0C0h,0CCh,078h,000h
fon8_ascii100 DB 00Ch,00Ch,00Ch,07Ch,0CCh,0CCh,07Ch,000h
fon8_ascii101 DB 000h,000h,078h,0CCh,0FCh,0C0h,078h,000h
fon8_ascii102 DB 038h,06Ch,060h,0F0h,060h,060h,0F0h,000h
fon8_ascii103 DB 000h,000h,07Ch,0CCh,0CCh,07Ch,00Ch,0F8h
fon8_ascii104 DB 060h,060h,07Ch,066h,066h,066h,066h,000h
fon8_ascii105 DB 030h,000h,070h,030h,030h,030h,078h,000h
fon8_ascii106 DB 00Ch,000h,00Ch,00Ch,00Ch,00Ch,06Ch,038h
fon8_ascii107 DB 060h,060h,066h,06Ch,078h,06Ch,066h,000h
fon8_ascii108 DB 070h,030h,030h,030h,030h,030h,078h,000h
fon8_ascii109 DB 000h,000h,0CCh,0FEh,0FEh,0D6h,0C6h,000h
fon8_ascii110 DB 000h,000h,0F8h,0CCh,0CCh,0CCh,0CCh,000h
fon8_ascii111 DB 000h,000h,078h,0CCh,0CCh,0CCh,078h,000h
fon8_ascii112 DB 000h,000h,07Ch,066h,066h,07Ch,060h,060h
fon8_ascii113 DB 000h,000h,07Ch,0CCh,0CCh,07Ch,00Ch,00Ch
fon8_ascii114 DB 000h,000h,0DCh,076h,066h,060h,0F0h,000h
fon8_ascii115 DB 000h,000h,07Ch,0C0h,078h,00Ch,0F8h,000h
fon8_ascii116 DB 010h,030h,07Ch,030h,030h,034h,018h,000h
fon8_ascii117 DB 000h,000h,0CCh,0CCh,0CCh,0CCh,07Ch,000h
fon8_ascii118 DB 000h,000h,0CCh,0CCh,0CCh,078h,030h,000h
fon8_ascii119 DB 000h,000h,0C6h,0D6h,0FEh,0FEh,06Ch,000h
fon8_ascii120 DB 000h,000h,0C6h,06Ch,038h,06Ch,0C6h,000h
fon8_ascii121 DB 000h,000h,0CCh,0CCh,0CCh,07Ch,00Ch,0F8h
fon8_ascii122 DB 000h,000h,0FCh,098h,030h,064h,0FCh,000h
fon8_ascii123 DB 01Ch,030h,030h,0E0h,030h,030h,01Ch,000h
fon8_ascii124 DB 018h,018h,018h,000h,018h,018h,018h,000h
fon8_ascii125 DB 0E0h,030h,030h,01Ch,030h,030h,0E0h,000h
fon8_ascii126 DB 076h,0DCh,000h,000h,000h,000h,000h,000h
fon8_ascii127 DB 000h,010h,038h,06Ch,0C6h,0C6h,0FEh,000h
fon8_ascii128 DB 01Eh,036h,066h,066h,07Eh,066h,066h,000h
fon8_ascii129 DB 07Ch,060h,060h,07Ch,066h,066h,07Ch,000h
fon8_ascii130 DB 07Ch,066h,066h,07Ch,066h,066h,07Ch,000h
fon8_ascii131 DB 07Eh,060h,060h,060h,060h,060h,060h,000h
fon8_ascii132 DB 038h,06Ch,06Ch,06Ch,06Ch,06Ch,0FEh,0C6h
fon8_ascii133 DB 07Eh,060h,060h,07Ch,060h,060h,07Eh,000h
fon8_ascii134 DB 0DBh,0DBh,07Eh,03Ch,07Eh,0DBh,0DBh,000h
fon8_ascii135 DB 03Ch,066h,006h,01Ch,006h,066h,03Ch,000h
fon8_ascii136 DB 066h,066h,06Eh,07Eh,076h,066h,066h,000h
fon8_ascii137 DB 03Ch,066h,06Eh,07Eh,076h,066h,066h,000h
fon8_ascii138 DB 066h,06Ch,078h,070h,078h,06Ch,066h,000h
fon8_ascii139 DB 01Eh,036h,066h,066h,066h,066h,066h,000h
fon8_ascii140 DB 0C6h,0EEh,0FEh,0FEh,0D6h,0C6h,0C6h,000h
fon8_ascii141 DB 066h,066h,066h,07Eh,066h,066h,066h,000h
fon8_ascii142 DB 03Ch,066h,066h,066h,066h,066h,03Ch,000h
fon8_ascii143 DB 07Eh,066h,066h,066h,066h,066h,066h,000h
fon8_ascii144 DB 07Ch,066h,066h,066h,07Ch,060h,060h,000h
fon8_ascii145 DB 03Ch,066h,060h,060h,060h,066h,03Ch,000h
fon8_ascii146 DB 07Eh,018h,018h,018h,018h,018h,018h,000h
fon8_ascii147 DB 066h,066h,066h,03Eh,006h,066h,03Ch,000h
fon8_ascii148 DB 07Eh,0DBh,0DBh,0DBh,07Eh,018h,018h,000h
fon8_ascii149 DB 066h,066h,03Ch,018h,03Ch,066h,066h,000h
fon8_ascii150 DB 066h,066h,066h,066h,066h,066h,07Fh,003h
fon8_ascii151 DB 066h,066h,066h,03Eh,006h,006h,006h,000h
fon8_ascii152 DB 0DBh,0DBh,0DBh,0DBh,0DBh,0DBh,0FFh,000h
fon8_ascii153 DB 0DBh,0DBh,0DBh,0DBh,0DBh,0DBh,0FFh,003h
fon8_ascii154 DB 0E0h,060h,060h,07Ch,066h,066h,07Ch,000h
fon8_ascii155 DB 0C6h,0C6h,0C6h,0F6h,0DEh,0DEh,0F6h,000h
fon8_ascii156 DB 060h,060h,060h,07Ch,066h,066h,07Ch,000h
fon8_ascii157 DB 078h,08Ch,006h,03Eh,006h,08Ch,078h,000h
fon8_ascii158 DB 0CEh,0DBh,0DBh,0FBh,0DBh,0DBh,0CEh,000h
fon8_ascii159 DB 03Eh,066h,066h,066h,03Eh,036h,066h,000h
fon8_ascii160 DB 000h,000h,078h,00Ch,07Ch,0CCh,076h,000h
fon8_ascii161 DB 000h,03Ch,060h,03Ch,066h,066h,03Ch,000h
fon8_ascii162 DB 000h,000h,07Ch,066h,07Ch,066h,07Ch,000h
fon8_ascii163 DB 000h,000h,07Eh,060h,060h,060h,060h,000h
fon8_ascii164 DB 000h,000h,03Ch,06Ch,06Ch,06Ch,0FEh,0C6h
fon8_ascii165 DB 000h,000h,03Ch,066h,07Eh,060h,03Ch,000h
fon8_ascii166 DB 000h,000h,0DBh,07Eh,03Ch,07Eh,0DBh,000h
fon8_ascii167 DB 000h,000h,03Ch,066h,00Ch,066h,03Ch,000h
fon8_ascii168 DB 000h,000h,066h,06Eh,07Eh,076h,066h,000h
fon8_ascii169 DB 000h,018h,066h,06Eh,07Eh,076h,066h,000h
fon8_ascii170 DB 000h,000h,066h,06Ch,078h,06Ch,066h,000h
fon8_ascii171 DB 000h,000h,01Eh,036h,066h,066h,066h,000h
fon8_ascii172 DB 000h,000h,0C6h,0FEh,0FEh,0D6h,0C6h,000h
fon8_ascii173 DB 000h,000h,066h,066h,07Eh,066h,066h,000h
fon8_ascii174 DB 000h,000h,03Ch,066h,066h,066h,03Ch,000h
fon8_ascii175 DB 000h,000h,07Eh,066h,066h,066h,066h,000h
fon8_ascii176 DB 011h,044h,011h,044h,011h,044h,011h,044h
fon8_ascii177 DB 055h,0AAh,055h,0AAh,055h,0AAh,055h,0AAh
fon8_ascii178 DB 0DDh,077h,0DDh,077h,0DDh,077h,0DDh,077h
fon8_ascii179 DB 018h,018h,018h,018h,018h,018h,018h,018h
fon8_ascii180 DB 018h,018h,018h,0F8h,018h,018h,018h,018h
fon8_ascii181 DB 018h,0F8h,018h,0F8h,018h,018h,018h,018h
fon8_ascii182 DB 036h,036h,036h,0F6h,036h,036h,036h,036h
fon8_ascii183 DB 000h,000h,000h,0FEh,036h,036h,036h,036h
fon8_ascii184 DB 000h,0F8h,018h,0F8h,018h,018h,018h,018h
fon8_ascii185 DB 036h,0F6h,006h,0F6h,036h,036h,036h,036h
fon8_ascii186 DB 036h,036h,036h,036h,036h,036h,036h,036h
fon8_ascii187 DB 000h,0FEh,006h,0F6h,036h,036h,036h,036h
fon8_ascii188 DB 036h,0F6h,006h,0FEh,000h,000h,000h,000h
fon8_ascii189 DB 036h,036h,036h,0FEh,000h,000h,000h,000h
fon8_ascii190 DB 018h,0F8h,018h,0F8h,000h,000h,000h,000h
fon8_ascii191 DB 000h,000h,000h,0F8h,018h,018h,018h,018h
fon8_ascii192 DB 018h,018h,018h,01Fh,000h,000h,000h,000h
fon8_ascii193 DB 018h,018h,018h,0FFh,000h,000h,000h,000h
fon8_ascii194 DB 000h,000h,000h,0FFh,018h,018h,018h,018h
fon8_ascii195 DB 018h,018h,018h,01Fh,018h,018h,018h,018h
fon8_ascii196 DB 000h,000h,000h,0FFh,000h,000h,000h,000h
fon8_ascii197 DB 018h,018h,018h,0FFh,018h,018h,018h,018h
fon8_ascii198 DB 018h,01Fh,018h,01Fh,018h,018h,018h,018h
fon8_ascii199 DB 036h,036h,036h,037h,036h,036h,036h,036h
fon8_ascii200 DB 036h,037h,030h,03Fh,000h,000h,000h,000h
fon8_ascii201 DB 000h,03Fh,030h,037h,036h,036h,036h,036h
fon8_ascii202 DB 036h,0F7h,000h,0FFh,000h,000h,000h,000h
fon8_ascii203 DB 000h,0FFh,000h,0F7h,036h,036h,036h,036h
fon8_ascii204 DB 036h,037h,030h,037h,036h,036h,036h,036h
fon8_ascii205 DB 000h,0FFh,000h,0FFh,000h,000h,000h,000h
fon8_ascii206 DB 036h,0F7h,000h,0F7h,036h,036h,036h,036h
fon8_ascii207 DB 018h,0FFh,000h,0FFh,000h,000h,000h,000h
fon8_ascii208 DB 036h,036h,036h,0FFh,000h,000h,000h,000h
fon8_ascii209 DB 000h,0FFh,000h,0FFh,018h,018h,018h,018h
fon8_ascii210 DB 000h,000h,000h,0FFh,036h,036h,036h,036h
fon8_ascii211 DB 036h,036h,036h,03Fh,000h,000h,000h,000h
fon8_ascii212 DB 018h,01Fh,018h,01Fh,000h,000h,000h,000h
fon8_ascii213 DB 000h,01Fh,018h,01Fh,018h,018h,018h,018h
fon8_ascii214 DB 000h,000h,000h,03Fh,036h,036h,036h,036h
fon8_ascii215 DB 036h,036h,036h,0FFh,036h,036h,036h,036h
fon8_ascii216 DB 018h,0FFh,018h,0FFh,018h,018h,018h,018h
fon8_ascii217 DB 018h,018h,018h,0F8h,000h,000h,000h,000h
fon8_ascii218 DB 000h,000h,000h,01Fh,018h,018h,018h,018h
fon8_ascii219 DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
fon8_ascii220 DB 000h,000h,000h,0FFh,0FFh,0FFh,0FFh,0FFh
fon8_ascii221 DB 0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h
fon8_ascii222 DB 00Fh,00Fh,00Fh,00Fh,00Fh,00Fh,00Fh,00Fh
fon8_ascii223 DB 0FFh,0FFh,0FFh,000h,000h,000h,000h,000h
fon8_ascii224 DB 000h,000h,07Ch,066h,066h,07Ch,060h,000h
fon8_ascii225 DB 000h,000h,03Ch,066h,060h,066h,03Ch,000h
fon8_ascii226 DB 000h,000h,07Eh,018h,018h,018h,018h,000h
fon8_ascii227 DB 000h,000h,066h,066h,03Eh,006h,03Ch,000h
fon8_ascii228 DB 000h,000h,07Eh,0DBh,0DBh,07Eh,018h,000h
fon8_ascii229 DB 000h,000h,066h,03Ch,018h,03Ch,066h,000h
fon8_ascii230 DB 000h,000h,066h,066h,066h,066h,07Fh,003h
fon8_ascii231 DB 000h,000h,066h,066h,03Eh,006h,006h,000h
fon8_ascii232 DB 000h,000h,0DBh,0DBh,0DBh,0DBh,0FFh,000h
fon8_ascii233 DB 000h,000h,0DBh,0DBh,0DBh,0DBh,0FFh,003h
fon8_ascii234 DB 000h,000h,0E0h,060h,07Ch,066h,07Ch,000h
fon8_ascii235 DB 000h,000h,0C6h,0C6h,0F6h,0DEh,0F6h,000h
fon8_ascii236 DB 000h,000h,060h,060h,07Ch,066h,07Ch,000h
fon8_ascii237 DB 000h,000h,07Ch,006h,03Eh,006h,07Ch,000h
fon8_ascii238 DB 000h,000h,0CEh,0DBh,0FBh,0DBh,0CEh,000h
fon8_ascii239 DB 000h,000h,03Eh,066h,03Eh,036h,066h,000h
fon8_ascii240 DB 066h,000h,07Eh,060h,07Ch,060h,07Eh,000h
fon8_ascii241 DB 024h,000h,03Ch,066h,07Eh,060h,03Ch,000h
fon8_ascii242 DB 000h,030h,018h,00Ch,006h,00Ch,018h,030h
fon8_ascii243 DB 000h,00Ch,018h,030h,060h,030h,018h,00Ch
fon8_ascii244 DB 00Eh,01Bh,01Bh,018h,018h,018h,018h,018h
fon8_ascii245 DB 018h,018h,018h,018h,018h,0D8h,0D8h,070h
fon8_ascii246 DB 000h,018h,018h,000h,07Eh,000h,018h,018h
fon8_ascii247 DB 000h,076h,0DCh,000h,076h,0DCh,000h,000h
fon8_ascii248 DB 000h,038h,06Ch,06Ch,038h,000h,000h,000h
fon8_ascii249 DB 000h,000h,000h,000h,018h,000h,000h,000h
fon8_ascii250 DB 000h,000h,000h,038h,038h,000h,000h,000h
fon8_ascii251 DB 0F8h,006h,073h,079h,023h,0FEh,0A0h,0A0h
fon8_ascii252 DB 006h,008h,0CBh,06Bh,068h,05Bh,058h,08Ch
fon8_ascii253 DB 030h,048h,010h,020h,078h,000h,000h,000h
fon8_ascii254 DB 0FFh,081h,0BDh,0A5h,0A5h,0BDh,081h,0FFh
fon8_ascii255 DB 000h,000h,000h,000h,000h,042h,07Eh,000h Исходный текст файла EGA_FONT.INC, содержащий определение шрифтов размера 8х14 пикселов приведен в листинге 5.8. Каждый символ определяется четырнадцатью байтами. Листинг 5.8. Файл EGA_FONT.INC fon14_ascii0 DB 000h,000h,000h,000h,000h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii1 DB 000h,000h,07Eh,081h,0A5h,081h,081h,0BDh
DB 099h,081h,07Eh,000h,000h,000h
fon14_ascii2 DB 000h,000h,07Eh,0FFh,0DBh,0FFh,0FFh,0C3h
DB 0E7h,0FFh,07Eh,000h,000h,000h
fon14_ascii3 DB 000h,000h,000h,06Ch,0FEh,0FEh,0FEh,0FEh
DB 07Ch,038h,010h,000h,000h,000h
fon14_ascii4 DB 000h,000h,000h,010h,038h,07Ch,0FEh,07Ch
DB 038h,010h,000h,000h,000h,000h
fon14_ascii5 DB 000h,000h,018h,03Ch,03Ch,0E7h,0E7h,0E7h
DB 018h,018h,03Ch,000h,000h,000h
fon14_ascii6 DB 000h,000h,018h,03Ch,07Eh,0FFh,0FFh,07Eh
DB 018h,018h,03Ch,000h,000h,000h
fon14_ascii7 DB 000h,000h,000h,000h,000h,018h,03Ch,03Ch
DB 018h,000h,000h,000h,000h,000h
fon14_ascii8 DB 0FFh,0FFh,0FFh,0FFh,0FFh,0E7h,0C3h,0C3h
DB 0E7h,0FFh,0FFh,0FFh,0FFh,0FFh
fon14_ascii9 DB 000h,000h,000h,000h,03Ch,066h,042h,042h
DB 066h,03Ch,000h,000h,000h,000h
fon14_ascii10 DB 0FFh,0FFh,0FFh,FFh,0C3h,099h,0BDh,0BDh
DB 099h,0C3h,0FFh,0FFh,0FFh,0FFh
fon14_ascii11 DB 000h,000h,01Eh,0Eh,01Ah,032h,078h,0CCh
DB 0CCh,0CCh,078h,000h,000h,000h
fon14_ascii12 DB 000h,000h,03Ch,066h,066h,066h,03Ch,018h
DB 07Eh,018h,018h,000h,000h,000h
fon14_ascii13 DB 000h,000h,03Fh,33h,03Fh,030h,030h,030h
DB 070h,0F0h,0E0h,000h,000h,000h
fon14_ascii14 DB 000h,000h,07Fh,63h,07Fh,063h,063h,063h
DB 067h,0E7h,0E6h,0C0h,000h,000h
fon14_ascii15 DB 000h,000h,018h,18h,0DBh,03Ch,0E7h,03Ch
DB 0DBh,018h,018h,000h,000h,000h
fon14_ascii16 DB 000h,040h,060h,70h,078h,07Ch,07Eh,07Ch
DB 078h,070h,060h,040h,000h,000h
fon14_ascii17 DB 000h,002h,006h,0Eh,01Eh,03Eh,07Eh,03Eh
DB 01Eh,00Eh,006h,002h,000h,000h
fon14_ascii18 DB 000h,000h,018h,3Ch,07Eh,018h,018h,018h
DB 07Eh,03Ch,018h,000h,000h,000h
fon14_ascii19 DB 000h,000h,066h,66h,066h,066h,066h,066h
DB 000h,066h,066h,000h,000h,000h
fon14_ascii20 DB 000h,000h,07Fh,DBh,0DBh,0DBh,07Bh,01Bh
DB 01Bh,01Bh,01Bh,000h,000h,000h
fon14_ascii21 DB 000h,07Ch,0C6h,60h,038h,06Ch,0C6h,0C6h
DB 06Ch,038h,00Ch,0C6h,07Ch,000h
fon14_ascii22 DB 000h,000h,000h,00h,000h,000h,000h,0FEh
DB 0FEh,0FEh,0FEh,000h,000h,000h
fon14_ascii23 DB 000h,000h,018h,3Ch,07Eh,018h,018h,07Eh
DB 03Ch,018h,07Eh,000h,000h,000h
fon14_ascii24 DB 000h,000h,018h,3Ch,07Eh,018h,018h,018h
DB 018h,018h,018h,000h,000h,000h
fon14_ascii25 DB 000h,000h,018h,18h,018h,018h,018h,018h
DB 07Eh,03Ch,018h,000h,000h,000h
fon14_ascii26 DB 000h,000h,000h,00h,000h,018h,00Ch,0FEh
DB 00Ch,018h,000h,000h,000h,000h
fon14_ascii27 DB 000h,000h,000h,00h,000h,018h,030h,07Fh
DB 030h,018h,000h,000h,000h,000h
fon14_ascii28 DB 000h,000h,000h,00h,000h,000h,0C0h,0C0h
DB 0C0h,0FEh,000h,000h,000h,000h
fon14_ascii29 DB 000h,000h,000h,00h,000h,028h,06Ch,0FEh
DB 06Ch,028h,000h,000h,000h,000h
fon14_ascii30 DB 000h,000h,000h,00h,010h,038h,038h,07Ch
DB 07Ch,0FEh,0FEh,000h,000h,000h
fon14_ascii31 DB 000h,000h,000h,00h,0FEh,0FEh,07Ch,07Ch
DB 038h,038h,010h,000h,000h,000h
fon14_ascii32 DB 000h,000h,000h,00h,000h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii33 DB 000h,000h,018h,3Ch,03Ch,018h,018h,018h
DB 000h,018h,018h,000h,000h,000h
fon14_ascii34 DB 000h,000h,066h,66h,066h,024h,000h,000h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii35 DB 000h,000h,06Ch,6Ch,0FEh,06Ch,06Ch,06Ch
DB 0FEh,06Ch,06Ch,000h,000h,000h
fon14_ascii36 DB 018h,018h,07Ch,C6h,0C2h,0C0h,07Ch,006h
DB 086h,0C6h,07Ch,018h,018h,000h
fon14_ascii37 DB 000h,000h,000h,C2h,0C6h,00Ch,018h,030h
DB 060h,0C6h,086h,000h,000h,000h
fon14_ascii38 DB 000h,000h,038h,6Ch,06Ch,038h,076h,0DCh
DB 0CCh,0CCh,076h,000h,000h,000h
fon14_ascii39 DB 000h,000h,030h,30h,030h,060h,000h,000h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii40 DB 000h,000h,00Ch,18h,030h,030h,030h,030h
DB 030h,018h,00Ch,000h,000h,000h
fon14_ascii41 DB 000h,000h,030h,18h,00Ch,00Ch,00Ch,00Ch
DB 00Ch,018h,030h,00h,000h,000h
fon14_ascii42 DB 000h,000h,000h,00h,066h,03Ch,0FFh,03Ch
DB 066h,000h,000h,000h,000h,000h
fon14_ascii43 DB 000h,000h,000h,00h,018h,018h,07Eh,018h
DB 018h,000h,000h,000h,000h,000h
fon14_ascii44 DB 000h,000h,000h,00h,000h,000h,000h,000h
DB 018h,018h,018h,030h,000h,000h
fon14_ascii45 DB 000h,000h,000h,00h,000h,000h,0FEh,000h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii46 DB 000h,000h,000h,00h,000h,000h,000h,000h
DB 000h,018h,018h,000h,000h,000h
fon14_ascii47 DB 000h,000h,000h,02h,006h,00Ch,018h,030h
DB 060h,0C0h,080h,000h,000h,000h
fon14_ascii48 DB 000h,000h,07Ch,C6h,0CEh,0DEh,0F6h,0E6h
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii49 DB 000h,000h,018h,38h,078h,018h,018h,018h
DB 018h,018h,03Ch,000h,000h,000h
fon14_ascii50 DB 000h,000h,07Ch,C6h,0C6h,006h,01Ch,030h
DB 060h,0C6h,0FEh,000h,000h,000h
fon14_ascii51 DB 000h,000h,07Ch,C6h,0C6h,006h,01Ch,006h
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii52 DB 000h,000h,00Ch,1Ch,03Ch,06Ch,0CCh,0CCh
DB 0FEh,00Ch,00Ch,000h,000h,000h
fon14_ascii53 DB 000h,000h,0FEh,C0h,0C0h,0FCh,006h,006h
DB 006h,0C6h,07Ch,000h,000h,000h
fon14_ascii54 DB 000h,000h,07Ch,C6h,0C0h,0C0h,0FCh,0C6h
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii55 DB 000h,000h,0FEh,C6h,086h,004h,00Ch,018h
DB 018h,030h,030h,000h,000h,000h
fon14_ascii56 DB 000h,000h,07Ch,C6h,0C6h,0C6h,07Ch,0C6h
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii57 DB 000h,000h,07Ch,C6h,0C6h,0C6h,07Eh,006h
DB 006h,0C6h,07Ch,000h,000h,000h
fon14_ascii58 DB 000h,000h,000h,00h,000h,018h,018h,000h
DB 000h,018h,018h,000h,000h,000h
fon14_ascii59 DB 000h,000h,000h,00h,000h,018h,018h,000h
DB 000h,018h,018h,030h,000h,000h
fon14_ascii60 DB 000h,000h,000h,0Ch,018h,030h,060h,030h
DB 018h,00Ch,000h,000h,000h,000h
fon14_ascii61 DB 000h,000h,000h,00h,000h,0FEh,000h,0FEh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii62 DB 000h,000h,000h,30h,018h,00Ch,006h,00Ch
DB 018h,030h,000h,000h,000h,000h
fon14_ascii63 DB 000h,000h,07Ch,C6h,0C6h,006h,00Ch,018h
DB 000h,018h,018h,000h,000h,000h
fon14_ascii64 DB 000h,000h,000h,7Ch,0C6h,0C6h,0DEh,0DEh
DB 0DEh,0DCh,0C0h,07Ch,000h,000h
fon14_ascii65 DB 000h,000h,038h,6Ch,0C6h,0C6h,0FEh,0C6h
DB 0C6h,0C6h,0C6h,00h,000h,000h
fon14_ascii66 DB 000h,000h,0FCh,66h,066h,066h,07Ch,066h
DB 066h,066h,0FCh,000h,000h,000h
fon14_ascii67 DB 000h,000h,07Ch,C6h,0C6h,0C0h,0C0h,0C0h
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii68 DB 000h,000h,0FCh,66h,066h,066h,066h,066h
DB 066h,066h,0FCh,000h,000h,000h
fon14_ascii69 DB 000h,000h,0FEh,66h,062h,068h,078h,068h
DB 062h,066h,0FEh,000h,000h,000h
fon14_ascii70 DB 000h,000h,0FEh,66h,062h,068h,078h,068h
DB 060h,060h,0F0h,000h,000h,000h
fon14_ascii71 DB 000h,000h,07Ch,C6h,0C6h,0C0h,0C0h,0CEh
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii72 DB 000h,000h,0C6h,C6h,0C6h,0C6h,0FEh,0C6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii73 DB 000h,000h,03Ch,18h,018h,018h,018h,018h
DB 018h,018h,03Ch,000h,000h,000h
fon14_ascii74 DB 000h,000h,01Eh,0Ch,00Ch,00Ch,00Ch,00Ch
DB 0CCh,0CCh,078h,000h,000h,000h
fon14_ascii75 DB 000h,000h,0C6h,CCh,0D8h,0F0h,0E0h,0F0h
DB 0D8h,0CCh,0C6h,000h,000h,000h
fon14_ascii76 DB 000h,000h,0F0h,60h,060h,060h,060h,060h
DB 062h,066h,0FEh,000h,000h,000h
fon14_ascii77 DB 000h,000h,0C6h,EEh,0FEh,0D6h,0C6h,0C6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii78 DB 000h,000h,0C6h,E6h,0E6h,0F6h,0DEh,0CEh
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii79 DB 000h,000h,07Ch,C6h,0C6h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii80 DB 000h,000h,0FCh,66h,066h,066h,07Ch,060h
DB 060h,060h,0F0h,000h,000h,000h
fon14_ascii81 DB 000h,000h,07Ch,C6h,0C6h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,07Ch,006h,000h,000h
fon14_ascii82 DB 000h,000h,0FCh,66h,066h,066h,07Ch,06Ch
DB 06Ch,066h,0E6h,000h,000h,000h
fon14_ascii83 DB 000h,000h,07Ch,C6h,0C6h,060h,038h,00Ch
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii84 DB 000h,000h,07Eh,5Ah,018h,018h,018h,018h
DB 018h,018h,03Ch,000h,000h,000h
fon14_ascii85 DB 000h,000h,0C6h,C6h,0C6h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii86 DB 000h,000h,0C6h,C6h,0C6h,0C6h,0C6h,06Ch
DB 06Ch,038h,010h,000h,000h,000h
fon14_ascii87 DB 000h,000h,0C6h,C6h,0C6h,0C6h,0C6h,0D6h
DB 0FEh,0EEh,0C6h,000h,000h,000h
fon14_ascii88 DB 000h,000h,0C6h,C6h,06Ch,07Ch,038h,07Ch
DB 06Ch,0C6h,0C6h,000h,000h,000h
fon14_ascii89 DB 000h,000h,066h,66h,066h,066h,03Ch,018h
DB 018h,018h,03Ch,000h,000h,000h
fon14_ascii90 DB 000h,000h,0FEh,C6h,086h,00Ch,018h,030h
DB 062h,0C6h,0FEh,000h,000h,000h
fon14_ascii91 DB 000h,000h,03Ch,30h,030h,030h,030h,030h
DB 030h,030h,03Ch,000h,000h,000h
fon14_ascii92 DB 000h,000h,080h,C0h,060h,030h,018h,00Ch
DB 006h,002h,000h,000h,000h,000h
fon14_ascii93 DB 000h,000h,078h,18h,018h,018h,018h,018h
DB 018h,018h,078h,000h,000h,000h
fon14_ascii94 DB 000h,018h,03Ch,66h,000h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii95 DB 000h,000h,000h,00h,000h,000h,000h,000h
DB 000h,000h,000h,0FFh,000h,000h
fon14_ascii96 DB 000h,000h,018h,18h,018h,00Ch,000h,000h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii97 DB 000h,000h,000h,00h,000h,07Ch,006h,07Eh
DB 0C6h,0C6h,07Eh,000h,000h,000h
fon14_ascii98 DB 000h,000h,0C0h,C0h,0C0h,0FCh,0C6h,0C6h
DB 0C6h,0C6h,0FCh,000h,000h,000h
fon14_ascii99 DB 000h,000h,000h,00h,000h,07Ch,0C6h,0C0h
DB 0C0h,0C6h,07Ch,000h,000h,000h
fon14_ascii100 DB 000h,000h,006h,06h,006h,07Eh,0C6h,0C6h
DB 0C6h,0C6h,07Eh,000h,000h,000h
fon14_ascii101 DB 000h,000h,000h,00h,000h,07Ch,0C6h,0FEh
DB 0C0h,0C6h,07Ch,000h,000h,000h
fon14_ascii102 DB 000h,000h,01Ch,36h,030h,030h,078h,030h
DB 030h,030h,078h,000h,000h,000h
fon14_ascii103 DB 000h,000h,000h,00h,000h,07Eh,0C6h,0C6h
DB 0C6h,07Eh,006h,0C6h,07Ch,000h
fon14_ascii104 DB 000h,000h,0C0h,C0h,0C0h,0FCh,0C6h,0C6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii105 DB 000h,000h,018h,18h,000h,038h,018h,018h
DB 018h,018h,03Ch,000h,000h,000h
fon14_ascii106 DB 000h,000h,018h,18h,000h,038h,018h,018h
DB 018h,018h,018h,0D8h,070h,000h
fon14_ascii107 DB 000h,000h,0C0h,C0h,0C0h,0CCh,0D8h,0F0h
DB 0F8h,0CCh,0C6h,000h,000h,000h
fon14_ascii108 DB 000h,000h,038h,18h,018h,018h,018h,018h
DB 018h,018h,03Ch,000h,000h,000h
fon14_ascii109 DB 000h,000h,000h,00h,000h,06Ch,0FEh,0D6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii110 DB 000h,000h,000h,00h,000h,0FCh,0C6h,0C6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii111 DB 000h,000h,000h,00h,000h,07Ch,0C6h,0C6h
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii112 DB 000h,000h,000h,00h,000h,0FCh,0C6h,0C6h
DB 0C6h,0FCh,0C0h,0C0h,0C0h,000h
fon14_ascii113 DB 000h,000h,000h,00h,000h,07Eh,0C6h,0C6h
DB 0C6h,07Eh,006h,006h,006h,000h
fon14_ascii114 DB 000h,000h,000h,00h,000h,0DEh,076h,060h
DB 060h,060h,0F0h,000h,000h,000h
fon14_ascii115 DB 000h,000h,000h,00h,000h,07Ch,0C6h,070h
DB 01Ch,0C6h,07Ch,000h,000h,000h
fon14_ascii116 DB 000h,000h,018h,18h,018h,07Eh,018h,018h
DB 018h,018h,01Ch,000h,000h,000h
fon14_ascii117 DB 000h,000h,000h,00h,000h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,07Eh,000h,000h,000h
fon14_ascii118 DB 000h,000h,000h,00h,000h,0C6h,0C6h,0C6h
DB 06Ch,038h,010h,000h,000h,000h
fon14_ascii119 DB 000h,000h,000h,00h,000h,0C6h,0C6h,0D6h
DB 0FEh,0EEh,0C6h,000h,000h,000h
fon14_ascii120 DB 000h,000h,000h,00h,000h,0C6h,06Ch,038h
DB 038h,06Ch,0C6h,000h,000h,000h
fon14_ascii121 DB 000h,000h,000h,00h,000h,0C6h,0C6h,0C6h
DB 06Ch,038h,030h,060h,0C0h,000h
fon14_ascii122 DB 000h,000h,000h,00h,000h,0FEh,0CCh,018h
DB 030h,066h,0FEh,000h,000h,000h
fon14_ascii123 DB 000h,000h,00Eh,18h,018h,018h,070h,018h
DB 018h,018h,018h,00Eh,000h,000h
fon14_ascii124 DB 000h,000h,018h,18h,018h,018h,000h,018h
DB 018h,018h,018h,018h,000h,000h
fon14_ascii125 DB 000h,000h,070h,18h,018h,018h,00Eh,018h
DB 018h,018h,018h,070h,000h,000h
fon14_ascii126 DB 000h,000h,062h,9Ch,000h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii127 DB 000h,000h,000h,00h,000h,010h,038h,06Ch
DB 0C6h,0FEh,000h,000h,000h,000h
fon14_ascii128 DB 000h,000h,01Eh,36h,066h,0C6h,0C6h,0FEh
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii129 DB 000h,000h,0FEh,62h,060h,07Ch,066h,066h
DB 066h,066h,0FCh,000h,000h,000h
fon14_ascii130 DB 000h,000h,0FCh,66h,066h,066h,07Ch,066h
DB 066h,066h,0FCh,000h,000h,000h
fon14_ascii131 DB 000h,000h,0FEh,62h,062h,060h,060h,060h
DB 060h,060h,0F0h,000h,000h,000h
fon14_ascii132 DB 000h,000h,01Eh,36h,066h,066h,066h,066h
DB 066h,066h,0FFh,0C3h,081h,000h
fon14_ascii133 DB 000h,000h,0FEh,66h,062h,068h,078h,068h
DB 062h,066h,0FEh,000h,000h,000h
fon14_ascii134 DB 000h,000h,0D6h,D6h,054h,054h,07Ch,054h
DB 0D6h,0D6h,0D6h,000h,000h,000h
fon14_ascii135 DB 000h,000h,07Ch,C6h,006h,006h,03Ch,006h
DB 006h,0C6h,07Ch,000h,000h,000h
fon14_ascii136 DB 000h,000h,0C6h,C6h,0CEh,0DEh,0F6h,0E6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii137 DB 038h,038h,0C6h,C6h,0CEh,0DEh,0F6h,0E6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii138 DB 000h,000h,0E6h,66h,06Ch,06Ch,078h,06Ch
DB 06Ch,066h,0E6h,000h,000h,000h
fon14_ascii139 DB 000h,000h,01Eh,36h,066h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii140 DB 000h,000h,0C6h,EEh,0FEh,0FEh,0D6h,0C6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii141 DB 000h,000h,0C6h,C6h,0C6h,0C6h,0FEh,0C6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii142 DB 000h,000h,07Ch,C6h,0C6h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii143 DB 000h,000h,0FEh,C6h,0C6h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii144 DB 000h,000h,0FCh,66h,066h,066h,07Ch,060h
DB 060h,060h,0F0h,000h,000h,000h
fon14_ascii145 DB 000h,000h,03Ch,66h,0C2h,0C0h,0C0h,0C0h
DB 0C2h,066h,03Ch,000h,000h,000h
fon14_ascii146 DB 000h,000h,07Eh,5Ah,018h,018h,018h,018h
DB 018h,018h,03Ch,000h,000h,000h
fon14_ascii147 DB 000h,000h,0C6h,C6h,0C6h,0C6h,0C6h,07Eh
DB 006h,0C6h,07Ch,000h,000h,000h
fon14_ascii148 DB 000h,03Ch,018h,7Eh,0DBh,0DBh,0DBh,0DBh
DB 07Eh,018h,03Ch,000h,000h,000h
fon14_ascii149 DB 000h,000h,0C6h,C6h,06Ch,07Ch,038h,07Ch
DB 06Ch,0C6h,0C6h,000h,000h,000h
fon14_ascii150 DB 000h,000h,0CCh,CCh,0CCh,0CCh,0CCh,0CCh
DB 0CCh,0CCh,0FEh,006h,006h,000h
fon14_ascii151 DB 000h,000h,0C6h,C6h,0C6h,0C6h,0C6h,07Eh
DB 006h,006h,006h,000h,000h,000h
fon14_ascii152 DB 000h,000h,0DBh,DBh,0DBh,0DBh,0DBh,0DBh
DB 0DBh,0DBh,0FFh,000h,000h,000h
fon14_ascii153 DB 000h,000h,0DBh,DBh,0DBh,0DBh,0DBh,0DBh
DB 0DBh,0DBh,0FFh,003h,003h,000h
fon14_ascii154 DB 000h,000h,0F8h,B0h,030h,03Ch,036h,036h
DB 036h,036h,07Ch,000h,000h,000h
fon14_ascii155 DB 000h,000h,0C3h,C3h,0C3h,0F3h,0DBh,0DBh
DB 0DBh,0DBh,0F3h,000h,000h,000h
fon14_ascii156 DB 000h,000h,0F0h,60h,060h,07Ch,066h,066h
DB 066h,066h,0FCh,000h,000h,000h
fon14_ascii157 DB 000h,000h,07Ch,C6h,006h,026h,03Eh,026h
DB 006h,0C6h,07Ch,000h,000h,000h
fon14_ascii158 DB 000h,000h,0CEh,DBh,0DBh,0DBh,0FBh,0DBh
DB 0DBh,0DBh,0CEh,000h,000h,000h
fon14_ascii159 DB 000h,000h,03Fh,66h,066h,066h,03Eh,03Eh
DB 066h,066h,0E7h,000h,000h,000h
fon14_ascii160 DB 000h,000h,000h,00h,000h,078h,00Ch,07Ch
DB 0CCh,0CCh,076h,000h,000h,000h
fon14_ascii161 DB 000h,002h,006h,3Ch,060h,060h,07Ch,066h
DB 066h,066h,03Ch,000h,000h,000h
fon14_ascii162 DB 000h,000h,000h,00h,000h,0FCh,066h,07Ch
DB 066h,066h,0FCh,000h,000h,000h
fon14_ascii163 DB 000h,000h,000h,00h,000h,07Eh,032h,030h
DB 030h,030h,078h,000h,000h,000h
fon14_ascii164 DB 000h,000h,000h,00h,000h,01Eh,036h,036h
DB 066h,066h,0FFh,0C3h,0C3h,000h
fon14_ascii165 DB 000h,000h,000h,00h,000h,07Ch,0C6h,0FEh
DB 0C0h,0C6h,07Ch,000h,000h,000h
fon14_ascii166 DB 000h,000h,000h,00h,000h,0D6h,0D6h,07Ch
DB 054h,0D6h,0D6h,000h,000h,000h
fon14_ascii167 DB 000h,000h,000h,00h,000h,03Ch,066h,00Ch
DB 006h,066h,03Ch,000h,000h,000h
fon14_ascii168 DB 000h,000h,000h,00h,000h,0C6h,0CEh,0D6h
DB 0E6h,0C6h,0C6h,000h,000h,000h
fon14_ascii169 DB 000h,000h,000h,38h,038h,0C6h,0CEh,0D6h
DB 0E6h,0C6h,0C6h,000h,000h,000h
fon14_ascii170 DB 000h,000h,000h,00h,000h,0E6h,06Ch,078h
DB 078h,06Ch,0E6h,000h,000h,000h
fon14_ascii171 DB 000h,000h,000h,00h,000h,01Eh,036h,066h
DB 066h,066h,066h,000h,000h,000h
fon14_ascii172 DB 000h,000h,000h,00h,000h,0C6h,0EEh,0FEh
DB 0D6h,0D6h,0C6h,000h,000h,000h
fon14_ascii173 DB 000h,000h,000h,00h,000h,0C6h,0C6h,0FEh
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii174 DB 000h,000h,000h,00h,000h,07Ch,0C6h,0C6h
DB 0C6h,0C6h,07Ch,000h,000h,000h
fon14_ascii175 DB 000h,000h,000h,00h,000h,0FEh,0C6h,0C6h
DB 0C6h,0C6h,0C6h,000h,000h,000h
fon14_ascii176 DB 011h,044h,011h,44h,011h,044h,011h,044h
DB 011h,044h,011h,044h,011h,044h
fon14_ascii177 DB 055h,0AAh,055h,AAh,055h,0AAh,055h,0AAh
DB 055h,0AAh,055h,0AAh,055h,0AAh
fon14_ascii178 DB 0DDh,077h,0DDh,77h,0DDh,077h,0DDh,077h
DB 0DDh,077h,0DDh,077h,0DDh,077h
fon14_ascii179 DB 018h,018h,018h,18h,018h,018h,018h,018h
DB 018h,018h,018h,018h,018h,018h
fon14_ascii180 DB 018h,018h,018h,18h,018h,018h,018h,0F8h
DB 018h,018h,018h,018h,018h,018h
fon14_ascii181 DB 018h,018h,018h,18h,018h,0F8h,018h,0F8h
DB 018h,018h,018h,018h,018h,018h
fon14_ascii182 DB 036h,036h,036h,36h,036h,036h,036h,0F6h
DB 036h,036h,036h,036h,036h,036h
fon14_ascii183 DB 000h,000h,000h,00h,000h,000h,000h,0FEh
DB 036h,036h,036h,036h,036h,036h
fon14_ascii184 DB 000h,000h,000h,00h,000h,0F8h,018h,0F8h
DB 018h,018h,018h,018h,018h,018h
fon14_ascii185 DB 036h,036h,036h,36h,036h,0F6h,006h,0F6h
DB 036h,036h,036h,036h,036h,036h
fon14_ascii186 DB 036h,036h,036h,36h,036h,036h,036h,036h
DB 036h,036h,036h,036h,036h,036h
fon14_ascii187 DB 000h,000h,000h,00h,000h,0FEh,006h,0F6h
DB 036h,036h,036h,036h,036h,036h
fon14_ascii188 DB 036h,036h,036h,36h,036h,0F6h,006h,0FEh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii189 DB 036h,036h,036h,36h,036h,036h,036h,0FEh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii190 DB 018h,018h,018h,18h,018h,0F8h,018h,0F8h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii191 DB 000h,000h,000h,00h,000h,000h,000h,0F8h
DB 018h,018h,018h,018h,018h,018h
fon14_ascii192 DB 018h,018h,018h,18h,018h,018h,018h,01Fh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii193 DB 018h,018h,018h,18h,018h,018h,018h,0FFh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii194 DB 000h,000h,000h,00h,000h,000h,000h,0FFh
DB 018h,018h,018h,018h,018h,018h
fon14_ascii195 DB 018h,018h,018h,18h,018h,018h,018h,01Fh
DB 018h,018h,018h,018h,018h,018h
fon14_ascii196 DB 000h,000h,000h,00h,000h,000h,000h,0FFh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii197 DB 018h,018h,018h,18h,018h,018h,018h,0FFh
DB 018h,018h,018h,018h,018h,018h
fon14_ascii198 DB 018h,018h,018h,18h,018h,01Fh,018h,01Fh
DB 018h,018h,018h,018h,018h,018h
fon14_ascii199 DB 036h,036h,036h,36h,036h,036h,036h,037h
DB 036h,036h,036h,036h,036h,036h
fon14_ascii200 DB 036h,036h,036h,36h,036h,037h,030h,03Fh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii201 DB 000h,000h,000h,00h,000h,03Fh,030h,037h
DB 036h,036h,036h,036h,036h,036h
fon14_ascii202 DB 036h,036h,036h,36h,036h,0F7h,000h,0FFh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii203 DB 000h,000h,000h,00h,000h,0FFh,000h,0F7h
DB 036h,036h,036h,036h,036h,036h
fon14_ascii204 DB 036h,036h,036h,36h,036h,037h,030h,037h
DB 036h,036h,036h,036h,036h,036h
fon14_ascii205 DB 000h,000h,000h,00h,000h,0FFh,000h,0FFh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii206 DB 036h,036h,036h,36h,036h,0F7h,000h,0F7h
DB 036h,036h,036h,036h,036h,036h
fon14_ascii207 DB 018h,018h,018h,18h,018h,0FFh,000h,0FFh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii208 DB 036h,036h,036h,36h,036h,036h,036h,0FFh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii209 DB 000h,000h,000h,00h,000h,0FFh,000h,0FFh
DB 018h,018h,018h,018h,018h,018h
fon14_ascii210 DB 000h,000h,000h,00h,000h,000h,000h,0FFh
DB 036h,036h,036h,036h,036h,036h
fon14_ascii211 DB 036h,036h,036h,36h,036h,036h,036h,03Fh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii212 DB 018h,018h,018h,18h,018h,01Fh,018h,01Fh
DB 000h,000h,000h,000h,000h,000h
fon14_ascii213 DB 000h,000h,000h,00h,000h,01Fh,018h,01Fh
DB 018h,018h,018h,018h,018h,018h
fon14_ascii214 DB 000h,000h,000h,00h,000h,000h,000h,03Fh
DB 036h,036h,036h,036h,036h,036h
fon14_ascii215 DB 036h,036h,036h,36h,036h,036h,036h,0FFh
DB 036h,036h,036h,036h,036h,036h
fon14_ascii216 DB 018h,018h,018h,18h,018h,0FFh,018h,0FFh
DB 018h,018h,018h,018h,018h,018h
fon14_ascii217 DB 018h,018h,018h,18h,018h,018h,018h,0F8h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii218 DB 000h,000h,000h,00h,000h,000h,000h,01Fh
DB 018h,018h,018h,018h,018h,018h
fon14_ascii219 DB 0FFh,0FFh,0FFh,FFh,0FFh,0FFh,0FFh,0FFh
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
fon14_ascii220 DB 000h,000h,000h,00h,000h,000h,000h,0FFh
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
fon14_ascii221 DB 0F0h,0F0h,0F0h,F0h,0F0h,0F0h,0F0h,0F0h
DB 0F0h,0F0h,0F0h,0F0h,0F0h,0F0h
fon14_ascii222 DB 00Fh,00Fh,00Fh,0Fh,00Fh,00Fh,00Fh,00Fh
DB 00Fh,00Fh,00Fh,00Fh,00Fh,00Fh
fon14_ascii223 DB 0FFh,0FFh,0FFh,FFh,0FFh,0FFh,0FFh,000h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii224 DB 000h,000h,000h,00h,000h,0DCh,066h,066h
DB 066h,066h,07Ch,060h,0F0h,000h
fon14_ascii225 DB 000h,000h,000h,00h,000h,07Ch,0C6h,0C0h
DB 0C0h,0C6h,07Ch,000h,000h,000h
fon14_ascii226 DB 000h,000h,000h,00h,000h,07Eh,05Ah,018h
DB 018h,018h,03Ch,000h,000h,000h
fon14_ascii227 DB 000h,000h,000h,00h,000h,0C6h,0C6h,0C6h
DB 0C6h,07Eh,006h,0C6h,07Ch,000h
fon14_ascii228 DB 000h,000h,000h,00h,03Ch,018h,07Eh,0DBh
DB 0DBh,0DBh,07Eh,018h,03Ch,000h
fon14_ascii229 DB 000h,000h,000h,00h,000h,0C6h,06Ch,038h
DB 038h,06Ch,0C6h,000h,000h,000h
fon14_ascii230 DB 000h,000h,000h,00h,000h,0CCh,0CCh,0CCh
DB 0CCh,0CCh,0FEh,006h,006h,000h
fon14_ascii231 DB 000h,000h,000h,00h,000h,0C6h,0C6h,0C6h
DB 07Eh,006h,006h,000h,000h,000h
fon14_ascii232 DB 000h,000h,000h,00h,000h,0D6h,0D6h,0D6h
DB 0D6h,0D6h,0FEh,000h,000h,000h
fon14_ascii233 DB 000h,000h,000h,00h,000h,0D6h,0D6h,0D6h
DB 0D6h,0D6h,0FEh,003h,003h,000h
fon14_ascii234 DB 000h,000h,000h,00h,000h,0F8h,0B0h,03Eh
DB 033h,033h,07Eh,000h,000h,000h
fon14_ascii235 DB 000h,000h,000h,00h,000h,0C6h,0C6h,0F6h
DB 0DEh,0DEh,0F6h,000h,000h,000h
fon14_ascii236 DB 000h,000h,000h,00h,000h,0F0h,060h,07Ch
DB 066h,066h,0FCh,000h,000h,000h
fon14_ascii237 DB 000h,000h,000h,00h,000h,03Ch,066h,01Eh
DB 006h,066h,03Ch,000h,000h,000h
fon14_ascii238 DB 000h,000h,000h,00h,000h,0CEh,0DBh,0FBh
DB 0DBh,0DBh,0CEh,000h,000h,000h
fon14_ascii239 DB 000h,000h,000h,00h,000h,07Eh,0CCh,07Ch
DB 06Ch,0CCh,0CEh,000h,000h,000h
fon14_ascii240 DB 000h,000h,06Ch,00h,0FEh,062h,068h,078h
DB 068h,062h,0FEh,000h,000h,000h
fon14_ascii241 DB 000h,000h,000h,6Ch,000h,07Ch,0C6h,0FEh
DB 0C0h,0C6h,07Ch,000h,000h,000h
fon14_ascii242 DB 000h,000h,000h,30h,018h,00Ch,006h,00Ch
DB 018h,030h,000h,07Eh,000h,000h
fon14_ascii243 DB 000h,000h,000h,0Ch,018h,030h,060h,030h
DB 018h,00Ch,000h,07Eh,000h,000h
fon14_ascii244 DB 000h,000h,00Eh,1Bh,01Bh,018h,018h,018h
DB 018h,018h,018h,018h,018h,018h
fon14_ascii245 DB 018h,018h,018h,18h,018h,018h,018h,018h
DB 0D8h,0D8h,0D8h,070h,000h,000h
fon14_ascii246 DB 000h,000h,000h,00h,018h,018h,000h,07Eh
DB 000h,018h,018h,000h,000h,000h
fon14_ascii247 DB 000h,000h,000h,00h,000h,076h,0DCh,000h
DB 076h,0DCh,000h,000h,000h,000h
fon14_ascii248 DB 000h,038h,06Ch,6Ch,038h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii249 DB 000h,000h,000h,00h,000h,000h,000h,018h
DB 018h,000h,000h,000h,000h,000h
fon14_ascii250 DB 000h,000h,000h,00h,000h,000h,000h,000h
DB 018h,000h,000h,000h,000h,000h
fon14_ascii251 DB 000h,000h,0E0h,18h,006h,003h,0F1h,0F9h
DB 023h,0FEh,0A0h,0A0h,000h,000h
fon14_ascii252 DB 000h,000h,000h,06h,008h,04Bh,04Bh,068h
DB 06Bh,058h,048h,088h,000h,000h
fon14_ascii253 DB 000h,070h,0D8h,30h,060h,0C8h,0F8h,000h
DB 000h,000h,000h,000h,000h,000h
fon14_ascii254 DB 000h,000h,000h,0FFh,081h,0BDh,0A5h,0A5h
DB 0BDh,081h,0FFh,000h,000h,000h
fon14_ascii255 DB 000h,000h,000h,00h,000h,000h,000h,000h
DB 000h,042h,042h,07Eh,000h,000h Исходный текст файла VGA_FONT.INC, содержащий определение шрифтов размера 8х16 пикселов приведен в листинге 5.9. Каждый символ определяется шестнадцатью байтами. Листинг 5.9. Файл VGA_FONT.INC fon16_ascii0 DB 000h,000h,000h,000h,000h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii1 DB 000h,000h,07Eh,081h,0A5h,081h,081h,0A5h
DB 099h,081h,081h,07Eh,000h,000h,000h,000h
fon16_ascii2 DB 000h,000h,07Eh,0FFh,0DBh,0FFh,0FFh,0DBh
DB 0E7h,0FFh,0FFh,07Eh,000h,000h,000h,000h
fon16_ascii3 DB 000h,000h,000h,000h,06Ch,0FEh,0FEh,0FEh
DB 0FEh,07Ch,038h,010h,000h,000h,000h,000h
fon16_ascii4 DB 000h,000h,000h,000h,010h,038h,07Ch,0FEh
DB 07Ch,038h,010h,000h,000h,000h,000h,000h
fon16_ascii5 DB 000h,000h,000h,018h,03Ch,03Ch,0E7h,0E7h
DB 0E7h,018h,018h,03Ch,000h,000h,000h,000h
fon16_ascii6 DB 000h,000h,000h,018h,03Ch,07Eh,0FFh,0FFh
DB 07Eh,018h,018h,03Ch,000h,000h,000h,000h
fon16_ascii7 DB 000h,000h,000h,000h,000h,000h,018h,03Ch
DB 03Ch,018h,000h,000h,000h,000h,000h,000h
fon16_ascii8 DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0E7h,0C3h
DB 0C3h,0E7h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
fon16_ascii9 DB 000h,000h,000h,000h,000h,03Ch,066h,042h
DB 042h,066h,03Ch,000h,000h,000h,000h,000h
fon16_ascii10 DB 0FFh,0FFh,0FFh,0FFh,0FFh,0C3h,099h,0BDh
DB 0BDh,099h,0C3h,0FFh,0FFh,0FFh,0FFh,0FFh
fon16_ascii11 DB 000h,000h,01Eh,006h,00Eh,01Ah,078h,0CCh
DB 0CCh,0CCh,0CCh,078h,000h,000h,000h,000h
fon16_ascii12 DB 000h,000h,03Ch,066h,066h,066h,066h,03Ch
DB 018h,07Eh,018h,018h,000h,000h,000h,000h
fon16_ascii13 DB 000h,000h,03Fh,033h,03Fh,030h,030h,030h
DB 030h,070h,0F0h,0E0h,000h,000h,000h,000h
fon16_ascii14 DB 000h,000h,07Fh,063h,07Fh,063h,063h,063h
DB 063h,067h,0E7h,0E6h,0C0h,000h,000h,000h
fon16_ascii15 DB 000h,000h,000h,018h,018h,0DBh,03Ch,0E7h
DB 03Ch,0DBh,018h,018h,000h,000h,000h,000h
fon16_ascii16 DB 000h,080h,0C0h,0E0h,0F0h,0F8h,0FEh,0F8h
DB 0F0h,0E0h,0C0h,080h,000h,000h,000h,000h
fon16_ascii17 DB 000h,002h,006h,00Eh,01Eh,03Eh,0FEh,03Eh
DB 01Eh,00Eh,006h,002h,000h,000h,000h,000h
fon16_ascii18 DB 000h,000h,018h,03Ch,07Eh,018h,018h,018h
DB 07Eh,03Ch,018h,000h,000h,000h,000h,000h
fon16_ascii19 DB 000h,000h,066h,066h,066h,066h,066h,066h
DB 066h,000h,066h,066h,000h,000h,000h,000h
fon16_ascii20 DB 000h,000h,07Fh,0DBh,0DBh,0DBh,07Bh,01Bh
DB 01Bh,01Bh,01Bh,01Bh,000h,000h,000h,000h
fon16_ascii21 DB 000h,07Ch,0C6h,060h,038h,06Ch,0C6h,0C6h
DB 06Ch,038h,00Ch,0C6h,07Ch,000h,000h,000h
fon16_ascii22 DB 000h,000h,000h,000h,000h,000h,000h,000h
DB 0FEh,0FEh,0FEh,0FEh,000h,000h,000h,000h
fon16_ascii23 DB 000h,000h,018h,03Ch,07Eh,018h,018h,018h
DB 07Eh,03Ch,018h,07Eh,000h,000h,000h,000h
fon16_ascii24 DB 000h,000h,018h,03Ch,07Eh,018h,018h,018h
DB 018h,018h,018h,018h,000h,000h,000h,000h
fon16_ascii25 DB 000h,000h,018h,018h,018h,018h,018h,018h
DB 018h,07Eh,03Ch,018h,000h,000h,000h,000h
fon16_ascii26 DB 000h,000h,000h,000h,000h,018h,00Ch,0FEh
DB 00Ch,018h,000h,000h,000h,000h,000h,000h
fon16_ascii27 DB 000h,000h,000h,000h,000h,030h,060h,0FEh
DB 060h,030h,000h,000h,000h,000h,000h,000h
fon16_ascii28 DB 000h,000h,000h,000h,000h,000h,0C0h,0C0h
DB 0C0h,0FEh,000h,000h,000h,000h,000h,000h
fon16_ascii29 DB 000h,000h,000h,000h,000h,028h,06Ch,0FEh
DB 06Ch,028h,000h,000h,000h,000h,000h,000h
fon16_ascii30 DB 000h,000h,000h,000h,010h,038h,038h,07Ch
DB 07Ch,0FEh,0FEh,000h,000h,000h,000h,000h
fon16_ascii31 DB 000h,000h,000h,000h,0FEh,0FEh,07Ch,07Ch
DB 038h,038h,010h,000h,000h,000h,000h,000h
fon16_ascii32 DB 000h,000h,000h,000h,000h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii33 DB 000h,000h,018h,03Ch,03Ch,03Ch,018h,018h
DB 018h,000h,018h,018h,000h,000h,000h,000h
fon16_ascii34 DB 000h,066h,066h,066h,024h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii35 DB 000h,000h,000h,06Ch,06Ch,0FEh,06Ch,06Ch
DB 06Ch,0FEh,06Ch,06Ch,000h,000h,000h,000h
fon16_ascii36 DB 018h,018h,07Ch,0C6h,0C2h,0C0h,07Ch,006h
DB 006h,086h,0C6h,07Ch,018h,018h,000h,000h
fon16_ascii37 DB 000h,000h,000h,000h,0C2h,0C6h,00Ch,018h
DB 030h,060h,0C6h,086h,000h,000h,000h,000h
fon16_ascii38 DB 000h,000h,038h,06Ch,06Ch,038h,076h,0DCh
DB 0CCh,0CCh,0CCh,076h,000h,000h,000h,000h
fon16_ascii39 DB 000h,030h,030h,030h,060h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii40 DB 000h,000h,00Ch,018h,030h,030h,030h,030h
DB 030h,030h,018h,00Ch,000h,000h,000h,000h
fon16_ascii41 DB 000h,000h,030h,018h,00Ch,00Ch,00Ch,00Ch
DB 00Ch,00Ch,018h,030h,000h,000h,000h,000h
fon16_ascii42 DB 000h,000h,000h,000h,000h,066h,03Ch,0FFh
DB 03Ch,066h,000h,000h,000h,000h,000h,000h
fon16_ascii43 DB 000h,000h,000h,000h,000h,018h,018h,07Eh
DB 018h,018h,000h,000h,000h,000h,000h,000h
fon16_ascii44 DB 000h,000h,000h,000h,000h,000h,000h,000h
DB 000h,018h,018h,018h,030h,000h,000h,000h
fon16_ascii45 DB 000h,000h,000h,000h,000h,000h,000h,0FEh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii46 DB 000h,000h,000h,000h,000h,000h,000h,000h
DB 000h,000h,018h,018h,000h,000h,000h,000h
fon16_ascii47 DB 000h,000h,000h,000h,002h,006h,00Ch,018h
DB 030h,060h,0C0h,080h,000h,000h,000h,000h
fon16_ascii48 DB 000h,000h,038h,06Ch,0C6h,0C6h,0D6h,0D6h
DB 0C6h,0C6h,06Ch,038h,000h,000h,000h,000h
fon16_ascii49 DB 000h,000h,018h,038h,078h,018h,018h,018h
DB 018h,018h,018h,07Eh,000h,000h,000h,000h
fon16_ascii50 DB 000h,000h,07Ch,0C6h,006h,00Ch,018h,030h
DB 060h,0C0h,0C6h,0FEh,000h,000h,000h,000h
fon16_ascii51 DB 000h,000h,07Ch,0C6h,006h,006h,03Ch,006h
DB 006h,006h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii52 DB 000h,000h,00Ch,01Ch,03Ch,06Ch,0CCh,0FEh
DB 00Ch,00Ch,00Ch,01Eh,000h,000h,000h,000h
fon16_ascii53 DB 000h,000h,0FEh,0C0h,0C0h,0C0h,0FCh,006h
DB 006h,006h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii54 DB 000h,000h,038h,060h,0C0h,0C0h,0FCh,0C6h
DB 0C6h,0C6h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii55 DB 000h,000h,0FEh,0C6h,006h,006h,00Ch,018h
DB 030h,030h,030h,030h,000h,000h,000h,000h
fon16_ascii56 DB 000h,000h,07Ch,0C6h,0C6h,0C6h,07Ch,0C6h
DB 0C6h,0C6h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii57 DB 000h,000h,07Ch,0C6h,0C6h,0C6h,07Eh,006h
DB 006h,006h,00Ch,078h,000h,000h,000h,000h
fon16_ascii58 DB 000h,000h,000h,000h,018h,018h,000h,000h
DB 000h,018h,018h,000h,000h,000h,000h,000h
fon16_ascii59 DB 000h,000h,000h,000h,018h,018h,000h,000h
DB 000h,018h,018h,030h,000h,000h,000h,000h
fon16_ascii60 DB 000h,000h,000h,006h,00Ch,018h,030h,060h
DB 030h,018h,00Ch,006h,000h,000h,000h,000h
fon16_ascii61 DB 000h,000h,000h,000h,000h,07Eh,000h,000h
DB 07Eh,000h,000h,000h,000h,000h,000h,000h
fon16_ascii62 DB 000h,000h,000h,060h,030h,018h,00Ch,006h
DB 00Ch,018h,030h,060h,000h,000h,000h,000h
fon16_ascii63 DB 000h,000h,07Ch,0C6h,0C6h,00Ch,018h,018h
DB 018h,000h,018h,018h,000h,000h,000h,000h
fon16_ascii64 DB 000h,000h,000h,07Ch,0C6h,0C6h,0DEh,0DEh
DB 0DEh,0DCh,0C0h,07Ch,000h,000h,000h,000h
fon16_ascii65 DB 000h,000h,010h,038h,06Ch,0C6h,0C6h,0FEh
DB 0C6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii66 DB 000h,000h,0FCh,066h,066h,066h,07Ch,066h
DB 066h,066h,066h,0FCh,000h,000h,000h,000h
fon16_ascii67 DB 000h,000h,03Ch,066h,0C2h,0C0h,0C0h,0C0h
DB 0C0h,0C2h,066h,03Ch,000h,000h,000h,000h
fon16_ascii68 DB 000h,000h,0F8h,06Ch,066h,066h,066h,066h
DB 066h,066h,06Ch,0F8h,000h,000h,000h,000h
fon16_ascii69 DB 000h,000h,0FEh,066h,062h,068h,078h,068h
DB 060h,062h,066h,0FEh,000h,000h,000h,000h
fon16_ascii70 DB 000h,000h,0FEh,066h,062h,068h,078h,068h
DB 060h,060h,060h,0F0h,000h,000h,000h,000h
fon16_ascii71 DB 000h,000h,03Ch,066h,0C2h,0C0h,0C0h,0DEh
DB 0C6h,0C6h,066h,03Ah,000h,000h,000h,000h
fon16_ascii72 DB 000h,000h,0C6h,0C6h,0C6h,0C6h,0FEh,0C6h
DB 0C6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii73 DB 000h,000h,03Ch,018h,018h,018h,018h,018h
DB 018h,018h,018h,03Ch,000h,000h,000h,000h
fon16_ascii74 DB 000h,000h,01Eh,00Ch,00Ch,00Ch,00Ch,00Ch
DB 0CCh,0CCh,0CCh,078h,000h,000h,000h,000h
fon16_ascii75 DB 000h,000h,0E6h,066h,066h,06Ch,078h,078h
DB 06Ch,066h,066h,0E6h,000h,000h,000h,000h
fon16_ascii76 DB 000h,000h,0F0h,060h,060h,060h,060h,060h
DB 060h,062h,066h,0FEh,000h,000h,000h,000h
fon16_ascii77 DB 000h,000h,0C6h,0EEh,0FEh,0FEh,0D6h,0C6h
DB 0C6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii78 DB 000h,000h,0C6h,0E6h,0F6h,0FEh,0DEh,0CEh
DB 0C6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii79 DB 000h,000h,07Ch,0C6h,0C6h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii80 DB 000h,000h,0FCh,066h,066h,066h,07Ch,060h
DB 060h,060h,060h,0F0h,000h,000h,000h,000h
fon16_ascii81 DB 000h,000h,07Ch,0C6h,0C6h,0C6h,0C6h,0C6h
DB 0C6h,0D6h,0DEh,07Ch,00Ch,00Eh,000h,000h
fon16_ascii82 DB 000h,000h,0FCh,066h,066h,066h,07Ch,06Ch
DB 066h,066h,066h,0E6h,000h,000h,000h,000h
fon16_ascii83 DB 000h,000h,07Ch,0C6h,0C6h,060h,038h,00Ch
DB 006h,0C6h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii84 DB 000h,000h,07Eh,07Eh,05Ah,018h,018h,018h
DB 018h,018h,018h,03Ch,000h,000h,000h,000h
fon16_ascii85 DB 000h,000h,0C6h,0C6h,0C6h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii86 DB 000h,000h,0C6h,0C6h,0C6h,0C6h,0C6h,0C6h
DB 0C6h,06Ch,038h,010h,000h,000h,000h,000h
fon16_ascii87 DB 000h,000h,0C6h,0C6h,0C6h,0C6h,0D6h,0D6h
DB 0D6h,0FEh,0EEh,06Ch,000h,000h,000h,000h
fon16_ascii88 DB 000h,000h,0C6h,0C6h,06Ch,07Ch,038h,038h
DB 07Ch,06Ch,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii89 DB 000h,000h,066h,066h,066h,066h,03Ch,018h
DB 018h,018h,018h,03Ch,000h,000h,000h,000h
fon16_ascii90 DB 000h,000h,0FEh,0C6h,086h,00Ch,018h,030h
DB 060h,0C2h,0C6h,0FEh,000h,000h,000h,000h
fon16_ascii91 DB 000h,000h,03Ch,030h,030h,030h,030h,030h
DB 030h,030h,030h,03Ch,000h,000h,000h,000h
fon16_ascii92 DB 000h,000h,000h,080h,0C0h,0E0h,070h,038h
DB 01Ch,00Eh,006h,002h,000h,000h,000h,000h
fon16_ascii93 DB 000h,000h,03Ch,00Ch,00Ch,00Ch,00Ch,00Ch
DB 00Ch,00Ch,00Ch,03Ch,000h,000h,000h,000h
fon16_ascii94 DB 010h,038h,06Ch,0C6h,000h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii95 DB 000h,000h,000h,000h,000h,000h,000h,000h
DB 000h,000h,000h,000h,000h,0FFh,000h,000h
fon16_ascii96 DB 030h,030h,018h,000h,000h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii97 DB 000h,000h,000h,000h,000h,078h,00Ch,07Ch
DB 0CCh,0CCh,0CCh,07Ch,000h,000h,000h,000h
fon16_ascii98 DB 000h,000h,060h,060h,060h,078h,06Ch,066h
DB 066h,066h,066h,07Ch,000h,000h,000h,000h
fon16_ascii99 DB 000h,000h,000h,000h,000h,07Ch,0C6h,0C0h
DB 0C0h,0C0h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii100 DB 000h,000h,00Ch,00Ch,00Ch,03Ch,06Ch,0CCh
DB 0CCh,0CCh,0CCh,07Ch,000h,000h,000h,000h
fon16_ascii101 DB 000h,000h,000h,000h,000h,07Ch,0C6h,0FEh
DB 0C0h,0C0h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii102 DB 000h,000h,038h,06Ch,064h,060h,0F0h,060h
DB 060h,060h,060h,0F0h,000h,000h,000h,000h
fon16_ascii103 DB 000h,000h,000h,000h,000h,07Ch,0CCh,0CCh
DB 0CCh,0CCh,0CCh,07Ch,00Ch,0CCh,078h,000h
fon16_ascii104 DB 000h,000h,060h,060h,060h,07Ch,066h,066h
DB 066h,066h,066h,066h,000h,000h,000h,000h
fon16_ascii105 DB 000h,000h,018h,018h,000h,038h,018h,018h
DB 018h,018h,018h,03Ch,000h,000h,000h,000h
fon16_ascii106 DB 000h,000h,006h,006h,000h,00Eh,006h,006h
DB 006h,006h,006h,006h,066h,066h,03Ch,000h
fon16_ascii107 DB 000h,000h,0E0h,060h,060h,066h,06Ch,078h
DB 078h,06Ch,066h,0E6h,000h,000h,000h,000h
fon16_ascii108 DB 000h,000h,038h,018h,018h,018h,018h,018h
DB 018h,018h,018h,03Ch,000h,000h,000h,000h
fon16_ascii109 DB 000h,000h,000h,000h,000h,0ECh,0FEh,0D6h
DB 0D6h,0D6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii110 DB 000h,000h,000h,000h,000h,07Ch,066h,066h
DB 066h,066h,066h,066h,000h,000h,000h,000h
fon16_ascii111 DB 000h,000h,000h,000h,000h,07Ch,0C6h,0C6h
DB 0C6h,0C6h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii112 DB 000h,000h,000h,000h,000h,07Ch,066h,066h
DB 066h,066h,066h,07Ch,060h,060h,060h,000h
fon16_ascii113 DB 000h,000h,000h,000h,000h,07Ch,0CCh,0CCh
DB 0CCh,0CCh,0CCh,07Ch,00Ch,00Ch,00Ch,000h
fon16_ascii114 DB 000h,000h,000h,000h,000h,0DCh,076h,066h
DB 060h,060h,060h,0F0h,000h,000h,000h,000h
fon16_ascii115 DB 000h,000h,000h,000h,000h,07Ch,0C6h,060h
DB 038h,00Ch,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii116 DB 000h,000h,010h,030h,030h,0FCh,030h,030h
DB 030h,030h,036h,01Ch,000h,000h,000h,000h
fon16_ascii117 DB 000h,000h,000h,000h,000h,0CCh,0CCh,0CCh
DB 0CCh,0CCh,0CCh,07Ch,000h,000h,000h,000h
fon16_ascii118 DB 000h,000h,000h,000h,000h,066h,066h,066h
DB 066h,066h,03Ch,018h,000h,000h,000h,000h
fon16_ascii119 DB 000h,000h,000h,000h,000h,0C6h,0C6h,0D6h
DB 0D6h,0D6h,0FEh,06Ch,000h,000h,000h,000h
fon16_ascii120 DB 000h,000h,000h,000h,000h,0C6h,06Ch,038h
DB 038h,038h,06Ch,0C6h,000h,000h,000h,000h
fon16_ascii121 DB 000h,000h,000h,000h,000h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,0C6h,07Eh,006h,0C6h,07Ch,000h
fon16_ascii122 DB 000h,000h,000h,000h,000h,0FEh,0CCh,018h
DB 030h,060h,0C6h,0FEh,000h,000h,000h,000h
fon16_ascii123 DB 000h,000h,00Eh,018h,018h,018h,070h,018h
DB 018h,018h,018h,00Eh,000h,000h,000h,000h
fon16_ascii124 DB 000h,000h,018h,018h,018h,018h,000h,018h
DB 018h,018h,018h,018h,000h,000h,000h,000h
fon16_ascii125 DB 000h,000h,070h,018h,018h,018h,00Eh,018h
DB 018h,018h,018h,070h,000h,000h,000h,000h
fon16_ascii126 DB 000h,000h,076h,0DCh,000h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii127 DB 000h,000h,000h,000h,010h,038h,06Ch,0C6h
DB 0C6h,0C6h,0FEh,000h,000h,000h,000h,000h
fon16_ascii128 DB 000h,000h,01Eh,036h,066h,0C6h,0C6h,0FEh
DB 0C6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii129 DB 000h,000h,0FEh,062h,062h,060h,07Ch,066h
DB 066h,066h,066h,0FCh,000h,000h,000h,000h
fon16_ascii130 DB 000h,000h,0FCh,066h,066h,066h,07Ch,066h
DB 066h,066h,066h,0FCh,000h,000h,000h,000h
fon16_ascii131 DB 000h,000h,0FEh,062h,062h,060h,060h,060h
DB 060h,060h,060h,0F0h,000h,000h,000h,000h
fon16_ascii132 DB 000h,000h,01Eh,036h,066h,066h,066h,066h
DB 066h,066h,066h,0FFh,0C3h,081h,000h,000h
fon16_ascii133 DB 000h,000h,0FEh,066h,062h,068h,078h,068h
DB 060h,062h,066h,0FEh,000h,000h,000h,000h
fon16_ascii134 DB 000h,000h,0D6h,0D6h,054h,054h,07Ch,07Ch
DB 054h,0D6h,0D6h,0D6h,000h,000h,000h,000h
fon16_ascii135 DB 000h,000h,07Ch,0C6h,006h,006h,03Ch,006h
DB 006h,006h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii136 DB 000h,000h,0C6h,0C6h,0CEh,0CEh,0D6h,0E6h
DB 0E6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii137 DB 038h,038h,0C6h,0C6h,0CEh,0CEh,0D6h,0E6h
DB 0E6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii138 DB 000h,000h,0E6h,066h,06Ch,06Ch,078h,078h
DB 06Ch,06Ch,066h,0E6h,000h,000h,000h,000h
fon16_ascii139 DB 000h,000h,01Eh,036h,066h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii140 DB 000h,000h,0C6h,0EEh,0FEh,0FEh,0D6h,0C6h
DB 0C6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii141 DB 000h,000h,0C6h,0C6h,0C6h,0C6h,0FEh,0C6h
DB 0C6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii142 DB 000h,000h,07Ch,0C6h,0C6h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii143 DB 000h,000h,0FEh,0C6h,0C6h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii144 DB 000h,000h,0FCh,066h,066h,066h,07Ch,060h
DB 060h,060h,060h,0F0h,000h,000h,000h,000h
fon16_ascii145 DB 000h,000h,03Ch,066h,0C2h,0C0h,0C0h,0C0h
DB 0C0h,0C2h,066h,03Ch,000h,000h,000h,000h
fon16_ascii146 DB 000h,000h,07Eh,05Ah,018h,018h,018h,018h
DB 018h,018h,018h,03Ch,000h,000h,000h,000h
fon16_ascii147 DB 000h,000h,0C6h,0C6h,0C6h,0C6h,0C6h,07Eh
DB 006h,006h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii148 DB 000h,03Ch,018h,07Eh,0DBh,0DBh,0DBh,0DBh
DB 0DBh,07Eh,018h,03Ch,000h,000h,000h,000h
fon16_ascii149 DB 000h,000h,0C6h,0C6h,06Ch,07Ch,038h,038h
DB 07Ch,06Ch,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii150 DB 000h,000h,0CCh,0CCh,0CCh,0CCh,0CCh,0CCh
DB 0CCh,0CCh,0CCh,0FEh,006h,006h,000h,000h
fon16_ascii151 DB 000h,000h,0C6h,0C6h,0C6h,0C6h,0C6h,07Eh
DB 006h,006h,006h,006h,000h,000h,000h,000h
fon16_ascii152 DB 000h,000h,0DBh,0DBh,0DBh,0DBh,0DBh,0DBh
DB 0DBh,0DBh,0DBh,0FFh,000h,000h,000h,000h
fon16_ascii153 DB 000h,000h,0DBh,0DBh,0DBh,0DBh,0DBh,0DBh
DB 0DBh,0DBh,0DBh,0FFh,003h,003h,000h,000h
fon16_ascii154 DB 000h,000h,0F8h,0B0h,030h,030h,03Eh,033h
DB 033h,033h,033h,07Eh,000h,000h,000h,000h
fon16_ascii155 DB 000h,000h,0C3h,0C3h,0C3h,0C3h,0F3h,0DBh
DB 0DBh,0DBh,0DBh,0F3h,000h,000h,000h,000h
fon16_ascii156 DB 000h,000h,0F0h,060h,060h,060h,07Ch,066h
DB 066h,066h,066h,0FCh,000h,000h,000h,000h
fon16_ascii157 DB 000h,000h,07Ch,0C6h,006h,026h,03Eh,026h
DB 006h,006h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii158 DB 000h,000h,0CEh,0DBh,0DBh,0DBh,0FBh,0DBh
DB 0DBh,0DBh,0DBh,0CEh,000h,000h,000h,000h
fon16_ascii159 DB 000h,000h,03Fh,066h,066h,066h,03Eh,03Eh
DB 066h,066h,066h,0E7h,000h,000h,000h,000h
fon16_ascii160 DB 000h,000h,000h,000h,000h,078h,00Ch,07Ch
DB 0CCh,0CCh,0CCh,076h,000h,000h,000h,000h
fon16_ascii161 DB 000h,002h,006h,03Ch,060h,060h,07Ch,066h
DB 066h,066h,066h,03Ch,000h,000h,000h,000h
fon16_ascii162 DB 000h,000h,000h,000h,000h,0FCh,066h,066h
DB 07Ch,066h,066h,0FCh,000h,000h,000h,000h
fon16_ascii163 DB 000h,000h,000h,000h,000h,07Eh,032h,032h
DB 030h,030h,030h,078h,000h,000h,000h,000h
fon16_ascii164 DB 000h,000h,000h,000h,000h,01Eh,036h,036h
DB 066h,066h,066h,0FFh,0C3h,0C3h,000h,000h
fon16_ascii165 DB 000h,000h,000h,000h,000h,07Ch,0C6h,0FEh
DB 0C0h,0C0h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii166 DB 000h,000h,000h,000h,000h,0D6h,0D6h,054h
DB 07Ch,054h,0D6h,0D6h,000h,000h,000h,000h
fon16_ascii167 DB 000h,000h,000h,000h,000h,03Ch,066h,006h
DB 00Ch,006h,066h,03Ch,000h,000h,000h,000h
fon16_ascii168 DB 000h,000h,000h,000h,000h,0C6h,0C6h,0CEh
DB 0D6h,0E6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii169 DB 000h,000h,000h,038h,038h,0C6h,0C6h,0CEh
DB 0D6h,0E6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii170 DB 000h,000h,000h,000h,000h,0E6h,06Ch,078h
DB 078h,06Ch,066h,0E6h,000h,000h,000h,000h
fon16_ascii171 DB 000h,000h,000h,000h,000h,01Eh,036h,066h
DB 066h,066h,066h,066h,000h,000h,000h,000h
fon16_ascii172 DB 000h,000h,000h,000h,000h,0C6h,0EEh,0FEh
DB 0FEh,0D6h,0D6h,0C6h,000h,000h,000h,000h
fon16_ascii173 DB 000h,000h,000h,000h,000h,0C6h,0C6h,0C6h
DB 0FEh,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii174 DB 000h,000h,000h,000h,000h,07Ch,0C6h,0C6h
DB 0C6h,0C6h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii175 DB 000h,000h,000h,000h,000h,0FEh,0C6h,0C6h
DB 0C6h,0C6h,0C6h,0C6h,000h,000h,000h,000h
fon16_ascii176 DB 011h,044h,011h,044h,011h,044h,011h,044h
DB 011h,044h,011h,044h,011h,044h,011h,044h
fon16_ascii177 DB 055h,0AAh,055h,0AAh,055h,0AAh,055h,0AAh
DB 055h,0AAh,055h,0AAh,055h,0AAh,055h,0AAh
fon16_ascii178 DB 0DDh,077h,0DDh,077h,0DDh,077h,0DDh,077h
DB 0DDh,077h,0DDh,077h,0DDh,077h,0DDh,077h
fon16_ascii179 DB 018h,018h,018h,018h,018h,018h,018h,018h
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii180 DB 018h,018h,018h,018h,018h,018h,018h,0F8h
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii181 DB 018h,018h,018h,018h,018h,0F8h,018h,0F8h
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii182 DB 036h,036h,036h,036h,036h,036h,036h,0F6h
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii183 DB 000h,000h,000h,000h,000h,000h,000h,0FEh
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii184 DB 000h,000h,000h,000h,000h,0F8h,018h,0F8h
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii185 DB 036h,036h,036h,036h,036h,0F6h,006h,0F6h
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii186 DB 036h,036h,036h,036h,036h,036h,036h,036h
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii187 DB 000h,000h,000h,000h,000h,0FEh,006h,0F6h
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii188 DB 036h,036h,036h,036h,036h,0F6h,006h,0FEh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii189 DB 036h,036h,036h,036h,036h,036h,036h,0FEh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii190 DB 018h,018h,018h,018h,018h,0F8h,018h,0F8h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii191 DB 000h,000h,000h,000h,000h,000h,000h,0F8h
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii192 DB 018h,018h,018h,018h,018h,018h,018h,01Fh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii193 DB 018h,018h,018h,018h,018h,018h,018h,0FFh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii194 DB 000h,000h,000h,000h,000h,000h,000h,0FFh
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii195 DB 018h,018h,018h,018h,018h,018h,018h,01Fh
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii196 DB 000h,000h,000h,000h,000h,000h,000h,0FFh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii197 DB 018h,018h,018h,018h,018h,018h,018h,0FFh
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii198 DB 018h,018h,018h,018h,018h,01Fh,018h,01Fh
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii199 DB 036h,036h,036h,036h,036h,036h,036h,037h
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii200 DB 036h,036h,036h,036h,036h,037h,030h,03Fh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii201 DB 000h,000h,000h,000h,000h,03Fh,030h,037h
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii202 DB 036h,036h,036h,036h,036h,0F7h,000h,0FFh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii203 DB 000h,000h,000h,000h,000h,0FFh,000h,0F7h
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii204 DB 036h,036h,036h,036h,036h,037h,030h,037h
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii205 DB 000h,000h,000h,000h,000h,0FFh,000h,0FFh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii206 DB 036h,036h,036h,036h,036h,0F7h,000h,0F7h
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii207 DB 018h,018h,018h,018h,018h,0FFh,000h,0FFh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii208 DB 036h,036h,036h,036h,036h,036h,036h,0FFh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii209 DB 000h,000h,000h,000h,000h,0FFh,000h,0FFh
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii210 DB 000h,000h,000h,000h,000h,000h,000h,0FFh
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii211 DB 036h,036h,036h,036h,036h,036h,036h,03Fh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii212 DB 018h,018h,018h,018h,018h,01Fh,018h,01Fh
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii213 DB 000h,000h,000h,000h,000h,01Fh,018h,01Fh
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii214 DB 000h,000h,000h,000h,000h,000h,000h,03Fh
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii215 DB 036h,036h,036h,036h,036h,036h,036h,0FFh
DB 036h,036h,036h,036h,036h,036h,036h,036h
fon16_ascii216 DB 018h,018h,018h,018h,018h,0FFh,018h,0FFh
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii217 DB 018h,018h,018h,018h,018h,018h,018h,0F8h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii218 DB 000h,000h,000h,000h,000h,000h,000h,01Fh
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii219 DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
fon16_ascii220 DB 000h,000h,000h,000h,000h,000h,000h,0FFh
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
fon16_ascii221 DB 0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h
DB 0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h
fon16_ascii222 DB 00Fh,00Fh,00Fh,00Fh,00Fh,00Fh,00Fh,00Fh
DB 00Fh,00Fh,00Fh,00Fh,00Fh,00Fh,00Fh,00Fh
fon16_ascii223 DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,000h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii224 DB 000h,000h,000h,000h,000h,0DCh,066h,066h
DB 066h,066h,066h,07Ch,060h,060h,0F0h,000h
fon16_ascii225 DB 000h,000h,000h,000h,000h,07Ch,0C6h,0C0h
DB 0C0h,0C0h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii226 DB 000h,000h,000h,000h,000h,07Eh,05Ah,018h
DB 018h,018h,018h,03Ch,000h,000h,000h,000h
fon16_ascii227 DB 000h,000h,000h,000h,000h,0C6h,0C6h,0C6h
DB 0C6h,0C6h,07Eh,006h,006h,0C6h,07Ch,000h
fon16_ascii228 DB 000h,000h,000h,000h,03Ch,018h,07Eh,0DBh
DB 0DBh,0DBh,0DBh,07Eh,018h,018h,03Ch,000h
fon16_ascii229 DB 000h,000h,000h,000h,000h,0C6h,06Ch,038h
DB 038h,038h,06Ch,0C6h,000h,000h,000h,000h
fon16_ascii230 DB 000h,000h,000h,000h,000h,0CCh,0CCh,0CCh
DB 0CCh,0CCh,0CCh,0FEh,006h,006h,000h,000h
fon16_ascii231 DB 000h,000h,000h,000h,000h,0C6h,0C6h,0C6h
DB 0C6h,07Eh,006h,006h,000h,000h,000h,000h
fon16_ascii232 DB 000h,000h,000h,000h,000h,0D6h,0D6h,0D6h
DB 0D6h,0D6h,0D6h,0FEh,000h,000h,000h,000h
fon16_ascii233 DB 000h,000h,000h,000h,000h,0D6h,0D6h,0D6h
DB 0D6h,0D6h,0D6h,0FEh,003h,003h,000h,000h
fon16_ascii234 DB 000h,000h,000h,000h,000h,0F8h,0B0h,030h
DB 03Eh,033h,033h,07Eh,000h,000h,000h,000h
fon16_ascii235 DB 000h,000h,000h,000h,000h,0C6h,0C6h,0C6h
DB 0F6h,0DEh,0DEh,0F6h,000h,000h,000h,000h
fon16_ascii236 DB 000h,000h,000h,000h,000h,0F0h,060h,060h
DB 07Ch,066h,066h,0FCh,000h,000h,000h,000h
fon16_ascii237 DB 000h,000h,000h,000h,000h,03Ch,066h,006h
DB 01Eh,006h,066h,03Ch,000h,000h,000h,000h
fon16_ascii238 DB 000h,000h,000h,000h,000h,0CEh,0DBh,0DBh
DB 0FBh,0DBh,0DBh,0CEh,000h,000h,000h,000h
fon16_ascii239 DB 000h,000h,000h,000h,000h,07Eh,0CCh,0CCh
DB 0FCh,06Ch,0CCh,0CEh,000h,000h,000h,000h
fon16_ascii240 DB 000h,06Ch,000h,0FEh,066h,062h,068h,078h
DB 068h,062h,066h,0FEh,000h,000h,000h,000h
fon16_ascii241 DB 000h,000h,000h,06Ch,000h,07Ch,0C6h,0FEh
DB 0C0h,0C0h,0C6h,07Ch,000h,000h,000h,000h
fon16_ascii242 DB 000h,000h,000h,030h,018h,00Ch,006h,00Ch
DB 018h,030h,000h,07Eh,000h,000h,000h,000h
fon16_ascii243 DB 000h,000h,000h,00Ch,018h,030h,060h,030h
DB 018h,00Ch,000h,07Eh,000h,000h,000h,000h
fon16_ascii244 DB 000h,000h,00Eh,01Bh,01Bh,018h,018h,018h
DB 018h,018h,018h,018h,018h,018h,018h,018h
fon16_ascii245 DB 018h,018h,018h,018h,018h,018h,018h,018h
DB 0D8h,0D8h,0D8h,070h,000h,000h,000h,000h
fon16_ascii246 DB 000h,000h,000h,000h,018h,018h,000h,07Eh
DB 000h,018h,018h,000h,000h,000h,000h,000h
fon16_ascii247 DB 000h,000h,000h,000h,000h,076h,0DCh,000h
DB 076h,0DCh,000h,000h,000h,000h,000h,000h
fon16_ascii248 DB 000h,038h,06Ch,06Ch,038h,000h,000h,000h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii249 DB 000h,000h,000h,000h,000h,000h,000h,018h
DB 018h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii250 DB 000h,000h,000h,000h,000h,000h,000h,000h
DB 018h,000h,000h,000h,000h,000h,000h,000h
fon16_ascii251 DB 000h,000h,000h,001h,003h,002h,006h,004h
DB 0CCh,068h,038h,010h,000h,000h,000h,000h
fon16_ascii252 DB 000h,000h,000h,03Ch,042h,099h,0A5h,0A1h
DB 0A5h,099h,042h,03Ch,000h,000h,000h,000h
fon16_ascii253 DB 000h,070h,0D8h,030h,060h,0C8h,0F8h,000h
DB 000h,000h,000h,000h,000h,000h,000h,000h
fon14_ascii254 DB 0FFh,0FFh,081h,081h,0BDh,0BDh,0A5h,0A5h
DB 0A5h,0A5h,0BDh,0BDh,081h,081h,0FFh,0FFh
fon16_ascii255 DB 000h,000h,000h,000h,000h,000h,000h,000h
DB 000h,000h,042h,07Eh,000h,000h,000h,000h Теперь приведем исходный текст программы TEST_RUS (листинг 5.10), которая позволяет проверить работу русификатора RUS_DRV в различных режимах работы видеоадаптера. Листинг 5.10. Файл TEST_RUS.INC #include "conio.h"
#include "stdio.h"
// Главная функция программы
void main(void) {
int ch = 0, i;
for( i = 0; ( i "= 0x13 ) ( ch!= 27 ); i++ ) {
// Исключаем из проверки режимы 8 - 0xC
if(( i" 7 ) ( i "= 0xC )) continue;
// Устанавливаем режим i
_asm {
mov ax,i
int 10h
}
// Отображаем текстовую строку
printf(" Режим видеоадаптера номер %x", i );
ch = getch();
}
} 6. Область данных видеофункций BIOS Глава описывает переменные BIOS, размещенные в младших адресах памяти (в так называемой системной области) и используемые видеофункциями BIOS. Знание адресов этих переменных позволяет программе определить количество и тип видеоадаптеров, подключенных к компьютеру, объем видеопамяти, текущий режим работы адаптера. По содержимому переменных BIOS можно также узнать значения регистров видеоадаптера, используемые по умолчанию в каждом поддерживаемом видеоадаптером режиме. Переменные в младших адресах памяти В младших адресах памяти 0000:0400h - 0000:0500h расположены переменные, используемые функциями BIOS. В них находятся основные параметры, определяющие состояние компьютера. Прикладные программы должны осторожно обращаться с этой областью памяти, так как нарушения в ней могут вызвать зависание системы, или другие нежелательные эффекты. Если вы программируете видеоадаптер непосредственно через регистры, вам следует самостоятельно изменять соответствующие переменные в младших адресах памяти. Это даст вам возможность пользоваться функциями BIOS. Например, если вы изменили непосредственно через регистры видеоадаптера положение курсора, а потом желаете определить его положение при помощи функций BIOS, то надо сразу после изменения регистра изменить и соответствующую переменную BIOS (ее адрес 0000:0450h). Адрес и имя Размер Содержание 0000:0410h bEquipFlags Байт Флаги конфигурации: биты D5 и D4 определяют режим видеоадаптера, используемый сразу после включения компьютера: D5 D4 0 0 зарезервировано; 0 1 40 символов в строке, цветной; 1 0 80 символов в строке, цветной; 1 1 текстовый, монохромный. Если биты D5 и D4 содержат единицы, значит используется монохромный адаптер. Видеопамять начинается по адресу B000:0000h. В противном случае активным является цветной видеоадаптер и видеопамять начинается по адресу B800:0000h. Остальные биты данного байта отвечают за другие подсистемы компьютера. Вы не должны изменять их значения 0000:0449h bVideoMode Байт Номер текущего режима работы видеоадаптера 0000:044Ah wColumns Слово Количество символов в строке экрана 0000:044Сh wPageLength Слово Размер страницы видеопамяти в байтах 0000:044Eh wVidStart Слово Смещение отображаемой области видеопамяти от начала видеопамяти (значение регистра начального адреса - SAR) 0000:0450h w8CursorPos 8 слов Каждое слово определяет координаты курсоров для одной из 8 страниц видеопамяти. Младший байт слова определяет столбец, а старший строку экрана в которой находится курсор 0000:0460h wCursorShape Слово Определяет форму курсора (позицию первой и последней линии курсора). Старший байт слова содержит позицию первой строки курсора, а младший - последней. Состояние данной переменной отвечает регистрам начальной и конечной линии курсора (CSR - старший и CER - младший байты соответственно) 0000:0462h bActivePage Байт Номер отображаемой (текущей) страницы видеопамяти 0000:0463h wAddrCRT Слово Адрес индексного регистра контроллера ЭЛТ. Содержит 3B4h для монохромных или 3D4h для цветных режимов адаптера 0000:0465h bRegMode Байт Значение регистра режима для видеоадаптеров CGA и MDA (регистр MCR). Для видеоадаптеров EGA и VGA эмулируется CGA и MDA 0000:0466h bRegPalette Байт Значение регистра цветовой палитры CGA (регистр CSR). Для видеоадаптеров EGA и VGA эмулируется CGA и MDA 0000:0484h bRows Байт Количество текстовых строк на экране минус единица 0000:0485h wCharHigh Слово Высота символов в пикселах 0000:0487h bInfo Байт Первый байт информации (для видеоадаптеров EGA и VGA): D0 если бит равен единице, то разрешена эмуляция курсора CGA D1 равен единице, видеоадаптер подсоединен к монохрому монитору D2 единица в этом бите означает, что BIOS будет ожидать обратного вертикального хода луча перед записью в видеопамять (для видеоадаптера EGA). D3 бит установлен, если видеоподсистема неактивна D4 зарезервировано D6 D5 позволяют определить объем видеопамяти, установленной на адаптере EGA. Объем видеопамяти адаптеров VGA и SVGA, как правило, не бывает меньше 256 Кбайт D6 D5 объем видеопамяти: 0 0 64 Кбайт; 0 1 128 Кбайт; 1 0 192 Кбайт; 1 1 256 Кбайт D7 единица означает, что последняя операция выбора режима видеоадаптера не очистила видеопамять 0000:0488h bInfoTwo Байт Второй байт информации о EGA: D3-D0 положение переключателей на плате EGA (1 - OFF, 0 - ON) D3 переключатель 4; D2 переключатель 3; D1 переключатель 2; D0 переключатель 1 BIOS видеоадаптера VGA эмулирует переключатели EGA в соответствии с типом используемого монитора; D7-D4 значение регистра управления дополнительным устройством видеоадаптера EGA 0000:0489h bFlags Байт Набор различных флагов D7, D4 количество линий развертки для текстовых режимов: D7 D4 0 0 350 линий; 0 1 400 линий; 1 0 200 линий; 1 1 зарезервировано D6 содержит единицу, если переключение мониторов разрешено и ноль в противном случае D5 зарезервировано D3 если данный бит содержит значение 1, значит загрузка палитры по умолчанию запрещена D2 содержит единицу, если используется монохромный монитор и ноль - если используется цветной монитор D1 содержит единицу, если разрешено преобразование серого цвета D0 содержит единицу, если VGA активен и ноль - если не активен 0000:048Ah bDCC Байт Индекс таблицы кодов комбинаций мониторов (Display Combination Code table index) 0000:04A8h dwSavePtr Двойное слово Адрес таблицы окружения (см. следующий раздел) Имена переменных видеофункций BIOS, которые мы привели в таблице соответствуют названиям полей структуры BIOS_VAR. Структура BIOS_VAR определена во включаемом файле SYSGRAPH.H. Вы можете просмотреть этот файл в листинге 3.3. В конце данной главы мы приведем пример использования структуры BIOS_VAR для доступа к переменным видеофункций BIOS (листинг 6.1). Таблица окружения Адрес таблицы окружения содержится в области переменных видеофункций BIOS (см. выше, переменная по адресу 0000:04A8h). Таблица окружения содержит пять двойных слов, представляющих собой указатели на различные структуры (таблицы и буфера памяти), используемые BIOS видеоадаптера. Таблица окружения, используемая сразу после загрузки компьютера, располагается в ПЗУ BIOS. Поэтому чтобы изменить какие-либо элементы этой таблицы, вы должны сначала перенести ее в оперативную память. Обычно для этого копируется уже существующая таблица и затем в копию вносятся необходимые изменения. Если надо сохранить в памяти новую таблицу окружения после окончания работы программы, то ее оставляют резидентной в памяти. Вы можете заменить таблицу окружения, записав указатель на новую таблицу по адресу 0000:04A8h. Таким образом, вы можете изменить шрифты и некоторые другие параметры, устанавливаемые BIOS при выборе режима работы видеоадаптера. Ниже описаны элементы таблицы окружения: Смещение Размер Описание 00h Двойное слово Указатель на таблицу параметров, содержащую значения регистров EGA/VGA, устанавливаемые BIOS по умолчанию 04h Двойное слово Указатель на область сохранения значений некоторых регистров EGA/VGA, доступных только для чтения 08h Двойное слово Указатель на таблицу символов текстового режима 0Ch Двойное слово Указатель на таблицу символов графического режима 10h Двойное слово Указатель на дополнительную таблицу окружения, используемую для расширения таблицы окружения (доступна только для видеоадаптеров VGA и SVGA) 14h Двойное слово Зарезервировано 18h Двойное слово Зарезервировано Сразу после загрузки компьютера заполняются только два элемента таблицы окружения - указатель на таблицу параметров и указатель на дополнительную таблицу окружения. Остальные указатели имеют нулевое значение и не используются. Таблица параметров Таблица параметров используется функциями BIOS для установки регистров видеоадаптера при изменении режимов его работы. Таблица содержит описания для каждого поддерживаемого адаптером режима (по 64 байта на каждый режим): Смещение Размер Содержание 0 Байт Количество символов в строке 1 -"- Количество текстовых строк на экране 2 -"- Высота символов в пикселах 3 Слово Объем страницы видеопамяти в байтах Синхронизатор 5 Байт Регистр режима синхронизации (CMR) 6 -"- Регистр разрешения записи цветового слоя (CPWER) 7 -"- Регистр выбора знакогенератора (CGSR) 8 -"- Регистр определения структуры памяти (MMR) 9 -"- Регистр определения различных режимов работы (MOR) Контроллер ЭЛТ 0Ah Байт Общая длина линии горизонтальной развертки (HTR) 0Bh -"- Длина отображаемой части горизонтальной развертки (HDER) 0Ch -"- Начало импульса гашения луча горизонтальной развертки (SHBR) 0Dh -"- Конец импульса гашения луча горизонтальной развертки (EHBR) 0Eh -"- Начало импульса горизонтального обратного хода луча (SHRR) 0Fh -"- Конец импульса горизонтального обратного хода луча (EHRR) 10h -"- Количество горизонтальных линий растра (VTR) 11h -"- Дополнительный регистр (OVR) 12h -"- Предварительная установка горизонтальной развертки (PRSR) 13h -"- Высота символов текста (MSLR) 14h -"- Начальная линия курсора (CSR) 15h -"- Конечная линия курсора (CER) 16-19h 4 Байта Не используются 1Ah Байт Начало обратного вертикального хода луча (VRSR) 1Bh -"- Конец обратного вертикального хода луча (VRER) 1Ch -"- Начало гашения вертикальной развертки (VDER) 1Dh -"- Логическая ширина экрана (OFR) 1Eh -"- Положение подчеркивания символа (ULR) 1Fh -"- Начало импульса гашения вертикальной развертки (SVBR) 20h -"- Конец импульса гашения вертикальной развертки (EVBR) 21h -"- Управление режимом (MCR) 22h -"- Разделение экрана монитора (LCR) Контроллер атрибутов 23-32h Байт Регистры цветовой палитры (0-15) (CPR) 33h -"- Регистр управления режимом (MCR) 34h -"- Регистр цвета рамки экрана (SBCR) 35h -"- Регистр разрешения цветового слоя (CPER) 36h -"- Регистр горизонтального панорамирования (HPR) Графический контроллер 37h Байт Регистр установки/сброса (SRR) 38h -"- Регистр разрешения установки/сброса (SRER) 39h -"- Регистр сравнения цветов (CCR) 3Ah -"- Регистр циклического сдвига и выбора функции (DRFS) 3Bh -"- Регистр выбора читаемого слоя (RPSR) 3Ch -"- Регистр режима работы (MDR) 3Dh -"- Регистр смешанного назначения (MIR) 3Eh -"- Регистр маскирования цветовых слоев (CDCR) 3Fh -"- Регистр битовой маски (BMR) В таблице параметров различные режимы размещаются в следующем порядке: Смешение от начала таблицы параметров Номер режима видеоадаптера +00h 0h +40h 1h +80h 2h +C0h 3h +100h 4h +140h 5h +180h 6h +1C0h 7h +200h 8h +240h 9h +280h Ah +2C0h Bh +300h Ch +340h Dh +380h Eh +3C0h Fh (адаптер EGA, имеющий 64 Кбайт памяти) +400h 10h (адаптер EGA, имеющий 64 Кбайт памяти) +440h Fh +480h 10h +4C0h 0*h +500h 1*h +540h 2*h +580h 3*h +5C0h 0h+,1h+ +600h 2h+,3h+ +640h 7h+ +680h 11h +6C0h 12h +700h 13h Область сохранения В таблице области сохранения хранятся значения регистров цветовой палитры и регистра цвета рамки. Когда функции BIOS изменяют содержимое этих регистров, они одновременно обновляют таблицу области сохранения. Для видеоадаптера EGA регистры цветовой палитры и регистр цвета рамки доступны только для записи. Через таблицу в область сохранения программа может определить значения этих регистров. Смещение в байтах Размер, байт Содержимое 0 16 Список значений 16 регистров цветовой палитры 10h 1 Значение регистра цвета рамки экрана 11h-0FFh 239 Не используется Таблица символов текстового режима Когда BIOS устанавливает текстовый режим работы видеоадаптера, он загружает таблицу знакогенератора шрифтами, записанными в ПЗУ. Если определена таблица символов текстового режима, то шрифты загружаются из нее, а не из ПЗУ. Таблица символов текстового режима может отсутствовать. Если соответствующий указатель в таблице окружения равен нулю, то она не используется. Формат таблицы символов текстового режима: Смещение (байт) Размер Содержание 0 Байт Количество байт, используемых для определения одного символа шрифта 1 Байт Номер таблицы знакогенератора (для видеоадаптера EGA 0-3, для VGA 0-7) 2 Слово Количество символов в таблице знакогенератора (обычно 256) 4 Слово Номер первого символа, определяемого таблицей 6 Двойное слово Указатель на таблицу символов (см. описание INT 1Fh) 0Ah Байт Высота символов в пикселах 0Bh Массив байт переменной длины Список режимов, использующих данную таблицу символов. На каждый номер режима отводится один байт. Должен оканчиваться числом 0FFh Вы можете использовать эту таблицу для установки собственных наборов шрифтов. Таблица символов графического режима Назначение таблицы символов графического режима практически полностью соответствует назначению таблицы символов текстового режима. За исключением того, что она используется при выборе графических режимов работы видеоадаптера. Таблица символов графического режима может отсутствовать. Если соответствующий указатель в таблице окружения равен нулю, то она не используется. Формат таблицы символов графического режима видеоадаптера: Смещение, байт Размер Содержание 0 Байт Количество строк символов на экране 1 Слово Количество байт, используемых при определении одного символа шрифта 3 Двойное слово Указатель на таблицу символов 7 Массив байт переменной длины Список режимов, использующих данную таблицу символов. На каждый номер режима отводится один байт. Должен оканчиваться числом 0FFh Дополнительная таблица окружения Последний элемент таблицы окружения содержит указатель на дополнительную таблицу окружения. Эта таблица содержит несколько дальних указателей на структуры данных, используемые BIOS видеоадаптеров VGA и SVGA. Дополнительная таблица окружения (также как таблица окружения), используемая сразу после загрузки компьютера, располагается в ПЗУ BIOS. Чтобы изменить какие-либо элементы этой таблицы, вы должны сначала перенести ее в оперативную память (см. раздел "Таблица окружения"). Ниже описаны элементы дополнительной таблицы окружения: Смещение Размер Описание 00h Слово Длина дополнительной таблицы окружения в байтах 02h Двойное слово Указатель на таблицу кодов комбинаций мониторов 06h "-" Указатель на вторую таблицу символов текстового режима 0Ah "-" Указатель на таблицу настройки палитры 0Eh "-" Зарезервировано 12h "-" "-" 16h "-" "-" После загрузки компьютера заполняются только один элемент таблицы окружения - указатель на таблицу кодов комбинаций мониторов. Остальные указатели имеют нулевое значение и не используются. Вторая таблица символов текстового режима Для видеоадаптера VGA вы можете определить второй набор из 256 символов. Формат второй таблицы символов текстового режима полностью соответствует таблице символов текстового режима. Таблица кодов комбинаций мониторов Таблица кодов комбинаций мониторов содержит список всех комбинаций видеоподсистем, которые поддерживает BIOS (см. прерывание INT 10h, функция 1Ah). Формат таблицы представлен ниже: Смещение Размер Описание 00h Байт Количество элементов в массиве комбинаций кодов (см. смещение 04h) 01h "-" Номер версии таблицы кодов комбинаций мониторов 02h "-" Максимальный код комбинаций мониторов 03h "-" Зарезервировано 04h Массив слов Каждое слово в массиве описывает пару видеоподсистем, поддерживаемых BIOS Таблица настройки палитры Таблица настройки палитры содержит значения, загружаемые при выборе режима работы видеоадаптера в регистр положения подчеркивания символа (регистра ULR), регистры палитры, и регистры таблицы цветов. Смещение Размер Описание 00h Байт Управление подчеркиванием символов в текстовых режимах: 1 подчеркивание разрешено во всех текстовых режимах; 0 подчеркивание разрешено во всех монохромных текстовых режимах; -1 подчеркивание не используется 01h Байт Зарезервировано 02h Слово Зарезервировано 04h Слово Количество регистров контроллера атрибутов, определенных в таблице 06h Слово Номер первого регистра контроллера атрибутов 08h Двойное слово Адрес таблицы, содержащей значения регистров контроллера атрибутов 0Ch Слово Количество регистров таблицы цветов 0Eh Слово Номер первого регистра таблицы цветов 10h Двойное слово Адрес таблицы, содержащей значения регистров таблицы цветов 14h Массив байт переменной длины Список режимов, в которых используется данная таблица. Каждый байт содержит номер режима. Список заканчивается числом 0FFh Программа BIOSVAR, исходный текст которой представлен в листинге 6.1, считывает из оперативной памяти компьютера значения переменных видеофункций BIOS, а затем отображает их на экране монитора. Формат вызова программы BIOSVAR имеет следующий вид: BIOSVAR "номер режима" Единственный параметр программы BIOSVAR должен задавать режим, в который переводится видеоадаптер перед чтением переменных видеофункций BIOS. Листинг 6.1. Файл BIOSVAR.С #include "stdio.h"
#include "dos.h"
#include "mem.h"
#include "sysgraph.h"
int main( int, char ** );
//- ____________________ =
// Главная функция программы
//- ____________________ =
int main( int argc, char * argv[] )
{
BIOS_VAR _far *bios_var_ptr;
BIOS_VAR bios_var_table;
union REGS inregs, outregs;
int vmode;
// Проверка командной строки программы
if( argc!= 2 )
{
printf( "\nФормат вызова: BIOSVAR "режим" "
"\n "режим": режим видеоадаптера \n" );
return - 1;
}
sscanf(argv[1],"%d",vmode);
// Устанавливаем режим работы видеоадаптера,
// заданный параметром vmode
inregs.h.ah = 0x0;
inregs.h.al = vmode;
int86( 0x10, inregs, outregs );
// Получаем указатель на область переменных видеофункций BIOS
bios_var_ptr = (BIOS_VAR _far *) FP_MAKE(0x0000, 0x0410);
// Копируем переменные видеофункций BIOS в структуру
// bios_var_table
_fmemcpy(bios_var_table,
(void far*) bios_var_ptr, sizeof(BIOS_VAR) );
// Устанавливаем текстовые режим видеоадаптера номер 3
inregs.h.ah = 0x0;
inregs.h.al = 3;
int86( 0x10, inregs, outregs );
// Отображаем содержимое переменных BIOS
printf( "Флаги конфигурации: %Xh\n"
"Текущий режим работы видеоадаптера: %Xh\n"
"Количество символов в строке: %d\n"
"Размер страницы видеопамяти: %d\n"
"Начальный адрес: %Xh\n"
"Координаты курсора нулевой страницы: %Xh\n"
"Форма курсора: %Xh\n"
"Активная страница: %Xh\n"
"Адрес индексного регистра контроллера ЭЛТ: %Xh\n"
"Регистр режима CGA: %Xh\n"
"Цветовая палитра CGA: %Xh\n"
"Количество текстовых строк: %d\n"
"Высота символов: %d\n"
"Информация о EGA 1: %Xh\n"
"Информация о EGA 2: %Xh\n"
"Адрес таблицы окружения: %Fp\n",
(unsigned char) bios_var_table.bEquipFlags,
(unsigned char) bios_var_table.bVideoMode,
(unsigned) bios_var_table.wColumns,
(unsigned) bios_var_table.wPageLength,
(unsigned) bios_var_table.wVidStart,
(unsigned) bios_var_table.w8CursorPos[0],
(unsigned) bios_var_table.wCursorShape,
(unsigned char) bios_var_table.bActivePage,
(unsigned) bios_var_table.wAddrCRT,
(unsigned char) bios_var_table.bRegMode,
(unsigned char) bios_var_table.bRegPalette,
(unsigned char) bios_var_table.bRows + 1,
(unsigned) bios_var_table.wCharHigh,
(unsigned char) bios_var_table.bInfo,
(unsigned char) bios_var_table.bInfoTwo,
(void far*) bios_var_table.dwSavePtr
);
printf("\nCopyright (C)Frolov G.V., 1992-1995. "
"E- mail: frolov@glas.apc.org\n");
return 0;
} 7. Видеоадаптеры SVGA Сразу после появления видеоадаптера VGA многие фирмы начали выпуск новых моделей видеоадаптеров, обеспечивающих отображение большего количества цветов и большую разрешающую способность. Такие видеоадаптеры получили общее название Super VGA или SVGA. Подавляющее большинство видеоадаптеров SVGA обеспечивают полную совместимость с VGA на уровне регистров. Поэтому все программное обеспечение, разработанное для видеоадаптера VGA, работает с видеоадаптерами SVGA без дополнительных изменений. Естественно, чтобы расширить возможности видеоадаптера VGA, пришлось дополнить его новыми регистрами. Видеоадаптеры SVGA имеют значительно больше регистров, чем простые видеоадаптеры VGA. Чтобы видеоадаптер SVGA смог проявить все свои возможности, необходимо, чтобы программное обеспечение правильно использовало все регистры видеоадаптера. К сожалению, SVGA не является стандартом, наподобие EGA или VGA. Различные модели видеоадаптера SVGA обладают различным набором регистров, расположенных по разным адресам и выполняющих различные функции. Это значительно затрудняет создание программ, использующих все возможности SVGA, так как такая программа должна правильно определить тип вашего видеоадаптера и работать с ним соответствующим образом. Ассоциация VESA разработала стандарт на функции BIOS, позволяющие управлять видеоадаптерами SVGA. Текущая версия стандарта VESA не позволяет реализовать все возможности современных видеоадаптеров, например, отображать геометрические фигуры с использованием аппаратных возможностей акселераторов. Мы опишем стандарт VESA и приведем несколько примеров программирования видеоадаптеров SVGA при помощи функций BIOS. Самые широкие возможности для использования видеоадаптеров SVGA предоставляет операционная система Windows. В ней используются специальные драйверы, выполняющие всю работу по программированию видеоадаптеров на аппаратном уровне. Обычно драйверы разрабатываются самой фирмой создавшей видеоадаптер. Поэтому кропотливая работа с регистрами адаптера скрыта от программистов, разрабатывающих программы Windows. Они имеют дело с хорошо документированными высокоуровневыми функциями графического интерфейса. Видеопамять SVGA Видеоадаптеры SVGA превосходят VGA по разрешению экрана и количеству одновременно отображаемых цветов. Лучшие режимы VGA Типичные режимы SVGA 640 x 480; 16 цветов 800 x 600; 256, 64 К, 16,7 М цветов 320 x 200; 256 цветов 1024 x 768; 256, 64 К, 16,7 М цветов 1280 x 1024; 256, 64 К, 16,7 М цветов Чтобы иметь возможность отображать большое количество цветов при большой разрешающей способности, видеоадаптер SVGA должен иметь значительно больше видеопамяти, чем адаптер VGA. Например, для реализации режима с разрешением 1024 x 768 пикселов и возможностью одновременного отображения 64 К цветов необходима видеопамять объемом 1,6 Мбайт. Для доступа центрального процессора к видеопамяти обычно резервируется адресное пространство размером всего 64 Кбайт. Как же процессор получает доступ к видеопамяти, объем которой для некоторых режимов достигает 4 Мбайт? Существует несколько различных подходов к решению этой проблемы, которые могут комбинироваться. Слоеный пирог В большинстве стандартных режимов адаптеров EGA и VGA видеопамять организована из четырех слоев. По каждому адресу расположены сразу четыре байта. Благодаря специальным схемам видеоадаптер может получить доступ к отдельным слоям памяти. Простейший путь втиснуть в адресное пространство объемом 64 Кбайт больше памяти лежит в увеличении количества слоев видеопамяти. Действительно у некоторых моделей видеоадаптера SVGA видеопамять организована в 8 и даже в 16 слоев. Каждый байт видеопамяти определяет 8 пикселов. Восемь слоев памяти позволяют закодировать 256 возможных цветов для пиксела, а шестнадцать слоев - 65536 различных цветов. Однако увеличение числа слоев влечет за собой усложнение аппаратуры видеоадаптера и ее удаление от стандарта адаптера VGA, регистры которого рассчитаны только на четыре слоя памяти. Увидеть весь мир через замочную скважину Многие современные видеоадаптеры применяют давно известный прием, ранее использовавшийся для подключения к компьютеру дополнительной памяти. Центральный процессор получает доступ к видеопамяти через небольшое окно. Это окно может иметь небольшой размер - до 64 Кбайт и располагаться в адресном пространстве процессора. Обычно окно занимает адресное пространство A000:0000h - A000:FFFFh, то есть расположено также как и для стандартных цветных режимов видеоадаптеров EGA, VGA и SVGA. Процессор компьютера может перемещать это окно по всей видеопамяти адаптера получая доступ к разным ее участкам. Таким образом, процессор может одновременно получить доступ только к части видеопамяти. Чтобы обратиться к другому участку видеопамяти, необходимо переместить окно доступа. Обычно для этого достаточно записать в определенный регистр видеоадаптера SVGA положение окна относительно начала видеопамяти. Доступ к видеопамяти через небольшое окно создает определенные трудности для программного обеспечения. Теперь чтобы отобразить на экране монитора пиксел вы должны не только вычислить положение соответствующей ячейки видеопамяти, но также определить смещение для окна доступа. Одновременно усложняются процедуры, отображающие на экране линии и другие геометрические фигуры. Возможно, что выводимое на экран изображение не помещается в одно окно. Процедура должна будет соответственно перемещать окно по видеопамяти. Усложняются процедуры копирования изображения из одной позиции экрана в другую. Они должны учитывать, что при копировании может понадобиться перемещать окно доступа к видеопамяти. Чтобы немного помочь программистам в решении этих и многих других задач, некоторые реализации видеоадаптеров SVGA отводят для доступа к видеопамяти не одно, а два окна. Обычно они обозначаются как окно A и окно B. В некоторых моделях видеоадаптеров через одно окно можно только записывать данные в видеопамять, а через другое только читать из видеопамяти. Больше цветов больше бит Многие режимы видеоадаптера SVGA позволяют одновременно отображать на экране больше чем 256 различных цветов. Естественно что для этого каждый пиксел должен быть представлен большим количеством бит. Количество различных цветов Количество бит для кодировки пиксела 256 8 32768 15 65536 16 16777216 24 4294967296 32 Рассмотрим 256-цветный режим видеоадаптера VGA. Каждый пиксел экрана представлен 8 битами данных видеопамяти. Видеоадаптер VGA содержит таблицу цветов (набор из 256 регистров ЦАП), которые согласно значениям, записанным в ней преобразует 8 битные данные видеопамяти в три 6-битных сигнала. Эти три сигнала поступают на три ЦАП и вырабатывающие красную, зеленую и синюю компоненты, определяющие цвет пиксела. Благодаря применению таблицы цветов вы можете выбрать для одновременного отображения на экране монитора любые 256 цветов из 262144 возможных. Видеоадаптеры SVGA для каждого пиксела используют больше чем 8 бит. Обычно пиксел определяется 15, 16 или 24 битами. Естественно, что в этом случае использование таблицы цветов адаптера VGA затруднено. Например, для режима 65536 цветов (16 бит на пиксел) требуется увеличить размер таблицы цветов до 65536 18-битных регистров. Если адаптер SVGA кодирует пиксел 24 битами, то придется увеличивать размерность таблицы цветов с 18 до 24 или выше. Поэтому в большинстве режимов SVGA реализована схема прямого кодирования цвета (Direct Color Mode). Биты, определяющие пиксел, группируются на три основные группы, непосредственно определяющие красную, зеленую и синюю компоненты цвета. Данные из этих трех групп передаются на три ЦАП и формируют видеосигнал. Таблица цветов не используется. В некоторых режимах SVGA существует дополнительная, четвертая группа бит, также соответствующая каждому пикселу. Как правило, четвертая группа бит не используется. Некоторые модели видеоадаптеров могут использовать ее по своему усмотрению. Например, на видеоадаптере Diamond Stealth 64, в режиме 110h, соответствующему спецификации VESA, для кодирования одного пиксела отводится два байта (рис. 7.1). Они разделены на четыре группы. Три из них имеют размер 5 бит и отвечают за красный, зеленый и синий компоненты цвета пиксела. Четвертая группа, резервная, состоит из одного бита. На рисунке 7.1 резервная группа отмечена символом 'X'. \s \* MERGEFORMAT Рисунок 7.1 Формат видеопамяти, 15 бит на пиксел Таким образом, в режиме 110h видеоадаптер может отображать пикселы 2 5+5+5 = 32768-и различных цветов. В режиме 111h на каждый пиксел также как и в режиме 110h отводится 2 байта, однако они имеют другой формат (рис. 7.2). Резервное поле отсутствует. За счет этого увеличен размер поля, управляющего зеленым компонентом цвета пиксела. Поэтому, в данном режиме видеоадаптер может отображать пикселы 2 5+6+5 = 65536-и различных цветов. \s \* MERGEFORMAT Рисунок 7.2 Формат видеопамяти, 16 бит на пиксел и резервное поле Чтобы видеоадаптер мог одновременно отображать на экране 16777216 различных цветов, необходимо, чтобы для кодирования каждого пиксела отводилось 24 бита. Обычно видеоадаптеры используют для этого два различных формата кодирования пиксела (рис. 7.3 и 7.4) \s \* MERGEFORMAT Рисунок 7.3 Формат видеопамяти, 24 бит на пиксел В режимах 112h, 115 и 118h на один пиксел отводится 4 байта (рис. 7.4). Они разделены на четыре группы по 8 бит в каждой. Три группы отвечают за красный, зеленый и синий компоненты цвета пиксела. Четвертая группа резервная. Такой формат позволяет одновременно отображать на экране монитора пикселы 2 8+8+8 = 16777216 различных цветов. \s \* MERGEFORMAT Рисунок 7.4 Формат видеопамяти, 24 бит на пиксел и резервное поле Интересно отметить, что даже в режиме 118h, имеющем разрешение 1024x768 пикселов, на экране отображается 786432 пиксела. То есть меньше, чем количество цветов, которое видеоадаптер может одновременно отобразить на экране монитора. Стандарт VESA Стандарт VESA описывает расширение прерывания BIOS номер 10h (VESA BIOS Extention - VBE), отвечающего за управление видеоадаптерами. Поддержка VBE обычно включается производителями видеоадаптеров в ПЗУ самого адаптера или поставляется в виде отдельной резидентной программы. Во втором случае перед использованием функций VBE необходимо загрузить данную резидентную программу в оперативную память компьютера. Ниже мы полностью опишем функции VBE версии 1.2 и опишем некоторые функции VBE версии 2.0. Перед вызовом функций VBE следует записать в регистр AH значение 4Fh. Если ваша реализация VBE поддерживает данную функцию, то в регистре AL возвращается значение 4Fh. Если функция не реализована, тогда в регистре AL возвращается значение, отличное от 4Fh. Результат выполнения функции записывается в регистр AH. В случае успешного завершения функции в регистре AH возвращается нулевое значение. Если в регистре AH записано значение 1h, значит функция завершилась с ошибкой. И, наконец, если в регистре AH возвращается значение 2h, значит аппаратура видеоадаптера не поддерживает данную функцию. Возможна ситуация, когда VBE может выполнить запрашиваемую функцию, а аппаратура видеоадаптера - нет. В этом случае после завершения функции регистр AH содержит значение 4Fh, а регистр AH - 2h. Получить информацию о реализации VBE и видеоадаптере Функция позволяет получить различную информацию о возможностях VBE и видеоадаптера. Вы должны использовать данную функцию, чтобы определить, наличие VBE и его версию. Формат вызова функции отличается для VBE версии 2.0 и VBE более ранних версий. В следующей таблице представлен формат вызова функции для VBE версии 1.2 и более ранних версий: На входе: AH 4Fh AL 00h ES:DI Указатель на буфер размером 256 байт (формат буфера см. ниже). В этот буфер записывается различная информация о видеоадаптере SVGA и реализации VBE На выходе: AL 4Fh AH 0, в случае успешного завершения, 1 в случае ошибки Примечание: Значения остальных регистров сохраняются Теперь приведем расширенный формат этой же функции соответствующий VBE версии 2.0: На входе: AH 4Fh AL 00h ES:DI Указатель на буфер размером 512 байт (формат буфера см. ниже). Первые четыре байта буфера должны содержать строку "VBE2". В буфер записывается различная информация о видеоадаптере SVGA и реализации VBE На выходе: AL 4Fh AH 0, в случае успешного завершения, 1 в случае ошибки Примечание: Значения остальных регистров сохраняются В следующей таблице представлен формат буфера, содержащего информацию об адаптере SVGA и реализации VBE. В таблице мы объединили разные версии VBE. Смещение Размер Описание 00h 4 байта В случае успешного завершения в это поле записывается строка 'VESA' 04h Слово Номер версии VBE. Старший байт содержит старшую часть номера версии, младший байт - младшую часть номера версии 06h Двойное слово Дальний указатель на строку, закрытую нулем. В строке содержится информация, определяемая производителем. Как правило, она служит для описания видеоадаптера и реализации VBE 0Ah Двойное слово Возможности видеоадаптера. В реализации VBE версии 1.2 задействуется только бит D0. Бит D0 содержит единицу, если ЦАП видеоадаптера может работать с данными переменной длинны. В противном случае ЦАП может использовать для представления каждой компоненты цвета (RGB-красный, зеленый, синий) только 6 бит. Бит D1 (VBE 2.0) содержит единицу, если видеоадаптер не полностью совместим с VGA. Бит D2 (VBE 2.0) содержит единицу, если BIOS не поддерживает другие функции VBE 0Eh Двойное слово Дальний указатель на список режимов, поддерживаемых функциями VBE. Список состоит из 16-битовых величин, являющихся номерами режимов и заканчивается числом 0FFFFh Следующие поля таблицы поддерживаются только VBE версии 1.2 12h Слово Объем памяти видеоадаптера, представленный в блоках размером по 64 Кбайт Следующие поля таблицы поддерживаются только VBE версии 2.0 14h Слово Дополнительный номер версии VBE (номер пересмотренной версии) 16h Двойное слово Дальний указатель на строку, закрытую нулем. В строке содержится имя фирмы разработчика 1Ah Двойное слово Дальний указатель на строку, закрытую нулем. В строке содержится название видеоадаптера 1Eh Двойное слово Дальний указатель на строку, закрытую нулем. В строке содержится дополнительный номер версии видеоадаптера 22h 222 байт Не используется 100h 256 байт Информация фирмы разработчика Получить информацию о режиме видеоадаптера Функция позволяет определить различные характеристики любого режима видеоадаптера, отвечающего стандарту VESA. Программа должна подготовить буфер и передать указатель на него функции. В случае успешного завершения в буфер будут записаны характеристики режима. На входе: AH 4Fh AL 01h CX Номер режима ES:DI Указатель на буфер размером 256 байт (см. ниже) для таблицы описания режима На выходе: AL 4Fh AH Результат: 0, в случае успешного завершения, 1 в случае ошибки Формат таблицы описания режима представлен ниже: Смещение Размер Описание 00h Слово Атрибуты режима: D0 режим поддерживается D1 доступна дополнительная информация D2 поддерживаются функции BIOS D3 1 - цветной режим, 0 - монохромный режим D4 1 - графический режим, 0 - текстовый режим 02h Байт Атрибуты окна A D0 доступно (поддерживается) D1 окно доступно для чтения D2 окно доступно для записи D3-D7 не используется 03h Байт Атрибуты окна B (см. атрибуты окна A) 04h Слово Шаг позиционирования окна в Кбайтах 06h Слово Размер окна в Кбайтах 08h Слово Начало сегмента окна A 0Ah Слово Начало сегмента окна B 0Ch Двойное слово Указатель на функцию перемещения (позиционирования) окна 10h Слово Количество байт на линию сканирования. Не является обязательным для режимов VESA Следующие поля таблицы поддерживаются только VBE версии 1.2 12h Слово Разрешение по горизонтали в пикселах 14h Слово Разрешение по вертикали в пикселах 16h Байт Ширина символа в пикселах 17h Байт Высота символа в пикселах 18h Байт Количество слоев видеопамяти 19h Байт Количество бит на пиксел 1Ah Байт Количество банков памяти 1Bh Байт Тип модели памяти 1Ch Байт Размер банка памяти в Кбайтах 1Dh Байт Количество страниц видеопамяти, доступных в данном режиме минус один 1E Байт Зарезервировано 1Fh Байт Количество бит, представляющих красную компоненту цвета пикселов 20h Байт Положение младшего бита поля, представляющего красную компоненту цвета пикселов 21h Байт Количество бит, представляющих зеленую компоненту цвета пикселов 22h Байт Положение младшего бита поля, представляющего зеленую компоненту цвета пикселов 23h Байт Количество бит, представляющих синюю компоненту цвета пикселов 24h Байт Положение младшего бита поля, представляющего синюю компоненту цвета пикселов 25h Байт Количество бит, представляющих запасное поле цвета пикселов 26h Байт Положение младшего бита запасного поля, предоставляющего цвет пикселов 27h Байт D0 равен единице, если в данном режиме видеоадаптера вы можете программировать регистры ЦАП; D1 равен единице, если в данном режиме видеоадаптера каждое значение пиксела представлено 4 полями (красное, зеленое, синее, дополнительное) и дополнительное поле можно использовать. Если бит равен нулю, тогда дополнительное поле зарезервировано и не используется; D2-D7 зарезервировано Следующие поля таблицы поддерживаются только VBE версии 2.0 28h Двойное слово Поле содержит физический 32-разрядный адрес начала видеобуфера для использования его в защищенном режиме 2Сh Двойное слово Смещение от начала видеобуфера области памяти неиспользуемой для отображения изображения на экране монитора 30h Слово Размер области памяти, неиспользуемой для отображения изображения 32h 206 байт Зарезервировано Теперь мы приведем программу VESATEST, которая позволяет собрать различную информацию о видеоадаптере и реализации VBE расширения BIOS. Объем информации, выдаваемой программой достаточно велик. Поэтому для упрощения программы вся выходная информация записывается в файл, который вы можете просмотреть с помощью любого текстового редактора. Программа VESATEST имеет следующий формат: VESATEST "имя файла" Параметр "имя файла" должен содержать имя файла, в который будут записаны результаты работы программы. Исходный текст программы представлен в листинге 7.1. Листинг 7.1. Файл VESATEST.CPP #include "stdio.h"
#include "conio.h"
#include "string.h"
#include "dos.h"
#include "vesa.h"
// Описание функций
int main( int argc, char * argv[] );
int GetBaseVESAInfo(FILE*);
int AnalyseResult(union REGS);
// Главная функция
int main( int argc, char * argv[] )
{
FILE *fileVesaReport;
int iResult;
// Проверка командной строки программы
if( argc!= 2 )
{
printf("\nФормат вызова: VESATEST "имя файла" "
"\n "имя файла": имя файла, в который будет"
" записана информация");
return - 1;
}
// Открываем файл
fileVesaReport = fopen(argv[1], "w+");
// Записываем в файл fileVesaReport информацию о VBE и
// видеоадаптере
iResult = GetBaseVESAInfo(fileVesaReport);
// Закрываем файл
fclose(fileVesaReport);
return ((iResult-0)? 0: -1);
}
//- ____________________ =
// Функция GetBaseVESAInfo
//- ____________________ =
int
GetBaseVESAInfo(FILE *file)
{
union REGS regs;
struct SREGS segregs;
int iResult, i;
// Структуры для получения информации о VBE
VESAINFO vesaInfo;
VESAMODEINFO modeInfo;
// Подготавливаем буфер для VBE версии 2.0
strcpy( vesaInfo.cSignature, "VBE2" );
// Получаем данные о реализации VBE и видеоадаптере
regs.h.ah = 0x4f;
regs.h.al = 0x00;
segregs.es = FP_SEG((void far *)vesaInfo);
regs.x.di = FP_OFF((void far *)vesaInfo);
int86x(0x10, regs, regs, segregs);
// Проверяем результат вызова функции VBE
iResult = AnalyseResult(regs);
if(iResult!= 0) return -1;
// Записываем в файл информацию из структуры vesaInfo
fprintf(file,"Сигнатура: '%4.4s'\n",vesaInfo.cSignature );
fprintf(file, "Информация фирмы производителя: '%s'\n",
vesaInfo.fpInfoOEM );
fprintf(file, "Версия VBE: %Xh \n", vesaInfo.usVersion);
fprintf(file, "Возможности видеоадаптера: '%x%x%x%x' \n",
vesaInfo.ucCapabilities[0],vesaInfo.ucCapabilities[1],
vesaInfo.ucCapabilities[2],vesaInfo.ucCapabilities[3]);
fprintf(file, "Поддерживаются следующие режимы VESA: \n");
for( i=0; i "50; i++ ) {
if(vesaInfo.fpModeTable[i] - 0xFFFF) break;
fprintf(file, " %Xh \n", vesaInfo.fpModeTable[i] );
}
// Объем видеопамяти определяется VBE версии не младше 1.2
if( vesaInfo.usVersion" = 0x102 )
fprintf(file, "Объем видеопамяти %d Кбайт\n",
vesaInfo.usTotalMemory * 64);
// Следующая информация доступна только для
// VBE версии 2.0 и старше
if( vesaInfo.usVersion" = 0x200 )
{
fprintf(file,"Дополнительный номер версии: %04Xh\n",
vesaInfo.usRevVersion);
fprintf(file, "Дополнительный номер версии"
"видеоадаптера: '%s'\n",
vesaInfo.fpOEMRevVersion);
fprintf(file, "Имя фирмы разработчика: '%s'\n",
vesaInfo.fpOEMName);
fprintf(file, "Название видеоадаптера: '%s'\n",
vesaInfo.fpOEMProductName);
}
// Теперь получаем информацию для каждого доступного
// режима VESA
for( i=0; i "50; i++ ) {
// Получаем очередной номер режима VESA
if(vesaInfo.fpModeTable[i] - 0xFFFF) break;
fprintf(file, "\n\nРежим %Xh \n",
vesaInfo.fpModeTable[i] );
// Получаем информацию о режиме vesaInfo.fpModeTable[i]
regs.h.ah = 0x4f;
regs.h.al = 0x01;
regs.x.cx = vesaInfo.fpModeTable[i];
segregs.es = FP_SEG((void far *)modeInfo);
regs.x.di = FP_OFF((void far *)modeInfo);
int86x(0x10, regs, regs, segregs);
// Проверяем результат вызова функции VBE
iResult = AnalyseResult(regs);
if(iResult!= 0) return -1;
// Записываем в файл информацию из структуры modeInfo
fprintf(file, "Атрибуты режима: %04Xh \n",
modeInfo.usModeAttr);
fprintf(file, "Атрибуты окна: A %02Xh \n",
modeInfo.ucWinAAttr);
fprintf(file, "Атрибуты окна: B %02Xh \n",
modeInfo.ucWinBAttr);
fprintf(file, "Шаг позиционирования окна: %d Кбайт \n",
modeInfo.usWinGranularity);
fprintf(file, "Размер окна, Кбайт: %d \n",
modeInfo.usWinSize );
fprintf(file, "Начало сегмента окна A: %04Xh \n",
modeInfo.usBegSegA );
fprintf(file, "Начало сегмента окна B: %04Xh \n",
modeInfo.usBegSegB );
fprintf(file, "Функция перемещения окна: %p \n",
modeInfo.fpWinFunc );
fprintf(file, "Байт на линию сканирования: %d \n",
modeInfo.usBytesPerScanLine );
// Объем видеопамяти определяется VBE версии не младше 1.2
if(vesaInfo.usVersion" = 0x102)
{
fprintf(file, "Разрешение по горизонтали: %d \n",
modeInfo.usSizeX);
fprintf(file, "Разрешение по вертикали: %d \n",
modeInfo.usSizeY);
fprintf(file, "Ширина символа: %02Xh \n",
modeInfo.ucCharSizeX);
fprintf(file, "Высота символа: %02Xh \n",
modeInfo.ucCharSizeY);
fprintf(file, "Количество слоев видеопамяти: %02Xh
\n", modeInfo.ucNumPlanes);
fprintf(file, "Количество бит на пиксел: %02Xh \n",
modeInfo.ucNumPixelBits);
fprintf(file, "Количество банков памяти: %02Xh \n",
modeInfo.ucBanksNum);
fprintf(file, "Тип модели памяти: %02Xh \n",
modeInfo.ucTypeMemModel);
fprintf(file, "Размер банка памяти: %02Xh \n",
modeInfo.ucBankSize);
fprintf(file, "Количество доступных страниц
видеопамяти: %02Xh \n", modeInfo.ucPageNum);
fprintf(file, "Размер поля красного компоненты"
" цвета: %02Xh \n", modeInfo.ucRedSize);
fprintf(file, "Положение красного поля: %02Xh \n",
modeInfo.ucRedField);
fprintf(file, "Размер поля зеленой компоненты"
"цвета пикселов: %02Xh \n",modeInfo.ucGreenSize);
fprintf(file, "Положение зеленого поля: %02Xh \n",
modeInfo.ucGreenField);
fprintf(file, "Размер поля синей компоненты цвета"
" пикселов: %02Xh \n", modeInfo.ucBlueSize);
fprintf(file, "Положение синего поля: %02Xh \n",
modeInfo.ucBlueField);
fprintf(file, "Размер резервной области: %02Xh \n",
modeInfo.ucResSize);
fprintf(file, "Положение резервного поля: %02Xh \n",
modeInfo.ucResField);
fprintf(file, "Режим ЦАП: %02X\n",
modeInfo.ucDACInfo);
}
}
return iResult;
}
//- ____________________ =
// Функция AnalyseResult
//- ____________________ =
int
AnalyseResult(union REGS regs)
{
int iResult;
if((regs.h.al - 0x4f) (regs.h.ah - 0))
iResult = 0;
else if(regs.h.al!= 0x4f)
iResult = -1;
else
iResult = 1;
return iResult;
} Во включаемом файле VESA.H определены структуры VESAINFO и VESAMODEINFO, которые используются при определении возможностей VBE и видеоадаптера. Исходный текст файла VESA.H представлен в листинге 7.2. Листинг 7.2. Файл VESA.H // Информация о VBE и видеоадаптере
typedef struct
{
// Поддерживается всеми версиями VBE
char cSignature[4];
unsigned short usVersion;
char far *fpInfoOEM;
unsigned char ucCapabilities[4];
unsigned short far *fpModeTable;
// Поддерживается VBE версии 1.2
unsigned short usTotalMemory;
// Поддерживается VBE версии 2.0
unsigned short usRevVersion;
char far *fpOEMName;
char far *fpOEMProductName;
char far *fpOEMRevVersion;
char cReserv[222];
char cOEMData[256];
} VESAINFO;
// Характеристика режима видеоадаптера
typedef struct
{
unsigned short usModeAttr;
unsigned char ucWinAAttr;
unsigned char ucWinBAttr;
unsigned short usWinGranularity;
unsigned short usWinSize;
unsigned short usBegSegA;
unsigned short usBegSegB;
void far *fpWinFunc;
unsigned short usBytesPerScanLine;
// Поддерживается VBE версии 1.2
unsigned short usSizeX;
unsigned short usSizeY;
unsigned char ucCharSizeX;
unsigned char ucCharSizeY;
unsigned char ucNumPlanes;
unsigned char ucNumPixelBits;
unsigned char ucBanksNum;
unsigned char ucTypeMemModel;
unsigned char ucBankSize;
unsigned char ucPageNum;
unsigned char ucReserv1;
unsigned char ucRedSize;
unsigned char ucRedField;
unsigned char ucGreenSize;
unsigned char ucGreenField;
unsigned char ucBlueSize;
unsigned char ucBlueField;
unsigned char ucResSize;
unsigned char ucResField;
unsigned char ucDACInfo;
// Поддерживается VBE версии 2.0
unsigned char far *VideoBuff;
unsigned char far *ScrOffset;
unsigned short usScrSize;
unsigned char ucReserv2[206];
} VESAMODEINFO; На рисунке 7.5 мы проиллюстрировали назначение полей структуры VESAMODEINFO, отвечающих за формат видеопамяти. \s \* MERGEFORMAT Рисунок 7.5 Определение образа символа Установить режим видеоадаптера Функция предназначена для установки режима работы видеоадаптера. Вы можете использовать ее для выбора любого из режимов, описанных в спецификации VBE и поддерживаемых видеоадаптером. Перед вызовом данной функции рекомендуется проверить, поддерживает ли адаптер данный режим. Для этого можно воспользоваться функцией 01h VBE. На входе: AH 4Fh AL 02h BX Номер режима VESA. Номера режимов VESA перечислены в главе "Режимы работы видеоадаптеров" На выходе: AL 4Fh AH Результат: 0, в случае успешного завершения, 1 в случае ошибки Перед вызовом функции вы должны занести в регистр BX номер режима VESA, который необходимо установить. Старший бит регистра BX (бит D15) определяет, будет ли выполняться очистка видеопамяти. Если бит D15 равен единице, тогда видеопамять не очищается. Бит D14 управляет адресацией видеопамяти. Если бит D14 равен единице, функция устанавливает режим видеоадаптера, используя 32-битную адресацию защищенного режима видеопамяти. В этом случае вы можете получить адрес начала и размер видеобуфера при помощи функции 01h (см. выше). Определить текущий режим видеоадаптера Функция предназначена для определения текущего режима видеоадаптера. Если видеоадаптер работает в режиме не соответствующем спецификации VBE, функция может вернуть неправильные значения. На входе: AH 4Fh AL 03h На выходе: AL 4Fh AH Результат: 0, в случае успешного завершения, 1 в случае ошибки BX Номер режима Сохранить/восстановить состояние видеоадаптера Функция позволяет сохранить в буфере программы информацию о текущем состоянии видеоадаптера и восстановить ее впоследствии. На входе: AH 4Fh AL 04h DL 00h Определить размер буфера состояния DL 01h Сохранить состояние видеосистемы ES:BX Указатель на буфер DL 02h Восстановить состояние видеосистемы ES:BX Указатель на буфер CX Флаги управления сохранением и восстановлением: D0 состояние видеоадаптера; D1 состояние видеоданных BIOS; D2 состояние регистров ЦАП; D3 состояние регистров SVGA На выходе: AL 4Fh AH Результат: 0, в случае успешного завершения, 1 в случае ошибки Управление адресацией видеопамяти Центральный процессор получает доступ к видеопамяти адаптера через окно небольшого размера. Функция 4F05h позволяет позиционировать окно по видеопамяти и определять его текущее положение. Окно может позиционироваться с определенным шагом. Функция 4F05h содержит две подфункции, выбираемые регистром BH. Первая подфункция BH = 0 позволяет переместить окно в определенную позицию. Вторая подфункция BH = 1 определяет текущее положение окна. На входе: AH 4Fh AL 05h BL Номер окна: 0 - окно A, 1 - окно B BH 00h выбор окна видеопамяти DX Адрес окна видеопамяти (в единицах шага) BH 01h определить адрес окна видеопамяти DX Адрес окна видеопамяти (в единицах шага) На выходе: AL 4Fh AH Результат: 0, в случае успешного завершения, 1 в случае ошибки Установить/определить длину строки развертки Функция 4F06h содержит две подфункции, выбираемые регистром BH. Первая подфункция BL = 0 позволяет установить логическую длину строки развертки больше чем физически может поместиться на экране. Такая возможность полезна для организации плавной свертки экрана. Вторая подфункция BL = 1 определяет длину строки развертки. На входе: AH 4Fh AL 06h BL 00h установить длину строки развертки CX Требуемая длинна строки развертки в пикселах BL 01h определить длину строки развертки На выходе: AL 4Fh AH Результат: 0, в случае успешного завершения, 1 в случае ошибки BX Количество байт на строку развертки CX Количество пикселов в строке развертки DX Максимальное количество строк развертки SYMBOL 119 \f "Wingdings" \s 10 \h Если запрашивается длинна строки развертки, которая не поддерживается, тогда устанавливается первое возможное значение, большее запрашиваемого SYMBOL 119 \f "Wingdings" \s 10 \h Линия развертки может быть шире видимой области экрана SYMBOL 119 \f "Wingdings" \s 10 \h Данная функция доступна в текстовых режимах, при условии, что значения длинны строки развертки и количества строк развертки умножаются на соответствующие значения размера символов Установить/определить видимую область экрана Функция 4F07h содержит две подфункции, выбираемые регистром BL. Первая подфункция BL = 0 позволяет установить логические координаты пиксела, отображаемого в левом верхнем углу экрана. Установка новых логических координат позволяет отобразить на экране другую область видеобуфера. В частности, вы можете с помощью функции 4F06h выбрать логическую длину линии развертки больше физической, а затем плавно сворачивать изображение на экране. Вторая подфункция BL = 1 определить текущие координаты первого пиксела на экране. На входе: AH 4Fh AL 07h BH Не используется BL 00h Установить начало видимой области монитора CX Первый (слева) видимый символ в строке развертки DX Первая видимая строка развертки BL 01h Определить начало видимой области монитора BH 00h CX Первый видимый символ в строке развертки DX Первая видимая строка развертки На выходе: AL 4Fh AH Результат: 0, в случае успешного завершения, 1 в случае ошибки SYMBOL 119 \f "Wingdings" \s 10 \h Данная функция доступна в текстовых режимах, при условии, что значения длинны строки развертки и количества строк развертки умножаются на соответствующие значения размера символов Установить/определить размер регистров ЦАП Видеоадаптеры VGA и SVGA содержат три ЦАП, каждый из которых определяет цвет одной из трех компонент цвета пиксела - красной, зеленой и синей. ЦАП стандартного видеоадаптера VGA отводит по шесть бит на определение каждой из этих компонент. Видеоадаптеры SVGA, имеющие переключаемый ЦАП, поддерживают переменное количество бит на каждую компоненту цвета. Чтобы определить обладает ли видеоадаптер переключаемым ЦАП следует воспользоваться функцией 4F00h. Функция 4F08h содержит две подфункции, выбираемые регистром BL. Первая подфункция BL = 0 позволяет установить количество бит используемых на каждый чистый цвет. Вторая подфункция BL = 1 позволяет определить количество бит используемых на каждый чистый цвет. На входе: AH 4Fh AL 08h BL 00h BH Количество бит на каждый чистый цвет BL 01h На выходе: AL 4Fh AH Результат: 0, в случае успешного завершения, 1 в случае ошибки BH Количество бит на каждый чистый цвет Управление монитором Многие современные мониторы позволяют временно отключать свои подсистемы, резко уменьшая потребление электроэнергии. Для обеспечения этой особенности монитор видеоадаптер должен соответствовать спецификации Energy Star и Display Power Management Signaling (DPMS). Мы опишем несколько функций VBE/PM (VESA Display BIOS Extensions/Power Management) версии 1.0. С помощью них вы сможете определить, какие режимы экономии электроэнергии обеспечивает ваша видеосистема и выбрать любой из этих режимов. В спецификации VBE/PM 1.0 различают следующие режимы: Режим Описание ON Обычный режим монитора STANDBY Гаснет изображение на экране монитора. Режим STANDBY доступен для всех типов мониторов REDUSED ON Уменьшается яркость изображения. Предназначается для мониторов, выполненных на основе газоразрядных и жидкокристаллических панелей SUSPEND Отключаются строчная развертка. Монитор переходит в режим экономии электроэнергии первого уровня (см. описание вашего монитора). Чтобы видеоадаптер мог установить режим SUSPEND, необходимо, чтобы монитор соответствовал стандарту Energy Star OFF Монитор отключаются полностью. Работает необходимый минимум схем монитора, позволяющий снова его включить. Монитор должен соответствовать стандарту Energy Star Определение возможностей управления Функция 4F10h определяет, какие режимы экономии электроэнергии поддерживает видеоадаптер. На входе: AH 4Fh AL 10h BL 00h ES:DI Зарезервировано, должен содержать 0000:0000h На выходе: AL 4Fh - функция поддерживается;!= 4Fh - функция не поддерживается AH 0, в случае успешного завершения, 1 в случае ошибки BH Поддерживаемые режимы сохранения электроэнергии: D0 - содержит 1, если доступен режим STANDBY; D1 - содержит 1, если доступен режим SUSPEND; D2 - содержит 1, если доступен режим OFF; D3 - содержит 1, если доступен режим REDUSED ON; D7-D4 зарезервировано BL Номер версии VBE/PM: D3-D0 младшая часть номера версии D7-D4 старшая часть номера версии ES:DI Не изменяется Включить режим сохранения электроэнергии Функция устанавливает один из режимов, определенных в спецификации VBE/PM. Перед установкой режима, следует убедиться, что он доступен вашей видеосистеме. Для этого следует воспользоваться функцией 4F10h. На входе: AH 4Fh AL 10h BL 01h BH Режим: 00h - установить режим ON (включить монитор); 01h - установить режим STANDBY (погасить экран); 02h - установить режим SUSPEND (отключить развертку); 04h - установить режим OFF (выключить монитор); 08h - установить режим REDUSED ON (уменьшить яркость) На выходе: AL 4Fh - функция поддерживается; в противном случае функция не поддерживается AH 0, в случае успешного завершения, 1 в случае ошибки BH Не изменяется Определить состояние монитора Последняя функция, рассматриваемая нами, служит для определена текущего режима видеосистемы. На входе: AH 4Fh AL 10h BL 02h На выходе: AL 4Fh - функция поддерживается; в противном случае функция не поддерживается AH 0, в случае успешного завершения, 1 в случае ошибки BH Текущий режим: 00h - ON (монитор включен) 01h - STANDBY (погашен экран монитора) 02h - SUSPEND (отключена строчная развертка) 04h - OFF (монитор отключен) 08h - REDUSED ON (уменьшена яркость изображения) Программа POWER, исходный текст которой представлен в листинге 7.3, демонстрирует использование функций VBE Power Management. После запуска программы POWER, она определяет возможности сохранения электроэнергии, доступные вашей видеоподсистеме. Затем, если компьютер поддерживает VBE Power Management, программа гасит экран монитора. Чтобы продолжить работу нажмите любую клавишу клавиатуры компьютера. Листинг 7.3. Файл POWER.CPP #include "stdio.h"
#include "conio.h"
#include "dos.h"
// Описание функций
void main(void);
int SetPowerState( unsigned char );
int GetPowerState( unsigned char* );
int AnalyseResult(union REGS);
int PowerCapabilities( unsigned char*, unsigned char*,
unsigned char*);
#define ON 0x00
#define OFF 0x04
#define STANDBY 0x01
#define SUSPEND 0x02
#define REDUCED 0x08
//- ____________________ =
// Главная функция
//- ____________________ =
void main(void) {
int uiResult;
unsigned char ucMode, ucModes,
ucMinorVer, ucMajorVer;
// Определяем возможность управления энергопотреблением
uiResult =
PowerCapabilities(ucModes, ucMajorVer, ucMinorVer);
printf("\n\n Copyright (C)Frolov G.V.,1995. "
"E- mail: frolov@glas.apc.org\n");
if(uiResult-0) {
printf("\n Версия VBE Power Management %d.%d",
(int)ucMajorVer, (int)ucMinorVer );
printf("\n Поддерживаются режимы:\n"
"STANDBY - %s\n"
"SUSPEND - %s\n"
"OFF - %s\n"
"REDUCED - %s\n",
(ucModes STANDBY)? "да": "нет",
(ucModes SUSPEND)? "да": "нет",
(ucModes OFF)? "да": "нет",
(ucModes REDUCED)? "да": "нет"
);
}
else if(uiResult "0) {
printf("\n Возможность управления энергопотреблением"
"не поддерживается" );
return;
}
else if(uiResult" 0) {
printf("\n Ошибка при вызове функции "
"VBE Power Management" );
return;
}
// Определяем текущий режим
uiResult = GetPowerState( ucMode );
printf("\n Функция GetPowerState возвращает %d",uiResult);
printf("\n GetPowerState = %x", ucMode );
printf("\n Текущий режим: %s\n",
(ucMode STANDBY)? "STANDBY":
(ucMode SUSPEND)? "SUSPEND":
(ucMode OFF)? "OFF":
(ucMode REDUCED)? "REDUCED": "Неопределен"
);
printf("\n\n После нажатия на клавиатуру "
"гасим изображение (режим STANDBY)"
"\n Для продолжения работы нажмите любую клавишу" );
// Ожидаем нажатие на клавиатуру
getch();
// Гасим экран монитора
uiResult = SetPowerState(STANDBY);
printf("\n Функция SetPowerState(STANDBY) "
"возвращает %d", uiResult );
// Ожидаем нажатие на клавиатуру
getch();
// Включаем монитор
uiResult = SetPowerState( ON );
printf("\n Функция SetPowerState( ON ) "
"возвращает %d", uiResult );
return;
}
//- ____________________ =
// Функция SetPowerState
// Устанавливает режим видеоадаптера и монитора
//- ____________________ =
int
SetPowerState( unsigned char ucMode )
{
union REGS regs;
int iResult;
regs.h.ah = 0x4f;
regs.h.al = 0x10;
regs.h.bl = 0x01;
regs.h.bh = ucMode;
int86(0x10, regs, regs);
iResult = AnalyseResult(regs);
return iResult;
}
//- ____________________ =
// Функция GetPowerState
// Определят текущий режим видеоадаптера
//- ____________________ =
int
GetPowerState( unsigned char *ucMode )
{
union REGS regs;
int iResult;
regs.h.ah = 0x4f;
regs.h.al = 0x10;
regs.h.bl = 0x02;
int86(0x10, regs, regs);
*ucMode = regs.h.bh;
iResult = AnalyseResult(regs);
return iResult;
}
//- ____________________ =
// Функция PowerCapabilities
// Определяет возможности видеоподсистемы
//- ____________________ =
int
PowerCapabilities( unsigned char *ucModes,
unsigned char *ucMajorVer,
unsigned char *ucMinorVer)
{
union REGS regs;
struct SREGS segregs;
int iResult;
regs.h.ah = 0x4f;
regs.h.al = 0x10;
regs.h.bl = 0x00;
segregs.es = 0x00;
regs.x.di = 0x00;
int86x(0x10, regs, regs, segregs);
*ucModes = regs.h.bh;
*ucMinorVer = regs.h.bl 0x0F; // Младший
*ucMajorVer = (regs.h.bl 0xF0)" 4; // Старший
iResult = AnalyseResult(regs);
return iResult;
}
//- ____________________ =
// Функция AnalyseResult
// Анализирует результат, возвращаемый функциями
// Power VBE
//- ____________________ =
int
AnalyseResult(union REGS regs)
{
int iResult;
// Функция VBE Power Management завершилась успешно
if((regs.h.al - 0x4f) (regs.h.ah - 0))
iResult = 0;
// Функция не поддерживается
else if(regs.h.al!= 0x4f)
iResult = -1;
// Ошибка при выполнении функции
else
iResult = 1;
return iResult;
} 8. Использование функций MS-DOS для управления видеоадаптерами Операционная система MS-DOS предоставляет программистам всего несколько функций для работы с видеоподсистемой компьютера. Вывод символов - функция 02h Вывод символа на экран через стандартный поток вывода. На входе: AH 02h DL ASCII-код выводимого символа На выходе: Не используются Данная функция обрабатывает нажатие комбинации клавиш "Ctrl+Break". Вывод строки на экран монитора - функция 09h Выводит строку на экран монитора. Строка отображается, начиная с текущей позиции курсора. Строка должна оканчиваться символом '$' (код ASCII 24h). Строка может включать управляющие символы. На входе: AH 09h DS:DX Адрес отображаемой строки На выходе: Не используются Данная функция обрабатывает нажатие комбинации клавиш "Ctrl+Break". 9. Стандартные функции вывода языка Си В главе рассмотрены основные стандартные функции вывода текстовых данных на экран (через стандартный выходной поток и через консоль). К ним относятся функции putc, putchar, putch, puts, cputs, printf и cprintf. Несмотря на то, что эти функции не входят в определение языка Си, по причинам совместимости их формат одинаков для всех трансляторов с языка Си. Функции putchar и putc Эти функции помещают один символ в текущую позицию выходного потока. Прототипы функций представлены ниже: int putc( int ch, FILE *stream );
int putchar( int ch ); Функция putc отличается от putchar наличием второго аргумента, который определяет выходной поток, в который помещается символ. Она может использоваться и для записи символов в открытый файл и для записи в стандартные потоки ввода-вывода. В частности, если второй аргумент функции равен константе stdout, то она эквивалентна функции putchar и выводит символ в стандартный выходной поток. Этот поток может идти на экран монитора или в файл, если используется свойство переназначения потока. Фактически функция putchar является макроопределением: #define putchar(_c) putc((_c),stdout) Первые параметры обеих функций совпадают по смыслу и задают ASCII-код выводимого символа (не смотря на то, что переменная ch целого типа, используется только ее младший байт). Функции обрабатывают управляющие символы. Список управляющих символов приведен в следующей таблице: Символ Код ASCII Значение \a 07h Звуковой сигнал \b 08h Перемещение назад \f 0Ch Переход к новой странице \n 0Ah Новая строка \r 0Dh Возврат каретки \t 09h Горизонтальная табуляция \v 0Bh Вертикальная табуляция \' 27h Символ кавычки \" 22h Двойная кавычка \\ 5Ch Обратный слеш \% 25h Знак процента Функции возвращают ASCII-код выведенного на экран символа, а в случае ошибки возвращают константу EOF. Чтобы конкретизировать ошибку можно воспользоваться функцией ferror. Программа PUTCHAR (листинг 9.1) демонстрирует использование функции putchar. Листинг 9.1. Файл PUTCHAR.C // Использование функции putchar
#include "stdio.h"
void main(void) {
char *ptr,
out_str[] = "\aputchar\nputc\a";
for(ptr = out_str; *ptr; putchar(*(ptr++)) );
} Включаемый файл STDIO.H содержит спецификации функций putchar и putc. Следовательно, этот файл необходимо включать во все программы, использующие данные функции. Функция puts Функция puts позволяет записать строку в стандартный выходной поток stdout. Строка должна оканчиваться нулем (символ '\0'). Этот символ не помещается в выходной поток. Вместо него записывается управляющий символ '\n', который переводит курсор в начало новой строки. Функция имеет следующий прототип: int puts( char *string ); Единственный параметр функции содержит указатель на отображаемую строку. При успешном выполнении функция возвращает ноль. Если же произошла ошибка, то возвращается ненулевая величина. При использовании функции puts необходимо включить директивой include файл STDIO.H, содержащий спецификацию этой функции. Программа PUTS (листинг 9.2) демонстрирует использование функции puts. Листинг 9.2. Файл PUTS.C #include "stdio.h"
void main(void) {
puts("Работает функция puts!");
} Функция printf Наиболее универсальной стандартной функцией, обеспечивающей запись в выходной поток stdout, является функция printf. Она производит вывод на экран монитора строк, отдельных символов и чисел в различных форматах. Приведем прототип функции printf: int printf( char *format [,argument]... ); Первый аргумент функции содержит указатель на управляющую строку, которая может состоять из: SYMBOL 119 \f "Wingdings" \s 10 \h символов непосредственно отображаемых на экране, SYMBOL 119 \f "Wingdings" \s 10 \h управляющих символов, SYMBOL 119 \f "Wingdings" \s 10 \h спецификаторов формата. Непосредственно выводимые символы и управляющие символы помещаются в выходной поток без изменения. Если управляющая строка содержит спецификаторы формата, то каждому спецификатору должен соответствовать один аргумент, следующий за управляющей строкой. Аргументы представляют собой переменные или константы, которые преобразуются согласно соответствующих им спецификаторов формата и затем также помещаются в выходной поток. Различные спецификаторы формата перечислены в следующей таблице: Спецификатор формата Тип данных %d, %i Целое десятичное число %s Текстовая строка %c Один символ %e, %E Число с плавающей точкой в экспоненциальной форме %f Число с плавающей точкой в десятичной записи %u Целое десятичное число без знака %o Целое восьмеричное число без знака %x, %X Целое шестнадцатиричное число без знака %g, %G Либо %e, либо %f в зависимости от того, в каком формате запись короче %p Значение указателя %n Количество символов В более общем случае, в спецификаторе формата между символом '%' и символом, определяющим тип преобразования можно разместить флаги и префиксы типов: % [флаг] [ширина] [.точность] [префикс типа] символ преобразования Флаги приведены в таблице 13.3, а префиксы типов в таблице 13.4. Параметр [ширина] задает минимальную ширину поля, используемую при печати строки или числа. Если это число или строка не помещаются в поле целиком, то ширина поля увеличивается. Параметр [.точность] определяет для чисел количество отображаемых после запятой цифр, а для строк - максимальное число символов в строке. Флаг Значение - Выравнивание по левой границе + Перед числом помещается его знак пробел (' ') Перед данными помещается пробел Префикс типа Значение F Дальний указатель N Ближний указатель h Короткое целое l, L Длинное целое Функция printf возвращает количество напечатанных ею символов или, в случае ошибки, отрицательную величину. Использование различных спецификаторов формата функции printf демонстрируется программой PRINTF (листинг 9.3). Листинг 9.3. Файл PRINTF.C // При использовании функции printf необходим файл stdio.h
#include "stdio.h"
void main(void) {
int char_count;
char ptr[] = "строка";
printf("\n%23d \n%e \n%.3E \n%f \n%+g \n%-23G \n\n",
1111, 0.01, 0.01, 0.01, 0.01, 0.0000001);
printf("%s%n", ptr, char_count);
printf("\n\nПредыдущая функция вывела %d символов.\n\n",
char_count);
printf("Это %s, расположенная по адресу %Lp.\n\a",
ptr, ptr);
} Функция putch Функция выполняет запись символа на консоль без буферизации. Прототип функции: int putch( int ch ); Параметр функции ch содержит код ASCII выводимого символа. Заметим, что используется только младший байт параметра функции. Функция putch возвращает код ASCII записанного символа, или, в случае возникновения ошибки, константу EOF. При использовании функции putch необходимо включить в программу файл CONIO.H, который содержит ее спецификацию. Функция cputs Функция выполняет запись строки символов, оканчивающихся нулем, на консоль. В отличие от функции puts курсор не переводится на новую строку. Приведем прототип функции cputs: int cputs( char *string ); Единственный параметр функции содержит указатель на отображаемую строку. При успешном выполнении функция возвращает ноль. Если произошла ошибка, то возвращается ненулевая величина. При использовании функции cputs необходимо включить директивой include файл CONIO.H, содержащий спецификацию этой функции. Функция cprintf Функция обеспечивает вывод на экран монитора строк, отдельных символов и чисел в различных форматах непосредственно на консоль. Для вывода отдельных символов используется функция putch. Приведем прототип функции cprintf: int cprintf( char *format [,argument]... ); Ее параметры соответствуют параметрам функции printf, описанной выше. Единственное отличие состоит в том, что она не преобразует символ перевода строки в пару символов - возврат каретки, перевод строки. Функция cprintf возвращает количество напечатанных символов или отрицательную величину в случае ошибки. Литература 1. Richard Wilton, "Programmer's Guide to PC Video Systems", Second Edition, Microsoft Press, 1987. 2. Richard Wilton, "Programmer's Guide to PC PS/2 Video Systems", Microsoft Press, 1987. 3. George Sutty, Steve Blair, "Programmer's Guide to the EGA/VGA", New York, 1988. 4. Bradley Dyck Kliewer, "EGA/VGA A Programmer's Reference Guide", New York, 1988. 5. Michael Abrash, "VGA color paging", Programmer's Journal 7.5, 1989. 6. Michael Abrash, "Still-higher 256-color VGA resolutions", Programmer's Journal 7.5, 1989. 7. Michael Abrash, "Higher 256-color resolutions on the VGA ", Programmer's Journal 7.1, 1989. 8. А. В. Фролов, Г. В. Фролов. Библиотека системного программиста. Тома 11-13. Операционная система Microsoft Windows 3.1 для программиста. Часть 1-3. Москва, "Диалог-МИФИ", 1994 9. А. В. Фролов, Г. В. Фролов. Персональный компьютер - шаг за шагом. Том 2. Операционная система Microsoft Windows 3.1. Москва, "Диалог-МИФИ", 1994 10. А. В. Фролов, Г. В. Фролов. Персональный компьютер - шаг за шагом. Том 4. Что вы должны знать о своем компьютере, "Диалог-МИФИ", 1994 11. А. В. Фролов, Г. В. Фролов. Библиотека системного программиста. Том 10. Компьютер IBM PC/AT, MS-DOS и Windows. Вопросы и ответы. Москва, "Диалог-МИФИ", 1994 12. А. В. Фролов, Г. В. Фролов. Библиотека системного программиста. Том 3. Программирование видеоадаптеров CGA, EGA и VGA. Москва, "Диалог-МИФИ", 1992 Оглавление TOC \o "1-3" Аннотация... PAGEREF _Toc479482490 \h 1 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003400390030000000 Введение... PAGEREF _Toc479482491 \h 1 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003400390031000000 Как связаться с авторами... PAGEREF _Toc479482492 \h 2 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003400390032000000 Благодарности... PAGEREF _Toc479482493 \h 2 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003400390033000000 Замечания... PAGEREF _Toc479482494 \h 2 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003400390034000000 1. Видеоподсистема компьютера... PAGEREF _Toc479482495 \h 2 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003400390035000000 Мониторы... PAGEREF _Toc479482496 \h 4 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003400390036000000 2. Режимы работы видеоадаптеров... PAGEREF _Toc479482497 \h 6 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003400390037000000 Режимы 0 и 1... PAGEREF _Toc479482498 \h 8 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003400390038000000 Режимы 0*, 1*... PAGEREF _Toc479482499 \h 9 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003400390039000000 Режимы 0 +, 1 +... PAGEREF _Toc479482500 \h 9 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500300030000000 Режимы 2 и 3... PAGEREF _Toc479482501 \h 9 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500300031000000 Режимы 2*, 3*... PAGEREF _Toc479482502 \h 9 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500300032000000 Режимы 2 +, 3 +... PAGEREF _Toc479482503 \h 9 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500300033000000 Режимы 4 и 5... PAGEREF _Toc479482504 \h 9 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500300034000000 Режим 6... PAGEREF _Toc479482505 \h 10 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500300035000000 Режим 7... PAGEREF _Toc479482506 \h 10 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500300036000000 Режим 7 +... PAGEREF _Toc479482507 \h 10 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500300037000000 Режимы 8, 9, 0Ah... PAGEREF _Toc479482508 \h 10 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500300038000000 Режим 0Dh... PAGEREF _Toc479482509 \h 10 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500300039000000 Режим 0Eh... PAGEREF _Toc479482510 \h 11 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500310030000000 Режим 0Fh... PAGEREF _Toc479482511 \h 11 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500310031000000 Режим 10h... PAGEREF _Toc479482512 \h 11 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500310032000000 Режим 11h... PAGEREF _Toc479482513 \h 11 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500310033000000 Режим 12h... PAGEREF _Toc479482514 \h 11 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500310034000000 Режим 13h... PAGEREF _Toc479482515 \h 12 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500310035000000 3. Архитектура видеоадаптеров EGA и VGA... PAGEREF _Toc479482516 \h 12 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500310036000000 Монитор... PAGEREF _Toc479482517 \h 13 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500310037000000 Видеопамять... PAGEREF _Toc479482518 \h 13 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500310038000000 Текстовый режим... PAGEREF _Toc479482519 \h 14 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500310039000000 Видеопамять в графических режимах... PAGEREF _Toc479482520 \h 21 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500320030000000 Графический контроллер... PAGEREF _Toc479482521 \h 27 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500320031000000 Последовательный преобразователь... PAGEREF _Toc479482522 \h 29 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500320032000000 Контроллер атрибутов... PAGEREF _Toc479482523 \h 29 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500320033000000 Контроллер ЭЛТ... PAGEREF _Toc479482524 \h 30 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500320034000000 Синхронизатор... PAGEREF _Toc479482525 \h 30 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500320035000000 4. Регистры видеоадаптеров EGA, VGA и SVGA... PAGEREF _Toc479482526 \h 31 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500320036000000 Краткий обзор... PAGEREF _Toc479482527 \h 31 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500320037000000 Внешние регистры... PAGEREF _Toc479482528 \h 33 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500320038000000 Регистр определения различных режимов работы (Miscellaneous Output Register - MOR) PAGEREF _Toc479482529 \h 33 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500320039000000 Регистр управления дополнительным устройством (Feature Control Register - FCR) PAGEREF _Toc479482530 \h 34 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500330030000000 Регистр состояния 0 (Input Status Register 0 - ISR0)... PAGEREF _Toc479482531 \h 34 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500330031000000 Регистр состояния 1 (Input Status Register 1 - ISR0)... PAGEREF _Toc479482532 \h 36 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500330032000000 Регистр разрешения работы системы VGA (VGA Enable Register - VGA_ER)... PAGEREF _Toc479482533 \h 38 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500330033000000 Регистр сброса триггера-защелки светового пера (Light Pen Latch Reset Register - LPLRR) PAGEREF _Toc479482534 \h 38 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500330034000000 Регистр установки триггера-защелки светового пера (Light Pen Latch Set Register - LPLSR) PAGEREF _Toc479482535 \h 39 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500330035000000 Регистры контроллера ЭЛТ... PAGEREF _Toc479482536 \h 39 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500330036000000 Общая длина линии горизонтальной развертки (Horizontal Total Register - HTR) (индекс 0) PAGEREF _Toc479482537 \h 41 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500330037000000 Длина отображаемой части горизонтальной развертки (Horizontal Display Enable End Register - HDER) (индекс 1) PAGEREF _Toc479482538 \h 42 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500330038000000 Начало импульса гашения луча горизонтальной развертки (Start Horizontal Blank Register - SHBR) (индекс 2) PAGEREF _Toc479482539 \h 42 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500330039000000 Конец импульса гашения луча горизонтальной развертки (End Horizontal Blank Register - EHBR) (индекс 3) PAGEREF _Toc479482540 \h 42 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500340030000000 Начало импульса горизонтального обратного хода луча (Start Horizontal Retrace Register - SHRR) (индекс 4) PAGEREF _Toc479482541 \h 42 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500340031000000 Конец импульса горизонтального обратного хода луча (End Horizontal Retrace Register - EHRR) (индекс 5) PAGEREF _Toc479482542 \h 43 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500340032000000 Число горизонтальных линий растра (Vertical Total Register - VTR) (индекс 6)... PAGEREF _Toc479482543 \h 43 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500340033000000 Дополнительный регистр (Overflow Register - OVR) (индекс 7)... PAGEREF _Toc479482544 \h 43 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500340034000000 Предварительная установка горизонтальной развертки (Preset Row Scan Register - PRSR) (индекс 8) PAGEREF _Toc479482545 \h 43 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500340035000000 Высота символов текста (Max Scan Line Register - MSLR) (индекс 9)... PAGEREF _Toc479482546 \h 44 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500340036000000 Начальная линия курсора (Cursor Start Register - CSR) (индекс 0Ah)... PAGEREF _Toc479482547 \h 44 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500340037000000 Конечная линия курсора (Cursor End Register - CER) (индекс 0Bh)... PAGEREF _Toc479482548 \h 45 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500340038000000 Регистры начального адреса... PAGEREF _Toc479482549 \h 46 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500340039000000 Регистры, определяющие положение курсора... PAGEREF _Toc479482550 \h 47 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500350030000000 Начало обратного вертикального хода луча (Vertical Retrace Start Register - VRSR) (индекс 10h) PAGEREF _Toc479482551 \h 48 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500350031000000 Конец обратного вертикального хода луча (Vertical Retrace End Register - VRER) (индекс 11h) PAGEREF _Toc479482552 \h 48 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500350032000000 Регистр адреса светового пера (Light Pen Address Register - LPAR)... PAGEREF _Toc479482553 \h 49 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500350033000000 Завершение отображения вертикальной развертки (Vertical Display End Register - VDER) (индекс 12h) PAGEREF _Toc479482554 \h 49 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500350034000000 Логическая ширина экрана (Offset Register - OFR) (индекс 13h)... PAGEREF _Toc479482555 \h 49 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500350035000000 Положение подчеркивания символа (Underline Location Register - ULR) (индекс 14h) PAGEREF _Toc479482556 \h 50 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500350036000000 Начало импульса гашения вертикальной развертки (Start Vertical Blank Register - SVBR) (индекс 15h) PAGEREF _Toc479482557 \h 52 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500350037000000 Конец импульса гашения вертикальной развертки (End Vertical Blank Register - EVBR) (индекс 16h) PAGEREF _Toc479482558 \h 52 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500350038000000 Управление режимом (Mode Control Register - MCR) (индекс 17h)... PAGEREF _Toc479482559 \h 52 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500350039000000 Регистр сравнения линий (Line Compare Register - LCR) (индекс 18h)... PAGEREF _Toc479482560 \h 53 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500360030000000 Регистры синхронизатора... PAGEREF _Toc479482561 \h 57 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500360031000000 Регистр сброса синхронизатора (Reset Register - RR) (индекс 0)... PAGEREF _Toc479482562 \h 57 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500360032000000 Регистр режима синхронизации (Clock Mode Register - CMR) (индекс 1)... PAGEREF _Toc479482563 \h 57 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500360033000000 Регистр разрешения записи цветового слоя (Color Plane Write Enable - CPWE) (индекс 2) PAGEREF _Toc479482564 \h 58 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500360034000000 Регистр выбора знакогенератора (Character Generator Select Register - CGSR) (индекс 3) PAGEREF _Toc479482565 \h 59 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500360035000000 Регистр определения структуры памяти (Memory Mode Register - MMR) (индекс 4)... PAGEREF _Toc479482566 \h 59 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500360036000000 Регистры графического контроллера... PAGEREF _Toc479482567 \h 60 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500360037000000 Регистр установки/сброса (Set/Reset Register - SRR) (индекс 0)... PAGEREF _Toc479482568 \h 61 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500360038000000 Регистр разрешения установки/сброса (Set/Reset Enable Register - SRER) (индекс 1) PAGEREF _Toc479482569 \h 61 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500360039000000 Регистр сравнения цветов (Color Compare Register - CCR) (индекс 2)... PAGEREF _Toc479482570 \h 62 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500370030000000 Регистр циклического сдвига и выбора функции (Data Rotate Function Select - DRFS) (индекс 3) PAGEREF _Toc479482571 \h 63 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500370031000000 Регистр выбора читаемого слоя (Read Plane Select Register - RPSR) (индекс 4)... PAGEREF _Toc479482572 \h 64 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500370032000000 Регистр режима работы (Mode Register - MDR) (индекс 5)... PAGEREF _Toc479482573 \h 65 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500370033000000 Регистр смешанного назначения (Miscellaneous Register - MIR) (индекс 6)... PAGEREF _Toc479482574 \h 66 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500370034000000 Регистр маскирования цветовых слоев (Color Don't Care Register - CDCR) (индекс 7) PAGEREF _Toc479482575 \h 67 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500370035000000 Регистр битовой маски (Bit Mask Register - BMR) (индекс 8)... PAGEREF _Toc479482576 \h 67 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500370036000000 Регистры контроллера атрибутов... PAGEREF _Toc479482577 \h 68 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500370037000000 Регистры цветовой палитры (0-15) (Color Palette Register's - CPR)... PAGEREF _Toc479482578 \h 68 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500370038000000 Регистр управления режимом (Mode Control Register - MCR) (индекс 10h)... PAGEREF _Toc479482579 \h 69 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500370039000000 Регистр цвета рамки экрана (Screen Border Color Register - SBCR) (индекс 11)... PAGEREF _Toc479482580 \h 69 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500380030000000 Регистр разрешения цветового слоя (Color Plane Enable Register - CPER) (индекс 12) PAGEREF _Toc479482581 \h 70 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500380031000000 Регистр горизонтального панорамирования (Horizontal Panning Register - HPR) (индекс 13) PAGEREF _Toc479482582 \h 70 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500380032000000 Регистр выбора цвета (Color Select Register - CSR) (индекс 14)... PAGEREF _Toc479482583 \h 75 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500380033000000 Регистры цифро-аналогового преобразователя VGA... PAGEREF _Toc479482584 \h 75 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500380034000000 Регистр маскирования пикселов (Pixel Mask Register - PMR)... PAGEREF _Toc479482585 \h 76 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500380035000000 Регистр состояния ЦАП (DAC State Register - DAC_SR)... PAGEREF _Toc479482586 \h 76 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500380036000000 Индекс читаемого регистра таблицы цветов (Look-up Table Read Index Register - LTRIR) PAGEREF _Toc479482587 \h 76 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500380037000000 Индекс записываемого регистра таблицы цветов (Look-up Table Write Index Register - LTWIR) PAGEREF _Toc479482588 \h 77 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500380038000000 Регистр данных таблицы цветов (Look-up Table Data Register - LTDR)... PAGEREF _Toc479482589 \h 77 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500380039000000 Нестандартные режимы видеоадаптера VGA... PAGEREF _Toc479482590 \h 80 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500390030000000 Организация видеопамяти... PAGEREF _Toc479482591 \h 81 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500390031000000 Режим 320х400 пикселов, 256 цветов... PAGEREF _Toc479482592 \h 82 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500390032000000 Режим 360х480 пикселов, 256 цветов... PAGEREF _Toc479482593 \h 88 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500390033000000 5. Использование функций BIOS для работы с видеоадаптерами PAGEREF _Toc479482594 \h 94 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500390034000000 Выбор режима работы - функция 00h... PAGEREF _Toc479482595 \h 95 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500390035000000 Изменение формы курсора - функция 01h... PAGEREF _Toc479482596 \h 95 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500390036000000 Изменение положения курсора - функция 02h... PAGEREF _Toc479482597 \h 96 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500390037000000 Определение положения и формы курсора - функция 03h... PAGEREF _Toc479482598 \h 96 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500390038000000 Использование светового пера - функция 04h... PAGEREF _Toc479482599 \h 96 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003500390039000000 Выбор активной страницы видеопамяти - функция 05h... PAGEREF _Toc479482600 \h 96 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600300030000000 Свертка окна вверх - функция 06h... PAGEREF _Toc479482601 \h 96 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600300031000000 Свертка текстового окна вниз - функция 07h... PAGEREF _Toc479482602 \h 97 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600300032000000 Чтение символа и его атрибутов - функция 08h... PAGEREF _Toc479482603 \h 97 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600300033000000 Запись символа с атрибутами в текущей позиции курсора - функция 09h... PAGEREF _Toc479482604 \h 98 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600300034000000 Запись символа в текущей позиции курсора - функция 0Ah... PAGEREF _Toc479482605 \h 100 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600300035000000 Установка цветовой палитры (режимы 4,5,6) - функция 0Bh... PAGEREF _Toc479482606 \h 100 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600300036000000 Вывод пиксела - функция 0Ch... PAGEREF _Toc479482607 \h 100 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600300037000000 Чтение пиксела - функция 0Dh... PAGEREF _Toc479482608 \h 101 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600300038000000 Запись символа в режиме телетайпа - функция 0Eh... PAGEREF _Toc479482609 \h 102 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600300039000000 Определение текущего режима работы видеоадаптера - функция 0Fh... PAGEREF _Toc479482610 \h 103 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600310030000000 Управление регистрами палитры - функция 10h... PAGEREF _Toc479482611 \h 103 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600310031000000 Установка регистра палитры - подфункция 00h... PAGEREF _Toc479482612 \h 103 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600310032000000 Установка цвета рамки - подфункция 01h... PAGEREF _Toc479482613 \h 103 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600310033000000 Установка всех регистров палитры - подфункция 02h... PAGEREF _Toc479482614 \h 104 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600310034000000 Управление атрибутом мигания и атрибутом интенсивности - подфункция 03h PAGEREF _Toc479482615 \h 104 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600310035000000 Чтение регистра палитры - подфункция 07h... PAGEREF _Toc479482616 \h 105 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600310036000000 Чтение регистра цвета рамки - подфункция 08h... PAGEREF _Toc479482617 \h 105 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600310037000000 Чтение всех регистров палитры - подфункция 09h... PAGEREF _Toc479482618 \h 105 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600310038000000 Установка регистра таблицы цветов (регистров ЦАП) - подфункция 10h... PAGEREF _Toc479482619 \h 105 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600310039000000 Установка нескольких регистров таблицы цветов (регистров ЦАП) - подфункция 12h PAGEREF _Toc479482620 \h 106 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600320030000000 Выбор подмножества цветов - подфункция 13h???... PAGEREF _Toc479482621 \h 106 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600320031000000 Чтение регистра таблицы цветов - подфункция 15h... PAGEREF _Toc479482622 \h 107 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600320032000000 Чтение нескольких регистров таблицы цветов (регистров ЦАП) - подфункция 17h PAGEREF _Toc479482623 \h 107 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600320033000000 Определение режима подмножества цветов - подфункция 1Ah???... PAGEREF _Toc479482624 \h 107 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600320034000000 Установка палитры из градаций серого цвета - подфункция 1Bh... PAGEREF _Toc479482625 \h 107 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600320035000000 Загрузка таблиц знакогенератора - функция 11h... PAGEREF _Toc479482626 \h 109 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600320036000000 Загрузка набора символов пользователя - подфункция 00h... PAGEREF _Toc479482627 \h 110 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600320037000000 Загрузка набора символов из BIOS - подфункция 01h... PAGEREF _Toc479482628 \h 110 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600320038000000 Загрузка набора символов из BIOS - подфункция 02h... PAGEREF _Toc479482629 \h 110 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600320039000000 Выбор активных таблиц знакогенератора - подфункция 03h... PAGEREF _Toc479482630 \h 110 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600330030000000 Загрузка набора символов из BIOS - подфункция 04h... PAGEREF _Toc479482631 \h 111 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600330031000000 Установка вектора прерывания 1Fh - подфункция 20h... PAGEREF _Toc479482632 \h 111 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600330032000000 Установка набора символов для графических режимов - подфункция 21h... PAGEREF _Toc479482633 \h 111 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600330033000000 Установка набора символов 8х14 из ПЗУ BIOS... PAGEREF _Toc479482634 \h 111 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600330034000000 Установка набора символов 8х8 из ПЗУ BIOS... PAGEREF _Toc479482635 \h 111 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600330035000000 Установка набора символов 8х16 из ПЗУ BIOS... PAGEREF _Toc479482636 \h 111 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600330036000000 Получение информации об используемом наборе символов - подфункция 30h PAGEREF _Toc479482637 \h 112 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600330037000000 Определение конфигурации и выбор программы распечатки экрана - функция 12h PAGEREF _Toc479482638 \h 112 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600330038000000 Определение конфигурации видеоадаптера - подфункция 10h... PAGEREF _Toc479482639 \h 112 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600330039000000 Выбор программы печати экрана - подфункция 20h... PAGEREF _Toc479482640 \h 113 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600340030000000 Выбор количества линий развертки в текстовом режиме - подфункция 30h... PAGEREF _Toc479482641 \h 113 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600340031000000 Запрещение переустановки палитры - подфункция 31h... PAGEREF _Toc479482642 \h 113 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600340032000000 Управление доступом к видеоадаптеру - подфункция 32h... PAGEREF _Toc479482643 \h 113 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600340033000000 Управление преобразованием серого цвета - подфункция 33h... PAGEREF _Toc479482644 \h 113 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600340034000000 Эмуляция курсора CGA - подфункция 34h... PAGEREF _Toc479482645 \h 114 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600340035000000 Выбор активного монитора - подфункция 35h... PAGEREF _Toc479482646 \h 114 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600340036000000 Гашение экрана монитора - подфункция 36h... PAGEREF _Toc479482647 \h 114 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600340037000000 Вывод текстовой строки - функция 13h... PAGEREF _Toc479482648 \h 115 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600340038000000 Чтение/запись конфигурации видеосистемы - функция 1Ah... PAGEREF _Toc479482649 \h 115 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600340039000000 Чтение конфигурации видеосистемы - подфункция 00h... PAGEREF _Toc479482650 \h 115 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600350030000000 Запись конфигурации видеосистемы - подфункция 01h... PAGEREF _Toc479482651 \h 115 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600350031000000 Получение данных о состоянии VGA - функция 1Bh... PAGEREF _Toc479482652 \h 115 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600350032000000 Сохранение/восстановление состояния видеоадаптера - функция 1Ch... PAGEREF _Toc479482653 \h 118 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600350033000000 Определение размера буфера - подфункция 00h... PAGEREF _Toc479482654 \h 118 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600350034000000 Сохранение текущего состояния видеоадаптера - подфункция 01h... PAGEREF _Toc479482655 \h 118 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600350035000000 Восстановление текущего состояния видеоадаптера - подфункция 02h... PAGEREF _Toc479482656 \h 118 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600350036000000 Русификация видеоадаптеров... PAGEREF _Toc479482657 \h 118 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600350037000000 6. Область данных видеофункций BIOS... PAGEREF _Toc479482658 \h 143 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600350038000000 Переменные в младших адресах памяти... PAGEREF _Toc479482659 \h 143 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600350039000000 Таблица окружения... PAGEREF _Toc479482660 \h 145 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600360030000000 Таблица параметров... PAGEREF _Toc479482661 \h 145 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600360031000000 Область сохранения... PAGEREF _Toc479482662 \h 147 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600360032000000 Таблица символов текстового режима... PAGEREF _Toc479482663 \h 147 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600360033000000 Таблица символов графического режима... PAGEREF _Toc479482664 \h 147 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600360034000000 Дополнительная таблица окружения... PAGEREF _Toc479482665 \h 147 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600360035000000 Вторая таблица символов текстового режима... PAGEREF _Toc479482666 \h 148 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600360036000000 Таблица кодов комбинаций мониторов... PAGEREF _Toc479482667 \h 148 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600360037000000 Таблица настройки палитры... PAGEREF _Toc479482668 \h 148 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600360038000000 7. Видеоадаптеры SVGA... PAGEREF _Toc479482669 \h 150 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600360039000000 Видеопамять SVGA... PAGEREF _Toc479482670 \h 150 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600370030000000 Слоеный пирог... PAGEREF _Toc479482671 \h 150 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600370031000000 Увидеть весь мир через замочную скважину... PAGEREF _Toc479482672 \h 151 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600370032000000 Больше цветов больше бит... PAGEREF _Toc479482673 \h 151 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600370033000000 Стандарт VESA... PAGEREF _Toc479482674 \h 152 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600370034000000 Получить информацию о реализации VBE и видеоадаптере... PAGEREF _Toc479482675 \h 152 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600370035000000 Получить информацию о режиме видеоадаптера... PAGEREF _Toc479482676 \h 153 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600370036000000 Установить режим видеоадаптера... PAGEREF _Toc479482677 \h 159 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600370037000000 Определить текущий режим видеоадаптера... PAGEREF _Toc479482678 \h 159 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600370038000000 Сохранить/восстановить состояние видеоадаптера... PAGEREF _Toc479482679 \h 159 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600370039000000 Управление адресацией видеопамяти... PAGEREF _Toc479482680 \h 159 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600380030000000 Установить/определить длину строки развертки... PAGEREF _Toc479482681 \h 159 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600380031000000 Установить/определить видимую область экрана... PAGEREF _Toc479482682 \h 160 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600380032000000 Установить/определить размер регистров ЦАП... PAGEREF _Toc479482683 \h 160 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600380033000000 Управление монитором... PAGEREF _Toc479482684 \h 161 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600380034000000 Определение возможностей управления... PAGEREF _Toc479482685 \h 161 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600380035000000 Включить режим сохранения электроэнергии... PAGEREF _Toc479482686 \h 161 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600380036000000 Определить состояние монитора... PAGEREF _Toc479482687 \h 161 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600380037000000 8. Использование функций MS-DOS для управления видеоадаптерами PAGEREF _Toc479482688 \h 165 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600380038000000 Вывод символов - функция 02h... PAGEREF _Toc479482689 \h 165 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600380039000000 Вывод строки на экран монитора - функция 09h... PAGEREF _Toc479482690 \h 165 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600390030000000 9. Стандартные функции вывода языка Си... PAGEREF _Toc479482691 \h 165 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600390031000000 Функции putchar и putc... PAGEREF _Toc479482692 \h 165 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600390032000000 Функция puts... PAGEREF _Toc479482693 \h 166 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600390033000000 Функция printf... PAGEREF _Toc479482694 \h 166 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600390034000000 Функция putch... PAGEREF _Toc479482695 \h 167 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600390035000000 Функция cputs... PAGEREF _Toc479482696 \h 168 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600390036000000 Функция cprintf... PAGEREF _Toc479482697 \h 168 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600390037000000 Литература... PAGEREF _Toc479482698 \h 168 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600390038000000 Оглавление... PAGEREF _Toc479482699 \h 168 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003400370039003400380032003600390039000000

This file was created
with BookDesigner program
bookdesigner@the-ebook.org
10.07.2008
 

---
lib.faint.ru - мобильная библиотека, проект wap-портала faint.ru