Inline assembler code

Close Index
{ 
     An inline assembler code for collecting status/answers from connected devices.
     Code was designed for a PC-XT/AT computer class, MS DOS system.

     Devices are connected through centronics/8255 interface.
     Code is from 1993.
}

const
     mz=40;

var
   pstav,typosi:byte;
   konstdl:word;
   ptime,zactime:longint;
   prresult,pocetsnimz:byte;

   adr:word absolute 0:$408;
   control:word;                   {0-clock
                                    1-reset}
   readport:word;          {vstup udaju z tlacidla - bit 4(poloha 5)}

   chybmysi:array[1..mz] of boolean;
   indp,zals,stav,sedenie,odp:array[1..mz] of byte;   {pole pre triedenie, zaloha pola sedenie;
   farba pre zobrazenie odpovede ziaka;sedenie ziakov v triede,pole, do ktoreho sa ukladaju odpovede}
   snimajpoz,jehlaseny,dalsiesn:array[0..mz] of boolean;  {ktori ziaci mozu byt snimani; ktori sa prihlasili;
                           ziaci, ktori zle odpovedali a budu snimani znova}


procedure initeppv;
begin
     rychlost; control:=adr+2; readport:=adr+1; 

     asm
        mov     dx,control
        mov     al,ds:[pstav]
        out     dx,al
     end;
	 
end;


procedure rychlost;
var
   r:real;
begin
     konstdl:=2000;
     zactime:=timesec;
     asm
        mov     cx,500
@1:     call    waitcyk
        loop    @1
     end;
     ptime:=(timesec-zactime)*10; r:=konstdl/ptime;
     konstdl:=trunc(r*500);
end;

procedure waitcyk; assembler;
asm
        push    cx
        mov     cx,ds:[konstdl]
@001:
        loop    @001
        pop     cx
end;

procedure initcit;
var
   i:byte;
begin
     asm
        mov    dx,control
        mov    al,3            {inicializacia systemu}
        add    al,ds:[pstav]
        out    dx,al
        call   waitcyk
        mov    al,2            {signal reset este drzi}
        add    al,ds:[pstav]
        out    dx,al
        call   waitcyk
        mov    al,0            {koniec inicializacie}
        add    al,ds:[pstav]
        out    dx,al
        call   waitcyk
     end;
     for i:=1 to maxziakov do odp[i]:=0;
end;

procedure snimstavtlac(konv:boolean); assembler;
var
   cisziaka,esteziakov,tlacidko,vaha,vysledok:byte;
   adresatlac:word;

asm
        push   ds
        push   bp
        mov    ax,0
        mov    es,ax
        mov    al,maxziakov         {bude uchovavat pocet ziakov}
        mov    ss:[esteziakov],al
        mov    ss:[adresatlac],0    {adresa tlacitka}
        mov    ss:[cisziaka],1
        mov    dx,control
        mov    al,2                 {nulovanie citaca}
        add    al,ds:[pstav]
        out    dx,al
        call   waitcyk
        mov    al,0                 {koniec inicializacie}
        add    al,ds:[pstav]
        out    dx,al
        call   waitcyk
        push   ss
        pop    es
;
{teraz sa precita stav a vysle sa signal CLOCK}
@001:
        mov    bl,pocetklaves           {BL-pocitadlo poctu klaves}
        mov    ss:[tlacidko],bl
        mov    ss:[vaha],8             {vaha odpovede}
        mov    ss:[vysledok],0          {vysledok zo vsetkych tlacidiel}
@002:
        mov    dx,readport
        in     al,dx
        and    al,10000b                {5 pozicia je vstup}
        jz     @003
        mov    al,vaha                  {bolo stlacene}
        cmp    es:[konv],0
        jz     @6
        cmp    es:[vysledok],0
        jnz    @003
@6:     add    ss:[vysledok],al
@003:
        ror     ss:[vaha],1
        mov     dx,control               {vysle hodinovy signal}
        mov     al,1
        add    al,ds:[pstav]
        out     dx,al
        call    waitcyk
        mov     al,0
        add    al,ds:[pstav]
        out     dx,al
        call    waitcyk
        dec     ss:[tlacidko]
        jnz     @002
{uz su vsetky tlacidka nasnimane, teraz dalsia mys}
        lea     bx,odp
        mov     al,ss:[cisziaka]
{        cmp     al,5
        jc      @3
        sub     al,2}
@3:
        dec     al
        mov     ah,0
        add     bx,ax
        mov     al,ds:[bx]
        cmp     al,0
        jnz     @004
        mov     al,ss:[vysledok]
        cmp     ss:[konv],1
        jnz     @005
        cmp     al,4
        jnz     @1
        mov     al,3
        jmp     @005
@1:
        cmp     al,8
        jnz     @2
        mov     al,4
        jmp     @005
@2:
        cmp     al,0
        jz      @005
        cmp     al,1
        jz      @005
        cmp     al,2
        jz      @005
        mov     al,255
@005:
        mov     ah,ss:[cisziaka]
{        cmp     ah,3
        jz      @004
        cmp     ah,4
        jz      @004}
        mov     ds:[bx],al
@004:
        inc     ss:[cisziaka]
        dec     ss:[esteziakov]
        jnz     @001
        pop     bp
        pop     ds
end;

procedure testchyb;
var
   i:byte;
begin
     initcit; snimstavtlac(false);
     for i:=1 to maxziakov do chybmysi[i]:=odp[i]=15;
     pocmysi:=maxziakov;
     while chybmysi[pocmysi] do dec(pocmysi);
     pocprmysi:=0;
     for i:=1 to maxziakov do if not(chybmysi[i]) then inc(pocprmysi);
end;


function vyhodnotprih(sethod:byte):byte;
var
   i,poc:byte;
begin
     poc:=0; {snimstavtlac;}
{snimanie odpovedi z mysi}
     snimstavtlac(true);
     for i:=1 to maxziakov do if (odp[i]>0)and(odp[i]<5)and(dalsiesn[i])and(not(chybmysi[i])) then
         begin inc(poc,1); stav[i]:=pritf; jehlaseny[i]:=true; end;
     vyhodnotprih:=poc;
     zobrodp;
end;

procedure vstupcisla(cis:byte);
var
   pocodp,i:byte;
begin
     initcit; horwin; for i:=1 to maxziakov do begin stav[i]:= nepritf; odp[i]:=0; end;
     ton(500,100);
     repeat
           pocodp:=vyhodnotprih(pritf);
           writestr(34,16+cis,dopznri(repchar('Û',trunc(pocodp/pocetsnimz*20)),'°',20),fartriedy);
           if jeklav then p_char:=readzn;
           if p_char=$3200 then obslm;
     until (pocodp>=pocetsnimz)or(prresult<>4);
     for i:=1 to maxziakov do if snimajpoz[i] then prezent[i,cis]:=odp[i];
end;

.... 

end.