Příklad VBI vs DLI

raster/c.p.u., 2009

Že může DLI přerušit rozpracované VBI jsme si ukázali v předchozím příkladě. Abych však jednou provždy demonstroval, že DLI a VBI jsou zcela rovnocenná přerušení, dovolím si v tomto příkladě naopak přerušit VBI přerušením rozpracovanou DLI rutinu. Slabším povahám se z téhle představy může udělat nevolno, vždyť i samotný OS ROM budeme muset trošku přesvědčit, aby našemu záměru nebránil. ;-)

Modré mihotání opět vyznačuje práci hlavní rutiny. Ta je v dolní části přerušená pomocí DLI, které nastaví hnědou barvu a odpočítává 70 mikrořádků. Na dolní hraně je však jeho činnost přerušena VBI přerušením, které 700x opakuje cyklus s náhodnou změnou barvy v zelených odstínech, takže jeho práce je dost dlouhá aby byla vidět i na následujícím snímku v horní části. VBI na svém konci nastaví černou barvu a procesor se vrátí k pokračování v rozpracovaném DLI a dopočítá ještě zbývající řádky. Ty jsou vidět jako černý úsek (neboť barvu opakovaně nenastavuje) a na závěr zobrazí bílou linku. Poté opět dostane slovo hlavní rutina se svým modrým mihotáním.

Teď ještě musím vysvětlit zmínku o OS ROM a jeho snahám znemožnit výše uvedený experiment. Vaší pozornosti doporučuji zajímavou část jeho kódu:

c118    txs
c119    lda $0104,x
c11c    and #$04
c11e    beq $c125
c120    jmp $c28a
c125    ...

Jak vidíte, bere ze zásobníku čtvrtou hodnotu pod aktuálním vrcholem a ověřuje, zda je její bit 2 nulový. Pokud ano, pokračuje normálně ve své další práci, pokud je však nenulový, skáče na $c28a, kde je okamžité ukončení (tedy i bez skoku na vektor naší VBI rutiny). Když jsem tohle prvně viděl, nechápal jsem, co to má znamenat, než mi došlo, co je zač ona hodnota 4 bajty pod vrcholem zásobníku. Takže, úplně na vrcholu se nachází uschovaný Y registr, pod ním X, třetí je A. Pod nimi je status flag, který se tam uložil právě v okamžiku, kdy se VBI vyvolalo (dále jsou dva bajty návratové adresy, ale ta nás teď nezajímá). Onen sledovaný bit 2 odpovídá "I" interrupt disable bitu. OS ROM tedy kontroluje, jaký byl stav flagu "I" před vyvoláním VBI a byl-li nastaven, ukončuje svou činnost stejně jako při aktivované návěsti CRITIC.

Nyní již víme, že nám tedy v našem příkladě stačí instrukcí CLI vynulovat v DLI rutině interrupt disable flag a OS ROM nebude proti vykonání své kompletní práce včetně volání naší VBI rutiny nic namítat. Podstatné však je, že onen interrupt disable flag vůbec nezabraňuje vyvolání samotného VBI přerušení (patřícího spolu s DLI do skupiny NMI přerušení), pouze OS ROM ho sleduje a podle toho mění své chování - je to tedy záležitost čistě programová, nikoli hardwareová. (Poznámka: Pokud si budete NMI přerušení kompletně obsluhovat vlastním kódem, je jen na vás, zda si tam takovou podmínku dáte či nikoliv.)

Opět se nabízí otázka, k čemu je dobré tohle všechno vědět? Tak na to si odpovíte sami, až budete pár hodin pátrat, jakto že se z ničeho nic přestala provádět vaše doposud skvěle fungující VBI rutina, nebo proč se ty zatrolené dolní registry nepřepisují do horních sledujících. Nemáte náhodou nějaké DLI příliš nízko na obrazovce a/nebo není tak dlouhé, že se jeho činnost nedokončí před dosažením dolní hrany vykreslovaného obrazu? Pokud ano, vše je rázem jasné.