1. как написать прерывание, которое по нажатию комбинации двух клавиш (например Ctrl+printScr или Alt+PrintScr) выдавало бы например ткстовое сообщение ?? (в досе)
2. какой код у клавиши PrintScr ???
3. как сдлать енто прерывние резидентным ??
BlackShadow
19.05.2004 0:20
Потешно ты выразился 1). Сделать тебе надо вот что: перехватить прерывание 09h, и там читать скан-коды из порта клавы. В нужный момент (когда нажали то, чего ты хотел) выводить своё сообщение.Только советую тут видеорежим проверять. 2). Код клавиши PrintScr не помню. 3). Пишешь обычный TSR, в которм и проворачиваешь п. 1
kile
19.05.2004 10:00
черная тень, ты выразился не менее потешно =))) ;) нельзя ли поподробней....
BlackShadow
19.05.2004 10:49
1). Прерывание 09h возникает при нажатии на клавишу. Чтобы его перехватить и среагировать раньше, чем обычный обработчик нужно его вектор настроить на свою функцию (см. в АЗЫ). Для этого можно воспользоватьяс INT 21h, а можно просто изменить указатель по адресу 0000:09h*4 = 00024h на адрес своей функции (только предыдущий адрес сохранить не забудь). Функция твоя должна считывать скан-код клавиши из порта клавиатуры, сравнивать с кодом PrintScr и, если не то, то вызывать старый обработчик, иначе творить что тебе там надо. Только не забывай регистры сохранять! Делается это примерно так:
PUSH AX
IN AL,60h
CMP AL,PRINT_SCR_CODE
JE Handle
POP AXJMP [FARPTRCS:OLD_VECTOR]
Handle:
IN AL,61h
MOV AH,AL
OR AL,80h
OUT 61h,AL
MOV AL,AH
OUT 61h,AL
DELAY_CHEGO_TO_TAM:
VIHOD:
MOV AL,20h
OUT 20h,ALIRET
Ну, или что-то похожее. 2). Код PrintScr - 37h 3). Чтобы сделать резидентной свою программу, нужно в AL занести код выхода, в AH 31h, в DX - адрес первого ненужного байта в твоей программе и вызвать INT 21h. DOS выгрузит всё, что начинается с CS:DX, а остальное оставит и пометит эту память, как зарезервированную. Так что TSR'ы лучше писать как COM'ики, а обработчики прерываний размещать в самом начале, тогда всё остальное можно будет выгрузить безболезненно.
kile
23.05.2004 0:52
знакомо ли вам состояние, когда 4 часа пишешь программу, а она не работает ???? ... почему мое долбаное прерывние не работает ?? мне надо по нажатию Shift+PrinScreen вывести звуковой сигнал (или тектовое сообещние).
пользователь запускает программу, после чего комп ждет нажатия шифт+принтскрин. когда нужная комбинация нажата, программа завершается.
резидентой делать не надо.
DATSEG SEGMENT
EndLine EQU'$'
KEEP_CS DW 0 ; segment
KEEP_IP DW 0 ; offsetя
line1 DB'LAB WORK ь5.', 0AH, 0DH, Endline
line2 DB'PRESS Shift+PrintScreen TO RUN INTERRUPT.', 0AH, 0DH, Endline
line3 DB'PROGRAM WILL DO SOUND SIGNAL.', 0AH, 0DH, Endline;
line4 DB'done', 0AH, 0DH, Endline;
line5 DB'end of program', 0AH, 0DH, Endline;
flag DW 0
;top_of_st LABEL WORD
DATSEG ENDS;-----------------------------------------------
STKSEG SEGMENTSTACKDW 4096 DUP ('?')
STKSEG ENDS;-----------------------------------------------
LAB5 SEGMENTPARAPUBLICASSUMECS : lab5, DS : DATSEG, ES : NOTHING, SS : STKSEG
ORG 100H
start: ; MOV SP, OFFSET top_of_st
MOV AX, DATSEG
MOV DS, AXJMP Begin
;-----------------------------------------------
WriteStr PROCNEAR
XOR AX, AX
MOV AH, 09H
INT 21H
RET
WriteStr ENDP;-----------------------------------------------
SUB_INT PROCFAR
PUSH AX
PUSH DX
PUSH DS
MOV AH, 02H
MOV DL, 07H
INT 21H
я
;mov dx,OFFSET line4 ;line5
; push ds
; mov ax, seg line4 ;line5
; mov ds,ax
; call writeStr
; pop ds
;mov cx,60000
;@l2: nop
; push cx
; mov cx,50000
;@l1: nop
; loop @l1
; pop cx
; loop @l2
; push ds
; mov ax, seg flag
; mov ds,ax
; mov dx,offset flag
mov flag, 0000h
; pop ds
POP DS
POP DX
POP AX
MOV AL, 20H
OUT 20H, ALIRET
SUB_INT ENDP
BEGIN :
MOV flag, 1
MOV DX, OFFSET line1
CALL WriteStr
MOV AH, 35H ; function of getting vector
MOV AL, 05H ; number of vector
INT 21H
MOV KEEP_IP, BX; remember offset я
MOV KEEP_CS, ES; remember segment
MOV DX, OFFSET line2
CALL WriteStr
;------------------- SET THE INTERRUPT ---------
PUSH DS
MOV DX, OFFSET SUB_INT
MOV AX, SEG SUB_INT я
MOV DS, AX
MOV AH, 25H
MOV AL, 05H
INT 21H
MOV AL, 20H ; ???????????
OUT 20H, AL; ???????????
POP DS;-----------------------------------------------
;жЁЄ«, Ё§ Є(r)в(r)а(r)Ј(r) ¬(r)¦(r) ўл(c)вЁ в(r)«мЄ(r) ¦ вЁҐ¬ Є« ўЁиЁ ESC
;LOO1:
;MOV AH,06H
;MOV DL,0FFH
;INT 21H
;JZ LOO1
;CMP AL, 27
;JNZ LOO1
@lo2: mov cx,200
mov bx,flag
cmp bx,0
jz @fin
jmp @lo2
@fin: mov dx,OFFSET line3
call writeStr
;------------------- RESTORE ORIGINAL VECTOR ---
CLI
PUSH DS
MOV DX, KEEP_IP
MOV AX, KEEP_CS
MOV DS, AX
MOV AH, 25H
MOV AL, 05H
INT 21H
MOV AL, 20H ; ???????
OUT 20H, AL; ???????
POP DS
STI
;-----------------------------------------------
;mov dx,OFFSET line4
;call writeStr
;xor ax,ax
MOV AX, 4C00H
INT 21H
MOV AL, 20H ; ??????
OUT 20H, AL; ??????
lab5 ENDSENDstart
kile
23.05.2004 0:53
подскажите пожалуста, а то нервных клеток в моем теле к понедельнику не останется =((((((((
BlackShadow
23.05.2004 12:25
Цитата
MOV AL, 20H ; ??????????? OUT 20H, AL ; ???????????
Я вот тоже этого не понял. Какое это ты тут аппаратное прерывание завершаешь?
Цитата
@lo2: mov cx,200
А это к чему?
Цитата
MOV AX, 4C00H INT 21H ----------- Тут выполнение заканчивается. Вообще.
MOV AL, 20H ; ?????? ----------- До этого бреда дело уже не доходит. OUT 20H, AL ; ??????
А тут твоя основная ошибка:
Цитата
mov flag, 0000h
Эта команда интерпретируется как "MOD [DS:flag],0", не грех кстати размер указать, а вот DS к этому моменту может оказаться иным. И не аппаратное прерывание 05h - не надо его завершать таким образом. Или ты просто решил наторкать эти строки повсеместно, так на всякий случай???
И ещё 1 вопрос: ты уверен, что INT 05h вызывается из INT 09h при нажатии на Shift+PrtSc? Я попробывал - у меня не получилось....
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.