Bu sayfadaki yazılar
Sayfanın metni
Sayfa 52
Tablomuzun X satırının ve Y kolonunun yardımıyla o noktayı bulun. 8192 + 328 = 8520 adresinin 0 numaralı bit'i olduğunu göreceksiniz. Hemen yanındaki (16,15) koordinatı ise, 8192 + 336 = 8528 adresinin 7 numaralı bit'i oluyor. Kâğıt üzerinde bulunması pek de zor olmayan bu adres ve bit'lerin, hesap yoluyla bulunması oldukça karmaşık. Birazdan grafik rutinlerini geliştirirken bu konuya geleceğiz. Çokrenkli mod (multicolor) kullanıldığında byte'ların düzeni değişmiyor. Tek değişen, yanyana iki noktanın bir noktaymış gibi davranması. Örneğin (0,0) multicolor koordinatı 8192'nin 7. bit'i iken, (1,0) koordinatı 8192'nin 5. bit'i olacaktır. Çünkü 7. ve 6. bit'lerin ikisi de (0,0) koordinatları için kullanılacaktır. Bu iki bit'in içeriği 00, 01, 10 veya 11 olabileceğinden, o nokta dört değişik renkte olabilecektir. Böylelikle renk konusuna girdik. Her iki modda da renk kullanımının nasıl olduğunu görelim... 320*200'ü kullanıyorsak, grafik ekranındaki her 8*8'lik bölgede iki değişik renk olabilir. Biri çizgi rengi, diğeri arka plan rengi. Her bir 8*8'lik bölgenin bu iki rengi farklı farklı olabilir. Bu renklerle ilgili bilgi, VIDEORAM dediğimiz bölgede saklanır. Normalde yazı yazdığımız ekranı saklayan bu hafıza bölgesi, grafik ekranına geçtiğimizde bir renk deposu haline gelir. Bu hafızanın her byte'ındaki sayısal değer, karşılık geldiği 8*8'lik alanın rengini belirler. Bir alandaki çizgi rengini RC ile, arkaplan rengini de RE ile gösterirsek, VIDEORAM'da karşılık gelen byte'ın içeriğinin RC*16 + RE olması gerekir. Bir başka deyişle, o byte'ın üst 4 bit'i çizgi rengini, alt 4 bit'i de ekran rengini belirler. VIDEORAM'ın organizasyonu daha basittir:
kolaylıkla hesaplanabilir. Örneğin VIDEORAM'ın başlangıç adresi $0400 (1024) ise (7,18) koordinatının renk byte'ı 1024 + 80 = 1104 adresinde olacaktır.
Multicolor'da ise, demin de değindiğimiz gibi her iki bit'in oluşturduğu çift, o noktanın rengini belirleyecektir:
00 = VIC'ın 33 numaralı yazmacı 01 = Renk 1 = VIDEORAM'ın alt dört bit'i 10 = Renk 2 = VIDEORAM'ın üst dört bit'i 11 = Renk 3 = Renk RAM'ı
A-7 aa alı 02 !.... 8-15 41 2 !....
Gördüğünüz gibi her 8*8'lik grafik noktası grubuna karşılık gelen byte
Renk RAM'ı 55296-56295 adresleri arasında yer alır ve yeri değiştirilemez. Organizasyonu VIDEORAM ile aynıdır. VIC'in 33 numaralı yazmacı ise normalde yazı ekranının rengini belirler. Şimdi ise 0 numaralı renk yerine geçiyor. Artık bu bilgileri değerlendirerek programlar yazmanın zamanı geldi. Nasıl grafik ekranı açılır / kapanır, renklendirilir, nokta çizilir / silinir, çizgi çizilir / silinir, elips çizilir / silinir? Tüm bu temel rutinleri birer alt-
program halinde yazarsak, artık grafik konusunda oldukça büyük bir adım atmış oluruz. Çünkü, tüm cisimlerin temelinde yatan şekiller bunlardır ve bunları kullanarak diğer tüm geometrik çizimleri yapabilen altprogramlar yazabiliriz.
Önce bir iki noktada anlaşalım. Kullanacağımız grafik sayfası, BANK0'ın ikinci yarısı, yani $2000'den (8192) başlıyor. Burayı seçmemizin nedeni, bilgisayarın açıldığı sırada BANK0'a ayarlı olması. Eğer CIA2'nin bit'leri ile oynayarak diğer BANK'lardan birini kullanırsak bir sürü kaydırma işlemi yapmamız gerekecek. İsteyenler, daha önceki bölümlerde gördüğümüz POKE komutlarını kullanarak başka bir grafik sayfası kullanabilirler. Ancak dikkat etmeniz gereken bir nokta var. BANK2 ve BANK3'ü BASIC ile kullanamazsınız. Makina dili programlaması gerekir. BANK0'ı kullanmamıza bağlı olarak, VIDEORAM da $400'den (1024) başlıyor.
Programlama dili olarak, herkesin anlayabilmesi için, BASIC kullanacağız. Bunun yaratacağı en büyük sorun programların yavaşlığı olacak. Ancak makina dili kullanmak isteyenler ve programlamasını bilenler, bizim verdiğimiz rutinleri kolayca makina diline çevirebileceklerdir. Ayhan Kalaylıoğlu'nun makina dili dizisini okumaya devam edin. İlerde, grafik rutinleri de vermeye başlayabilir. Grafik rutinlerimizi geliştirdikçe onları birleştirip bir program haline getireceğiz. Vereceğimiz satır numaraları 50000'den büyük olacak ve her bir parçası GOSUB ile çağrılabilecek. Gerekli olduğu zaman, bazı değişkenler parametre gibi kullanılacak. Örneğin XN=100:YN=20 verip nokta koyma rutinini GOSUB ile çağırdığımızda, 320*200 ekranının (100,20) koordinatına bir nokta konacak. Bir başka gereklilik de, grafik işlemlerine geçmeden önce POKE 56,32 vererek BASIC kullanım alanının tavanını $2000 olarak belirlemeniz. Yoksa, BASIC programınız ile değişkenleriniz grafik sayfasının bilgileri ile silinebilir. Artık başlayalım. İlk işimiz grafik sayfasını açmak.
320*200'lük ekrana geçmek için üç işlem yapmamız gerekiyor:
1) Yüksek çözünürlü grafiği aktif yapmak. 2) Multicolor'ı kapatmak.
3) Grafik sayfasının $2000'den başladığını belirtmek.
İlk işlemi yapmak için, VIC'in 17 numaralı yazmaçının 5. bit'ini yakmak gerekiyor. Multicolor'u kapatmak içinse 22. yazmaçın 4. bit'ini sıfırlamak lazım. Bir numaralı grafik sayfasını kullanmak için vereceğimiz POKE komutunu da evvelki sayımızda görmüştük. 160*200'lük ekrana geçmek içinse, birinci ve üçüncü işlemlerin yanında ikinci işlemin tam tersini yapmak, yani 22. yazmaçın 4. bit'ini yakmak gerekiyor.
Programımızın 50000-50060 arası satırları, 320*200'e geçmek için kullanılan komutları kapsar. 52000-52060 arası ise multicolor'a geçer. Sadece
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 53
GOSUB ile çağrılmaları yeterlidir. Parametreye gerek yok. Sıra geldi grafik sayfamızı silmeye. Grafik sayfasını açar açmaz fark edeceksiniz, daha önceden hafızada kalan bir sürü garip byte değeri, ekranı bir nokta karmaşasına döndürecek. Bunları silmek için 8192'den başlayan bölgeye 8000 byte boyunca sıfır POKE etmemiz gerekiyor. Bu işlemi de, 50100-50140 arasındaki altprogram yapıyor. Parametresi yok. Çizim yaptığımız renkleri belirlemek, kullandığımız çizim moduna göre değişiyor. Bu nedenle iki rutinimiz var. 320*200'de renklendirme işlemi bir tek FOR... NEXT içinde bitiyor. 1024'ten başlayıp 1000 byte boyunca devam eden çizgi ve ekran renginden hesaplayacağımız sayıyı POKE edince işimiz bitiyor. Bunu 50200-50240 arası satırlarda görüyorsunuz. Parametre olarak, RC içinde çizgi rengi, RE içinde de ekran rengi olması gerekiyor. Ekran, bu iki değişkene göre renklendiriliyor. 160*200'de ise, hem VİDEORAM doldurulacak, hem de 55296-56295 arasındaki renk RAM'ı. Bir de VIC'in 33. yazmaçı. Bu rutini de 52200-52250 arasında görüyorsunuz. Parametre olarak, R0, R1, R2 ve R3 içinde kullanılacak renkleri gönderiyorsunuz.
Grafik ekranıyla ilgili son işlem, işimiz bittiğinde yazı ekranına geri dönmek. Grafik sayfasını kapatmak için yapılacak işlem, açmak için yaptığımız işlemin tam tersi. Önce VIC'in 17. yazmaçının 5. bit'ini söndüreceğiz. Sonra 22. yazmaçta multicolor kapatılacak. Ve nihayet, ekranı $2000'e yerleştirirken değişen karakter üreteci adresini düzeltip $1000'e getiriyoruz. Grafik ekranı ile karakter üreteci adresi arasındaki bu ilişkiye geçen sayımızda dikkatinizi çekmiştik. Tüm bu işlemler, 50300-50360 arası satırlarda yapılmaktadır. Parametre gerekmiyor. Hem multicolor hem de normal ekran için bu altprogram kullanılabilir. Bu altprogram GOSUB ile çağrıldıktan sonra yazı ekranının silinmesinde fayda var. Tüm ekran, kullanılan çizim renklerine göre baştan aşağı karakterlerle dolmuş olacaktır. Şimdi nokta, çizgi ve elips gibi temel şekilleri çizmeye başlıyoruz. Önce nokta...
Grafik sayfamız soldan sağa 320, yukarıdan aşağı 200 noktadan oluşuyor. Multicolor da kullansak, soldan sağa 320 tane bit'i kontrol etmemiz gerekiyor. Tek fark, bu sefer onları ikişer ikişer kontrol etmemiz gerektiği. Sağdan sola noktalar, 0-319 olarak, yukarıdan aşağıya da 0-199 olarak numaralandırılırlar. Bizim yazacağımız rutin, bu koordinatlar verildiğinde, hangi byte'ın hangi bit'inin yakılması gerektiğini bulmalı. Peki, bu iş nasıl olacak? 50400-50460 arasındaki rutin, (XN, YN) değişkenleri ile gönderilen noktayı basmakta. Şimdi bu işi nasıl yaptığını görelim. Öncelikle basılmak istenen koordinatın ekranda olup olmadığını kontrol ediyoruz. Eğer değilse, ana programa doğrudan geri dönülüyor. Aksi durumda byte ve bit hesabı yapılıyor. Y-koordinatından başlayalım. Her ekran satırında 8 grafik satırı olduğuna göre (grafik ekranının organizasyonunu hatırlayın), INT (YN/8) ile hangi ekran satırında olduğumuzu bulabiliriz. Her ekran satırı 320 byte'dan oluştuğuna göre, 320*INT (YN/8) ile noktamızın yer aldığı ekran satırının ilk byte'ının grafik ekranının başlangıç adresinden uzaklığını buluruz. Sıra geldi, noktayı bulunduran grafik satırının ilk byte'ının adresini bulmaya. Demin bulduğumuz sayıya (YN AND 7) ile bulacağımız YN/8 işleminin kalanını eklersek, grafik satırının başını buluruz.
Şimdi de XN koordinatını kullanarak, noktanın sol taraftan kaç byte ve kaç bit uzakta olduğunu bulalım. INT (XN/8) ile sola olan uzaklığı byte cinsinden buluruz. Adres olarak hesabı yapmak için, bu sayıyı 8 ile çarparız. Hatırlarsanız, yatay bir çizgi üstünde byte'ların adresleri sekizer sekizer artıyordu. Daha önce YN değerini kullanarak bulduğumuz byte değerine son bulduğumuz değeri de eklersek, noktamızın kaç numaralı byte içinde olduğunu saptamış oluruz. Sıra geldi bit numarasına. YN ile yaptığımız gibi (XN AND 7) yaparak XN'in byte içindeki yerini soldan itibaren buluruz. Bunu 7'den çıkarırsak, bit'in sağdan itibaren olan numarasını hesaplamış oluruz. İki üssü bit numarası ile, bulduğumuz adresin eski içeriğini OR'larsak, hedeflediğimiz nokta yanık duruma geçer. Tüm bu işlem 320*200 için geçerli. Yanan noktanın rengi de, daha önce ekranı renklendirirken verdiğiniz çizgi rengi olacaktır. Multicolor ekranda da buna benzer bir işlem yapılır. 52400-52460 arası satırlarda görmektesiniz. Parametreler gene XN ve YN'dir. Bir de hangi renk ile çizim yapılacağını belirleyen RR değişkenini göndermelisiniz. İçeriği 0-3 arası bir sayı olmalıdır. Böylece, ekranı renklendirirken belirlediğiniz 4 renkten hangisinin nokta konurken kullanılacağı belirlenir. Bu kez, tüm hesaplamalarda XN yerine XN*2 kullanıyoruz. Diyelim ki XN = 20. Multicolor'da bu X değeri, soldan 40 ve 41 numaralı bit'lere hitap eder. Biz de hesaplamalarımızda bunu göz önüne alıyoruz. Tüm işlemler sonucunda byte'ın adresini bulduktan sonra, o noktamızı oluşturan iki bit'in hangileri olduğunu hesaplıyor, sonra bunları AND ile sıfırlayıp, RR'nin gösterdiği değer ile OR'luyoruz. Tabii bunu yapmak için de bazı ufak hesaplamalar gerekiyor. Bir de nokta silme işlemi var. Bu işlemi sadece 320*200 için düşünebiliriz. Multicolor'da nokta silmek anlamsızdır. Dört renkten herhangi biriyle çizim yapılınca eski nokta ortadan kalkar, yerine yeni bir nokta gelir. Nokta silmenin nokta koymaktan pek bir farkı yok. Tek farkı, OR işlemi için kullandığımız sayının tam tersini (yani 255'ten çıkarılmış halini) byte'ın eski içeriği ile AND'liyoruz. Böylece hedeflediğimiz nokta sönüyor. Bu işlemi de, 50500-50560 arası yapıyor ve (XN, YN) parametrelerini kullanılıyor. Geriye çizgi ve elips kaldı. Çizgi ile devam edelim. Programımızın 50800-51040 arası, 320*200'lük ekrana, başlangıç ve bitiş koordinatları X1, Y1, X2, Y2 ile belirlenmiş bir çizgi çizer. Bu koordinatlar ekranın dışında da yer alabilir. O zaman çizginin ekranda kalan kısmı çizilecektir. Ortaokulda geometri dersini görenlerin hatırlayacağı meşhur bir düz çizgi formülü vardır: Y=MX+T. M ve T harfleri değişik de olsa, formül budur. Şimdi bu formülü nasıl kullanacağımızı görelim. X1 ve Y1 değerlerini yerlerine koyar ve denklemi T'ye göre ayarlarsak şu formülü elde ederiz: T=Y1-M*X1. Aynı işlemi X2 ve Y2 ile de yapalım: