Kapitola 4: Výukový program 6502 Microprocessor Assembly Language

Kapitola 4 Vyukovy Program 6502 Microprocessor Assembly Language



Kapitola 4: Výukový program 6502 Microprocessor Assembly Language

4.1 Úvod

Mikroprocesor 6502 byl uveden na trh v roce 1975. Používal se jako mikroprocesor pro některé osobní počítače tehdy jako Apple II, Commodore 64 a BBC Micro.







Mikroprocesor 6502 se vyrábí ve velkém i dnes. Nejedná se již o centrální procesorovou jednotku, která se dnes používá v osobních počítačích (notebookech), ale stále se vyrábí ve velkých počtech a dnes se používá v elektronických a elektrických spotřebičích. Abychom pochopili modernější počítačové architektury, je velmi užitečné prozkoumat starší, ale docela úspěšný mikroprocesor, jako je 6502.



Protože je jednoduchý na pochopení a programování, je to jeden z nejlepších (ne-li nejlepší) mikroprocesorů pro výuku jazyka symbolických instrukcí. Assembler je nízkoúrovňový jazyk, který lze použít k programování počítače. Všimněte si, že jazyk symbolických instrukcí pro jeden mikroprocesor se liší od jazyka symbolických instrukcí jiného mikroprocesoru. V této kapitole je vyučován jazyk assembleru mikroprocesoru 6502. Přesněji řečeno, je to 65C02, který se učí, ale je jednoduše označován jako 6502.



Slavný počítač v minulosti se nazývá commodore_64. 6502 je mikroprocesor rodiny 6500. Počítač commodore_64 používá mikroprocesor 6510. Mikroprocesor 6510 má 6500 µP. Instrukční sada 6502 µP je téměř všemi instrukcemi 6510 µP. Znalost této a další kapitoly je založena na počítači commodore_64. Tyto znalosti slouží jako základ pro vysvětlení moderních počítačových architektur a moderních operačních systémů v této části online kariérního kurzu.





Architektura počítače odkazuje na součásti základní desky počítače a vysvětlení toho, jak data proudí v každé součásti, zejména mikroprocesoru, jak data proudí mezi součástmi a také jak data interagují. Jednotné číslo pro data je datum. Efektivní způsob, jak studovat počítačovou architekturu počítače, je studovat jazyk symbolických instrukcí základní desky.

O počítači commodore_64 se říká, že je to počítač 8bitového počítače word. To znamená, že informace jsou ukládány, přenášeny a manipulovány ve formě osmibitových binárních kódů.



Blokové schéma základní desky Commodore 64
Blokové schéma základní desky commodore 64 je:


Obr 4.1 Blokové schéma systémové jednotky Commodore_64

Představte si mikroprocesor 6510 jako mikroprocesor 6502. Celková paměť je řada bajtů (8 bitů na bajt). Je zde paměť s náhodným přístupem (čtení/zápis), do které lze bajty zapisovat nebo mazat. Po vypnutí napájení počítače se vymažou všechny informace v paměti RAM (random-access memory). K dispozici je také paměť pouze pro čtení (ROM). Po vypnutí počítače informace v paměti ROM zůstanou (nejsou vymazány).

Je zde vstupní/výstupní port (obvod), který je ve schématu označován jako vstupní/výstupní zařízení. Tento port by se neměl zaměňovat s porty, které jsou viditelné na levém a pravém nebo předním a zadním vertikálním povrchu systémové jednotky počítače. To jsou dvě různé věci. Připojení z tohoto vnitřního portu k periferním zařízením, jako je pevný disk (nebo disketa), klávesnice a monitor, nejsou na obrázku znázorněna.

Ve schématu jsou tři sběrnice (skupiny elektrických velmi malých vodičů). Každý vodič může přenášet bit 1 nebo bit 0. Datová sběrnice pro přenos osmibitových bytů najednou (jeden hodinový impuls) do RAM a vstupní/výstupní port (vstupní/výstupní zařízení) je obousměrná. Datová sběrnice je široká osm bitů.

Všechny komponenty jsou připojeny k adresové sběrnici. Adresová sběrnice je jednosměrná z mikroprocesoru. Adresová sběrnice má šestnáct vodičů a každý nese jeden bit (1 nebo 0). Šestnáct bitů je odesláno v jednom hodinovém impulsu.

Je tam řídící sběrnice. Některé z vodičů řídicí sběrnice by přenesly po jednom bitu z mikroprocesoru do ostatních součástí. Několik řídicích linek přenáší bity ze vstupního/výstupního (IO) portu do mikroprocesoru.

Paměť počítače
RAM a ROM jsou považovány za jednu paměťovou sestavu. Toto sestavení je znázorněno schematicky následovně, kde hexadecimální čísla mají předponu „$“:


Obr 4.11 Rozložení paměti pro počítač Commodore 64

RAM je od 0000 16 do DFFF 16 který se píše od 0000 $ do $ DFFF. V jazyce symbolických instrukcí 6502 µP je hexadecimálnímu číslu předpona „$“ a nikoli přípona (subscriptovaná) 16 nebo H nebo hex. Veškeré informace v paměti RAM zhasnou, když je počítač vypnutý. ROM začíná od $E000 do $FFFF. Má podprogramy, které se nevypnou, když je počítač vypnutý. Tyto podprogramy jsou běžně používané rutiny, které pomáhají při programování. Uživatelský program je volá (viz další kapitola).

Prostor (bajty) od $0200 do $D000 je určen pro uživatelské programy. Mezera od $D000 do $DFFF je pro informace, které přímo souvisí s periferiemi (vstupní/výstupní zařízení). Toto je součást operačního systému. Operační systém počítače commodore-64 se tedy skládá ze dvou hlavních částí: části v ROM, která se nikdy nevypne, a části od $ D000 do $ DFFF, která zhasne při vypnutí napájení. Tato IO (vstup/výstup) data se musí načíst z disku při každém zapnutí počítače. Dnes se takovým datům říká periferní ovladače. Periferie začínají od portu Input/Output Device přes přípojky na základní desce až po identifikovatelné porty na svislých plochách počítače, ke kterým je připojen monitor, klávesnice atd., a k samotným periferiím (monitor, klávesnice atd.). .).

Paměť se skládá z 2 16 = 65 536 umístění bajtů. V hexadecimálním tvaru je to 10 000 16 = 10 000 H = 10 000 hex = místa za 10 000 USD. V počítání začíná počítání v základu dva, základ deset, základ šestnáct atd. od 0 a ne od 1. Takže první umístění je ve skutečnosti číslo místa 0000000000000000 2 = 0 10 = 0000 16 = 0000 $. V jazyce symbolických instrukcí 6502 µP má identifikace umístění adresy předponu $ a neexistuje žádná přípona ani dolní index. Poslední umístění je číslo umístění 1111111111111111 2 = 65 535 10 = FFFF 16 = $ FFFF a ne 10000000000000000 2 nebo 65 536 10 nebo 10 000 16 nebo 10 000 $. 10000000000000000 2 , 65,536 10 , 10 000 16 , nebo 10 000 $ udává celkový počet umístění bajtů.

Tady, 2 16 = 65 536 = 64 x 1024 = 64 x 2 10 = 64 kilobajtů (kilobajtů). Přípona 64 v názvu Commodore-64 znamená 64KB celkové paměti (RAM a ROM). Bajt má 8 bitů a 8 bitů půjde do jednoho bajtového místa v paměti.

64 kB paměti je rozděleno na stránky. Každá stránka má 0100 16 = 256 10 umístění bajtů. Prvních 256 10 = prvních 0100 16 umístění je stránka 0. Druhá je stránka 1, třetí je stránka 2 a tak dále.

Aby bylo možné adresovat 65 536 míst, je pro každé místo (adresu) zapotřebí 16 bitů. Adresová sběrnice z mikroprocesoru do paměti se tedy skládá z 16 linek; jeden řádek za jeden bit. Bit je buď 1 nebo 0.

Registry 6502 uP
Registr je jako bajtové buňky pro umístění bajtové paměti. 6502 µP má šest registrů: pět 8bitových registrů a jeden 16bitový registr. 16bitový registr se nazývá Program Counter, což je zkráceně PC. Uchovává adresu paměti pro další instrukci. Program v assembleru se skládá z instrukcí, které jsou umístěny v paměti. Šestnáct (16) různých bitů je potřeba k adresování konkrétního umístění bajtu v paměti. Při určitém hodinovém impulsu jsou tyto bity odeslány do 16bitových adresních linek adresové sběrnice pro čtení instrukce. Všechny registry pro 6502 µP jsou znázorněny následovně:


Obr. 4.12 Registry 6502 µP

Program Counter nebo PC lze v diagramu vidět jako 16bitový registr. Spodních platných osm bitů je označeno jako PCL pro Program Counter Low. Vyšších platných osm bitů je označeno jako PCH pro Program Counter High. Instrukce v paměti pro Commodore-64 se může skládat z jednoho, dvou nebo tří bajtů. 16 bitů v PC ukazuje na další instrukci, která má být provedena, v paměti. Mezi obvody v mikroprocesoru se dva z nich nazývají aritmetická logická jednotka a instrukční dekodér. Pokud je aktuální instrukce zpracovávaná v µP (mikroprocesoru) dlouhá jeden bajt, tyto dva obvody zvýší PC pro další instrukci o 1 jednotku. Pokud je aktuální instrukce zpracovávaná v µP dlouhá dva byty, což znamená, že zabírá dva po sobě jdoucí byty v paměti, tyto dva obvody zvýší PC pro další instrukci o 2 jednotky. Pokud je aktuální instrukce zpracovávaná v µP dlouhá tři bajty, což znamená, že zabírá tři po sobě jdoucí bajty v paměti, tyto dva obvody zvýší PC pro další instrukci o 3 jednotky.

Akumulátor „A“ je osmibitový obecný registr, který ukládá výsledky většiny aritmetických a logických operací.

Každý z registrů „X“ a „Y“ se používá k počítání kroků programu. Počítání při programování začíná od 0. Říká se jim tedy indexové registry. Mají několik dalších účelů.

Přestože registr Stack Pointer, „S“ má 9 bitů, což je považováno za osmibitový registr. Jeho obsah ukazuje na bajtové umístění na stránce 1 paměti RAM (Random Access Memory). Stránka 1 začíná od bajtu 0100 $ (256 10 ) na bajt $01FF (511 10 ). Když je program spuštěn, přechází z jedné instrukce na další po sobě jdoucí instrukci v paměti. Není tomu však vždy tak. Jsou chvíle, kdy skočí z jedné oblasti paměti do jiné oblasti paměti, aby tam pokračovalo spouštění instrukcí za sebou. Jako zásobník se používá stránka 1 v paměti RAM. Zásobník je velká oblast paměti RAM, která má další adresy pro pokračování kódu, odkud je skok. Kódy s instrukcemi přeskakování nejsou v zásobníku; jsou jinde v paměti. Po provedení instrukcí skoku jsou však pokračovací adresy (nikoli segmenty kódu) v zásobníku. Byli tam zatlačeni v důsledku pokynů skoku nebo větve.

Osmibitový registr stavu procesoru P je speciálním druhem registru. Jednotlivé bity spolu nesouvisí ani spolu nesouvisí. Každý bit se nazývá příznak a je oceňován nezávisle na ostatních. Významy příznaků jsou uvedeny v následujícím textu podle potřeby.

První a poslední bitový index pro každý registr jsou uvedeny nad každým registrem v předchozím diagramu. Počítání bitového indexu (pozice) v registru začíná od 0 vpravo.

Paměťové stránky v binárním, hexadecimálním a decimálním formátu
Následující tabulka ukazuje začátek stránek paměti v binární, šestnáctkové a desítkové soustavě:

Každá stránka má 1 000 000 2 počet bajtů, který je stejný jako 100 H počet bajtů, který je stejný jako 256 10 počet bajtů. V předchozím paměťovém diagramu jsou stránky označeny od stránky 0 nahoru a nikoli dolů, jak je uvedeno v tabulce.

