Mýty a pověry o systémovém VBI

aneb

Odpojovat nebo neodpojovat?

Jedna ze základních pouček, která se mezi programátory strojů Atari XL/XE traduje, zní: potřebuješ-li z mašiny vytřískat maximální výkon, musíš odpojit ROMku a napsat si vlastní obsluhu NMI. Důvodem pro toto trzení je fakt, že systémová VBI rutina dělá spoustu zbytečností, které stojí hromadu drahocenných taktů procesoru 6502.

Pokud ovšem člověk současně nepotřebuje využívat i oněch 14 kB paměti RAM (prostory $C000-$CFFF a $D800-$FFFF), kterou odpojením ROMky získá, lze výše uvedené tvrzení s úspěchem napadnout. Dokonce si dovolím tvrdit, že poté může být za určitých okolností výhodnější nechat ROMku v provozu a s problémem se poprat jinak.

Nejprve, jak to celé funguje. VBI neboli Vertical Blank Interrupt se vyvolá vždy jednou za snímek a systémová rutina na jeho obsluhu skutečně sežere relativně dost času. Úžasní autoři neméně úžasného osmibitového Atari ovšem mysleli na všechno a uživateli poskytli mocné nástroje, jak vše uzpůsobit obrazu svému.

Řeč je o vektorech VVBLKI (Vertical Blank Immediate) a VVBLKD (Vertical Blank Deffered) na adresách $0222 + $0223, respektive $0224 + $0225. Právě přes ně se typicky řeší obsluha těch částí kódu, které je nutno pravidelně volat, přičemž většinou se používá VVBLKD ukončené instrukcí JMP $E462. Nastavování těchto vektorů se provádí přes notoricky známé JSR $E45C.

Je ovšem zcela zásadní mít stále na paměti, že odskoky na vektory VVBLKI a VVBLKD jsou součástí jedné jediné systémové VBI rutiny! Nenechme se zmást všemi těmi učenými Vertical Blank názvy. Atárko neprovádí dvě či tři různá VBI přerušení nebo kolika se méně zkušený uživatel může dopočítat.

Ve skutečnosti zpracování požadavku na VBI probíhá při zapnuté ROMce v rámci jedné akce ve třech po sobě následujících krocích:

  1. úschova registrů,
  2. skok na vektor VVBLKI,
  3. skok na vektor VVBLKD.

To samozřejmě vyžaduje, aby VVBLKD část kódu na závěr obnovila hodnoty registrů a poté ukončila obsluhu přerušení pomocí instrukce RTI. Což je přesně to, co dělá u XL/XE strojů kratičký kousíček kódu na adrese $C28A, kam také defaultně vektor VVBLKD směřuje.

Vlastní "nabubřelá" systémová VBI rutina, která je mnoha programátorům takovým trnem v oku, začíná u XL/XE mašinek od adresy $C0E2. A právě sem po zapnutí počítače ukazuje vektor VVBLKI, změnou kterého dosáhneme téhož, jako kdybychom ROMku shodili a obsluhu VBI si udělali zcela po svém.

Stačí pouze na konci naší VVBLKI rutiny nepředat přes JMP $E45F činnost zpět systému, nýbrž jednoduše obnovit registry a vše ukončit přes RTI. Toto elegantní řešení nám zajistí jednak maximální využití času procesoru pro kód mimo VBI a druhak nám zůstane k dispozici celá ROMka se spoustou velmi užitečných funkcí.

Je proto dle mého názoru vždy případ od případu zvážit, zda je nutné ROMku za účelem získání co nejvyššího počtu taktů pro svoje účely opravdu odpojovat. Přiznám se, že na počátku své programátorské kariéry jsem tak vždy bez přemýšlení činil a teprve až pochopení celé problematiky obluhy VBI mne přimělo dívat se na tuto otázku z trošičku odlišného pohledu.

Snad tento krátký text přiměje k zamyšlení i všechny dva vážené čtenáře Flopu. :)

F.