uses crt,go32;
{$MODE FPC}

{$DEFINE OPATRNOST}   {Zda se, ze je mozne ji vypnout...}
const kbdint = $9;
      enter = 28;

var oldint9_handler:tseginfo;
    newint9_handler:tseginfo;
    FromPort:byte;
    clickproc:pointer;
    backupDS:Word; external name '___v2prt0_ds_alias';
    {___v2prt0_ds_alias je promenna uvnitr DPMI serveru. Je tu uchovan DS preruseneho programu}
    {My se na tuto promennou dostaneme prostrednictvim backupDS}

    klavesa:Array[0..127] of boolean; {To nejsou ASCII kody, ale polohove kody}
    zmena:boolean;

procedure int9_handler; assembler;interrupt; { VSIMNETE SI, ZE TU MUSI BYT UVEDEN MODIFIKATOR INTERRUPT }
asm
cli
{$IFDEF OPATRNOST}
push ds
push es
push fs
push gs
pusha
{$ENDIF}
   mov ax,cs:[backupDS]
   mov ds,ax
   mov es,ax
   mov ax,dosmemselector
   mov fs,ax
 call clickproc
{$IFDEF OPATRNOST}
popa
pop gs
pop fs
pop es
pop ds
{$ENDIF}
sti
end;
procedure int9_dummy; begin end;


procedure clicker;
begin
sound(500);delay(10);nosound;

FromPort:=InPortB($60);  {NAPROSTO NUTNE! JE ABSOLUTNE NUTNE PRECIST Z PORTU 60h I KDYZ NAS TO TREBA NEZAJIMA}
if (FromPort and 128)<>0 then klavesa[FromPort-128]:=false else klavesa[FromPort]:=true;
zmena:=true;
OutPortB($20,$20);       {NUTNE}
end;
procedure clicker_dummy; begin end;


procedure install_click;
begin
clickproc:=@clicker;
lock_data(clickproc, sizeof(clickproc));
lock_data(dosmemselector, sizeof(dosmemselector));
lock_data(fromport, sizeof(fromport));
lock_data(klavesa, sizeof(klavesa));
lock_data(zmena, sizeof(zmena));

lock_code(@clicker,longint(@clicker_dummy) - longint(@clicker));
lock_code(@int9_handler,longint(@int9_dummy)-longint(@int9_handler));
newint9_handler.offset:=@int9_handler;
newint9_handler.segment:=get_cs;
get_pm_interrupt(kbdint, oldint9_handler);
set_pm_interrupt(kbdint, newint9_handler);
end;

procedure remove_click;
begin
set_pm_interrupt(kbdint, oldint9_handler);
unlock_data(dosmemselector, sizeof(dosmemselector));
unlock_data(clickproc, sizeof(clickproc));
unlock_data(fromport, sizeof(fromport));
unlock_data(klavesa, sizeof(klavesa));
unlock_data(zmena, sizeof(zmena));

unlock_code(@clicker,longint(@clicker_dummy)-longint(@clicker));
unlock_code(@int9_handler,longint(@int9_dummy)-longint(@int9_handler));
end;

var a:integer;
    s,t:string;

begin
install_click;
zmena:=false;
Writeln('Neco mackej. Enterem skoncis');
writeln;
repeat
if zmena then
   begin
   s:='';
   for a:=0 to 127 do if klavesa[a] then
       begin
       Str(a,t);
       s:=s+'|'+t;
       end;
   gotoxy(1,24);write(s:80);
   zmena:=false;
   end;
until klavesa[enter];
remove_click;
end.

