Makine Dilinin Püf Noktaları

Vedat Hallaç kaç aydır “Bana yazın. Sorununuz olursa, ne kadar basit olursa olsun. Çekinmeyin. Cevaplamaya diye diye dilimde tüy bitti, ama hiçbirinizi bana yazmaya ikna edemedim. Bu durumda iki ihtimal var: Ya hepiniz her şeyi en ince ayrıntısına kadar anlıyorsunuz, ya da yazdıklarımı bir tek ben okuyorum. Ben gene de ilk ihtimali göz önüne alarak, yazıda daha da ileri gitmeye karar verdim. Ama bu işi yaparken, bir de intro yapacağım. Daha doğrusu bu sefer introyu birlikte hazırlayacağız. “Bir intro hazırlamanın ilk ve en zor basamağı, kaba olarak nerede ne tür hareketler yapılacağına karar vermektir. Daha sonra bu hareketleri yaptıracak rutinleri düzgün bir şekilde ve en az belleği işgal edecek biçimde bir sıraya sokmamız gerekiyor.” diyebiliriz. Ama bu sefer her şeyi tasarlanmış bir intro yerine, “Şurada da şu işi yapalım.” diye diye, rutinleri kafadan atma yerlere çok da düzgün olmadan yerleştirerek gidelim. Biliyorum, bu söylediğim sistem şimdiye kadar söylediğim her şeyle çelişiyor. Ama, koşullar bu şekilde çalışmanızı gerektirebilir (Umarım gerekmez, çünkü bu şekilde bir intro bitirmek oldukça uzun zaman alır). Neyse. Sözü pek fazla uzatmadan intromuzu yapmaya girişelim. İntromuza ne koyacaksak koyalım, bir interrupt başlatma rutinine ihtiyacımız olacak. Bu yüzden yeterince geride olan $0900'e Tablo-1'de gördüğünüz standart programı yazarak ilk adımı atalım. Unutmayın, şu anda ne yapacağımıza karar vermediğimiz için $D012'ye verdiğimiz değerin bir anlamı yok. Yalnızca ilk interrupt parçacığını, $0900'e en yakın yuvarlak adres olan $0A00'a koymaya karar vermek oldukça yerinde olur. Çünkü, daha sonra $0900'de bulunan rutine sprite açtırma, grafik ekranına geçme, data taşıma gibi garip işler yaptırmaya karar verebiliriz. Rutinlerin neye benzediği ortaya çıktıkça, kısa bazı rutinlerle de $0A00'a kadar olan boşluğu doldurabiliriz. Şu ana kadar yaptıklarımız yeterince saçma geldi mi? Ne yazık ki çoğu programcı bu şekilde çalışır, ve programları genelde ilk denemede çalışmaz. Bu yüzden bu introyu yapmış stilimizi asla kendinize örnek almayın (Yani öğretmeninizin dediğini yapın, ama yaptığını yapmayın!). Şimdi ilk adımı attığımıza göre oturup düşünebiliriz (önce düşünüp sonra adımı atsaydık ya!!!). Ne yapsak hoş olur? Mesela bir kayan yazıyı yukarı aşağı oynatsak? Çok alanı kaplar ve o kadar da göz doldurucu değil! Ne yaparsak bu alanı doldururuz? Arkasına renkleri döşersek ta-

PÜF NOKTASI tabii ki. (Burada okuduklarınız, ne yapacağına karar veremeyen programcıların genelde düşündüğü şeylerin bir özetidir. Kendi kendilerine yaptıkları bu tartışma genelde bir-iki güne kadar uzayabilir.) Ama biz hem ekranı aşağı kaldırmayı, hem de renk dizmeyi bilmiyoruz ki. Şimdiye kadar anlattığım rutinler, bir raster satırında en fazla bir işlem yapabiliyordu. Aslında çok da zor değil hem ekranı aşağı kaydırıp hem de renk dizmek. Hatta DMA satırları ortadan kalktığı için tek zamanlamayla tüm satırların en başında işlem yapmanız garanti edilmiş durumdadır. Yani yapacağımız tek iş, ekranı bir satır aşağı kaydırmak, hemen sonra ekran rengini değiştirmek ve ekran kaydırabileceğimiz noktaya gelmeyi beklemek. Pek de zor gibi görünmüyor değil mi? Deneyin de görün ne kadar kolay olduğunu. Denemek gibi bir niyetiniz yoksa, Tablo-2'ye bir göz atarak ekranı istediğiniz kadar aşağı renkli olarak kaydıran rutinin kısalığını görün. Kısaca rutinin yaptığı işi anlatayım: İlk iki NOP komutunu kullanarak, tam ekranı kaydıracak noktada elektronu kontrol altına alıyoruz. Sonra ilk üç bitinde bulunan Y pozisyonunu bir aşağı alıyoruz. Tüm baytı değil, yalnızca ilk üç biti değiştirmeye çalıştığımız için sonucun ilk üç bitinden başka tüm bitlerini izole ediyoruz, ve bu bitleri, 25 satırlık karakter ekranını tanımlayacak bitlere ORA'lıyoruz. Bu sonucu $D011'e yazdığımızda, ekranın bir nokta aşağıda olduğunu sanıyor bilgisayarımız. Sonra ilk rengi alıp $D020 ve $D021 adreslerine (çerçeve ve ekran rengine) yazıyoruz. Y'yi 4'den geri saydırıp üç de NOP bekletince, elektron için gerekli zamanlamayı yapmış oluyoruz. Y'yi 4'den geri sayacağımızı ve üç NOP koyacağımızı nasıl mı buldum? Kolay. Önce Y'yi 0-8 arası bir değerden geri saydırdım ve hiç NOP kullanmadım. Olmadı tabii ki. Kafadan attığım (Tabii ki destekli attım. İlk değerin az, çok veya aşırı çok gelmiş olduğunu renklerden ve ekranın yamulmasından anlayabiliriz) ikinci bir değeri denedim, ve bu şekilde dört değerini buldum. Tabii ki tek başına dört işe yaramadı. Beş veya üç kullanınca da olmadığına göre, işimiz NOP'lara kaldı diye iki NOP attım. Neyse ki ilk denemede tuttu. Yoksa duruma göre iki NOP yerine bir BIT $EA kullanmam gerekecekti. Niye mi $EA? BIT komutunun kodunu $BA yaptığım zaman ikinci baytın da direkt olarak NOP olması için. BIT $00 kullanarak da zamanlama tutturulurdu, ama ilk baytı NOP yapıp bırakırsanız artan $00 baytını da NOP yapmanız gerekecekti.

