[Back to KEYBOARD SWAG index]  [Back to Main SWAG index]  [Original]

UNIT KeyIntr ;  { support for INT 09 16 routines } { Turbo Pascal 5.5+ }

INTERFACE

Type
   InterruptProcedure = Procedure ;

Const
   BiosDataSegment = $40 ;

Procedure DisableInterrupts ; Inline( $FA ) ;   { CLI }
Procedure EnableInterrupts ;  Inline( $FB ) ;   { STI }
Procedure CallInterrupt( P : Pointer ) ;

Function AltPressed : Boolean ;
Function ControlPressed : Boolean ;
Function ShiftPressed : Boolean ;

Procedure EOI ;                      { end of interrupt to 8259 }
Function ReadScanCode : Byte ;       { read keyboard }
Procedure ResetKeyboard ;            { prepare for next key }
                                     { put key in buffer for INT 16 }
Function StoreKey( Scan, Key : Byte ) : Boolean ;

IMPLEMENTATION

Type
   TwoBytesPtr = ^TwoBytes ;
   TwoBytes =               { one key in the keyboard buffer }
   Record
      KeyCode,
      ScanCode : Byte ;
   End ;

Var
   KeyState       : Word Absolute BiosDataSegment:$17 ;
   KeyBufferHead  : Word Absolute BiosDataSegment:$1A ;
   KeyBufferTail  : Word Absolute BiosDataSegment:$1C ;
   KeyBufferStart : Word Absolute BiosDataSegment:$80 ;
   KeyBufferEnd   : Word Absolute BiosDataSegment:$82 ;

Procedure CallInterrupt( P : Pointer ) ;
Begin
   Inline( $9C ) ;           { PUSHF }
   InterruptProcedure(P) ;
End ;

Function AltPressed : Boolean ;
Begin
   AltPressed := (KeyState and 8) <> 0 ;
End ;

Function ControlPressed : Boolean ;
Begin
   ControlPressed := (KeyState and 4) <> 0 ;
End ;

Function ShiftPressed : Boolean ;
Begin
   ShiftPressed := (KeyState and 3) <> 0 ;
End ;

Procedure EOI ;  { end of interrupt to 8259 interrupt controller }
Begin
   Port[$20] := $20 ;
End ;

Function ReadScanCode : Byte ;
Var
   N : Byte ;
Begin
   N := Port[$60] ;     { $FF means keyboard overrun }
   ReadScanCode := N ;
End ;

Procedure ResetKeyboard ;      { prepare for next key }
Var
   N : Byte ;
Begin
   N := Port[$61] ;
   Port[$61] := (N or $80) ;
   Port[$61] := N ;
End ;

Function StoreKey( Scan, Key : Byte ) : Boolean ;
Var                { put key in buffer that INT 16 reads }
   P : TwoBytesPtr ;
   N : Word ;
Begin
   DisableInterrupts ;

   N := KeyBufferTail ;
   P := Ptr( BiosDataSegment, N ) ;

   Inc( N, 2 ) ;
   If( N = KeyBufferEnd ) then        { end of the circular buffer }
      N := KeyBufferStart ;
   If( N = KeyBufferHead ) then       { buffer full }
   Begin
      EnableInterrupts ;
      StoreKey := False ;
   End
   Else
   Begin
      P^.KeyCode := Key ;
      P^.ScanCode := Scan ;             { store key in circular buffer }
      KeyBufferTail := N ;              { advance tail pointer }
      EnableInterrupts ;
      StoreKey := True ;
   End ;
End ;


END.




[Back to KEYBOARD SWAG index]  [Back to Main SWAG index]  [Original]