Makine Dilinin Püf Noktaları

Herkese merhaba. Hatırlayacağınız gibi geçen ay köşemizde uyduruk bir introya başlamıştım, ama programları döküm ekinde çıkmamıştı. Bu ayki derginin döküm ekinde geçen ayın programlarını bulabilirsiniz. Biliyorum, geçen ay bu sayıda introyu yapmaya devam edeceğimizi söylemiştim, ama Samsun'dan Bay Derya Kılıçlı'nın gönderdiği programları görünce bu isteğimden vazgeçtim. Derya Bey'in bana gönderdiği diskte dört adet introyla birlikte, tamamen intro teknikleriyle yapılmış bir oyun da bulunuyordu. Bu oyun oldukça ilgilimi çekti ve Derya Bey'in gönderdiği dokümanlarla birlikte incelendiğinde makine dilini geliştirmenizde oldukça yararı olacağını düşündüm. Program, yazarken canınızın çıkmasını engellemek için sıkıştırıldı. Bu sebeple incelemek için önce bir kez çalıştırmanız gerekli. Hiçbir koruma olmadığından dolayı RUN/STOP RESTORE tuşu kombinasyonuyla BASIC'e çıkıp, bir monitör programı aracılığıyla program üzerinde istediğiniz incelemeyi ve değişiklikleri yapabilirsiniz. Programı tekrar çalıştırmak için $2855

(10325) adresine sıçramanız yeterli. Oyunun asıl amacı, arabanızı 80 km boyunca engellerden kurtarabilmek. Bu yolla giderken karşınıza sizi öldürmek isteyen kayalar, zehirli bulutlar, zıplayan şeytanlar, kamyonlar ve ateş edebilen uçan daireler çıkacaktır. Ne yalan söyleyeyim, oldukça da zor bir oyun olmuş. Normal yollarla oyunu bitirmek hiç de kolay değil. Oyunun asıl adı “Springwood'dan Kaçış”. Bulunduğunuz yer, hepimizin yakından tanıdığı Freddy Krueger'in rüyalar alemi. Amacınız ise 80 km ilerde bulunan çıkışa, 1955 model Chevrolet'nizi kullanarak ulaşmak. Tabii Freddy'nin kabusları izin verirse...

Programından da Bahsedelim mi?