Binární, hexadecimální a decimální sloupce této tabulky poskytují adresy umístění bajtů paměti v jejich různých základech. Všimněte si, že pro stránku nula je nutné při kódování zadat pouze bity pro spodní bajt. Bity pro vyšší bajt lze vynechat, protože jsou vždy nuly (pro stránku nula). Pro zbytek stránek by měly být použity bity pro vyšší bajt.

Zbytek této kapitoly vysvětluje jazyk assembleru 6502 µP s využitím všech předchozích informací. Aby čtenář rychle pochopil jazyk, musí sčítat a odčítat v základu šestnáct místo v základu deset. Ve skutečnosti to má být základ dva, ale počítání v základu dva je těžkopádné. Pamatujte, že při sčítání dvou čísel v základu dva je přenos stále 1 jako v základu deset. Ale při odečtení dvou čísel v základu dva je výpůjčka dvě a ne deset jako v základu deset. Při sečtení dvou čísel v základu šestnáct je přenos stále 1 jako v základu deset. Ale při odečtení dvou čísel v základu šestnáct je výpůjčka šestnáct a ne deset jako v základu deset.

4.2 Pokyny pro přenos dat

Zvažte následující tabulku pokynů pro přenos dat v jazyce symbolických instrukcí pro 6502 µP:

Když je bajt (8 bitů) zkopírován z místa bajtů paměti do registru akumulátoru, registru X nebo registru Y, dochází k načítání. Když je bajt zkopírován z některého z těchto registrů do umístění bajtů v paměti, dojde k přenosu. Když je bajt zkopírován z jednoho registru do druhého, stále probíhá přenos. Ve druhém sloupci tabulky šipka ukazuje směr kopírování pro bajt. Zbývající čtyři sloupce ukazují různé režimy adresování.

Záznam ve sloupci režimu adresování je skutečným byte kódem pro odpovídající mnemotechnickou část instrukce v hexadecimální soustavě. AE je například skutečný byte kód pro LDX, který má načíst bajt z paměti do registru X v režimu absolutního adresování, jako je AE 16 = 10101110 2 . Takže bity pro LDX v umístění bajtů paměti jsou 10101110.

Všimněte si, že pro mnemotechnickou část instrukce LDX existují tři možné bajty, které jsou A2, AE a A6, a každý je pro určitý režim adresování. Když bajt, který se načte do registru X, nemá být zkopírován z místa bajtu v paměti, musí být hodnota napsána pomocí mnemotechnického kódu LDX (hned za) v instrukci v šestnáctkové nebo desítkové soustavě. V této kapitole jsou takové hodnoty zadávány v šestnáctkové soustavě. Toto je okamžité adresování, takže skutečný bajt v paměti reprezentující LDX je A2 16 = 10100010 2 a ne AE 16 což se rovná 10101110 2 .

V tabulce se všechny bajty pod nadpisy režimu adresování nazývají operační kódy, což je zkráceno jako operační kódy. Pro jednu mnemotechnickou pomůcku může být více než jeden operační kód, v závislosti na režimu adresování.

Poznámka: Slovo „načíst“ v systémové jednotce počítače může mít dva významy: může odkazovat na načtení souboru z disku do paměti počítače nebo může odkazovat na přenos bajtu z místa bajtů paměti do registru mikroprocesoru. .

Existuje více režimů adresování než čtyři v tabulce pro 6502 µP.

Pokud není uvedeno jinak, veškerý uživatelský programovací kód v této kapitole začíná adresou 0200 16 což je začátek uživatelské oblasti v paměti.

Paměť M a akumulátor A

Paměť do akumulátoru

Okamžité adresování
Následující instrukce ukládá číslo FF 16 = 255 10 do akumulátoru:

LDA # $ FF

„$“ se nepoužívá pouze k identifikaci adresy paměti. Obecně se používá k označení, že další číslo, které následuje, je šestnáctkové. V tomto případě $FF není adresa žádného umístění bajtů paměti. Je to číslo 255 10 v šestnáctkové soustavě. Základ 16 nebo jakýkoli jiný ekvivalentní index nesmí být napsán v instrukci v jazyce symbolických instrukcí. „#“ znamená, že cokoli následuje, je hodnota, která má být vložena do registru akumulátoru. Hodnota může být také zapsána v základu deset, ale to není v této kapitole provedeno. „#“ znamená okamžité adresování.

Mnemotechnická pomůcka má určitou podobnost s odpovídající anglickou frází. „LDA #$FF“ znamená načíst číslo 255 10 do akumulátoru A. Protože se jedná o okamžité adresování z předchozí tabulky, LDA je A9 a ne AD nebo A5. A9 je binárně 101010001. Pokud je tedy A9 pro LDA v paměti na adrese $0200, $FF je v $0301 = 0300 + 1 adresa. #$FF je přesně operand pro mnemotechnickou pomůcku LDA.

Absolutní adresování
Pokud je hodnota $FF na místě $0333 v paměti, předchozí instrukce je:

LDA 0333 USD

Všimněte si absence #. V tomto případě absence # znamená, že to, co následuje, je adresa paměti a nikoli hodnota zájmu (nikoli hodnota, která se má vložit do akumulátoru). Takže operační kód pro LDA je tentokrát AD a ne A9 nebo A5. Operandem pro LDA je zde adresa $0333 a nikoli hodnota $FF. $FF je v místě $0333, což je poměrně daleko. Instrukce „LDA $0333“ zabírá v paměti tři po sobě jdoucí místa, nikoli dvě, jak tomu bylo na předchozím obrázku. „AD“ pro LDA je v umístění 0200 USD. Spodní bajt 0333, což je 33, je v umístění $0301. Vyšší bajt $0333, což je 03, je v umístění $0302. Toto je malý endianness, který používá jazyk symbolických instrukcí 6502. Abecední jazyky různých mikroprocesorů jsou různé.

Toto je příklad absolutního adresování. $0333 je adresa místa, které má $FF. Instrukce se skládá ze tří po sobě jdoucích bajtů a nezahrnuje $FF ani jeho skutečné umístění bajtů.

Zero-Page Addressing

Předpokládejme, že hodnota $FF je v paměťovém místě $0050 na stránce nula. Umístění bajtů pro nulovou stránku začínají od 0 000 $ a končí na 00 FF. Těch je 256 10 umístění celkem. Každá stránka paměti Commodore-64 je 256 10 dlouho. Všimněte si, že vyšší bajt je nula pro všechna možná umístění v prostoru nulové stránky v paměti. Režim adresování nulové stránky je stejný jako režim absolutního adresování, ale vyšší bajt 00 se do instrukce nezapisuje. Takže pro načtení $FF z místa $0050 do akumulátoru je instrukce režimu adresování nulové stránky:

LDA 50 dolarů

S LDA je A5 a ne A9 nebo AD, A5 16 = 10100101 2 . Pamatujte, že každý bajt v paměti má 8 buněk a každá buňka obsahuje bit. Instrukce se zde skládá ze dvou po sobě jdoucích bajtů. A5 pro LDA je v paměťovém místě $0200 a adresa $50, bez vyššího bajtu 00, je v umístění $0301. Absence 00, která by spotřebovala bajt v celkové paměti 64 kB, šetří paměťový prostor.

Akumulátor do paměti

Absolutní adresování
Následující instrukce zkopíruje bajtovou hodnotu, ať už je jakákoli, z akumulátoru do paměťového místa 1444 $:

JSOU 1444 USD

Jedná se prý o přenos z akumulátoru do paměti. Nenačítá se. Načítání je opačné. Bajt operačního kódu pro STA je 8D 16 = 10001101 2 . Tato instrukce se skládá ze tří po sobě jdoucích bajtů v paměti. 8D 16 je na místě 0200 $. 44 16 z adresy 1444 USD je v umístění 0201 USD. A 14 16 je v lokaci 0202 $ – malý endianness. Skutečný bajt, který je zkopírován, není součástí instrukce. 8D a ne 85 pro adresování nulové stránky (v tabulce) jsou zde použity pro STA.

Zero Page Addressing
Následující instrukce zkopíruje bajtovou hodnotu, ať už je jakákoli, z akumulátoru do paměťového místa $0050 na stránce nula:

STA $ 0050

Bajt operačního kódu pro STA je zde 85 16 = 10000101 2 . Tato instrukce se skládá ze dvou po sobě jdoucích bajtů v paměti. 85 16 je na místě $0200. 50 16 z adresy 0050 $ je v lokalitě $0201. Problém endianness zde nevzniká, protože adresa má pouze jeden bajt, což je spodní bajt. Skutečný bajt, který je zkopírován, není součástí instrukce. 85 a ne 8D pro adresování nulové stránky se zde používají pro STA.

Nemá smysl používat okamžité adresování k přenosu bajtu z akumulátoru na místo v paměti. Je to proto, že skutečná hodnota jako $FF musí být uvedena v instrukci v okamžitém adresování. Okamžité adresování tedy není možné pro přenos bajtové hodnoty z registru v µP do libovolného paměťového místa.

Mnemotechniky LDX, STX, LDY a STY
LDX a STX jsou podobné LDA a STA. Zde se ale používá registr X a ne registr A (akumulátor). LDY a STY jsou podobné LDA a STA. Zde se však používá registr Y a nikoli registr A. Viz Tabulka 4.21 pro každý operační kód v hexadecimální soustavě, který odpovídá konkrétní mnemotechnické pomůcce a konkrétnímu režimu adresování.

Převody registrace k registraci
Předchozí dvě sady instrukcí v tabulce 4.21 se zabývají kopírováním paměti/mikroprocesorového registru (přenos) a kopírováním registru/registru (přenos). Instrukce TAX, TXA, TAY, TYA, TSX a TXS provádějí kopírování (přenos) z registru v mikroprocesoru do jiného registru téhož mikroprocesoru.

Chcete-li zkopírovat bajt z A do X, instrukce zní:

DAŇ

Chcete-li zkopírovat bajt z X do A, instrukce je:

TX

Chcete-li zkopírovat bajt z A do Y, instrukce zní:

RUKA

Chcete-li zkopírovat bajt z Y do A, instrukce zní:

TYA

U počítače commodore 64 je zásobník stránka 1 hned za stránkou 0 v paměti. Jako každá jiná stránka se skládá z 25610 10 umístění bajtů, od $0100 do $01FF. Normálně se program provádí od jedné instrukce k další po sobě jdoucí instrukci v paměti. Čas od času dojde ke skoku do jiného segmentu kódu paměti (souboru instrukcí). Oblast zásobníku v paměti (RAM) má adresy dalších instrukcí, od kterých byly skoky (nebo větve) přerušeny pro pokračování programu.

Ukazatel zásobníku „S“ je 9bitový registr v 6502 µP. První bit (zcela vlevo) je vždy 1. Všechny adresy umístění bajtů na stránce jedna začínají číslem 1 následovaným 8 různými bity pro 256 10 umístění. Ukazatel zásobníku má adresu umístění na stránce 1, která má adresu další instrukce, kterou má program vrátit a pokračovat v ní po provedení aktuálního segmentu kódu (na který se skočí). Protože první bit všech adres zásobníku (první stránka) začíná číslem 1, registr ukazatele zásobníku musí obsahovat pouze zbývajících osm bitů. Koneckonců, jeho první bit, který je nejvíce vlevo (devátý bit počítáno zprava), je vždy 1.

Chcete-li zkopírovat bajt z S do X, instrukce je:

TSX

Chcete-li zkopírovat bajt z X do S, instrukce je:

TXT

Instrukce registr-to-registr neberou žádný operand. Skládají se pouze z mnemotechnické pomůcky. Každá mnemotechnická pomůcka má svůj operační kód v šestnáctkové soustavě. Toto je v režimu implicitního adresování, protože neexistuje žádný operand (žádná adresa paměti, žádná hodnota).

Poznámka: Neexistuje žádný přenos X na Y nebo Y na X (kopírování).

4.3 Aritmetické operace

