Vidíte, že použití programů z ROM nemusí být zrovna to pravé ořechové, proto si ukážeme vlastní program na tisk znaků, který si můžete ještě nějak vylepšit. Výhoda je třeba v tom, že se nemusíme starat o otevírání správného kanálu nebo si můžeme definovat vlastní font a nemusíme být odkázání na font v ROM.
Vyzkoušejte tento základní prográmek a studujte rozdělení obrazovky:
cpu z80undoc
relaxed on
org 25000
ld hl,16384 ;nastav pozici
ld (POZICE),hl ;uloz ji do promenne
ld a,'A' ;znak A
call znak ;vytiskni
ld a,'B' ;znak B
call znak ;vytiskni
ret ;vrat se
ZNAK sub 32 ;odecti tak aby znak byl od nuly
ld l,a ;pismenko je nyní v HL
ld h,0 ;horni byte na nula
add hl,hl ;nasob 2x
add hl,hl ;nasob 4x
add hl,hl ;nasob 8x
ld de,FONT ;adresa fontu
add hl,de ;adresa predlohy pismenka = font + (8*(znak-32))
ld de,(POZICE) ;adresa pozice na obrazovce
push de ;musi byt presne v atributu
ld b,8 ;smycka s 8 pruchody
znak1 ld a,(hl) ;vezmi predlohu znaku
ld (de),a ;dej ji do obrazovky
inc hl ;pozun se na dalsi byte predlohy
inc d ;posun se o byte dolu
djnz znak1 ;opakuj 8x - vykresli cele pismenko
pop de ;vyzvedni adresu pozice
inc e ;posun ji o jeden znak vpravo
jr nz,znak2 ;pokud neni prekrocena tretina, tak je to OK
ld a,d ;vyssi bajt adresy do A
add a,8 ;pricti tretinu obrazovky
ld d,a ;a dej ji zpet
cp 88 ;pokud by presahla treti tretinu,
jr c,ZNAK2 ;nepresahne, skok
ld d,64 ;tady presahne, tak nastav prvni tretinu
ZNAK2 ld (POZICE),de ;uloz pozici na priste
ret ;navrat zpet
POZICE dw 16384 ;zde se uklada pozice
FONT equ 15616 ;zde je definovan font
Jesti tedy někdo touží po vlastním fontu, musí si jej nakreslit (třeba v Art studiu) a ve zdrojáku na něj odkázat třeba: FONT binclude font.bin nebo jej může mít definován jako blok čísel pomocí db, asi takto:FONT db 0,60,66,….
Zde se hodí vysvětlit, jak jsme došli k adrese, kde je uložena předloha toho konkrétního písmenka: Na adrese 15616 začíná předloha znaku “ “ (mezera). Tento znak má kód 32 (dekadicky). Každé písmenko má 8 bajtů dlouhou předlohu, tedy musíme od písmenka odečíst číslo 32 (aby se to vyrovnalo), vynásobit 8x a přičíst 15616.
Tento prográmek je možné ještě vylepšit. třeba výpočet adresy předlohy by šel zkrátit tak, že se nebude odečítat 32 a místo adresy FONT se zadá FONT-(32*8). Program tiskne tak, že to, co bylo na obrazovce jako podklad, se smaže a písmenko se vykreslí. Toto by se dalo taky velice snadno zařídit:
ld b,8 ;smycka s 8 pruchody
znak1 ld a,(de) ;vezmi byte z obrovky
or (hl) ;pridej k nemu predlohu
ld (de),a ;dej to vsechno do obrazovky
inc hl ;pozun se na dalsi byte predlohy
inc d ;posun se o byte dolu
djnz znak1 ;opakuj 8x - vykresli cele pismenko
Zkuste instrukci or (hl) nahradit xor (hl) nebo and (hl).
Taky vidíme, že zadání polohy na obrazovce není nic moc. Zadávat přímou adresu a navíc tak, aby byla vždy do atributu není zrovna to pravé. Takže zkusíme někde vyšťourat program, který nám adresu vypočte podle souřadnic (řádek,sloupec) zadaných v registrech b a c (b=řádek 0-23, c=sloupec 0-31):
ADRSET ld a,c ;sloupec
add a,a ;nasob 8x
add a,a
add a,a ;dostaneme pixelovou pozici
ld c,a
ld a,b ;radek
add a,a
add a,a
add a,a ;opet pixel
call $22B0 ;prepocet pixelovych souradnic na adresu v pameti
ld (POZICE),hl ;uloz do promenne
ret
Takze volani programu by mohlo vypadat asi takto:
START ld b,10 ;b=radek, c=sloupec
ld c,5 ;nebo kratsi zapis (ld bc,10*256+5)
call ADRSET ;nastav pozici
ld a,'A' ;znak k vytisteni
call ZNAK ;vytiskni
ret
Další vychytávkou by mohlo být nastavení barev. Musíme tedy adresu atributu na obrazovce vypočítat. Počítání je celkem jednoduché, dolní byte adresy se nemění, horní upravíme na číslo třetiny a k němu přičteme horní byte adresy začátku atributů ($5800).
ATTRIB ld hl,(pozice) ;precti adresu pozice
ld a,h
sub $40 ;posunuti pocatku adresy do nuly
rrca ;deleni 8
rrca
rrca
and 3 ;v A je nyni cislo tretiny
add a,$58 ;posun do attributu
ld h,a ;do vyssiho bajtu, nizsi je stejny
ld a,(COLOR) ;uloz do promenne
ld (hl),a
ret
COLOR db 0
Úprava programu je pak asi taková, že po vykreslení znaku (po instrukci djnz znak1 napíšte call ATTRIB a je to hotové.
Domácí úkol bude dnes o hodně složitější a budu trvat na tom, aby jej alepoň někdo, kdo měl zájem na tomto seriálu, splnil. Rutina ZNAK umí tiskat do attributových souřadnic. Navrhněte řešení, které by umělo tiskat písmenko s dvojitou výškou do libovolné polohy po ose y (po ose x ne, to by vyžadovalo mnohem více prostoru). Tedy tak, abych programu ADRSET zadal číslo řádku od 0 do 184 a číslo sloupce od 0 do 31 a on dokázal na tuto pozici znak vytisknout (bez atributů). A aby to nebylo zas tak složité, napíši sem rutinu, která posune registr de o bajt níže v obrazovce, nehledě na její rozložení třetin.
DOWNDE inc d ;posun v ramci textoveho radku
ld a,d ;je jednoduchy
and 7 ;neni-li prekrocen
ret nz ;vrat se zpet
ld a,e ;prechod mezi textovymi radky
add a,32 ;pokud pri pricitani dojde k preteceni
ld e,a ;je to signal, že doslo k prechodu
ld a,d ;mezi tretinami
jr c,DOWNDE2 ;hotovo a tedy odskok
sub 8 ;jeste zbyva uprava horniho bytu
ld d,a ;pri prechodu mezi tretinami
DOWNDE2 cp 88 ;test opusteni obrazovky
ret c ;nedoslo, navrat
ld d,64 ;doslo, uprav na zacatek
ret ;navrat
O splnění úkolu mě informujte mailem a poštete mi zdrojový kód řešení.

6 komentáre na “2.díl: opět znaky”
Je nám líto, ale formulář pro přidávání komentářů je momentálně uzavřen.
Uvedene rutiny sa daju este trochu vylepsit 🙂
1) Ak font zacina na adrese delitelnej 8 (co nebyva problem), mozeme zrychlit slucku "znak1" tak, ze namiesto INC HL pouzijeme INC L (nizsi bajt nema sancu pretiect).
2) Pri nasobeni znaku 8x mozeme vyuzit fakt, ze ASCII kody su v intervale 0..127, takze prva iteracia nasobenia moze byt ADD A,A (nehrozi pretecenie). Potom moze vypocet adresy vyzerat takto:
ADD A,A
LD L,A
LD H,START
ADD HL,HL
ADD HL,HL
Tu ale musime pozorne volit adresu fontu. V tomto pripade sa font musi nachadzat na adrese (4 * START) * 256. Inymi slovami, jeho adresa musi byt zaokruhlena na cele kilobajty. Zaroven ale usetrime register DE, takze ho uz nemusime cucat z pameti, ale mozeme ho pouzit rovno ako parameter.
Děkuji Bazemu za komentář a chci dodat, že všechny zde uvedené rutiny se dají vždy nějak vylepšit.
Poznávám v tom seriálu Universumovo Asembler a ZX Spectrum, ale jinak super. Proč stále vymýšlet všechno znova, když se dá celkem dobře recyklovat :). Držím palce.
Jo. Trumfnout tuto knihu se uz neda, tak ji alespon vyuzijeme. Pridame neco vlastniho, neco opiseme a neco vynechame a je to hotove. Pokud by ses chtel pridat mezi lektory, neni problem, rad to uvitam, alespon mi zbyde vice casu na neco jineho.
Nebo, pokud mas namet na nejaky dalsi dil, klidne posli. Nebo posli i cely text. Cokoliv noveho vitam.
Ja som si tiez spravil domacu ulohu o tej dvojnasobnej vyske znakov, ale v BASICu. To mna asi zabijete lebo to co tu pisem sem ani nepatri.
A este chcem doplnit ze s vyuzitim prikazu PLOT x, y, cize som to mal ovela jednoduchsie nez s pouzitim POKE v BASICu.