Oyun 7 adet interrupt rutininin birleşmesinden oluşmuş. Normal düzeyde ise program sonsuz döngüye giriyor. Yani tüm programın çalışması sadece interrupt'larla yapılmış. Neden olduğunu anlamadıysam da, Derya Bey bunu özellikle yaptığını söylemiş. Sanırım iyi bir nedeni vardır bunun için. Programın kullandığı bellek bölgeleri ise şöyle: $0900-$1000: Tüm Switch'ler, hesaplama ve zamanlama adresleri burada. Daha doğru bir tabirle değişkenler bölümü burası. Bazı önemli adresler ise şunlar: $09C8: Araba çarpışma açık/kapalı. $090B-$090C: Tüm zamanlama burada yapılıyor, 80 Km burada sayılıyor. $090A:$D01E: Register bilgisi burada. $0908: Ateş açık/kapalı. $3800-$3C00: Arka kayan dağ manzaralarının resim dataları burada saklanıyor. $3D00-$EE00: Yaratıkların X 255 ($D010 bitleri) tablosu. Yaratıkların X sinüs tablosu. $0A00: Kamyon, uçan daire sinüs tablosu. $1220: Girişteki intronun renk şeritleri. $1270: Renk şeritlerinin zamanlama baytları tablosu. Şimdi de oyunu oluşturan 7 interrupt rutini hakkında daha detaylı bilgi verelim: 1. Interrupt: #$90 raster satırında başlıyor ve $1153 adresinde bulunuyor. Bu rutinin işi arkaplan görüntüsünü kaydırmak. 2. Interrupt: #$01 raster satırında başlıyor ve $1192 adresinde bulunuyor. Alt yolun kaydırılması ve müziğin çalınması işlerini hallediyor. 3. Interrupt: #$30 raster satırından başlıyor ve $1300 adresinde bulunuyor. Araba, kaya, bulut ve ateş hareketlerinin yapılmasını sağlıyor. 4. Interrupt: #$4A raster satırından başlıyor ve $15C4 adresinde bulunuyor. Zıplayan şeytana hayat veren rutin burada. 5. Interrupt: #$52 raster satırından başlıyor ve $16A8 adresinde bulunuyor. Uçan daire ve mermilerin hareketlerinden sorumlu rutin burada çalışıyor. 6. Interrupt: #$5B raster satırından başlıyor ve $2A8E adresinde bulunuyor. Kamyonun hareketleri burada ayarlanıyor. 7. Interrupt: #$62 raster satırından başlıyor ve $2568 adresinden başlıyor. Oyunun ana kontrol rutinleri burada toplanmış. Çarpışma kontrolleri, skorun yazılması, glow yapılması, GAME OVER ve HAPPY END sayfalarına geçilmesi tamamen bu rutin tarafından gerçekleştiriliyor. Bu rutin bitince tekrar bir nolu interrupt'a sıçranıyor. C-64'ün yalnızca 8 adet sprite'ı olduğu için değişik karakterlerin bazı sprite'ları ortak kullanması gerekiyor. Bu karakterler ve hangi sprite'ı ne zaman kullandıklarıyla ilgili bilgileri aşağıda bulabilirsiniz: 1. CHEVROLET: Sprite No: 1. Sürekli kullanılıyor (0-80 Km). Joystick aracılığıyla sola ve sağa hareket edebiliyor, zıplayabiliyor ve sürekli ateş edebiliyor. 2. ATEŞ: Sprite No: 2. Sürekli kullanılıyor (0-80 Km). Araba tarafından atılıyor. Bulut, Kamyon ve Şeytanları vurabiliyor. Patlama efekti sırasında dokunduğu yaratıkları yok edebiliyor. 3. KAYA: Sprite No: 3. 2 Km'den sonra çıkmaya başlıyor ve oyun sonuna kadar geliyor. Yol üzerinde bulunuyor. Vurulamıyor ve ancak üzerinden atlanarak kurtulunabiliyor. 4. BULUT: Sprite No: 4. 11 Km'den sonra gelmeye başlıyor ve tüm kalan yolda görülebiliyor. Arabanın üzerinden geçiyor. Zıplayıp ateş ederek yok edilebiliyor. Ya zıplamayın, ya da yok edin. 5. ŞEYTAN: Sprite No: 5. 26 Km'den sonra gelmeye başlıyor, 36 Km'ye kadar tepenizde dolaşıyor. Daha doğrusu zıplıyor. Ya sağa-sola giderek kaçın, ya da durun, yoksa Freddy'ye yem olursunuz. 6. KAMYONET: Sprite No: 6. 36. Km'den sonra gelmeye başlıyor ve oyunun sonuna kadar görülebiliyor. Sizi ezmek için arkadan yaklaşıyor. Vurulabiliyor, ama önce zıplayıp önünüze almanız, daha sonra vurmanız gerekiyor. Ama üzerinden zıpladıysanız dokunmayın, çünkü kayaları yok ediyor. 7. UÇAN DAİRE: Sprite No: 5-7-8, 56 Km'den sonra gelmeye başlıyor. Size mermi atıyor ve vurulamıyor. Tek kurtuluş ümidiniz kaçmak. Eğer yeterince hızlı olamazsanız, Freddy'nin rüyalarından hiçbir zaman kurtulamıyorsunuz. 76. Km'den sonra tüm yaratıklar yok oluyor ve rahat rahat araba sürmenin keyfini yaşıyorsunuz. 80 Km'lik yolu bitirdiğinizde HAPPY END sahnesini görüp mutlu oluyorsunuz. Derya Bey bu oyunu yazarken kullandığı programların da bir listesini göndermiş. Çoğunu henüz görmediysem de ne aradığınızı bilmeniz için isimlerini burada yazıyorum. Sanırım bir 45 oyun yapmaya yeterli olan malzeme, her tür iş yapmanız için yeterli olacaktır: (1) Sprite Tasarımı ve animasyonlar: PRO SPRITE. (2) Manzara karakteri: ACY-CREW LOGO EDİTÖRÜ. (3) Müzik: FUTURE COMPOSER'a ait bir blok ile, (4) Sinüs ve Swing Tabloları: BOUN-CER ile. (Bu programı dergimizin 65. döküm ekinde yayınlamıştık.) Derya Bey'in yolladığı dökümanlar burada sona eriyor. Sanırım bu kadar bilgiyle makina dili bilen herkesin programı incelemesi mümkün olacaktır. Yaptığı güzel oyun ve harika grafikleri için Derya Bey'i kutluyorum ve başarılarının devamını diliyorum.

