unit Keyboard; { copyright (c) 1994,1995 Dan Melton -- All rights reserved }

interface

uses
  DOS;

const
  kESC     = $01;         kN1      = $02;         kN2      = $03;
  kN3      = $04;         kN4      = $05;         kN5      = $06;
  kN6      = $07;         kN7      = $08;         kN8      = $09;
  kN9      = $0A;         kN0      = $0B;         kMINUS   = $0C;
  kEQUAL   = $0D;         kBACKSPC = $0E;         kTAB     = $0F;
  kQ       = $10;         kW       = $11;         kE       = $12;
  kR       = $13;         kT       = $14;         kY       = $15;
  kU       = $16;         kI       = $17;         kO       = $18;
  kP       = $19;         kLBRACE  = $1A;         kRBRACE  = $1B;
  kENTER   = $1C;         kEENTER  = $9C;         kLCTRL   = $1D;
  kRCTRL   = $9D;         kA       = $1E;         kS       = $1F;
  kD       = $20;         kF       = $21;         kG       = $22;
  kH       = $23;         kJ       = $24;         kK       = $25;
  kL       = $26;         kSCOLON  = $27;         kOQUOTE  = $28;
  kCQUOTE  = $29;         kLSHIFT  = $2A;         kBSLASH  = $2B;
  kZ       = $2C;         kX       = $2D;         kC       = $2E;
  kV       = $2F;         kB       = $30;         kN       = $31;
  kM       = $32;         kCOMMA   = $33;         kPERIOD  = $34;
  kSLASH   = $35;         kRSHIFT  = $36;         kSTAR    = $37;
  kLALT    = $38;         kRALT    = $B8;         kSPACE   = $39;
  kCAPLOCK = $3A;         kF1      = $3B;         kF2      = $3C;
  kF3      = $3D;         kF4      = $3E;         kF5      = $3F;
  kF6      = $40;         kF7      = $41;         kF8      = $42;
  kF9      = $43;         kF10     = $44;         kNUMLOCK = $45;
  kSCRLOCK = $46;         kP7      = $47;         kHOME    = $C7;
  kP8      = $48;         kP9      = $49;         kPGUP    = $C9;
  kPMINUS  = $4A;         kP4      = $4B;         kP5      = $4C;
  kP6      = $4D;         kPPLUS   = $4E;         kP1      = $4F;
  kEND     = $CF;         kP2      = $50;         kP3      = $51;
  kPGDN    = $D1;         kINS     = $52;         kDEL     = $53;
  kF11     = $57;         kF12     = $58;         kUP      = $C8;
  kDN      = $D0;         kLF      = $CB;         kRT      = $CD;

  KBflagCallInt9 : boolean = FALSE;
  KBflagNoBuffer : boolean = true;

var
  Key : array [$00..$FF] of byte;

procedure InitKeyboard;
procedure ExitKeyboard;

implementation

const
  Ok2Exit : boolean = false;
  OldProc : pointer = nil;
  OldInt9 : pointer = nil;

  Ext : word = 0;

procedure NewInt09; interrupt; assembler;
  asm
    in al,060h
    cmp al,0E0h
    jne @@normalkey
    mov [Ext],(offset Key+00080h)
    jmp @@quit
@@normalkey:
    mov bx,ax
    mov si,[Ext]
    and bx,0007Fh
    shr al,7
    add si,bx
    xor al,001h
    mov ds:[si],al
    mov [Ext],offset Key
    mov ax,040h
    mov es,ax
@@quit:
    test [KBflagCallInt9],not false
    jnz @@callorig
    mov al,020h
    out 020h,al
    jmp @@done
@@callorig:
    pushf
    call [OldInt9]
    test [KBflagNoBuffer],not false
    jz @@done
@@killkbuf:
    mov word ptr es:[0001Ah],01Eh
    mov word ptr es:[0001Ch],01Eh
@@done:
  end;

procedure UndoKeyboard; far;
  begin
    if not OK2Exit then exit;
    SetIntVec($09,OldInt9);
    Ok2Exit:=false;
    ExitProc:=OldProc;
  end;

procedure InitKeyboard;
  begin
    if Ok2Exit then exit;
    OldProc:=ExitProc;
    ExitProc:=@UndoKeyboard;
    Ext:=ofs(Key[0]);
    GetIntVec($09,OldInt9);
    SetIntVec($09,@NewInt09);
    Ok2Exit:=true;
  end;

procedure ExitKeyboard;
  begin
    Undokeyboard;
  end;

end.
