Assembler (nejen) pro pokročilé

MULTITASKING na 8-bitovém Atari

Radek Štěrba

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ů:

  1. Rutina pro VBI musí být konstruována tak, aby byla volně průchozí. Klasická struktura programu s prováděním něčeho v cyklu s čekací pauzou není možná. Je tedy nutné program přetvořit do podstatně složitější a nepřehlednější struktury.
  2. Pro každý průchod touto rutinou máme k dispozici pouze cca 20000 strojových cyklů.
  3. Klasickým způsobem můžeme nechat běžet ve VBI pouze jeden program. Pokud bychom potřebovali postupně různě spouštět a vypínat několik rutin, které mají běžet na pozadí, struktura programu by se zkomplikovala ještě více.

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,

Radek Štěrba - RASTER 1996

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 # 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.