Vše o MZ-800 - Kurz assembleru

 

Zpět Nahoru Další

 

Obsah této stránky:

bullet

KURZ STROJOVÉHO JAZYKA.

bullet

1. Programovací medium.

bullet

2. Dvojkový systém.

bullet

3. Hexadecimální systém.

bullet

3.1. Přepočítání z dvojkové do hexadecimální soustavy.

bullet

4. Bit a byte.

bullet

5.Procesor Z-80.

bullet

5.1. Registry.

bullet

5.1.1. Akumulátor (A-registr).

bullet

5.1.2. Další 8-bitové registry.

bullet

5.1.3. Příznaky přepínače (flags).

bullet

5.1.3.1. Indikátor přenosu.

bullet

5.1.3.2. Odečítací flag.

bullet

5.1.3.3. Poloviční indikátor přenosu.

bullet

5.1.3.4. Paritní flag.

bullet

5.1.3.5. Zero-flag.

bullet

5.1.3.6. Znaménkový flag.

bullet

5.1.4. R - registr.

bullet

5.1.5. I - registr.

bullet

5.1.6. PC - registr.

bullet

5.1.7. SP - registr.

bullet

5.1.8. HL - registr.

bullet

5.1.9. BC a DE - registry.

bullet

5.1.10. IX a IY registry.

bullet

5.1.11. Zdvojené registry.

bullet

5.2. Mnemonic a Opcode.

bullet

5.3. Struktura paměti

bullet

5.4. Druhy adresování.

bullet

5.4.1. Výpočet indexového adresování.

bullet

5.6. Dvojková aritmetika.

bullet

5.7.  Logické a početní operace

bullet

5.7.1. Příkaz ADD

bullet

5.7.2. Příkaz ADC

bullet

5.7.3. Příkaz SUB

bullet

5.7.4. Příkaz SBC

bullet

5.7.5. Příkaz INC

bullet

5.7.6. Příkaz DEC

bullet

5.7.7. Příkaz CP

bullet

5.8. Práce s jednotlivými bity

bullet

5.8.1. Příkaz SET

bullet

5.8.2. Příkaz RES

bullet

5.8.3. Příkaz BIT

bullet

5.8.4. Příkazy rotací

bullet

5.8.5. Blokové příkazy

bullet

5.8.5.1. Příkazy pro hledání bloků

bullet

5.8.5.2. Příkazy přesunu bloků

bullet

5.8.6. Příkazy skoků

bullet

5.8.6.1. Absolutní příkazy skoků

bullet

5.8.6.2. Relativní příkazy skoků

bullet

5.8.7. Příkazy CALL

bullet

5.8.8. Příkaz DJNZ

bullet

5.8.9. Příkazy IN a OUT

bullet

6. Kapitola programování

bullet

6.1. Doporučení

bullet

6.2. Jak tisknout ve strojovém jazyce

bullet

6.2.1. Vytisknutí textu na displej

bullet

6.2.2. Vytištění jednoho znaku

bullet

6.3. Čtení klávesnice

bullet

6.3.1. GET ve strojovém jazyce

bullet

6.3.2 INPUT ve strojovém jazyce

bullet

6.3.3. Kurzorový vstup ve strojovém jazyce

bullet

6.4. Dimenzování ve strojovém jazyce

bullet

6.5. Smyčky

bullet

6.6. Dvojkový výraz v akumulátoru

bullet

6.7. Převod hexadecimálního čísla na dekadické

bullet

6.8. Převod dekadického čísla na hexadecimální

bullet

6.9 Přídavné příkazy Z-80

KURZ STROJOVÉHO JAZYKA.
Pro uživatele každého počítače je důležité a užitečné, když se naučí systémový vnitřní jazyk. Ale není to tak jednoduché, aby si mohl člověk jednoduše sednout a začít programovat. Nejprve srovnejme znaky BASICu a strojového jazyka. V BASICu je obsluha velmi pohodlná, protože např. programy pro počítání jako *,+,-,/ jsou již definovány. U komfortnějších BASICů, jako je např. MZ-800 je přirozeně definováno mnohem více funkcí jako např. SIN,COS,TAN,EXP atd. Naproti tomu si ve strojovém jazyce musíme i obyčejné násobení dobře rozmyslet; opravdu těžké jsou např. programy pro počítání v reálném čase. Hledisko rychlosti je jeden z rozhoduj1icích argumentů pro programování v assembleru. A tak je někdy zcela nemožné napsat některé programy v BASICu, protože rychlost je úplně nedostačující. Totéž platí pro potřebu místa v paměti, která je u BASICu velmi velká. Proti tomu se ve strojovém jazyce stejný problém vyřešit na jedné desetině místa,zvláště, když se BASIC nemusí nahrávat. Toto uspoří při pozdějším provádění programu mnoho času. Nyní ale začneme odhrnovat roušku tajemství strojového jazyka.
 

1. Programovací medium.
Jako se v BASICu nedá programovat bez BASICu, nedá se programovat ve strojovém jazyce bez strojového jazyka. Zde je několik možností:

  A. programování v assembleru

  B. programování ve strojovém jazyce

  C. programování v Monitoru

Chceme zde jen ukázat rozdíly mezi assemblerem a strojovým jazykem (zkráceně ML = machine language), ale dále se budeme zabývat programováním v ML (viz. též kniha: "ASSEMBLERPROGRAMMI-ERUBG AUF DEM MZ-700/800"). Proto vám doporučujeme, abyste si pro tento ML-kurs obstarali dobrý strojový jazyk, který by měl v každém případě ovládat následující povely:

  a. Disassembler

  b. zapsání hex. čísla do paměti

  c. listování pamětí

  d. ukládání ASCII - řetězců do paměti (textwrite)

  e. ASCII - listing

     Toto vám umožní např. strojový jazyk 8002 od firmy BBG Software.
 

2. Dvojkový systém.
Pro znalce strojového jazyka mohou být následující kapitoly příliš lehké a může je proto klidně přeskočit. Jestliže někomu není dvojkový neboli binární systém známý, měl by zde dávat dobrý pozor, protože toto je klíč k porozumění ML. Jak již jméno napovídá, jedná se zde o systém čísel, který má něco společného s dvojkou (bi = řecky dvě). Jak možná víte, v elektronice a tím i u počítačů existují jen dva stavy, a to 0 a 1 (vypnuto a zapnuto). Tento dvojkový sytém používá jen tyto dva stavy. Princip je podobný naší desítkové soustavě. Pro ty, kteří náš desítkový systém ještě dostatečně neznají, máme jeden příklad. Vezměme si číslo 15326. Musíme zde jednotlivé číslice rozdělit podle jednotek, desítek, stovek, tisíců atd. To znamená:
 

15326  =  1 deset tisíc ...... 1x10

                           3
          5 tisíc ............ 5x10

                           2
          3 sta .............. 3x10
 

                           1
          2 desítky .......... 2x10
 

                           0
          6 jednotek ......... 6x10  (pro všechny nematematiky: deset na nultou je jedna!)

            4        3        2        1        0
15326 = 1x10  +  5x10  +  3x10  +  2x10  +  6x10

            n        n-1        n-2
číslo = Xx10  +  Yx10    +  Zx10    +  Ax10 + Bx1

Právě tak se chová dvojkový systém. Desítkový systém má za základ 10, dvojkový systém 2. U desítkového systému je největší číslice 9, u dvojkového systému tomu odpovídající číslo 1. Jsou zde tedy pouze číslice 0 a 1.

           n        n-1        n-2
dv.č. = Xx2   +  Yx2     +  Zx2     +  Ax2x1 + Bx1

Jako příklad přepočítáme decimální číslo 39 na binární. Na to musíme znát mocniny dvojky. Tak jako 10,100,1000,10000 atd. jsou mocniny deseti, tak jsou 2,4,8,16,32,64,128 atd. mocniny dvojky.

         x
