[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]