home *** CD-ROM | disk | FTP | other *** search
- PROGRAM Shift_Key_Pressed;
- uses crt, dos;
- {=============}
- {BEGIN INCLUDE}
- {=============}
- VAR
- Kbd_Vec, Exit_Vec : pointer;
- CONST
- Kbd_Int = 9;
-
- {$I ERROR.INC}
-
- PROCEDURE CLI; INLINE($FA); {INLINE procedures are NICE!}
- PROCEDURE STI; INLINE($FB);
-
- CONST
- (* Scan codes for seven shift keys *)
- SC_LeftShift = 42;
- SC_RightShift = 54;
- SC_CtrlShift = 29;
- SC_AltShift = 56;
- SC_NumLock = 69;
- SC_ScrollLock = 70;
- SC_CapsLock = 58;
- SKP : Boolean = False;{ShiftKeyPressed flag}
- which : Byte = 0;
-
- PROCEDURE INT9_ISR(_Flags, _CS, _IP, _AX, _BX, _CX, _DX,
- _SI, _DI, _DS, _ES, _BP:word);
- INTERRUPT;
- BEGIN
- INLINE(
- $9C/ {PUSHF}
- $E4/$60/ {IN AL,$60 ;read keyboard port}
- $3C/<SC_CAPSLOCK/ {CMP AL,<SC_CAPSLOCK}
- $74/$1F/ {JZ Was_Pressed}
- $3C/<SC_LEFTSHIFT/ {CMP AL,<SC_LEFTSHIFT}
- $74/$1B/ {JZ Was_Pressed}
- $3C/<SC_RIGHTSHIFT/ {CMP AL,<SC_RIGHTSHIFT}
- $74/$17/ {JZ Was_Pressed}
- $3C/<SC_CTRLSHIFT/ {CMP AL,<SC_CTRLSHIFT}
- $74/$13/ {JZ Was_Pressed}
- $3C/<SC_ALTSHIFT/ {CMP AL,<SC_ALTSHIFT}
- $74/$0F/ {JZ Was_Pressed}
- $3C/<SC_NUMLOCK/ {CMP AL,<SC_NUMLOCK}
- $74/$0B/ {JZ Was_Pressed}
- $3C/<SC_SCROLLLOCK/ {CMP AL,<SC_SCROLLLOCK}
- $74/$07/ {JZ Was_Pressed}
- (* ================================================= *)
- (* IF you didn't jump by now, it wasn't a shift key *)
- (* ================================================= *)
- $C6/$06/>SKP/$00/ {MOV BYTE PTR [>SKP],+$00 ;set SKP FALSE}
- $EB/$08/ {JMP SHORT To_Normal}
- {Was_Pressed:}
- $C6/$06/>SKP/$01/ {MOV BYTE PTR [>SKP],+$01 ;set SKP TRUE}
- $A2/>WHICH/ {MOV [>WHICH],AL ;remember WHICH key}
- {To_Normal:}
- (* ============================ *)
- (* CHAIN to the regular INT 9 *)
- (* ============================ *)
- $9D/ {POPF ;Restore the flags}
- $A1/>KBD_VEC+2/ {MOV AX,[>KBD_VEC+2] ;Old vector seg to AX}
- $8B/$1E/>KBD_VEC/ {MOV BX,[>KBD_VEC] ;Old vector ofs to BX}
- $87/$5E/$0E/ {XCHG BX,[BP+$0E] ;Swap ofs w/ return address}
- $87/$46/$10/ {XCHG AX,[BP+$10] ;Swap seg w/ return address}
- $89/$EC/ {MOV SP,BP ;UNDO procedure's entry code}
- $5D/ {POP BP}
- $07/ {POP ES}
- $1F/ {POP DS}
- $5F/ {POP DI}
- $5E/ {POP SI}
- $5A/ {POP DX}
- $59/ {POP CX}
- $CB); {RETF ;in effect, JMP to old vector}
- END;
-
- FUNCTION ShiftKeyPressed : Boolean;
- (* ======================================= *)
- (* Returns the value of flag variable SKP, *)
- (* and resets it to FALSE *)
- (* ======================================= *)
- BEGIN
- CLI; {Don't want it changing DURING this!}
- ShiftKeyPressed := SKP;
- SKP := false;
- STI; {OK, can change now}
- END;
-
- FUNCTION Read_SKP : Byte;
- (* ================================== *)
- (* Returns the value of flag variable *)
- (* "WHICH", and resets it to 0 *)
- (* ================================== *)
- BEGIN
- CLI; {Don't want it changing DURING this!}
- Read_SKP := which;
- which := 0;
- STI; {OK, can change now}
- END;
-
- {=============}
- {END INCLUDE }
- {=============}
-
- PROCEDURE Do_Demo;
- VAR
- CH : Char;
- BEGIN
- ClrScr;
- WriteLn(' KEYBOARD INTERRUPT DEMO "Shift Keys"');
- WriteLn(' ====================================');
- WriteLn;
- Write(' Press the various shift keys on the ');
- WriteLn('keyboard. The normal "KeyPressed"');
- Write(' function doesn''t notice these keys. ');
- WriteLn('But the new "ShiftKeyPressed"');
- WriteLn(' notices! Hit <Ctrl><Break> to quit.');
- REPEAT
- REPEAT UNTIL KeyPressed OR ShiftKeyPressed;
- WHILE KeyPressed DO CH := ReadKey;
- CASE Read_SKP OF
- SC_LeftShift : WriteLn('Left Shift');
- SC_RightShift : WriteLn('Right Shift');
- SC_CtrlShift : WriteLn('Control Shift');
- SC_AltShift : WriteLn('Alt Shift');
- SC_NumLock : WriteLn('Num Lock');
- SC_ScrollLock : WriteLn('Scroll Lock');
- SC_CapsLock : WriteLn('Caps Lock');
- END;
- UNTIL FALSE;
- END;
-
- BEGIN
- CheckBreak := TRUE;
- GetIntVec(Kbd_Int, Kbd_Vec); {save "old" INT9}
- SetIntVec(Kbd_Int, @INT9_ISR); {install new}
- Exit_Vec := ExitProc; {save old ExitProc}
- ExitProc := @My_Error; {install new}
- Do_Demo; {show yer stuff!}
- {Old interrupt is restored by ExitProc}
- END.