číslo = 2 = mocnina 2

          x
číslo = 10 = mocnina 10

Číslo 39 se skládá z mocnin 2, následujícím způsobem:

  39 = 32 + 4 + 2 + 1

        5    2    1    0
  39 = 2  + 2  + 2  + 2
           

To se pokusíme zvládnout nejlépe pomocí následující tabulky:

-----------------------------------------------------------------
128   64    32    16    8     4     2     1

  0    0     1     0    0     1     1     1   = 39
-----------------------------------------------------------------

Decimální číslo 39 se v binární soustavě rovná číslu 00100111. Jako jiný příklad decimální číslo 111. Sestavíme opět tabulku tak, že zapíšeme pod příslušnou mocninu 2 jedničku nebo nulu, aby vzniklo správné číslo.

-----------------------------------------------------------------
128   64    32    16    8     4     2     1

  0    1     1     0    1     1     1     1  = 111
-----------------------------------------------------------------

Decimální číslo 111 je tedy v binární soustavě 01101111. Předkládáme vám ale ještě jednu dobrou metodu, jak určit, kdy se musí pod mocninu 2 napsat 0 nebo 1. Ukážeme si to opět na čísle 111. Nejdříve hledáme mocninu 2, která je nejbližší nižší k desítkovému číslu. 128 je větší než 111, ale zároveň je číslo 111 větší než číslo 64. Napíšeme tedy pod 64 číslo 1, a potom 64 odečteme od 111 (111 - 64 = 47). Nyní zacházíme s číslem 47 právě tak, jako s číslem 111, takže 32 by bylo nejbližší nižší mocnina 2. Zapíšeme tedy pod 32 číslo 1 a odčítáme (47 - 32 = 15). Příští nejbližší nižší mocnina 2 je 8, takže pod ní zapíšeme 1, odečtením dostaneme 7, což se dá z hlavy spočítat jako dvojkové číslo 111 (1 + 2 + 4 = 7). Tam, kam nebyla zapsána žádná 1, je logicky zapsána 0. Tím dostaneme dvojkové číslo 01101111. Čím větší je decimální číslo, tím větší musí být mocniny 2. Jestliže máme dvojkové číslo a chceme ho přepočítat na desítkové, sečteme jednoduše mocniny 2. To může sloužit jako kontrola např. 01101111 = 64 + 32 + 8 + 4 + 2 + 1 = 111.
 

3. Hexadecimální systém.
Hexadecimální systém se může z počátku zdát pro začátečníka zmatený, ale přesto je to velice logický systém a základ pro naučení strojového jazyka. Ptáte se proč se za základ pro počítač nevzal desítkový nebo dvojkový systém. Odpověď je zřejmá.

Desítkový systém není pro počítač zpracovatelný, a přepočítávaní desítkového systému do dvojkového spotřebuje mnoho času. Přepočítávání hexadecimálního systému do dvojkového je velice rychlé, protože 16 je přece mocnina 2. Tím se ještě budeme zabývat. Jak již jméno napovídá, je číslo 16 základ tohoto číselného systému. Obecná přepočtová rovnice tedy tentokrát zní:

              n        n-1        n-2
  číslo = Zx16  +  Yx16    +  Zx16    +  Ax16 

Mocniny 16 jsou:
                       0   1   2   3
  1, 16, 256, 4096 = 16 ,16 ,16 ,16

Potřebujeme jen tyto mocniny, protože v paměti můžeme adresovat jen po 63 535, takže vyšší mocninu nepotřebujeme. Pravděpodobně vás již napadlo, jak jak může být hexadecimální systém vybaven číslicemi, když od 10 do 15 žádné číslice nejsou. Zde bylo rozhodnuto vzít za základ písmena A - F, takže A=10,B=11, C=12, D=13, E=15. Výpočet hexadecimálního čísla se provádí podle stejného schématu jako při výpočtu dvojkového čísla. Jenom se zde samozřejmě hledá nejbližší nižší mocnina 16. Podívejme se na to na příkladu. Decimální číslo 83 má být přepočítáno na hexadecimální.

  Nejdříve tedy napíšeme tabulku:

  -----------------------------------------
      4096      256      16      1

        0        0        5      3  =  83
  -----------------------------------------

Postupujme analogicky k dvojkovému systému. Nejprve hledáme nejbližší nižší mocninu 16, čili číslo 16. Toto je v 83 obsaženo 5 krát, napíšeme tedy pod 16 číslo 5, 5x16=80, dostaneme tedy zbytek 3. Dohromady to tedy dává hexadecimální číslo 83. Zkusme to na větším decimálním čísle, třeba 15311. Nejlépe bude, vezmete-li si na pomoc kapesní kalkulačku. První mocnina je 4096. Toto číslo je v 15311 obsaženo 3x, 3x4096=12288. Nyní dostaneme jeho zbytek (15311-12288) 3023, který musíme porovnat s další menší mocninou 16. Do 3023 se 256 vejde 11x. Nyní musíme opět spočítat zbytek (3023-(11x256)=207). 207 děleno 16 je 12 a zbytek je 15.

  -------------------------------------------------
  15311  =   3x4096  +  11x256  +  12x16  +  15

                 3           2          1         0
  15311  =   3x16    +  11x16   +  12x16  +  15x16
  -------------------------------------------------

Nyní musíme čísla přeformovat na hexadecimální čísla. Jak jsme se již zmínili, představují čísla přes 9 samostatné hexadecimální cifry(A=10,B=11 atd.). Nyní musíme vypočtené hodnoty čili 3,11,12,15 přeformovat na hexadecimální číslo, což dává 3BCF. Nejvyšší hexadecimální hodnota by byla FFFF. Od teď budou hexadecimální čísla na konci označena písmenem H. To nám také ulehčí identifikaci, zda se jedná o čísla mající decimální nebo hexadecimální hodnotu. FFFFH je tedy 15x4096 + 15x256 + 15x16 + 15=65535. Volné místo v paměti je 65535 bytů, což je 64 Kbytů.
 

3.1. Přepočítání z dvojkové do hexadecimální soustavy.
Při programování ve strojovém jazyce je později důležité převádět dvojkové hodnoty na hexadecimální a naopak. K tomu několik dobrých rad: budeme se zde zabývat jen 8-bitovými hodnotami, např. dvojkovou hodnotou 01111111. Potom se 8-bitové číslo rozdělí na dvě poloviny, a to přesně uprostřed a vznikne 0111 a 1111. To jsou decimální čísla 7, resp. 15, což jsou hexadecimální hodnoty 7 a F. Hexadecimální číslo tedy je 7FH.
 

4. Bit a byte.
S těmito pojmy jsme se již setkali občas v předcházejících kapitolách. Kdo ještě neví oč se jedná, tomu budiž řečeno následující. Bit je nejmenší jednotka, kterou počítač zná. Byte se skládá z 8 bitů. Bity si mohou pamatovat jen stavy 0 a 1, jeden byte má proti tomu 2 na osmou, tj. 256 možností zapamatování. Byte je normálně udáván jako hexadecimální číslo. Celá paměť MZ-800 má podle toho 8x65535 = 524280 bitů.

 

5.Procesor Z-80.

Mikroprocesor Z-80 je srdcem MZ-800. Každý počítač má mikroprocesor, ATARI, APPLE, COMMODORE mají především procesory 6502. Jiné známé procesory jsou 6809 a nové 32-bitové procesory 68000, 80186 a mnoho dalších. Z-80 procesor má asi 400 oficiálních povelů a ještě mnohem více neznámých povelů, kterými se budeme zabývat později. Povely jsou 1,2,3,4 bytové.
 

5.1. Registry.
Registry jsou zvláštností procesoru. S registry se dá počítat, vyjímat hodnoty z paměti a přenášet hodnoty do paměti. Mnoho logických operací, sčítání, odčítání a další se provádí pomocí registrů. Přitom existují jednobytové a dvoubytové registry. Dvoubytové neboli také 16 bitové registry jsou zvláště praktické pro matematické operace. To je výhoda, kterou má procesor Z-80 proti procesoru 6502.

Sada registrů:

     8-bitové registry        16-bitové registry
     -----------------        ------------------

     A (akumulátor)           PC (programmcounter-čítač programů)
     B                        BC (skládá se dohromady
     C                           z B a C)
     D                        DE (skládá se
     E                            z D a E)
     H                        HL (skládá se
     L                            z H a L)
     F (příznak přepínače)    SP (ukazatel zásobníku)
     LX                       IX (skládá se z
     HX                           registrů LX a HX)
     LY                       IY (skládá se z
     HY                           registrů LY a HY)
     Dvojitý registr        z  A,B,C,D,E,F,H,L 
     R - obnovovací registr
     I - přerušovací registr

 

5.1.1. Akumulátor (A-registr).
Jak již bylo naznačeno, má akumulátor mezi registry zvláštní postavení. Akumulátor je 8-bitový registr, ve kterém se provádí logické operace jako AND,OR, ale též sčítání a odčítání. Jako jediný 8-bitový registr je schopen vyvolat hodnoty z paměti a do paměti je ukládat. Logické operace může provádět s pomocí ostatních registrů nebo s pamětí. To dělá z akumulátoru důležitou součástí procesoru.
 

5.1.2. Další 8-bitové registry.
Kromě akumulátoru má Z-80 ještě další registry, jako B,C,D,E,H,L. Obecně působí tyto registry jako akumulátor, ale jejich zásoba povelů není tak velká. A tak mohou pracovat jen ve spojení s akumulátorem. Také není možné adresování paměti z těchto registrů.
 

5.1.3. Příznaky přepínače (flags).
Příznaky přepínače jsou představovány F-registrem, takže je dohromady 8 příznaků přepínače, z kterých je používáno pouze 6.

Zde je grafický přehled:

--------------------------------------------
 7    6     5     4     3     2     1     0

 S    Z     -     H     -     P     N     C
--------------------------------------------
 

Jména flagů:

    S - znaménkový flag

    Z - nulový flag
    H - poloviční indikátor přenosu
    P - paritní flag
    N - odčítací flag
    C - indikátor přenosu

Flagy se používají pro označení výsledku matematicko-aritmetické operace. Udává se, zda operace dává výsledek jako 0, nebo jestli existuje přeplnění atd.
 

5.1.3.1. Indikátor přenosu.
Indikátor přenosu nám ukazuje přeplnění bitu 7 (u 16-bitových přeplnění bitu 15). Indikátor přenosu si můžeme představit jako aktivní devátý bit. Chceme provést operaci, při které vznikne přeplnění 8-bitů, takže při ní překročíme výpočetní oblast. Např.A obsahuje 83H a B obsahuje 90H. Součet dává potom 113H, což by bylo ale 9-bitové číslo. V akumulátoru je potom 13H a v indikátoru přenosu 1.
 

5.1.3.2. Odečítací flag.
Tento příznak přepínače není programátorem požíván, používá se při speciálních desítkově-aritmetických povelech jako vnitřní znaménkový bit. Pro programování je relativně nedůležitý.

5.1.3.3. Poloviční indikátor přenosu.
Poloviční indikátor přenosu funguje podobně jako indikátor přenosu, ale ukazuje se zde přenosu ze 3 bitů na 4. Pro programátora zpracovávajícího program ve strojovém jazyce zde není žádná možnost tento indikátor kontrolovat, a proto je praktický význam minimální.
 

5.1.3.4. Paritní flag.
Paritní flag má 2 hlavní funkce.

a) Určení rovnosti nějakého jevu. Rovnost znamená totéž jako křížový součet. To znamená, že se spočítají jednotky uvnitř jednoho bytu. Jestliže se suma jednotek nerovná, potom je v P-flagu jednotka (1), jinak je obnoven počáteční stav.

b) Druhá hlavní funkce je funkce přeplnění. Udává se, zda při sčítání nebo odčítání nebyl omylem změněn znaménkový bit tím, že výsledek omylem přeběhl do znaménkového bitu.
 

5.1.3.5. Zero-flag.
Jak jsme se již zmínili ve výše uvedeném příkladu, slouží nulový flag k zobrazení toho, zda některá operace má výsledek 0 nebo ne. Při výsledku 0 má Z-flag nastaveno 1, jinak 0.
 

5.1.3.6. Znaménkový flag.
Tento flag slouží k zobrazení znaménka, přičemž se osmice bitů rozdělí na 7 datových bitů a jeden bit znaménkový. To má za následek to, že výpočetní oblast je od -127 do +128.
 

5.1.4. R - registr.
Obnovovací registr slouží interně k obnovení paměti. Přitom počítadlo odpočítává z 7FH na 0, a potom je paměti vydán obnovovací impuls. Z tohoto registru se dá prakticky jen číst, což se však báječně hodí pro generátor náhodných čísel. Tím, že se zamezí impulsu obnovení (do akumulátoru se dá xx a do R se dá A) se dá vymazat celá paměť a zůstane pouze destruktivní program.
 

5.1.5. I - registr.
Přerušovací registr ukazuje stav uvnitř úrovně operačního systému, takže pro programátora nemá velký praktický význam.
 

5.1.6. PC - registr.
PC-registr, nebo též čítač programů, ukazuje, na kterém místě právě pracuje základní jednotka Z-80. K čítači programů není možný žádný přímý přístup.
 

5.1.7. SP - registr.
SP-registr, nebo též ukazatel zásobníku, je registr, ve kterém je 16-bitová adresa místa v paměti. Na tomto místě se nachází zásobník, což je pomocí ukazatele zásobníku definovaná pracovní oblast, do které se ukládají, a ze které se vybírají data. Pro práci s tímto zásobníkem jsou speciální povely, kterými se budeme zabývat později.
 

5.1.8. HL - registr.
HL-registr je 16-bitový registr, který se skládá ze dvou 8-bitových registrů H a L. Přitom nižší byt (Low Byte) tvoří L, zatím co vyšší byt (High Byte) tvoří H.

Pro osvěžení:
Low znamenalo nižší, High vyšší hodnotu. Zde začínáme mluvit o něčem, na co se v 16-bitovém zápisu musí dávat pozor. V paměti je nejprve uložen Low, a potom High registr. Nechť tedy obsahuje H-registr 06H, L-registr F4H. Potom bude registr HL obsahovat jako celek O6F4H. Jestliže nyní uložíme obsah registru HL do paměti, bude v paměti stát F406, čili přesně obráceně. HL-registr je tedy 16-bitový registr pro logické operace, a je to vedle A nejpoužívanější registr v sadě registrů.
 

5.1.9. BC a DE - registry.
Tyto dva registry jsou velmi podobné registru HL. Oba se skládají z 8-bitových registrů B a C, resp. D a E, ale povelový komfort je ve srovnání s HL velmi omezený. Musí se dát ale velký pozor na to, že když se při programování použije registr B, změní se i hodnota registru BC, takže se nejprve musí zachránit hodnota registru BC. To je chyba, která se při programování ve strojovém jazyce často stává. To samozřejmě platí pro všechny 16-bitové registry, takže i pro HL,DF,IX,IY.
 

5.1.10. IX a IY registry.
Registry IX a IY jsou velcí bratři registru HL. Zde se musí dát pozor, protože zde bylo trochu nešťastně zvoleno pojmenování registrů. Za prvé nemají registry IY a IX nic společného s registrem I. Část I  z IX registru je HX registr, část X je LX registr. Právě tak je to u IY registru, kde I je HY, část Y je LY registr. Pozor ale na to, že LY,HY,HX,LX jsou 8-bitové registry, a ne jak se může na první pohled zdát 16-bitové registry. Programování těchto registrů není popsáno v žádné knize o Z-80, jsou to neznámé povely, kterými se budeme zabývat později. IX a IY se též nazývají indexové registry. Sada povelů indexových registrů je velice podobná povelům pro HL registr, ale pro každý povel pro indexový registr je potřeba minimálně tři, většinou dokonce čtyři byty, což značně zvětšuje délku programu. O způsobu adresování budeme mluvit v jiné kapitole, protože je to opravdu těžká část programování ve strojovém jazyce.
 

5.1.11. Zdvojené registry.
Zvláštností v sadě registrů jsou tzv. zdvojené registry, A',B',C',D',E',H',L',F'. Jsou to duplikáty registrů A,B,C,D,E,H,L,F, které byly vyměněny s normálními registry pomocí povelů pro vyměňování. Procesor dále počítá s hodnotami zdvojených registrů. Jestliže se povely vyměňování požijí dvakrát, logicky se vytvoří původní stav.
 

5.2. Mnemonic a Opcode.
Další důležitou kapitolou je souvislost mezi symbolem a významem povelů ve strojovém jazyce. Právě tak jako v BASICu má i zde každý povel konkrétní význam. Tak např. povel DIM v BASICu má význam zřízení pole. Ve strojovém jazyce má také každý povel svůj hexa. kód, čili hexa. číslo označuje povel. Tak povel NOP (No OPeration) je označen číslem 00H. Takže když je zpracovávána hodnota 00H, je interpretována jako NOP, a potom zpracovává ihned další povel. Jestliže přijde jako povel 09H, budou sečteny registry HL a BC. Přehled všech těchto povelů Z-80 najdete v dodatku této knihy. Mnemoniccode 09H znamená ADD HL,BC, čímž se dostáváme k mnemotechnickému způsobu zápisu. Mnemoniccode povelu je pro programátora srozumitelná interpretace hexa. povelu. Tak je pro hexa. povel 09H definován mnemoniccode ADD HL,BL. Pro programátora není možné rozpoznat smysl programu jen na základě čísel, naproti tomu mnemoniccode je pro něj snadno srozumitelný. V mnemoniccode se dá programovat, ovšem pouze v assembleru. V assembleru programujete např. INC A a assembler to převede na 3CH. Disassembler dělá pravý opak, takže převede 3CH na INC A. Pro nás je disassembler plně dostačující, ale každý dobrý stroj. jazyk by měl mít disassembler. Program se vloží v hexa. číslech a potom se může vylistovat pomocí disassembleru. Programování v assembleru je rozsáhlejší, ale má také více možností.
 

5.3. Struktura paměti
Napsaný program je v paměti na určité adrese. Paměť začíná na adrese 0000H a končí na FFFFH. Normální oblast programování MZ-800 začíná na 1200H. Odtud budeme též psát všechny naše programy. Ke každé adrese v paměti patří také obsah, což může být datový nebo programový byte. Abychom se mohli tímto zabývat, potřebujeme disassembler, který přeloží ze strojového jazyka do jazyka symbolických instrukcí oblast od 1200H. Když se zapne počítač, nejprve se většinou vymaže paměť. Je tomu tak i u MZ-800. Nyní tedy nalézáme v paměti pouze 00H a FFH. Když uvedený obsah přeložíme, objeví se následující:

  ADRESA     OPCODE     MNEMONICCODE
   
   1200        00          NOP
   1201        00          NOP
   1202        FF          RST 38
   1203        FF          RST 38
 

5.4. Druhy adresování.
V možnostech adresování není Z-80 vybaven tak bohatě jako jeho protějšek - 6502. Přesto zde musíme říci několik věcí ne právě zanedbatelného významu. U Z-80 má mnemoiccode tři díly:

  a) druh povelu
  b) cílová adresa / registr
  c) strojová adresa / registr

To znázorníme na příkladu:

Příklad:   LD A,B

Toto je ukládací povel, při kterém bude hodnota, která je v registru B uložena do registru A. V BASICu by tento povel zněl: A = B. Na tomto se dá vysvětlit struktura mnemonického kódu. Druh povelu je ukládací povel (LD). Cílový registr je zde A-registr, zdrojový registr je B-registr. To je registrové adresování. Zabývejme se nyní povelem LD A,(HL), což je opět ukládací povel. Akumulátor zde opět představuje cílový registr. Jen zdrojový registr zde potřebuje další vysvětlení. Vidíme, že zdrojový výraz je zde (HL). Závorka nám ukazuje, že zde pracujeme s pamětí. Výraz v závorce je HL-registr. HL je 16-bitový registr, který zde ukazuje na místo v paměti. Jestliže by HL měl hodnotu 0000H, pak by byla zpracovávána hodnota, která je v paměti na místě 0000H (u MZ-800 je na adrese 0000H C3H). Tato hodnota je potom uložena do akumulátoru. A ještě další příklad:

  LD (1000H),A

Jedná se opět o ukládací příkaz. Tentokrát nám závorka ukazuje, že cílová adresa je v paměti, zde tedy adresa 1000H. Hodnota, která má být uložena za adresu 1000H, je tedy v akumulátoru (zdrojovém registru). Rozdílné jsou 16-bitové ukládací povely. Vezměme příklad uvedený výše, ale tentokrát s HL-registrem.

  LD (1000H),HL

Jak si můžete domyslet, bude hodnota v HL-registru uložena na adrese 1000H. Nyní je ale tato hodnota 16-bitová, takže obsadí kromě adresy 1000H ještě adresu 1001H. Jak jsme se již zmínily, při 16-bitových znacích se v paměti ukládá nejprve nižší a potom vyšší byte. Nechť HL obsahuje před provedením příkazu LD (1000H),HL hodnotu 12F5H. Po provedení je na adrese 1000H hodnota F5H, na adrese 1001H hodnota 12.

Jako poslední bychom se chtěli zabývat dříve zmíněným indexovým adresováním registrů IX a IY. Jak již bylo řečeno, můžeme tyto registry považovat za velké bratry registru HL. Pro IX platí hexadecimální označení DDH, pro IY platí označení FDH. K hexa. kódu, který platí pro HL, se jednoduše přidá DDH nebo FDH. Jako příklad uvedeme povel INC HL:

  INC HL = 23
  INC IX = DD 23
  INC IY = FD 23
 

To platí jen pro ty povely, u kterých nejsou žádné cílové a zdrojové pohyby, protože tam musí být ještě hodnota indexu. Po Opcode se přidá ještě jeden byte.

Zabývejme se např. povelem:

  LD A,(IX+05)

Tento povel má velkou vnější podobu s již zmíněným příkladem LD A,(HL), jen je tentokrát jiná hodnota výrazu v závorce; místo HL je zde IX+05. Jestliže tedy IX obsahuje hodnotu 2000H, přičte se k ní 5 a dostaneme hodnotu 2005H. Potom bude vybrána hodnota z adresy 2005Ha bude uložena do akumulátoru.
 

5.4.1. Výpočet indexového adresování.
Rozhodující je výpočet indexové hodnoty za Opcode, protože např. existuje povel LD A,(IX-03). Můžete se domyslet, že při indexovém adresování přicházejí v úvahu hodnoty v rozsahu od -128 do +127. Jako další příklad uvedeme povel:

  LD A,(IX+F0H)

Při hexa. hodnotě F0 je nastaven sedmý bit. Tento sedmý bit je znaménkový bit - to znamená, že to je záporné číslo. V tomto případě se jednoduše hodnota neguje (vytvoří se doplněk); doplněk k FOH je 10H (F0H + 10H = 00H). Takže kdyby IX bylo 2000H, od 2000H by se odečetlo 10H, což dává 1FF0H. Z této adresy by byl obsah uložen do akumulátoru.
 
Příklady:

  IX hodnota     Hodnota indexu     Vytvořená adresa

    3000H             10H                3010H
    3000H             00H                3000H
    3000H             C0H                 2FC0H

