HAFIZADAN OKUNAN BİR BYTE’I HEX OLARAK EKRANA

YAZDIRMA RUTİNİ (1. YÖNTEM)

*=$0801
.word nextline
.word 2004
; 2004
.byte $9e
; SYS
.text "2061"
; 2061
.byte 0
; komutu
nextline
.word 0
mem_read
lda
adres
; adresteki değeri al
pha
; akünün değerini yığına at
lsr
; sağa kaydır
lsr
; sağa kaydır
lsr
; sağa kaydır
lsr
; sağa kaydır
jsr
convert
; byte çevirme var
pla
; yığındaki değeri geri al
and
#$0f
; alt 4 biti al
convert
cmp
#$0a
; okunan değer 10’dan
bcc
number
; küçükse rakam demekmiş.
clc
; büyükse harf demekmiş.
adc
#$07
; önce 7 ile topla
number
clc
; carry’i sıfırla
adc
#$30
; $30 (48) ile topla
print
jsr
$ffd2
; ekrana yazdır.
rts
; Bu iş burada biter.
adres
.byte 179
; Örnek sayı

Şimdi açıklama yapalım. Hex sistemde kullanılan karakterler 0-9 ve A-F arasındadır. Dolayısıyla bunların ASCII değerleri rakamlar için $30-$39 (48-57), harfler için $41-$46 (65-70) arasındadır. Hafızadan okunan bir değeri hex olarak ekrana yazdırmak demek ekrana iki karakter basmak demektir. Önce aküyü kullanarak hafızayı okuyoruz ve aynı değeri tekrar kullanabilmek için yığına atıyoruz. Sonra 4 defa LSR komutuyla 7-6-5-4 nolu bitleri 3-2-1-0 nolu bitlerin yerine taşıyoruz. Bunu yapmak zorundayız. Eğer yapmazsak ekrana istemediğimiz karakterler çıkabilir veya başka işler olabilir. Mesela ekran silinebilir. Devam ediyoruz. 4 LSR komutundan sonra JSR komutu ile çevirme işlemi alt rutinine gidiyoruz. Burada aslında alt rutin yok. Program tek parça ve bir kısmını alt rutinmiş gibi kullanıyoruz. Yani program kendi kendini çağırıyor.

Şimdi çevirme yapmaya başlayabiliriz. Önce aküdeki değeri 10 ile karşılaştırıyoruz. Eğer 10’dan küçükse ekrana rakam basmamız gerekiyor. Bunun için aküye $30 (48) sayısını ekliyoruz. Böylece ekrana basacağımız rakamın ASCII kodunu elde etmiş oluyoruz. JSR $FFD2 komutuyla ise ekrana bir adet rakam basıyoruz. Eğer karşılaştırma sonucu elimizdeki değer 10 ve daha büyükse (en fazla 15 olabilir) bu değeri 65-71 arasına tamamlamak için $37 (55) eklememiz gerekiyor. Önce 7 ile ve sonrasında hemen $30 ile toplayıp A ile F arasındaki bir harfin ASCII kodunu elde ederek ekrana bir adet harf basmış oluyoruz.

Daha sonra RTS komutuyla geri dönerek JSR CONVERT komutundan sonraki komuta geliyoruz. Yığındaki değeri geri alarak ve AND #$0F komutuyla sadece 7-6-5-4 nolu bitleri sıfırlayıp 3-2-1-0 nolu bitleri dikkate alıyoruz. Bundan sonraki işlemler ikinci paragraftaki anlattıklarımızın aynısı. Tek fark RTS komutuyla işimizi bitiriyoruz.

Örnek vererek anlattıklarımızı doğrulayalım. Adresteki sayımız 179 ($B3) olsun. Ekrana “B3” yazdırmamız gerekiyor. İlk olarak $B3 sayısını binary (ikili) sistemde yazalım. Bunun için önce $B (11) sayısının binary sistemdeki karşılığı olan 1011 sayısını ve hemen yanına ise 3 sayısının binary sistemdeki karşılığı olan 0011 yazalım. Demek ki $B3=%10110011 oluyormuş. Devam edelim. İlk olarak aküye 4 LSR komutunu uygulayacağız.

