Multitaskingem označujeme souběžné provádění více procesů (úloh, programů). Na větších počítačích ho považujeme za naprostou samozřejmost, ale podívejme se na možnosti využívat tuto techniku na 8-bitovém Atari.
Co je to VBI asi každý Atarista ví. Jedná se o možnost nechat volat danou strojovou rutinu každou 1/50 sekundy. Tato rutina pak běží jakoby na pozadí a používá se s oblibou například pro hraní hudby nebo pro rolující se text. S využíváním VBI však souvisí několik základních problémů:
Je jasné, že s bodem 2 toho moc neuděláme. Omezení je dáno tím, že naše rutina má být prováděna každou 1/50 sekundy a pokud překročíme oněch zmiňovaných 20tisíc cyklů, dojde k zablokování systému. Ostatní problémy, zmiňované v bodu 1 a 3 však lze programově obejít:
TaskManager je sada speciálních assemblerovských podprogramů mé vlastní výroby určená pro podporu nonpreemprivního multitaskingu na 8bitovém Atari. To dlouhé cizí slovo znamená, že jednotlivé rutiny pro souběžné zpracování musí splňovat určité podmínky, jinak dojde k "zamrznutí" systému.
Nejlepší je názorný příklad:
Mějme rutinu, která má provádět postupné zvyšování barvy textu na obrazovce s pauzou 1/10 sekundy.
RUTINA LDX #0 NA1 STX 709 ;barva textu LDA #5 ;5/50 = 1/10sec JSR PAU ;cekani A padesatin sec. INX JMP NA1 ;Podprogram PAU vypada takto PAU PHA LDA #0 STA 20 PLA PA2 CMP 20 BNE PA2 RTS
Pokud bychom chtěli, aby se tato rutina prováděla ve VBI, museli bychom ji upravit třeba takto:
RUTINA INC PP1 LDA PP1 CMP #5 BNE NA2 LDA #0 STA PP1 INC PP2 LDA PP2 STA 709 NA2
Dále by ještě bylo třeba vyhradit místo pro proměnné PP1 a PP2 a zařídit ještě před spuštěním rutiny jejich inicializaci (počáteční nastavení):
LDA #0 STA PP1 STA PP2 ;vyhrazeni mista musi byt mimo oblast programu PP1 .BYTE 0 PP2 .BYTE 0
Díky TaskManageru lze však ponechat původní tvar a pouze nahradit volání pauzy PAU jeho rutinou SLPTASK.
RUTINA LDX #0 NA1 STX 709 ;barva textu LDA #5 ;5/50 = 1/10sec JSR SLPTASK ;cekani A padesatin sec. INX JMP NA1
Vlastní použití TaskManageru je velice snadné. Sada jeho rutin je umístěna v knihovně TASKMNG.LIB, kterou lehce přidáme ke svému assemblerovskému programu. Kompletní řešení celého problému s jeho použitím by pak vypadalo takto:
;MULTI1.MAC ;Vyrobil Radek Sterba ;RASTER 1996 .OPT OBJ, NO LIST *= $5000 ; .INCLUDE #D:TASKMNG.LIB ; START TASKMANAGER 4 ; JSR INITTM ; LDA #0 LDX #RUTINA JSR RUNTASK ; LOOP ;zde muzeme provadet cokoliv dalsiho JMP LOOP ; RUTINA LDX #0 NA1 STX 709 ;barva textu LDA #5 ;5/50 = 1/10sec JSR SLPTASK ;cekani A padesatin sec. INX JMP NA1 ; *= $2E0 .WORD START
Nyní následuje komentář jednotlivých řádků programu:
.INCLUDE #D:TASKMNG.LIB
Přidá k vašemu programu knihovnu TASKMNG.LIB, která obsahuje makro TASKMANAGER a sadu podprogramů pro pohodlné řízení multitaskingu.
TASKMANAGER 4
Makro, definované v knihovně. Zajistí přikompilování všech rutin TaskManageru do vašeho programu. Číslo 4 označuje, že budeme moci používat současně maximálně 4 souběžné rutiny. (Pro tento příklad by stačilo i číslo 1.)
JSR INITTM
Inicializace TaskManageru. Bez tohoto volání nebude multitasking fungovat.
LDA #0
Budeme spouštět rutinu pod symbolickým číslem 0. (Protože jsme u makra TASKMANAGER uvedli číslo 4, mohli bychom spouštět celkem až 4 rutiny pod čísly 0,1,2 a 3.)
LDX # JSR RUNTASK Od tohoto okamžiku běží souběžně s dalším programem i příslušná rutina.
LDA #5 Kompletní výpis všech podprogramů TaskManageru najdete v druhém samostatném článku.
Nastavení dolního a horního byte adresy počátku rutiny.
Vlastní spuštění rutiny.
JSR SLPTASK
Volání podprogramu SLPTASK způsobí, že návrat z něj nastane až za dobu 5/50 sekundy (v Akumulátoru bylo číslo 5). Nejedná se však o klasické čekání, které by ve VBI rutině způsilo spolehlivé "vytuhnutí", ale o jakési "uspání" rutiny na danou dobu. Čekání tedy není aktivní a nezdržuje zbytek systému.