Obvod, aritmetická logická jednotka v 6502 µP, může přidat pouze dvě osmibitová čísla najednou. Neodčítá, nenásobí a nedělí. Následující tabulka ukazuje operační kódy a režimy adresování pro aritmetické operace:

Poznámka: Všechny mnemotechnické pomůcky pro aritmetické operace a další typy operací (tj. všech 6502 mnemotechnických pomůcek) mají jeden byte provozního (op) kódu. Pokud existuje více než jeden režim adresování pro mnemotechnickou pomůcku, budou existovat různé operační kódy pro stejnou mnemotechnickou pomůcku: jeden pro každý režim adresování. C, D a V v tabulce jsou příznaky stavového registru. Jejich význam bude uveden později podle potřeby.

Přidání čísel bez znaménka
U 6502 µP jsou čísla se znaménkem čísla dvojkového doplňku. Čísla bez znaménka jsou běžná kladná čísla, která začínají od nuly. Takže pro bajt osmibitů je nejmenší číslo bez znaménka 00000000 2 = 0 10 = 00 16 a největší číslo bez znaménka je 11111111 2 = 255 10 = FF 16 . Pro dvě čísla bez znaménka je sčítání:

A+M+C→A

To znamená, že 8bitový obsah akumulátoru je přičten aritmetickou logickou jednotkou k bajtu (8bitů) z paměti. Po sečtení A a M přejde přenos do devátého bitu do buňky příznaku přenosu ve stavovém registru. Jakýkoli předchozí bit přenosu z předchozího přidání, který je stále v buňce příznaku přenosu ve stavovém registru, je také přidán k součtu A a M, takže A+M+C→A. Výsledek je vložen zpět do akumulátoru.

Pokud je přičtení úroků:

A + M

A není třeba přidávat žádné předchozí přenášení, příznak přenosu musí být vymazán, což je 0, takže přidání je:

A+M+0→A stejné jako A+M→A

Poznámka: Pokud se k A přidá M a dojde k přenosu 1, protože výsledek je větší než 255 10 = 11111111 2 = FF 16 , toto je nový přenos. Tento nový přenos 1 je automaticky odeslán do buňky s příznakem přenosu v případě, že jej potřebuje další pár osmi bitů k sečtení (další A + M).

Kód pro přidání dvou nepodepsaných osmibitů
00111111 2 +00010101 2 je stejný jako 3F 16 + 15 16 což je stejné jako 63 10 +21 10 . Výsledek je 010101002 2 což je stejné jako 54 16 a 84 10 . Výsledek nepřesahuje maximální počet pro osm bitů, což je 255 10 = 11111111 2 = FF 16 . Takže neexistuje žádný výsledný přenos 1. Jinými slovy, výsledný přenos je 0. Před přidáním neexistuje žádné předchozí přenášení 1. Jinými slovy, předchozí přenos je 0. Kód k provedení tohoto sčítání může být:

CLC
LDA#$3F
ADC # 15 $

Poznámka: Při psaní jazyka symbolických instrukcí se na konci každé instrukce stiskne klávesa „Enter“. V tomto kódu jsou tři instrukce. První instrukce (CLC) vymaže příznak přenosu v případě, že předchozí přidání má 1. CLC lze provést pouze v režimu implicitního adresování. Mnemotechnická pomůcka pro implicitní režim adresování nebere žádný operand. Toto vymaže přenosovou buňku stavového registru P. Vymazání znamená přidělení bitu 0 buňce s příznakem přenosu. Další dvě instrukce v kódu používají režim okamžitého adresování. Při okamžitém adresování existuje pouze jeden operand pro mnemotechnickou pomůcku, kterým je číslo (a ani adresa paměti ani registru). A tak před číslem musí být „#“. „$“ znamená, že následující číslo je hexadecimální.

Druhá instrukce načte číslo 3F 16 do akumulátoru. Pro třetí instrukci obvod aritmetické logické jednotky µP vezme předchozí (vyčištěný) přenos 0 (vynucený na 0) buňky s příznakem přenosu, stavového registru a přidá ho k 15 16 stejně jako na hodnotu, která je již v 3F 16 akumulátor a vloží kompletní výsledek zpět do akumulátoru. V tomto případě je výsledný přenos 0. ALU (aritmetická logická jednotka) pošle (vloží) 0 do buňky s příznakem přenosu stavového registru. Stavový registr procesoru a stavový registr znamenají totéž. Pokud dojde k přenosu 1, ALU odešle 1 do příznaku přenosu stavového registru.

Před provedením musí být v paměti tři řádky předchozího kódu. Operační kód 1816 pro CLC (implicitní adresování) je v umístění 0200 bajtů $. Operační kód A9 16 pro LDA (okamžité adresování) je v $0201 byte umístění. Číslo 3F 10 je v $0202 byte umístění. Operační kód 69 16 pro LDA (okamžité adresování) je v $0203 byte umístění. Číslo 15 10 je v $0204 byte umístění.

Poznámka: LDA je instrukce pro přenos (načtení) a nikoli aritmetická instrukce (mnemotechnika).

Kód pro přidání dvou nepodepsaných šestnáctibitů
Všechny registry v 6502 µP jsou v podstatě osmibitové registry, kromě PC (Program Counter), který je 16bitový. Dokonce i stavový registr je široký 8 bitů, i když jeho osm bitů nepracuje společně. V této části se uvažuje přidání dvou 16 bitů bez znaménka s přenosem z prvního páru osmi bitů do druhého páru osmi bitů. Zajímavým přenosem je zde přenos z pozice osmého bitu do pozice devátého bitu.

Nechť jsou čísla 0010101010111111 2 = 2ABF16 16 = 10 943 10 a 0010101010010101 2 = 2A95 16 = 10 901 10 . Součet je 0101010101010100 2 = 5554 16 = 21 844 10 .

Přidání těchto dvou čísel bez znaménka do základu dva je následující:

Následující tabulka ukazuje stejné přidání s přenosem 1 z osmého bitu na devátou pozici bitu, počínaje zprava:

Při kódování se nejprve přidají dva nižší bajty. Potom ALU (aritmetická logická jednotka) odešle přenos 1 z pozice osmého bitu do pozice devátého bitu do buňky příznaku přenosu ve stavovém registru. Výsledek 0 1 0 1 0 1 0 0 bez přenosu jde do akumulátoru. Poté se s přenosem přidá druhý pár bajtů. Mnemotechnická pomůcka ADC znamená automatické přidávání s předchozím přenášením. V tomto případě se předchozí přenos, který je 1, nesmí před druhým přidáním změnit. Pro první přidání, protože jakékoli předchozí přenášení není součástí tohoto kompletního přidání, musí být vymazáno (uděleno 0).

Pro úplné přidání dvou párů bajtů je první přidání:

A + M + 0 -> A

Druhý dodatek je:

A + M + 1 -> A

Takže příznak přenosu musí být vymazán (s hodnotou 0) těsně před prvním přidáním. Následující program, u kterého si čtenář musí přečíst následující vysvětlení, používá pro toto sčítání režim absolutního adresování:

CLC
LDA 0213 USD
ADC 0215 $
; žádné vymazání, protože je potřeba hodnota příznaku přenosu
STA $ 0217
LDA 0214 USD
ADC 0216 $
STA $ 0218

Všimněte si, že u jazyka symbolických instrukcí 6502 začíná středníkem komentář. To znamená, že při provádění programu je ignorován středník a vše napravo. Program, který byl dříve napsán, je v textovém souboru a je uložen s názvem podle volby programátora a s příponou „asm“. Předchozí program není přesný program, který jde do paměti pro provedení. Odpovídající program v paměti se nazývá přeložený program, kde jsou mnemotechnické pomůcky nahrazeny operačními kódy (byty). Jakýkoli komentář zůstane v textovém souboru jazyka symbolických instrukcí a bude odstraněn, než se přeložený program dostane do paměti. Ve skutečnosti jsou dnes na disku uloženy dva soubory: soubor „.asm“ a soubor „.exe“. Soubor „.asm“ je stejný jako na předchozím obrázku. Soubor „.exe“ je soubor „.asm“ se všemi komentáři odstraněnými a všechny mnemotechnické pomůcky nahrazeny jejich operačními kódy. Při otevření v textovém editoru je soubor „.exe“ nerozpoznatelný. Pokud není uvedeno jinak, pro účely této kapitoly se soubor „.exe“ zkopíruje do paměti počínaje umístěním $0200. To je další význam zatížení.

Dvě 16bitová čísla, která mají být přidána, zabírají čtyři bajty v paměti pro absolutní adresování: dva bajty na číslo (paměť je posloupnost bajtů). Při absolutním adresování je operand k operačnímu kódu v paměti. Výsledek součtu je široký dva bajty a musí být také umístěn do paměti. To dává celkem 6 10 = 6 16 bajtů pro vstupy a výstupy. Vstupy nejsou z klávesnice a výstup není z monitoru nebo tiskárny. Vstupy jsou v paměti (RAM) a výstup (součet výsledku) se v této situaci vrací zpět do paměti (RAM).

Před spuštěním programu musí být přeložená verze nejprve v paměti. Při pohledu na předchozí kód programu je vidět, že instrukce bez komentáře tvoří 19 10 = 13 16 bajtů. Program tedy vezme z $0200 byte umístění v paměti na $0200 + $13 – $1 = $0212 byte umístění (počínaje od $0200 a ne $0201, což znamená – $1). Přidáním 6 bajtů pro vstupní a výstupní čísla skončí celý program na $0212 + $6 = $0218. Celková délka programu je 19 16 = 25 10 .

Nižší bajt augendu by měl být v adrese $0213 a vyšší bajt stejného augendu by měl být v adrese $0214 – little endianness. Podobně nižší bajt sčítání by měl být v adrese $0215 a vyšší bajt stejného sčítání by měl být v adrese $0216 – little endianness. Nižší bajt výsledku (součet) by měl být v adrese $0217 a vyšší bajt stejného výsledku by měl být v adrese $0218 – little endianness.

Operační kód 18 16 pro CLC (implicitní adresování) je v byte umístění 0200 $. Operační kód pro „LDA $ 0213“, tj. AD 16 pro LDA (absolutní adresování), je v byte umístění $0201. Spodní bajt augendu, který je 10111111, je v místě bajtu paměti $0213. Pamatujte, že každý operační kód zabírá jeden bajt. Adresa „$0213“ pro „LDA $0213“ je v bajtových umístěních $0202 a $0203. Instrukce „LDA $0213“ načte spodní bajt augendu do akumulátoru.

Operační kód pro „ADC $ 0215“, tj. 6D 16 pro ADC (absolutní adresování), je v byte umístění $ 0204. Spodní bajt dodatku, který je 10010101, je v umístění bajtu $0215. Adresa „$0215“ u „ADC $0215“ je v bajtových umístěních $0205 a $0206. Instrukce „ADC $0215“ přidá spodní byte sčítání k dolnímu bytu augendu, který je již v akumulátoru. Výsledek je umístěn zpět do akumulátoru. Jakýkoli přenos po osmém bitu je odeslán do příznaku přenosu stavového registru. Buňka s příznakem přenosu nesmí být vymazána před druhým přidáním vyšších bajtů. Tento přenos se automaticky přičte k součtu vyšších bajtů. Ve skutečnosti je přenos 0 automaticky přidán k součtu nižších bajtů na začátku (ekvivalentní tomu, že se nepřidává žádný přenos) kvůli CLC.

Komentář trvá dalších 48 10 = 30 16 bajtů. To však zůstává pouze v textovém souboru „.asm“. Do paměti se nedostane. Odstraňuje se překladem, který provádí assembler (program).

Pro další instrukci, která je „STA $0217“, operační kód STA, který je 8D 16 (absolutní adresování) je v byte umístění $0207. Adresa „$0217“ pro „STA $0217“ je v paměťových místech $0208 a $0209. Instrukce „STA $0217“ zkopíruje osmibitový obsah akumulátoru do paměťového místa $0217.

