Процедуры для работы с одним окном видеопамяти
Процедура 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. Каким из двух способов лучше воспользоваться, решает программист. Мы привели эти примеры для того, чтобы еще раз проиллюстрировать различие между прерыванием и прямым обращением к процедуре.
Контроль ошибок
В данном разделе ничего не говорилось о контроле ошибок при установке или изменении окон видеопамяти. Это объясняется несколькими причинами. Прежде всего, признак ошибки функция 4F05h возвращает только в том случае, если содержимое регистра bb больше единицы, т. е. если неправильно указано запрашиваемое действие. Контроль правильности указанного значения окна не производится, поскольку его не так просто осуществить.
Если задача проверила поддержку установленного видеорежима, т. к. это рекомендовалось в предыдущем разделе, то при корректно организованной работе с видеопамятью значение устанавливаемого окна не может выходить за допустимые пределы. При организации любого контроля над ходом вычислительного процесса надо, прежде всего, руководствоваться соображениями здравого смысла, иначе можно дойти до проверки результатов каждого выполняемого действия.
В рассматриваемом случае возможен единственный способ контроля – проверка соответствия номера окна реально существующему объему видеопамяти. Но выполнять такую проверку при каждом изменении номера окна едва ли целесообразно. В крайнем случае, ее можно временно на период отладки задачи включить в подпрограмму setwin и убрать после отладки. Но лучше тщательно продумать алгоритм работы задачи и проверить правильность его воплощения.
Если вы умеете работать с отладчиками и восстанавливать по кодам команд исходный текст на языке ассемблера, то имеет смысл разобраться в том, как воплощена процедура VMC в BIOS. Это позволит вам узнать, как выполняется чтение или установка номера окна на уровне работы с портами ввода-вывода.