Вывод в графическом режиме, используя функции bios

Вид материалаЛитература
Использование функций BIOS для работы с видеоадаптерами
Выбор режима работы - функция 00h
Выбор активной страницы видеопамяти - функция 05h
Установка цветовой палитры (режимы 4,5,6) - функция 0Bh
Вывод пиксела - функция 0Ch
Чтение пиксела - функция 0Dh
Определение текущего режима работы видеоадаптера - функция 0Fh
Задержка программных операций
Int 1Аh, функция 00h. Чтение счетчика циклов таймера.
Int 15h, функция 86h.
Подобный материал:
1   2   3   4

Использование функций 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, 0Dh ; Выбираем режим номер 0Dh (16 цветов, графический,

int 10h ; разрешение 320x200)

Выбор активной страницы видеопамяти - функция 05h


Функция 05h позволяет изменить активную страницу видеопамяти. Активная страница видеопамяти отображается на экране монитора. Функция не проверяет физического наличия выбранной страницы видеопамяти. Если номер страницы указан неправильно, результат работы функции не определен.


На входе:

AH

05h

 

AL

Номер страницы видеопамяти, которая станет активной

На выходе:

Не используются



Установка цветовой палитры (режимы 4,5,6) - функция 0Bh


Данная функция позволяет выбрать одну из двух стандартных цветовых палитр (см. таблицу ниже). Функция используется для обеспечения совместимости с видеоадаптером 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 – вниз.

Чтение пиксела - функция 0Dh


Функция позволяет определить цвет любого пиксела экрана по его координатам. Функция используется только в графических режимах работы видеоадаптеров.


На входе:

AH

0Dh

 

BH

Номер страницы (для видеоадаптера CGA не используется)

 

CX

Координата X пиксела

 

DX

Координата Y пиксела

На выходе:

AL = номер цвета пиксела

Определение текущего режима работы видеоадаптера - функция 0Fh


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


На входе:

AH

0Fh

На выходе:

AH

Количество символов в строке

 

AL

Номер текущего режима

 

BH

Номер активной страницы видеопамяти


Бит D7 регистра AL соответствует значению бита D7 регистра AL, использованному при предыдущем выборе режима работы видеоадаптера (см. функцию 00h).

Приложение

Задержка программных операций


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

Листинг 1. Программная задержка на основе выполнения вложенных циклов с командой Loop.

proc delay       ; Подпрограмма задержки

     mov cx, N   ; N – счётчик внешнего цикла

outer:

push cx     ; Сохраним содержание счётчик внешнего цикла

mov cx,0 ; Обеспечим максимальное число

              ; повторений (64К раз) внутреннего цикла

inner:

loop Inner  ; Внутренний цикл

     pop cx     ; Восстановим содержание счётчик внешнего цикла

     loop outer  ;Повторим вешний цикл N раз

endp delay


В листинге 1 параметр N выполняет роль масштабного множителя времени задержки:

tзадержки = N*tисполнения внутреннего цикла.

При этом наименьшей единицей времени (т.е. "тиком") является время выполнения внутреннего цикла, состоящего, в свою очередь, из времени исполнения 65535 раз команды Loop. Параметр N подбирается экспериментально для получения tзадержки (в мсек или сек) с учётом быстродействия конкретного компьютера.

Из рассмотрения данного примера очевидны недостатки данного подхода, когда требуется обеспечить выполнение временной задержки в программе, независимо от типа используемого компьютера. Поэтому разумно определять время программной задержки непосредственно по таймеру. Выходные сигналы таймера с частотой 18,2 раза в секунду не зависят от производительности компьютера и играют роль счетчика суточного времени. Реализация данного способа использует функцию 00h прерывания BIOS int 1Ah.

Int 1Аh, функция 00h. Чтение счетчика циклов таймера. Обработчик прерывания BIOS от системного таймера (int 8) подсчитывает количество прерываний (каждые 55 мсек или 18,2 раза в секунду) в двойном слове памяти с адресом 0040h:006Сh. Данная функция возвращает накопленное значение (двоичный код) и сбрасывает его в 0. В регистре AL возвращается 0, если содержимое счетчика не превысило значения, соответствующего 24 часам (при достижении этого значения счетчик сбрасывается), иначе возвращается AL = 1.

Вызов:        АН = 00h.

Возврат:     СХ:DX – число тактов системного времени от полуночи,

                    AL – флаг перехода через сутки.

Примеры возвращаемых значений в СХ:DX:

1 сек             12h или 18,

1 минута       04 44h или 1092,

1 час             1 00 07h или 65543,

24 часа         18 00 B0h или 1 573 040.

Для задержек, меньших 14 секунд, можно пользоваться только младшим байтом регистра DX.