Her neyse, bu kadar deneme yanılma yeter. Aslında tüm bu işlemleri deneme yanılmayla bulmak yerine komutların Cycle uzunluğundan da hesaplayabilirdik ama deneme yanılma metodu benim daha çok hoşuma gider. Satır sayısı olan X'i bir arttırdıktan sonra, değişken uzunluk olan (satırı yukarı-aşağı oynatacağımıza göre kayma miktarını sabitlememek iyi bir fikir olur sanırım) $FE'de bulunan değerle karşılaştırıyoruz, ve bu değere ulaşamadıysak satır kaydırma işine devam ediyoruz. Pek de zor değilmiş ha? Şimdi işin zor kısmına geldik. Yani kayan yazının arkasına renk koymaya. Burada yazılar olacağı için DMA satırları da olacak, ve zamanlamamızı sapıttırmak için hazır bekleyecekler. Ama saydırma metodunu kullanacağımız için bu zorluklar bize sökmez. Her şeyden önce tam satır başını yakalamamız, ve ilk üç bitini ayarlamamız gerekecek (Yazıları kaydıracaktık hatırlarsanız. Eğer $D016'yı şimdi değiştirmezsek, daha sonra araya onu da sokuşturmak için tüm zamanlamamızı çökertmemiz gerekebilir).

İlk satır DMA olduğu için, hiç bir işe girişmeden önce ekran ve çerçeve rengini değiştirmeliyiz. Zamanlama için Y'yi birden geriye saydırmak gerekiyor (Deneme yanılma olduğunu buradan da görebilirsiniz. Başka hangi aptal Y'yi birden geri saydırıp, sonra sıfır olmuş mu diye kontrol eder?). Bu yöntem bizim için Y'yi de sıfırlayacağı için, Y'yi 25

PÜF NOKTASI

AJASILDA

$DO20
STA Sİ
LDY 4805
STA

satır kullanmamızı programcık, ekran renklerini ve kayma miktarını istediğimiz yerde bir sayaç olarak kullanabiliriz. Daha sonra $0FFE adresinde bulunan değeri $D016'ya koyarak ekranın x pozisyonunu ayarlıyoruz. Bu adres de bir değişken olacağı için, bunu da aklınızda tutun (daha da iyisi bir yerlere yazın). Sonra geçen sayılarımızdan tanıdığımız saydırmalı renk koyma rutinine geliyoruz. Bu rutine girmeden önce sayaç olarak seçtiğimiz X'i sıfırlıyoruz. Daha sonra da, $0B90 adresindeki tabloda bulunan bekleme değerini Y'ye alıyoruz, ve gerekli miktarda bekliyoruz. Bu işleri yaptıktan sonra, renk tablosundan kayan yazı renklerini alıp, ekrana ve çerçeveye veriyoruz. Bu işlemi 16 raster satırı boyunca yaptıktan sonra, buradaki işimizi bitirip, ekranı renkli olarak kaydırmaya devam ediyoruz. Bu işleri yapan kısa programcığı Tablo-3'de bulabilirsiniz. Gördüğünüz gibi, sadece renk değiştirme rutini, ekranı kaydırırken renk değiştiren rutinden biraz daha uzun sürüyor. Sanırım DMA'larla uğraşmanın ne kadar belalı bir iş olduğunu yavaş yavaş anlıyorsunuzdur. Gelelim, kayan yazıdan sonra ekranı kaydıracak rutine. Ekranı yazıdan sonra da kaydırmamızın sebebi, tüm sinüsünü içeren bölgenin hemen altında ekran satırlarını sabitlemek. Bu sayede, en altta kalan iki-üç satıra da bir ufak efekt sokuşturabiliriz. Geriye kalan kısmı sabitleyecek olan rutini Tablo-4'de bulabilirsiniz. Bu programın başında