Bu sayfadaki yazılar
Sayfanın metni
Sayfa 61
780— — Akümülatör X-registeri 782- Y-registeri Durum registeri
Makine dilindeki programımızın belli bir akü değeriyle başlaması gerekiyorsa, sadece SYS komutundan önce gerekli değeri 780 adresli belleğe yazmak gerekiyor. 781 ve 782 adresli hafıza birimleri, aynı tür kullanımı X- ve Y-registerleri için sağlıyorlar. Durum registerini BASIC'ten kontrol ederken biraz dikkat etmek gerekiyor. En fazla dikkat gerektiren durumlar Interrupt ve Desimal flaglarının gereksiz yere yakılmamasıdır. 783 adresli hafıza birimi normal durumlarda sıfır değerini içerir. Bu değer, hiçbir zaman karışıklık yaratmayacak bir değerdir. Bu hafıza birimlerini BASIC'ten makine dili programlara değer geçirmek için kullanabileceğiniz gibi makine dili programların yürümesi bittiğinde ana işlem ünitesinin registerlerinin durumunu izlemek için de bu hafıza birimlerini kullanabilirsiniz. Bu yöntemle BASIC ve makine dili programlar arasında üç adet sekizer bitlik bilgi bağlantısı kurulmuş oluyor. Birçok kullanımda bu kadarlık bağlantı yetebiliyor. Daha çok parametre geçişi gerekiyorsa, yukarıda bahsettiğimiz gibi daha fazla hafıza birimini bu iş için kullanmanız gerekiyor.
Parametre geçişinde kullanılan bir başka yöntem de daha fazla konforu amaçlıyor. Bu yöntemde BASIC yorumlayıcısının bazı özel altprogramları kullanılıyor. Diyelim ki, BASIC yorumlayıcısı POKE 780, 10 gibi bir satırla karşılaştı. Yorumlayıcı, POKE komutunu tanıdıktan sonra gerekli parametreyi BASIC programından alması için genel bir altprogram modülünü çağırır. Bu altprogram, örneğimizdeki gibi sadece sabit sayıları değil, aynı zamanda değişkenler bulunduran karmaşık terimleri de hesaplayabilir. Yani, satırımız POKE EXP(X) kadar karışık olsa da hiç bir sorun çıkmayacaktır. Bu altprogramlar her ne kadar yorumlayıcıda bulunsalar da sadece yorumlayıcının kendisi tarafından çağrılması gerekli diye bir kural yoktur. Bu altprogramların gereksinimlerini karşılayabildiğimiz sürece biz de kullanabiliriz. Çağırılan altprogramların gereksinimlerine biraz daha detaylı olarak değinelim. Burada sözünü ettiğimiz aritmetik hesaplama (formula evaluation) altprogramı FRMEVL adı taşıyor ve rekursif bir yapıya sahip. (Bu yapıyı daha detaylı görmek isterseniz ARALIK 86 sayımızdaki RECURSI-
Grafik işlemleri
makine
diliyle yapmak, BASIC'le yapmaktan daha zor ama daha
olanaklı ve daha
hızlı.
ON adlı yazıya başvurmanızı öneririm). Bu program her bir parantezde veya işlem önceliğine göre sırayı düzenlemesi gerektiğinde, son durumunu gösteren ara değerleri yığına atar ve kendi kendini çağırır. Sonuç olarak, yığını aşırı yoğun olarak kullanır. Bilindiği gibi 6510 ana işlem ünitesinin yığını sınırlı bir büyüklüğe sahiptir (256 byte). Bu yüzden böyle bir altprogram çağrılmadan önce yığında yeterli büyüklükte yer olup olmadığı kontrol edilmelidir. Grafik işlemleri ile ilgili programımızı yazmaya başlamadan önce, gelin grafikle ilgili bazı temel prensiplere gözatalım. Yüksek çözünürlüklü grafikte, ekranın her bir noktasına ayrı ayrı hitap etme olanağınız doğuyor. Normal yazı ekranında 40x25 karakter genişliğinde bir bölge üzerinde kontrolünüz vardı. Buradaki her bir karakter de 8x8 = 64 noktadan oluşmuştu. Yüksek çözünürlüklü grafikte, kontrol olanağımız hem yatay hem dikey pozisyonda sekizer kat artıyor, 320 x 200'lük bir hassasiyetimiz var. Yazı ekranını tanımlarken her bir karakter için bir byte kullanıyoruz. Yani tüm ekran için 40 x 25 = 1000 byte kullanmamız gerekiyor. Yüksek çözünürlüklü grafikte her bir noktayı bir tek bitle gösterebiliyoruz. Böylece hafıza gereksinimimiz, 200 x 320 x 1 = 64000 bit = 8000 byte oluyor. Yazı ekranı normalde 1024'ten 2023'e kadar uzanan bölgede bulunuyor. VIC çipine gerekli değerleri bildirerek bu bölgeyi bir KByte'lık ($400) adımlarla ilerletebiliyorsunuz. Mesela, $800, $C00, $1000 gibi. Yüksek çözünürlüklü grafik için sekiz KByte'lık bir bölge gerekiyor. Bu bölgenin başlangıç adresi, gene VIC çipinin kullanımı ile belirleniyor. Burada dikkat etmemiz gereken husus, VIC çipinin bir kerede sadece 16 KByte'lık bölgeyi görebilmesi. 16 KByte'lık bölgelerden hangisini seçtiğimizi belirtmek için CIA çiplerinden birinin bir hafıza birimini kullanmamız gerekiyor. Gelin, hep beraber kendimize uygun bir 8 KByte'lık boş bir bölge bulalım.
İlk bakışta, böyle bir yer olarak ilk akla gelen yer BASIC için ayrılmış olan belleğin bir kısmı geliyor. Fakat, biz gene de tembellik etmeyelim. Çünkü, COMMODORE 64'ümüzün tüm belleği RAM ile kaplı. Kullanacağımız en uygun yer, işletim sistem ROM'unun altında yeralan ve $E000'dan $FFFF'e kadar uzanan RAM belleği olacaktır. BASIC'ten bu bölgedeki RAM'e erişmek mümkün olmayacaktır. Çünkü, bu bölgelerin içeriğini okumak için işletim sistemi ve BASIC yorumlayıcısı ROM'unu geçici de olsa kapatmamız gerekecektir. Aklımıza gelen bir nokta da, normal ekran hafızasının grafik modunda renk hafızası olarak kullanıldığıdır. Yani ekran hafızasını da aynı 16 KByte'lık bölge içine taşımamız gerekecektir. Kolaylık olsun diye, hemen bu bölgenin baş kısmını ($C000-$C3FF) seçelim. Bu bölge, normal şartlarda BASIC tarafından da kullanılmıyor. Renk bilgisi için ayrılan bölgenin bir KByte büyüklüğünde olduğunu gözönünde tutarsak, her bir noktanın ayrı bir renge sahip olamayacağını da farkederiz. Gerçekte, 8 x 8'lik bir bölgenin içinde bulunan noktalar aynı renk grubunu kullanmak zorundadırlar. Çalışma sistemimizi, modüler tutmak için ufak ufak ve belli bir işi yapan makine dili altprogramlar yazacağız. Daha sonra bunları BASIC'ten çağıracağız. İlk altprogramımızın yapacağı işlem, bilgisayarı yüksek çözünürlüklü grafiğe geçirmek. Tabii, grafiğimiz demin yukarıda belirlediğimiz hafıza bölgesinde yeralmak zorunda. Yapacağımız işlemi önce BASIC'te formüle edelim: 100 V=53248:REM VIC ÇİPİNİN BAŞLANGIÇ ADRESİ 110 V1 = V + 17:REM GRAFİK MODUNA GEÇME REGİSTERİ 120 V2 = V + 24:REM EKRAN HAFIZASININ BAŞLANGICI BURADAN BELİRLENİYOR. 130 CIA = 56576:REM($DD00) 16K'LIK BÖLGEYİ SEÇMEK İÇİN 140 POKE V1,59 150 POKE V2,8 160 POKE CIA,0 170 END Bu örneğimizi, makine diline çevirmeden önce, programımızın belleğin hangi bölgesine yerleşeceğine karar vermemiz gerekmektedir. $C000'dan $C3FF'e kadar olan bölge, grafik ekranımızın renk bilgileriyle dolu olacağı için, biz de hemen bu bölgenin arkasını yani $C400 adresinden itibaren olan bölgeyi kullanacağız. Assembler kullanacak olursak:
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 60
AYHAN KALAYLIOĞLU
6. MAKİNE DİLİNDE PROGRAMLAMA
COMMODORE 64'te makine dilini kullandırmayı gerektiren başlıca konu, yüksek çözünürlüklü grafiklerin yaratılması olayı. Bu bölümde, biz bu sorunları önce BASIC'te formüle edip, daha sonra makine diline çevirmeyi deneyeceğiz. Bu arada ana işlem ünitesinin yapabileceklerinin hepsini keşfedip, yeri gelince kullanmaya çalışacağız.
Grafik işlemlerini yürütmek üzere yazılmış BASIC programlar genelde birbirinin içine geçmiş PEEK ve POKE komutları yığını şeklindedir. Bilhassa bu tip programları makine diline çevirirken bu dilin asıl gücünü keşfedeceğiz. Bundan başka, her iki dilin avantajlı yönlerinden aynı anda yararlanmak için değişik yollar deneyeceğiz. Böylece yarı makine dili, yarı BASIC yapısına benzer programlarımız olacak. Böylece, oldukça kısa bir zamanda oldukça güçlü programlar elde edebileceğiz.
Örnek programımıza geçmeden önce makine dili programların BASIC'ten nasıl kullanıldığını ve parametrelerin nasıl gönderildiğini görelim. Makine dilindeki altprogramların çağrılması için SYS komutunu kullanacağız. Bu komutun arkasından gelen rakam, yürütülmek istenen altprogramın bellekte bulunduğu başlangıç adresidir. Makine dilindeki altprogram RTS (return from subroutine) komutu ile bittiğinde kontrol gene BASIC yorumlayıcısına geçer. Böylece BASIC'teki program kaldığı yerden yürümeye devam eder. Diyelim ki makine dilindeki altprogramımızın sabit bir görevi var, örneğin ekranı silmek, böyle bir durumda herhangi bir parametreye gereksi-
60 nim duyulmayacak ve SYS komutu kendi başına yeterli olacaktır. Diyelim ki grafik ekranına bir nokta koyan bir altprogramı çağıracağız; böyle bir durumda tabii ki noktanın nereye konacağını bildiren bilgiler, makine diline geçmesi gereken parametrelerimiz olacaktır. Bu parametreleri göndermek için birçok yöntem vardır. Bunlardan ilki ve en basiti, parametreleri peşpeşe gelen hafıza birimlerine saklamaktır. Makine dilindeki altprogram, daha sonra bu parametreleri o bölgeden alır. Bizim örneğimizde de aynı yöntemi kullanacağız. Şöyle ki: Yatay koordinatı bir hafıza birimine, dikey koordinatı bir diğer hafıza birimine saklayacağız. BASIC'te tüm bu işlemi yapmak için iki adet POKE komutuna ihtiyacımız olacak. Makine dili programımız yürürken bu parametreleri o adreslerden alıp kullanacak. BASIC yorumlayıcımız bize bir olanak daha sağlıyor. Bu olanak, BASIC'ten ana işlem ünitesinin registerlerine hitap etmemizi sağlıyor. Tabii, bu olay doğrudan gerçekleşemeyeceği için, ara değerleri saklayacak bir bölge olması gerek değil mi? Doğru, bu iş için dört hafıza elemanı ayrılmış. SYS komutu ile bir programı çağırdığımızda, altprogram çağırılmadan önce ana işlem ünitesinin registerleri bu bölgedeki değerlerle yüklenir. Bu hafıza birimlerinin adresleri ve yüklendikleri registerler şunlardır: