HRA

Ruletti 64
Herní styl [uncategorized]
Multiplayer Bez multiplayeru
Rok vydání 1988
Programátor Robert Brotherus
Grafik (Unknown)

INTRO

Assembler 4. část - Sčítáme, odčítáme, skáčeme a kontrolujeme

1. Přičítání po jedné k registrům .... a nejen to.


V minulém díle jsme probírali ukládání hodnot nejen do registrů, ale i do paměti a následné čtení těchto dat. V dnešním díle se naučíme nejen sčítat, odčítat, kontrolovat výsledky,ale i skákat v závislosti na dodaných výsledcích.
Nejzákladnější příkaz pro pouhé přičítání a odečítání hodnoty 1 pro registr A paradoxně neexistuje !!!
Pro registr X jsou to příkazy INX (DEX) a pro registr Y jsou to INY (DEY).

INX / DEX .... INY / DEY

Použití těchto příkazů je opravdu velmi jednoduché. Příkazy nedělaji nic jiného, než že přičítají a odečítaji hodnotu 1.

Příklad hovoří za vše. Od hodnoty 00 budeme postupně přičítat 1 a výsledek zobrazovat na obrazovce. Jak jde vidět, příkazy pro registr X i Y se chovají absolutně stejně.

ADC... přičítání k akumulátoru A ,CLC, SEC ... Příznak C - CARRY - STATUSREGISTR

Pro registr A není vyhrazen žádný příkaz, který by striktně přičítal pouze hodnotu 1.
Instrukce ADC má tu možnost přičíst k registru A libovolnou hodnotu 0 - FF + CARRY příznak. Instrukce SBC je pravý opak a umožňuje odečítat libovolnou hodnotu + NEGOVANÉ CARRY příznak. !!!

Příkaz SBC odečítá nejen hodnotu, ale i negované CARRY, což znamená, že potřebujeme-li se propracovat ke správnému výsledku rovnice kde

10 - 5 (+neg.carry) = 5

musíme mít CARRY nastavené na 1. (negovaná hodnota je 0 !!)


Zde je ovšem nesmírně důležité zmínit jednu věc a to jsou FLAGY neboli příznaky neboli statusregistr.
Příznaky je 8 "ukazatelů" systému (statusregistr - nepleci si z registry) , které drží v paměti určité nastavení pomocí hodnot 0 a 1. (nastaveno / nenastaveno). Tyto příznaky jsou ovlivňovány nejen aritmetickýmy vypočty, ale například podmiňují instrukce pro matematické skoky , řídí přerušení ... zkrátka .. budeme si je představovat postupně, jak se s nimi budeme dostávat do "křížku".

Následující přiklad ukazuje vlastnost příznaku C dokonale. Příznak CARRY se automaticky přičítá k instrukcím přičítajícím a odečítajícím od akumulátoru !!! V příkladu to znamená toto: jestliže nastavíme carry na 1 (sec) , přičte se automaticky k našemu výpočtu ( 3 + 3) a na adrese $2000 kam ukádáme obsah akumulátoru naleznete hodnotu 7 !!!
V druhé části příkladu příznak carry vynulujeme (clc) a počítáme-li dále náš příklad v akumulátoru 3+3, na adrese $2001, kam výsledek ukádáme najdeme hodnotu 6 !!!!

Vždy je nutno (pokud není potřeba jinak) počítat s tím, že výsledek bude ovlivněn hodnotou příznaku CARRY. Vždy si musíte uvědomit, že chcete-li přesný výsledek při počítání akumulátorem, je potřeba carry nulovat instrukcí CLC.

Zde je potřeba říct a názprně ukázat, kdy se příznak CARRY automaticky nastavuje sám. Carry je ovlivněno přetečením počtů při sčítání a odčítání.
Jestliže přetáhnete součet nad hodnotu 255, carry se automaticky nastaví na 1. Při odečítání jestliže najdříve nastavíte carry na 1 a poté přetáhnete rozdíl přes 0 , to znamená, že se carry nastaví na 0 a vy dostanete výsledek přetočen o 255. A jak to vypadá v realu ?

