.model large .data PUBLIC _keys _keys db 256 dup(0) oldint9 dd 0 e0flag db 0 kSYSREQ EQU 054h kCAPSLOCK EQU 03Ah kNUMLOCK EQU 045h kSCROLLLOCK EQU 046h kLEFTCTRL EQU 01Dh kLEFTALT EQU 038h kLEFTSHIFT EQU 02Ah kRIGHTCTRL EQU 09Dh kRIGHTALT EQU 0B8h kRIGHTSHIFT EQU 036h kESC EQU 001h kBACKSPACE EQU 00Eh kENTER EQU 01Ch kSPACE EQU 039h kTAB EQU 00Fh kF1 EQU 03Bh kF2 EQU 03Ch kF3 EQU 03Dh kF4 EQU 03Eh kF5 EQU 03Fh kF6 EQU 040h kF7 EQU 041h kF8 EQU 042h kF9 EQU 043h kF10 EQU 044h kF11 EQU 057h kF12 EQU 058h kA EQU 01Eh kB EQU 030h kC EQU 02Eh kD EQU 020h kE EQU 012h kF EQU 021h kG EQU 022h kH EQU 023h kI EQU 017h kJ EQU 024h kK EQU 025h kL EQU 026h kM EQU 032h kN EQU 031h kO EQU 018h kP EQU 019h kQ EQU 010h kR EQU 013h kS EQU 01Fh kT EQU 014h kU EQU 016h kV EQU 02Fh kW EQU 011h kX EQU 02Dh kY EQU 015h kZ EQU 02Ch k1 EQU 002h k2 EQU 003h k3 EQU 004h k4 EQU 005h k5 EQU 006h k6 EQU 007h k7 EQU 008h k8 EQU 009h k9 EQU 00Ah k0 EQU 00Bh kMINUS EQU 00Ch kEQUAL EQU 00Dh kLBRACKET EQU 01Ah kRBRACKET EQU 01Bh kSEMICOLON EQU 027h kTICK EQU 028h kAPOSTROPHE EQU 029h kBACKSLASH EQU 02Bh kCOMMA EQU 033h kPERIOD EQU 034h kSLASH EQU 035h kINS EQU 0D2h kDEL EQU 0D3h kHOME EQU 0C7h kEND EQU 0CFh kPGUP EQU 0C9h kPGDN EQU 0D1h kLARROW EQU 0CBh kRARROW EQU 0CDh kUARROW EQU 0C8h kDARROW EQU 0D0h kKEYPAD0 EQU 052h kKEYPAD1 EQU 04Fh kKEYPAD2 EQU 050h kKEYPAD3 EQU 051h kKEYPAD4 EQU 04Bh kKEYPAD5 EQU 04Ch kKEYPAD6 EQU 04Dh kKEYPAD7 EQU 047h kKEYPAD8 EQU 048h kKEYPAD9 EQU 049h kKEYPADDEL EQU 053h kKEYPADSTAR EQU 037h kKEYPADMINUS EQU 04Ah kKEYPADPLUS EQU 04Eh kKEYPADENTER EQU 09Ch kCTRLPRTSC EQU 0B7h kSHIFTPRTSC EQU 0B7h kKEYPADSLASH EQU 0B5h .code PUBLIC _Set_New_Int9 _Set_New_Int9 PROC FAR push ds cli mov ax,3509h ; get old INT 9 int 21h mov si,offset oldint9 mov [si],bx ; save offset mov [si + 2],es ; save segment mov ax,2509h ; set new INT 9 mov dx,seg _New_Int9 mov ds,dx mov dx,offset _New_Int9 int 21h sti pop ds ret _Set_New_Int9 ENDP PUBLIC _Set_Old_Int9 _Set_Old_Int9 PROC FAR push ds cli mov ax,2509h ; set new INT 9 mov si,offset oldint9 mov dx,word ptr [si] ; load offset mov ds,word ptr [si + 2] ; load segment int 21h sti pop ds ret _Set_Old_Int9 ENDP _New_Int9 PROC FAR cli push ds push ax push bx mov ax,@data mov ds,ax in al,60h ; Get scan code in AL cmp al,0E0h ; was it an E0 key? jne setscancode ; E0 key routine mov [e0flag],128 mov al,20h ; Send generic EOI to PIC out 20h,al ; 001 00 000 ; | | | ; | | +--- INT request level ; | +------ OCW2 ; +---------- non-specific EOI command pop bx pop ax pop ds sti iret setscancode: mov bl,al ; Save scan code in BL and bl,01111111b add bl,[e0flag] xor bh,bh ; clear for index use and al,10000000b ; keep break bit, if set xor al,10000000b ; flip bit - 1 means pressed ; - 0 means released rol al,1 ; put it in bit 0 mov [_keys + bx],al ; set index for key mov [e0flag],0 mov al,20h ; Send generic EOI to PIC out 20h,al ; 001 00 000 ; | | | ; | | +--- INT request level ; | +------ OCW2 ; +---------- non-specific EOI command pop bx pop ax pop ds sti iret _New_Int9 ENDP END