Листинг 2. B данном примере установлена задержка на 5 секунд, что соответствует 91 отсчету таймера

mov ah,0            ; Функция "чтения" циклов таймера

int 1Ah             ; Получаем значение счетчика циклов в cx:dx

add dx,91           ; Добавляем 5 сек. к младшему слову в dx

mov bx,dx           ; Запоминаем требуемое значение в bx и

; выполняем постоянную проверку значений

; счетчика времени суток

repeat:

int 1Ah             ; Вновь получаем значение счетчика

cmp dx,bx            ; Сравниваем с искомым

jne repeat           ; Если не равно, то повторяем снова,

                     ; иначе задержка окончена


Если требуется введение задержки с высокой точностью, то необходимо использовать функцию 86h прерывания BIOS int 15h. Она позволяет определить время задержки в микросекундах. Во время выполнения задержки разрешены прерывания. Управление программе возвращается после истечения заданного времени.

Int 15h, функция 86h.

Вызов:    AH = 86h,  СX:DX = время задержки в мксек.

Возврат: CF = 0 – нормальное исполнение, CF = 1 – функция не поддерживается.

Пример: CX:DX = 0098h:9680h = 10 000 000 мксек = 10 сек.

Примеры

Пример 1


Рассмотрим лишь один наиболее простой и употребительный графический режим VGA 320x200, 256 цветов. В нём каждый пиксель описывается одним байтом, значение которого определяет цвет пикселя.

Переход в графический режим VGA 320x200, 256 цветов осуществляется при помощи функции 00h прерывания BIOS 10h установкой режима 13h.

Приведём программу, которая в графическом режиме 13h рисует две прямые линии: одну красную горизонтальную, другую зелёную под углом 45°. Эта программа демонстрирует отображение пикселей как с помощью BIOS (функция 0Ch прерывания 10h), так и с помощью непосредственного обращения к видеопамяти. Второй способ действует гораздо быстрее первого.

Рассмотрим соответствие байтов видеопамяти и позиций пикселей на экране. Пусть m=0, 1, …, 319 – номер пикселя в строке, n=0, 1, …, 200 – номер строки пикселей. Тогда смещение относительно начала видеопамяти байта, соответствующего m-му пикселю в n-й строке будет m+320*n.


putpix macro x,y,color ; Пиксель при помощи BIOS

mov cx,x

mov dx,y

mov al,color

mov ah,0Ch

int 10h

endm


.model small

.code

prg:

mov ax,0A000h

mov es,ax ; Настройка ES на видеопамять

mov ax,0013h

int 10h ; В графический режим 13h

mov cx,200 ; Линии в 200 пикселей

xor si,si

rpt:

push cx

putpix si,si,2 ; При помощи BIOS

mov es:[si]+32000,byte ptr 4 ; В видеопамять

inc si

pop cx

loop rpt ; Повторить 200 раз

mov ah,08h

int 21h ; Задержка до нажатия клавиши

mov ax,0003h

int 10h ; В текстовый режим 03h

mov ax,4Ch

int 21h ; Возврат в DOS

.stack 256

end prg

Пример 2


При вызове функции 0Ch прерывания 10h в регистр BH заносится номер видеостраницы, на которую выводится данная точка. По умолчанию активной является страница 0, однако рисовать изображение можно как на активной, так и на не активной странице. Для переключения страниц предусмотрена функция 05h прерывания 10h.


putpix macro x,y,color,page

mov cx,x

mov dx,y

mov al,color

mov bh,page

mov ah,0Ch

int 10h

endm


.model small

.code

prg:

mov ax,0A000h

mov ax,000Dh

int 10h


mov bx,1

lbl_page:

push bx

mov cx,200

xor si,si

rpt:

push cx

putpix si,si,bl,bl

inc si

pop cx

loop rpt

pop bx

inc bx

cmp bx,8

jne lbl_page


mov cx,7

lbl_draw:

mov ah,05h ; функция выбора активной страницы

mov al,cl

int 10h

mov ah,08h ; ожидание нажатия клавиши

int 21h

loop lbl_draw

mov ax,0003h ; в текстовый режим

int 10h

mov ax,4Ch

int 21h ; возврат в DOS

.stack 256

end prg

Литература

  1. Фролов А.В., Фролов Г.В. Программирование видеоадаптеров. Библиотека системного программиста. Том 21. – М.: Диалог-МИФИ, 1993.
  2. Митницкий В.Я. Архитектура IBM PC и язык Ассемблера: Учеб. пособие. – М.: МФТИ, 2000. – 148 с.
  3. Рудаков П.И., Финогенов К.Г. Язык ассемблера: уроки программирования. – М.: ДИАЛОГ-МИФИ, 2001. – 640 с.
  4. Ассемблер IBM PC. – .ru/book/assem/index.php.