Tento příklad je tak absolutně vševypovídající, že jestliže ho nepochopíte ... nečtěte dál !!! Rozebereme si ho po řádku dopodrobna.
1.Začínáme tím, že nastavíme Carry na 0.
2. Jestliže sečteme čísla , která dávají výsledek větší než #$FF, příznak Carry přeteče a nastaví se na 1.
3.Výsledek sčítání je vlastně hodnota $1020 , což znamená, že carry je nastavena na 1 a v A je #$20.
4. Jestliže do dalšího počítání necháme nastavené carry z minula a nevynulejeme ji, potom výsledek počtu 1+1 nebude 2, ale přičte se i carry,tudíž výsledek bude 3. (Uloženo na adreses 2001)
5. Druhá část příkladu je součet, který nepřeteče. To znamená, že po sečtení hodnot #$10+#$10 = $20 s tím rozdílem, že carry zůstane na hodnotě 0.
6. Jestliže poté provedeme stejný součet jako v první části příkladu ... tzn. 1 + 1 a výsledek uložíme na adresu, zjistíme, že výsledek je opravdu 2.

To vše znamená, že s příznakem CARRY je potřeba opravdu počítat v pravém slova smyslu.

Tato obrazovka ukazuje problém negovaného Carry příznaku v odečítání hodnot. Jako ukázka k problematice sčítání i odčítání snad tyto příklady stačí.
Opravdu je potřeba pochopit a zafixovat si tyto pravidla dokonale, protože jinak se budete potkávat ve svých programech s "pro vás náhodnými výsledky" :)

ADC, SBC s adresami.

samozřejmě, že matematické sčítání a odčítání můžeme provádět taktéž s adresami a hodnotami na nich uloženými.

Myslím,že není potřeba dalších komentářů. Práce s hodnotami na adresách je totožná jako operace s čísly "natvrdo" zadanými.
Syntaxy pro příkazy ADC a SBC jsou možné snad ve všech možných možnostech.

SBC #$xx
SBC $xxxx
SBC $xx
SBC ($xx,X)
SBC (xx),Y
SBC $xx,X
SBC $xxxx,X
SBC $xxxx,Y

Smyčky a podmíněné skoky , BNE, BEQ


První příklad , který si ukážeme je výpis ascii tabulky na obrazovku.


a výsledek

Příklad si rozebereme postupně.

1. Do X registru vložíme hodnotu 0
2. intrukce TAX udělá to, že obsah registru X uloží do A.
3.
Akumulátor uložíme na adresu videoram $0400 a colorram $d800.
4. Přičteme instrukcí INX k X registru hodnotu 1
5. Jestliže přeteče registr X (přes #$FF) nastaví se flag Z (ZERRO) na 1. Instrukce BNE skáče až poté, co se ZERRO nastaví na 1.

Příznak Z - ZERRO se nastaví na 1 až pokud přeteče přičítání v registrech X a Y přes 255 ($ff) a nebo jestliže proběhne pravdivě instrukce pro kontrolu . (viz dále)

Kontrola hodnot .. CMP, CPX, CPY


Možná se Vám bude zdát, že skáči v popisu instrukcí halabala, ale není to tak. Příkazy pro podmíněné skoky jsou ruku v ruce s kontrolními instrukcemi, proto nadále budeme brát všechny zatím probrané příkazy s těmi novými dohromady.

Příkaz CMP - Compare acumulator dělá pouze to, že kontroluje, zda-li se v akumulátoru ocitla kontrolovaná hodnota.
Pokud ANO, potom se provede skok BEQ na proměnnou STOP.
Jestliže tato hodnota zatím nepřišla, instrukce BNE opakuje smyčku tak dlouho dokud ZERRO nebude 1. (díky INX).
Tento příklad zobrazí pouze 10 znaku na obrazovku. Další příklad provede to samé za pomocí kontroly X registru.
Je to ideální ukázka využití instrukce BEQ ... příkaz BEQ se dá použít i jako rozcestník podmínek, kde se hlídá více potřebných hodnot.

Tento příklad ukáže kontrolu na vyskytlý znak P ... prográmek zobrazí i informační text.
Jako obvykle si následující příklad rozebereme dopodrobna.

1. Ve smyčce je zde progámek pro výpis ASCII tabulky.
2. V těle programu je kontrola na znak P (všimněte si syntaxu na kontrolu znaku)
3. Jestliže program narazí na znak P, instrukce BEQ skočí na další program ZNAK
4. Program ZNAK začíná uložením akumulátoru do registru Y.
5. Po té následuje smyčka pro výpis dat TEXT, která kontroluje výpis 13-ti znaků
6. Po vypsání textu provedeme uložení znaku za řetězec. STY ...

Následující příklad bude kontrolovat zmáčknutí kláves přes rutinu kernalu. Budeme kontrolovat zmáčknutí dvou kláves.
Samozřejmě, že kontrolu můžeme rozšířit na kolik kláves potřebujeme.

Rutina na adrese $FFE4 vrací v akumulátoru hodnotu zmáčklé klávesnice. Kontrolujeme klávesu A a O ... jestliže tyto zmáčknete,zobrazí se informační věta o stisku. Všimněte si hlavně zápisu STY $0400+20 . Možnosti tuboassembleru jsou vynikající a tyto výpočty můžete klidně nechávat na něm ... no není to jednodušší ?? myslim, že jo :)
Také si všimněte podmíněných skoků BEQ a BNE v první části příkladu ... Myslím, že tento příklad ukazuje využití příkazů CMP, BEQ, BNE, INX, CPX takřka dokonale ... vše v jednom.

