
01H - ввод с клавиатуры с эхом и ожиданием и с проверкой на
Ctrl-Break;
08H - ввод с клавиатуры без эха с ожиданием и с проверкой на
Ctrl-Break;
07H - ввод с клавиатуры без эха c ожиданием и без проверки на
Ctrl-Break
06H - ввод с клавиатуры без эха без ожидания и без проверки на
Ctrl-Break
0bH - дать статус ввода – была ли нажата клавиша - (и обработать
ждущий Ctrl-Break)
0cH - очистить буфер клавиатуры и ждать ввода
0aH - буферизованный ввод с клавиатуры (ввод строки)
2.Описание спроектированных модулей.
Все программные модули написаны на языке ASSEMBLER. Передача параметров и возврат результатов соответствуют соглашениям, принятым для языка С модели SMALL. Где это необходимо по смыслу задания, пользователю предлагается осуществить выбор из меню, предварительно выведенного на экран, необходимой опции путем ввода ее порядкового номера.
Процедуры для вывода на экран, многократно используемые при выполнении работы, собраны в модуле outprocs.asm (см. Листинг 1.).
Процедуры, реализующие требуемые в задании функции работы с клавиатурой, собраны в модуле kbd.asm (см. Листинг 2).
В остальных модулях, соответствующих каждому пункту задания, содержатся основные части программ, в частности организация интерфейса пользователя.
В тексте модулей даны соответствующие комментарии, поясняющие их назначение, а также назначение всех процедур.
3. Листинги разработанных программ.
Листинг 1. Модуль, содержащий процедуры вывода на экран (outprocs.asm).
masm
model small,c
.stack 100h
.data
digit_sym db ?
.code
public outhex
public outbyte
public initvideo
public clrscr
public outtextxy
public outtext
public outstring
outhex proc c near x:word ;вывод hex-тетрады
mov ax,x ;в текущей позиции
and ax,000Fh
cmp al,10
jae abcdef ; if al>=10
add al,30h ; для 0123456789
jmp short write;
abcdef:
add al,55 ; для ABCDEF
write:
mov digit_sym,al
call outtext c,offset digit_sym,1
ret
outhex endp
outbyte proc c near x:word ;вывод байта в виде hex
mov ax,x ;в текущей позиции
shr ax,4
call outhex c,ax ;вывод старшей тетрады
mov ax,x
call outhex c,ax ;вывод младшей тетрады
ret
outbyte endp
initvideo proc c near ;установка видеорежима
mov ax,0003h ; color 80x25
int 10h ;установка активной страницы
mov ax,0500h
int 10h
ret
initvideo endp
clrscr proc c near ;очистка экрана
mov ax,0600h
mov bh,07h
mov cx,0000h
mov dx,184Fh
int 10h
ret
clrscr endp
;вывод текста в заданную позицию
outtextxy proc c near x:word,y:word,text:word,len:word
push ds
pop es
mov ah,13h
mov al,01h
mov bh,00h
mov bl,0Ah
mov dh,byte ptr y
mov dl,byte ptr x
mov cx,len
push bp
mov bp,text
int 10h
pop bp
ret
outtextxy endp
;вывод текста в текущую позицию
outtext proc c near text:word,len:word
mov ah,03h ;чтение положения курсора
mov bh,00h
int 10h
mov cl,dh ;строка
call outtextxy c,dx,cx,text,len
ret
outtext endp
;вывод строки текста в текущую позицию
outstring proc c near s:word;
mov ah,09h
mov dx,s
int 21h
ret
outstring endp
end
Листинг 2. Модуль, содержащий процедуры, реализующие требуемые функции работы с клавиатурой (kbd.asm).
masm
model small,c
.stack 100h
.code
public getcharfromport
public setkbdparameters
public getcharfrombuf
public getstatus
public putcharinbuf
public clearbuf
public BIOSsetkbdparameters
public BIOSgetchar
public BIOSgetstatus
public BIOSputcharinbuf
;получение скан-кода из порта клавиатуры
getcharfromport proc c near
in al,60h
ret
getcharfromport endp
;задание времени задержки и скорости повтора
setkbdparameters proc c near parametr:word
mov al,0f3h ;запись управляющего кода в al
out 60h,al
mov cx,8000h
kbd_delay: loop kbd_delay
mov al,byte ptr parametr ;запись параметров в al
out 60h,al
ret
setkbdparameters endp
;получение расширенного скэн-кода клавиши путем
;непосредственного обращения к буферу клавиатуры
getcharfrombuf proc c near
mov ax,0040h
mov es,ax
mov bx,es:001Ah ;чтение ук.головы bx:=head
waitkey:
cmp bx,es:001Ch ;head==tail ?
je waitkey ;да - в буфере нет кода
mov ax,es:[bx] ;ax:=[head] чтение кода из буфера
cmp bx,003Ch ;если head указывает на конец буфера
je rewind ;установить head на начало буфера
add bx,2 ;head:=head+2
jmp savehead
rewind:
mov bx,001Eh ;голова на начало буфера
savehead:
mov es:001Ah,bx ;установить head
ret
getcharfrombuf endp
;чтение регистров состояния клавиатуры
; AL 0417h
; AH 0418h
getstatus proc c near
mov ax,0000h
mov es,ax
mov ax,es:0417h
ret
getstatus endp
;запись символа в буфер клавиатуры
putcharinbuf proc c near symb:word
mov ax,0040h
mov es,ax
mov bx,es:001Ch ;bx:=tail
mov ax,symb
mov es:[bx],ax ;код в буфер
add bx,0002h ;tail:=tail+2
cmp bx,003Eh ;if tail==end_of_buf
jne quit_proc ;tail:=beg_of_buf
mov bx,001Eh
quit_proc:
mov es:001Ch,bx ;tail:=bx
ret
putcharinbuf endp
clearbuf proc c near ;очистка буфера клавиатуры
push ax
push es
mov ax,0040h
mov es,ax
cli
mov ax,es:001Ch ;head:=tail
mov es:001Ah,ax
sti
pop es
pop ax
ret
clearbuf endp
;задание времени задержки и скорости повтора через BIOS
; BH repeat delay 0,1,2,3
; BL typematic rate 00..1F
BIOSsetkbdparameters proc c near parametr:word
mov ah,03h
mov al,05h
mov bx,parametr
int 16h
ret
BIOSsetkbdparameters endp
;получение расширенного скэн-кода через BIOS
BIOSgetchar proc c near
mov ah,10h
int 16h
ret
BIOSgetchar endp
;чтение регистров состояния клавиатуры через BIOS
; AL 0417h
; AH 0418h
BIOSgetstatus proc c near
mov ah,12h
int 16h
ret
BIOSgetstatus endp
;запись символа в буфер клавиатуры через прерывание BIOS
BIOSputcharinbuf proc c near symb:word
mov ah,05h
mov cx,symb
int 16h
ret
BIOSputcharinbuf endp
end
Листинг 3. Получение скэн-кодов нажатых и отжатых клавиш.
masm
model small,c
.stack 100h
.data
start_msg db 'Получение скэн-кодов нажатой и отпущенной клавиш (ESC выход) '
down_msg db 'Код нажатой клавиши '
up_msg db 'Код отпущенной клавиши '
cur_60 db 0
.code
extrn outbyte :near
extrn clearbuf :near
extrn initvideo :near
extrn clrscr :near
extrn outtextxy :near
extrn getcharfromport : near
start:
mov ax,@data
mov ds,ax
call initvideo c
call clrscr c
call outtextxy c,0,0,offset start_msg,62
cyckle:
call getcharfromport c
cmp al,01h
jne go ;ESC выход
mov ax,4c00h
int 21h
go:
call clearbuf c
cmp al,cur_60
je cyckle ; если значение изменилось
mov cur_60,al ; вывести код
cmp al,80h
jae keyup ;if al>=128 goto keyup
call outtextxy c,00h,02h,offset down_msg,24
jmp short show
keyup: call outtextxy c,00h,02h,offset up_msg,24
show: mov al,cur_60
call outbyte c,ax
jmp cyckle
end start
Листинг 4.Управление временем задержки и частотой повтора имитации нажатой клавиши непосредственно через порт контроллера.
masm
model small,c
.stack 100h
.data
param dw 0
start_msg db 'Настройка времени задержки и частоты повтора символов'
cr equ 10
lf equ 13
tab equ 9
menu_msg_freq db cr,lf,cr,lf,tab,'Выберите частоту повторения :'
db cr,lf,tab,tab,'1 - 30,0 Гц'
db cr,lf,tab,tab,'2 - 26,7 Гц'
db cr,lf,tab,tab,'3 - 24,0 Гц'
db cr,lf,tab,tab,'4 - 20,0 Гц'
db cr,lf,tab,tab,'5 - 15,0 Гц'
db cr,lf,tab,tab,'6 - 10,0 Гц'
db cr,lf,tab,tab,'7 - 9,2 Гц'
db cr,lf,tab,tab,'8 - 7,5 Гц'
db cr,lf,tab,tab,'9 - 5,0 Гц'
db cr,lf,tab,tab,'0 - 2,0 Гц'
db cr,lf,tab,tab,'ESC выход $'
menu_msg_delay db cr,lf,cr,lf,tab,'Выберите время задержки :'
db cr,lf,tab,tab,'F1 - 250 мсек'
db cr,lf,tab,tab,'F2 - 500 мсек'
db cr,lf,tab,tab,'F3 - 750 мсек'
db cr,lf,tab,tab,'F4 - 1000 мсек'
db cr,lf,tab,tab,'ESC выход $'
.code
extrn clearbuf :near
extrn initvideo :near
extrn clrscr :near
extrn outtextxy :near
extrn outstring :near
extrn getcharfromport:near
extrn setkbdparameters:near
start:
mov ax,@data
mov ds,ax
call initvideo c
call clrscr c
call outtextxy c,0,0,offset start_msg,53
call outstring c,offset menu_msg_freq
menu_loop1:
call getcharfromport c
call clearbuf c
cmp al,02 ;1
je fr1
cmp al,03 ;2
je fr2
cmp al,04 ;3
je fr3
cmp al,05 ;4
je fr4
cmp al,06 ;5
je fr5
cmp al,07 ;6
je fr6
cmp al,08 ;7
je fr7
cmp al,09 ;8
je fr8
cmp al,0Ah ;9
je fr9
cmp al,0Bh ;0
je fr0
cmp al,01h ;ESC - выход
jne menu_loop1
mov ax,4c00h
int 21h
fr1: mov param,00h
jmp menu2
fr2: mov param,01h
jmp menu2
fr3: mov param,02h
jmp menu2
fr4: mov param,04h
jmp menu2
fr5: mov param,08h
jmp menu2
fr6: mov param,0Ch
jmp menu2
fr7: mov param,0Dh
jmp menu2
fr8: mov param,10h
jmp menu2
fr9: mov param,14h
jmp menu2
fr0: mov param,1Fh
menu2: call outstring c,offset menu_msg_delay
menu_loop2:
call getcharfromport c
call clearbuf c
cmp al,3Bh ; F1
je execute
cmp al,3Ch ; F2
je d2
cmp al,3Dh ; F3
je d3
cmp al,3Eh ; F4
je d4
cmp al,01h ;ESC - выход
jne menu_loop2
mov ax,4c00h
int 21h
d2: add param,20h
jmp execute
d3: add param,40h
jmp execute
d4: add param,60h
execute:
call setkbdparameters c,param
mov ax,4c00h
int 21h
end start
Листинг 5.Получение расширенного скэн-кода клавиатуры при непосредственном обращении к буферу клавиатуры
masm
model small,c
.stack 100h
.data
start_msg db 'Получение расширенных скэн-кодов из буфера клавиатуры(ESC выход)'
lo_msg db ' ASCII-код или префикс ' ;al
hi_msg db ' Скэн-код ' ;ah
scancod dw 0
.code
extrn outbyte :near
extrn initvideo :near
extrn clrscr :near
extrn outtextxy :near
extrn getcharfrombuf:near
start:
mov ax,@data
mov ds,ax
call initvideo c
call clrscr c
call outtextxy c,0,0,offset start_msg,64
cyckle:
call getcharfrombuf c
mov scancod,ax
call outtextxy c,0,1,offset lo_msg,24
mov ax,scancod
call outbyte c,ax
call outtextxy c,0,2,offset hi_msg,10
mov al,byte ptr scancod + 1
call outbyte c,ax
mov ax,scancod
cmp al,1Bh ; ASCII-код клавиши ESC
je quit
jmp cyckle
quit: mov ax,4c00h
int 21h
end start
Листинг 6. Определение состояния клавиатуры путем чтения регистров состояния клавиатуры 0000:0417 и 0000:0418.
masm
model small,c
.stack 100h
.data
status dw 0FFFFh
msg_on db ' Да '
msg_off db ' Нет'
cr EQU 13
lf EQU 10
table_msg db 'Состояние клавиатуры ( ESC выход)'
db cr,lf,' 0 Right Shift нажат'
db cr,lf,' 1 Left Shift нажат'
db cr,lf,' 2 Ctrl нажат'
db cr,lf,' 3 Alt нажат'
db cr,lf,' 4 Scroll Lock включен'
db cr,lf,' 5 Num Lock включен'
db cr,lf,' 6 Caps Lock включен'
db cr,lf,' 7 Insert включен'
db cr,lf,' 0 Left Ctrl нажат'
db cr,lf,' 1 Left Alt нажат'
db cr,lf,' 2 Right Ctrl нажат'
db cr,lf,' 3 Right Alt нажат'
db cr,lf,' 4 Scroll Lock нажат'
db cr,lf,' 5 Num Lock нажат'
db cr,lf,' 6 Caps Lock нажат'
db cr,lf,' 7 Insert нажат','$'
.code
extrn clearbuf :near
extrn initvideo :near
extrn clrscr :near
extrn outtextxy :near
extrn outstring :near
extrn getcharfromport :near
extrn getstatus :near
start:
mov ax,@data
mov ds,ax
call initvideo c
call clrscr c
call outstring c,offset table_msg
cyckle:
call getcharfromport c
cmp al,01h
je quit ;esc for quit
call clearbuf c
call getstatus c
cmp status,ax
je cyckle
mov status,ax
mov cx,16
bit_loop:
push cx
rol status,1
test status,0001h
jz zero
call outtextxy c,30,cx,offset msg_on,4
jmp next
zero:
call outtextxy c,30,cx,offset msg_off,4
next:
pop cx
loop bit_loop
jmp cyckle
quit:
call clearbuf c
call clrscr c
mov ax,4c00h
int 21h
end start
Листинг 7. Имитация работы клавиатуры путем непосредственного обращения к буферу клавиатуры.
masm
model small,c
.stack 100h
.data
start_msg db 'Имитация работы клавиатуры напрямую через буфер '
start_msg2 db 'Программа заносит в буфер клавиатуры команду dir '
char_d dw 2064h
char_i dw 1769h
char_r dw 1372h
char_enter dw 1C0Dh
.code
extrn initvideo :near
extrn clrscr :near
extrn outtextxy :near
extrn clearbuf :near
extrn putcharinbuf :near
start:
mov ax,@data
mov ds,ax
call initvideo c
call clrscr c
call clearbuf c
call outtextxy c,0,0,offset start_msg,50
call outtextxy c,0,1,offset start_msg2,50
call putcharinbuf c,char_d
call putcharinbuf c,char_i
call putcharinbuf c,char_r
; call putcharinbuf c,char_enter
mov ax,4c00h
int 21h
end start
Листинг 8.Управление временем задержки и частотой повтора имитации нажатой клавиши через BIOS.
masm
model small,c
.stack 100h
.data
param dw 0
start_msg db 'Настройка времени задержки и частоты повтора символов через BIOS'
cr equ 10
lf equ 13
tab equ 9
menu_msg_freq db cr,lf,cr,lf,tab,'Выберите частоту повторения :'
db cr,lf,tab,tab,'1 - 30,0 Гц'
db cr,lf,tab,tab,'2 - 26,7 Гц'
db cr,lf,tab,tab,'3 - 24,0 Гц'
db cr,lf,tab,tab,'4 - 20,0 Гц'
db cr,lf,tab,tab,'5 - 15,0 Гц'
db cr,lf,tab,tab,'6 - 10,0 Гц'
db cr,lf,tab,tab,'7 - 9,2 Гц'
db cr,lf,tab,tab,'8 - 7,5 Гц'
db cr,lf,tab,tab,'9 - 5,0 Гц'
db cr,lf,tab,tab,'0 - 2,0 Гц'
db cr,lf,tab,tab,'ESC выход $'
menu_msg_delay db cr,lf,cr,lf,tab,'Выберите время задержки :'
db cr,lf,tab,tab,'F1 - 250 мсек'
db cr,lf,tab,tab,'F2 - 500 мсек'
db cr,lf,tab,tab,'F3 - 750 мсек'
db cr,lf,tab,tab,'F4 - 1000 мсек'
db cr,lf,tab,tab,'ESC выход $'
.code
extrn clearbuf :near
extrn initvideo :near
extrn clrscr :near
extrn outtextxy :near
extrn outstring :near
extrn getcharfromport :near
extrn BIOSsetkbdparameters :near
start:
mov ax,@data
mov ds,ax
call initvideo c
call clrscr c
call outtextxy c,0,0,offset start_msg,64
call outstring c,offset menu_msg_freq
menu_loop1:
call getcharfromport c
call clearbuf c
cmp al,02 ;1
je fr1
cmp al,03 ;2
je fr2
cmp al,04 ;3
je fr3
cmp al,05 ;4
je fr4
cmp al,06 ;5
je fr5
cmp al,07 ;6
je fr6
cmp al,08 ;7
je fr7
cmp al,09 ;8
je fr8
cmp al,0Ah ;9
je fr9
cmp al,0Bh ;0
je fr0
cmp al,01h ;ESC - выход
jne menu_loop1
mov ax,4c00h
int 21h
fr1: mov param,00h
jmp menu2
fr2: mov param,01h
jmp menu2
fr3: mov param,02h
jmp menu2
fr4: mov param,04h
jmp menu2
fr5: mov param,08h
jmp menu2
fr6: mov param,0Ch
jmp menu2
fr7: mov param,0Dh
jmp menu2
fr8: mov param,10h
jmp menu2
fr9: mov param,14h
jmp menu2
fr0: mov param,1Fh
menu2: call outstring c,offset menu_msg_delay
menu_loop2:
call getcharfromport c
call clearbuf c
cmp al,3Bh ; F1
je execute
cmp al,3Ch ; F2
je d2
cmp al,3Dh ; F3
je d3
cmp al,3Eh ; F4
je d4
cmp al,01h ;ESC - выход
jne menu_loop2
mov ax,4c00h
int 21h
d2: add param,0100h
jmp execute
d3: add param,0200h
jmp execute
d4: add param,0300h
execute:
call BIOSsetkbdparameters c,param
mov ax,4c00h
int 21h
end start
Листинг 9.Получение расширенного скэн-кода клавиатуры через BIOS.
masm
model small,c
.stack 100h
.data
start_msg db 'Получение расширенных скэн-кодов через BIOS(ESC выход) '
lo_msg db ' ASCII-код или префикс ' ;al
hi_msg db ' Скэн-код ' ;ah
scancod dw 0
.code
extrn outbyte :near
extrn initvideo :near
extrn clrscr :near
extrn outtextxy :near
extrn BIOSgetchar :near
start:
mov ax,@data
mov ds,ax
call initvideo c
call clrscr c
call outtextxy c,0,0,offset start_msg,55
cyckle:
call BIOSgetchar c
mov scancod,ax
call outtextxy c,0,1,offset lo_msg,24
mov ax,scancod
call outbyte c,ax
call outtextxy c,0,2,offset hi_msg,10
mov al,byte ptr scancod + 1
call outbyte c,ax
mov ax,scancod
cmp al,1Bh ; ASCII-код клавиши ESC
je quit
jmp cyckle
quit: mov ax,4c00h
int 21h
end start
Листинг 10. Определение состояния клавиатуры через BIOS.
masm
model small,c
.stack 100h
.data
status dw 0FFFFh
msg_on db ' Да '
msg_off db ' Нет'
cr EQU 13
lf EQU 10
table_msg db 'Состояние клавиатуры, полученное через BIOS( ESC выход)'
db cr,lf,' 0 Right Shift нажат'
db cr,lf,' 1 Left Shift нажат'
db cr,lf,' 2 Ctrl нажат'
db cr,lf,' 3 Alt нажат'
db cr,lf,' 4 Scroll Lock включен'
db cr,lf,' 5 Num Lock включен'
db cr,lf,' 6 Caps Lock включен'
db cr,lf,' 7 Insert включен'
db cr,lf,' 0 Left Ctrl нажат'
db cr,lf,' 1 Left Alt нажат'
db cr,lf,' 2 Right Ctrl нажат'
db cr,lf,' 3 Right Alt нажат'
db cr,lf,' 4 Scroll Lock нажат'
db cr,lf,' 5 Num Lock нажат'
db cr,lf,' 6 Caps Lock нажат'
db cr,lf,' 7 SysRq нажат','$'
.code
extrn clearbuf :near
extrn initvideo :near
extrn clrscr :near
extrn outtextxy :near
extrn outstring :near
extrn getcharfromport :near
extrn BIOSgetstatus :near
start:
mov ax,@data
mov ds,ax
call initvideo c
call clrscr c
call outstring c,offset table_msg
cyckle:
call getcharfromport c
cmp al,01h
je quit ;esc for quit
call clearbuf c
call BIOSgetstatus c
cmp status,ax
je cyckle
mov status,ax
mov cx,16
bit_loop:
push cx
rol status,1
test status,0001h
jz zero
call outtextxy c,30,cx,offset msg_on,4
jmp next
zero: call outtextxy c,30,cx,offset msg_off,4
next: pop cx
loop bit_loop
jmp cyckle
quit: call clearbuf c
call clrscr c
mov ax,4c00h
int 21h
end start
Листинг 11. Имитация работы клавиатуры путем обращения к буферу клавиатуры через BIOS.
masm
model small,c
.stack 100h
.data
start_msg db 'Имитация работы клавиатуры напрямую через буфер '
start_msg2 db 'Программа заносит в буфер клавиатуры команду dir '
char_d dw 2064h
char_i dw 1769h
char_r dw 1372h
char_enter dw 1C0Dh
.code
extrn initvideo :near
extrn clrscr :near
extrn outtextxy :near
extrn clearbuf :near
extrn BIOSputcharinbuf:near
start:
mov ax,@data
mov ds,ax
call initvideo c
call clrscr c
call clearbuf c
call outtextxy c,0,0,offset start_msg,50
call outtextxy c,0,1,offset start_msg2,50
call BIOSputcharinbuf c,char_d
call BIOSputcharinbuf c,char_i
call BIOSputcharinbuf c,char_r
; call BIOSputcharinbuf c,char_enter
mov ax,4c00h
int 21h
end start