REGISTERLERİ YIĞINLARA DEPOLAMA

REGISTERLERİ YIĞINLARA DEPOLAMA (Storing registers on the stack) Bildiğiniz gibi Commodore 64 makine kodu ile çalışırken 3 adet register olduğundan kısıtlıyız. Mutlaka 'bunları hafızaya depolarız transfer' diye düşünüyorsunuzdur. Bazı durumlarda bunlar da yeterli olmayabilir.

Bunun altından registerleri yığınlara depolayarak kalkarız. Bu bölümde registerlerin yığınlara nasıl depolandığını ve nasıl geri alındığını göreceğiz..

PHA, A registerini yığın üzerine bastır. A registerini yığın üzerine bastırdığın zaman değeri Stack Pointer (SP) tarafından gösterilen bölgeye (adrese) depolanır ve SP azaltılır, ki bundan sonraki boş byte'ı gösterirsin. Örnek: Eğer SP= $89 ise ve A registerini yığına bastırdığında A registerinin değeri $0189 bölgesine transfer edilecek SP $88'e inecektir.

PLA, A registerini yığından çek (Pull the A register from the stack). A registerini yığına bastırdıktan sonra bu komutu yığın üzerindeki A'ya geçirmek için kullanıyorsun. Misal olarak, eğer SP= $92 ise ve PLA komutunu kullanıyorsan, A registeri $0193 bölgesindeki değerle yüklenecektir. SP= $93 olacaktır.

İşte A registerini yığına yükleyen ve tekrar yığından
geri alan bir örnek:
LDA # $ 30
Co02 PHA
CO03 LDA # $ 00
5 STA $ DO20
Co08 PLA
Co09 RTS

PHP ve PLP PHP, P registerini stack'a (yığına) bastır (Push the P register onto the stack) demektir. PHP, PHA komutunda olduğu gibi işlev görür. PLP, PLA komutunda olduğu gibi işlev görür (Pull

Dr. Ali Özçelik

the P register from the stack) demektir.
İşte P registerini yığına yükleyen ve geri alan örnek
bir program:
Co00 LDA # $ 00
Co02 PHP
CO03 LDA # $ 80
CO0O5 STA $ 028A
Co08 PLP
Co09 RTS

TXS ve TSX TSX, yığın göstergecini X registerine transfer et (Transfer the Stack pointer to X register) demektir. TXS, X registerini yığın göstergecine transfer et (Transfer the X register to the Stack pointer) anlamına gelmektedir. Her ikisi de yığın göstergecinin ne olup olmadığını anlamak için kullanılır.

NOT — Yığınlara numaraları basarken bunları geri almayı unutma. Eğer yığından değerleri almazsan RTS komutuna geldiği zaman sistem donabilir (crash). — Yığından çekilen numaralar konuluş sırasının tersine çekilir (son giren ilk çıkar). Örnek olarak, yığına konan numaralar 1,2,3,4,5 ve 6 ise, bunlar alınırken aşağıdaki sıra ile alınacaktır: 6,5,4,3,2,1 (son giren ilk çıkar, last in-first out). İşte size diğer bölüme geçmeden önce düşündürücü bir problem: Bütün registerleri yığına transfer et ve geri al. $C000 PHP PHA $C002 TXA $C003 PHA $C004 TYA $C005 PHA

CO00 PLA
TAY
C002 PLA
TAX
CO04 PLA
Co05 PLP

Birinci program tüm registerleri yığına yükler ve ikinci program ise onları geri alır. Yukarıdaki programı yazmak değil, anlamak önemlidir.

