AMIGA REVIEW online
  Uvodná stránka     Software     Hry     Obaly     Download     Kniha návštev     Amiga na PC     Amiga Forever  

Assembler a system

Jan Hlavatý

Tentokrát se podíváme na způsob předávání parametrů, který byl do systému zaveden s příchodem OS verze 2.0, a to tzv. TAGS. O co jde?

Operační systém Amigy se neustále vyvíjí, přitom ale je nanejvýš žádoucí, aby veškeré programové vybavení určené pro starší verze systému zůstalo i nadále použitelné. Jedním z hlavních problémů v této oblasti jsou změny datových struktur používaných pro předávání dat - obvykle jsou ke stávajícím strukturám přidány další položky, nebo je dříve nevyužitým položkám přiřazován nový význam. Starší programy pak přirozeně o nových změnách neví a vznikají problémy např. při dynamické alokaci struktur - starší program alokuje strukturu která byla používána v době jeho vzniku a ta může být odlišná od právě používané verze. Tento problém se podařilo odstranit právě pomocí TAGů. Vezměme si například takové otevření okna na Workbenchi. Starý způsob předávání parametrů systémovým funkcím spočíval ve vyplnění určité datové struktury požadovanými hodnotami. Tato struktura pak byla předána funkci. Význam vyplněných dat určovalo jejich UMÍSTĚNÍ ve struktuře - v našem případě například funkce OpenWindow() ví, že v předávané struktuře NewWindow jsou na začátku dva wordy označující X a Y souřadnice umístění otevíraného okna a za nimi (kromě jiného) další dva wordy udávající jeho rozměry. Kdybychom chtěli strukturu NewWindow rozšířit, narazíme na problém, protože starší programy vyplní jen tu "starou" část a nové položky budou nevyplněny, t.j. budou obsahovat náhodná data. Jak tento problém obejít? Je prostě třeba ke každé předávané hodnotě také napsat, která že to je hodnota. Je to jako bychom místo "0, 10, 320, 100" napsali "x=0, y=10, šířka=320, výška=100". V praxi se tento způsob předávání parametrů řeší pomocí dvojic longů, nazývaných TAGs. Hodnota prvního longu určuje význam druhého longu. Takto je struktura TAGu definována v systémovém include souboru "utility/tagitem.i":
STRUCTURE Tagitem,0 ULONG ti_Tag typ hodnoty ULONG ti_Data ; hodnota LABEL ti SIZEOF
Tagy se používají ve skupinách za sebou (taglistech), poslední je ukončovací tag se speciální hodnotou ti_Tag. Je možné i propojit víc oddělených skupinek do jednoho velkého taglistu. Funkce zpracovávající data z taglistu se řídí dvěma pravidly:
1. Najde-li funkce tag který nezná, ignoruje ho. Tak je možné funkci použít i když program zná a používá novější tagy než Funkce (i když nemusí dělat úplně totéž co by udělala novější funkce, která tag zná).
2. Nenajde-li funkce v dodaném taglistu některý méně důležitý tag (tj. ne nezbytně nutný pro funkci), vhodným způsobem si tento parametr "domyslí" (tj. přiřadí mu implicitní hodnotu). Takto je možné danou funkci rozšiřovat aniž by o tom starší programy musely vědět - funkce pro ně zůstane použitelná a nemusí se vytvářet funkce nová.
Na nejnižší úrovni si systém rezervuje některé hodnoty tagů pro "administrativu" taglistů:
TAG_DONE, TAG_END (hodnota 0) ukončují celý taglist. V tomto případě je jedno, jakou hodnotu bude mít
ti_Data tohoto tagu.
TAG_IGNORE (hodnota 1) - obsah ti_Data je ignorován, prohledávání pokračuje následujícím tagem.
TAG_MORE (hodnota 2) - pomocí tohoto tagu můžete propojit více samostatných bloků tagů dohromady. ti_Data obsahuje adresu začátku dalšího taglistu, kde má prohledávání taglistu pokračovat (podobně jako instrukce JMP).
TAG_SKIP (hodnota 3) - přeskočit tolik následujících tagů, kolik je hodnota ti_Data.
Ostatní hodnoty jsou pak používány různými částmi systému, případně i uživatelskými programy. Obecně všechna nesystémová ID tagů by měla být větší než TAG_USER ($80000000) a neměla by využívat bity 16-30 (nechat nulové).
Použití tagů bychom si mohli demonstrovat na funkci intuition.library OpenScreenTagList().
OpenScreenTag List(A0: NewScreen,A1 :TagItems)->D0:Screen
Tato funkce vyžaduje v A0 pointer na strukturu NewScreen, která může být použita jako základ popisu otevíraného screenu, a v registru A1 ukazatel na taglist s údaji. Pokud chceme použít jen taglist může být A0 NULL. Taktéž pokud nechceme použít taglist, může být v A1 NULL.
Tzv. BODL tagy jsou tagy, jejichž hodnota může nabývat jen dvou hodnot - TRUE (nerovno nule) a FALSE (nula). Tady je seznam tagů použitelných pro tuto funkci který je definovaný v include souboru "intuition/screens.i":
SA_Left, SA_Top, SA_Width, SA_Height - X, Y, šířka a výška screenu. Pokud neuvedete žádný z těchto tagů, bude screen velký přesně jako celá viditelná oblast obrazovky (nejlépe použijete-li i SA_Overscan).
SA_Depth - počet bitplánů screenu (hloubka). Počet barev screenu je 2 na n, kde n je hloubka. (implicitně 1) SA_DetailPen, SA_BlockPen implicitní barvy použité pro kreslení textu a pozadí lišty screenu
SA_Title - ukazatel na titul screenu (implicitně NULL)
SA_Font - font pro screen (ukazatel na TextAttr).
SA_BitMap - ukazatel na BitMap pro CUSTOMBITMAP.
SA_ShowTitle - (BOOL) - zapíná zobrazování lišty screenu (implicitně TRUS - zobrazuje)
SA_Behind - (BOOL) - má-li se screen otevřít pod všemi ostatními screeny - t.j. nebude vidět, dokud ho nepřesunete dopředu. To je možno využít pokud chcete například na screen něco nakreslit než ho uživatel uvidí. (implicitně FALSE)
SA_Quiet - (BOOL) - zakáže kreslení titulu a gadgetů screenu. (implicitně FALSE)
SA_Type - typ otevíraného screenu PUBLICSCREEN nebo CUSTOMSCREEN.
SA_DispIayID - mole ID zobrazovacího módu který má být použit. Definovány v "graphics/modeid.i" pro OS 3.0+, nebo v "graphics/displayinfo.i" pro OS 2.0. Pomocí tohoto tagu si můžete otevřít screen třeba v NTSC.
SA_Overscan - ti_Data obsahuje identifikátor módu overscanu který má být použit - jeden z OSCAN_TEXT, OSCAN_STANDARD, OSCAN_MAX, OSCAN_VIDEO.
SA_DClip - ti_Data je pointer na strukturu Rectangle přesně specifikující overscan screenu. Normálně je jednodušší použít SA_Overscan.
SA_AutoScroll - (BOOL) - automatický scrolling screenu většího než je zobrazitelná část
SA_PubName - jméno public screenu. Zároveň indikuje že screen má být public screen. Ke zpřístupnění public screenu je třeba použít ještě PubScreenStatus().
SA_Pens - ukazatel na pole s čísly barev pro DrawInfo screenu. Zároveň zapíná "new look" vzhled screenu (3D).
SA_PubTask - pro public screen - task kterému bude nastaven signál až ze screenu zmizí poslední cizí okno (implicitně task který volá OpenScreenTagList())
SA_PubSig - pro public screen - číslo signálu pro SA_PubTask
SA_Colors - ti_Data ukazuje na pole struktur ColorSpec s definicí palety screenu
SA_FullPalette - (BOOL) - nastavit všech 32 barev podle preferencí (implicitně FALSE)
SA_ErrorCode - ti_Data je pointer na ulong kam se uloží případný důvod selhání otevření screenu nebo 0 (viz OSERR_... z intuition/screens.i)
SA_SysFont - použít některý implicitní font: 0 pro topaz.8, 1 pro Font WorkbenchScreen.
OS 3.0 umožňuje připojit ke screenu (parent) jiný (child) screen tak, že jsou navzájem spojeny při přesouvání dopředu nebo dozadu, případně při stažení dolů. Tyto 3 tagy umožňují spojení screenů:
SA_Parent - (OS 3.0) ti Data obsahuje pointer na už otevřený screen, ke kterému má být nový screen připojen.
SA_FrontChild - (OS 3.0) ti_Data obsahuje pointer na už otevřený screen, který má být připojen k novému screenu (před něj)
SA_BackChild - (OS 3.0) ti Data obsahuje pointer na už otevřený screen, který má být připojen k novému screenu (za něj)
SA_BackFill - (OS 3.0) ti Data obsahuje pointer na hook pro vyplňování pozadí screenu (speciální funkce, pomocí které je například realizován pattern na pozadí workbenche)
SA_Draggable - (OS 3.0) (BOOL) smí-li uživatel screen stáhnout dolů. Jeli false, screen stáhnout nejde. U child screenů (připojených k parent screenům) se tímto zakáže hýbání s child screenem vůči parent screenu. Oba screeny se pak jeví jako jeden screen.
SA_Exclusive (OS 3.0) (BOOL) - screen nebude nikdy sdílet displej s jiným screenem
SA_SharePens (OS 3.0) (BOOL) nastavit na TRUE budete-li používat sdílení barev
SA_Colors32 - (OS 3.0) - Paleta barev ve formátu jako pro LoadRGB32() z graphics.library
SA_Interleaved - (OS 3.0) (BOOL) pokusit se vytvořit bitplány screenu v interleaved formátu (zmenšuje blikání např. při scrollování velkých ploch)
SA_VideoControl - (OS 3.0) - taglist který bude po otevření screenu předán funkci VideoControl() - např. pro zapnutí sprajtů v okrajích...
SA_ColorMapEntries - (OS 3.0) - počet položek ColorMap screenu (je-li potřeba víc)
SA_LikeWorkbench - (OS 3.0) (BOOL) - pokusit se otevřít screen stejný jako je Workbench. Nemusí se povést. Ostatní tagy přebíjí takto získané hodnoty.
SA_MinimizeISG - (OS 3.1) minimalizovat mezeru mezi screeny
Abyste si s tím mohli pohrát, připravil jsem vám malinký prográmek, který otevře screen pomocí OpenScreenTagList(), počká 5 sekund a pak screen zavře. Na začátku je konstanta MODEID - je jí přiřazena hodnota $00019020, což je ModeID pro NTSC, super-hires. Tento mód vám nebude fungovat, pokud nemáte instalován driver pro monitor NTSC! Zkuste si dosadit i jiné hodnoty, např. $00000000 pro LoRes v implicitním módu (pravděpodobně PAL), $00008000 pro HiRes... viz příslušné include (graphics/modeid.i pro OS 3.0). Všimněte si, že v tomto případě jsou automaticky nastaveny rozměry screenu - to lze např. využít aby váš program měl k dispozici co největší ale přitom viditelné místo na monitoru - v závislosti na nastavení preferencí overscanu. Jaké rozměry váš screen ve skutečnosti má zjistíte snadno po otevření screenu ze struktury Screen - sc_Width je šířka a sc_Height je výška. Tamtéž lze zjistit i jiné užitečné údaje.
Tagy jsou v novém OS velice rozšířené a jsou mj. základem pro objektově orientovaný přístup k intuitionu, jako jsou BOOPSI gadgety nebo datatypy, právě pro svou flexibilitu a snadnost rozšíření.

