{----------------------------SNiPy, SNiPy-----------------------------------} { I don't remember where I got this unit. If anyone is upset with me because I distribute it, just let me know. Willem van de Vis, s0730076@let.rug.nl } unit pushkey; interface uses dos; Procedure PushKbdBuffer; Procedure PushKeys(Keys:String); var kbd : Text; PushKeyBusy : Boolean; implementation var Vector : Array [0..$FF] of pointer absolute 0:0; SaveInt16 : Pointer; SaveInt1B : Pointer; SaveBufPtr : Pointer; SaveBufPos : Word; KeyPopped : Boolean; DirectPush : Boolean; DirectBuf : String; PopPtr : Word; Procedure CLI; InLine($FA); Procedure STI; InLine($FB); {$F+} Function KbdFlush(var F:TextRec):Integer; begin with F do begin if BufPtr^[BufPos-1] = ^J then Dec(BufPos); if BufPos >= BufSize then begin Writeln('KbdBuffer overflow'); Halt; end; end; KbdFlush:=0; end; Function Ignore(var F:TextRec):Integer; begin Ignore:=0; end; Function KbdOpen(var F:TextRec):Integer; begin with F do begin Mode:=fmOutput; FlushFunc:=@KbdFlush; InOutFunc:=@Ignore; CloseFunc:=@Ignore; BufPos:=0; end; KbdOpen:=0; end; Procedure UnHook; begin with TextRec(kbd) do begin PushKeyBusy:=False; Vector[$16]:=SaveInt16; Vector[$1B]:=SaveInt1B; BufPos:=0; if DirectPush then begin BufPtr:=SaveBufPtr; BufPos:=SaveBufPos; DirectPush:=False; end; end; end; procedure BreakHandler(Flags,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP: Word); interrupt; begin UnHook; end; Procedure BiosKbdFunctions(Flags,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP: Word); interrupt; begin with TextRec(kbd) do begin case Hi(AX) of 0, $10 : begin { read character function } Inc(PopPtr); KeyPopped:=True; AX:=Ord(BufPtr^[PopPtr-1]); case Lo(AX) of 0 : if PopPtr < BufPos then begin AX:=Ord(BufPtr^[PopPtr]) shl 8; Inc(PopPtr); end; $0D : AX:=$1C0D; end; end; 1, $11 : begin { keypressed function } AX:=Ord(BufPtr^[PopPtr]); case Lo(AX) of $00 : AX:=Ord(BufPtr^[PopPtr+1]) shl 8; $0D : AX:=$1C0D; end; if KeyPopped then Flags:=Flags or FZero else Flags:=Flags and (not FZero); KeyPopped:=False; end; 2, $12 : begin { get shiftflags function } AX:=Mem[$40:$17]; end; end; if PopPtr >= BufPos then UnHook; end; end; Procedure PushKbdBuffer; begin with TextRec(kbd) do if (BufPos > 0) and (not PushKeyBusy) then begin CLI; PopPtr:=0; KeyPopped:=False; SaveInt16:=Vector[$16]; Vector[$16]:=@BiosKbdFunctions; SaveInt1B:=Vector[$1B]; Vector[$1B]:=@BreakHandler; PushKeyBusy:=True; STI; end; end; Procedure PushKeys(Keys:String); begin if (not PushKeyBusy) and (Keys <> '') then with TextRec(kbd) do begin DirectPush:=True; SaveBufPos:=BufPos; SaveBufPtr:=BufPtr; BufPos:=Length(Keys); BufPtr:=addr(DirectBuf[1]); DirectBuf:=Keys; PushKbdBuffer; end; end; begin with TextRec(kbd) do begin PushKeyBusy:=False; DirectPush:=False; Handle:=$FFFF; Mode:=fmClosed; BufSize:=SizeOf(Buffer); BufPtr:=@Buffer; OpenFunc:=@KbdOpen; Name[0]:=#0; ReWrite(kbd); end; end.