delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/12/18/08:36:32

From: "Anthony.Appleyard" <MCLSSAA2 AT fs2 DOT mt DOT umist DOT ac DOT uk>
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>

  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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019