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

         

Три подпрограммы для работы с видеоокнами



Пример 2.8. Три подпрограммы для работы с видеоокнами



; Установка следующего окна
NxtWin: push ax ; сохраняем содержимое ах
mov ax, GrUnit ; читаем единицу приращения окна
add Cur win, ax ; увеличиваем номер окна
pop ax ; восстанавливаем содержимое ах
; Установка окна, указанного в Cur win
SetWin: PushP,eg <ax,bx,dx> ; сохранение содержимого регистров
xor bx, bx ; признак установки окна
mov dx, Cur win ; номер устанавливаемого окна
call [VMC] ; обращение к подпрограмме BIOS
PopReg <dx,bx,ax> ; восстановление содержимого регистров
ret ; возврат из подпрограммы
; Установка предыдущего окна
PrevWin push ax ; сохранение содержимого ах
mov ax, GrUnit ; читаем единицу приращения окна
sub Cur win, ax ; уменьшаем номер окна
pop ax ; восстанавливаем содержимое ах
jmp SHORT SetWin ; переходим на установку окна

Процедура VMC расположена в "удаленном" сегменте, т. е. в пространстве адресов, не принадлежащих задаче. В таких случаях для обращения к подпрограммам используется команда call, у которой операнд является двойным словом, содержащим полный адрес (сегмент и смещение). При компиляции Макроассемблер формирует специальный код, указывающий процессору, что переход производится на удаленный адрес. В примере 2.8 операндом команды call является переменная VMC, описанная как двойное слово. Заключение имени переменной в квадратные скобки указывает на то, что адресом процедуры является не VMC, а хранящееся в ней значение, которое было установлено при выполнении команд примера 2.6.

Указание типа short в команде jmp заставит Макроассемблер сформировать короткую команду (для перехода не более чем на 128 байтов), код которой занимает два байта. pushReg и PopReg — это макросы (макровызовы). Первый эквивалентен трем командам push ax, push bx и push dx, а второй — трем командам pop dx, pop bx, pop ax. В реальной программе вы должны либо заменить макросы указанными командами, либо поместить в начале текста программы соответствующие им макроопределения, текст которых приведен в примере 2.12. Сохранение исходного содержимого регистров в стеке и восстановление при выходе делается для того, чтобы находящиеся там данные не изменялись в результате выполнения подпрограммы.

Чтение текущего окна. Еще раз вернемся к текущему окну. При корректной работе задачи с окнами значение переменной Cur_win всегда соответствует номеру, находящемуся в регистре видеоконтроллера. Если по каким-то причинам такое соответствие нарушено, то текущее значение окна можно восстановить, прочитав его из видеоконтроллера. Оформлять чтение текущего окна в виде самостоятельной процедуры не целесообразно, поскольку регулярных обращений к ней не должно быть.

Для чтения окна с помощью функции 4F05h надо выполнить следующие три команды:

mov bx, 10Oh ; признак чтения окна
mov ax, 4F05h ; код запрашиваемой функции
int 10h ; обращение к BIOS

Другой способ чтения текущего значения окна заключается в прямом обращении к процедуре BIOS, а именно:

mov bx, lOOh ; признак чтения окна
call [VMC] ; обращение к процедуре BIOS

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



Содержание раздела