HOOKS
U SA_Backfill jsem se zmínil o hooku. Co to je? V některých případech potřebují systémové rutiny od uživatele nějakou funkci. Například file requester z asl.library umožňuje při načítání výpisu directory volajícímu programu rozhodnout, zdali se má právě načtená položka directory v requesteru zobrazit či nikoliv. Program poskytne tuto funkci prostřednictvím tzv. callback hooku. V podstatě váš program předává systému adresu vaší funkce, která bude systémem volána ve vhodném okamžiku. Je to jakýsi "opačný" způsob, obvykle voláte vy rutiny systému a ne systém vaše. Hook je struktura, která vypadá takto (utility/hooks.i):
STRUCTURE HOOK,MLN_SIZE APTR h_Entry ; assembler entry point APTR h_SubEntry ; optional HLL entry point APTR h Data ; owner specific LABEL h SIZEOF
Program uloží adresu své rutiny do h_Entry. Když je funkce zavolána, A0 obsahuje ukazatel na hook, A1 pointer na nějaká data a A2 pointer na objekt kterého se volání týká.

incdir incl:
include dos/dos lib.i
include exec/exec lib.i
include intuition/intuition lib.i
include intuition/screens.i
MODEID = $00019020 ;ntsc, superhires
section prg,code
START move.l 4.w,a6
lea intname(pc),a1
moveq #37,d0
jsr _LVOOpenLibrary(a6)
move.l d0,intbase
beq .fail1
lea dosname(pc),a1
moveq #37,d0
jsr _LVOOpenLibrary(a6)
move.l d0,dosbase
beq .fail2
move.l intbase(pc),a6
sub.l a0,a0
lea testtags(pc),a1
jsr _LVOOpenScreenTagList(a6)
move.l d0,screen
beq .fail3
move.l dosbase(pc),a6
move.l #5*50,d1
jsr _LVODelay(a6)
move.l intbase(pc),a6
move.l screen(pc),a0
jsr _LVOCloseScreen(a6)
.fail3 move.l 4.w a6
move.l dosbase(pc),a1
jsr _LVOCloseLibrary(a6)
.fail2 move.l intbase(pc),a1
jsr _LVOCloseLibrary(a6)
.fail1 moveq #0,d0
rts
cnop 0,4
testtags dc.l SA_Overscan,OSCAN_TEXT
dc.l SA_Depth,2
dc.l SA_Title,title
dc.l SA_Pens,pens
dc.l SA_DispIayID,MODEID
dc.l TAG_END
intbase dc.l 0
dosbase dc.l 0
screen dc.l 0
pens dc.w -1
intname dc.b "intuition.library,0
dosname dc.b "dos.library",0
title dc.b "pokusny screen",0