Vyšší bajt augendu, který je 00101010, je v paměťovém místě $0214 a vyšší bajt augendu, který je 00101010, je v místě bajtu $02 16 . Operační kód pro „LDA $0214“, což je AD16 pro LDA (absolutní adresování), je v byte umístění $020A. Adresa „$0214“ pro „LDA $0214“ je v umístěních $020B a $020C. Instrukce „LDA $0214“ načte vyšší bajt augendu do akumulátoru a vymaže vše, co je v akumulátoru.

Operační kód pro „ADC $ 0216“, což je 6D 16 pro ADC (absolutní adresování) je v byte umístění $020D. Adresa „$0216“ „ADC 0216“ je v bajtových umístěních $020E a $020F. Instrukce „ADC $0216“ přidá vyšší byte sčítání k vyššímu bytu augendu, který je již v akumulátoru. Výsledek je vložen zpět do akumulátoru. Pokud existuje přenos 1, pro toto druhé přidání se automaticky umístí do přenosové buňky stavového registru. Ačkoli přenos za šestnáctý bit (vlevo) není pro tento problém vyžadován, je hezké zkontrolovat, zda došlo k přenosu 1 kontrolou, zda se příznak přenosu stal 1.

Pro další a poslední instrukci, která je „STA $0218“, je operační kód STA, což je 8D16 (absolutní adresování), v bajtovém umístění $0210. Adresa „$0218“ pro „STA $0218“ je v paměťových místech $0211 a $0212. Instrukce „STA $0218“ zkopíruje osmibitový obsah akumulátoru do paměťového místa $0218. Výsledkem sečtení dvou šestnáctibitových čísel je 0101010101010100, přičemž spodní byte 01010100 je v paměťovém místě $0217 a vyšší bajt 01010101 v paměťovém místě $0218 – malý endianness.

Odčítání
U 6502 µP jsou čísla se znaménkem čísla dvojkového doplňku. Číslo doplňku dvojky může být osm bitů, šestnáct bitů nebo libovolný násobek osmi bitů. S dvojkovým doplňkem je první bit zleva znaménkový bit. Pro kladné číslo je tento první bit 0 pro označení znaménka. Zbytek bitů tvoří číslo normálním způsobem. Chcete-li získat dvojkový doplněk záporného čísla, invertujte všechny bity pro odpovídající kladné číslo a pak přidejte 1 k výsledku z pravého konce.

Pro odečtení jednoho kladného čísla od jiného kladného čísla se subtrahend převede na záporné číslo s dvojkovým doplňkem. Poté se normálním způsobem přidá minuend a nové záporné číslo. Osmibitové odečítání tedy bude:

Kde se předpokládá přenos jako 1. Výsledkem v akumulátoru je rozdíl ve dvojkovém doplňku. Takže pro odečtení dvou čísel musí být nastaven příznak přenosu (na 1).

Při odečítání dvou šestnáctibitových čísel se odčítání provádí dvakrát jako při sčítání dvou šestnáctibitových čísel. Protože odečítání je formou sčítání u 6502 µP, při odečítání dvou šestnáctibitových čísel je příznak přenosu nastaven pouze jednou pro první odečítání. Pro druhé odečtení se jakékoli nastavení příznaku přenosu provede automaticky.

Programování odčítání pro osmibitová čísla nebo šestnáctibitová čísla se provádí podobně jako programování sčítání. Příznak přenosu je však nutné nastavit hned na začátku. Mnemotechnická pomůcka k tomu je:

Odečítání s šestnáctibitovými kladnými čísly
Zvažte odčítání s následujícími čísly:

Toto odčítání nezahrnuje dvojkový doplněk. Protože se odečítání v 6502 µP provádí ve dvou komplementech, odečítání v základu dva se provádí následovně:

Výsledek dvojkového doplňku je stejný jako výsledek, který se získá z běžného odčítání. Všimněte si však, že 1, která jde na sedmnáctou pozici bitu zprava, je ignorována. Minuend a subtrahend jsou rozděleny každý na dva osminové bity. Dvojkový doplněk 10010110 spodního bajtu subtrahendu je určen nezávisle na jeho vyšším bajtu a jakémkoli přenosu. Dvojkový doplněk 11101011 vyššího bajtu subtrahendu je určen nezávisle na jeho nižším bajtu a jakémkoli přenosu.

16 bitů minuendu je již ve dvojkovém doplňku, začíná 0 zleva. Nepotřebuje tedy žádné úpravy v bitech. U 6502 µP se spodní bajt minuendu bez jakékoli úpravy přidá k dolnímu bajtu dvojkového doplňku subtrahendu. Spodní bajt minuendu není převeden na dvojkový doplněk, protože šestnáct bitů celého minuendu musí být již ve dvojkovém doplňku (s 0 jako prvním bitem vlevo). V tomto prvním přidání je přidáno povinné přenášení 1 kvůli instrukci 1=0 SEC.

V aktuálním efektivním odečítání je přenos 1 (sčítání) z osmého bitu na devátý bit (zprava). Protože se v podstatě jedná o odečítání, jakýkoli bit, který má být v příznaku přenosu ve stavovém registru, je doplněn (invertován). Takže přenos 1 se v příznaku C stane 0. Ve druhé operaci je vyšší bajt minuendu přidán k bajtu doplňku vyšších dvou subtrahendu. Automaticky doplněný bit příznaku přenosu stavového registru (v tomto případě je 0) je také přidán (k vyšším bytům). Jakákoli 1, která přesahuje šestnáctý bit zprava, je ignorována.

Další věcí je kódovat celé toto schéma následovně:

SEC
LDA 0213 USD
0215 SBC
; žádné vymazání, protože je potřeba hodnota invertovaného příznaku přenosu
STA $ 0217
LDA 0214 USD
SBC 0216 USD
STA $ 0218

Pamatujte, že v jazyce symbolických instrukcí 6502 začíná středníkem komentář, který není obsažen v přeložené verzi programu v paměti. Dvě 16bitová čísla pro odečítání zabírají čtyři bajty paměti s absolutním adresováním; dva na číslo (paměť je řada bajtů). Tyto vstupy nejsou z klávesnice. Výsledek součtu je dva bajty a také musí být umístěn v paměti na jiné místo. Tento výstup nejde na monitor nebo tiskárnu; jde do paměti. To dává celkem 6 10 = 6 16 bajtů pro vstupy a výstupy, které mají být umístěny do paměti (RAM).

Než je program spuštěn, musí být nejprve v paměti. Při pohledu na kód programu je vidět, že instrukce bez komentáře tvoří 19 10 = 13 16 bajtů. Vzhledem k tomu, že všechny programy v této kapitole začínají z paměťového místa $0200, program převezme z místa $0200 bajtů v paměti do místa $0200 + $13 – $1 = $0212 bajtů (začíná od $0200 a nikoli $0201). Tento rozsah nezahrnuje oblast pro vstupní a výstupní bajty. Dvě vstupní čísla zabírají 4 bajty a jedno výstupní číslo 2 bajty. Přidáním 6 bajtů pro vstupní a výstupní čísla vznikne rozsah pro program, který končí na $0212 + $6 = $0218. Celková délka programu je 19 16 = 25 10 .

Spodní bajt minuendu by měl být v adrese $0213 a vyšší bajt stejného minuendu by měl být v adrese $0214 – little endianness. Podobně by měl být nižší bajt subtrahendu v adrese $0215 a vyšší bajt stejného subtrahendu by měl být v adrese $0216 – little endianness. Nižší bajt výsledku (rozdíl) by měl být v adrese $0217 a vyšší bajt stejného výsledku by měl být v adrese $0218 – little endianness.

Operační kód 38 16 pro SEC (implicitní adresování) je v adrese 0200 $. Předpokládá se, že všechny programy v této kapitole začínají na paměťovém místě $0200, čímž se zruší jakýkoli program, který by tam byl; pokud není uvedeno jinak. Operační kód pro „LDA $ 0213“, tj. AD 16 , pro LDA (absolutní adresování) je v $0201 byte umístění. Spodní bajt minuendu, který je 10111111, je v místě bajtu paměti $0213. Pamatujte, že každý operační kód zabírá jeden bajt. Adresa „$0213“ pro „LDA $0213“ je v bajtových umístěních $0202 a $0203. Instrukce „LDA $0213“ načte spodní byte minuendu do akumulátoru.

Operační kód pro „SBC $ 0215“, tj. ED 16 , pro SBC (absolutní adresování) je v umístění $0204 bajtů. Spodní byte subtrahendu, který je 01101010, je v umístění bajtů $0215. Adresa „$0215“ u „ADC $0215“ je v bajtových umístěních $0205 a $0206. Instrukce „SBC $0215“ odečte spodní byte subtrahendu od spodního bytu minuendu, který je již v akumulátoru. Toto je odčítání dvojkového doplňku. Výsledek je umístěn zpět do akumulátoru. Doplněk (inverze) jakéhokoli přenosu po osmém bitu je odeslán do příznaku přenosu stavového registru. Tento příznak přenosu nesmí být vymazán před druhým odečtením s vyššími bajty. Tento přenos je automaticky přidán k odečítání vyšších bajtů.

Komentář trvá dalších 57 10 = 3916 16 bajtů. To však zůstává pouze v textovém souboru „.asm“. Do paměti se nedostane. Odstraňuje se překladem, který provádí assembler (program).

Pro další instrukci, která je „STA $ 0217“, operační kód STA, tj. 8D 16 (absolutní adresování), je v umístění $0207 bajtů. Adresa „$0217“ pro „STA $0217“ je v paměťových místech $0208 a $0209. Instrukce „STA $0217“ zkopíruje osmibitový obsah akumulátoru do paměťového místa $0217.

Vyšší bajt minuendu, který je 00101010, je v paměťovém místě $0214 a vyšší bajt subtrahendu, který je 00010101, je v místě bajtu $0216. Operační kód pro „LDA $ 0214“, tj. AD 16 pro LDA (absolutní adresování) je v byte umístění $020A. Adresa „$0214“ pro „LDA $0214“ je v umístěních $020B a $020C. Instrukce „LDA $0214“ načte vyšší byte minuendu do akumulátoru a vymaže vše, co je v akumulátoru.

Operační kód pro „SBC $ 0216“, tj. ED 16 pro SBC (absolutní adresování), je v byte umístění $020D. Adresa „$0216“ pro „SBC $0216“ je v bajtových umístěních $020E a $020F. Instrukce „SBC $0216“ odečte vyšší bajt subtrahendu od vyššího bajtu minuendu (dvojkový doplněk), který je již v akumulátoru. Výsledek je vložen zpět do akumulátoru. Pokud existuje přenos 1 pro toto druhé odečítání, jeho doplněk se automaticky umístí do přenosové buňky stavového registru. Ačkoli přenos za šestnáctý bit (vlevo) není pro tento problém vyžadován, je hezké zkontrolovat, zda k přenosu doplňku dochází kontrolou příznaku přenosu.

Pro další a poslední instrukci, která je „STA $0218“, operační kód STA, tj. 8D 16 (absolutní adresování), je v umístění 0210 bajtů $. Adresa „$0218“ pro „STA $0218“ je v paměťových místech $0211 a $0212. Instrukce „STA $0218“ zkopíruje osmibitový obsah akumulátoru do paměťového místa $0218. Výsledek odečtení se dvěma šestnáctibitovými čísly je 0001010101010101 s nižším bytem 01010101 v paměťovém místě $0217 a vyšším bytem 00010101 v paměťovém místě $0218 – malá endianness.

6502 µP má obvody pouze pro sčítání a nepřímo pro odečítání dvou komplementů. Nemá obvody pro násobení a dělení. Pro násobení a dělení by měl být napsán program v assembleru s detaily, včetně přesouvání dílčích produktů a dílčích dividend.

4.4 Logické operace