Naschvál jsem nezmínil příkazy INY, CPY ... tyto se chovají absolutně stejně jako s X registrem.
Samozřejmě, že instrukce pro porovnávání můžeme kontrolovat hodnoty na adresách .. CMP $1000 , CPX $1000 nebo CPY $1000 ... možnosti jsou obrovské.

Skoky kontrolující větší menší .. aneb BPL, BMI


Poslední dnes probranými skoky budou "matematické skoky" BMI a BPL. Využití je následné a myslím, že s vašimi nabitými znalostmi určitě snado zmáknutelné ..

Tento prográmek bude kontrolovat řetězec znaků se znakem G. Pokud bude znak v řetězci menší
(CMP #"g")
napíše se 0. Jinak se napíše 1. Se skoky BMI a BPL souvisí další s flagů a to N - NEGATIVE. Je li nastaven na 1, podmínka je splněna a to znamená skok BPL. Není-li splněna, funguje instrukce BMI.

Zkuste si pořadně prozkoumat tento prográmek. Myslím,že je to velmi elegantní řešení tohoto prográmku.

Příkazy pro transfer registrů - TAX,TAY,TSX a naopak


Možnosti těchto příkazů jsme si ukázali již výše. Seznamte se tímto pouze se suchým syntaxem.

TAX přenese akumulátor do X registru
TXA přenese X registr do akumulátoru
TAY přenese akumulátor do Y registru
TYA přenese Y registr do akumulátoru
TSX přenese statusregistr do X registru
TXS přenese X registr do statusregistru

Zde jen zaslouží pozornost instrukce TSX a TXS .. Je to ale velmi jednoduché. Statusregistr se ve vašem programu v určité fázi nachází v určitém stavu. Jestliže je potřeba tento stav zachovat, popřípadě z něj binárně číst, je možnost statusregistr uchovat do X registru. A protože jsme si říkali, že statusregistr má 8 ukazatelů, lze z něj přečítat bity velmi jednodušše. Statusregistr si ukážeme nyní.

Statusregistr


N V # B D I Z C
* . * * . . . *

Statusregistr je ukazatelem stavu celého počítače.

C Carry Nastavuje se při početních operacích v případě že počet cyklů dosáhl 255 #FF
Z Zero Nastavuje se při používání podmíněných skoků
I Interupt Přerušení. Probíhá-li nějaké přerušení, I je nastaveno na 1 ... jinak 0
D Decimal Jestliže je D=1, pak počítač pracuje v tzv. BCD modu. Jinak v normálu.
B Break Nepoužívaný příznak. Nedá se nastavit ani smazat. Slouží jako ukazatel, byl li program zastaven nebo ne.
# Nevyužito Snad jasne ... :)
V Overflow Protože Commodore 64 neumí počítat se zápornými čísly, pracuje počítač tímto způsobem. Je-li flag nastaven na 1, potom hodnoty $00-$7F jsou brány jako kladné. Přeteče-li hodnota přes $7F nastaví se V na 1
N Negative Jestliže se NEGATIVE nastaví na 1, pak je umožněno pracovat s OVERFLOW

Takže pokud jste dočetli až sem a divíte se , proč je to tak blbě napsané, když to vše je přeci jasné, tak je tady několik možnosti.

1. Buď jste již měli s nějakým assemberem něco do činění
2. Jste rodillý assemblerista
3. Jste génius
4. Napsal jsem to dobře :)

JMP END

Nový příspěvek k článku

podpis :
První znak podpisu musí být vykřičník, jinak se příspěvek neodešle (ochrana proti spamu)

Advert

Hardcode and datamining by PCH of UNREAL, Hardware guru by RAY of UNREAL, Bugs report by SILLICON of UNREAL
UNREAL 2014-2021 Czech republic