Herkese merhaba.... Biraz uzun olmak kaydı ile size C64 assembler deneme hikayemi anlatmak istiyorum. Yaklaşık 1 aydır öğrenerek yaptıklarımı çok detaya inmeden anlatmaya çalışacağım, bu arada son prg dosyasını ve kaynak kodu da ekleyeceğim, bakmak isteyen olursa diye

İlgisini çekmeyen olursa okumayı burada kesebilir

Aslında yeniden C64 aldığım 5 sene öncesine kadar assembler ile ilgilenmemiştim. Taaa 80'lerde örendiklerimi unuttuktan sonra tekrar arada bakmadım ama C64'le yeniden ilgilenmeye başladığımdan itibaren youtube kanallarına ve karşıma çıkan github sitelerine gözüm kaymaya başladı. Nitekim 2 sene önce vakit buldukça komutlara ve ikilik/onaltılık operasyonlara bakmaya başladım. Bilenler bilir, C64'te register'lara yazarak yapılıyor çoğu şey, hani BASIC'te PEEK-POKE hikayeleri. O yüzden makinayı donanım olarak iyi tanımak ve bilmek lazım, öyle API falan yok, en iyi yardımcı assembler, o da artık makina kodu ile yazmamak için şart.
Yakın zamanda birşeyler yapayım dedim ama ne yapacağımı veya nerden başlayacağımı bilmiyordum. En sonunda basit bir oyun yazarsam (en basitinden ama) bu arada grafik, ses, kontrol vb oyun yaratma kriterlerine de ucundan dokunmuş olurum dedim. Arada C64 üzerinde Turbo Macro Pro Assembler ile birşeyler denedim, özellikle youtube'daki Robin, "8 bit show and tell" kanalında kullanım şeklini açıklamıştı. Ama gerçek C64 üzerinde bugün birşey yapmanın nostalji ötesinde mantığı pek yok (gerçi C64 için yapmanın da yok ama onu es geçiyorum şimdilik). Bu yüzden C64 PRG STUDIO'yu (bundan sonra C64PS diyeyim kısaca) tercih ettim.
Öncelikle çok basit bir shoot'em up olsun dedim: Bir ana gemi altta, üstte bir düşman gemisi, ateş etsinler birbirlerine. C64PS'de bir ekran oluşturdum basitten, çeşitli renkte noktalarla uzay efekti. Sonra basitten 2 sprite ile ana gemi ve düşman gemisi (bunu Space Invaders'tan arakladım basitçe), sonra da 2 sprite ile bunların füzeleri. Sonuçta 4 adet sprite tanımladım, başlangıç yerlerine yerleştirdim, sonra ana gemiyi nasıl kumanda ederim diye joystick programlamasına baktım. İlk hareket rutinini yazdım da tabi sonra gerçekler ortaya çıkmaya başladı. C64'ün ekran koordinatlarının aşağıdaki şekilde olduğunu gördüm, zira gemi sağa giderken ekranın bir yerinde kaybolup tekrar soldan ortaya çıkıyordu. Tabi 320x200 ekranın 8-bit makinada 255'e kadar sayabileceği aşikar, 255 ötesine geçtiğinde $d010 adresindeki Most Significant Bit (MSB) 1 yapıldığında ekranın devamına geçebiliyor. Tabii birkaç deneme yaptım, sadece gemiyi de o alana taşıdım ama üstteki gemi ve bunların füzelerini dikkate alınca işler karıştı, o yüzden MSB'nin set edildiği sağ tarafa başka bilgileri koyup geri kalan ekranı savaş alanı olarak belirledim. Sonra her geminin oynayacağı alanı kısıtladım.

Peki gemi hareket ediyor, nasıl ateş edecek? Eh, düğmeye basıldığından ana gemi koordinatlarının hemen üstünde füzenin belirmesi lazım, sonra da her raster'da (yani ekranın her taranıp komutların işlendiğinde) yukarı çıkması lazım. Bunu da yaptıktan sonra düşman gemisini yukarda gezdirmek lazım. Tabi çok basit sağ sol da yapabilir ama bir "wave table generator" ile eliptik hareket oluşturup koordinatlarını verdim. Sonra ana gemi füzesi ile düşman gemisi sprite çarpışmasını hallettim, bu arada bir de patlama sprite'ı yarattım (bunu arka arkaya değişecek 3 sprite oluşturuyor, sadece pointer değiştirmek yeterli). Asında genelde sprite çarpışmasını (collision) önermiyorlarmış, her sprite'ın bulunduğu yeri karakter koordinatına indirgeyip öbür sprite'ın oraya gelip gelmediğini kontrol etmek daha iyiymiş. Özellikle engelli (duvar vs) platform oyunlarında, ama ben şimdilik bu yöntemi uygulamadan devam ettim, zira benim yaptığım da çalıştı. Düşman gemisinin ateş etmesini de yaptım, ana geminin koordinatlarına göre -yani üzerindeyken- ateş edecek şekilde. Tabi ekranda bir füze varken ekrandan kaybolmasını bekliyor, nihayetinde sprite multiplexing yapamıyorum henüz.
Bu arada tabi tam çözemediğim şeyler de var hala. Bazen ana geminin ateş komutuna cevap vermemesi veya düşman gemisinin ateş etmemesi gereken yerde ateş etmesi gibi. Muhtemelen komutlar için harcanan cycle'ları saymam ve aksaklığı bulmam gerekiyor. Ama henüz o aşamada değil bilgim. Aşağıdaki ekranda raster ve cycle'lar var, bu kapsamda detaylı kontrolü yapamam gerekiyor (herhalde).

Sonra yanda kalan tarafa bari kalan hayat (lives) ve skoru yazayım dedim. Skoru tek tek değil de böyle 100'er puan artsın falan diye araştırınca yapan bir yer buldum. Mantığını anlamam ve adapte etmem biraz zaman aldı tabi ama çalıştı netekim. Canı da 3'ten geri saydırdım, 0 olunca oyun bitiyor.
Tabi sıra ses efektine geldi. Yani Commodore 64'te ses efekti, müzik falan oluşturmak için deveye hendek atlatmak daha kolay herhalde. Tabi bu konular artık demo'cular tarafından yenilip yutulduğundan, Goat Tracker ile ses ve müzikleri oluşturmak ve basit bir rutin ile bunları çağırmanın yeterli olduğunu öğrendim...Goat Tracker ile uğraştım biraz, birkaç ses ve kayıt da yaptım ama güzel birşey çıkması için vakit gerektiğinden ve de fokusu kaybetmek istemediğimden örnek bir ses dosyası aldım (tamam, arakladım)... İçinde ses efekti ve müzik barındırdığından işimi gördü. Müziği çalmak içinde kısa bir interrupt routin'i gerekiyor, bunu da anladım. Ama tabi farklı bir interrupt da gerektiğinde nasıl çakışacaklar, bu konu henüz net değil bende.
Bir sonrak adımda hadi dedim bari bir de "title screen" olsun dedim. Ama artık hiç olmazsa bitmap olsun, zaten oyun oynanan ekran karakterlerden oluşuyor. Şimdi oturupta olmayan yeteneğimle Koala Painter'de resim çizecek değilim. Bir bitmap (bmp) resim buldum, önce onu 320x200'e indirdim. Sonra Timanthes diye bir programla Koala Painter formatına çevirip yükleme rutinini yazdım. Oyun başlarken bu ekran çıkıyor, bitince de yine buraya dönüyor.

Bu arada müzik 3K, bitmap 10K, e ekran ve renk dataları var, sprite'lar var... Bunların her birini ekleyişte birşeyler bozuldu. Kiminde müzik çalmadı, kimide bitmap bozuldu, bazen sprite'lar saçmaladı. En sonunda şöyle bir adresleme ile çözebildim. Hiç efektif değil tabi ama tüm hafıza bank'larının verimli şekilde kulanılması ve gerektiğinde değiştirilme işini hala çözmeye çalışıyorum.
$0801 - $080F ML yükleme kodu
$0810 - $0D50 Ana kod (1344 byte)
$2000 - $21C0 Sprite dataları (7 sprite - 448 byte)
$3000 - $3C00 Ses dosyası (Goat Tracker - 3K)
$5000 - $53E8 Savaş ekranı karakter datası (1000 byte)
$5400 - $57E8 Savaş ekranı renk datası (1000 byte)
$6000 - $8088 Title ekranı multicolor bitmap dosyası (Koala - 10K)
Şimdi zaten Commodore'un açılışındaki "38911 bytes free" nerden geliyor, işte $0801-$9FFF arasını kullanıyor. Ben de herhangi bir numara yapmama gerek kalmadan bu aralığa yerleştirdim. Tabi millet bu alanda ne cambazlıklar yapıyor, benimkisi onların yanında çerez bile değil.

Son olarak vurma anında dış border'ın renk değiştirmesi, oyun bitti yazısının parlaması gibi ufak dokunuşlar ve keşifler de oldu. Soru: Buraya kadar gelen oyun oynanır mı? Cevap: Katiyyen oynanmaz, son derece sıkıcı, hataları var vs. Ama bunları yaparken ben çok zevk aldım, yeri geldi bir sorunu çözmek için bir hafta uğraştım. Tabi sırada birkaç şey daha var çözmek veya yapmak istediğim. Aşağıdakilerin örnek olabilir:
1- Savaş ekranı arka planı renkli karakterlerden oluşuyor ama buraya bir kayan yıldızlar (starfield simulation) animasyonu eklemek,
2- Sağdaki bilgi ekranını kaldırıp 255 sonrası alanı savaşa açmak (sprite yönetme kodunu baştan yazmam gerekecek herhalde),
3- İkinci maddeye bağlı olarak skor ve hayat bilgilerini -eğer birden fazla interrup olayını çözebilirsem- alt veya üst çerçeveye yazmak. Bu zor bir konu, internet'te muhtemelen kod parçacıkları da vardır ama tam anlamazsam adapte edemeyebilirim.
4- Goat tracker ile kendi (özgün) ses efekt ve müzik dosyamı ouşturmak.
5- Ve tabii ki birden fazla düşman gemisi olması.
Bu arada tabi C64PS ile de sıkıntım var: "i" kullanarak yazdığım komutları saymıyor, "ı" istiyor (yani inx yazarsam olmuyor, ınx yazmam lazım). Keyboard ayarları ile oynamamak için sabrediyorum bakalım da daha büyük sıkıntı debugger'ı çalışmıyor. Vice'ın monitörü ile idare ettim ama zannedersem kaldırıp baştan kuracağım C64PS'i.
Bütün bunları yapar veya yapabilir miyim bilmiyorum. Ama sıkılır da devam edemezsem bari bugüne kadar yaptığım şeyin bir hikayesi olsun

Buraya kadar sabreden herkese teşekkürler