Mektuplar İçin Teşekkürler:

Yavaş yavaş arkadaşlarınızdan katılımlar olmaya başladı. Kimi yalnızca yazmış olmak için, kimi yaptıklarını anlatmak için, kimi de problemlerine çözüm bulabilmek için yazmışlar dergimize. Ben yalnızca problemlerine çözüm arayan arkadaşların mektuplarını cevaplayacağım burada. Cevaplayacağım ilk mektup Mahir Çipil ve Caner Şimşir'den gelmiş. Mahir ve Caner, kendilerine CMC diyorlar. İlk C Caner, M ile Mahir olsa gerek. O zaman grubun üçüncü elemanı kim? Ama belki de Caner grubun kurucusudur ve CMC Caner Mahir Caner anlamına geliyor. Çok mu egoistçe oldu? Her neyse kısaltmalarınızın uzun hallerini yollamayı unutmayın. Benim bu konuda takıntım vardır, uzun halini bulamazsam içim rahat etmez... Bu kadar gevezelik yeter. Gelelim CMC'nin sorunlarına: CMC, introların çoğunda açıldığını, yazıların da buralardan geçebildiğini görmüşler ve bunun nasıl yapılacağını soruyorlar. Ne yazık ki bu aylık köşem oldukça dolu. Bu yüzden bu sorularının cevabını gelecek ay tam bir konu olarak vereceğim. Konunun sonunda da Hi-Res hakkında özet bilgileri sıkıştırırım. Sanırım pek tatmin edici olmadı, ama en azından gelecek ay tüm cevaplara kavuşacaklarını biliyorlar. Bu arada benim C-64 oyunlarını açıklamam gerektiğini söylüyorlar, ama ne yazık ki bu imkansız, çünkü dünyaya benim kadar beceriksiz bilgisayar oyuncusu gelmemiştir sanırım. Bu yüzden oyun açıklamalarında hiçbir zaman benim adımı göremeyeceksiniz. İkinci mektup Özgür Geşli'den geliyor. Özgür'ün asıl problemi müziklerle. Oturup nota nota müzik yazamadığını, bu yüzden introlardan müzik yürütmek istediğini söylüyor. Bu işi nasıl yapacağını anlatmamı istemiş. İlk olarak söyleyeceğim, introlardan müzik yürütmenize gerek yok. Çünkü (umarım hâlâ bu şekilde satılıyordur) FUTURE COMPOSER adlı müzik editörüyle birlikte altmış kadar müzik de verilmişti bize. Bunların yirmisi bile güzel olsa yeterince introya malzeme olur sanırım. Ya da composer programlarını kullanabilen bir arkadaş bulup ısmarlama müzik yaptırırsınız. Her neyse, ben gene de müzik sökme yöntemlerini anlatayım. İlk olarak standart bir müzik yürütme sistemi bulunmadığını söylemeliyim. Müziği yürüttüğünüzde de sadece müziği mi aldığınızdan veya müziğin birazını almadığınızdan emin olmanız zordur. Eskiden beri benim yürüttüğüm müzikler 32 bloktan aşağı inmezken, Celal'in yürüttükleri (aynı müzikler) 16 blok civarı dolaşırdı. Şanssızlığınızdan olsa gerek, müzik yürütmeyi ben anlatıyorum: İlk olarak bellekte $D400-$D420 arasında işlem yapan yerlerin bir dökümünü alın (Expert kullanıyorsanız: K * D400 D420 komutunu kullanabilirsiniz). Müziği çalan rutinin bulunduğu yerde bir yığılma gözünüze çarpacaktır. Daha sonra bu bölgelerde olan bir rutinin çağrılıp çağrılmadığına bakın (eğer Expert'ünüz yoksa önce programın başlangıcı olabilecek bir yer bulun) ve bulduğunuzda adrese sıçradığınızda bir ses gelip gelmediğini kontrol edin. Buradan sonrası size kalmış, yerini bulduğunuz müzikteki fazlalıkları ayırmanız yeterli olacaktır. Ama bir Intro'dan müzik yürütüyorsanız, büyük bir ihtimalle müzik programı $1000 veya $1003'te başlayacaktır. Future Composer'ın müziklerine (yer değiştirilmediyse) $1800'de rastlayabilirsiniz. Biliyorum, biraz kabaca anlattım ama gerçekten de anlatarak öğrenilecek bir şey değil bu sorduğunuz. En iyisi üzerlerinde uğraşarak deneyim kazanmaya çalışın. Zaten zamanla müzik rutinlerini bile birbirinden ayırmaya başlayacaksınız. İkinci sorunuzda Cycle'ın ne olduğunu ve bir Cycle'lık zamanda elektronun ne kadar ilerlediğini sormuşsunuz.

