C64 için Püf Noktaları
Retro bilgisayarMAKİNE DİLİNİN PÜF NOKTALARI
Bu aydan itibaren sizlerle birlikte olup makine dilinin tüm inceliklerini tanıtmaya çalışacağız. Ancak bu tanıtım daha öncekiler gibi değil. Amacımız sadece assembler komutlarını öğretmek değil, bu dilin programlama mantığını ve basit programlar yazmanızı sağlamak. Evet hazırsanız başlıyoruz. Makine dilinde kullandığınız sayılar hexadecimal yani 16'lık sistemdeki sayılardır. Bu sayılar: 0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F şeklindedir. Örneğin $1000'i decimal (onluk) sistemde gösterelim
- 16 x 16 x 16 x 1 = 4096 - 16 x 16 x 2 = 512 - 16 x 5 = 80 - (4'ün 0, 1) x 4 = 4 * 4096 değerine eşittir.
Esasen bu çevirmeleri monitör programları kendi kendine yapabilirler. Commodore 64'ün assembler'ında 3 register mevcuttur. Register'lar bir değeri sakladığınız değişkenlerdir. Bu değişkenler A, X ve Y'dir.
Bu işlemlerden sonra size çok karmaşık gibi görünen bazı temel komutları inceleyelim. LDA VE STA KOMUTLARI: Assembler'da “LDA” komutu en çok kullanılan komutlardan biridir. Anlamı “load accumulator”dür. Bu komutla A register'ine yani accumulator'e herhangi bir değer verebilirsiniz. LDA #$50 - Bu örnekte A'ya 50 değeri verilmiştir. Örnekte “#” kullanılmasının nedeni yüklenen değerin direkt kullanılması içindir. LDA - Eğer buradaki gibi “#” kullanmazsanız makine A'ya yükleyeceği değeri $4000 adresinden alır. Yani $4000'deki değer A'ya yüklenir. Eğer $4000 adresinde #$80 varsa A değeri 80 olacaktır. Unutmadan şunu da ekleyelim; komutlarda kullanacağınız sayılar HEXADECIMAL yani 16'lık sistemdeki sayılardır. Bu sayıları kullandığınız monitör programı yardımıyla kolayca bulabilirsiniz.
STA komutu ise “store A” anlamına gelir. Bu komut BASIC'deki POKE komutuna karşılıktır. LDA ile yüklediğiniz değeri STA ile istediğiniz adrese yerleştirebilirsiniz. LDA #$09 - A'ya #$09 değerini verir. STA $1000 - değerini adresine yerleştirir. Aynı işlemi BASIC'de şu şekilde yapabilirsiniz. POKE 4096,9 - Buradaki 4096, decimal (onluk sistem)'deki değeridir. Umarız ki bu yazılanlar size karmaşık gelmiyordur. Çünkü LDA ve STA komutlarının daha değişik şekillerini incelemeye başlıyoruz. Şimdi de aşağıdaki küçük programa bir göz atalım. LDA #$41 - A = 41 (onluk olarak 65) STA $0400 - $0400 = 41 ($0400 onluk olarak 1024'e eşittir. 1024 değeri ekranın başlangıç adresidir.) Yukarıdaki programda ekranın sol üst köşesine A harfi bastık. Aynı işlemi BASIC'de POKE 1024,65 ile yapabilirsiniz. Sizin de anladığınız gibi BASIC'deki POKE komutu assembler'da LDA ve STA komutuna karşılık gelir. Klavye üzerinde bulunan bütün karakterlerin, hafızada bir sayı değeri vardır. Bu sayı değerlerini kullanım kılavuzunda bulabilirsiniz. Şimdide diğer register'leri kullanarak kısa bir program yazalım:
TST
İŞTE OLAY!
5,25" TEAC-Extern Disk Drive
2 MB RAM
512 KB RAM
LDX X — 00
DÖNGÜ: LDA $1000,X -> $1000'deki değeri A'ya
yükle
STA $0400,X -> A'daki değeri S04004- X'e
koy
INX ->X' bir arttır
TST
JMP DÖNGÜ - > (LDA $1000, X'e)
DÖNGÜ'ye git.
Yukarıdaki programda, $1000-$4100'de bulunan değerlerin $0400-$0500 arasına nasıl basılabileceğini gördük. Bu işlem sırasında ekrana $00'dan $FF'e kadar olan değerleri bastık. Yani decimal olarak 255 tane karakter bastık. Bunun sebebi de makine dilinde her sayının karakter olarak bir karşılığı vardır. Eğer ekrana bir mesaj yazdırmak isterseniz $1000 ile $4100 arasına, mesajınızı yazın. Programın içinde kullandığımız LDX #$00 komutu ile hafızada bir sayaç açıyoruz. INX komutuyla (Increment X) X'i bir değer arttırıyoruz. JMP ile ekrana X'in bir değer artmış halini basıyoruz. Yani X, sıfır iken sıfırıncı değeri, X bir iken birinci değeri bastırıyoruz. Bu işlem X, 255 olana kadar devam ediyor. Eğer bu sayının 255'den küçük olmasını isterseniz INX komutundan sonra CPX (Compare X) kullanmamız gerekir. $10 kullanarak X'in $10 olup olmadığı karşılaştırılır. Aynı zamanda JMP komutu yerine BNE (Branch if not Equal) kullanmamız gerekir.
BNE komutu BASIC'de IF komutuna karşılık gelir. X, $10 olana kadar BNE DÖNGÜ yapılır. Yani X'in o andaki değeri kontrol edilir, $10 olup olmadığı kontrol edilir, X $10'dan küçükse BNE yardımıyla LDA X yazan satıra gidilir. Şimdi LDA, STA, LDX, STX komutlarını kullanarak ekranı silme, zemin ve kenar renklerini değiştirmeyi görelim. Ekran iki şekilde silinir. 1- Aynen BASIC'de olduğu gibi (PRINT “CLR HOME”)
LDA #$93-
JSRS D2- ekranın yazım adresi
Yukarıdaki programda A'nın aldığı değer (147), BASIC'de yaptığımız CLRHOME'a eşittir. Yani SHIFT tuşu ile beraber CLEAR HOME tuşuna bastığımızda ekrana çıkan (negatif kalp) işaretin değeri, hafızada $93 değerine karşılık gelir. JSR $FFD2 ise PRINT komutunun assembler karşılığıdır. Commodore 64'ün içinde bulunan (KERNAL ROM) bazı komutlar vardır. Bunlara KERNAL RUTİNLERİ denir. $FFD2'de bu kernal rutinlerinden biridir. Yukarıdaki program ekrana CLRHOME'a karşılık gelen değeri basar. Böylece ekran silinmiş olur. Bildiğiniz gibi BASIC'de ekranın renklerini 53280 ve 53281 adreslerini kullanarak değiştiriyoruz. POKE 53280,0 yazdığımızda ekranın dışı siyah rengi alır. POKE 53281,0 yazdığımızda ekranın iç kısmı da siyah olur. Aynı işlemi assembler'da şöyle yapabiliriz
LDA #$00 -> Az00
STA $DO20 - >A'daki değeri $DO20 adresine yerleştir.
LDX #S00
STX $DO21 ->X'deki değeri $DO21 adresine yerleştir
Aynı işlemi pratik olarak
LDA # $00 - >
STA $DO20 - > A'daki değeri $DO20'ye koy.
STA $DO21 - > A'daki değeri $DO21'e koy.
Sanırım şu ana kadar basit de olsa bir şeyler anlamışsınızdır. Gelecek sayıda INTERRUPT ve TIMING konularını anlatacağım. Görüşmek dileğiyle.