Bu sayfadaki yazılar
Sayfanın metni
Sayfa 16
Herkese merhaba. Yeni bir bölümle daha karşınızdayız. Umarım işinize yarar. Bu bölümde sizi uzun uzun bazı rutinleri yazmaktan kurtaracak ROM adresleri ve bunlarla ilgili kısa kısa rutinler vereceğim.
C64 mühendisleri - assemblerci olanlar - bizler için zamanında birçok hazır rutin hazırlamış olup bize de bunları kullanmak düşer. İlk adresimiz ekran silme işini yerine getiren $E544.
ADRES: $E544 GÖREVİ: EKRANI SİLER KLAVYE KARŞILIĞI: SHIFT+CLR/HOME
Aslında bu adres C64'ün ilk açılışta bazı işlemleri yaparken uğradığı $E518 adresindeki rutinin bir parçası olup, "THE ANATOMY OF A C64" kitabında "CLEAR SCREEN" olarak tanımlanmıştır. Bu adres sizi bilmem kaç byte'lık bir ekran silme rutini yazmaktan kurtaracaktır.
Aşağıda bu adresi kullanmadan yapılan bir ekran silme rutini bulunmaktadır. C64'ün ekran belleği 1 KB olup 1024 ($0400) adresinden başlar ve 1000 byte uzunluğundadır. Fakat bilgisayar dilinde 1 KB 1024 byte demektir. Dolayısıyla elimizde fazladan bir 24 byte vardır ve bu 24 byte'ın son 8 byte'ı sprite pointer'ı olarak kullanılır. Ekranı silmek demek bu adreslere ASCII kodu 32 ($20) olan "BOŞLUK" karakterini yazmak demektir. Çok basit bir şekilde bir adet LDA, 1000 adet STA ve son olarak da RTS komutunu yazarsanız ekranınız çok çabuk temizlenecektir.
LDA #$20 STA $0400 STA $0401 ::: ::::: STA $07E6 STA $07E7 RTS
Gördüğünüz gibi arka arkaya 1002 adet komut yazarak ekranı sildik. Çok kolaymış değil mi? Evet ama maalesef çok uzun. Bu arada bir not düşelim, bu şekilde yazılan programlar daha hızlı çalışır ama hafızayı da yer bitirir. Nitekim 1K'lık bir bölgeyi temizlemek için 3003 byte uzunluğunda bir program yazdık. Bence hızı bir tarafa bırakıp birazcık hafızadan tasarruf edelim ne dersiniz?
LDX #$00 LDA #$20 TEKRAR STA $0400,X STA $0500,X STA $0600,X STA $0700,X INX BNE TEKRAR RTS
İşte birazcık tasarruf yaptık. Sadece 3003 byte'lık ekran silme rutini birdenbire 20 byte'a düştü. Şimdi bu rutin çok mu yavaş çalışacak? Hayır. Aslında aradaki hızı anlamak imkansızdır. Çünkü zaten makine dili komutlarının yerine getirilmesi için birkaç mikrosaniye yeterlidir. Yani siz C64'te 2 mikrosaniye süren bir komuttan 500.000 tanesini arka arkaya çalıştırırsanız sadece 1 saniye zaman harcamış olursunuz. Dolayısıyla yukarıdaki iki rutinin süreleri size aynı gelecektir.
İkinci örneğimizde aslında 1000 byte değil 1024 byte temizliyoruz. 24 byte fazla temizlik yapmanın duruma göre şöyle bir sakıncası vardır. Eğer programınızda sprite kullandıktan sonra yukarıdaki rutinle ekranı silerseniz sprite pointer'larınız bozulacaktır ve ekranda saçma sapan şekle sahip sprite'lar olacaktır. Bunu önlemenin yolu ise yukarıdaki rutinde INX komutundan sonra CPX #$FA komutu kullanmak ve STA komutlarındaki adresleri ayarlamaktır.
Neyse biz tasarruf etmeye devam edelim ve en iyisi yukarıdaki rutinlere hiç bulaşmadan programımızın başlangıcında bir JSR komutuyla ekran silme işini sessizce halledelim.
JSR $E544
İşte bu kadar. Sadece 3 byte ile koskoca ekranı temizledik, üstelik sprite pointer'larımız da bozulmadı. Peki bu nasıl oluyor? C64 aslında ekranı arka arkaya 1000 byte şeklinde temizlemiyor. Ekran silme işi satır satır yapılıyor. Eğer $E544'teki rutini incelerseniz $E55E'den itibaren aşağıdaki komutları görebilirsiniz.
E55E LDX #$18 E560 JSR $E9FF E563 DEX E564 BPL $E560 .... ... .....
İşte asıl ekran silme işi burada yapılıyor. O zaman niçin $E55E yerine $E544 adresini kullanıyoruz? İşin aslı şu: Eğer siz programınızda $D018 adresini kullanarak ekran belleğinin yerini değiştirdiyseniz - Ekran belleği 1K'lık adımlarla o anki VIC BANK içinde 16 farklı yerde olabilir- ve bu yeni ekran adresini 256'ya böldükten sonra bulduğunuz değeri $0288 adresine yazarak değişikliği KERNAL'in ekran editörüne bildirmeniz gerekmektedir. Eğer BANK değiştirmişseniz bank başlangıç adresini de eklemeniz gerekmektedir. $E544 adresi işte bu değişikliklere göre ekran adresini hesaplayıp silme işini yapacaktır. Alışkanlık olduğu için her zaman $E544 kullanılır. Aslında ekran silme işini $E536 adresini kullanarak da yapabilirsiniz. Fakat önce bir LDA komutu kullanarak ekran silindikten sonra ekrana yazılacak karakterlerin rengini değiştirme işlemini de yapmış olacaksınız.
Eğer özetleyecek olursak elimizde ekran silmek için 3 adres bulunmaktadır.
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 17
1 - $E536: Bu adrese gitmeden önce bir LDA komutuyla yazı rengini değiştirerek ekran silinir.
LDA #$01 JSR $E536 ... .....
Burada LDA komutuyla, ekran silindikten sonra yazılar beyaz olarak ekrana yazılır. Bu işlemi eğer BASIC ile yapmak isterseniz aşağıdaki komutları kullanmanız gerekecektir.
POKE 780,RENKKODU : SYS 58678
2 - $E544: Eğer bu adresi kullanırsanız o anki yazı rengi korunur ve ekran silindikten sonraki yazılacak yazıların rengi değişmez. Bu adresin BASIC'teki karşılığı ise SYS 58692'dir. 3 - $E55E: Eğer yazdığınız programda ekran belleğinin yerini ve/veya bank değiştirmediyseniz ve yazı rengi sizin için önemli değilse bu adresi güvenle kullanabilirsiniz. Bu adres daha önce bahsettiğimiz satır satır ekran silme işini yapan adrestir. BASIC'ten SYS 58718 komutuyla aynı işi yaparsınız.
Sırada ikinci ROM adresimiz var.
ADRES: $E566 GÖREVİ: KURSÖRÜ EKRANIN SOL ÜST KÖŞESİNE YERLEŞTİRİR KLAVYE KARŞILIĞI: CLR/HOME
Fazla teknik bilgiye gerek yok. Ekranı silmeden kursör sol üst köşeye gider. Aslında $E55E adresindeki rutinin devamında yer alır. Daha önceki verdiğimiz adreslerde ekran silindikten sonra kursör sol üst köşeye gitmektedir. Bu adresi de BASIC'ten SYS 58726 komutuyla kullanabilirsiniz.
ADRES: $E9FF GÖREVİ: EKRANDAKİ BİR YAZI SATIRINI SİLER
İşte geldik güzel bir adrese... Bu adres gerçekten güzeldir çünkü X registerini kullanarak istediğiniz bir ekran satırını silebilirsiniz. Fakat bir şeye dikkat etmeniz gerekmektedir. Bu rutinde ilk ekran satırı 1'den değil 0'dan başlamaktadır. Dolayısıyla sizin ekranda 1, 2, 3 diye saydığınız satırlar artık 0, 1, 2 olacaktır. Bu arada ufak bir hatırlatma yapayım. Derginin bu sayısında başladığımız C64'e yeni komutlar ekleme konusundaki CLS komutu, komuttan sonraki parametrenin olup olmamasına göre $E544 veya $E9FF adresini kullanmaktadır.
Daha önce ekranın aslında satır satır silindiğinden bahsetmiştim. Bu silme işi yukarıdan aşağıya doğru değil, aşağıdan yukarıya doğrudur. Bu küçük bilgiden sonra bir iki örnek verelim.
LDX #$0C JSR $E9FF ... .....
İlk örneğimizde ekranın tam ortasındaki yazı satırını silmiş olduk.
LDX #$14 CLEAR JSR $E9FF DEX CPX #$08 BNE CLEAR ... .....
Bu örnekte ise ekranda 8 ile 20. satırlar arasını sildik. Ve son örnek olarak...
LDX #$10 JSR $E9FF DEX BPL CLEAR ... .....
Son örnekte ise ekranın üstten 17 satırını siliyoruz. Eğer en üstten itibaren olacak şekilde birkaç satır silecekseniz o zaman sadece aşağıdaki komutlar işinizi görecektir.
LDX SATIRNO JSR $E560 ... .....
Yukarıdaki adresleri BASIC'te şu şekilde kullanabilirsiniz: 1 - Sadece bir satır silmek için:
POKE 781,SATIRNO : SYS 59903
2 - En üstten itibaren birkaç satır silmek için:
POKE 781,SATIRNO : SYS 58720
ADRES: $EEB3 GÖREVİ: 1 MİLİSANİYE GECİKME RUTİNİ
Bu adreste 1 milisaniye gecikme rutini bulunmaktadır. Eğer program içinde kullanmak isterseniz X veya Y registerini kullanmalısınız. Registere girdiğiniz sayı kadar milisaniye gecikme sağlarsınız. En fazla gecikme 0 değeri ile sağlanır ve 256 milisaniyedir. Daha uzun süreli bir gecikme elde etmek isterseniz iç içe döngü kullanmanız gereklidir. 7D3 demo party'de 256 byte on the fly olarak yaptığım "ZOOMER" programında bu adresi kullanarak 1/2 saniyelik bir gecikme kullandım. Aşağıdaki örnekte yaklaşık olarak 1 saniyelik gecikme elde edebilirsiniz. Eğer Y registeri de 0 olursa gecikme yaklaşık 65,5 saniye olur.
LDY #$04 LDX #$00 DELAY JSR $EEB3 DEX BNE DELAY DEY BNE DELAY ... .....
ADRES: $AB1E GÖREVİ: HAFIZADAKİ BİR YAZIYI EKRANA YAZAR
Bu adresimiz ise hafızada ASCII kodlarıyla bulunan bir yazıyı ekrana basar. En fazla 255 byte uzunluğundaki bir yazıyı ekrana basabilirsiniz. Bu rutini kullanırken dikkat etmeniz gereken üç konu var. Birincisi yazınız 255 byte'ı geçmemelidir, ikincisi C64'ün yazının bittiğini anlaması için son byte'ın değeri 0 olmalıdır, sonuncusu ise hafızadaki yazının bulunduğu adresin LOW BYTE'ı Akü'ye, HIGH BYTE'ı ise Y registerine yerleştirilmelidir. İsterseniz yazınızın rengini, kursör pozisyonunu vs. bile değiştirebilirsiniz.