Keyboard driver routine, attached to INT9 IO port

Close Index
{
	Code sample: Keyboard driver for regional characters. Driver table is loaded from text file and kept in memory.
		
	Routine is attached to Int9 interrupt vector. Driver is activated and deactivated when main application is loaded 
	(thus not real TSR routine).
	
	Igor Klepoch, 1992
}

var
  klbuf,zalintr:pointer;
  posvrchol,zmenklav,pockl,zactab,zacodk,ukzact,zalzact:word;
  zacpredv:word;
  jeklavdr,flagpredv,nasflpredv:boolean;

procedure prevkl; interrupt; assembler;
asm
           pushf
           call    zalintr
           sti
           pushf
           push    ax
           push    bx
           push    ds
           push    es
           push    si
           push    di

           mov     ax,40h
           mov     es,ax
           mov     bx,es:[1ch]
           cmp     bx,posvrchol {je to nova klavesa ?}
           jnz     @jenovkl      {ano
                                {este moze byt zmena klavesnice}
           mov     bx,es:[bx]   {status klaves}
           mov     al,es:[17h]  {je to Alt+right shift ?}
           and     al,9
           cmp     al,9
           jz      @jezmkl       {je zmena klavesnice}
           jmp     @ukon         {ani zmena klavesnice}

@jezmkl:                         {bol kod zmeny klavesnice}
           mov     si,100h	{ton zmeny klavesnice}
           mov     di,50h
           call    @ton
           push    cx
           mov     cx,0
@c1:
           loop    @c1
           pop     cx
           mov     si,100h
           mov     di,50h
           call    @ton
           mov     bx,ukzact
           add     bx,2
           mov     ukzact,bx
           les     si,klbuf
           mov     bx,es:[bx]
           mov     ax,zacodk
           cmp     bx,0ffffh
           jnz     @esteniezac
           mov     bx,zacodk    {bola uz posledna klavesnica, teraz ide prva}
           mov     ukzact,bx
           mov     bx,es:[bx]
@esteniezac:
           add     bx,ax
           mov     zactab,bx
           push    es
           mov     si,zactab    {kde hladat}

@hladc2:   mov     ax,es:[si]   {vyhladavanie v tabulke}
           add     si,2
           cmp     ax,0ffffh
           jnz     @hladc2
           pop     es
           mov     zacpredv,si
           mov     flagpredv,0
           jmp     @ukon

@jenovkl:
           mov     posvrchol,bx
           cmp      bx,es:[1ah]
           jz       @p1
           sub      bx,2
           cmp      bx,1ch
           jnz      @p1
           mov      bx,3ch
@p1:
           push    bx
           mov     bx,es:[bx]
@prehladaj:
           les     si,klbuf
           mov     si,zactab    {kde hladat}
           mov     nasflpredv,0 {doteraz predvolba nebola}

@hladc1:
           mov     ax,es:[si]   {vyhladavanie v tabulke}
           cmp     ax,0ffffh
           jz      @predvolby    {este predvolby}
           cmp     ax,bx
           jz      @prevedie
           add     si,2
           jmp     @hladc1


@predvolby:
           cmp     nasflpredv,1
           jnz     @pred1
           mov     ax,40h
           mov     es,ax
           jmp     @nieje        {uz bola aj tab. predvolieb - nieje v tab.}
@pred1:
           mov     nasflpredv,1  {nastavi tabulku predvolieb}
           mov     si,zacpredv
           jmp     @hladc1


{ tu sa prevedie znak podla tabulky a vyhodnoti sa predvolba}

@prevedie:
           pop     bx           {adresa v pam. do BX}
           cmp     nasflpredv,1 {bol teraz stlaceny klaves predvolby ?}
           jnz     @jeznak      {nie - vyber z tabulky v rut. jeznak}

{bola teraz stlacena predvolba}

           mov     ax,40h
           mov     es,ax
           cmp     flagpredv,1  {v predchadzajucom bola predvolba ?}
           jz      @chpr        {ano - pipnutie na znak chyby}

           mov     es:[1ch],bx
           mov     posvrchol,bx
           mov     ax,zactab    {zalozenie predvolby}
           mov     zalzact,ax
           push    es
           les     bx,klbuf
           mov     ax,es:[si+2]
           pop     es
           add     ax,bx
           mov     zactab,ax

           mov     flagpredv,1
           mov     si,500h	{ton predvolby}
           mov     di,50h
           call    @ton
           jmp     @ukon


@chpr:                           {chyba pri predvolbe: dva krat volana,alebo nedef. znak}
           mov     es:[1ch],bx
           mov     posvrchol,bx

@vyberpr:                        {zrusenie predvolby}
           mov     si,100h
           mov     di,100h
           call    @ton
           mov     si,500h
           mov     di,50h
           call    @ton
           mov     ax,zalzact
           mov     zactab,ax
           mov     flagpredv,0
           jmp     @ukon


@jeznak:
           mov     ax,es:[si+2]
           mov     cx,40h
           mov     es,cx
           mov     es:[bx],ax
           cmp     flagpredv,1
           jnz     @ukon
                                {bol klaves s predvolbou, teraz treba predvolbu zrusit}
           mov     ax,zalzact
           mov     zactab,ax
           mov     flagpredv,0
           jmp     @ukon

@nieje:                          {znak sa neprevadza}
           pop     bx
           cmp     flagpredv,1
           jnz     @ukon
           jmp     @chpr

@ton:
           push     ax
           push     bx
           push     cx
           in       al,61h
           push     ax
           mov      bx,di
@tc1:
           and      al,0fch
           or       al,2
           out      61h,al
           mov      cx,si
@tc2:
           loop     @tc2

           and      al,0fch
           out      61h,al
           mov      cx,si
@tc3:
           loop     @tc3

           dec      bx
           jnz      @tc1
           pop      ax
           out      61h,al
           pop      cx
           pop      bx
           pop      ax
           ret


@ukon:
           pop     di
           pop     si
           pop     es
           pop     ds
           pop     bx
           pop     ax
           popf
           cli
end;



procedure zarklav(nazdiakr:string);
var
   f:file;
   s:longint;
begin
     assign(f,nazdiakr+'.klv'); reset(f,1); seek(f,4);
     blockread(f,klbuf^,filesize(f)-4);
     close(f);
     asm
        push    es
        les     bx,klbuf
        mov     zacodk,bx
        mov     ukzact,bx
        mov     ax,es:[bx]
        add     ax,bx
        mov     zactab,ax
        mov     flagpredv,0
        mov     jeklavdr,1
        mov     si,zactab    {kde hladat - nastavi zaciatok predvolieb}
        push    ds
        mov     ax,40h
        mov     ds,ax
        mov     bx,ds:[1ch]
        push    es
        pop     ds

@11:    lodsw
        add     si,2
        cmp     ax,0ffffh
        jnz     @11
        sub     si,2
        pop     ds
        mov     posvrchol,bx
        mov     zacpredv,si
        pop     es
     end;
{     setintvec(9,@prevkl);}
end;


procedure  rusklav;
begin setintvec(9,zalintr); end;