Cycle, benim tahminimce bilgisayarın saat frekansının bir periyoduna verilen ad. Fakat sadece komutların hızını ölçebilmek için kullanılan bir zaman birimi olarak düşünseniz de olur. Mesela en kısa komut olan NOP 2 cycle sürerken BIT $XX komutu 3 cycle yer. Bir cycle'lık süre içinde elektron yatay olarak sekiz piksellik (noktalık), yani bir karakterlik yol alır. Hassas ayarlar yaparken bundan yararlanmanız daha iyi olur. Mesela NOP'u zaman olarak değil de uzunluk olarak algıladığınızda hesaplarınız oldukça kolaylaşır. Bu durumda bir NOP komutu iki karakterlik, bir absolute STA komutu (STA$XXXX) dört karakterlik yol kaplar gibi düşünmeniz gerekir. Üçüncü sorunuzda ise interrupt'a giriş ayarlayan rutinde yer alan bazı adreslerin ne iş yaptıklarını sormuşsunuz. Bu konuyu yazının başlarında ele almıştım ama burada da kısaca değinmekte bir sakınca görmüyorum. Interrupt'a giriş rutininde kullanılan adresler şu işe yarar: $0314-$0315: Rutinin başlangıç adresi. Ekran modu (karakter ekranı, hi-res extended Background) ve Raster'ın 9. biti. $D012: Raster satırının ilk sekiz biti. $D01A: Yapılacak interrupt'ın türü. ($01 — Raster interrupt). Diğerleri ça-

Çarpışma, light-pen vb. interrupt'ların yapılmasını sağlar. $DC0E-$DC0D: CIA 1 zamanlayıcısıyla yapılan interrupt'ları ve zamanlayıcının çalışma şeklini (tek atışlı, devamlı geriye sayış, vb.) kontrol eder bu adresler. Gerekli değerleri vererek Raster'dan başka interrupt'ın oluşmasını engelleyebiliriz. 4. Sorunuzun cevabı ise çok basit. Mesela ekranın en üzerinde yazıyı kaydırıyor olun. $30-$32 gibi bir raster satırında gerekli X pozisyonunu $D016'yı kullanarak ayarlayın, daha sonra kayan yazıların bulunduğu satırlardan sonraki bir raster satırında (1x1 karakterlik yazı kayıyorsa $40 fazla bile gelir) $D016'ya $C8 (multi-color için $D8) verin. Bu sayede ekranın alt kısmındaki yazıların da kayan yazıyla birlikte oynamasını engellemiş olursunuz. Bu konuları önceki sayılarda oldukça detaylı bir şekilde anlattım. Eğer bu yazıları okumadıysanız, eski sayılarımızı ele geçirin ve bir okuyun. Mektubunuz için de çok teşekkürler. Üçüncü ve son mektup da Gökhan Keser'e ait. 1. ve 2. sorusunun cevabını 69. sayıda vermeye çalışacağım, çünkü bu sayıda örnek program için yerimiz kalmadı. Ama çoğu arkadaşınızın yakındığı logo sallama rutiniyle ilgili sorunu bu sayıda cevaplayacağım. Sizlerden gelen yakınmaları görünce gerekli yazıya göz attım ve kendimden utandım. Hem programlar yanlış basılmış, hem de gerekli programlar döküm ekinde çıkmamış. Neyse, hatamı burada telafi etmeye çalışacağım. Bu sayıda anlatacağım logo-swing programı bir logoyu değil, yalnızca bir satırlık bilgiyi sallıyor, ama ekrana basılan satır sayısını arttırarak herhangi bir logoyu da sallayabilirsiniz. İlk olarak swing sinüslerinin yapılmasını anlatacağım. Programın en başında sinüs tablosunun boyutunda bir FOR döngüsü açıyoruz. (0-255 = 256 bayt). Daha sonra gerekli bayta karşılık gelecek olan değeri hesaplıyoruz, yani sinüs fonksiyonunun bu baytta alacağı değeri buluyoruz. Eğer tam bir sinüs kullanacaksanız, formülümüz: INT (GENLİK*SIN(R/ToplamBayt*2*PI)+GENLİK) olur. Eğer eski sayıları da istiyorsanız, ikinci GENLİK değerini eklemeyebilirsiniz. Bu K değerini 7 ile AND'lediğinizde, değerin bir karakter uzunluğu olan 8'in tam katından kaç fazla olduğunu buluruz (25 değeri için, 25 AND 7=1). Bu sayede gerekli karakteri bastıktan sonra ekranı yumuşak olarak ne kadar kaydırmamız gerektiğini buluruz (25 için gerekli karakter ve ekran 1 piksel yanda olacak). Ama bu kayma miktarı sağa kayma miktarı olmasına karşılık, $D016'da sola kayma miktarı tutulur. Bu yüzden bu değeri 7'den çıkararak sola kayma miktarını (0-7 arası bir değer) buluruz. Y=(K-(K AND 7))/8 işlemi sayesinde tam sayı olarak kaçıncı karakterin ekrana basılacağını hesaplarız. Bu baytları gerekli tablolara yazarak işimizi bitiririz. Bu program için gerekli tablolar: Karakter sayısı: $C100; $D016'nın değeri: $C200; $D016'nın değerini yazarken, bulduğumuz sayıya 192 ekleyerek, 38 kolonluk, multi-color olmayan bir ekranda çalışmasını sağlayabiliriz. Eğer 192'yi burada eklemezsek programda STA $D016'dan önce ORA #$C0 komutunu vermeniz gerekir. Bu şekilde özelleştirilmiş sinüs tablosunu hazırladıktan sonra sıra logoyu sallayacak programı incelemeye geldi. Ekranın en üstünde logo sallamaya çalıştığımız için, $D016'nın değerini $32 raster satırında değiştirmemiz gerekli. Bunun için ilk olarak raster'ın $32'ye gelmesini bekliyoruz, daha sonra tablodan $D016'nın şu anki değerini alarak doğrudan veriyoruz. Daha sonra logonun sallandığı alanın sonunu bekleyip (burada biraz fazla tuttum, azaltabilirsiniz) $D016'nın değerini düzeltiyoruz. Sonra tablo gösteri-