V 6502 µP je mnemotechnická pomůcka pro OR ORA a mnemotechnická pomůcka pro exkluzivní OR je EOR. Všimněte si, že logické operace nemají implicitní adresování. Implicitní adresování nevyžaduje žádný operand. Každý z logických operátorů musí mít dva operandy. První je v akumulátoru a druhý je v paměti nebo v instrukci. Výsledek (8 bitů) je zpět do akumulátoru. První v akumulátoru se tam buď vloží okamžitou instrukcí, nebo se zkopíruje z paměti s absolutním adresováním. V této části je pro ilustraci použito pouze adresování na nulté stránce. Všechny tyto logické operátory jsou bitové operátory.

A
Následující tabulka ilustruje bitové součinové spojení v binární, šestnáctkové a desítkové soustavě:

Všechny programy v této kapitole by měly začínat na pozici bajtu paměti $0200. Programy v této sekci jsou však na stránce nula, s cílem ilustrovat použití stránky nula bez vyššího bajtu 00000000 2 . Předchozí AND může být kódováno následovně:

LDA #$9A ; ne z paměti – okamžité adresování
AND #$CD ; ne z paměti – okamžité adresování
STA $ 30; ukládá 88 USD za 0030 USD s nulovou základnou

NEBO
Následující tabulka ilustruje bitový OR v binární, šestnáctkové a desítkové soustavě:

LDA #$9A ; ne z paměti – okamžité adresování
ORA #$CD ; ne z paměti – okamžité adresování
STA $ 30; ukládá $CF za 0030 $

VOLNÝ, UVOLNIT
Následující tabulka ilustruje Bitwise XOR v binární, šestnáctkové a desítkové soustavě:

LDA #$9A ; ne z paměti – okamžité adresování
EOR #$CD ; ne z paměti – okamžité adresování
STA $ 30; ukládá 57 USD za 0030 USD s nulovou základnou

4.5 Operace Shift a Rotate

Mnemotechnické pomůcky a operační kódy pro operátory posunu a rotace jsou:

ASL: Posun doleva o jeden bit akumulátoru nebo paměťového místa a vložení 0 do prázdné buňky úplně vpravo.

LSR: Posunutí doprava o jeden bit akumulátoru nebo paměťového místa, vložením 0 do prázdné buňky zcela vlevo.
ROL: Otočte o jeden bit doleva od místa akumulátoru nebo paměti a vložte bit, který vypadl vlevo, do prázdné buňky úplně vpravo.
ROR: Otočte o jeden bit vpravo od místa akumulátoru nebo paměti a vložte bit, který vypadl vpravo, do prázdné buňky zcela vlevo.

Chcete-li provést posun nebo otočení s akumulátorem, instrukce zní asi takto:

LSR A

Toto používá jiný režim adresování nazývaný režim adresování akumulátoru.

Chcete-li provést posun nebo otočení s umístěním bajtové paměti, instrukce je něco takového:

ROR $ 2BCD

Kde 2BCD je umístění paměti.

Všimněte si, že neexistuje žádný okamžitý nebo předpokládaný režim adresování pro posouvání nebo otáčení. Neexistuje žádný režim okamžitého adresování, protože nemá smysl posouvat nebo otáčet číslo, které zůstane pouze v instrukci. Neexistuje žádný předpokládaný režim adresování, protože návrháři 6502 µP chtějí, aby byl posunut nebo otočen pouze obsah akumulátoru (registr A) nebo umístění bajtů v paměti.

4.6 Režim relativního adresování

Mikroprocesor vždy zvýší (o 1, 2 nebo 3 jednotky) programový čítač (PC), aby ukázal na další instrukci, která má být provedena. 6502 µP má instrukci, jejíž mnemotechnická pomůcka je BVS, což znamená větev při přetečení. PC se skládá ze dvou bajtů. Tato instrukce způsobí, že PC bude mít jinou paměťovou adresu pro další instrukci, která se má provést, což není výsledkem normálního přírůstku. Činí tak přidáním nebo odečtením hodnoty, nazývané offset, k obsahu PC. A tak počítač poté ukazuje na jiné (rozvětvené) paměťové místo, kde může počítač pokračovat ve spouštění odtud. Offset je celé číslo od -128 10 na +127 10 (dvou doplněk). Takže offset může způsobit skok v paměti. Jestli je pozitivní nebo pozadu v paměti, nebo jestli je negativní.

Instrukce BVS přebírá pouze jeden operand, kterým je offset. BVS používá relativní adresování. Zvažte následující pokyn:

BVS $ 7F

V základu dva, 7F H je 01111111 2 = 127 10 . Předpokládejme, že obsah v PC pro další instrukci je 0300 $. Instrukce BVS způsobí, že $ 7F (kladné číslo již ve dvojkovém doplňku) bude přidáno k $ 0300, což dává $ 037 F. Takže místo další instrukce, která má být provedena na paměťovém místě $0300, je to na paměťovém místě $037F (přibližně poloviční rozdíl stránky).

Existují další větvené instrukce, ale BVS je velmi dobrá pro ilustraci relativního adresování. Relativní adresování se zabývá instrukcemi větve.

4.7 Indexované adresování a nepřímé adresování odděleně

Tyto režimy adresování umožňují 6502 µP zpracovat obrovské množství dat v krátkých časových intervalech se sníženým počtem instrukcí. Existuje 64 kB umístění pro celou paměť Comodore-64. Takže pro přístup k libovolnému umístění bajtů o 16 bitech jsou potřeba dva bajty. Jedinou výjimkou z potřeby dvou bajtů je stránka nula, kde je vyšší bajt $00 vynechán, aby se ušetřil prostor, který zabírá instrukce v paměti. V režimu adresování bez stránky nula jsou vyšší i nižší bajty 16bitové adresy paměti většinou nějak indikovány.

Základní indexované adresování

Absolutní indexové adresování
Pamatujte, že registr X nebo Y se nazývá indexový registr. Zvažte následující pokyn:

LDA $ C453,X

Předpokládejme, že hodnota 6 H je v registru X. Všimněte si, že 6 není nikde v instrukci napsáno. Tato instrukce přidá hodnotu 6H k C453 H který je součástí zadané instrukce v textovém souboru, který se má ještě sestavit – C453 H + 6 H = C459 H . LDA znamená načíst bajt do akumulátoru. Byte, který se má načíst do akumulátoru, pochází z adresy $ C459. $ C459, což je součet $ C453, který je zadán s instrukcí a 6 H která se nachází v registru X, se stává efektivní adresou, ze které pochází byte, který má být načten do akumulátoru. Pokud 6 H byl v registru Y, Y je napsáno místo X v instrukci.

V příkazu zadané instrukce je $C453 známý jako základní adresa a 6 H v registru X nebo Y je známá jako počítací nebo indexová část pro efektivní adresu. Základní adresa může odkazovat na jakoukoli bytovou adresu v paměti a na dalších 256 10 adresy lze přistupovat za předpokladu, že započatý index (nebo počet) v registru X nebo Y je 0. Pamatujte, že jeden bajt může poskytnout nepřetržitý rozsah až 256 10 čísla (tj. 00000000 2 na 11111111 2 ).

Absolutní adresování tedy přidá vše, co je již vloženo (bylo vloženo jinou instrukcí) do registru X nebo Y k 16 adresám, které jsou zapsány s instrukcí, aby se získala efektivní adresa. V typované instrukci jsou dva indexové registry rozlišeny X nebo Y, které jsou napsány za čárkou. Zadává se buď X nebo Y; ne obojí.

Poté, co je celý program napsán v textovém editoru a uložen s příponou „.asm“, musí assembler, což je jiný program, přeložit napsaný program do toho, co je (nahráno) v paměti. Předchozí instrukce, která je „LDA $C453,X“, zabírá v paměti tři bajtová místa, nikoli pět.

Pamatujte, že mnemotechnická pomůcka, jako je LDA, může mít více než jeden operační kód (různé bajty). Operační kód pro instrukci, která používá registr X, se liší od operačního kódu, který používá registr Y. Assembler ví, jaký operační kód použít na základě zadané instrukce. Jednobajtový operační kód pro „LDA $ C453,X“ se liší od jednobajtového provozního kódu pro „LDA $ C453,Y“. Ve skutečnosti je operační kód pro LDA v „LDA $ C453,X“ BD a operační kód pro LDA v „LDA $ C453,9“ je BD.

Pokud je operační kód pro LDA v umístění 0200 bajtů $. Poté 16bitová adresa $C453 převezme další bajtová umístění v paměti, která jsou $0201 a $0202. Konkrétní bajt operačního kódu udává, zda se jedná o registr X nebo registr Y. A tak sestavená jazyková instrukce, která je „LDA $C453,X“ nebo „LDA $C453,Y“, zabírá v paměti tři po sobě jdoucí bajty, nikoli čtyři nebo pět.

Zero-Page Indexed Addressing
Adresování indexu nulové stránky je jako adresování absolutního indexu, které bylo popsáno dříve, ale cílový bajt musí být pouze na stránce nula (od $0000 do $00FF). Nyní, když se zabýváme nulovou stránkou, vyšší bajt, který je vždy 00 H protože paměťovým místům se obvykle vyhneme. Obvykle se tedy uvádí, že stránka nula začíná od 00 $ do FF. Takže předchozí instrukce „LDA $ C453,X“ je:

LDA $ 53,X

$C4, vyšší bajt, který odkazuje na stránku nad nulou stránky, nelze v této instrukci použít, protože vkládá očekávaný cílový bajt, který má být načten, do akumulovaného bajtu mimo a nad nulu stránky.

Když se hodnota zadaná v instrukci přičte k hodnotě v indexovém registru, součet by neměl dát výsledek nad nulou stránky (FF H ). Je tedy vyloučeno mít instrukci jako „LDA $FF, X“ a hodnotu jako FF H v indexovém registru, protože FF H + FF H = 200 H což je umístění prvního bajtu (0200 $) stránky 2 (třetí stránka) v paměti, je velká vzdálenost od stránky 0. Takže s indexovaným adresováním s nulovou stránkou musí efektivní adresa ležet na stránce nula.

Nepřímé adresování

Skokové absolutní adresování
Než budeme diskutovat o absolutním nepřímém adresování, je dobré se nejprve podívat na absolutní adresování JMP. Předpokládejme, že adresa, která má hodnotu úroku (cílový bajt), je 8765 $. Jedná se o 16 bitů sestávajících ze dvou bajtů: vyšší bajt je 87 H a spodní bajt, který je 65 H . Takže dva bajty za 8765 $ jsou vloženy do PC (počítadla programů) pro další instrukci. Co je napsáno v programu (souboru) v assembleru je:

JMP 8765 dolarů

Probíhající program v paměti skočí z jakékoli adresy, na kterou přistupoval, na 8765 $. Mnemotechnická pomůcka JMP má tři operační kódy, které jsou 4C, 6C a 7C. Operační kód pro toto absolutní adresování je 4C. Operační kód pro absolutní nepřímé adresování JMP je 6C (viz následující obrázky).

Absolutní nepřímé adresování
Toto se používá pouze s instrukcí skoku (JMP). Předpokládejme, že adresa, která má bajt zájmu (cílový bajt), je 8765 $. Jedná se o 16 bitů sestávajících ze dvou bajtů: vyšší bajt je 87 H a spodní bajt, který je 65 H . Při absolutním nepřímém adresování jsou tyto dva bajty ve skutečnosti umístěny ve dvou po sobě jdoucích místech bajtů jinde v paměti.

Předpokládejme, že jsou umístěny v paměťových místech $0210 a $0211. Potom spodní bajt adresy zájmu, která je 65 H je v adrese $0210 a vyšší bajt, který je 87 H je na adrese $0211. To znamená, že nižší bajt paměti jde na nižší po sobě jdoucí adresu a vyšší bajt paměti jde na vyšší po sobě jdoucí adresu – malá endianness.

16bitová adresa může odkazovat na dvě po sobě jdoucí adresy v paměti. V tomto světle adresa $0210 odkazuje na adresy $0210 a $0211. Adresový pár $0210 a $0211 obsahuje konečnou adresu (16 bitů ze dvou bajtů) cílového bajtu, přičemž spodní bajt je 65 H v $ 0210 a vyšší byte 87 H za 0211 dolarů. Takže instrukce skoku, která je napsána, je:

