From: "Anthony.Appleyard" Organization: Materials Science Centre To: djgpp AT delorie DOT com Date: Thu, 18 Dec 1997 11:55:54 GMT Subject: assembler; reading keyboard events by hooking int09 Reply-to: Anthony DOT Appleyard AT umist DOT ac DOT uk Message-ID: <4B8C71522A@fs2.mt.umist.ac.uk> Precedence: bulk I have written and tested a program in Assembler (hereinunder) which sets up a TSR which does this:- (1) Hooks the system interrupt 9 so it also records the keyboard events in a 255-byte buffer called KEYEVENT. If the key-event buffer was full, the latest entry in it is replaced by 0xff. It does not stop the ordinary keyboard buffer from getting full : the user should keep the keyboard buffer emptied himself. (2) Hooks the user interrupt 0xFD so that it does this:- AX = 0x9900 : read from the key-event buffer one keyboard event and return it in AL. Carry is clear. Prefix-code combinations are sent on as two events as they are and are not decoded. Note two special return codes:- AL==0xff : here the key-event buffer got full, see above. AL==0x00 and carry set : the key-event buffer was empty. AX = 0x9901 : empty the key-event buffer. AX = any other 0x99** value: do nothing. ------------------------------------------------------------------ Query: When a TSR is set up, it seems that the installer program's PSP remains as 256 dead bytes taking up space below the TSR. Would any disaster happen if the interrupt handler in the TSR used this dead PSP as working space? How would the DOS instruction MEM react if such an old embedded PSP was corrupted? ================================================================== CODE SEGMENT ASSUME CS:CODE JMP INSTALL KEYEVENT DB 256 DUP 0 ; circular buffer, can be empty, can't be completely full INPTR DB 0 OUTPTR DB 0 SIGNATUR DW 0BEEF HOOK09 LABEL BYTE ; new int09 handler code PUSHF ; needed to match the implicit extra POPF in IRET DB 09A ; code for FAR CALL :: call the old int09 handler OFF09 DW 0 ; for offset & seg of ind int09 handler SEG09 DW 0 PUSH AX PUSH BX PUSH DS DB 0B8 ; MOV AX,number SETDS09 DW 0 MOV DS,AX CLI ; disable interrupts IN AL,060 ; get key scan code MOV BL,INPTR ; buffer input pointer MOV BH,0 MOV KEYEVENT[BX],AL ; put key event in buffer MOV AH,BL ; save old BL INC BX ; +=1 MOV BH,0 ; BX&=255 CMP BL,OUTPTR ; if inptr has not hit outptr, OK JNE INOK MOV BL,AH ; that would make buffer full, so restore old BL MOV KEYEVENT[BX],0AB ; & replace previous key value by 0xff JMP INEND INOK: MOV INPTR,BL ; update pointer INEND: POP DS POP BX POP AX IRET HOOKFD PROC FAR ; new intFD handler code CMP AH,099 JE MYFD ; if AH==0x99, call my intFD handler DB 0EA ; code for JMP FAR OFFFD DW 0 ; for offset & seg of ind intFD handler SEGFD DW 0 MYFD: PUSH DS ; if AH==0x99, call my intFD handler DB 0BB ; MOV AX,number ; set DS as the installer was compiled for SETDSFD DW 0 MOV DS,BX CMP AL,0 ; if AL==0, read a key event JE GETEVENT CMP AL,1 ; if AL==1, empty the key event buffer JE EMPTYBUF WHOA: POP DS IRET EMPTYBUF: MOV BL,0 MOV INPTR,BL MOV OUTPTR,BL JMP WHOA GETEVENT: MOV BL,OUTPTR ; buffer output pointer CMP BL,INPTR JE EMPTY CLC ; clear carry MOV BH,0 MOV AL,KEYEVENT[BX] INC BX ; +=1 MOV OUTPTR,BL JMP WHOA EMPTY: STC ; carry set = nothing in buffer MOV AL,0 JMP WHOA ALREADY DB,10,13,"program AAKEYS already in memory",13,10,'$' NOWINST DB,10,13,"program AAKEYS installed",13,10,'$' INSTALL: MOV AX,03509 ; ES:BX := current vector INT 09h INT 021 MOV AX,[ES:BX-2] CMP AX,SIGNATUR JE ALREDDY MOV CS:OFF09,BX MOV CS:SEG09,ES MOV CS:SETDS09,DS ; set instr to set DS MOV AX,CS ; change int09 vector MOV DS,AX MOV DX,OFFSET HOOK09 MOV AX,02509 INT 021 MOV AX,035FD ; ES:BX := current vector INT FDh INT 021 MOV CS:OFFFD,BX MOV CS:SEGFD,ES MOV CS:SETDSFD,DS ; set instr to set DS MOV AX,CS ; change intFD vector MOV DS,AX MOV DX,OFFSET HOOKFD MOV AX,025FD INT 021 LEA DX,NOWINST ; print remark MOV AH,9 INT 021 LEA DX,ALREADY ; install TSR ADD DX,15 MOV CX,4 SHR DX,CL ADD DX,16 MOV AX,03100 PUSH CS POP DS INT 021 ALREDDY: ; PUSH CS ; POP DS LEA DX,ALREADY MOV AH,9 INT 021 MOV AX,04C00 INT 021 END INSTALL