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