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

         

Ввод символов текста в буфер строки (Linbuf)



Пример 5.28. Ввод символов текста в буфер строки (Linbuf)

Inline: lea si, Linbuf si = адрес буфера строки
; Ввод очередного символа и управление курсором
Gs: cli запрещаем прерывания
mov CurStat, 03 CurStat = 3
mov Ntick, 09 Ntick =9 (0,5 сек)
sti разрешаем прерывание
call TglCrsr рисуем изображение курсора
mov ah, 00 код запроса ввода символа
int 16h ожидание ввода символа
cli запрещаем прерывания
test CurStat, 02 курсор нарисован ?
mov CurStat, 00 CurStat = О


sti разрешаем прерывания
je Prevanl -> нет, курсор погашен
call TglCrsr гашение курсора ; Предварительный анализ введенного кода
Prevanl: cmp ah, 35h код ASCII существует ?
ja Detail -> нет, это служебный символ
cmp al, 2Oh это управляющий символ ?
jb Detail -> да
mov ds:[si], al запись ASCII кода в буфер строки
inc si коррекция адреса
call outsgn вывод символа на экран
jmp SHORT Gs переход на продолжение ввода ; Детальный анализ служебных кодов
Detail: crap ah, ICh это символ "Enter" ?
jne Cont_l -> нет, продолжение анализа
mov byte ptr ds:[di], 00; запись признака конца текста
ret возврат из подпрограммы
Cont_l: cmp ah, OEh это символ "возврат на шаг" ?
jne Cont_2 -> нет, продолжение анализа
call prevpos адрес предыдущего знакоместа
mov al, ' ' al = код символа "пробел"
call outsgn стираем предыдущий символ
dec si и удаляем его из буфера строки
call prevpos адрес предыдущего знакоместа
jmp short Gs переход на продолжение ввода
Cont 2: jmp short Gs здесь можно продолжить анализ
; Вьиисление позиции предыдущего символа
Prevpos:sub di, 08 уменьшение адреса видеопамяти
jnc @F -> смена окна не нужна
mov ax, GrUnit ax = единица приращения памяти
sub Cur_win, ax Cur_win = Cur_win — GrUnit
@@: ret возврат из подпрограммы

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

Прерывания от таймера надо запрещать на время работы с переменными Ntick и CurStat. Напомним, что команда cli запрещает, a sti разрешает маскируемые прерывания. В примере 5.28 они используются дважды при разрешении и запрещении изменения состояния рисунка курсора. Во втором случае между test Curstat, 02 и je Prevani расположены две команды, выполнение которых не изменяет состояние регистра флагов (признаков). Это просто трюк, упрощающий проверку состояния и очистку байта
CurStat.

Коды введенного с клавиатуры символа находятся в регистрах ah (scan) и al (ASCII). Если код ASCII существует и его значение больше, чем iFh, то изображение символа выводится на экран и продолжается ввод.
Если обнаружен код служебного символа, то производится его детальный анализ. В примере 5.28 обрабатываются коды только двух символов — <Enter> и <возврат на шаг>. В других случаях подпрограмма просто игнорирует введенный код и ждет ввода с клавиатуры очередного символа. Если вы захотите дополнить подпрограмму, то вместо команды jmp short GS, имеющей метку Cont_2, вставьте команды, выполняющие анализ и обработку нужных вам кодов.

При обнаружении кода символа <Enter> в буфер строки записывается пустой байт и происходит возврат из подпрограммы.

Символ <позврат на шаг> обрабатывается так. Устанавливается адрес предыдущего знакоместа, в него выводится символ <пробел>, последний введенный символ удаляется из буфера строки и повторно устанавливается адрес предыдущего знакоместа. Установку адреса предыдущего знакоместа выполняет подпрограмма Prevpos, которая понадобится, если вы добавите обработку клавиши <левая стрелка> для перемещения влево по строке.



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