SAYI LSR LSR LSR LSR 10110011 Æ 01011001 Æ 00101100 Æ 00010110 Æ 00001011

Gördüğünüz gibi 4 LSR komutu ile sayının 7654 nolu bitleri birer sağa kayarak 3210 numaralı bitler haline geldi. Yani aküde artık %00001011 sayısı var.

Sıradaki JSR komutu ile bir gezintiye çıkalım. Önce CMP #$0A ile karşılaştırma yapalım ve BCC NUMBER komutuna gelelim. BCC komutu ile daha önceki CMP komutunun sonucuna göre işlem yapıyoruz ve aküdeki değer, karşılaştırma yaptığımız değerden küçükse NUMBER kısmına gidiyoruz. Fakat burada aküdeki değer $B (11) olduğu için bir sonraki komuta geçiyoruz. Önce CLC ile “carry” bitini sıfırlayalım. Sonra ADC #$07 ile aküdeki değeri $7 ile toplayalım. Sonuç $12 (18) olur ve yine aküde tutulur. Devam ediyoruz. Bir CLC ve ADC #$30 ile aküdeki değer $12 + $30 = $42 olur. Daha sonra JSR $FFD2 komutu ile aküdeki değeri ekrana basıyoruz. Acaba gerçekten doğru mu? Eğer ASCII kodlara bakarsanız $42=”B” demektir. Bu arada CLC kullanmazsak ne olur? Sonuç yanlış çıkabilir. ADC komutu şöyle çalışır.

AKÜDEKİ DEĞER + CARRY BİTİ + EKLENECEK SAYI = SONUÇ tekrar aküde tutulur. Buna göre CLC komutuyla Carry biti 0 yapıldıktan sonra toplama yapılırsa $0B + 0 + $07 = $12 ve devam edersek $12 + 0 + $30 = $42 olur. Eğer CLC kullanmazsak sonuç aşağıdaki gibi olur.

$0B + x + $7 = SONUÇ Æ Burada “x” 0 veya 1 olabilir ve sonuç $12 veya $13 olur. Bunun sonucunda programımız istediğimiz gibi çalışmaz.

Bu kısa bilgiden sonra RTS komutuyla kaldığımız yerden devam ediyoruz ve geri dönüş yaparak JSR’den sonraki komutu işletiyoruz. Aküye tekrar adresteki değeri yani $B3’ü yüklüyoruz. AND #$0F ile 7654 nolu bitleri sıfırlayarak sadece 3210 nolu bitleri dikkate alıyoruz. Bu arada AND komutuyla ilgili olarak bilgilerimizi tazeleyelim. AND komutu ile işleme sokulan bitlerin değerleri “1” ise sonuç “1”, herhangi bir bit “0” ise sonuç “0” olur. Yani 0 AND 0 = 0, 0 AND 1 = 0, 1 AND 0 = 0 ve 1 AND 1 = 1 olur. Bu bilgilerin ışığında bizim AND #$0F ile nasıl bir sonuç elde ediyoruz inceleyelim.

AKÜ Æ $B3 Æ %10110011 SAYI Æ $0F Æ %00001111 SONUÇ Æ $03 Æ %00000011 Æ Sonuç aküde tutulur.

Devam ediyoruz ve tekrar CMP #$0A ve BCC NUMBER komutlarına geldik. BCC komutu programda karşılaştırma sonrası “...den küçükse” şartı için kullanılmaktadır ve burada $0A’dan küçükse NUMBER kısmına gidilecektir. Aküdeki sayımız $03 ve dolayısıyla $0A’dan küçüktür. NUMBER kısmında CLC ve ADC #$30 komutları ile aküyü $30 ile toplayıp $33 sayısını elde ediyoruz ve JSR $FFD2 ile ASCII kodu $33 sayısı olan “3” rakamını ekrana yazdırıyoruz. Son olarak RTS komutuyla işimizi bitiriyoruz.

Ön bilgi:

BCC Æ Küçükse; BCS Æ Büyük veya eşitse; BEQ Æ Eşitse; BNE Æ Eşit değilse;

şartlarının kontrolü için kullanılır.