code segment byte public assume cs:code public SetKeyVector,RestoreKeyVector,Ext_Keyboard_Present ;_______________________________________________________________ SetKeyVector proc far ; Install new interrupt vector ;First get old INT 16h vector mov ah,35h ; get interrupt vector into ES:BX mov al,16h ; vector to get int 21h ; DOS call ; now store the old vector mov ax,es ; vector segment mov cs:vectseg,ax ; store it mov cs:vectofs,bx ; store vector offset ; get address of the new interrupt handler and set the INT 16h vector push ds ; save data segment mov ax,cs mov ds,ax ; set current segment mov dx,offset newkey mov ah,25h ; set interrupt vector mov al,16h ; vector to set int 21h pop ds ; Temporary storage for old interrupt vector in the code segment vectofs dw 0 vectseg dw 0 ; First check the function number to see if its one of the ones we want ; to operate on i.e. functions 0, 1 and 2. The function no is in AH. If ; not we pass control to the old INT 16h vector. newkey: push ds ; store data segment push ax ; keep function params sti ; restart interrupts cmp ah,03h ; check function jae oldvect ; if ah>=3 then call the old vector ; Function must be one of 0, 1 or 2 so we use the new routine below. First ; test for enhanced keyboard by checking the flag in the BIOS data area. mov ax,0040h ; BIOS data segment mov ds,ax mov al,byte ptr ds:[0096h] ; get keyboard state flags and al,10h ; must be old keyboard so transfer jz oldvect ; control to old routine ; If we get here the machine has probably got an enhanced keyboard ; so add 10h to the BIOS function number and call the old vector newcall: pop ax ; get old function no add ah,10h ; modify function no cmp ah,12h ; function 12h ? je ovect2 ; use enhanced function ; At this point the function must have been 0 or 1 so start by calling ; the old INT 16h routine with the modified function no. We simulate an ; INT intstruction a long call to the original vector. cli pushf ; simulate interrupt call dword ptr cs:[vectofs] ; do INT 16h ! ; Set up a stack frame using BP so we can access the flags that were pushed ; on to the stack by the calling INT instruction. push bp ; save base pointer mov bp,sp ; set up stack frame push ax ; save AX temporarily pushf ; save result flags pop ax ; get flags into AX mov word ptr [bp+8],ax ; replace stacked interrupt flags pop ax ; restore AX pop bp ; restore base pointer ; If the extended function returns the value 244 decimal in AL then a special ; function key has been pressed (like PgUp etc) so we must modify this result ; appropriately by returning zero in AL if neccessary. cmp al,224 ; special key ? jne exit ; no so quit cmp ah,0 ; fix for special keys je exit mov al,0 exit: pop ds ; restore from stack sti ; restart interrupts iret ; end of interrupt oldvect: pop ax ; pop function number ovect2: cli ; disable interrupts pop ds ; restore data segment jmp dword ptr cs:[vectofs] ; jump to old vector SetKeyVector endp ;_____________________________________________________________________________ RestoreKeyVector proc far ; procedure to restore original interrupt vector push ds mov ax,seg SetKeyVector mov ds,ax mov dx,vectofs mov ax,vectseg ; get old vector mov ds,ax mov ah,25h ; set interrupt vector mov al,16h ; interrupt number int 21h ; DOS call pop ds ret RestoreKeyVector endp ;______________________________________________________________________________ Ext_Keyboard_Present proc far ; Returns boolean flag to indicate presence on enhanced keyboard. If Al=0 ; on return then the enhanced keyboard is not present. If Al=1, it is. push es mov ax,0040h ; BIOS data segment mov es,ax mov al,byte ptr es:[0096h] ; get keyboard state flags pop es and al,10h ; mask enhanced flag jz fin ; must be old keyboard mov al,1 fin: ret Ext_Keyboard_Present endp code ends end