[Back to KEYBOARD SWAG index] [Back to Main SWAG index] [Original]
UNIT MultiKey;
INTERFACE
VAR
KeyStat : Array[1..127] OF ShortInt;
{ 0 (not physically down)
1 (that sucker's down)
-1 (it's being held, don't repeat) }
PROCEDURE EnableMultiKey;
PROCEDURE DisableMultiKey;
IMPLEMENTATION
USES Dos;
VAR
OldKbdInt : Pointer;
OldCtrlBreakInt : Pointer;
OldKeyExitProc : Pointer;
PROCEDURE ClearKeyValues;
VAR
keyclearcounter : Byte;
BEGIN
FOR keyclearcounter := 1 TO 127 DO KeyStat[keyclearcounter] := 0;
END;
PROCEDURE NewKeyExitProc; Far;
BEGIN
SetIntVec($09, OldKbdInt);
SetIntVec($1B, OldCtrlBreakInt);
ExitProc := OldKeyExitProc;
END;
PROCEDURE NewCtrlBreakInt; Interrupt;
{ it is important that the new Ctrl-Break handler does *nothing* }
BEGIN
END;
PROCEDURE NewKbdInt; Interrupt;
VAR
p60 : Byte;
BEGIN
p60 := Port[$60];
Port[$61] := Port[$61] OR 128; {/ keyboard \}
Port[$61] := Port[$61] AND (NOT 128); {\ acknowledge /}
IF (p60 > 0) THEN BEGIN
IF (p60 > 127) THEN
KeyStat[p60 AND 127] := 0
ELSE
IF (KeyStat[p60] = 0) THEN Inc(KeyStat[p60]);
END;
ASM CLI; END; {disable hardware ints}
MemW[$0040:$001A] := MemW[$0040:$001C]; {clear buffer}
ASM STI; END; {restore hardware ints}
Port[$20] := $20; { send EOI to PIC }
END;
PROCEDURE EnableMultiKey;
BEGIN
SetIntVec($09, Addr(NewKbdInt));
END;
PROCEDURE DisableMultiKey;
BEGIN
SetIntVec($09, OldKbdInt);
END;
BEGIN { unit initialization }
GetIntVec($1B, OldCtrlBreakInt);
SetIntVec($1B, Addr(NewCtrlBreakInt));
ClearKeyValues;
OldKeyExitProc := ExitProc;
ExitProc := Addr(NewKeyExitProc);
GetIntVec($09, OldKbdInt);
EnableMultiKey;
END.
[Back to KEYBOARD SWAG index] [Back to Main SWAG index] [Original]