TOPLAMA VE ÇIKARTMA Bu bölümde 6510 (C64'ün microprocessor)nun matematik fonksiyonları ile ilgilidir. 6510 sadece çıkartma ve toplama yapabilir, ve bunlar A registeri kullanarak yapılır. Bu nedenle A registeri akümülatör (accumulator) diye adlandırılır.

ADC (Add to Accumulator with Carry) A registerine Carry ile ilave et. Şu ana kadar bütün adresleme modlarını öğrenmiş olmanız gerekiyor. Bundan sonra adresleme modlarını izah etmeyeceğim.

ADC komutu, değerin Carry flag ile A registerine ilave edilmesini sağlar. Örnek olarak eğer Carry flag 'set' ve A registerinde $40 değeri varsa ve ADC #$03 komutu kullanılırsa, A registerinin değeri $44 olacaktır. Çünkü kompüter $03 ile $40'ı toplayarak $43'ü elde edecek sonra Carry Flag ilave edilerek neticede $44 bulunacaktır. Eğer Carry Flag “Set” değilse (reset) A registerinin değeri $43 olacaktır. Toplamadan önce CLC (Clear the Carry) komutu kullanırsak $01 değeri eklenecektir.

İşte 02 ile 02 yi toplayan örnek program:
Co00 LDA # $ 02
C002 CLC
C0O03 ADC # $ 02
Co0O5 RTS

Yukarıdaki programda netice şüphesiz $04 olacaktır. İşte yine $02 ile $02'yi toplayan bir başka program, fakat aynı zamanda Carry flag 'set'tir: $C000 LDA #$02 $C002 SEC $C003 ADC #$02 $C005 RTS

Sonuç $05'tir, çünkü Carry flag set ($01). Eğer Carry flag clear olsaydı ve siz $06 ile $04'ü toplamış olsaydınız alacağınız cevap $0A olacaktır.

Bazen bu tür toplama yapmak işimize gelmeyebilir. Desimal sonuçları tercih edebiliriz. Desimal toplama, desimal flag'ı set etme yoluyla yapılabilir. SED (Set Decimal flag) komutu kullanılır. Desimal flag set ve toplama $07 + $05 = $12 şeklinde ($0C değilse) olacak. BASIC moduna dönmeden önce Decimal flag, clear'lanmalıdır.

Desimal toplamaya örnek:

Co00 SED
Co01 LDA # $ O7
CLC
C0O04 ADC # $ 06
Co06 CLD
COO7 RTS

Bu A registerinin değerini 13 olarak verecektir. Eğer Decimal flag önceden set edilmeseydi A, $0D değerine sahip olacaktı.

ADC ÜZERİNE NOTLAR — Normal durumlarda toplama 255'i geçerse Carry flag set olacaktır. — Toplamanın sonucu 0 ise Zero flag set olacak. — Toplama 80 ile FF arasında ise Negative flag set olacak. — Toplamanın sonucu 7F'yi aşarsa Overflow flag set olacak.

— BASIC moduna dönmeden önce Decimal flag'ı reset et, aksi taktirde kompüter crash olacaktır. — ADC aşağıdaki adresleme modlarında kullanılabilir.

IMMEDIATE (ADC #$ZZ) ZERO PAGE (ADC $ZZ) ZERO PAGE INDEXED (ADC $ZZ,X) ABSOLUTE (ADC $ZZZZ) ABSOLUTE INDEXED (ADC $ZZZZ,X) INDIRECT INDEXED (ADC ($ZZ),Y) Yukarıdaki ZZ iki digit rakam, ZZZZ 4 digit hex rakam demektir.

SBC (Subtract from a Register with Borrow) Registerden, borç hanesi ile beraber çıkarma. SBC komutu A registerinden çıkarma yapmak için kullanılır. Eğer Carry flag set değilse, A registerinden extra bir $01 alınır. Eğer Carry flag set ise, Carry flag çıkarma sırasında ihmal edilir.

İşte bir örnek. Dikkat et, ihmal edilmesi için Carry flag
set durumunda:
CO00 LDA # $ 40
C002 SEC
SBC # $ 20
Co05 RTS

A registerindeki sonuç $20, çünkü $40-$20 = $20'dir. Carry clear olsa idi A = $1F olacaktı, çünkü extradan $01 çıkarılmış olacaktır. $40-$20-$01 = $1F

SBC desimal modda da kullanılabilir. Decimal flag set ise, SBC komutu desimal çıkarma yapar. Örnek: Decimal flag set ise 20-01 = 19 olacak, 1F değil. Desimal çıkarmaya bir örnek:

CO00 LDA # $ 60
C002 SED
SEC
SBC # $ 15
Co06 CLD
COO7 RTS

Yukarıdaki program 60'dan 15'i çıkartır. Decimal ve Carry flag'lar set olduğundan sonuç A = 45 olacaktır.

SBC ÜZERİNE NOTLAR — Çıkarmanın sonucu Zero veya pozitif ise Carry flag set'tir. — Çıkarma sonucu 00 ise Zero flag set olacaktır. — Sonuç 00'dan az ise negatif flag set olacak, bu durumda A register'inin 7.ci bit'i de set olacaktır. — Çıkarma -80'den az ise Overflow flag set olacaktır. — SBC aşağıdaki adresleme modlarını kullanabilir:

TST

IMMEDIATE (SBC #$ZZ) ZERO PAGE (SBC $ZZ) ZERO PAGE INDEXED (SBC $ZZ,X)

ABSOLUTE (SBC $ZZZZ) ABSOLUTE INDEXED (SBC $ZZZZ,X veya SBC $ZZZZ,Y) INDEXED INDIRECT (SBC ($ZZ,X)) INDIRECT INDEXED (SBC ($ZZ),Y)

İşte size bu bölümü kavradığınızı anlamak için bir problem: X ve Y register'lerini toplayan ve bu toplamı da A register'ine ilave eden bir program yaz. Aşağıdaki komutları kullanabilirsiniz: PHA, PLA, CLC, RTS, TXA, TAX, STY $FE, STX $FE, ADC $FE. Bunlardan herbirini bir kereden fazla kullanabilirsiniz. Bu komutları kullanarak yapamıyorsan kendi istediğin komutları kullan. İşte cevap:

Co00 PHA
Co01i TXA
C002 STY $ FE
CO04 CLC
ADC $ FE
COO7 TAX
CO08 PLA
C009 STX $ FE
CO0OB CLC
| COOC ADC $ FE
| COOE RTS

Bu problemin tek cevabı değil, bundan başkada cevap bulunabilir.

MENDA