Použití ROMky nebo její obšlehnutí není jedniný způsob, jak testovat klávesy. Celý článek »
Pro napsání první samostatné aplikace nám ještě schází si vysvětlit, jak funguje vstup od uživatele: z klávesnice. Jestli jste četli Assembler a ZX Spectrum 1, tak dnešní díl nepřinese nic nového, většinou budu čerpat z této publikace a nakonec si ukážeme na ROM nezávislý program na čtení klávesnice, který je v MDOS3. Celý článek »
Před dalším dílem o klávesnici si musíme vysvětlit princip přerušení, k čemu slouží a jak jej využít. Celý článek »
Už jsme se naučili psát písmenka, už známe organizaci videoram, takže se můžeme pustit do něčeho zábavnějšího: psaní celých textů. Celý článek »
V dnešnom diely si ukážeme, ako je organizovaná videoram a a ko sa s ňou pracuje. Popíšeme si niektoré rutiny na prácu s adresami vo videoram a tiež prevody súradníc na adresy vo videoram. Taktiež bude dobré, keď si zoženiete tabuľky adries videoram. Nájdete ich napr. v ZXM 6/1994 alebo na adrese http://nairam.sk/vram.pdf. Celý článek »
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í.
Takže začínáme nový seriál a vynecháme popisy instrukcí, ty už jste si nadrtili z jiných publikací a začneme něčím jednoduchým. Zkusíme vytisknou znak a pak zkusíme celý text.
Nejjednodušší metoda, jak dostat na obrazovku znak je použití ROMky. Na to slouží rutina na adrese 16 (#10). Tuto rutinku voláme rst 16
.
Příklad
ld a,"A" rst 16
Nevýhoda této metody je, že ke svému běhu potřebuje systémové proměnné Basicu. Pro nenáročné programy je to v pohodě, ale pro programy, které využívají celou RAMku, je to nevýhoda.
rst 16
lze posílat i řídící kódy, které ovlivňují polohu a barvu textu. Nejříve předejte pomocí rst 16 řídící kód a pak jeho parametr. Ukázky budou v příkladech.
6 – posune kurzor na další pozici
8 – kurzor doleva
9 – kurzor doprava
10 – kurzor dolu
11 – kurzor nahoru
13 – ENTER
16 – INK
17 – PAPER
18 – FLASH
19 – BRIGHT
20 – INVERSE
21 – OVER
22 – pozice textu
23 – TAB
Ještě než začnete obrazovku plnit znaky, musíme si říci, jak je obrazovka pro rst 16 rozdělena: obrazovka má 24 řádek a 32 sloupců, avšak řádky jsou rozděleny na 2 kusy. První část je 22 řádek a je to kanál 2 a další 2 řádky (editační) je kanál nula. Před prvním použitím kanálu je třeba jej otevřít:
Příklad
START ld a,2 ;číslo kanálu call $1601 ;otevřít ld a,22 ;řídící kód rst 16 ;pošli ld a,10 ;číslo řádku rst 16 ;pošli ld a,20 ;číslo sloupce rst 16 ;odešli ld a,'A' ;znak rst 16 ;už ho konečně vytiskni ret
Pokud budeme chtít psát znaky do editační oblasti, musíme otevřít kanál nula. Podobně se to dělá v Basicu příkazem PRINT #0;AT 0,0;“pokus“.
START xor a ;číslo kanálu call $1601 ;otevřít ld a,22 ;řídící kód rst 16 ;pošli ld a,1 ;číslo řádku rst 16 ;pošli xor a ;číslo sloupce rst 16 ;odešli ld a,18 ;kód pro nastavení FLASH rst 16 ;pošli ld a,1 ;nastav 1 rst 16 ;pošli ld a,'A' ;znak rst 16 ;už ho konečně vytiskni ret
Pokud již máme otevřen kanál 2 a otevřeme kanál 0, kanál 2 bude uzavřen. Zkrátka rst 16 je vhodné tam, kde nám stačí jen prvních 22 řádek.
Protože rst 16
je v ROM, je třeba, aby registr iy
ukazoval na 23610, tedy do oblasti systémových proměnných. Pomoci nich je možné taky ovlivnit barvu výsledného znaku, pokud potřebujete totálně překopat barvy tak, že by to zabralo 10 řídících kódů, lze toto nastavit jediným POKE. Tato proměnná se nazývá ATTR-T a je: 23695. Vzoreček pro výpočet hodnoty je takto: 128*FLASH+64*BRIGHT+8*PAPER+INK (pro černý inkoust a bílý papír je to 7*8+0=56).
Příklad
START ld a,2 call $1601 ld a,242 ld (23695),a ld a,'A' rst 16 ret
Vidíte, že je to o mnoho jednodušší, než se babrat postupně s několika řídícími kódy.
Za domácí úlohu si zkuste na obrazovce pomocí znaků namalovat něco jako hořící svíčku (když byly ty vánoce).
Pro všechny naše příklady a úkoly budeme potřebovat nějak přeložit zdrojový text do spustitelné podoby. Vzhledem k tomu, že se dnes již nepoužívá metoda programování přímo na speccy, i my se budeme učit používat PC (Pomocný Computer).
Nejprve budeme potřebovat nějaký slušný textový editor. Na Linuxu je jich spousty, pro začátek stačí Kate, Kwrite nebo obyčejný mc. Windows uživatelé musí nejprve stahnout něco normálního, notepad se dá přinejhorším použít.
Pak musíme stáhnout vlastní překladač. Tady používáme AS (http://john.ccac.rwth-aachen.de:8000/as/index.html). AS vyprodukuje soubor s binárním obsahem, takže ještě musíme mít program bin2tap (http://zeroteam.sk/utils.html).
Nakonec potřebujeme slušný emulátor, na kterém si přeložený kód vyzkoušíme. Pro Windows znám jen RealSpec a pro Linux se zdá býti slušný Fuse, ale RealSpecu nešahá ani po kolena, bohužel.
Soubory se zdrojovými texty ukládáme s příponou a80, na začátek textu vkládáme toto:
cpu z80undoc relaxed on
První direktiva oznámí překladači, jaký je použitý jazyk (překladač umí více jazyků) a druhý umožní používat pro zápis hexa a binárních čísel něco podobného jako PROMETHEUS (toto se hodí hlavně při převodu zdrojáků z PROMETHEA do ASu):
ld hl,$25AB ;hexa číslo ld a,%10101010 ;binární číslo ld a,@15 ;osmičkové číslo
Jinak lze pro zápis čísel použít tyto syntaxe:
ld hl,10000 ;dekadicky ld de,25ABh ;hexadecimálně ld a,1001b ;binární zápis ld b,15o ;osmičková soustava
Další odlišnost od PROMETHEA je zápis retězců:
db "Text1" ;normální text db "Text",'a'+128 ;text s posledním invertovaným znakem db 'A' ;pouze jeden znak dw 65535 ;16 bitové číslo db 255 ;8 bitové číslo ds 16 ;definuje prostor 16 bytů
Zdrojový kód přeložíme příkazem takto:
- Linux: asl soubor.a80 -L -E soubor.err
- Windows: as soubor.a80 -L -E soubor.err
Toto vyprodukuje soubor s koncovkou .p, ze kterého je třeba vyrobit binárku:
- Linux: p2bin soubor.p -r $-$
- Windows: p2bin soubor.p -r $-$
Z binárky vyrobíme pomocí bin2tap TAPku už se zaváděcím Basicem, abychom si ušetřili práci:
- Linux i windows: bin2tap soubor.bin -a adresa_zacatku -b
Pak už jen nasměrujeme emulátor na výslednou TAPku a sledujeme výplod naší usilovné práce.
Za domácu úlohu si skúste preložiť nasledujúci text:
sum.a80:
cpu z80undoc relaxed on MAIN ld a,h and 31 ld h,a ld de,16384 ld bc,6144 ldir ld a,191 in a,(254) rra jr c,MAIN ret
Tiež si vyskúšajte zapísať čísla v rôznych číselných sústavách, zapísať chybné čísla (napríklad 16384 nahraďte 16i) alebo chybné inštrukcie (ldir zameňte za ldiruj) a sledujte chybové hlásenia.