PROGRAM ADI 00010

00020
00030
FOR.Rz0O TO 255
BAYTI
00040 Y-(K-(K AND 7))/8:REM
RAKTER POZİSYONU
00050
00060
00070 NEXT

PROGRAM

LOGO

PÖKE
PÖKE 491524512-4*R,1924X:REM

cisinin bir ileri alıp, gelecek taramada görünecek olan ekranı ayarlıyoruz. Eğer INC $C0FF'i şimdi değil de ekranı ayarladıktan sonra verirsek, karakter pozisyonuyla $D016 pozisyonu arasında bir baytlık fark doğar ve bu sebeple de logonuz titrer, karakter pozisyonuyla (sanırım şimdi neden logolarınızın titrediğini anlamışsınızdır Derya Bey). Gelecek ekranı tasarlamak için karakter pozisyonunu $C200'dan alıp, bu pozisyondan itibaren 40 karakteri ekranın en üstüne basmamız yeterlidir. Logo kaydıracak arkadaşlar ise bu transferi $0400, $0428, $0450, vb. için

SINUS YAPICI

)
X-7-(K AND 7):REM

$D016'NIN İLK UC LOGONUN X KA

-$C100
z$C200
20
20
12
De
21
20
20
ZO

satır satır yaparsa yeterli olur. Daha sonra da ekranın alt kısmında bulunan $32. raster satırını geçip (yani $0132, - ama kullanarak yalnızca $32'sini görebiliriz) döngüye tekrar giriyoruz. Logo sallama denilen musibet şey bundan ibarettir yalnızca. Eğer gene de anlayamadığınız bir yer olursa tekrar yazmaktan çekinmeyin, anlamadığınız kısımları daha detaylı olarak anlatmaktan zevk duyarım. Hepiniz gelecek aya kadar hoşçakalın. Mektuplarınızı bekliyorum.

Program 1: .,C000 SEI LDA CMP LDY LDA STA LDA CMP

#$32
$DO12
$COFF
$C200,Y
$DO16
n003
BNE
LDA
STA
INC
LDY
LDX
LDY
$C013
#SC8
$DO16
$COFF
$COFF
$COFF,Y
#S00
LDA $C300,x
STA $0400,Y
(başka satırlar için
LDA $C380,X |
STA $0428,X
vb.)
INY
CPY
BNE
LDA
BPL
LDA
BMI
JMP