JMP (0210 $)

Mnemotechnická pomůcka JMP má tři operační kódy, které jsou 4C, 6C a 7C. Operační kód pro absolutní nepřímé adresování je 6C. V textovém souboru je napsáno „JMP (0210 $)“. Kvůli závorkám používá assembler (překladač) operační kód 6C pro JMP, nikoli 4C nebo 7C.

Při absolutním nepřímém adresování jsou ve skutečnosti tři oblasti paměti. První oblast se může skládat z umístění bajtů $0200, $0201 a $0202. To má tři bajty pro instrukci „JMP ($0210)“. Druhá oblast, která nemusí být nutně vedle první, se skládá ze dvou po sobě jdoucích umístění bajtů $0210 a $0211. Je to spodní bajt zde (0210 $), který je zadán v instrukci programu assembleru. Pokud je adresa zájmu 8 765 $, dolní bajt 65 H je v umístění 0210 bajtů $ a vyšší bajt z 87 H je v $0211 byte umístění. Třetí oblast se skládá pouze z umístění jednoho bajtu. Je to adresa 8765 $ pro cílový bajt (poslední bajt zájmu). Dvojice po sobě jdoucích adres, $0210 a $0211, obsahuje ukazatel $8765, což je adresa zájmu. Po výpočetní interpretaci je to 8 765 USD, které jde do PC (Program Counter) pro přístup k cílovému bajtu.

Nepřímé adresování nulové stránky
Toto adresování je stejné jako absolutní nepřímé adresování, ale ukazatel musí být na stránce nula. Dolní bajtová adresa oblasti ukazatele je to, co je v zadané instrukci takto:

JMP (50 USD)

Vyšší bajt ukazatele je v umístění 51 bajtů $. Efektivní adresa (ukazatelná) nemusí být na stránce nula.

Takže s adresováním indexu je hodnota v registru indexu přidána k základní adrese, která je uvedena v instrukci, aby měla efektivní adresu. Nepřímé adresování používá ukazatel.

4.8 Indexované nepřímé adresování

Absolutní indexované nepřímé adresování
Tento režim adresování se používá pouze s instrukcí JMP.
Při absolutním nepřímém adresování existuje pointovaná hodnota (byte) s vlastními dvěma po sobě jdoucími adresami bajtů. Tyto dvě po sobě jdoucí adresy tvoří ukazatel, který má být v oblasti ukazatele dvou po sobě jdoucích bajtů v paměti. Dolní bajt oblasti ukazatele je to, co je napsáno v instrukci v závorkách. Ukazatel je adresa pointované hodnoty. V předchozí situaci je 8765 $ adresou bodované hodnoty. $0210 (následuje $0211) je adresa, jejíž obsah je $8765, což je ukazatel. V režimu absolutního nepřímého adresování je to ($0210) to, co se zadává do programu (textového souboru), včetně závorek.

Na druhou stranu v režimu absolutního indexovaného nepřímého adresování je nižší adresní bajt pro oblast ukazatele tvořen přidáním hodnoty v registru X k zadané adrese. Pokud je například ukazatel v umístění adresy $0210, zadaná instrukce může být něco takového:

JMP (020 USD, X)

Kde má registr X hodnotu 6 H . 020A H + 6 H = 0210 H . Registr Y se v tomto režimu adresování nepoužívá.

Indexované nepřímé adresování s nulovou stránkou
Tento režim adresování používá registr X a nikoli registr Y. V tomto režimu adresování stále existuje pointovaná hodnota a ukazatel v jeho dvoubajtové oblasti ukazatele adresy. Na stránce nula musí být pro ukazatel dva po sobě jdoucí bajty. Adresa zadaná v instrukci je jednobajtová adresa. Tato hodnota se přičte k hodnotě v registru X a jakýkoli přenos je zahozen. Výsledek ukazuje na oblast ukazatele na stránce 0. Pokud je například adresa zájmu (ukázala) 8765 $ a nachází se v umístěních bajtů $50 a $51 na stránce 0 a hodnota v registru X je $30, zadaná instrukce je něco takového:

LDA (20,X $)

Protože 20 $ + 30 $ = 50 $.

Nepřímé indexované adresování
Tento režim adresování používá registr Y a nikoli registr X. V tomto režimu adresování stále existuje pointovaná hodnota a oblast ukazatele, ale obsah oblasti ukazatele funguje odlišně. Na stránce nula pro oblast ukazatele musí být dva po sobě jdoucí bajty. Spodní adresa oblasti ukazatele je napsána v instrukci. Toto číslo (pár bajtů), které je obsaženo v oblasti ukazatele, se přičte k hodnotě v registru Y, aby se získal skutečný ukazatel. Nechť je například adresa zájmu (ukazatel) 8765 $, hodnota 6H je v registru Y a číslo (dva bajty) je na adrese 50 H a 51 H . Dva bajty dohromady jsou $ 875 F, protože $ 875 F + $ 6 = $ 8765. Zadaná instrukce je něco takového:

LDA (50 USD), Y

4.9 Pokyny pro zvýšení, snížení a zkušební bity

Následující tabulka ukazuje operace instrukcí pro zvýšení a snížení:

INA a DEA zvyšují a snižují hodnotu akumulátoru. Tomu se říká adresování akumulátoru. INX, DEX, INY a DEY jsou pro registry X a Y. Neberou žádný operand. Používají tedy předpokládaný režim adresování. Přírůstek znamená přidání 1 do registru nebo bajtu paměti. Dekrementace znamená odečtení 1 od bajtu registru nebo paměti.

INC a DEC zvyšují a snižují bajt paměti (a ne registr). Použití adresování nulové stránky místo absolutního adresování má za úkol ušetřit paměť pro instrukci. Nulové adresování stránky je o jeden bajt menší než absolutní adresování instrukce v paměti. Režim adresování nulové stránky však ovlivňuje pouze nulovou stránku.

Instrukce BIT testuje bity bajtu v paměti s 8 bity v akumulátoru, ale nemění ani jeden. Jsou nastaveny pouze některé příznaky registru stavu procesoru „P“. Bity určeného paměťového místa jsou logicky spojeny AND s bity akumulátoru. Poté se nastaví následující stavové bity:

  • N, což je bit 7 a poslední bit (vlevo) stavového registru, přijímá bit 7 paměťového místa před AND.
  • V, což je bit 6 stavového registru, přijímá bit 6 paměťového místa před AND.
  • Příznak Z stavového registru je nastaven (vyroben na 1), pokud je výsledek AND nula (00000000 2 ). V opačném případě se vymaže (udělá 0).

4.10 Porovnání pokynů

Porovnávací instrukční mnemotechnické pomůcky pro 6502 µP jsou CMP, CPX a CPY. Po každém porovnání jsou ovlivněny příznaky N, Z a C registru stavu procesoru „P“. Příznak N se nastaví (vytváří 1), když je výsledkem záporné číslo. Pokud je výsledkem nula (000000002), nastaví se příznak Z (udělá se 1). Příznak C se nastaví (udělá 1), když dojde k přenosu z osmého na devátý bit. Následující tabulka poskytuje podrobnou ilustraci

Znamená „větší než“. Srovnávací tabulka by proto měla být samovysvětlující.

4.11 Pokyny pro skok a větvení

Následující tabulka shrnuje pokyny pro skok a větvení:

Instrukce JMP používá absolutní a nepřímé adresování. Zbytek pokynů v tabulce jsou pokyny pro větve. Používají pouze relativní adresování s 6502 µP. Díky tomu se tabulka stává samovysvětlující, pokud je čtena zleva doprava a shora dolů.

Všimněte si, že větve lze použít pouze na adresy v rozmezí -128 až +127 bajtů od dané adresy. Toto je relativní adresování. U instrukcí JMP i větve je přímo ovlivněn počítadlo programů (PC). 6502 µP neumožňuje větvení na absolutní adresu, i když skok může provádět absolutní adresování. Instrukce JMP není oborová instrukce.

Poznámka: Relativní adresování se používá pouze s instrukcemi větvení.

4.12 Oblast zásobníku

Podprogram je jako jeden z předchozích krátkých programů pro sečtení dvou čísel nebo odečtení dvou čísel. Oblast zásobníku v paměti začíná od $0100 do $01FF včetně. Tato oblast se jednoduše nazývá zásobník. Když mikroprocesor provede skok na instrukci podprogramu (JSR – viz následující diskuse), potřebuje vědět, kam se má po dokončení vrátit. 6502 µP uchovává tyto informace (zpáteční adresu) v nízké paměti od $0100 do $01FF (oblast zásobníku) a používá obsah registru ukazatele zásobníku, který je v mikroprocesoru „S“ jako ukazatel (9 bitů) na poslední vrácenou adresu. který je uložen na stránce 1 ($0100 až $01FF) paměti. Zásobník roste z $01FF a umožňuje vnořit podprogramy až do hloubky 128 úrovní.

Dalším využitím ukazatele zásobníku je zpracování přerušení. 6502 µP má piny označené jako IRQ a NMI. Je možné, že na tyto piny budou aplikovány malé elektrické signály, které způsobí, že 6502 µP ukončí provádění jednoho programu a spustí provádění jiného. V tomto případě je první program přerušen. Stejně jako podprogramy mohou být segmenty kódu přerušení vnořeny. Zpracování přerušení je diskutováno v další kapitole.

Poznámka : Ukazatel zásobníku má 8 bitů pro adresu nižšího bajtu při adresování míst od $0100 do $01FF. Vyšší bajt 00000001 2 se předpokládá.

Následující tabulka uvádí pokyny, které spojují ukazatel zásobníku „S“ s registry A, X, Y a P s oblastí zásobníku v paměti:

4.13 Volání a návrat podprogramu

Podprogram je soubor instrukcí, které dosahují určitého cíle. Předchozí program sčítání nebo odčítání je velmi krátký podprogram. Podprogramům se někdy říká jen rutiny. Instrukce pro volání podprogramu je:

JSR : Přejít na SubRoutine

Instrukce pro návrat z podprogramu je:

RTS: Návrat z podprogramu

Mikroprocesor má tendenci nepřetržitě provádět instrukce v paměti, jednu po druhé. Předpokládejme, že mikroprocesor právě provádí segment kódu a narazí na instrukci skoku (JMP), aby přešel a provedl segment kódu, který je zakódován za tím, že by již mohl být vykonán. Spustí tento segment kódu za a pokračuje ve vykonávání všech segmentů kódu (instrukcí) následujících za segmentem kódu, dokud znovu nespustí aktuální segment kódu a pokračuje níže. JMP neposílá další instrukci do zásobníku.

Na rozdíl od JMP, JSR tlačí adresu další instrukce po sobě z PC (programového čítače) do zásobníku. Pozice zásobníku této adresy je umístěna v ukazateli zásobníku „S“. Když je v podprogramu nalezena (provedena) instrukce RTS, adresa, která je vložena do zásobníku, stáhne zásobník a program pokračuje na této stažené adrese, která je další adresou instrukce těsně před voláním podprogramu. Poslední adresa, která je odstraněna ze zásobníku, je odeslána do programového čítače. V následující tabulce jsou uvedeny technické podrobnosti pokynů JSR a RTS:

Viz následující obrázek pro použití JSR a RTS:

4.14 Příklad odpočítávací smyčky

Následující podprogram odpočítává od $FF do $00 (celkem 256 10 počítá):

spustit LDX #$FF ; zatížení X s $FF = 255
smyčka DEX ; X = X – 1
BNE smyčka ; pokud X není nula, pak goto loop
RTS; vrátit se

