Bu sayfadaki yazılar
Sayfanın metni
Sayfa 36
10 FOR R-0 TO 7:POKE 65535,2.R: NEXT:GOTO 10
Yukarıdaki program $FFFF adresinde yer alan baytın bitlerini sırasıyla yakarak sola kayan ince şeritler oluşturur. Program, sizin de sprite kullanmanıza izin verebiliyor. İsterseniz şu satırları girin bir:
POKE 53248,100:POKE 53249,100 POKE 53269,1:POKE 2040,0
Nasıl, 17. sprite'ınız da garip garip sırıtıyor ortalıkta, değil mi?
Aslında programın kullanımıyla ilgili söyleyebileceğim başka bir şey kalmadı. MDE ve BDE yardımıyla BORDER ve BORDER.DEMO programlarını yazın ve çalıştırın. BORDER.DEMO yardımıyla BASIC'ten bu programa neler yaptırabileceğinizi öğrenebilirsiniz. Canınız sıkıldığı zaman programı RUN/STOP tuşuyla durdurun ve SYS 49664 komutunu girerek devreden çıkartın. 500. satır numarasından başlayan alt program, A$ gibi bir değişkenin içeriğini yazı alanına nasıl yerleştireceğinizi gösteren bir örnektir. Kendi programlarınızda burayı olduğu gibi kullanabilirsiniz. Yalnız dikkat, program sadece harfler, sayılar ve basit işaretlerle başa çıkabilir. Eğer DATA satırları yardımıyla harf yazdırmak niyetindeyseniz mesajı ekranın sol üst köşesinden başlayacak şekilde yazın ve $0400-$0418 (1024-1048) arası bellek alanının içeriklerini bir yere not edin. Bu sayıları programınızda olduğu gibi kullanabilirsiniz. Eğer kaset kullanıcısıysanız, 10. satırda yer alan LOAD komutunu tamamen silin ve makine dili programını kendiniz yükleyin. Makine dili kısım belleğe yüklendikten sonra BASIC program LOAD komutu olmadan da çalışır.
Sıra Makine Dili Açıklamalarda
Program, tüm makine dili programları gibi $C000'dan başlıyor. İntrolar yazı dizisini izleyen herkes bilir; interrupt kullanan bir program yaratmanın ilk adımı interrupt vektörlerini, raster interrupt'ının başlangıç satırını ve CIA interrupt'larını gerekli sayılarla ayarlayıp, VIC'e Raster interrupt yapmasını söylemektir. Bu işi yapmak için $C000-$C02B arasında yer alan rutini kullanıyoruz. İlk olarak BORDER programını yazın, daha sonra bir monitör programıyla size söylediğim adresleri disassemble edin. Sonra yazıyı okurken bu programı izleyin. Karışık gibi duruyor, ama emin olun bu sayede programı daha iyi anlayacaksınız. İlk olarak $C000 adresinde, CIA'i ayarlıyoruz ($DC0E). $C006 adresinde yer alan dört komut yardımıyla $0314-$0315 adreslerini $C030'u gösterecek şekilde ayarlıyoruz. Bu sayede interrupt rutininin $C030'da yer aldığını bilgisayara bildiriyoruz. Bundan sonra yer alan iki komut, elektron $F9 (249.) satıra geldiği zaman $C030'a sıçranmasını sağlayacak raster interrupt'ı da gerekli şekilde ayarladıktan sonra (bak. MAKİNE DİLİNİN PÜF NOKTALARI, Konu: RASTER INTERRUPT) standart işimiz bitiyor. Artık tek yapmamız gereken şey, border açıldığında şeritler halinde kötü görüntüye yol açabilecek $3FFF ve $FFFF adreslerini sıfırlamak, interrupt'a izin vermek ve BASIC'e geri dönmek. Artık yüzde otuz yavaşlamış, fakat alt ve üst ekran açık bir bilgisayarınız var. Kolay gelsin. Tabii ki sizi bu kadar kolay atlatamam. Artık kurtuluş yok. Asıl rutini ayrıntılarıyla anlatmak zorundayım. Neyse ki kolay bir rutin. Geldik $C030'a. En iyisi rutin kendi kendini anlatsın size: “Burası Raster Satırı $F9. Yani ekranın kapandığı yer. İlk olarak Commodore'u dolandırıp ekranın alt ve üstünü açmalıyım. Yani görünebilen ekranı 24 satır olarak tanımlayacağım. Ama önce VIC'e interrupt yapıldığını bildireyim: INC $D019. Şimdi vereceğiz ve Commodore border'ları açacak. “Programcının ekranda sekiz sprite'ı da kullanabilmesini istiyorum. Bu yüzden sprite datalarını değiştirmeden önce eski dataları bir yerlere koyayım. Bu sayede ekran görüntüsü başlamadan hemen önce bu değerleri geri yazabileceğim. Programcının sprite'ları da yukarıda ve aşağıda 16 sprite gösterilmemiş gibi görünmeye devam edebilecekler. İlk olarak $D015'in değerini (programcının açık olan sprite'larını) $C1EE'ye kovalıyorum. Abzürd sprite'lar görünmesin diye $D015'e de 0 koyuyorum (meali: Sprite'lar kapalı!). Renkleri de kurtarmalıyım, yani $D027-$D02E gider $C1E4'e. Sonra da koordinatlar saklanmalı: $D000-$D010, $C1FF'e kopyalanmalı. “Sprite'ları kurtardık, şimdi de yeni sprite datalarını ayarlayalım: Bütün Y koordinatlarını 1 yapalım ilk olarak. Bu sayede $0101 (257.) raster satırında sekiz tane sprite olacağını bilgisayara söylüyorum. Bitişik sekiz sprite'ın da ekranın ortasında yer almasını sağlayacak X koordinatlarını da $D002, vb. adreslerine yazdıktan sonra son sprite'ın MSB'sini 1 yapıyorum (Ne yapalım, x koordinatı $0100'e denk geliyor. Ben de $D010'a yazdım). Sprite'lar $E000'ın altında duruyor. Bu durumda yapılacak tek şey $DD00'a yazmaktır. Ben de öyle yapıyorum. “Renkleri de unutmamalıyız. Alt tarafın rengini alıyorum ve $D027-$D02E'ye bu rengi yazıyorum. Bir de sprite'ların grafik datalarının $E000'dan başlamaları gerekiyor. N'apalım, ben de $C7F8'i 8580 yapıyorum. $C08B'ye bakınca bu değer gibi duruyor, ama dikkatli bakınca. Y sıfır olduğunda bu değerin de olduğunu hemen fark edebilirsiniz. Bunun sebebini iki soruya cevap vererek açıklamalıyım: *1) Niçin $C7F8? Çünkü, sprite'ların grafik dataları aktif olan bank'in karakter ekranı sonunda yer alır. $DD00'a 0 yazınca $C000-$FFFF arası aktif bank oldu. Bu bank'in karakter ekranı da $0400 bayt ileriden başlar ($C400). Bu ekranın sonundaki sprite alanı da bank'in başından $07F8 baytı ileriden başlar. Bu da bizim $C7F8'e denk.
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 37
geliyor. Diğer sprite'ların datalarını da sırasıyla $C7F9, $C7FA, vb.'ne yazacağım: “2) Niçin? İlk olarak grafik datalarının bank başından ne kadar ileride olduğuna bakarız: $B000-$C000 = $2000. Bunun 64'de birine bakalım ne çıkacak: $2000/$40 = $80! Ne ilginç. Bizim $80 buradan geliyormuş demek! “Hadi bakalım yola devam edelim. Şimdiye kadar neleri ayarladık? X, Y koordinatları tamam. Renkler tamam. Grafik datalarının yeri tamam. Evet, sprite'ları bitirdik. Bir de gösterdik miydi bitecek işimiz. Hadi yazalım $D015'e. Şimdi elektron ekranın üstüne çıkana kadar sabırlı sabırlı beklemeliyim. $D011'de bir yerlerde elektronun nerede olduğunu da öğrenebilirsin demişlerdi bana. Son biti miymiş, neymiş? En iyisi son bit temizlenene kadar bekleyeyim de göreyim. (BMI, son bit 1 olduğu sürece dallanır). Ne güzel, ekranın tepesine vardım. Şimdi yeni Y koordinatlarını gireyim bakalım: Y'ler 10 olsun! “Renkleri $C1E0'dan alıp yerine yazdıktan sonra bir tek işim kalıyor: Grafik datalarını $E200'dan alınacak şekilde ayarlamak. Sprite'lar gerekli yerde görünürler artık. “Son işim ekranın başından biraz önceye kadar beklemek artık. Ekrana girmeden hemen önce eski sprite verilerini de yerleştiririm, bank'i düzeltirim ve $EA31'e sıçrayarak kontrolü Commodore'a geri veririm. “Ben bu işi saniyede 20 kere yapıyorum. Ağır iş yaptığını söyleyenlere duyurulur. Bu arada normal BASIC zamanının yüzde 30-yüzde 50 arası bir miktarını çalıyorum, ama o bunu kaldırabilir. Bir tek KERNAL beni çekemiyor. Program yüklemeye kalktığında beni görürse intihar ediyor. Tabii ki beni de birlikte götürüyor. Lütfen bu fırsatı ona vermeyin. $C200'ı kullanarak beni bir süre için kapatabilirsiniz. $C000'la yükleme sonrası geri açarsanız sevinirim. Beni kullandığınız için teşekkürler. Artık sözü babama bırakıyorum.” Sağ ol, programcık. Geri kalan birkaç rutini açıklamam gerekiyordu benim de. İlk olarak $C100'da yer alan basit bellek doldurma rutinini anlatayım. $FB-$FC'yi $E000'ı gösterecek şekilde ayarlıyorum, bu adresi indeksli şekilde 255 kere temizletiyorum. Böylece $E000-$E0FF arasını sıfırlamış oluyoruz. Şimdi $FC'yi bir artırmalı ve değeri #$E4 olana kadar temizleme işlemine devam etmeliyiz. Bu sayede $E000-$E3FF arasını temizlemiş oluruz. Bu rutincik de böylece aradan çıkar. Programın can alıcı rutinlerinden birine geldi sıra. Yani bir karakter dizisinin içinde yazan yazıyı grafik datası olarak sprite'lara yerleştirme rutini. Bu rutin karakter ROM'una erişirken ortalığı karıştırdığı için başlamadan hemen önce kullanıyor. Bu yüzden border açıkken kullanılırsa bir-iki ekran taraması süresince ortalığı karıştırabiliyor. Hemen sonra $01'e yazarak $D000'da karakter ROM'unu bulabilmeyi garantiliyoruz. Bundan sonra yaptığımız işlemler biraz karışık gelebilir size (en azından bana öyle geliyor). Burada karşılaşacağımız en büyük problem, sprite'ların grafik datalarının garip dizilişi. Rutinde uzunluk ve hız dengesini kurmak için çok uğraştım. Eğer her şeyi tablolara yerleştirmeye kalksaydım, bu rutinin en az 5-7 katı hızlı bir rutin ortaya çıkabilirdi, ama rutin de $C600 sınırlarına dayanırdı herhalde. Bu yüzden sadece n'inci (n = 0..23) karakterin grafik datasının ilk baytını hangi adrese yerleştireceğimi tutan bir tablo yaptım. Bu tablo 24 bayttan oluşuyor (oldukça kısa yani). Bunun yanında, sırtımızdan da ağır bir yükü kaldırıyor. Bu rutini alta ya da üste yazı yazarken kullanmayı düşünüyoruz. Bu yüzden belli adresler ya $E000 ve $E100 (alt yazı) ya da $E200 ve $E300 (üst yazı) değeriyle başlıyor işe. Bu değerleri $C180 ve $C18C'deki rutinler ayarlıyor. Sizin şu anda bakmakta olduğunuz program üst tarafı değiştirmek için ayarlanmış olan $E2 ve $E3 değerlerini içeriyor. Şimdi rutini yavaşça ve dikkatlice inceleyelim: