str.21

----------------------------------------
|Binárně   |Hex  |Dec  |ASCII |MZ-800  |
|----------|-----|-----|------|--------|
|01000000  |40   |64   |@     |@       |
|01000001  |41   |65   |A     |A       |
|01000010  |42   |66   |B     |B       |
|01000011  |43   |67   |C     |C       |
|01000100  |44   |68   |D     |D       |
|01000101  |45   |69   |E     |E       |
|01000110  |46   |70   |F     |F       |
|01000111  |47   |71   |G     |G       |
|01001000  |48   |72   |H     |H       |
|01001001  |49   |73   |I     |I       |
|01001010  |4A   |74   |J     |J       |
|01001011  |4B   |75   |K     |K       |
|01001100  |4C   |76   |L     |L       |
|01001101  |4D   |77   |M     |M       |
|01001110  |4E   |78   |N     |N       |
|01001111  |4F   |79   |O     |O       |
|--------------------------------------|
|01010000  |50   |80   |P     |P       |
|01010001  |51   |81   |Q     |Q       |
|01010010  |52   |82   |R     |R       |
|01010011  |53   |83   |S     |S       |
|01010100  |54   |84   |T     |T       |
|01010101  |55   |85   |U     |U       |
|01010110  |56   |86   |V     |V       |
|01010111  |57   |87   |W     |W       |
|01011000  |58   |88   |X     |X       |
|01011001  |59   |89   |Y     |Y       |
|01011010  |5A   |90   |Z     |Z       |
|01011011  |5B   |91   |[     |[       |
|01011100  |5C   |92   |\     |\       |
|01011101  |5D   |93   |]     |]       |
|01011110  |5E   |94   |^     |^       |
|01011111  |5F   |95   |-     |-       |
----------------------------------------

----------------------------------------
|Binárně   |Hex  |Dec  |ASCII |MZ-800  |
|----------|-----|-----|------|--------|
|01100000  |60   |96   |`     |  viz   |
|01100001  |61   |97   |a     |dodatek |
|01100010  |62   |98   |b     |   A    |
|01100011  |63   |99   |c     |        |
|01100100  |64   |100  |d     |        |
|01100101  |65   |101  |e     |        |
|01100110  |66   |102  |f     |        |
|01100111  |67   |103  |g     |        |
|01101000  |68   |104  |h     |        |
|01101001  |69   |105  |i     |        |
|01101010  |6A   |106  |j     |        |
|01101011  |6B   |107  |k     |        |
|01101100  |6C   |108  |l     |        |
|01101101  |6D   |109  |m     |        |
|01101110  |6E   |110  |n     |        |
|01101111  |6F   |111  |o     |        |
---------------------------------------|

str.22

|--------------------------------------|
|01110000  |70   |112  |p     |  viz   |
|01110001  |71   |113  |q     |dodatek |
|01110010  |72   |114  |r     |   A    |
|01110011  |73   |115  |s     |        |
|01110100  |74   |116  |t     |        |
|01110101  |75   |117  |u     |        |
|01110110  |76   |118  |v     |        |
|01110111  |77   |119  |w     |        |
|01111000  |78   |120  |x     |        |
|01111001  |79   |121  |y     |        |
|01111010  |7A   |122  |z     |        |
|01111011  |7B   |123  |{     |        |
|01111100  |7C   |124  ||     |        |
|01111101  |7D   |125  |}     |        |
|01111110  |7E   |126  |~     |        |
|01111111  |7F   |127  |DEL   |        |
----------------------------------------

Pomocí hexmonitoru z učebního learn souboru můžete ukládání
textů okamžitě vyzkoušet.
Příklad:
        Pohybujte kursorem <tlačítkem ALPHA> až do okénka
        hexmonitoru.
Zadejte pomocí <INST> adresu A=8000
Na vstup dávejte
                TEST následováno <CR>
V okénku najděte teď.

      ----------------------------------
      |8000 :   T   54                 |
      |8001 :   E   45                 |
      |8002 :   S   53                 |
      |8003 :   T   54                 |
      |8004 :   .   00                 |
      |8005 :   .   00                 |
      |8006 :   .   00                 |
      |8007 :   .   00                 |
      ----------------------------------

     Text TEST je nyní uložen do paměti. Hodnoty, které vlastní každé
písmeno v ASCII najdete vedle písmena.

 3.2 Císlice, texty a programy BASIC
 -----------------------------------

     Jak jste viděli, lze tedy v jedné paměťové buňce jen jediný
znak textu v kódu ASCII. Stejně tak lze ukládat jednoduchá
dvojková čísla mezi 0 a 255. Při tom nutno je si uvědomit, že
jsou různé možnosti, jak znázornit čísla. Můžete čísla ukládat
jako text tím, že použijete pro cifry 0-9 znaky ASCII. Právě tak
lze ukládat čísla jako binární hodnoty.

str.23

Příklad:
        Vyjádření čísla 27 (desítkově)
Dvojková hodnota znázorněna šestnáctkově 18
ASCII kód pro 2 a 7     3237 
Ve znázorňování čísel existují ještě další možnosti. V dodatku
A některé z nich najdete. Kódování je umění s cílem umístit co
nejvíce informací do pokud možno nejmenšího prostoru v paměti,
přičemž úsilí pro jejich zpětné získání má být co nejmenší.
Programy BASIC se např. ukládají jako pestrá směs znaků ASCII,
číslic ve dvojkové soustavě a tzv. Tokenů. U Tokenů se jedná
o speciální kódy pro typická slova BASIC, jako GOTO, PRINT atd.
Protože tím, že tato slova nejsou v paměti vypsána v ASCII kódu,
nýbrž speciálním kódem uspoří se tak prostor v paměti.

 3.3 Strojvý program.

   OP kódy a dvojkvá čísla
     Právě jako v programu BASIC mohou se ukládat i strojové
programy do paměti. Na místo Tokenů BASIC se používají pro povely
speciální kódy tzv. OP-kódy (operatien codes).
Příklad:
Odpovídající povel příkazu BASIC GOTO 1000 je ve strjové řeči
JP 1000
pro JUMP (skoč) na adresu 1000. Právě tak jako u GOTO pokračuje
program na jiném místě.
Příkaz, JP 1000 vyžaduje však 3 Byty a je zachycen v paměti
takto:
      první řádek: C3      OP kód: JP 
      druhý řádek: 00      adresa: L-Byte
      třetí řádek: 10      adresa: H-Byte
     S příkazy ve strojovém jazyku jeho OP kódem a nutnými údaji
adresy se v následujícím budeme blíže zabývat. Zde šlo pouze o
to, ukázat, že zcela odlišné věci se mohou ukládat do paměti, i
když se vlastně ukládají pouze dvojková čísla.

 KAPITOLA 4

 Strojový jazyk: První přehled
 -----------------------------
     V tomto odstavci přicházíme k jádru věci. Předkládáme vám
první přehled o programování ve strojovém jazyce a podnikneme
hned první zkušební krůčky. K tomu je potřeba se přesněji zaměřit
na CPU , což znamená, že se na chvíli musíme zabývat suchou
teorií.
 4.1 CPU: Srdce všeho
     Srdce každého počítače je CPU (Central Processing Unit)
ústřední procesorová jednotka, která provádí téměř všechny
operace v počítači. Sám od sebe však CPU nedělá nic. Potřebuje
detaijlované příkazy, co má vykonat, a to dostane ze strojového
programu. Na štěstí obsahuje ROM vašeho počítače již několi
tisíc příkazů ve strojovém jazyku pro CPU, protože jinak byste
po zapnutí počítače nemohli nic vložit, načež nechat proběhnout
program. CPU vašeho počítače je výkonný 8mi Bitový mikroprocesor
Z 80 vyvinutý fy Zilog, je nástupcem Intel 8080, a obsahuje jeho
kompletní povelovou sadu jakož i bezpočet přídavných funkcí. Jak
vypadá CPU? Především obsahuje Z 80 jako každý CPU řadu interních
paměťových buněk tzv. registry. Tyto interní paměťové buňky mají
též svoje zvláštní pojmenování: A, F, BC, BE, HL, IX, IY, SP, PC.
Budeme se teď zabývat významy těchto registrů.

str.24

Přehled:
A             8mi bitový akumulátor
         F    8mi bitový Flagregistr s příznaky SZHP/VNC
BC            16ti bitový registr BC resp. 8mi bitový pár B, C
DE            16ti bitový registr DE resp. 8mi bitový pár D, E
HL            16ti bitový registr HL resp. 8mi bitový pár H, L
IX            16ti bitový indexový registr
IY            16ti bitový indexový registr
SP            16ti bitový Stack pointer
PC            16ti bitový Programm counter

     Registry představují krátkodobou paměť CPU. Jsou používány
ve strojovém programu k tomu, aby se krátkodobě zachytily data
pro později prováděné operace.Typický sled příkazů ve strojovém
programu by mohl vypadat takto:
-zaveď registr A obsahem paměťové buňky 1000
-odečti B od A
-ulož obsah A do paměťové buňky 1001
Toto odpovídá příkazům BASIC:
-A = PEEK (1000)
-A = A - B
- POKE 1001, A
     Takovéto BASICové přirovnání vám budeme dávat co možná
nejčastěji, protože umožňují (doufejme) snažšímu porozumnění
strojových povelů. Avšak zpět k registrům. Registry se ve
strojových povelech používají rozdílným způsobem. Proto si
jednotlivé registry proberemel separátně.

Registr A (akumulátor).
Akumulační registr A má stejný objem jako paměťové buňky RAM
nebo ROM, právě jeden Byte (8 Bit). Většina operací strojového
jayzka se odehrává v akumulátoru přičemž se výsledek těchto
operací tam ukládá. Typický sled příkazů:
- zaveď do A obsah paměťové buňky 1000       (A=PEEK(1000))
- sečti 10 s obsahem A                       (A=A+10)
- ulož obsah A                               (POKE 1000, A)
Akumulátor je tedy ten operační registr. Nacházíme ho skoro ve
všech osmibytových mikroprocesorech (8O80, 6800, 6809, 6502).

Registr BC, DE, HL.
Tyto registry mají objem 16 Bit (2 Byte) a mohou proto přijmout
právě údaj jedné adresy (hex.0000 ... FFFF).Přesně to je také
jejich nejdůležitejší funkce, při provádění mnohých strojových
povelů nesou jednu paměťovou buňku s adresou, na kterou má být
operace provedena.
Příklad:
- zaveď do A obsah paměťové bunky jejíž
  adresa je v registru HL                    (A=PEEK(HL))
- ulož obsah  do paměťové buňky jejíž
  adresa je v registru BC                    POKE BC, A
     Protže registry BC, DE a HL přitom ukazují na pamťové buňky,
nazývají se též ukazovací registr (Point register). Samozřejmě
se tyto registry mohou použít jako mezipaměť, přičemž se mohou
oba jednotlivé Byty u těchto dvou Bytovch registrů používat
separátně.Registrový pár BC se pak skládá z dvou osmibitových
registrů B a C, registr DE z D a E, registr HL z H a L.

str.25

Příklad:
- zaveď do A obsah registru B     (A=B)
- odečti od A obsah registru C    (A=A-C)
- ulož A do registru D            (D=A)
     Registr HL hraje přitom zvláětní roli. Je několik příkazů
podle nichž působí HL registr jako akumulátor pro 16ti Bitové
hodnoty. Např. je možno jediným povelem přečíst obsah jiného
16ti Bitového registru k HL registru.

Programové počítadlo PC.

     Programové počítadlo (Programcounter) potřebuje CPU,
aby si během postupného vykovávání příkazů pamatoval, jak
pokračuje strojový program dále. CPU to dělá zrovna tak jako
vy, když například si krok po kroku probíráte nějaký návod k
obsluze a přitom ukazováčkem spočíváte namístě, které právě
studujete. Napřed je přečten pokyn, přičemž putuje ukazováček
dále textem. Když je kompletní pokyn přečten, zůstává ukazováček
stát a pokyn je proveden. Programové počítadlo je ukazováčkem
CPU. Protože příkazy strojového programu jsou stále v paměti
počítače, obsahuje programové počítadlo vždy adresu paměťové
buňky při které začíná příští příkaz. Příkaz je přečten,
počítadlo počítá přitom dále, až CPU naplní kompletní příkaz.
Programové počítadlo pak již ukazuje na počáteční adresu příštího
příkazu, zatímco čtený příkaz je převáděn CPU. Tento cyklus
opakuje PU při každém příkazu. Programové počítadlo je u každého
mikroprocesoru.

CPU - stack.
     CPU - stack (stoh) je zvláště pro CPU rezervovaný obsah
RAM. Během používání učebního souboru (learn paket) pokrývá
rozsah adres od hex. A000 dolů. Stack používá CPU aby si
zapamatoval při podprogramových pokynech (jako GOSUB a RETURN
v BASICu), kde se po návratu od podprogramu bude zase pokračovat.
Po každém pokynu podprogramu zůstává na stacku uložena adresa
zpětného skoku. Dejme tomu, že byste si denní kancelářskou práci
organizovali takto:
     pokaždé, jste-li přerušen při činnosti, odložte právě
zpracovaný list na hromadu (stoh) a načněte nový list. Na novém
listu zaznamenejte pak toto přerušení. V případě, že budete znovu
přerušeni, učiňte totéž jako předtím. Pokaždé, když naopak děj
byl zpracován, či přerušení bylo ukončeno vezněte si nejhořejší
list ze stohu a pokračujte na jeho zpracování. To je tedy ten
naposledy přerušený postup na kterém pak pokračujete. Takto lze
při tomto postupu libovolně od sebe škatulkovat přerušení, jak
je třeba, když při provádění jednoho přerušení přichází další
přerušení, atd. Přesto se vždycky najde cesta zpátky a zpracují
se všechny postupy až dokonce. Přepracovaní manažéři mívají ve
zvyku čas od času příliš narostlý stoh přenést především jinam a
založit nový.To šetří přáci, ale natrvalo nepřinese nic jiného,
než nepříjenosti. Ne tak u CPU. Vrství list po listu, aby
příležitostně zprcoval po čase všechny. V tom je velice
svědomitý! 
     Stack CPU je jako stoh organizován jako paměť  Last-in-first
 out. Poslední odložená hodnota se odebírá opět jako první ze
stohu (viz. odst. 1.2). Vyskytne-li se přerušení programu, nebo
když je způsoben podprogram, CPU odkládá okamžitý program
počítadla programu PC na stoh, aby při skončení podprogramu
nebo přerušení jej mohl vzít opět ze stohu zpět.

str.26

Stackpointer SP
---------------
Pomocí Stackpointeru (stohový ukazatel) registru si CPU pamatuje
až do které adresy je stack naplněn. SP obsahuje vždy adresu
následující volné pozice ve Stacku. To odpovídá místu, na které
byste odložili příští list. Když se ze stacku odebírá hodnota,
vrací se stackpointer zase na předcházející stav. SP ukazuje
tedy vždy na nejbližší volné místo nad stohem, které není nic
jiného, než rezervovaný rozsah RAM. Stack a příslušný registr
stackpointeru se vyskytuje u každého mikroprocesoru.

Flagregistr F

     Šest z osmi bitů registru F-Flagy (příznaky)- obsahují
informace o stavu CPU podle naposled provedených operací. Proto
se někdy tento registr nazývá stavový registr.
Oba nejdůležitější flagy jsou:

Z   Zero Flag  jeli výsledek operace 0
     (nula)     je Z=1, jinak Z=0

C   Cassy Flag nastane-li po součtu nebo
               odečtu přenos na další místo (viz. 1.5)

Tyto flagy udávají např. výsledek porovnávacích operací. Při
porovnávací operaci provede CPU jednoduše odečítání. Výsledkem
je 0, jestliže obě hodnoty byly stejné.

Příklad:
Porovnej obsah A s obsahem B
Výsledek
Z=1    hodnoty jsou stejné    A=B
Z=0    hodnoty jsou nestejné  A<>B

Stav flagů lze v programu testovat pomocí podmíněných skokových
příkazů. Tyto příkazy pracují dle schematu:

Když Z=0 skoč k adrese ... (IF Z=0 GOTO ... )
Když C=1 skoč k adrese ... (IF C=1 GOTO ... )

Typický sled příkazů vypadá ve strojovém jazyce takto:
Srovnej A s B
Když Z=1 skoč k adrese ...
Toto odpovídá příkazu BASIC.

Pro úplnost se chceme zmínit o zbylých flagech i když je zatím
nepotřebujeme.

S    Sign       má po aritmetických povelech znaménko S=0,
                pozitivní, S=1 negativní

H    Halfcarry  obsahuje po aritmetických povelech přenos z
                nízkohodnotového polovičního bytu na poloviční
                byt vyšší hodnoty (B3 po B4)

str.27

P/V Parity/     má po logických povelech paritu P=0, nerovná
    Overflow    parita, P=1 rovná parita
Při aritmetických operacích s předznamenanými čísly značí V=1
přechod z rozsahu -128 ... + 127 (viz.dodatek A3).

N    Subtract   Označuje po aritmetických povelech typ příkazu
                N=0 sčítání, N=1 odečítání (Použije se pro příkaz
                DAA).
Které operace flagy ovlivňují a které ne, nutno vyčíst z popisů
strojových povelů. U každého mikroprocesoru přitom platí jiná
pravidla, což bohužel ztěžuje programátorovi práci. Právě při
Z80 je vliv flagů částečně velice neprůhledný.

Registr IX a IY
---------------
     Pro úpůnost by měla být zmínka o registru IX a IY. Jedná
se tu o tzv. indexové registry, které jsou používány rovněž k
adresování operandů.

Druhá registrová sada Á',F',BC',DÉ',HL'
---------------------------------------
     Registry A,F,HL,BC,DE se vyskytují v Z-80 zdvojeně. Dvěma
instrukcemi lze přepínat z jedné sady registru na druhou.
Protože tato druhá sada registů není v jednoduchých programech
potřebná, nebudeme se zde tím dále zabývat.

4.2 Jak vypadají strojové programy?
-----------------------------------
     Příkazy ve strojovém jazyku jsou ve srovnání s příkazy
BASIC relativně primitivní, zato však jsou podstatně rychleji
prováděny. Zatímco BASIC zpracuje za sekundu nejvýše 100 příkazů,
stačí zpracovat CPU několik 100 000 příkazů. Ale právě proto, že
strojové příkazy jsou relativně primitivní, je většinou v
programu zapotřebí též většího počtu povelů, aby se dosáhl tentýž
výsledek, který dosáhne jediný povel BASIC.
     Jak jste se přesvědčili, vztahuje se většina příkazů
strojového jazyka přímo k registru CPU nebo k paměťovým buňkám.
Chceme-li např. sečíst obsahy dvou paměťových buněk, musíme
nejprve obsah jedné buňky a výsledek znovu uložit zpět. V BASICu
se postupuje komfortněji, protože lze používat proměnné a
kompletní numerické výrazy.

Příklad:
Příkaz BASIC   x=Y+Z-5  by ve strojovém jazyku byl:
-zaveď do A obsahem buňky č.2(Y)
-sečti buňku č.3 (Z) s A
-odečti číslo 5 od A
-ulož A do paměť.buňky č.1 (X)

Přitom se musí samozřejmě udávat adresy paměťových buněk
ztěžující okolností je, že CPU počítá hlavně s 8mi bitovými
hodnotami, tzn. čísla musí u shora uvedeného příkladu být v
rozsahu 0...255. Sice Z-80 nabízí ještě možnost pomocí jedné
instrukce sečítat 16ti Bitové hodnoty, chceme-li ale sečítat
ještě větší čísla, pak se musí v programu provádět sčítání
postupně po místech s prováděním přenosu, avšak o tom až později.
Přesto nejsou věci příliš obtížné, máme-li potřebné podprogramy
pohromadě a mnoho problémů se dá ve strojovém jazyku řešit
elegantně a efektivně.

str.28

Mnemonics, Op kódy
Symbolika
------------------
     Příkazy strojového jazyka mají vždy určité pojmenování,
tato jména nazývá symbolikou (mnemonics). Symbolické názvy jsou
většinou anglické zkratky pro funkce povelů.
Příklad:
Symbol povelu  zaveď do A obsah paměť. buňky 1000  zní  LD  pro
zaveď (Load), úplný příkaz zní  LD A,(1000).
Seznam všech symbolů Z-80 CPU najdete v dodatku B2.
     Kromě symbolu se v úplném příkaze udávají jeden nebo dva
operandy, s kterými se má příkaz provést.

Příklad:
V příkaze LD A,(1000) jsou operandy  A a paměťová buňka s adresou
1000.

Symbolická forma příkazů má však programátorovi jenom pomoci. 
Ukládány jsou jednotlivé příkazy strojového programu v podobě
číselného kódu, tj.v paměti není název příkazu, nýbrž kód, tzv.
OP-kód (operation code).

Přklad:
příkaz LD A,B        Cp Code 78
příkaz LD A(1000)    Op Code 3A 00 10

Vidíte, že Op-kódy příkazů mají různé délky, první příkaz vyžaduje
1 Byte, druhý zato 3 Byte. Pozoruhodné je, že u dr
uhého příkazu se píše napřed Low-Byte (00) a potom High-Byte (10) v adrese
(toto je obvyklé i u jiných procesorů
např.8080, 6502). V dodatku C najdete
Op kódy pro všechny příkazy strojového
jazyka.

4.3.Zavedení a test strojových programů
---------------------------------------
     Pomocí  Line Assembleru  z učebního souboru (nejdelší okénko
programovacího vidu) můžete zadávat strojové programy přímo
formou symboliky. Assembler přebírá pak převod do Op-kódu a
ukládá upravený strojový program do RAMu. Nemáte-li k dispozici
Assembler, musíte sami překládat strojové programy do Op-kódů,
a pak kódy zavést. Obvykle se to děje pak pomocí příkazu BASIC
POKE.

První strojový program
----------------------
     Abychom si mohli vyzkoušet zavedení a testování strojového
programu dejme si jednoduchý příklad:
Do registrů A,B,C... se po řadě mají zadat čísla 11,22,33...77.
K tomu se použiijí zadávací povely, jak již znáte. Číslo, které
se má dát do registru se přitom bezprostředně zadává.

str.29

Program vypadá v mnemotechnické formě takto:

Příkaz             Působnost

LD A,11            A=11
LD B,22            B=22
LD C,33            C=33
LD D,44            D=44
LD E,55            E=55
LD H,66            H=66
LD L,77            L=77
RET                RETURN

     Na konci tohoto programu je příkaz RET (RETURN). Tento je
nutný u všech programů, které byly vyvolány učebním programem
nebo z BASICu. Příkaz RET obstarává návrat k vyvolanému programu.
Jestliže chybí rozloučí se s vámi váš počítač ve strojovém
programu natrvalo.

Když proberete tabulku příkazů v dodatku C najdete v zaváděcích
příkazech programu následující Op-kódy:

Příkaz (mnemonicky)Op-Kode (hex)
LD A,11            3E 11
LD B,22            06 22
LD C,33            0E 33
LD D,44            16 44
LD E,55            1E 55
LD H,66            26 66
LD L,77            2E 77
RET                C9

     Díky Assembleru nepotřebujete tento překlad do Op-kódu
provádět sami, to provede assembler za vás. Tak zavedete program:

V programovacím vidu uveďte kurzor pomocí <ALPHA> do nejspodnějšího
okénka.

Teď zvolte adresu 8000 (klávesa <INST>). Vedle příkazu assembleru,
který tam již je, můžete teď zavést  LD A,11. Na to zadáváte
ostatní příkazy. Po dokončení odjeďte kurzorem opět do monitorového
okénka. Teď můžete přezkoušet, zda v rozsahu adres 8000...800E
je všechno správně přeloženo do Op-kódů. Nechte si ještě jednou
ukázat pro kontrolu kód odassemblovaný, protože kód musí přesně
souhlasit. Jinak udělá CPU některé nedefinovatelné věci a může
nastat zhroucení  počítače. Pro  odassemblování  volte zaváděcí
adresu 8000 a nechte si zobrazit pomocí <CR> program řádek po
řádku. Potom, co jste zkontrolovali příkazy, můžete program
vyzkoušet.

Přitom je Tracer (sledovač-stopovač) právě tou správnou pomůckou
se kterou lze odehrávat pochody zpomaleně a přitom sledovat co
se děje.

str.30

Test strojového programu
------------------------
     Pomocí zkušebního vidu učebního souboru můžete nahlédnout
do všech registrů CPU. Protože je kromě toho možné nechat odehrát
strojový program způsobem jednotlivých kroků, můžete se po
provedení každého jednotlivého příkazu přesvědčit, co se stalo.
Přepojte pomocí <GRAPH> na zkušební vid (testmodus). Teď vypadá
obrazovka takto:
-----------------------------------------
|                                     0 | ---Kalkulator
|---------------------------------------|
| 8000: 3E 11 06 22 0E 33 16 44 >..".3.D| ---Dump
| 8008: 1E 55 26 66 2E 77 C9 00 .U&.....|
|---------------------------------------|
| 8000: LD A,11                         | ---Disassembler
| 8001: LD B,22                         |
|---------------------------------------|
|  A:    BC:   DE:    HL:    F:SZ-H-PNC | ---CPU
|  00    0000  0000   0000     00000000 |
|                                       |
|              IX:    IY:    PC:   SP:  |
|              0000   0000   8000  A000 |
|---------------------------------------|
| * #                                   | ---Příkazové okénko
-----------------------------------------

     Aby bylo možno startovat nějaký program, musíte napřed
zavést do programového počítadla PC startovací adresu strojového
programu.To v tomto případě není však vůbec nutné, jelikož PC
již obsahuje startovací adresu našeho strojového programu 8000.
Povelem  Trace  můžete nechat probíhat program po jednotlivých
krocích, stisknete klávesu <T> a objeví se na indikaci:

-----------------------------------------
| * T :   #                             |
-----------------------------------------

     Když teď aktivujete <šipka dolů> bude proveden první příkaz
programu. Stlačíte-li znovu <šipka dolů> provede se další příkaz.
Přitom označuje ukazatel stavu T vpravo v okénku, že byl startován
strojový program. Dáte-li dvakrát <šipka dolů> uvidíte na stínítku
toto:
-----------------------------------------
|                                     0 |
|---------------------------------------|
| 8000: 3E 11 06 22 0E 33 16 44 >..".3.D|
| 8008: 1E 55 26 66 2E 77 C9 00 .U&.....|
|---------------------------------------|
| 8004: LD C,33                         |
| 8006: LD D,44                         |
|---------------------------------------|
|  A:    BC:   DE:   HL:    F: SZ-H-PNC |
|  11    2200  0000  0000      00000000 |
|                                       |
|              IX:   IY:    PC:    SP:  |
|              0000  0000   8004   9FFE |
|---------------------------------------|
| * #                                T  |
-----------------------------------------

str.31

     Hodnota pod  PC je okamžitým stavem programového počítadla
PC. Udává adresu v pořadí příštího příkazu programu. Nahoře v
disassembleru vidíte, který příkaz to je, totiž LD C,33.

Oba první příkazy  LD A,11 a LD B,22, jsou tedy již provedeny.
Pohlédnete-li na okénko CPU, zjistíte, že všechno fungovalo:
Do A je zavedeno 11, do B 22.

     Příští povely programu můžete nechat provést pomocí <šipka
dolů> a přitom uvidíte, jak počítadlo programu počítá dále a jak
se postupně registry plní danými hodnotami. V obou polích vpravo
u okénka CPU se jedná vlastně o Flagregistr F a o Stackpointer
SP.
Když byl program zcela odehrán, zhasne T - flag v příkazovém
okénku a PC ukáže zase 8000. Teď vidíte v okénku CPU, že všechny
registry byly naplněny danými hodnotami.

-----------------------------------------
|  A:    BC:   DE:   HL:    F: SZ-H-PNC |
|  11    2233  4455  6677      00000000 |
|                                       |
|              IX:   IY:    PC:    SP:  |
|              0000  0000   8000   A000 |
-----------------------------------------

Potom, co jste si vyzkoušeli program ve strojovém jazyce,
doufáme, že vás můžeme zase zatížit trochou teorie.

4.4 Kterým příkazům rozumí CPU?
-------------------------------
     Že podle příkazů ve strojové řeči se operuje jednotlivými
registry nebo buňkami to už víte. O operacích, které jsou přitom
možné, chceme vám dát krátký přehled. Detaily budou teprve látkou
příští kapitoly, celkový přehled všech povelů najdete v dodatku C.

Povely k nabírání
-----------------
Těmito povely se transferují data mezi registry a paměťovými
buňkami.

Skokové povely
--------------
     Těmito povely je pokračováno v programu na jiném místě.
Přitom je vždy udávána adresa pod kterou je instrukce uložena
a kde má být v programu pokračováno.
Příklad:

JP     'Jump'           'Skoč na'                GOTO
CALL   'Call subroutine''Podprogramový skok na'  GOSUB
RET    'Return'         'Návrat'                 RETURN

Jestliže CPU se setká v některém podprogramu na nějaký povel
RET, vrátí se tento zpět na místo, ze kterého byl podprogram
vyvolán a odtud pracuje dále. Největší význam mají podmíněné
skokové povely, kterými je testován (zkušen) stav některého CPU
Flagu. Skok je proveden jen tehdy, když test dopadne pozitivně.

str.32

Příklad:

JP Z   'Jump if Z set'  'Skoč když Z je nastaven'IF Z=1 GOTO
JP NZ  'Jump if Z reset''Skoč když Z je nulován' IF Z=0 GOTO

Aritmetické povely
------------------
     Těmito povely lze provádět jednoduché početní operace, tj.
součet, odečítání, přírůstek i úbytek. U posledních se jedná o
jednoduchý součet nebo odečet od 1.

Příklad:

ADD     'Add'      'Sečti'
SUB     'Subtract' 'Odečti'
INC     'Increment''Povyš o 1'
DEC     'Decrement''Sniž o 1'

Porovnávací povely
------------------
     Porovnávacími povely se porovnávají dvě hodnoty a nastavují
se příslušné flagy.

Příklad:

CP      'Compare'  'Porovnej'

Logické povely
--------------
     Těmito povely se provádějí logické operace AND, OR, XOR
(viz.1.6).

Příklad:

AND      'AND'           'Logická operace -a-'
OR       'OR'            'Logická operace -nebo-
XOR      'Exclusive OR'  'Logická operace -výlučné nebo-

Povely k přesunu bitu
---------------------
     Těmito povely se přesouvají 8mi bitové hodnoty o jeden bit
doprava nebo doleva.
Příklad:

SRA      'Shift right arithmetical' 'Přesun doprava'
SLA      'Shift left arithmetical'  'Přesun doleva'

Kontrolní povely CPU
--------------------
     Sem spadají všechny možné speciální povely jako např.
nastavování a invertování invertování Carry Flagu nebo zastavení
CPU.

Příklady:

SCF      'Set Carry flag'        'Nastav Carry flag'
CCF      'Complement Carry flag' 'Invertuj Carry flag'

str.33

     Tím jsou rozdílné typy povelů vyčerpány. Samozřejmě se
vyskytuje mezi jednotlivými rubrikami podstatně více jednotlivých
povelů, zatím jsme uvedli pouze příklady. V podstatě nejsou
žádné další operace v povelové sade obsaženy. Chybí, jako u téměř
všech 8mi bitových mikroprocesorů např. násobení, pro které
se již musí napsat malý program, ve kterém se pomocí sčítání a
přesuvných operací provede násobení dvou čísel.

4.5 Druh adresování: Odkud bere CPU data ?
------------------------------------------
     Různé operace strojového jazyka se provádějí pomocí dat,
které udává příkaz, např. pomocí obsahu jednoho registru nebo
buňky. Způsob jakým se tato data vyznačují v příkaze, označujeme
druhem adresování. Podívejme se na příkaz  naplň akumulátor
různým způsobem podle druhu adresování.

Bezprostřední adresování (Immediate Adressing)
----------------------------------------------
     Tento druh adresy je třeba, když operand instrukce je číslo,
které je bezprostředně udáno v příkaze:

Příklad:
      naplň akumulátor bezrostředně 3

povel:  LD A,03
Op-kód: 3E 03

Číslo 3 - operand instrukce - se tedy udává společně v kódu
příkazu.

Registrové adresování (Register Adressing)
------------------------------------------
     Tento druh adresy je užit, když operand instrukce je CPU
registr.

Příklad:

    naplň akumulátor obsahem B registru

povel: LD A,B
Op-kód:  78

Přímé resp. absolutní adresování (Extendet Adressing)
-----------------------------------------------------
     Tento druh adresy se užívá, když operand instrukce je
paměťová buňka, jejíž adresa je udána přímo v příkaze.

Příklad:

naplň akumulátor obsahem paměť.buňky 8100
povel:  LD A,(8100)
Op-kód: 3A 0081

Adresa 8100 se dává do závorek, aby bylo jasné, že se jedná o
obsah paměťové buňky.

str.34

Nepřímé registrové adresování (Register Indirect Adressing)
-----------------------------------------------------------
     Tento druh adresy se užívá, když operand instrukce je
paměťová buňka, jejiž adresa stojí v BC-, DE- nebo HL registru.

Příklad:

naplň do A obsah paměť.buňky jejíž adresa je v HL registru
povel:   LD A,(HL)
Op-kód:  7E

Aby bylo jasně znát, že je míněna paměťová buňka, jejíž adresa
je v HL a ne v samotném HL registru, dává se HL do závorek.

Indexované adresování (Indexed Adressing)
-----------------------------------------
     Tento druh adresy, podobně jako u nepřímého registrového
adresování, stojí adresa v jednom z indexových registrů IX nebo
IY.

Příklad:

naplň do A obsah 5.Bytu od adresy IX
povel:  LD A,(IX+05)
Op-kód:  DD 7E 05

Implikované adresování (Implied Adressing)
------------------------------------------
     Tento druh adresy se užívá, když není udán žádný operand,
protože příkaz je převeden pouze určitým operandem.

Příklad:

invetuj obsah akumulátoru (complement Accumulator)
povel:  CPL
Op-kód:  2F

Povel působí vždy na akumulátor, proto se tento již také neudává
explicitně.

Relativní adresování (Relative adressing)
-----------------------------------------
     Tento druh adresy se používá u většiny 8mi bitových
mikroprocesorů, pouze na relativní skoky. V Op-kódu se udává
adresa skoku relativní hodnotou, která se přičítá k okamžitému
stavu programového počitadla. V assembleru můžete však počítat
od prvního byte skokové instrukce.

Příklad:

skoč 5 byte vpřed
povel: JR 05  (Jump relative)
Op-kód:  18 03

str.35

Bitové adresování  (Bit Adressing)
----------------------------------
     S tímto druhem adresování se mohou bity 0...7 jednoho
registru nebo paměťové buňky dávat, brát nebo se na ně dotazovat.

Příklad:

nastav bit 4 z C registru na 1
povel: SET 4,C
Op-kód:  CB E1

U jiných mikroprocesorů existují částečně ještě další druhy
adresování, obzvláště nabízí 6502 velké množství možností.

 KAPITOLA 5

Příkazová věta : Co všechno dokáže
----------------------------------
     V této kapitole se budeme zabývat blíže s příkazy
strojového jazyka procesoru Z-80. Představíme vám všechny
základní důležité příkazy CPU a při tom též ukážeme jak se tyto
příkazy používají. Příliž speciální příkazy Z-80 v následujícím
výkladu pomineme. Úplnou sbírku všech příkazů najdete v dodatku
C. Příkazy vám představíme v jednotlivých skupinách. Ke každé
skupině budou uvedeny základní programovací techniky a příklady.
Přitom se někdy může narážet na ještě neprobrané věci, v takovém
případě vždy dáme krátké vysvětlení. V případě kdy vám bude
nejasná působnost toho nebo onoho příkazu, vezměte si k ruce
učební soubor a můžete si příkaz vyzkoušet. V poslední kapitole
jste poznali jak jednotlivým způsobem se to děje, když necháváte
příkazy provádět po jednotlivých krocích.
     Následující programovací příklady můžete zadávat přímo v
okénku assembleru. Pro kontrolu je skoro všude společně udán
programový kód.
     Při zadávání strojových programů se má vždy postupovat s co
největší pečlivostí, nepatrná chyba může hned po startu přivést
computer ke 'zhroucení', v mnoha případech vám pak nic jiného
nezbude, než reset (vynulování) a nové natažení "učebního
programu" (learn program), protože paměť počítače se při zhroucení
snadno uvede do nepořádku.

5.1 Skokové povely
------------------
     Skokovými povely lze během programu přeskakovat na různá
místa, vyvolávat podprogramy a vracet se opět k hlavnímu programu,
způsobem odpovídajícím povelům BASIC GOTO, GOSUB a RETURN.

Nepodmíněné absolutni skoky
Vyvolávání podprogramu a návrat
-------------------------------------------------------
| Mnemonic | Působnost | Flagy | Hexkód |Analog BASIC |
|-----------------------------------------------------|
| Nepodmíněné absolutní skoky                         |
|-----------------------------------------------------|
| JP nm    | PC=nm     | ----- | C3,m,n | GOTO nm     |
| JP (HL)  | PC=HL     | ----- | E9     | GOTO HL     |
| JP (IX)  | PC=IX     | ----- | DD,E9  | GOTO IX     |
| JP (IY)  | PC=IY     | ----- | FD,E9  | GOTO IY     |
|-----------------------------------------------------|

str.36

| Nepodmíněné vyvolání podprogramu                    |
|-----------------------------------------------------|
| CALL nm  | SP=SP-1   | ----- | CD,m,n | GOSUB nm    |
|          | (SP)=PC^H |       |        |             |
|          | SP=SP-1   |       |        |             |
|          | (SP)=PC^L |       |        |             |
|          | PC=nm     |       |        |             |
|-----------------------------------------------------|
| Nepodmíněný return                                  |
|-----------------------------------------------------|
| RET      | PC^L=(SP) | ----- | C9     | RETURN      |
|          | SP=SP+1   |       |        |             |
|          | PC^H=(SP) |       |        |             |
|          | SP=SP+1   |       |        |             |
-------------------------------------------------------
 V povelu JP (Jump, česky skoč) se prostě dává adresa cíle
skoku a to adresa u které začíná Op-kód příkazu kam se má skočit.
V tabulce se tato adresa vyznačuje "nm". Nutno si povšimnout,
že v Op-kódu jsou H-Byte a L-Byte cíle skoku zaměněny. Následující
příklad si můžete pomocí "učebního souboru" vyzkoušet tak, že
zadáte příkazy na udaných adresách a pak startujete program jako
bylo popsáno v poslední kapitole.

Příklad:
Adresa   Kód       Příkaz    Analog BASIC

8000:    C3 05 80  JP 8005   8000:GOTO 8005
8003:    06 99     LD B,99   8003:B=99
8005:    0E 99     LD C,99   8005:C=99
8007:    C3 07 80  JP 8007   8007:GOTO 8007
800A:    C9        RET       800A:RETURN

     Když jste zadali program, startujte ho "zkušebním způsobem"
(Test modus) "učebního souboru" (k tomu dávejte: PC=8000, <T>
následováno <šipka dolu>). Za průběhu programu po jednotlivých
krocích (klávesa <šipka dolu>) uvidíte na indikaci cestu CPU
programem podle postavení programového počitadla : 8005, 8007,
8007, 8007... Podíváte-li se na registry uvidíte že pouze registr
C nabral hodnotu 99, nikoliv však B, protože tento naplňovací
povel byl přeskočen. Na konci uvázne program v nekonečné smyčce.
Tracer však můžete kdykoliv opustit, vložením nové hodnoty do
PC. Podíváte-li se znovu do shora uvedené tabulky vidíte, že
povel JP ponechá všechny Flagy nezměněné (vyznačeno -----).
Současně můžete na působení příkazu vidět, že se nic jiného
nestalo, než že programové počitadlo PC nabralo adresu nm, která
byla obsažena v příkazu.
     Chcete-li během programu navodit podprogram, použijte povel
CALL (Call subroutine, česky volej podprogram). V povelu CALL
se stejně jako u povelu JP udává adresa "nm" cíle skoku, tedy
adresa startu podprogramu. Podprogram končí příkazem RET (Return,
česky návrat), který způsobí návrat zpět na místo v programu, na
kterém byl podprogram volán.

Příklad:
Adresa   Kód       Příkaz    Analog BASIC

8000:    CD 3E 00  CALL 003E 8000:GOSUB 003E
8003:    06 77     LD B,77   8003:B=77
8005:    C9        RET       8005:RETURN

str.37

     Když budete startovat tento program, nechte ho proběhnout
v jednom tahu, nikoliv krokovým způsobem. To se uskuteční
následovně:
Po vložení startovací adresy PC=8000 z Test modusu "učebního
souboru", dejte <G> následováno dvojnásobným <CR>. Uslyšíte pak
krátký pípavý tón, protože u vyvolaného podprogramu se jedná o
běžný program ROMu (ROM-routine) vašeho computeru který je 
vyřizován pípáním. Podíváte-li se na registry vidíte, že B je
obsazen správně 77. Po podprogramu tedy pokračoval hlavní program
dále. Povel RET na konci přivodí vždy návrat do programu 
"učebního souboru" (Learn program).
     V povelových tabulkách najdete přesný popis jak při vyvolání
podprogramu postupuje počítač programem při odkládání na Stack
(stoh). Nejprve je stackpointer snížen o 1, aby ukazoval na
nejbližší volnou pozici stacku (SP=SP-1). Pak je uložen H-Byte
z PC na stack. Toto je zaznamenáno (SP)=PC^H. Pak se SP znovu
sníží aby bylo možno uložit PC^L na stack (SP=SP-1, (SP)=PC^L).
Teprve potom je proveden skok "PC=nm". Stack tedy jde v RAMu
pozpátku, protože SP se pokaždé snižuje o 1. Povel RET opět
odebírá hodnoty ze stacku do počitadla programu, takže v programu
se dá pokračovat. Přitom je důležité, aby na stacku uložená
programová hodnota počitadla již ukazovala na příští povel, na
povel CALL. To se děje automaticky, protože programové počitadlo
již před provedením příkazu je jednoduše přírůstkováno. (viz 4.1)
Tady to můžete pozorovat pomocí Learn programu. Pohleďte na
okénko CPU a tam vidíte :

-----------------------------------------
|  A:    BC:   DE:   HL:    F: SZ-H-PNC |
|  00    7700  0007  0000      01000100 |
|                                       |
|              IX:   IY:    PC:    SP:  |
|              0000  0000   8000   A000 |
-----------------------------------------

     Když teď startujete klávesou <T> a <šipka dolu> obsahuje
SP pouze ještě hodnotu 9FFC. Jestliže pomocí <GRAPH> přepnete
do programovacího módusu a podíváte se v okénku monitoru na
poslední pozici stacku obsazenou M=9FFC, najdete tam 03 a v další
paměťové buňce bude 80. Přitom se jedná právě o návratovou adresu
z podprogramu 8003.
Podprogramy jsou pro programování ve strojovém jazyce zvlášť
důležitou věcí. Každý delší program je dělen na malé porce, které
jako podprogramy lze později spojovat jako hlavní program. Tyto
malé podprogramy jsou testovány samostatně, takže se při spojování
již ví že fungují.
     Zvlášť pěkná bude záležitost máme-li k dispozici assembler
lako MZ-MACRO. Pak můžeme podprogramy vybavit pojmenováním,
při pozdějším použití podprogramů udáváme pak pouze příslušné
jméno. Tímto způsobem je možné si sestavovat svou vlastní řeč,
ve které pak můžeme programovat. Povely této "řeči" jsou pak
dotyčné jednotlivé podprogramy.


