C64 için Püf Noktaları

Hepinize merhaba, Commodore programcıları. Eğer yazımızı dikkatle takip ediyorsanız, 59. 60. sayılarda, döküm ekinde yayınlanması gereken programlarımızın doğru sırada olmadığını farketmişsinizdir. Makine dilinin püf noktaları yazıları, dergi çıkmadan çok önce yazıldığı için aylarda meydana gelen bu ufak(!) hatayı anlayışla ; karşılayacağınıza İnanıyoruz. Geçen sayıda hazır olmayan İntromuzu gerekiyordu, fakat onun yerine iki sayı önce yayınlanması gereken yıldız kaydırma rutini yayınlanmıştı. Programlarda olan bu kaymayı telafi etmek için, bu sayıda İlk İntronuzun kullanılabilir olan halini yayınlıyoruz.

Şimdiye kadar, intorlarda hep intterrupt'rutinler kullanıyorduk. İnterrupt olmayan kısmı ise: Döngü Jmp Döngü komutuyla sonsuz döngülere sokuyorduk. Bunun yararını, İntro çalışırken devamlı olarak boşluk Tuşu kontrolü yapma ihtiyacı doğduğunda görüyoruz. İnterrupt'ların programınızı serbest bıraktığı.her anda boşluk tuşu edildiği için, her ekran taramasında yüzlerce kez tuş takımı taranır. Herhangi bir insan, bir tuşa bastıktan sonra, parmağını mikrosaniyelerle ölçülebilecek bir süratle geri çekemeyeceğine göre de basılan bir tuşun gözden kaçması olanaksızdır. Bu kadar hikayeden sonra hâlâ uyanıksanız bu işin nasıl yapılacağını anlatayım size. Şimdiye kadar kullandığımız tüm interrupt rutinlerin başında $0314-15, $DO12 gibi adresleri ayarlayan kısmın sonuna koyduğumuz

Sei :
Jsr $EDA3
Jsr $SFDA5
Jsr

Eğer intro'nuzu yalnızca bir gösteri amacıyla düzenlediyseniz, bu aşamadan sonra yapmanız gereken, bir RTS komutuyla BASIC'e dönmektir. Fakat daha profesyonel kulanımlar düşünüyorsanız, bir miktar bilgi daha yüklemeniz gerekecek. Bir program çalışmadan önce kendi intronuzu çalıştırmak istiyorsanız, İki seçeneğiniz var. İntronuzu programın başına veya sonuna ekleyebilirsiniz.

Döngü Lda $DCO1 komutun yerine, boşluk tuşunu kontrol etmeye yarayan şu satırları koyun:

Döngü Lda $DCO1
'Cmp # $EF
Bne Döngü

İntromuzu, başlangıç adresi olan $0900'den İtibaren izleyecek olursanız, $0CB3 civarında bu program parçacığıyla karşılaşırsınız. İyi de boşluk tuşuna basıldığında ne Akla ilk gelen çözüm, bir kullanarak tüm interruptları kapattıktan sonra, İnterrupt vektörlerini ($80314-$0315) SEA31'i gösterecek şekilde ayarladıktan sonra bir CLI vererek intronun çalışmasını bitirmek olabilir. Kulağa hoş gelse de ne yazık ki böyle bir işe kalkıştığınızda, bilgisayarınızı kilitlermekten daha iyi bir sonuç alamazsınız. Bunun sebebi, $DCOD-$DCOE, $D012 ve adreslerinin değerlerini değiştirmiş olmanız. Tüm bu değiştirdiklerinizi tek tek düzeltmek belki bir çözüm olabilir, fakat bu işi bizim için yapacak KERNAL dururken, bütün adreslerle tek tek uğraşmak pek de akıllıca olmaz sanırım. Şimdi belirteceğim üç KERNAL rutinine ardışık olarak sıçrarsanız, bellekte bulunan bütün vektörler normal değerlerini alırlar, sprite'lar kapatılır, vo. Yani C 64'ünüz ilk açılış haline döner, Tabii ki programlarınıza hiç bir şey yapmadan. Bü-// tün bu işleri yapan üç JSR'nin kullanımı şöyledir:

