Problémy a jejich řešení
1) Napište program v assembleru, který začíná na 0200 $ pro 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ě.
Řešení:
CLC
LDA 0213 USD
ADC 0215 $
STA $ 0217
LDA 0214 USD
ADC 0216 $
STA $ 0218
Sestavený program:
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). Nechť jsou vstupy a výstupy v paměti. Vytvořte také sestavený programový dokument ručně.
Řešení:
SEC
LDA 0213 USD
0215 SBC
STA $ 0217
LDA 0214 USD
0216 SBC
STA $ 0218
Sestavený program:
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ě.
Řešení:
LDA # 09 $
STA $ 0220; pro srovnání X a $09
LDX # 00 $
smyčka INX
CPX 0220 USD
BNE smyčka
Sestavený program:
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 0102 H (přidat). Druhý podprogram přidá součet z prvního podprogramu, který je 0305 H do 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ě.
Řešení:
SECSUB CLC
LDA $ 021A
ADC 0234 $
STA $ 0236
LDA 021 miliard USD
ADC 0235 $
STA $ 0237
RTS
FSTSUB CLC
LDA 0216 USD
ADC 0218 $
STA $ 021A
LDA 0217 USD
ADC 0219 $
STA 021 miliard dolarů
RTS
JSR FSTSUB
Sestavený program:
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 základní 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.
Řešení:
NMISR PHA; Rutina NMI začíná zde na adrese 0400 $
PHX
PHY
;
LDA # 04 $
ADC # 05 $
STA $ 0501
;
VRSTVA
PLX
CHKO
RTI
ISR PHA; tato instrukce je na adrese 0300 $
PHX
PHY
;
LDA # 01 $
ADC # 02 $
; JMP NMISR : komentováno, protože to není součástí rutiny
STA $ 0500; půjde do zásobníku
;
VRSTVA
PLX
CHKO
RTI
;
JMP ISR ; tato instrukce je na adrese $0200
6) Stručně vysvětlete, jak se instrukce BRK používá k vytvoření softwarového přerušení v počítači 65C02.
Řešení:
Hlavním způsobem softwarového přerušení pro 65C02 µP je použití instrukce BRK implikované adresy. Předpokládejme, že hlavní program běží a narazí na instrukci BRK. Od tohoto okamžiku by měla být adresa další instrukce v PC odeslána do zásobníku, jakmile bude aktuální instrukce dokončena. Dále by měl být vyvolán podprogram pro zpracování softwarové instrukce. 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.
7) Vytvořte tabulku, která porovnává a kontrastuje normální podprogram s obslužnou rutinou přerušení.
Řešení:
8) Stručně vysvětlete hlavní režimy adresování 65C02 µP na příkladech instrukcí v jazyce symbolických instrukcí.
Řešení:
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 hexadecimální soustavě, pak „#“ musí být následováno „$“. 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é nebyly 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í). Existuje 64K10 = 65 53610 adres 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 si měl prostudovat dokumentaci pro 65C02 µP, aby věděl, jak používat instrukce, které jsou zde uvedeny, stejně jako pro ostatní režimy adresování, které nebyly vysvětleny v této kapitole. Příklad instrukce je:
JSOU 1234 $
Implicitní režim adresování
S předpokládaným režimem 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 -12810 do +12710. Tato hodnota se nazývá offset. Na základě znaménka se tato hodnota přičte nebo odečte od další instrukce programového čítače k výsledku v adrese 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)
který přidá 127 k aktuálnímu programovému čítači (adrese, která se má provést) a spustí provádění instrukce na této adrese. Podobně:
BEQ $F9 : (větev, pokud Z = : ve stavovém registru, P)
který 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í indexové 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. od 010 do 6553610), aby měl 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 se použije registr Y, bude to něco takového:
LDA $ C453, Y
Hodnota pro registr X nebo Y se nazývá hodnota počtu nebo indexu a může být kdekoli od $ 00 (010) do $ FF (25010). 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í jsou tedy následující:
JMP (3 456 USD)
Se závorkami a $13 v $3456 adrese, zatímco $EB je v $3457 (= $3456 + 1) adrese, cílová adresa je $13EB a $13EB je ukazatel. Absolutních 3456 $ je v pokynu uvedeno v závorkách.
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 za předpokladu, že je tam jeden po druhém posílá nějaký podprogram. Program také sestavte ručně. (Pokud potřebujete znát ASCII kódy pro „Miluji tě!“, zde jsou: 'I':4916, mezera: 2016, 'l': 6C16, 'o':6F16, 'v':7616, ' e':65, 'y':7916, 'u':7516 a '!':2116. 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í na 0016. Program by měl začínat na adrese $0200. Získejte každý znak z akumulátoru za předpokladu, že je tam jeden po druhém posílá nějaký podprogram. Program také sestavte ručně.
Řešení:
a) Strategie: Řetězec má 12 bajtů: 1 bajt pro délku řetězce a 11 bajtů pro řetězcový literál. Musí tedy existovat 12 iterací (smyček) počítajících od 0. To znamená: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11. Toto je 12 čísel.
Celé číslo 0 se vloží do registru X a číslo 1110 = 1210 – 110 = B16 = $0B se vloží na adresové místo v paměti, řekněme adresa $0250. Pro každou iteraci se hodnota v registru X zvýší a výsledek se porovná s $0B v umístění adresy $0250. Jakmile je hodnota v X rovna hodnotě $0B, iterace se zastaví. V tomto okamžiku délka (počet bajtů) řetězce a řetězcový literál zabírají místa adresy $0300 až $030B (včetně). Aby bylo možné inkrementovat adresy paměti od $0300, používá se registr Y. Kód je:
LDA # 0 miliard $
JSOU 0250 $
LDX # 00 $
LDY # 00 $
STA $ 0300; délka 11 je vložena do A nějakým podprogramem a jde na 0300 $
smyčka INX
TAM
CPY 0250 $
smyčka BEQ
b) Strategie: Řetězec má 12 bajtů: 1 bajt pro terminátor $00 Null a 11 bajtů pro řetězcový literál. Musí tedy existovat 12 iterací (smyček) počítajících od 0. To znamená: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11. Toto je 12 čísel.
Celé číslo 0 se vloží do registru X a číslo 1110 = 1210 – 110 = B16 = $0B se vloží na adresové místo v paměti, řekněme adresa $0250. Pro každou iteraci se hodnota v registru X zvýší a výsledek se porovná s $0B v umístění adresy $0250. Jakmile je hodnota v X rovna hodnotě $0B, iterace se zastaví. V tomto okamžiku počet bajtů řetězcového literálu plus znak Null zabírá místa adresy $0300 až $030B (včetně). Pro zvýšení adres paměti z $0300 se používá registr Y. Kód je:
LDA # 0 miliard $
JSOU 0250 $
LDX # 00 $
LDY # 00 $
STA $ 0300; 'I' je vloženo do A pomocí nějakého podprogramu a jde na 0300 $
smyčka INX
TAM
CPY 0250 $
smyčka BEQ