Nejspíše jsi si přečetl příklad pro začátečníky, jak programovat
parport… Protože jsem programoval dost dlouho v PC assembleru (jinak těch
200k kroků/sec z PC nelze vymáčknout), musím ti ukázat, jak vypadá IN/OUT
programování:
push BX, AX, DX ;uložení registrů
inc BX ; inkrementovat pointer
mov BX,[pointer odesílaných dat]
cmp BX,[Počet prenesených dat] ; je ještě co přenášet?
jz KonecPrenosu ; všechna data přenesena
mov AL,LPT_Buffer[BX] ; natažení dalšího byte pro prenos
mov DX,0×378
out DX,AL ; ano toto je ta OUT instrukce a u 486-ky trvá 2 takty – tím se
zapíší data do registru 0×378 je uloženo v DX
mov DX,0×37a ; ještě je třeba vyrobit strobe puls a ten udělá manipulaci
s registrem 0×37A
in AL,DX
xor AL,1
out DX,AL
xor AL,1
nop
out DX,AL ;Puls je vyroben, konec přenosu bytu
pop DX, AX, BX ; obnova registrů
IRET ; návrat z přerušení
Protože parport má přerušení, není třeba neustále zjišťovat tisíci
instrukcemi, zda zařízení převzalo byte. Až nahodí ACK, vygeneruje se
interrupt a na port se „vyhodí“ další byte podle výše uvedené
sekvence. Trochu jsem ji zjednodušil, ještě jsou tam 4 instrukce na
zjištění stavu tiskárny (zda nedošel papír nebo tiskárna není
v chybovém stavu). Samozřejmě tam chybí také inicialitace portu a řadiče
přerušení – ale to se provádí jen jednou po restartu. A taky tam chybí
zahájení a ukončení přenosu a obsluha chybových stavů – to je trochu
složitější, ale zas se to nedělá příliš často…
Po návratu z přerušení se pokračuje přesně tam kde byl běh systému
přerušen. A i kdyby tam byl čas jen na provedení jedné instrukce, tak se
ta instrukce provede, pokud tam bude času více, udělá se více
instrukcí.
Přerušení LPT se nesheduluje jako proces. K přerušení dochází naprosto
náhodně v průběhu nějakého běžícího procesu. Provádění procesu se
přeruší a po přenesení dalšího byte se pokračuje v provádění
procesu. Proces ani „nevyčmuchá“, že byl přerušen. Žádný čas se
zbytečně neprofláká, ty moje počty jsou správné.
Jo a k té granularitě: jediné co se musí dělat navíc, když dochází
k rozkouskování přenosu pomocí „jednobytového přerušení“ jsou
instrukce PUSH na začátku přerušení a POP a IRET na konci. Ale to jsou tak
často používané instrukce, že je autoři procesorů dělají jednotaktové.
Ostatně jsem je započetl do předchozího výpočtu.