В программе после двух подряд (в течении 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