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

         

Подпрограмма создающая эффект мигающего курсора



Пример 5.27. Подпрограмма, создающая эффект мигающего курсора

Timeint: PushReg <ax,ds,es>; !! сохранение регистров ах, ds и es
mov ax, data ; ! ! ах = значение сегмента данных
mov ds, ах ; ! ! ds = код сегмента данных
mov es, VBuff ; ! ! es = код сегмента видеобуфера
test CurStat, 01 работа с курсором разрешена ?
jz GoVIC -> нет, завершение подпрограммы
dec Ntick Ntick = Ntick — 1
jnz GoVIC -> пауза продолжается
mov Ntick, 09 Ntick = 9 (примерно 0,5 сек)
xor CurStat, 02 изменение признака состояния курсора
call TglCrsr изменение состояния рисунка курсора
GoVIC: PopReg <es,ds,ax> !! восстановление es, ds и ax
db OEAh код инструкции jmp, на удаленный адрес
VeclC dw 00, 00 старое содержимое вектора ICh

Прежде всего отметим, что подпрограмму примера 5.27 нельзя вызывать командой call Timeint, поскольку ее выполнение завершается не командой ret, а безусловным переходом на тот адрес, который раньше находился в векторе ich. Подпрограмму вызывает процедура BIOS, обрабатывающая задания, адресованные таймеру. Действия, которые надо выполнить для разрешения или запрещения вызовов данной подпрограммы при каждом тике таймера, показаны в примерах 5.25 и 5.26.



При вызове прерывающей подпрограммы в стеке сохраняется содержимое регистров ах, ds и es. В общем случае при входе содержимое регистра ds не определено, и в него надо записать код сегмента данных. Имя сегменту данных присваивается при его описании (см. пример 2.11), обычно это data. Если вы выбрали другое имя, то измените команду mov ax, data. Регистр es используется в подпрограмме TglCrsr, изменяющей текущее состояние рисунка курсора, поэтому он должен содержать код сегмента видеобуфера, который хранится в переменной vbuff.

Основные действия, выполняемые в примере 5.27, достаточно просты. Проверяется состояние младшего разряда байта CurStat, если он очищен, то команда jz GOVIC завершает выполнение подпрограммы, в противном случае работа с рисунком курсора разрешена. Содержимое счетчика тиков уменьшается на 1 и если разность больше нуля, то пауза не закончена и происходит выход из подпрограммы без изменения рисунка курсора. Наконец, если разность равна нулю, то в счетчик тиков записывается число 9, и инвертируются рисунок курсора и признак его состояния.

Перед выходом из подпрограммы восстанавливается сохраненное в стеке содержимое регистров es, ds и ах, а затем выполняется команда jmp, которая передает управление на адрес, сохраненный в двух словах переменной vecic (при выполнении примера 5.25).

В тексте примера 5.27 использован следующий трюк. Имя команды jmp не записано явно, вместо этого в байте, расположенном перед переменной vecic, указан код операции (ОЕАЬ). При ее выполнении микропроцессор интерпретирует содержимое следующих двух слов как адрес, на который производится переход. Это наиболее простой, но не единственно возможный способ вернуться на сохраненное значение вектора прерывания.

Замечание 2
Замечание 2

Если при выполнении вашей задачи содержимое сегментных регистров ds и ез не изменяется после их первоначальной установки, то из текста примера 5.27 можно исключить 5 команд, комментарий к которым начинается с двух восклицательных знаков.

 


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