Každý řádek má komentář. Komentáře se nikdy nedostanou do paměti k provedení. Assembler (překladač), který převádí program na to, co je v paměti pro spuštění (spuštění), vždy odstraní komentáře. Komentář začíná „;“ . „Start“ a „smyčka“ v tomto programu se nazývají štítky. Štítek identifikuje (jméno) adresy instrukce. Pokud je instrukce jednobajtová instrukce (implicitní adresování), návěští je adresa této instrukce. Pokud je instrukce vícebajtová instrukce, návěští identifikuje první bajt pro vícebajtovou instrukci. První instrukce pro tento program se skládá ze dvou bajtů. Za předpokladu, že začíná na adrese 0300 USD, lze adresu 0300 USD v programu nahradit výrazem „start“. Druhá instrukce (DEX) je jednobajtová instrukce a měla by být na adrese $0302. To znamená, že adresa $0302 může být nahrazena „loop“ dole v programu, což je ve skutečnosti tak v „BNE loop“.

„Smyčka BNE“ znamená větev na danou adresu, když je příznak Z stavového registru 0. Když je hodnota v registru A nebo X nebo Y 00000000 2 , kvůli poslední operaci je příznak Z 1 (set). Takže zatímco je 0 (ne 1), druhá a třetí instrukce v programu se opakují v tomto pořadí. V každé opakované sekvenci se hodnota (celé číslo) v registru X sníží o 1. DEX znamená X = X – 1. Když je hodnota v registru X $00 = 00000000 2 , Z se změní na 1. V tomto bodě se již tyto dvě instrukce neopakují. Poslední instrukce RTS v programu, což je jednobajtová instrukce (implicitní adresování), se vrací z podprogramu. Účinek této instrukce je vytvořit adresu programového čítače v zásobníku pro kód, který se má provést před voláním podprogramu, a vrátit se zpět do programového čítače (PC). Tato adresa je adresa instrukce, která má být provedena před voláním podprogramu.

Poznámka: Při psaní programu v assembleru pro 6502 µP musí na začátku řádku začínat pouze štítek; jakýkoli jiný řádkový kód musí být posunut alespoň o jednu mezeru doprava.

Volání podprogramu
Ignoruje-li se paměťový prostor, který zabírají předchozí štítky, program zabere 6 bajtů po sobě jdoucích míst v paměti (RAM) od $0300 do $0305. V tomto případě je program:

LDX #$FF ; zatížení X s $FF = 255
DEX; X = X – 1
BNE 0302 $; pokud X není nula, pak goto loop
RTS; vrátit se

Počínaje adresou $0200 v paměti může být voláním podprogramu. Pokyn k volání je:

JSR start ; začátek je adresa 0300 $, tj. JSR 0300 $

Podprogram a jeho volání, které jsou správně zapsány v souboru textového editoru, jsou:

spustit LDX #$FF; zatížení X s $FF = 255
smyčka DEX ; X = X – 1

BNE smyčka ; pokud X není nula, pak goto loop
RTS; vrátit se

JSR start: Přejít na rutinu začínající na 0300 $

Nyní může být v jednom dlouhém programu mnoho podprogramů. Všechny nemohou mít název „start“. Měli by mít jiná jména. Ve skutečnosti žádný z nich nemusí mít jméno „start“. „Start“ se zde používá z výukových důvodů.

4.15 Překlad programu

Překlad programu nebo jeho sestavení znamená totéž. Zvažte následující program:

spustit LDX #$FF: načíst X s $FF = 255
smyčka DEX : X = X – 1
BNE smyčka: pokud X není nula, pak goto smyčka
RTS: návrat
JSR start: Přejít na rutinu začínající na 0300 $

Toto je program, který byl napsán dříve. Skládá se z podprogramu, startu a volání podprogramu. Program odpočítává od 255 10 na 0 10 . Program začíná na uživatelské počáteční adrese 0200 $ (RAM). Program se napíše v textovém editoru a uloží se na disk. Má název jako „sample.asm“, kde „sample“ je název podle volby programátora, ale přípona „.asm“ pro jazyk assembleru musí být spojena s názvem souboru.

Sestavený program vytváří jiný program, který se nazývá assembler. Kompletátor dodává výrobce 6502 µP nebo třetí strana. Assembler reprodukuje program tak, že je při provádění (běhu) v paměti (RAM).

Předpokládejme, že instrukce JSR začíná na adrese $0200 a podprogram začíná na adrese $0300. Assembler odstraní všechny komentáře a bílá místa. Komentáře a bílá místa plýtvají pamětí, která je vždy vzácná. Případný prázdný řádek mezi předchozím segmentem kódu podprogramu a voláním podprogramu je příkladem mezery. Sestavený soubor je stále uložen na disku a jmenuje se něco jako „sample.exe“. „Ukázka“ je název podle volby programátora, ale měla by tam být přípona „.exe“, která označuje, že se jedná o spustitelný soubor.

Sestavený program lze dokumentovat následovně:

Vyrobit takový dokument je prý ruční skládání. Všimněte si, že komentáře v tomto dokumentu se nezobrazují v paměti (pro spuštění). Sloupec adres v tabulce udává počáteční adresy instrukcí v paměti. Všimněte si, že „JSR start“, což je „JSR $0300“, u kterého se očekává, že bude kódováno jako „20 03 00“, je ve skutečnosti zakódováno jako „20 00 03“, přičemž adresa dolního bajtu paměti přebírá spodní bajt v paměti a adresa vyššího bajtu paměti zabírá vyšší bajt v paměti – malá endianness. Operační kód pro JSR je 20 16 .

Všimněte si, že offset k instrukci větve, jako je BNE, je číslo dvojkového doplňku v rozsahu 128 10 na + 127 10 . Takže „smyčka BNE“ znamená „BNE -1 10 ” což je ve skutečnosti „D0 FF“ v kódové podobě FF 16 je -1 ve dvojkovém doplňku, který je zapsán jako = 11111111 v základu dva. Program assembler nahradí popisky a pole skutečnými hexadecimálními čísly (hexadecimální čísla jsou binární čísla, která jsou seskupena do čtyř bitů). Skutečné adresy, kde každá instrukce začíná, jsou skutečně zahrnuty.

Poznámka: Instrukce „JSR start“ je nahrazena kratšími instrukcemi, které odesílají aktuální obsah (vysoké a nízké bajty) programového čítače do zásobníku s ukazatelem zásobníku, který je dvakrát dekrementován (jednou pro vysoký bajt a jednou pro nízký bajt) a poté znovu načte PC s adresou $0300. Ukazatel zásobníku nyní ukazuje na $00FD, za předpokladu, že je inicializován na $01FF.

Také instrukce RTS je nahrazena řadou kratších instrukcí, které dvakrát zvýší ukazatel zásobníku „S“ (jednou pro nízký bajt a jednou pro vysoký bajt) a vytáhnou odpovídající dva bajty adresy z ukazatele zásobníku do počítače. další pokyn.

Poznámka: Text štítku by neměl mít více než 8 znaků.

„Smyčka BNE“ používá relativní adresování. To znamená přidat -3 10 na obsah počítadla dalšího programu 0305 $. Bajty pro „smyčku BNE“ jsou „D0 FD“, kde FD je dvojkový doplněk -3 10 .

Poznámka: Tato kapitola neuvádí všechny pokyny pro 6502 µP. Všechny pokyny a jejich podrobnosti lze nalézt v dokumentu nazvaném “SY6500 8-Bit Microprocessor Family”. Pro tento dokument existuje soubor PDF s názvem „6502.pdf“, který je volně dostupný na internetu. 6502 µP, která je popsána v tomto dokumentu, je 65C02.

4.16 Přerušení

Signály jakéhokoli zařízení, které je připojeno k externím (vertikálním povrchovým) portům Commodore 64, musí před dosažením mikroprocesoru 6502 projít buď obvody CIA 1 nebo CIA 2 (IC). Signály z datové sběrnice 6502 µP musí projít buď čipem CIA 1 nebo CIA 2, než se dostanou k jakémukoli externímu zařízení. CIA je zkratka pro Complex Interface Adapter. Na obr. 4.1 „Blokové schéma základní desky Commodore_64“ představují bloková vstupní/výstupní zařízení CIA 1 a CIA 2. Když je program spuštěn, může být přerušen, aby se spustil nějaký jiný kód, než bude pokračovat. Dochází k přerušení hardwaru a přerušení softwaru. Pro hardwarové přerušení jsou k dispozici dva piny vstupního signálu na 6502 µP. Názvy těchto kolíků jsou IRQ a NMI . Toto nejsou datové linky µP. Datové řádky pro uP jsou D7, D6, D5, D4, D3, D2, D1 a DO; s D0 pro nejméně významný bit a D7 pro nejvýznamnější bit.

IRQ znamená Interrupt ReQuest „active“ low. Toto vstupní vedení k µP je normálně vysoké, přibližně 5 voltů. Když klesne na přibližně 0 voltů, jedná se o požadavek na přerušení, který signalizuje µP. Jakmile je žádost schválena, linka se vrátí vysoko. Udělení požadavku na přerušení znamená, že se µP větví na kód (podprogram), který přerušení zpracovává.

NMI znamená Non-Maskable Interrupt „active“ low. Zatímco kód pro IRQ se provádí NMI může jít nízko. V tomto případě, NMI je zpracován (je spuštěn jeho vlastní kód). Poté kód pro IRQ pokračuje. Po kódu pro IRQ skončí, pokračuje hlavní programový kód. to znamená, NMI přeruší IRQ psovod. Signál pro NMI může být stále dán µP, i když je µP nečinný a nic nezpracovává nebo neběží hlavní program.

Poznámka: Je to vlastně přechod z vysokého k nízkému NMI , toto je NMI signál – o tom později. IRQ obvykle pochází ze CIA 1 a NMI obvykle pochází ze CIA 2. NMI , což je zkratka pro Non-Maskable Interrupt, lze považovat za nezastavitelné přerušení.

Manipulace s přerušeními
Zda je požadavek od IRQ nebo NMI , musí být dokončen aktuální pokyn. 6502 má pouze registry A, X a Y. Zatímco podprogram pracuje, může používat tyto tři registry společně. Obsluha přerušení je stále podprogramem, i když tak není vnímán. Po dokončení aktuální instrukce se obsah registrů A, X a Y pro 65C02 µP uloží do zásobníku. Do zásobníku je také odeslána adresa další instrukce programového čítače. µP se pak větví na kód přerušení. Poté se obsah registrů A, X a Y obnoví ze zásobníku v opačném pořadí, v jakém byly odeslány.

Příklad kódování přerušení
Pro jednoduchost předpokládejme, že rutina pro µP IRQ přerušení je pouze sečíst čísla $01 a $02 a uložit výsledek $03 na paměťovou adresu $0400. Kód je:

ISR PHA
PHX
PHY
;
LDA # 01 $
ADC # 02 $
STOJÍ 0400 $
;
VRSTVA
PLX
CHKO
RTI

ISR je štítek a identifikuje adresu paměti, kde je instrukce PHA. ISR znamená rutina přerušení služby. PHA, PHX a PHY posílají obsah registrů A, X a Y do zásobníku s nadějí, že je bude potřebovat jakýkoli kód (program), který běží těsně před přerušením. Další tři instrukce tvoří jádro obsluhy přerušení. Instrukce PLY, PLX a PLA musí být v tomto pořadí a přinášejí zpět obsah registrů Y, X a A. Poslední instrukce, kterou je RTI, (bez operandu) vrací pokračování provádění libovolného kódu (programu), který se provádí před přerušením. RTI vytáhne adresu další instrukce kódu, který se provádí, ze zásobníku zpět do programového čítače. RTI znamená Návrat z přerušení. Tím je zpracování přerušení (podprogram) u konce.

Softwarové přerušení
Hlavním způsobem softwarového přerušení pro 6502 µP je použití implikované adresy BRK. Předpokládejme, že hlavní program běží a narazí na instrukci BRK. Od tohoto bodu by měla být adresa další instrukce v PC odeslána do zásobníku, jakmile je aktuální instrukce dokončena. Podprogram pro zpracování softwarové instrukce by se měl nazývat „next“. Tento podprogram přerušení by měl přesunout obsah registrů A, X a Y do zásobníku. Po provedení jádra podprogramu by se měl obsah registrů A, X a Y stáhnout zpět ze zásobníku do jejich registrů dokončovacím podprogramem. Poslední příkaz v rutině je RTI. Obsah PC je také automaticky stažen zpět ze zásobníku do PC kvůli RTI.

