В программе после двух подряд (в течении 2х секунд) нажатий на F1,
вместо цифр 0,1,... при вводе на консоль надо выводить строки. Цифры должны заменяться на:
0 — a
1 — bb
2 — ccc
...
Как сделать именно эту замену?
Не помню как это сделать. Пробовал в лоб, но из прерывания строки выводить похоже нельзя:
intprg segment para public'code'assume cs:intprg, ds:intprg
org 100h
start: jmp init
; Резидентная часть
; Данные
old1Ch dd ? ; Для сохранения адреса старого обработика таймера
old09h dd ? ; Старый обработчик клавиатуры
myin db 0ah,0dh,'My interupt in','$'
myout db 0ah,0dh,'My interupt out','$'
str0 db 0ah,0dh,'a','$'
str1 db 0ah,0dh,'bb','$'
str2 db 0ah,0dh,'ccc','$'
str3 db 0ah,0dh,'dddd','$'
str4 db 0ah,0dh,'eeeee','$'
str5 db 0ah,0dh,'ffffff','$'
str6 db 0ah,0dh,'ggggggg','$'
str7 db 0ah,0dh,'hhhhhhhh','$'
str8 db 0ah,0dh,'jjjjjjjjj','$'
str9 db 0ah,0dh,'kkkkkkkkkk','$'
smb db 0ah,0dh,'p','$'
tic db 0 ; количество тиков таймера (36,4 за 2 сек)
flag db 0 ; включен ли отсчет времени (2 сек)
flag2 db 0 ; если == 1, то включён режим замены цифр на буквы
cctrl db 0 ; счётчик кол-ва заблокированных цифр
calt db 0 ; счётчик кол-ва заблокированных клавишь верхней линейки
; Обработчик прерывания по таймеру. Будем использовать прерывание 1Ch
sign dw 0AD03h ; сигнатура для проверки, установлен ли уже свой обработчик прерывания
int1Ch proc far
; если flag == 0, то выходим из обработчика
cmp cs:flag, 0
je exitl
inc cs:tic
; если tic == 36, то считаем, что две секунды прошло
cmp cs:tic, 36
jne exitl
mov cs:tic, 0
mov cs:flag, 0
exitl:
iret
int1Ch endp
; Обработчик клавиатуры
int09h proc far
sti ; разрешить прерывания
push ax
push bx
push es
; проверяем, что нажато...
in al, 60h
cmp al, 3Bh ; F1 ?
jne btn
cmp cs:flag, 0 ; первый раз нажата ?
jne change
mov cs:flag, 1
jmp pre_block ; на pre_block, a не напрямую на block - т.к. слишком далеко до этой метки
change: ; второе нажатие F1
cmp cs:flag2, 1 ; уже включен ражим замены ?
je pre_block
mov cs:flag2, 1
jmp pre_block
btn: ; нажата не F1
cmp cs:flag2, 1
jne to_old
cmp al, 02h
jb to_old
cmp al, 0Bh
ja to_old
; нажата цифровая клавиша:
push dx
cmp al, 0Bh ; 0
jne next1
lea dx, cs:str0
jmp showmsg
next1:
cmp al, 02h ; 1
jne next2
lea dx, cs:str1
jmp showmsg
next2:
cmp al, 03h ; 2
jne next3
lea dx, cs:str2
jmp showmsg
. . .
next8:
cmp al, 09h ; 8
jne next9
lea dx, cs:str8
jmp showmsg
next9:
lea dx, cs:str9
showmsg:
push ax
mov ah, 09h
int 21h ; вывести строку-замену на экран
pop ax
pop dx
jmp block ; не выводить сами цифровые клавиши
; старый обработчик прерываний
to_old:
pop es
pop bx
pop ax
jmp cs:[old09h]
; производим блокирование нажатой клавиши (не отображаем её)
block:
; посылаем подтверждение о чтении порта 60h
in al, 61h
mov ah, al
or al, 80h
out 61h, al
mov al, ah
out 61h, al
; завершаемся - посылаем сообщение для разблокировки прерываний в схеме приоритетов
fin:
cli
mov al, 20h
out 20h, al
pop es
pop bx
pop ax
iret
int09h endp
Re: [asm, dos] прерывание 09h,замена вводимых символов на ст
Здравствуйте, Arks, Вы писали:
A>В программе после двух подряд (в течении 2х секунд) нажатий на F1, A>вместо цифр 0,1,... при вводе на консоль надо выводить строки. A>Не помню как это сделать. Пробовал в лоб, но из прерывания строки выводить похоже нельзя:
Насколько помню, многие прерывания DOS 21h не реентерабельные. Есть определенные способы это обойти: перед выводом проверить, что находимся в "безопасном" обработчике прерывания, например, ожидаем ввода пользователя, и если это не так — запланировать попытку вывода через некоторый интервал времени. Эта ситуация рассматривалась кажется то ли у Зубкова, то ли у Кулакова.
Другой вариант — выводить не через 21-е прерывание DOS, а через 10h — видеосервис. Или вообще, в обработчике int 09h помещать в буфер клавиатуры серию нажатий нужных клавиш.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[2]: [asm, dos] прерывание 09h,замена вводимых символов на
Здравствуйте, Arks, Вы писали:
A>В программе после двух подряд (в течении 2х секунд) нажатий на F1, A>вместо цифр 0,1,... при вводе на консоль надо выводить строки. Цифры должны заменяться на: A>0 — a A>1 — bb A>2 — ccc A>...
Можно попробовать записать строчку в буфер клавиатуры.
Re[3]: [asm, dos] прерывание 09h,замена вводимых символов на
Здравствуйте, Arks, Вы писали:
A>Здравствуйте, ДимДимыч: A>Я не бог весть какой профессионал в этой области. Не могли бы вы мне пример кода написать?
Для резидентов есть специальный int 28h — DOS idle, как раз нужен для того, чтобы можно было что-то нарисовать на экран, например, из резидента (садиться строго аккуратно! Куча резидентов зависят от этого инта, поэтому не забывать отдаться по окнчанию обработки).
А вообще, есть и другие решения — например, подменять программный буффер клавиатуры BIOS (многие программы для клавиатурных макросов под ДОС так и делали).
Re[2]: [asm, dos] прерывание 09h,замена вводимых символов на
Здравствуйте, sch, Вы писали:
sch>Здравствуйте, Arks, Вы писали:
A>>В программе после двух подряд (в течении 2х секунд) нажатий на F1, A>>вместо цифр 0,1,... при вводе на консоль надо выводить строки. Цифры должны заменяться на: A>>0 — a A>>1 — bb A>>2 — ccc A>>...
sch>Можно попробовать записать строчку в буфер клавиатуры.
Кстати, так и сделал. Всем спасибо за советы.
П.С.: Вечно ухожу дела не закрыв как следует старых тем.