Ještě nezkušený programátor by měl nejprve znát všechny hodnoty HL-registru, než začne s indexovým programováním.
 

5.6. Dvojková aritmetika.
Dvojková logika je ve strojovém jazyce důležitá věc. Většinou jde o logické operace s akumulátorem, se kterým se dají lépe rozpoznat nebo maskovat určité stavu bitu.

  Povely logických operací jsou:

  a) AND
  b) OR
  c) XOR

Nejprve něco o základu logických operací. Provádí se vždy logické operace se dvěma bity podle logického schématu. Cílový bit bude obsahovat novou hodnotu, přičemž se postupuje podle tabulek.

   Například tabulka příkazu OR

   bit A   bit B   výsledný bit
   ----------------------------
      0      0         0
      1      0         1
      0      1         1
      1      1         1

Na vysvětlenou: Když má bit A  hodnotu 1 a bit B  hodnotu 0, bude mít výsledný bit logické operace hodnotu 1. Když bude mít bit A, nebo B hodnotu 1, bude výsledný také 1. Ve strojovém jazyce se provádějí logické operace vždy v akumulátoru s jedním s registrů. Například logická operace OR A,B, nebo lépe uspořádáno OR(AaB). Výsledek log. operace je také v akumulátoru. Proveďme operaci OR v akumulátoru a C registru. A obsahuje 45H a C obsahuje 09H. Nyní napište tyto hodnoty ve dvojkovém kódu.

  registr A   01000101    45H
          C   00001001    09H
              ---------------
  výsledek    01001101    4DH

Porovnávali jsme pod sebou napsané bity podle tabulky OR, a jako výsledek jsme dostali 4DH.

Nyní tabulka pro příkaz AND

  bit A   bit B   výsledný bit
  --------------------------------
     0       0        0
     0       1        0
     1       0        0
     1       1        1

Vezměte nahoře uvedená data a porovnejte podle tabulky AND.

  registr A   01000101    45H         C     00001001    09H
              -------------------
  výsledek    00000001    01H

Po provedení AND A,B je tedy v akumulátoru hodnota 01H. Při log. operaci AND bude výsledek 1, pouze tehdy, když oba původní bity obsahují 1.

Nakonec ještě tabulka pro příkaz XOR.

  bit A   bit B   výsledný bit
  --------------------------------
     0       0        0
     0       1        1
     1       0        1
     1       1        0

Znovu porovnáváme uvedená data pomocí tabulky XOR

  registr A   01000101    45H
          C   00001001    09H
          -------------------
    výsledek   01001100    4CH

Po provedení příkazu XOR A,B obsahuje akumulátor hodnotu 4CH. Příkaz XOR dá interpretovat také takto. Výsledný bit obsahuje 1 pouze tehdy, když bity A,B jsou rozdílné.
 

5.7.  Logické a početní operace
V sadě příkazů je několik příkazů, které programátorovi při těchto operacích pomáhají
 

5.7.1. Příkaz ADD
Příkaz ADD je jednoduchý sčítací příkaz, který sčítá dva registry. Například  ADD HL,BC. Když HL obsahuje 3245H a BC A753H, pak po provedení příkazu obsahuje HL registr hodnotu D998H.
 

5.7.2. Příkaz ADC
Příkaz ADC pracuje stejně jako ADD, ale při sčítání je přičten i indikátor přenosu. Kdyby byl indikátor nastaven a provedli bychom příkaz ADC HL,BC s hodnotami dříve uvedenými, v registru HL by byl výsledek D999H.
 

5.7.3. Příkaz SUB
Příkaz SUB vzájemně odečítá dva 8-bitové registry. Například příkaz SUB A,B odečítá registr B od akumulátoru.
 

5.7.4. Příkaz SBC
Příkaz SBC pracuje stejně jako příkaz SUB, ale při nastavení indikátoru přenosu je odečten i indikátor přenosu. SBC příkaz platí na rozdíl od příkazu SUB i pro 16-bitové registry.
 

5.7.5. Příkaz INC
Příkaz INC jednoduše načítá registr, to znamená, že je jeho hodnota o jednotku zvýšena. Když HL obsahuje 3323H, po provedení příkazu INC HL bude obsahovat hodnotu 3324H. Podobně jako v BASICu X=X+1.
 

5.7.6. Příkaz DEC
Příkaz DEC jednoduše odčítává registr, to znamená, že jeho hodnota je o jednotku snížena. Když HL obsahuje 3323H, po provedení příkazu DEC HL bude obsahovat hodnotu 3322H. Podobně jako v BASICu X=X-1.
 

5.7.7. Příkaz CP
Příkaz CP umožňuje srovnávat registr nebo obsah paměti s akumulátorem. Srovnává se, zda hodnota v akumulátoru je větší, menší nebo stejná. Například registry A i B obsahují  hodnotu 99H. Po provedení příkazu CP A,B se v registrech hodnoty nemění, ale nastaven Zero-flag, protože hodnoty se sobě rovnají.
 

5.8. Práce s jednotlivými bity
V sadě příkazů jsou příkazy, které umožňují zjišťování hodnot, nastavení nebo obnovení počátečních hodnot jednotlivých bitů.
 

5.8.1. Příkaz SET
Příkaz umožňuje nastavení jednotlivých bitů v registrech. Například SET 7,A nastavuje nejvyšší bit v akumulátoru na 1. Může se manipulovat i s hodnotou v paměti pomocí indexového adresování.
 

5.8.2. Příkaz RES
Příkaz RES umožňuje nastavení počáteční hodnoty jednotlivých bitů v registrech. Například RES 5,B nastavuje pátý bit registru B na 0. Jestliže B obsahoval předtím 23H (00100011), obsahuje po provedení příkazu hodnotu 03H (00000011)
 

5.8.3. Příkaz BIT
Příkaz BIT umožňuje zjišťování hodnot jednotlivých bitů v registrech. Například BIT 0,A zde se zjišťuje obsah nultého bitu akumulátoru. Tato část hodnoty je potom v Z-flagu. Jestliže nultý bit akumulátoru obsahoval 1, pak v Z-flagu je 0.
 

5.8.4. Příkazy rotací
Příkazy rotací jsou příkazy, pomocí kterých můžeme bity v registrech rolovat, to znamená, že při levotočivé rotaci se 6-tý bit přesune na místo 7-mého bitu, 5-tý bit na místo 6-tého bitu atd. až se přesune 7-mý bit na místo 0-tého bitu. Při pravotočivé rotaci se budou bity posouvat obráceně. Příkazy rotace se liší jen nepatrně. Co bude pro programátory Z-80 jistě nové, je příkaz SLS (CB30 až CB37 jako Opcode). Většinou se obejdeme s příkazy RRCA a RLCA. Zde se ještě zmíníme o použití při násobení. Vezměme si např. číslo 52, napišme ho v binárním kódu  00110100. Když provedeme RRCA, bude po rotaci v akumulátoru 01101000, což je číslo 104. Provedlo se násobení dvěma. Jestliže byl nastaven 7 bit, výsledek není správný! Přeplnění je v flagu CY. Pávě tak otáčení doprava znamená dělení. Proto jsou tyto příkazy zvláště při matematických programech nepostradatelné.
 

5.8.5. Blokové příkazy
Mikroprocesor Z-80 má tu zvláštnost, že může použít příkazy pro operace s bloky. Tyto příkazy se dělí do dvou skupin.
 

  a) příkazy pro hledání bloků
  b) příkazy pro přesuny bloků
 

