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 #<RUTINA
LDY #>RUTINA
Nastavení dolního a horního byte adresy počátku rutiny.
JSR RUNTASK
Vlastní spuštění rutiny.
Od tohoto okamžiku běží souběžně s dalším programem i příslušná rutina.
LDA #5
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.
Kompletní výpis všech podprogramů TaskManageru najdete v druhém samostatném článku.