Porovnání a kontrast podprogramu a servisního programu přerušení
Následující tabulka porovnává a porovnává podprogram a rutinu služby přerušení:

4.17 Souhrn hlavních režimů adresování 6502

Každá instrukce pro 6502 je jeden bajt, po kterém následuje nula nebo více operandů.

Režim okamžitého adresování
V režimu okamžitého adresování je za operandem hodnota a ne adresa paměti. Hodnotě musí předcházet #. Pokud je hodnota v šestnáctkové soustavě, za „#“ musí následovat „$“. Okamžité adresovací instrukce pro 65C02 jsou: ADC, AND, BIT, CMP, CPX, CPY, EOR, LDA, LDX, LDY, ORA, SBC. Čtenář by si měl prostudovat dokumentaci k 65C02 µP, aby věděl, jak používat zde uvedené pokyny, které nejsou vysvětleny v této kapitole. Příklad instrukce je:

LDA # 77 $

Režim absolutního adresování
V režimu absolutního adresování existuje jeden operand. Tento operand je adresa hodnoty v paměti (obvykle v hexadecimální soustavě nebo návěští). Je jich 64tis 10 = 65 536 10 adresy paměti pro 6502 µP. Typicky je jednobajtová hodnota na jedné z těchto adres. Absolutní adresovací instrukce pro 65C02 jsou: ADC, AND, ASL, BIT, CMP, CPX, CPY, DEC, EOR, INC, JMP, JSR, LDA, LDX, LDY, LSR, ORA, ROL, ROR, SBC, STA , STX, STY, STZ, TRB, TSB. Čtenář by se měl seznámit s dokumentací pro 65C02 µP, aby věděl, jak používat zde uvedené pokyny, stejně jako pro ostatní režimy adresování, které nejsou vysvětleny v této kapitole. Příklad instrukce je:

JSOU 1234 $

Implicitní režim adresování
V režimu implicitního adresování neexistuje žádný operand. Jakýkoli zahrnutý registr µP je zahrnut instrukcí. Předpokládané adresovací instrukce pro 65C02 jsou: BRK, CLC, CLD, CLI, CLV, DEX, DEY, INX, INY, NOP, PHA, PHP, PHX, PHY, PLA, PLP, PLX, PLY, RTI, RTS, SEC , SED, SEI, TAX, TAY, TSX, TXA, TXS, TYA. Příklad instrukce je:

DEX : Snížení registru X o jednu jednotku.

Režim relativního adresování
Režim relativního adresování se zabývá pouze instrukcemi větvení. V režimu relativního adresování existuje pouze jeden operand. Je to hodnota od -128 10 na +127 10 . Tato hodnota se nazývá offset. Na základě znaménka je tato hodnota přičtena nebo odečtena od další instrukce programového čítače a výsledkem je adresa zamýšlené další instrukce. Instrukce režimu relativní adresy jsou: BCC, BCS, BEQ, BMI, BNE, BPL, BRA, BVC, BVS. Příklady instrukcí jsou:

BNE $7F : (větev, pokud Z = 0 ve stavovém registru, P)

Což přidá 127 k aktuálnímu čítači programu (adresa, která se má provést) a spustí se provádění instrukce na této adrese. Podobně:

BEQ $F9 : (větev, pokud Z = : ve stavovém registru, P)

Což přidá -7 k aktuálnímu programovému čítači a spustí provádění na nové adrese programového čítače. Operand je číslo s dvojkovým doplňkem.

Absolutní indexované adresování
Při adresování absolutního indexu je obsah registru X nebo Y přidán k dané absolutní adrese (kdekoli od $ 0000 do $ FFFF, tj. 10 na 65536 10 ), abyste měli skutečnou adresu. Tato daná absolutní adresa se nazývá základní adresa. Pokud je použit registr X, instrukce pro sestavení je něco takového:

LDA $ C453,X

Pokud je použit registr Y, je to něco jako:

LDA $ C453, Y

Hodnota registru X nebo Y se nazývá hodnota počtu nebo indexu a může být kdekoli od 00 $ (0 10 ) na $FF (250 10 ). Neříká se tomu offset.

Instrukce pro adresování absolutního indexu jsou: ADC, AND, ASL (pouze X), BIT (s akumulátorem a pamětí, pouze s X), CMP, DEC (pouze paměť a X), EOR, INC (pouze paměť a X), LDA , LDX, LDY, LSR (pouze X), ORA, ROL (pouze X), ROR (pouze X), SBC, STA, STZ (pouze X).

Absolutní nepřímé adresování
Toto se používá pouze s instrukcí skoku. Díky tomu má daná absolutní adresa adresu ukazatele. Adresa ukazatele se skládá ze dvou bajtů. Dvoubajtový ukazatel ukazuje (je adresou) cílové hodnoty bajtu v paměti. Instrukce v jazyce symbolických instrukcí tedy zní:

JMP (3 456 USD)

Se závorkami a $13 je v umístění adresy $3456, zatímco $EB je v umístění adresy $3457 (= $3456 + 1). Potom je cílová adresa $13EB a $13EB je ukazatel. Absolutních $3456 je v instrukci v závorkách, kde 34 je nižší bajt a 56 je vyšší bajt.

4.18 Vytvoření řetězce pomocí assembleru 6502 µP

Jak je ukázáno v další kapitole, po vytvoření souboru v paměti lze soubor uložit na disk. Soubor je třeba pojmenovat. Název je příkladem řetězce. Existuje mnoho dalších příkladů řetězců v programování.

Existují dva hlavní způsoby vytvoření řetězce ASCII kódů. V obou případech všechny ASCII kódy (znaky) zaujímají v paměti po sobě jdoucí bajtová umístění. V jednom ze způsobů této sekvenci bajtů předchází celočíselný bajt, což je délka (počet znaků) v sekvenci (řetězci). V opačném případě je sekvence znaků následována (bezprostředně následována) bajtem Null, který je 00 16 , tj. 00 USD. Délka řetězce (počet znaků) se tímto jiným způsobem neuvádí. Znak Null se nepoužívá prvním způsobem.

Zvažte například „Miluji tě!“ řetězec bez uvozovek. Délka je zde 11; mezera se počítá jako jeden ASCII bajt (znak). Předpokládejme, že řetězec musí být umístěn v paměti s prvním znakem na adrese $0300.

Následující tabulka ukazuje nastavení paměti řetězce, když je první bajt 11 10 = 0B 16 :

Následující tabulka ukazuje nastavení paměti řetězce, když je první bajt „I“ a poslední bajt je Null (00 $):

Následující instrukce lze použít k zahájení vytváření řetězce:

STOJÍ 0300 $

Předpokládejme, že první bajt je v akumulátoru, který má být odeslán na adresu 0300 $. Tato instrukce platí pro oba případy (oba typy řetězců).

Po vložení všech znaků do paměťových buněk jeden po druhém lze řetězec číst pomocí smyčky. V prvním případě se načte počet znaků po délce. Ve druhém případě se znaky čtou od „I“, dokud není splněn znak Null, který je „Null“.

4.19 Vytvoření pole pomocí jazyka assembleru 6502 µP

Pole jednobajtových celých čísel se skládá z po sobě jdoucích umístění bajtů paměti s celými čísly. Potom je zde ukazatel, který ukazuje na umístění prvního celého čísla. Pole celých čísel se tedy skládá ze dvou částí: ukazatele a řady umístění.

Pro pole řetězců může být každý řetězec na jiném místě v paměti. Potom existují po sobě jdoucí paměťová umístění s ukazateli, kde každý ukazatel ukazuje na první umístění každého řetězce. Ukazatel se v tomto případě skládá ze dvou bajtů. Pokud řetězec začíná svou délkou, odpovídající ukazatel ukazuje na umístění této délky. Pokud řetězec nezačíná svou délkou, ale končí znakem null, odpovídající ukazatel ukazuje na umístění prvního znaku řetězce. A existuje ukazatel, který ukazuje na nižší byte adresu prvního ukazatele po sobě jdoucích ukazatelů. Pole řetězců se tedy skládá ze tří částí: řetězců na různých místech v paměti, odpovídajících po sobě jdoucích ukazatelů a ukazatele na první ukazatel z po sobě jdoucích ukazatelů.

4.20 Problémy

Čtenáři se doporučuje vyřešit všechny problémy v kapitole, než přejde k další kapitole.

  1. Napište program v assembleru, který začíná na 0200 $ za 6502 µP a přidá čísla bez znaménka 2A94 H (přidat) k 2ABF H (augend). Nechť jsou vstupy a výstupy v paměti. Vytvořte také sestavený programový dokument ručně.
  2. Napište program v assembleru, který začíná na 0200 $ pro 6502 µP a odečte čísla bez znaménka 1569 H (subtrahend) od 2ABF H (minuend). Vstupy a výstupy nechť jsou v paměti. Vytvořte také sestavený programový dokument ručně.
  3. Napište program v assembleru pro 6502 µP, který počítá od 00 $ do 09 $ pomocí smyčky. Program by měl začínat na 0200 dolarech. Vytvořte také sestavený programový dokument ručně.
  4. Napište program v assembleru, který začíná na 0200 $ za 6502 µP. Program má dva podprogramy. První podprogram přidává čísla 0203 bez znaménka H (augend) a 0102H (add). Druhý podprogram přidá součet z prvního podprogramu, který je 0305H až 0006 H (augend). Konečný výsledek se uloží do paměti. Zavolejte první podprogram, který je FSTSUB a druhý podprogram, který je SECSUB. Vstupy a výstupy nechť jsou v paměti. Vytvořte také sestavený programový dokument pro celý program ručně.
  5. Vzhledem k tomu, že an IRQ handler přidá 02 $ až 01 $ na akumulátoru jako základní manipulaci NMI je vydáno a jádro manipulace pro NMI přidá 05 $ až 04 $ na akumulátoru, napište assembler pro oba handlery včetně jejich volání. Výzva k IRQ handler by měl být na adrese $0200. The IRQ handler by měl začínat na adrese 0300 $. The NMI handler by měl začínat na adrese $0400. Výsledek IRQ handler by měl být umístěn na adresu $0500 a výsledek NMI handler by měl být umístěn na adresu $0501.
  6. Stručně vysvětlete, jak se instrukce BRK používá k vytvoření softwarového přerušení v počítači 65C02.
  7. Vytvořte tabulku, která porovnává a kontrastuje normální podprogram s obslužnou rutinou přerušení.
  8. Stručně vysvětlete hlavní režimy adresování 65C02 µP na příkladech instrukcí v jazyce symbolických instrukcí.
  9. a) Napište program ve strojovém jazyce 6502, do kterého vložíte „Miluji tě!“ řetězec ASCII kódů v paměti, počínaje adresou $0300 s délkou řetězce. Program by měl začínat na adrese 0200 $. Získejte každý znak z akumulátoru jeden po druhém, za předpokladu, že jsou tam odeslány nějakým podprogramem. Program také sestavte ručně. (Pokud potřebujete znát ASCII kódy pro „Miluji tě!“. Zde jsou: „Já“:49 16 , prostor: 20 16 , „l“: 6C 16 , „o“: 6F 16 , ‘v’:76 16 , 'e':65, 'y':79 16 , 'v':75 16 a ‚!‘:21 16 (Poznámka: každý kód zabírá 1 bajt).
    b) Napište program ve strojovém jazyce 6502, do kterého vložíte „Miluji tě!“ řetězec ASCII kódů v paměti, začínající od adresy $0300 bez délky řetězce, ale končící 00 16 . Program by měl začínat na adrese 0200 $. Získejte každý znak z akumulátoru za předpokladu, že je tam posílá jeden po druhém nějakým podprogramem. Program také sestavte ručně.