5.8.5.1. Příkazy pro hledání bloků
Hledání bloků zde bude vysvětleno na příkazu CPIR. Přitom se znak, který je v akumulátoru, hledá v určité oblasti. Adresa začátku je v HL, délka bloku, ve kterém se má hledat je v BC a znak, který se bude hledat je v akumulátoru. Například budeme hledat znak 66H v oblasti od 3000H do 4000H. Jestliže je znak nalezen, bude práce na tomto místě v paměti přerušena a Z-flag je nastaven. Jestliže znak není nalezen, je Z-flag nastaven na původní hodnotu.

  1200  3E 66       LD   A,66H
  1202  21 00 30    LD   HL,3000H
  1205  01 00 10    LD   BC,1000H
  1208  ED B1       CPIR
  120A  CA XX XX    JP   Z,XXXXH
  120D  pokračování
 

5.8.5.2. Příkazy přesunu bloků
Funkce přesunu bloků bude vysvětlena na příkazu LDIR. Přitom bude blok v paměti přesunut do jiné části paměti. Budeme

přesouvat oblast od 2000H do 3000H za C000H. Pro příkaz LDIR jsou třeba tři parametry:

  a) počáteční adresa původního bloku HL - registr
  b) počáteční adresa přesunu         DE - registr
  c) délka bloku                      BC - registr

Jsou-li nastaveny všechny parametry, můžeme použít příkaz LDIR. Pro shora uvedená data by se musel napsat následující program:

  1200  21 00 20    LD   HL,2000H     odkud
  1203  11 00 C0    LD   DE,C000H     kam
  1206  01 00 10    LD   BC,1000H     délka
  1209  ED B0       LDIR
  120B  C3 AD 00    JP   00ADH        skok do monitoru
 

5.8.6. Příkazy skoků
Zásadně jsou dva druhy skoků, podmíněné a nepodmíněné.

Nepodmíněné skoky "skáčí" vždy na definovanou adresu, podmíněné skoky "skáčí" na adresu pouze tehdy, je-li splněna podmínka, např. když je Z-flag 1.
 

5.8.6.1. Absolutní příkazy skoků
Absolutní příkazy skoků jsou jednoduché příkazy, například JP 3000H skočí vždy na adresu 3000H v paměti, nebo například JP NZ,3000H skáčí na adresu 3000H, když výsledek operace není nulový,bude v Z-flagu 0. N v podmínce znamená vždy NE !!

Například: NC = not Carry
 

5.8.6.2. Relativní příkazy skoků
Relativní příkazy skoků jsou o něco komplikovanější než absolutní. Jsou také podmíněné a nepodmíněné, ale způsob adresování je jiný. Podobá se indexovému adresování, popsanému v kapitole 5.4.1.. Jak si vzpomínáme, rozsah hodnot byl od -128 do 127, čili 7-mi bitové zobrazení. Právě tak je to u relativního skoku. Nejprve následuje normální byt pro druh příkazu, potom hodnota indexu, například

  1200  38 06       JR C,PC+2+06      ;PC - obsah čítače instrukcí

V tomto případě bude pokračovat zpracování programu o 6 bytů dále, je-li nastaven indikátor přenosu. Výhoda relativních skoků je možnost přesunutí do libovolné oblasti paměti. Naproti tomu je nevýhodou malý rozsah adresování pouze 256 bytů, což hovoří pro absolutní adresování. Zvláštní formou je skok závislý na registru například JP (HL). To znamená, že ve zpracování programu se bude pokračovat na tom místě v paměti, které odpovídá hodnotě registru HL. Jestliže HL obsahuje například hodnotu 2000H, stačí na adresu 2000H. To platí i pro registry IX a IY.
 

5.8.7. Příkazy CALL
Příkaz CALL je obdobou příkazu GOSUB v BASICu. Je jím vyvolán podprogram, který je zakončen příkazem RETURN. Přitom existují právě tak jako u skoků podmíněných a nepodmíněných příkazy CALL, jako například  CALL Z,3000H. Zde je vyvolán podprogram na adrese 3000H. když je nastaven Z-flag. K příkazu CALL patří také příkaz RET, který může být též podmíněný nebo nepodmíněný. Například RET C skáče zpět, když je nastaven indikátor přenosu.
 

5.8.8. Příkaz DJNZ
Speciální příkaz skoku je příkaz DJNZ, který provádí funkci příkazu cyklu. Přitom registr B používá jako počítač smyček. Příkaz DJNZ je spojen s relativní adresou skoku a s odpočítáváním B registru. To může znít velmi složité, ale složité to není.


  1200  06 06       LD   B,06H
  1202  CD 3E 00    CALL 003EH   nechá zaznít tón
  1205  10 FB       DJNZ 1202H
  1207  C3 AD 00    JP   00ADH   skok do monitoru

Když se tento program odstartuje z monitoru pomocí J 1200, zazní 6x tón, protože jsem na začátku uložili do registru B hodnotu 6H, potom jsme standardním programem 003EH zavolali standardní tónový program. Nyní čítač programu narazil na příkaz DJNZ, přičemž od B registru odečte jednotku. B registr obsahuje nyní 5H. Protože tento registr neobsahuje 0, řízení programu skočí na 1202 a znovu se vyvolá tón. Po šesti kolech je B registr 0, takže se již neskáče na adresu 1202, ale pokračuje dále v programu. Pomocí tohoto příkazu se vytvoří smyčka.

Program v BASICu by zněl takto:

 

  FOR T=1 TO 6:USR ($003E):NEXT
 

5.8.9. Příkazy IN a OUT
Tyto příkazy vysílají a přijímají data přes porty. Tím je umožněno provozování externích zařízení jako floppy, tiskárny apod. Vhodným programováním se dají například řídit signály modelů vlaků a mnoho jiných. U MZ-800 mají příkazy OUT a IN často za úlohu provádět řízení přídavné paměti, čili aktivovat nebo deaktivovat oblasti paměti.
 

6. Kapitola programování
 

6.1. Doporučení
Následující příkaz programů jsou napsány tak, že mohou být spuštěny pomocí monitoru MZ-800. Ale pro porozumění je potřeba Disassembler, protože pouze z hexadecimálních čísel se dá těžko vyčíst smysl. Napsané programy se dají spustit z monitoru příkazem J 1200 a vkládat příkazem M. Na to se musí zadat i hexadecimální kód. Po provedení programu se řízení předá zpět do monitoru. Pomocí Disassembleru se dá snadno rozluštit obsah programu.
 

6.2. Jak tisknout ve strojovém jazyce
 

6.2.1. Vytisknutí textu na displej
Při tisknutí ve strojovém jazyce je nejpříjemnější, dá-li se použít standardní program monitoru. To se musí text, který chceme vytisknout, napsat na určitou adresu v paměti. Pomocí příkazu M napíšeme na adresu 2000H náš text, například  BBG

  M 2000 (CR)
  42 (CR)      B  v ASCII kódu
  42 (CR)      B
  47 (CR)      G
  0D (CR)         konec textu

Jak vidíte, musí být text, který chceme vytisknout, ukončen ODH. Nyní ještě program, který tento text vytiskne:


  1200  11 00 20    LD   DE,2000H   adresa, textu
  1203  CD 15 00    CALL 0015H      vyvolání tisku
  1206  C3 AD 00    JP   00ADH      skok do monitoru

Takže se nejprve do DE registru nahraje adresa 2000H, na které je text, který chceme vytisknout. Když zavoláme podprogram 0015H, objeví se text na obrazovce. Po provedení J1200 se tedy objevy text BBG na obrazovce.
 

6.2.2. Vytištění jednoho znaku
V popsaném příkladě jsme tiskli na obrazovku libovolně dlouhý text. Nyní chceme na obrazovku vytisknout je jeden znak. Přirozeně pro to můžeme použít výše uvedený program, ale je jednodušší možnost, použit standardní program monitoru 0012H (viz. též standardní programy monitoru). Znak, který má být vytištěn musí být v akumulátoru, než je tiskový příkaz zavolán. Například:
chceme-li vytisknou 0. Na to musíme znát hodnotu v ASCII kódu a tu uložit do akumulátoru (ASCII kód 0 je 30H).

  1200  3E 30       LD   A,30H   vložení 0 (30H)
  1202  CD 12 00    CALL 0012H   tisk
  1205  C3 AD 00    JP   00ADH   skok do monitoru
 

