[Back to KEYBOARD SWAG index] [Back to Main SWAG index] [Original]
  {========================================================================}
  {                                                                        }
  { If you find these procedures/functions useful, please help support the }
  { SHAREWARE system by sending a small donation ( up to $5 ) to help with }
  { my college education. Reguardless of a donation, use these routines in }
  { good health (and with a clear concious), I hope you find them useful.  }
  {                                                                        }
  {                                                                        }
  { Send Any Replies To:  EUROPA Software                                  }
  {                       314 Pleasant Meadows Dr.                         }
  {                       Gaffney, SC 29340                                }
  {                                                                        }
  { Program: KB_v02                                Last Revised: 11/21/89  }
  {                                                                        }
  { Author: J.E. Clary                                                     }
  {                                                                        }
  { Using ALL of these routines increases the .EXE by only 336 bytes.      }
  {                                                                        }
  { Implementation: Turbo Pascal v.4.0 & v.5.0                             }
  {                                                                        }
  { Purpose:                                                               }
  {                                                                        }
  { This UNIT is to provide direct access to the Keyboard status byte.     }
  { It is intended to use while running under MS-DOS. The unit will not    }
  { function properly, if at all, when running under OS/2. This is because }
  { low-memory access is denied under OS/2 to protect the Operating System.}
  { If you need these functions under OS/2 they are easily accesible by    }
  { calling OS Interrupt 9, which returns status bytes 40:17h and 40:18h   }
  { 'leagally'. The UNIT is written to carry as little excess baggage as   }
  { possible ( only 16 bytes in constants and work variables ) and execute }
  { as fast as possible. This is achieved by directly addressing the key-  }
  { board status byte instead of calling the Operating System.             }
  {                                                                        }
  {=========================   DISCALIMER   ===============================}
  {                                                                        }
  {                                                                        }
  {   These routines are provided AS IS. EUROPA Software, nor any of its   }
  {   employees shall be held liable for any incidental or consequential   }
  {   damage attributed to the use, or inability to use this product.      }
  {                                                                        }
  {                                                                        }
  {========================================================================}
unit KB_v02;
   INTERFACE
   const   Right_Shift     = 0;    { Key_To_Check Constants  }
           Left_Shift      = 1;
           Control_Key     = 2;
           Alt_key         = 3;
           Scroll_Lock_Key = 4;    { Key_To_Set Constants    }
           Number_Lock_Key = 5;
           Caps_Lock_Key   = 6;
           State_Off       = 0;    {  Action Constants       }
           State_On        = 1;
           State_Toggle    = 2;
   function Is_Key_Pressed( Key_To_Check  :  byte )  :  boolean;
   procedure Set_Keyboard_State( Key_To_Set, Action  :  byte );
   procedure Save_Keyboard_Status;
   procedure Restore_Keyboard_Status;
   procedure Clear_Type_Ahead_Buffer;
   IMPLEMENTATION
   var Hold_Keyboard_Status, Or_Mask, And_Mask  :  byte;
       kb_stat   :  byte absolute $0:$417;  { Keyboard Status Byte }
       tail_buf  :  byte absolute $0:$41C;  { Tail of Circular KB Buffer }
       head_buf  :  byte absolute $0:$41A;  { Head of Circular KB Buffer }
   procedure Clear_Type_Ahead_Buffer;
      begin
         tail_buf := head_buf;
      end;
   procedure Save_Keyboard_Status;
      begin
         Hold_Keyboard_Status := kb_stat;
      end;
   procedure Restore_Keyboard_Status;
      begin
         kb_stat := Hold_Keyboard_Status;
      end;
   function Is_Key_Pressed( Key_To_Check  :  byte )  :  boolean;
      begin
         Or_Mask := (1 SHL Key_To_Check);
         Is_Key_Pressed := ((kb_stat AND Or_Mask) = Or_Mask);
      end;
   procedure Set_Keyboard_State(  Key_to_Set, Action  :  byte );
      begin
         Or_Mask  := 1 SHL Key_To_Set;
         And_Mask := (NOT Or_Mask);
         case Action of
              0: kb_stat := kb_stat AND And_Mask;          {  Off   }
              1: kb_stat := kb_stat OR   Or_Mask;          {  On    }
              2: if ( kb_stat AND Or_Mask) = Or_Mask then  { Toggle }
                      kb_stat := (kb_stat AND And_Mask)
                 else kb_stat := (kb_stat  OR  Or_Mask);
             end;
      end;
   begin  { UNIT Initialization Code }
      Hold_Keyboard_Status := 0;
   end.
{ --------------------------  DEMO ----------------------------}
program test_KB;
   { Demonstates the use of the KB_v02 Unit. }
   uses crt, KB_v02;
   const on       = 'Key is Pressed   ';
         off      = 'Key isn''t Pressed';
         EveryMsg = 'Any Key to Force ';
         MidMsg   = ' Lock Key to ';
         lock_keys   :  array[1..3] of byte =
                        ( Number_Lock_Key, Caps_Lock_Key, Scroll_Lock_Key );
         key_states  :  array[1..3] of byte =
                       ( State_On, State_Off, State_Toggle );
         key_names    :  array[1..3] of string = ('Number','Caps','Scroll');
         state_names  :  array[1..3] of string = ('On','Off','Toggle');
   var i,j  :  byte;
   procedure BurnKey;
      var ch  :  char;
      begin
         ch := readkey;
         if ch = #0 then ch := readkey;
      end;
   procedure writeAT( x,y  :  byte;  st  :  string );
      begin
         gotoxy( x,y );
         write( st );
      end;
   begin
      clrscr;
      writeln( 'DEMO of Is_Keypressed Function' );
      writeln;
      writeln( ' Any Normal Key to continue ' );
      writeAT( 10, 10, 'Alt Key Status'  );
      writeAT( 10, 12, 'CTRL Key Status' );
      writeAT( 10, 14, 'Left Shift Status' );
      writeAT( 10, 16, 'Right Shift Status' );
      repeat
          if Is_Key_Pressed( Alt_Key ) then writeAT( 30,10, on )
          else writeAT( 30,10, off );
          if Is_Key_Pressed( Control_Key ) then writeAT( 30,12, on )
          else writeAT( 30,12, off );
          if Is_Key_Pressed( Left_Shift ) then writeAT( 30,14, on )
          else writeAT( 30,14, off );
          if Is_Key_Pressed( Right_Shift ) then writeAT( 30,16, on )
          else writeAT( 30,16, off );
          delay(100);
      until keypressed;
      clrscr;
      burnkey;
      writeln('Keyboard Status Saved' );
      writeln;
      Save_Keyboard_Status;
      for i := 1 to 3 do begin
          for j := 1 to 3 do begin
              writeln( EveryMsg, key_names[i], MidMsg, state_names[j] );
              burnkey;
              Set_Keyboard_State( Lock_Keys[i], key_States[j] );
          end;
          writeln;
      end;
      writeln;
      writeln( 'End of Demo.' );
      writeln( 'Any Key to Restore Original Lock Status and Exit.' );
      BurnKey;
      Restore_Keyboard_Status;
   end.
[Back to KEYBOARD SWAG index] [Back to Main SWAG index] [Original]