Vytlačiť článok


© ATLANTIDA Publishing Všechna práva vyhrazena.
Žádna část nesmí být reprodukována nebo jinak šířena bez písemného svolení vydavatele.



Amiga na Vašem PC rychle, snadno a zdarma!


none

AMIGA REVIEW

57 ( 11-12 / 2000 )
56 ( 9-10 / 2000 )
55 ( 7-8 / 2000 )
54 ( 5-6 / 2000 )
53 ( 3-4 / 2000 )
52 ( 1-2 / 2000 )
 
51 ( 12 / 1999 )
50 ( 11 / 1999 )
49 ( 10 / 1999 )
48 ( 9 / 1999 )
46-47 ( 7-8 / 1999 )
45 ( 6 / 1999 )
44 ( 5 / 1999 )
43 ( 4 / 1999 )
42 ( 3 / 1999 )
41 ( 2 / 1999 )
40 ( 1 / 1999 )
 
39 ( 12 / 1998 )
38 ( 11 / 1998 )
37 ( 10 / 1998 )
36 ( 9 / 1998 )
35 ( x / 1998 )
34 ( x / 1998 )
33 ( 1-2 / 1998 )
 
32 ( 11-12 / 1997 )
31 ( 9-10 / 1997 )
30 ( 7-8 / 1997 )
29 ( 6 / 1997 )
28 ( 5 / 1997 )
27 ( 4 / 1997 )
26 ( 3 / 1997 )
25 ( 2 / 1997 )
24 ( 1 / 1997 )
 
23 ( 12 / 1996 )
22 ( 11 / 1996 )
21 ( 10 / 1996 )
20 ( 9 / 1996 )
18-19 ( 7-8 / 1996 )
17 ( 6 / 1996 )
16 ( 5 / 1996 )
15 ( 4 / 1996 )
14 ( 3 / 1996 )
13 ( 2 / 1996 )
12 ( 1 / 1996 )
 
11 ( 12 / 1995 )
10 ( 11 / 1995 )
9 ( 10 / 1995 )
8 ( 9 / 1995 )
7 ( 7 / 1995 )
6 ( 5 / 1995 )

ATLANTIDA NEWS

5 ( 3 / 1995 )
4 ( 1 / 1995 )
 
3 ( 11 / 1994 )
2 ( 9 / 1994 )
1 ( 7 / 1994 )
0 ( 5 / 1994 )