Každý dneska šílí po grafice, okýnkách, miliónech barev a já nevím o čem ještě. Pak se diví, že jeho Pentium to nějak nezvládá, že se jeho prográmek cuká avůbec, že to není hezké. Vraťte se tedy ke kráse textového režimu. Vemte si Výheň. Ta je celá v texťáku a je přitom hezká, plynulá a bez okýnek. Prostě texťák má svoje kouzlo. Lidi ale nemají texťák moc rádi, připadá jim strohý, jednoduchý a stále stejný. Berou všechny jeho kvality, ale neumí jich využít. My se teď na texťáky podíváme, takže hurá na to. Nejprve kde ho máme. Textový mód se nám nachází ( mluvím o VGA adaptérech ) v oblasti od B800:0000 dál. Trochu jinak je to u Herkulů, ale pochybuji, že ho ještě někdo vlastní ( kromě Ferdy, a ten ho má kvůli dual - monitor - systému ), ale budiž. Herkulesovi začíná videopaměť na BC00:0000. Samozdřejmě se rozdílných počátků dá využít právě dual monitor systémem, ale je to trochu složitější, něž pouhý zápis. Vraťme se ale k normálnímu VGA adaptéru. Textová videopamět tedy začíná na adrese B800:0000. Skádá se vždy ze dvojic bytů. První byte je vždy znak a druhý byte je atribut. V atributu je vždy uložená barva znaku, barva pozadí a blikání. Vypadá asi takhle: Atribut bity 7 6 5 4 3 2 1 0 | | | | +---+---+---+-- Bity barvy + - +---+---+------------------ Bity pozadí* +------------------------------ Bit blikání Se 7mým bitem je bit ve kterém je uloženo, zda bude barva blikat či nikoliv. Je ale možné textový mód přepnout do režimu, kdy je sedmý bit použit jako bit pozadí a potom máme namísto osmi barev pozadí barev šestnáct. Hodnotu atributu tedy dostaneme vztahem: Barva_znaku + Barva_pozadí * 10h ( + 80h blikání ) Přičtením oněch 80h zapneme poslední bit a znak se rozbliká nebo pozadí bude světlé. Už víme jak vytvořit atribut. Toto je však pro ty z vás, co ho budou tvořit sami ( assembler a pod ). Pod Pascal je zlepšovák. Vrámci unity Crt existuje proměná Textattr, ve které je uložen aktivní atribut. Ten se mění příkazy TextColor a TextBackGround. Crt má samozdřejmě své konstanty, takže si nemusíte barvy pamatovat a můžete je rovnou psát slovy. Pro ty neznalejší z vás je tu tabulka barviček: Tmavé barvy a barvy pozadí Světlé barvy 0 - Black - Černá 8 - DarkGray - Tmavě šedivá 1 - Blue - Modrá 9 - LightBlue - Světle modrá 2 - Green - Zelená 10 - LightGreen - Světle zelená 3 - Cyan - Vyblitá ( ta 11 - LightCyan - Světle vyblitá vážně tak 12 - LightRed - Světle červená vypadá ) 13 - LightMagenta - Světle růžová 4 - Red - Červená 14 - Yellow - Žlutá 5 - Magenta - Fialová 15 - White - Bílá 6 - Brown - Hnědá 7 - LighGray - Světle šedivá 128 - Blink - blikání ( přičíst ) ( Omlouvám se čtenářům Výhně, ale fialovou neuvidíte, neb je Výhní rezervovaná jako barva pro tlačítka a paleta stále dělá fade in a out ). Teď už víte jak nastavit barvu. A jak vypsat znak na obrazovku. Lze to samodřejmě provést přes BIOS, ale je to pomalé a napřílad na přepis celé obrazovky to nestačí. O módech větších než 80*25 ani nemluvím. Co tedy zkusit zápis přímo do paměti? Známe místo, známe barvu, nic nám nebrání. Jak jsem se zmínil, byty jsou uspořádány výjmečně dle X a v pořadí znak, atribut, znak, atribut,... Pokud tedy chceme zapsat znak na Xtý řádek, Ytý slopec, zapíšeme ho do místa B800:(X+Y*šířka_obrazovky)*2. Atribut bude na následujícím bytu, tedy na B800:(X+Y*šířka_obrazovky)*2+1. V pascalu bude přiřazení pro mód široký Š vypadat asi takhle: Procedure PutCharXY ( X,Y : Byte ; Ch : Char ; Color,Back : Byte) ; Begin Mem [B800:(X+Y*Š)*2] := Ord ( Char ) ; Mem [B800:(X+Y*Š)*2+1] := Color+Back*10h ; End ; K čemu to je? Je to rychlejší než pascalské gotoxy a write a je možné zapisovat i za 25 řádek a 80 sloupec. Pro vás je však důležité umět dostat za 25 řádek i kurzor. K tomu již GotoXY užít musíme, napíšeme si ho ale sami, abychom nebyli omezeni Pascalem. Přerušení 10h ( služby obrazovky ) poskytuje službu 02h - nastav pozici kurzoru. Do registrů dh, dl se dá X, Y souřadnice, do BH stránka obrazovky, do které se má zapsat. V praxi to vypadá takhle: Var R : Registers ; Procedure GotoXY ( X,Y : Byte ) ; Begin With R Do Begin AH := 2 ; BH := 0 ; {případně aktivní stránka} DL := X ; DH := Y ; End ; Intr(10,R) ; End ; A nebo takhle: Procedure Gotoxy ( X,Y : Byte ) ; Assembler ; Asm mov ah,2 xor bh,bh { nebo mov bh,číslo_stránky } mov dl,x mov dh,y int 10h end ; Samozdřejmě lze zapsat i znak na místo kurzoru a provede se to opět přes služby obrazovky. Slouží k tomu funkce 09h s atributem nebo funkce 0ah bez atributu. Fce 0ah zachová atribut, který měl předchozí znak na tomto místě. Paskalisté prominou, ale dále budu uvádět pouze příklady v assembleru a jak na to s Pascalskými registry snad každý pochopí sám. Obě fce používají BH jako číslo stránky, AL jako hodnotu znaku ( ASCII ) a CX jako počet opakování. Fce 09h navíc čte z registru BL atribut znaku. V praxi tedy takto: Procedure WriteChar ( ASCII:Byte,C:Word /Attrib:Byte/ ;); Assembler; Asm mov ah,09h /mov ah,0ah/ mov al,ASCII mov cx,x xor bh,bh { mov bh,aktivní_stránka } /mov bl,attrib/ int 10h End ; Pozor. Pokud dáte do CX opakování, znak se sice vypíše několikrát vedle sebe, ale kurzor se neposune. Proto je to nepraktické, pokud po každé klávese nechcete posouvat kurzor o znak doprava. Nakonec si ukážeme, jak přes služby obrazovky vytisknout celý řetězec. Je k tomu zapotřebí funkce 13h. Zde se použijí registry AL jako formát zadávaného řetězce ( osvětlím později ), ES:BP začátek řetězce, CX délka, DL a DH jako souřadnice počátku zobrazení a BH jako stránka. Řetězec je možné zadat ve čtyřech formátech: Hodnota AL Formát zadání Formát výstupu 0 Atribut bere z BL Nehýbe kurzorem 1 Atribut bere z BL Kurzor na konec řetězce 2 Formát znak, atribut, znak, atribut, .... Nehýbe kurzorem 3 Formát znak, atribut, znak, atribut, .... Kurzor na konec řetězce Příklad psát nebudu, protože je příliš mnoho parametrů a záleží na vás, co zvolíte za konstanty a co za parametry. Dovolím si ale upozornit, že pointer v paskalu ukazuje na nultý znak stringu, kde je uložena délka. Je proto nutné do CX načíst právě tento byte a potom se posunout o byte dál. Někde v procedůrce by tedy mělo být: mov ax,seg STRING mov es,ax { do ES nejde zapsat přímo } mov bp,offset STRING xor ch,ch { vynulovat vrchní část CX } mov cl,[es:bp] { zapsat do CX délku } inc bp { posunout offset na začátke STRINGu } Potom je již paskalský string reprodukován správně. Přerušení 10h samozdřejmě nabízí ještě řadu dalších služeb. Ty však nebudu zmiňovat, nejsou tak důležité, a kdo je bude potřebovat, ten si je dokáže zcela určitě najít. Tak. Celou dobu jsem se snažil vám ukázat, že nejste omezeni žádným makrojazykem a můžete si psát co chcete kam chcete do paměti. K čemu vám to ale bude, když vám na monitoru stále bude oxidovat režim 80*25? Takže se podíváme na nějaké neobyčejné textové režimy . výheň