Bu sayfadaki yazılar
Sayfanın metni
Sayfa 16
Ve Y koordinatının geri kalan kısmı da bu adresten kaç bayt ileri gideceğimizi belirliyor: adresY = adresY + (Y-INT(Y/8)*8) Ya da daha kısa bir şekilde: adresY = adresY + (Y AND 7) Formülün Y kısmını bir araya toplarsak: adresY = 320*(INT(Y/8)) + (Y AND 7) Formülün X koordinatını ilgilendiren kısmına geçmeden önce çok renk modunda renklerin nasıl oluştuğunu ve bu sistemin X koordinatını ne şekilde etkilediğini incelemeliyiz. Demin anlattığım gibi, kartların baytlarının değeriyle oynayarak sekiz noktanın açık ya da kapalı olması gerektiğini belirleyebiliyoruz. Ama ondan daha önce de “çok renk modunda üç renkten birini seçebiliriz” demiştim. Aslında bu da tam doğru değildir. Çok renk modundayken üç renkten birini ya da renksiz konumunu (yani “nokta görülmüyor” durumunu) seçebilirsiniz. Bu da her noktaya dört değişik değer verebilmemizi gerektiriyor. Eğer nokta değeri sıfırsa nokta kapalı oluyor, birse birinci, ikiyse ikinci ve üçse de üçüncü rengi kullanıyor. Tabii ki hepinizin tahmin edebileceği gibi tek bir noktanın açık-kapalı olma durumuyla bu dört koşulu birden kontrol etmemiz imkânsız. Bu yüzden çok renk moduna geçtiğinizde noktalar, şekil 4'de de görebileceğiniz gibi, ikişer ikişer gruplanır ve bu ikili grupta bulunan bileşik değere göre renk alır. Eğer iki nokta da kapalıysa bileşik nokta kapanır, ikisi de açıksa üçüncü renk verilir, biri açık biri kapalıysa açık olanın hangisi olduğuna bakılarak birinci veya ikinci renk verilir. Aşağıdaki kısa tabloda bu durumları görebilirsiniz: KK: Nokta görülmez
Şekil-1 Grafik ekranını oluşturan kartlardan biri
KA: Birinci renk. AK: İkinci renk. AA: Üçüncü renk. Bu durumu da ikili noktaların her bir noktasına ağırlıklar vererek özetleyebiliriz. Sağdaki noktanın ağırlığı 1, soldakinin iki olursa, ve açık konumunda bu değeri dikkate alırsak: KK=0 KA=1 AK=2 AA=3 Gördüğünüz gibi ekranın x uzunluğunu 320'den 160'a düşürerek her noktanın dört adet değere sahip olabilmesini sağladık. Tabii ki bu durumda her kart 8x8'lik noktalardan değil 4x8'lik geniş noktalardan oluşmaya başladı. Şimdi formüllerimizi oluştururken bu geniş noktalara göre düşünmek çok daha mantıklı ve kolay olacaktır. Formülü oluşturmak için demin yaptığımız gibi özel durumları inceleyip birleştirelim ve genel sonuca varalım (şekil 3'ü incelemek bu konuda size yardımcı olabilir): 1. X koordinatı 0..3 arasındaysa nokta başlangıç adresinde yer alıyor. 2. X koordinatı 4..7 arasındaysa nokta başlangıç adresinden sekiz ileride yer alıyor. 3. X koordinatı 8..11 arasındaysa nokta başlangıç adresinden on altı ileride yer alıyor. Sonuç olarak, 'X koordinatının dörtte birinin tam sayı kısmı bize adresten kaç kere sekiz bayt ileri gideceğimizi belirtir.” diyebiliriz. Yani bu işlemi formüle edersek: adresX = 8*INT(X/4) yazabiliriz. X ve Y koordinatlarıyla belirlenen noktanın adresinin: ADRES = adresY + adresX olarak hesaplanabileceği ise kolayca görülebilir. Şimdi yapmamız gereken, ve bizi oldukça oyalayacak tek görevimiz kaldı. O da X koordinatından artan değere göre demin hesapladığımız adresteki baytın hangi noktaları açık konumuna getireceğimiz. Bu hesabı ilk bayt üzerinde yaparsak hiçbir değişiklik yapmadan diğer baytlara da uygulayabiliriz. Yani Y koordinatı sıfır, X koordinatı da 0 ile 3 arasında bir değer alabilmeli. Demin de söylediğim gibi X koordinatı, geniş noktanın alacağı renge göre bileşik noktaların açık veya kapalı olmasını ayarlar. Başlangıçta kolaylık olsun diye üçüncü rengi basacağımızı, yani bileşik noktaların ikisini de açık konumuna getireceğimizi düşünelim ve bu bileşik noktaların yerini bulalım. Tabii ki dört durum olduğuna göre dördünü de inceleyip genel bir formüle varabiliriz: 1. X=0 ise Değer=3*2^6 2. X=1 ise Değer=3*2^4 3. X=2 ise Değer=3*2^2 4. X=3 ise Değer=3*2^0 Dikkatimizi ilk çeken şey, X'in en büyük değerini aldığı yerde 2'nin en küçük üssünü alması. Bu durumda X'i üçten çıkarmalı ve buna göre bir işlem yapmalıyız. İkinci olarak da en sağdaki üslerin hepsinin (3-X)'in iki katı olması. Sonuç olarak: Değer = (Renk) * 2^(2*(3-X)) formülünü çıkarabiliriz. İsterseniz X'in alabileceği üç değer için bu formülün sonucunu bulun. Özel durumlarımızı sağladığını göreceksiniz. Artık geriye çok fazla şey kalmadı yapmamız gereken. İlk olarak bu değeri hazırda olan değerin yerine geçirmeliyiz. Bunu yaparken de kendisini ilgilendirmeyen noktaların hiçbirine (yani diğer üç noktaya) dokundurtmamalıyız. Eğer bu değeri doğrudan doğruya yazmaya kalkarsak diğer üç nokta otomatik olarak silinecektir. Diğer noktalara dokunmamak için ise gerekli adresteki baytı alıp, bu bileşik noktaya ait bilgileri o bayttan silmeli ve bileşik noktayı bayta eklemeliyiz. Bilgi silmek için en uygun komut AND'dir. Eğer baytın alabileceği maksimum değerden yani 255'den demin bulduğumuz Değer'i çıkartırsak, baytta bileşik noktamızın dışındaki tüm bileşik noktaların açık konumda olduğu durumu elde ederiz. Bu değeri adreste saklı olan baytla AND'lediğimiz zaman bileşik noktamıza ait bilgiyi bayttan silmiş ve başka hiçbir şeye dokunmamış oluruz. Bayta bilgiyi eklemek için ya toplama kullanırız, ya da makine dilinde toplamanın amcaoğlu olan ORA komutunu kullanırız. Boş olan noktalar üzerine yapılacak bir toplama ve ORA komutu aynı sonucu verecektir, fakat ORA komutu toplamadan çok daha hızlı işler. İşimiz bitince de baytı geri yazarız. Seçilen renge göre bileşik baytın değerini hesaplamaksa makine dilinde tüm bu hesapları karıştıracak. Bu yüzden formülleri kullanmak yerine daha hızlı çalışacak olan sağa-sola kaydırma ve tablodan okuma metodlarını kullanacağız. Bu yüzden renk konusunu formüle etmekle burada uğraşmayacağım. Şimdi asıl yapmamız gereken şey, bütün
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 17
bu formülleri makine dili bir programda uygulamaya sokabilmek. Tabii ki pek de kolay bir iş olmayacak, ama birbiriyle çarpılan değerlerin birinin sabit olması işlerimizi inanılmaz derecede kolaylaştıracak. Rutinin en başında kullanıcının verdiği X,
Y ve renk değerlerini alıyoruz. Eğer X, 0 ile 160; Y, 0 ile 200 ve renk 0 ile 2 arasında değilse hemen ILLEGAL QUANTITY ERROR verdiriyoruz. Tüm değerler izin verilen sınırlardaysa formülümüzü uygulamaya başlıyoruz: İlk iş olarak Y'nin sekizde biriyle 320'yi çarpmalıyız, Y'yi sekize bölmek çok kolay, Y koordinatını akümülatöre aldıktan sonra üç kere LSR kullanırsınız, olur biter. Asıl zor kısmı bu sayıyı 320 ile çarpmak. İlk olarak 320'yi çarpanlarına ayırmalıyız: 320 = 64 * 5
128 | 32 | 16 8 4 | 2 1
128 Ml
1 |
5s
Şekil 2 Bir bayt'ta bulunan değerin her noktayı nasıl kontrol edeceğini burada
görebilirsiniz.
Şimdi yapmanız gereken şey sonuç olacak adresi tutacak bayt çiftini ayarlamamız gerekli. Bellekte ardışık iki adres seçin ($0000-$00FF arasında) ve bunları sıfırlayın, Y/8'i buraya yazın ve iki kere sola kaydırın. Sola kaydırmak iki ile çarpmak anlamına geldiği için sayıyı dörtle çarpmış olduk şimdiden,
Daha sonra A'da bulunan Y/8'i bu iki bayta ekleyin: CLC ADC AD STA AD LDA 0 ADC STA İkinci toplama size anlamsız gelebilir, ama C bayrağının değerini de A + 1'e eklediğiniz için hayati önemi vardır. Bundan sonrası çocuk oyuncağı. İki baytlık bir alanı tam altı kere sola kaydırmak işi halledecektir: ASL AD ROL AD+1 ASL AD ROL AD+1 «4 kere daha... Buradaki ASL AD komutuyla AD adresini sola kaydırıp ilk bitini sıfır yapıyoruz, ve ROL AD+1 ile de sola kaydırıp ilk bitini AD'nın kaydırılmadan önceki son bitine eşitliyoruz. Bir de bu değere Y'nin ilk üç bitini eklersek (Y AND 7'yi bu yüzden tercih etmiştim) AdresY kısmı tamamlanmış olacak, Y koordinatını akümülatöre alın, AND $7 komutuyla ilk üç bitini alırız, ve deminki ADC komutlarıyla adrese bu değeri ekleriz. İnanılmaz derecede kolay oluyor, değil mi? Şimdi de adresX'i hesaplayıp AdresY'ye ekleyelim. X/4 için X koordinatını içeren akümülatörü toplam iki kere sağa kaydırmalıyız. Daha sonra da bunu 8'le çarpmak için üç kere sola kaydırmalıyız. Toplam olarak