[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 = Record { one key in the keyboard buffer }
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]