6.3. Čtení klávesnice
 

6.3.1. GET ve strojovém jazyce
Rovněž velmi důležitou součástí programu je testování klávesnice. V monitoru je již testování klávesnice definováno (program monitoru 001BH). Tento program je volán stisknutím klávesy, její hodnota je uložena v akumulátoru. Nebyla-li stisknuta žádná klávesa, je v akumulátoru 00H. Tento program zároveň vytiskne znak stisknuté klávesy na obrazovku.

  1200  CD 1B 00    CALL 001BH     GET program
  1203  28 FB       JR   Z,1200H   není stisknuta
  1205  CD 12 00    CALL 0012H     tisk stisk.klávesy
  1208  C3 00 12    JP   1200H     testování kláves.

Jestliže nyní stiskneme libovolnou klávesu, zobrazí se znak klávesy obrazovce, Tento program se musí přerušit pomocí RESET.
 

6.3.2 INPUT ve strojovém jazyce
Zde jde jako v BASICu o to, zpracovávat celý řetězec znaků. Tento program je uložen v monitoru 0003H. Program uloží celý textový řetězec v ASCII kódu na adrese definovanou registrem DE. Konec řetězce je automaticky ukončen 0DH.

  1200  11 00 20    LD   DE,2000H   oblast textu
  1203  CD 03 00    CALL 0003H      progr. INPUT
  1206  CD 06 00    CALL 0006H      nový řádek
  1209  CD 15 00    CALL 0015H      tisk textu 120C  C3 AD 00    JP   00ADH  skok do monitoru

To je program, který přečte text, uloží ho od adresy 2000H a potom text vytiskne ještě jednou na obrazovku (J 1200). Text si můžeme prohlédnout příkazem monitoru D.
 

6.3.3. Kurzorový vstup ve strojovém jazyce
Další možnost vstupu znaku z klávesnice je pomocí programu monitoru 09B3H. Při vyvolání tohoto programu bliká korsor na obrazovce a čeká na vklad znaku z klávesnice. Jestliže je stisknuta klávesa, je hodnota této klávesy ve video kódu v akumulátoru.

  1200  CD B3 09    CALL 09B3H       vyzvedne znak
  1203  32 00 D0    LD   (D000H),A   umístní znak
  1206  C3 AD 00    JP   00ADH       skok do monitoru

Tento program vyzvedne znak z klávesnice a uloží ho na adresu D000H. Tato adresa patří video-paměti a je to první adresa v této paměti. Zda se tedy objeví na obrazovce vlevo nahoře.
 

6.4. Dimenzování ve strojovém jazyce
Nejpozději při ukládání dat do paměti potřebuje každý programátor pole. V BASICu se pro to používá příkaz DIM, ve strojovém jazyce si takový program musíme sami napsat. Nyní provedeme jednoduché dimenzování pole ve strojovém jazyce a porovnáme ho s BASICem. Nejprve příklad v BASICu:

  10 DIM A(4)
  20 A(0)=10000:A(1)=10001:A(2)=10003:A(3)=10005:A(4)=0
  30 X=1:PRINT A(X)

Tento program by nám vytiskl na obrazovku číslo 10001. Naše data musíme v paměti ukládat od definované adresy a to ne v dekadickém systému, ale jako hexadecimální data. Uložíme našich pět dat za adresu 3000H. Dá se říci, že začátek tabulky téměř odpovídá jménu proměnné. Jestliže bychom zvolili jiný začátek, dosáhli bychom samozřejmě jiných hodnot.

Za adresou 3000H v paměti musí být následující hodnoty (překontrolujte pomocí příkazu D monitoru):

  D3000
  3000 10 27 11 27 13 27 15 27
  3008 00 00

To jsou hexadecimální hodnoty A(0) - A(4). Nyní potřebujeme dva parametry

  a) naši proměnnou (zde adresa 3000H)
  b) naše X (příklad v Basicu)

Jestliže první parametr máme 3000H a druhý parametr 1H, měla by nám být vydána hodnota 2711H (10001 dek.), jako příklad v BASICu.

  1200  3E 01       LD   A,01H      v Basicu X=1
  1202  21 00 30    LD   HL,3000H   začátek dat
  1205  87          ADD  A          když 16 bit  A*2
  1206  06 00       LD   B,06H      uložení hodoty z
  1208  4F          LD   C,A        akum. do BC reg.
  1209  09          ADD  HL,BC
  120A  5E          LD   E,(HL)
  120B  23          INC  HL
  120C  56          LD   D,(HL)
  120D  EB          EX   DE,HL
  120E  CD BA 03    CALL 03BAH      tiskne hodnotu HL
  1211  C3 AD 00    JP   00ADH      skok do monitoru

Jestliže nyní vložíme J1200, tak se na obrazovce objeví číslo 2711H. Nyní změníme adresu na 1201H, která odpovídá našemu X. Jestliže napíšeme 0, dostaneme 2710H (10000 dek.). Uvnitř tohoto programu jsou části, které můžeme často použít jako užitečné programy. Podívejme se na program ještě jednou.

Nejprve máme vstupy obou parametrů. potom. Potom provedeme ADD,A proč ? Zcela jednoduše, jestliže máme 1 jako první parametr a 3000H jako druhý parametr, pak adresa, na které je naše hodnota, musí být 3002H, protože máme dvou bytové hodnoty. Čili musíme A zdvojnásobit, pomocí ADD A. Potom musíme tuto novou hodnotu akumulátoru přičíst k našemu začátku tabulky (začátek tabulky je 3000H), což musí dát 3002H. Potřebujeme tedy jen program, který sčítá HL a akumulátor (ADD HL,A).

  2000  C5      PUSH BC      zabraň BC, nutné
  2001  06 00   LD   B,00H   vlož do BC
  2003  4F      LD   C,A     akumulátor
  2004  09      ADD  HL,BC
  2005  C1      POP  BC      vrať BC
  2006  C9      RET

Nyní chybí program, který z této adresy, která je v HL, uloží 16-ti bitovou hodnotu do registru HL, čili ulož do HL obsah adresy z HL (LD HL,(HL)).

  2007  D5      PUSH DE      zabraň DE, nutné
  2008  5E      LD   E,(HL)
  2009  23      INC  HL
  200A  56      LD   D,(HL)
  200B  EB      EX   DE,HL
  200C  D1      POP  DE
  200D  C9      RET

Nyní můžeme program napsat ještě jednou s použitím podprogramu.

  1200  3E 01       LD   A,01H
  1202  21 00 30    LD   HL,3000H
  1205  87          ADD  A
  1206  CD 00 20    CALL 2000H    ADD HL,A
  1209  CD 07 20    CALL 2007H    LD  HL,(HL)
  120C  CD BA 03    CALL 03BAH    tisk na obrazovku
  1210  C3 AD 00    JP   00ADH    skok do monitoru

Program můžeme odstartovat opět pomocí J1200, měnit adresu 1201H.
 

6.5. Smyčky
Smyčky jsou při vytváření programu velice důležitá věc, ale při smyčkových proměnných, které jsou větší než 255, není možno použít příkaz DJNZ. Zde se musí zhotovit nová smyčka. Napíšeme si program, který nechá 1000 x zaznít tón (prosím raději nezkoušet, chudák reproduktor).

  1200  01 E8 03    LD   BC,03E8H   uloží do BC 1000
  1203  C5          POSH BC         zajistí BC
  1204  CD 3E 00    CALL 003EH      zazní tón
  1207  C1          POP  BC
  1208  0B          DEC  BC
  1209  78          LD   A,B
  120A  B1          OR   C
  120B  C2 03 12    JP   NZ,1203H
  120E  C3 AD 00    JP   00ADH      skok do monitoru

