[asm, dos] прерывание 09h,замена вводимых символов на строки
От: Arks Россия  
Дата: 23.10.07 16:28
Оценка:
В программе после двух подряд (в течении 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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.