Eğer programın sonuna İntro eklerseniz, program çalışmadan önce, sizin İntro'nuza bir JSSR yapmanız gerekli. İntronun İşi bittikten sonra, hiç bir şeye dokunmadan asıl programı çalıştırabilirsiniz. Fakat burada büyük bir problem söz konusu oluyor. Programların hepsi aynı uzunlukta olmadığı İçin, İntronuzun bellekte yerleşeceği alan her proğram İçin farklı olacaktır. Yer değiştirebilir programlarla intro yazmak imkansız olduğu için her program için | ayrı intro yazmanız gerekir. Bunun yanında hiç de ATA e beklemediğiniz bazı sorunlarla da karşılaşabilirsiniz. (Programın, bitiş adresini kontrol etmesi gibi). Bu kadar problemle karşılaşmaktansa, diğer seçe-

'. MR neğimizi bir kontrol etsek daha İyi olur sanırım, Eğer 19 programın başına İntro eklemeye karar verirsek başka problemlerle karşılaşırız. Her şeyden önce BASIC RAM'i $0800'den başlar ve hemen öncesinde de ($0400-$0800) erkam RAM'i bulunur. Daha da kötüsü, $0000-$0400 arası da sistem vektörlerinin ve değişkenliklerinin bulunduğu RAM'dir. Yani BASIC RAM'inden öncesine program yerleştiremeyiz. Ozaman ne yapacağız peki? Gene İki çözüm var bu duruma. İlk denememizde, BASIC RAM başlangıcını İnfromuzdan sonraya alırız. Fakat ne yazık ki bu çözüm sadece BASİC programların (kısa olanların) başına intro atmak için geçerli olur. İkinci çözüm İse, $0801'den itibaren intronun arkasına da asıl programı yerleştirmek (BASIC'ten SYS İle çalışacak şekilde), boşluk tuşuna basılınca da asıl programı $0801”e taşıyıp çalıştırmaktır. Bu sayede, çalışması bittikten sonra inironuzdan geriye tek bir bayt bile kalmayacaktır. Asıl programı geriye taşıyacak olan rutine, Yer değiştirici (relocator) rutinleri adı verilir. Bu rutinler, belli transferleri yerine getirmek için yapılmışlırdır, ve ROM'ların altını da transfer edebilmektedirler. Bir veri bloğunu birkaç bayt sonrasına taşımak için seçilecek yol, önce lik baytı hedefe taşımak ve sonraki bavtlar için de bu İşlemi degil mi? HAYIR. Bu sistem yalnızca kaynak ve hedef çakışmazsa geçerli olur. Ama bir veri bloğunu yalnızca bir bayt İleri almak İstersek, İlk işlem sonucu ikinci baytın değeri, ilkiyle aynı olur, sonra da bu baytı üçüncüye taşırız, ve verilerin sonuna kadar bu iş böyle devam eder. Sonuçta tüm bloğun aynı değeri alınmasını sağlamış olursunuz. Bundan kaçınmak için bloğu sondan başa doğru trasfer etmeniz -introda kullanacacığınız gibidataları geriye transfer edecekseniz, baştan sona doğru transfer yapmanız şarttır. İntrolardan sonra yapılan transferlerin uzunluğunu programlamalara göre ayarlamaktansa İntronun sonundan itibaren tüm belleği geriye transfer etmek daha kolay olur. Bunu yapmadan önce, Jransfer Sel Ldy # $00: Sty $01 komutlarıyla bütün KERNAL ve BASIC ROM'larını, GİÇ alanlarını kaldırır ve bilgisayarlarımızı 64 K RAM hale getiririz. Bu sayede, transferler sırasında ROM'ları değil de programları Yaşın. İyi de nasıl taşırız? Basit:

Taşı1 Lda TransBaşı, Y
Taşı2 Sta BasicBaşı, Y
Dey
Bne
(TransBaşı—intronun bitiş, programınızın
başlangıç adresi
Basic Başı — $800)