Jak vidíte, registr BC je použit jako čítač smyček. Proto musí být tato hodnota zajištěna pomocí PUSH BC, pro případ, že by registr BC byl změněn uvnitř smyčky. Po provedení standardního programu, ležícího ve smyčce (zde 003EH),musí být hodnota BC opět zajištěna. Potom musí být počet smyček sníženo jednu a musí být zjištěno, zda již není nulový, protože v tom případě by byl program přerušen. Zjištění, zda registr BC je nulový se provádí kombinací LD A,B a OR C. Vzpomeňme si, že pokud jsou obě části 0, je výsledek 0. Takže pouze pokud jsou nulové oba registry B i C, je nastaven Z-flag. Potom je smyčka přerušena, jinak se pokračuje v jejím provádění.
 

6.6. Dvojkový výraz v akumulátoru
Zde je krátký příklad programu, který vytiskne obsah akumulátoru na obrazovku jako 8-místné dvojkové číslo. Dá se použít jako podprogram.

  2000  C5          PUSH BC
  2001  F5          PUSH AF
  2002  06 08       LD   B,08H
  2004  07          RLCA
  2005  F5          PUSH AF
  2006  3E 30       LD   A,30H
  2008  30 01       JR   NC,200B
  200A  3C          INC  A
  200B  CD 12 00    CALL 0012H
  200E  F1          POP  AF
  200F  10 F3       DJNZ 2004
  2011  F1          POP  AF
  2012  C1          POP  BC
  2013  C9          RET

Základní myšlenka programu je v tom, že obsah akumulátoru je otáčen pomocí indikátoru přenosu. PO každé rotaci je indikátor přenosu nastaven nebo ne, podle toho co obsahuje 7-mí bit s akumulátoru. Jestliže je idikátor přenosu nastaven, vytiskne se 1, je-li nulový, vytiskne se 0.

 

6.7. Převod hexadecimálního čísla na dekadické
Pomocí tohoto programu se obsah registru HL objeví na obrazovce dekadické číslo.

  1200  A7          AND  A
  1201  ED 52       SBC  HL,DE      dělení mocninou 10
  1203  38 04       JR   C,1209H
  1205  3C          INC  A
  1206  10 F8       DJNZ 1200H
  1208  C9          RET
  1209  19          ADD  HL,DE      při přenosu korigovat
  120A  C9          RET
  120B  C5          PUSH BC         DE = BC
  120C  D1          POP  DE
  120D  AF          PUSH AF
  120E  C9          RET
  120F  00          NOP
  1210  CD 0B 12    CALL 120BH
  1213  06 0A       LD   B,0AH
  1215  CD 00 12    CALL 1200H      program dělení
  1218  C6 30       ADD  30H        převod do ASCII
  121A  C3 12 00    JP   0012H      vytisknutí
  121D  01 10 27    LD   BC,2710H   10000 dekadicky
  1220  CD 10 12    CALL 1210H
  1223  01 E8 03    LD   BC,03E8H   1000 dekadicky
  1226  CD 10 12    CALL 1210H
  1229  01 64 00    LD   BC,0064H   100 dekadicky
  122C  CD 10 12    CALL 1210H
  122F  01 0A 00    LD   BC,000AH   10 dekadicky
  1232  CD 10 12    CALL 1210H
  1235  01 01 00    LD   BC,0001    1 dekadicky
  1238  C3 10 12    JP   1210H

Když chceme tento program otestovat, např. chceme znát dekadickou hodnotu hexadecimálního čísla C000H, musíme napsat
 

  2000  21 00 C0    LD   HL,C000H

  2003  CD 1D 12    CALL 121DH
  2006  C3 AD 00    JP   00ADH

Provedeme-li příkaz  J 2000  se na obrazovce objeví číslo 49152. Nyní musíme jen uložit hexadecimální číslo na adresu 2001H, spustit program a dostaneme příslušné decimální číslo. Ještě něco k porozumění programu. Dělíme naše číslo příslušnými mocninami deseti tak dlouho, dokud nevznikne přenos, čili nejprve 10000. Ve 43243 je obsaženo 4x, vytiskne se 4, zbytek dělíme 1000 atd.
 

6.8. Převod dekadického čísla na hexadecimální
Napíšeme krátký program, který vyzvedne pětimístné dekadické číslo s klávesnice a převede ho na hexadecimální

  1200  CD B3 09    CALL 09B3H      vyzvedne číslo
  1203  CD CE 0B    CALL 0BCEH      video kód na ASCII
  1206  F5          PUSH AF         zachraň vlož.číslo
  1207  CD 12 00    CALL 0012H      tisk čísla
  120A  F1          POP  AF         vyzvedne číslo
  120B  D6 30       SUB  30H        převádí na hexa.
  120D  47          LD   B,A        nastav. smyček
  120E  B7          OR   A          je číslo nula (0)
  120F  C8          RET  Z          když ano, pak zpět
  1210  19          ADD  HL,DE      přečte mocninu
  1211  10 FD       DJNZ 1210H
  1213  C9          RET
  1214  CD 06 00    CALL 0006H      posun řádky
  1217  21 00 00    LD   HL,0000H   inicializace HL
  121A  11 10 27    LD   DE,2710H
  121D  CD 00 12    CALL 1200H      vyvolání výpočtu
  1220  11 E8 03    LD   DE,03E8H   1000 dekadicky
  1223  CD 00 12    CALL 1200H
  1226  11 64 00    LD   DE,0064H   100 dekadicky
  1229  CD 00 12    CALL 1200H
  122C  11 0A 00    LD   DE,000A    10 dekadicky
  122F  CD 00 12    CALL 1200H
  1232  11 01 00    LD   DE,0001H   1 dekadicky
  1235  CD 00 12    CALL 1200H

  1238  CD 06 00    CALL 0006H      posun řádky
  123B  CD BA 03    CALL 03BAH      tisk obsahu HL
  123E  C3 AD 00    JP   00AD       skok do monitoru

Tento program ze dá volat z monitoru příkazem  J 1214. Zadané dekadické číslo se převede na hexadecimální. Ještě něco k porozumění. Při pětimístném čílse, např. 45225 se mohou jednotlivé mocniny deseti nasčítat, takže principiálně se sčítání provádí podle následujícího schématu.

  45225 = 4*10000 + 5*1000 + 2*100 + 2*10 + 5*1
 

6.9 Přídavné příkazy Z-80
Přídavné příkazy Z-80 je něco, o čem není zmínka v žádné literatuře o Z-80. Rozsah příkazů procesoru zahrnuje totiž asi 1000 příkazů, místo známých 400. Z největší části se přitom jedná o příkazy, pro řízení registrů HX, HY, LX a LY. Jak jsme se již zmínili, jedná se přitom o 8-mi bitové registry a to vždy o vyšší a nižší byt registru IX a IY. Přitom je opcode přikloněn ke kódům registrů H a L, právě tak jako  IX a IY, právě tak jako IX, IY jsou přikloněny k opcode registru HL.

  2000  26 77       LD    H,77H
  2002  DD 26 77    LD    HX,77H

Takže se jednoduše napíše DD nebo ED a už je možnost výběru z obrovské palety příkazů. Musíme si dát pozor, protože téměř žádný Disassembler není schopen tyto příkazy přečíst, protože není schopen tyto příkazy přečíst, protože o nich není nikde zmínka. V naší nabídce naleznete Disassembler, který je schopen tyto příkazy přeložit.

 

Úvod | Sharp MZ-800 | 8 bit klub Brno | Download | Kniha návštěv | Vyhledání na těchto stránkách | Mapa stránek

 

Tyto stránky byly naposledy aktualizovány dne 08. 02. 2014      Copyright © 05/2006 - SCAV - Pavel Brázda webmaster(c)scav.cz

 

 

Google