Keyboard
Unit KeyBoard;
{ Ž¡ëç® ª« ¢¨ âãà ¯®áë« ¥â ᨬ¢®«ë ¢ ª®¬¯ìîâ¥à }
{ á ¬ ªá¨¬ «ì®© ᪮à®áâìî 4 èâ㪨 ¢ ᥪã¤ã. }
{ —â®¡ë ¨£àãèª ¥ ¯à®áâ ¨¢ « ¢ ®¦¨¤ ¨¨ ¢¢®¤ á ª« ¢¨ âãàë }
{ 㦮 ॠ«¨§®¢ âì á«¥¤ãî騩 «£®à¨â¬: }
{ 1) ¢ ç «¥ ¯à®£à ¬¬ë ¤®¯ãáâ¨âì, çâ® ¢á¥ ª« ¢¨è¨ ®â¯ãé¥ë }
{ ¢ 横«¥ ¯à®£à ¬¬ë: }
{ 2) áç¨â âì ¦ â묨 ⥠ª« ¢¨è¨, ª®â®àë¥ ¥ ®â¯ãé¥ë }
{ 3) ¯® «®£¨¨ áç¨â âì ®â¯ãé¥ë¬¨ ¥ ¦ âë¥ }
{ ‘®¡á⢥® íâ®â ¬®¤ã«ì ¨ ¯®¬®£ ¥â ॠ«¨§®¢ âì ᥩ «£®à¨â¬: }
{ Set_Handler -> 1) }
{ New_Handler -> 2), 3) }
Interface
{ ‡¤¥áì ᪠ª®¤ë ¯®ç⨠¢á¥å ª« ¢¨è }
Const
sEsc = 1;
s1 = 2;
s2 = 3;
s3 = 4;
s4 = 5;
s5 = 6;
s6 = 7;
s7 = 8;
s8 = 9;
s9 = $0A;
s0 = $0B;
sMinus = $0C; { - _ }
sEqual = $0D; { = + }
sBackSpace = $0E;
sTab = $0F;
sQ = $10;
sW = $11;
sE = $12;
sR = $13;
sT = $14;
sY = $15;
sU = $16;
sI = $17;
sO = $18;
sP = $19;
sLBraket = $1A; (* [ { *)
sRBraket = $1B; (* ] } *)
sEnter = $1C;
sCtrl = $1D;
sA = $1E;
sS = $1F;
sD = $20;
sF = $21;
sG = $22;
sH = $23;
sJ = $24;
sK = $25;
sL = $26;
sSemicolon = $27; { ; : }
sQuote = $28; { ' " }
sApostrophe = $29; { ` ~ }
sLShift = $2A;
sSlash = $2B; { \ | }
sZ = $2C;
sX = $2D;
sC = $2E;
sV = $2F;
sB = $30;
sN = $31;
sM = $32;
sComma = $33; { , < }
sPoint = $34; { . > }
sBackSlash = $35; { / ? }
sRShift = $36;
sAsteriks = $37; { * æ¨ä஢®© ª« ¢¨ âãॠ}
sAlt = $38;
sSpace = $39; { ¯à®¡¥« }
sCapsLock = $3A;
sF1 = $3B;
sF2 = $3C;
sF3 = $3D;
sF4 = $3E;
sF5 = $3F;
sF6 = $40;
sF7 = $41;
sF8 = $42;
sF9 = $43;
sF10 = $44;
sNumLock = $45;
sScrollLock = $46;
sHome = $47;
sUp = $48;
sPageUp = $49;
sGrayMinus = $4A; { - æ¨ä஢®© ª« ¢¨ âãॠ}
sLeft = $4B;
sFive = $4C; { 5 æ¨ä஢®© ª« ¢¨ âãॠ}
sRight = $4D;
sGrayPlus = $4E; { + æ¨ä஢®© ª« ¢¨ âãॠ}
sEnd = $4F;
sDown = $50;
sPageDown = $51;
sInsert = $52;
sDelete = $53;
sF11 = $57;
sF12 = $58;
Var
KeyMap : Array [0..$7F] of Boolean; { ‘¬¥é¥¨¥-᪠ª®¤ ª« ¢¨è¨, TRUE - }
{ ¦ â ᥩç á, FALSE - ®â¯ãé¥ }
SymMap : Array [0..$7F] of Char; { ‘¬¥é¥¨¥-᪠ª®¤ ª« ¢¨è¨, }
{ ᮤ¥à¦¨¬®¥ - ASCII-ᨬ¢®«ë ¤«ï ª« ¢¨è }
Procedure Set_Handler;
{ “áâ ¢«¨¢ ¥â ®¢ë© ®¡à ¡®â稪 ª« ¢¨ âãண® ¯à¥àë¢ ¨ï, }
{ ª®£¤ ®¢ë© ®¡à ¡®â稪 ªâ¨¢¥, â® …‚އŒŽ†Ž ¯®«ì§®¢ âìáï }
{ KeyPressed, ReadKey ¨ Read, â ª¦¥ ®áâ ¢«¨¢ âì ¯à®£à ¬¬ã }
{ ¯® Ctrl+C (Ctrl+Break) ¨«¨ ¥¥ ®â« ¦¨¢ âì. }
{ KeyPressed ¨ ReadKey ¨¬¥îâ «®£¨ - ᬮâਠ¨¦¥ }
Procedure Remove_Handler;
{ ‚®§¢à é ¥â áâ àë© ®¡à ¡®â稪 ª« ¢¨ âãண® }
{ ¯à¥àë¢ ¨ï ¥£® § ª®®¥ ¬¥áâ® }
Procedure WaitForACSReleased;
{ †¤¥â ®â¯ã᪠¨ï Alt,Ctrl,Shift; ¨á¯®«ì§ã¥âáï ’Ž‹œŠŽ ……„ }
{ ãáâ ®¢ª®© ®¢®£® ®¡à ¡®â稪 ª« ¢¨ âãண® ¯à¥àë¢ ¨ï }
Function KeyPressedNow : Boolean;
{ ‚®§¢à é ¥â TRUE ¥á«¨ ¢ „€›‰ ¬®¬¥â ¢à¥¬¥¨ }
{ ¤¥©áâ¢¨â¥«ì® ¦ â å®âï¡ë ®¤ ª« ¢¨è , ¨ ç¥ ¢®§¢à é ¥â FALSE. }
{ ˆá¯®«ì§ã¥âáï ¢¬¥áâ¥ á ¬ áᨢ ¬¨ KeyMap ¨ SymMap }
Function KeyPressed2 : Boolean;
{ ®«ë© «®£ ä-樨 KeyPressed ¨§ ¬®¤ã«ï CRT. }
Function ReadScan : Byte;
{ € «®£ ä-樨 ReadKey (¬®¤ã«ì CRT). }
{ §¨æ ¢ ⮬, çâ® íâ ä-æ¨ï ¢®§¢à é ¥â }
{ ¥ ᨬ¢®« ª« ¢¨è¨, ¥¥ ᪠ª®¤, ¯®§¢®«ïï }
{ ¤®¡à âìáï ¤® ª ¦¤®© ª« ¢¨è¨. }
{ ˆá¯®«ì§ã¥âáï ¢¬¥á⥠á KeyPressed2 }
Function ReadChar : Char;
{ € «®£ ä-樨 ReadKey (¬®¤ã«ì CRT). }
{ §¨æ ¢ ⮬, çâ® íâ ä-æ¨ï ¢®§¢à é ¥â }
{ ᨬ¢®« ª« ¢¨è¨ ¡¥§ ãç¥â á®áâ®ï¨© Alt,Ctrl,Shift ¨ Caps Lock. }
{ …᫨ ¦ â ï ª« ¢¨è ¥ ¨¬¥¥â ᥡ¥ ᨬ¢®« , â® ¢®§¢à é ¥âáï }
{ ã«¥¢®© ᨬ¢®«, ¨ ® ª ª¨å à áè¨à¥ëå ª®¤ å §¤¥áì à¥ç¨ ¡ëâì ¥ }
{ ¬®¦¥â. ˆá¯®«ì§ã¥âáï ¢¬¥á⥠á KeyPressed2 }
Procedure ClearKeyboardBuf;
{ Žç¨é ¥â ª®«ì楢®© ¡ãä¥à, ¨á¯®«ì§ã¥¬ë© ä-æ¨ï¬¨ KeyPressedNow, KeyPressed2, }
{ ReadScan ¨ ReadChar }
Implementation
Uses DOS;
Const
Old_Handler : Pointer = Nil; { ‘î¤ á®åà ¨¬ ¤à¥á áâ ண® ®¡à ¡®â稪 }
KeyBufSize = 16; { Š« ¢¨ âãàë© ¡ãä¥à ¡ã¤¥â ᮤ¥à¦ âì }
{ ¬ ªá¨¬ã¬ 16 ᪠ª®¤®¢ }
Symbs : Array [sEsc..sSpace] of Char =
#27'1234567890-='#8#9'QWERTYUIOP[]'#13#0'ASDFGHJKL;''`'#0'\'+
'ZXCVBNM,./'#0'*'#0' ';
Var
KeyBuf : Array [0..KeyBufSize] of Byte; { Š®«ì楢®© ª« ¢¨ âãàë© ¡ãä¥à }
BufHead, { ƒ®«®¢ ¡ãä¥à }
BufTail : Word; { •¢®áâ ¡ãä¥à }
KeyCount : Byte; { Š®«-¢® ᪠ª®¤®¢ ª« ¢¨è }
{ ¢ ¡ãä¥à¥ }
Procedure New_Handler; Interrupt; Assembler;
{ Using assembler because we need a fast interrupt-handling routine }
Asm
Push AX
Push BX
In AL, 060h
Mov AH, AL
And AL, 07Fh { AL = ‘ª ª®¤ }
LEA BX, KeyMap
Add BL, AL
AdC BH, 0
Test AH, 080h
JNZ @released { ‘â à訩 ¡¨â - ä« £ ®â¯ã᪠¨ï }
Mov Byte Ptr [BX], TRUE { Š« ¢¨è ¡ë« ¦ â }
Cmp KeyCount, KeyBufSize
JE @done { ãä¥à ¡¨âª®¬ ¡¨â }
LEA BX, KeyBuf
Add BX, BufTail
Mov [BX], AL { ‘®åà ¨«¨ ᪠ª®¤ ¢ KeyBuf }
Inc KeyCount { More keys avaible to read }
Inc BufTail { ‘«¥¤ãîé ï ¯®§¨æ¨ï ¤«ï á®åà ¥¨ï }
Cmp BufTail, KeyBufSize
JNE @done
Mov BufTail, 0 { ‘ª®à४â¨à®¢ «¨ ¯®§¨æ¨î }
Jmp @done
@released:
Mov Byte Ptr [BX], FALSE { Š« ¢¨è ¡ë« ®â¯ãé¥ }
@done:
Mov AL, 020h { ‘®®¡é¨«¨ ª®â஫«¥àã }
Out 020h, AL { ¯à¥àë¢ ¨©, çâ® ¯à¥àë¢ ¨¥ }
{ ®¡à ¡®â ® }
Pop BX
Pop AX
End;
Procedure Set_Handler;
Begin
If Old_Handler <> Nil then Exit;
FillChar (KeyMap, $80, False); { ˆ§ ç «ì® áç¨â ¥¬ ¢á¥ ª« ¢¨è¨ }
KeyCount := 0; { ®â¯ãé¥ë¬¨ }
BufHead := 0; { -//- }
BufTail := 0; { -//- }
GetIntVec (9, Old_Handler);
SetIntVec (9, @New_Handler)
End;
Procedure Remove_Handler;
Begin
If Old_Handler = Nil then Exit;
SetIntVec (9, Old_Handler);
Old_Handler := Nil
End;
Procedure WaitForACSReleased;
Begin
While Mem[$40:$17] and $0F <> 0 do
End;
Function KeyPressedNow : Boolean; Assembler;
{ áᥬ¡«¥à¥ à ¡®â ¥â èãáâ॥, 祬 ᪠«¥ }
Asm
Mov AX, DS
Mov ES, AX
LEA DI, KeyMap+1 { ç¨ ¥¬ á Escape }
Mov CX, 058h { ‚ᥠª« ¢¨è¨ ¯«îá F11 ¨ F12 }
Mov AL, FALSE { ।¯®«®¦¨«¨, çâ® ¯ãáâ® }
CLD
RepE ScaSB { ‘ª ¨à㥬 ¬ áᨢ KeyMap }
JE @end { ãáâ® }
Mov AL, TRUE { —â®-â® ¦ â® }
@end:
End;
Function KeyPressed2 : Boolean;
Begin
KeyPressed2 := KeyCount<>0 { ãä¥à ¥ ¯ãáâ }
End;
Function ReadScan : Byte;
Begin
While KeyCount=0 do;
ReadScan := KeyBuf[BufHead];
Inc (BufHead); { ‘¬¥é¥¨¥ á«¥¤ãî饩 ª« ¢¨è¨ }
If BufHead = KeyBufSize then BufHead := 0;
Dec (KeyCount) { Ž¤ã ª« ¢¨èã ¤®«®© }
End;
Function ReadChar : Char;
Begin
ReadChar := SymMap[ReadScan]
End;
Procedure ClearKeyboardBuf;
Begin
Asm PushF; CLI End;
BufHead := BufTail;
KeyCount := 0;
Asm PopF End
End;
Var I : Byte;
Begin
{ ‡ ¯®«¥¨¥ ¬ áᨢ ᨬ¢®«®¢ }
FillChar (SymMap, $80, 0);
For I := sEsc to sSpace do
SymMap[I] := Symbs[I];
SymMap[sGrayMinus] := '-';
SymMap[sGrayPlus] := '+'
End.