Bu kadarını tabi ki siz de biliyorsunuz. Bu rutin sayesinde bir blokluk bilgiyi $0800'e taşırız. Yeri gelmişken söyleyeyim, $0801'den başlayan proğramları TransBaşı - 1 adresine yükleyin ve Transbaşı adresinin değerini O'layın. Her neyse, transferimize devame delim. Bunun için de programın kendini değiştirmesi metodunu kullanıyoruz gene. İnc Taşı2-42 Inc Taşı1 42 taşınan dataların bloklarını birer arttırdık. Şimdi de bellek sonu konirolü yapılıyor. Bne Taşı Bu kadar basit olduğunu tahmin etmiyordunuz eminim. Sadece transfer bloğunun değerinin sıfır olup olmadığını kontrol ediyoruz. Eğer değeri sıfır olduysa, TransBaşı'dan SFFFF'e kadar transfer tamamlanmış demektir. Y'yi tekrar sıfırlamaya gerek yok, çünkü son İşlemden zaten sıfır olarak çıkmıştı. Eğer tüm bellek transfer edildiyse, yapacak pek bir İşimiz kalmadı demektir. Sadece Lda # $37 Sta $01 komutuyla ROM'lar geri alıp, Clı ile interrupfları açıp, Jsr Jmp SAZAE ile de RUN işlemini yerine getirmek asıl programı hatasız olarak çalıştırmak için yeterli olacaktır. Eğer program kendi sonunu kontrol ediyorsa ($2D veya $AE adresinden) bu değerleri de birkaç Lda ve Sta ile eski haline getirmek sizin için pek zor olmaz herhalde, Transfer label'ıyla başlayan programı, üç JSR'nin arkasında eklediniz mi? Peki neden çalışmadı sizce? Evet doğru bildiniz. Bu rutin, asıl programı $0800 adresinden başlayacak şekilde geri Taşıyor ve bu arada da kendi üzerine de bol bol bay? yazarak sonunu hazırlıyor. Bunu engellemek için programı $0400'de çalışacak şekilde yazıp boş bir alana transfer edin: Trans1 Lda BoşAlan, Y Sta $0400, Y Jmp $0400 Üç JSR'nin arkasına eklemeniz gereken program: cık bu. Buradaki BoşAlan Transfer rutinini koyduğunuz boş alanın adresidir. Bu sayede Transfer, taşı-.

dığı dataları kendi üzerine yazmaz. Şimdi de sıra bu İntroya nasıl program ekleyeceğinizi görmeye geldi. İlk olarak intronuzu belleğe yükleyin ve Kayan yazılarla, Ekran harflerini bir monitör program yardımıyla değiştirin. Kayan yazılar $2800 adresinden başlıyor. Ekrandaki yazılar da adresinde. Yalnız DİKKAT!!! Ekran yazılarının ilk dört satırını kullanmayın. Bundan sonra şu komutları BASIC'de verin: Poke 43,1 Poke 44,44 Poke 11264, O Şimdi de asıl program LOAD “isim”, 8 komufuyla yükleyebilirsiniz. Sakın kullanmayın, programı üzerine yüklersiniz. Yükledikten sonra dö: Poke 43,1 Poke 44,8 komutlarını verip, SAVE “yeni isim”, 8, 1 komutuyla proğramınızı diskete kaydedin. Eğer SAVE tunuzdan sonra “OUT OF MEMORY ERROR” hata mesajıyla karşılaşıyorsanız, makine dilinde bir program kaydedici yapıp, kayıttan hemen önce $01'e $36 değerini vermeniz gerekir. Bu değeri $01'e verdiğinizde, yalnızca $A000-$BFFF arasında bulunan ROM ortadan kalkar ve $E000-$FFFF arasındaki KERNAL ROM kullanılabilir. Çok uzun datalarla uğraşmamanız için Program Döküm Eki'ne girecek olan intromuzu kısalttım. Bunu kullanmak için önce programı yükleyin, sonra da boş bir disket yerleştirin drive'ınıza, Daha sonra programı çalıştırın. Program önce kendini açacak, sonra da kullanılabilir halini diske kaydedecektir. Eğer makine dilinde SAVE işlemini nasıl yapacağınızı merak ediyorsanız, bu-İşlemden sonra $2C00 adresine bakarak SAVE rutinini görebilirsiniz. Gelecek aya kadar hoşçakalın.

RUBGOBUR