Atari 800 XL/XE Bölüm 2

Bölüm 2 Emir 'Skate' Akaydın

Giriş

Atari, evlerimize giren 8 bit ailesi bilgisayarların en eskilerinden biri olmasına rağmen, bazı açılardan çok şanslı bir bilgisayardır. Çünkü günümüz PC'lerinde bile donanımsal olarak yer almayan ve yine dönemin bilgisayarlarının bir kısmında da bulunmayan bir özelliğe sahiptir. Bu özelliğe genel olarak yaratıklar (sprites) diyoruz. Ancak Atari fazlasıyla oyun odaklı tasarlanmış olacak ki, bu yaratıkları iki başlık altında toplamıştır: Oyuncular ve füzeler (players & missiles). İlk başta bir donanım özelliği olarak kulağa komik gelse de işin içine girince gerçekten de ismini hak eder bir tasarıma sahip olduğunu göreceksiniz.

Bu sayımızda, bu muhteşem donanım özelliğini çeşitli yönleriyle inceleyeceğiz. Öncelikle genel tanımıyla yaratıklara bir göz atalım.

Not: Bu yazıda verilen kaynak kodlar, ACME ile derlenebilirler. Detaylı bilgi için yazı dizisinin birinci bölümüne göz atınız.

Şekil 1.

Yaratık Nedir?

Günümüz bilgisayarları hiper süper hızlarda çalıştıkları için bu tür bir donanım özelliğine ihtiyaç duymamaktadırlar. Kaldı ki 2 boyutlu donanım destekleri 3 boyutun bize yetmediği (!) günümüzde biraz arkaplanda kalmaktadır.

70'lerin sonlarında, 80'lerin başlarında piyasaya sürülmüş 8 bit bilgisayarlar en fazla birkaç MHz hızındaydı. Atari'nin 1-2 MHz aralığındaki hızı da diğer benzerleri gibi bazı grafik fonksiyonlarını yerine getirebilmek için yetersizdi. Bu bilgisayarların önemli ölçüde oyun odaklı tasarlandıklarını düşünecek olursanız, karşımıza ilk çıkacak problem ekranda hareket eden "yaratıklar" oluyor. Yaratık demek öcü demek değil elbette ki. Bu yaratıklar kah hoplayıp zıplayan bir Mario, kah cıv cıv ateş eden bir uzay gemisi, kah namludan fırlamış akıbeti kötü bir kurşun olabilir.

Ekranda hareket eden her yaratık donanım destekli olmak zorunda mı? Bunun başka bir yolu yok mudur? Elbette ki var. Zaten o dönemdeki hemen hiçbir donanım, ekrandaki yaratık sayısı arttıkça yeterli desteği verememekte ve başka yollara başvurulması gerekmektedir. Bunun en bariz örneklerinden biri 1978 yılında yayınlanan Space Invaders oyunudur. Ekranda 50'den fazla hareketli yaratık ve bunlara ek olarak yaratıkların attıkları kurşunlar yer almaktadır. Hele ki bu yaratıklardan 10-11 tanesinin yan yana durduğunu düşünecek olursak o günün standartlarında her biri bağımsız, donanım destekli birer yaratık olarak gösterilmeleri mümkün değildir. Ancak kolaylıkla grafik ekranına çizdirilebilir ya da karakter ekranında karakter seti değiştirilerek elde edilebilirler.

Şekil 2.

Buradaki asıl problem 50'den fazla yaratığın ekrana basılmasının ve yaratıkların hareket etmelerinden önce ekranın temizlenmesi işlemlerinin alacağı zamandır. Bu zaman şu ana kadar bu konu üzerine çok düşünmemiş bir insanın tahmin edebileceğinden daha büyük bir sıkıntıdır. Zaman yetmemesinden kasıt şudur: Atari, Commodore ve benzeri bilgisayarların PAL (Örnek: Avrupa Ülkeleri) standartlarında 50, NTSC (Örnek: Amerika) standartlarında 60 saniyede gösterebileceği belli bir kare (frame) sayısı vardır. Yani bir ekran karesi saniyede 50 ya da 60 kere oluşabilir. Bir kareyi oluşturmak için bilgisayarın belirli bir zamanı vardır. Bu zaman içerisinde işleyebileceği komut sayısı da elbette ki sınırlıdır. Komutların çalışmasında geçen süre cycle ile ifade edilir. Farklı komutlar farklı cycle'larda zaman yiyebilirler. Ekranın tamamının ya da tamamına yakın bir kısmının byte byte silinmesi ve yeni yaratıkların ekrana yine byte byte basılması işlemi, söz konusu yaratık sayısı 50'nin üzerindeyse tek bir karede mümkün olmayacaktır. Bu durumda birkaç karede bir ekran güncellenecek ve bu da gözle görülür bir yavaşlamaya neden olacaktır. Gel gelelim Space Invaders'da yaşanan sorun da budur. Oyun ilk başladığında yaratıklar oldukça yavaş hareket etmektedirler. Yaratık sayısı azaldıkça yaratıkların hareket hızları artar. Son yaratık tek başına kaldığında süpersonik bir hıza ulaşır. Bu oyunun bir özelliği olmasının yanı sıra aynı zamanda teknik bir sorundur.

Space Invaders oyununun bir diğer özelliği ise siyah arkaplana sahip olmasıdır. Yani yaratıklar bir arkaplanın üzerine basılmazlar. Peki ya arkaplanda bir resim olacak olsaydı ne olacaktı? Sil-çiz kadar basit bir yöntem kullanmamız mümkün olmayacaktı. Şimdi bu duruma bir göz atalım.

Şekil 3.

Öncelikle yaratığın üzerine çizileceği arkaplanın hafızada bir kopyasının durması gerekir. Bir diğer seçenek ise yaratığın basılacağı alan bir dikdörtgen şeklinde düşünülerek sadece bu kısmın bir kopyası alınabilir. Daha sonra yaratık bu alana yine dikdörtgen biçiminde basılabilir. Ancak arkaplanın silinmemesi için matematikteki VEYA (OR) işleminin kullanılması gerekir. Bir sonraki karede, arkaplan yaratığın bulunduğu alana yeniden kopyalanarak yaratık silindikten sonra, yaratığın yeni pozisyonuna uygun bir biçimde arkaplan hafızaya alınır ve yaratık yeni pozisyonuna yerleştirilir. Bu işlem her harekette tekrarlanmak zorundadır. Grafik moduna ve yaratığın çizimine bağlı olarak yaratık basılmadan önce VE (AND) işlemi ile yaratığın basılacağı alanı arkaplan üzerinde maskelemek de gerekebilir. Bütün bu işlemler ciddi zaman alan işlemlerdir ve oyunun akıcılığını önemli ölçüde etkilerler.

Arkaplan üzerine hareketli grafik basma işinin çözümü donanımsal yaratık desteğinde gizlidir. Konumuz olan Atari 800 XL/XE bilgisayarlarında grafik işlemlerinden sorumlu çip olan Antic çipi yaratıklardan sorumlu değildir. Bu işi GTIA çipi yani Antic'deki görüntüyü TV ya da monitöre aktarma işinden sorumlu olan çip üstlenir. Kısacası Antic çipi ekrandaki görüntüyü oluşturduktan sonra GTIA çipi bu görüntünün üzerine dilediği gibi yaratık basabilir. Hatta bu yaratıkları şeffaf bile basması mümkündür. Atari'deki yaratık desteğini televizyonunuzun sesini açtığınızda ekrana çıkan volume seviye grafiği gibi düşünebilirsiniz.

Oyuncular ve Füzeler

Her donanımsal yaratık desteği olan bilgisayarda kendisine özel sınırlamalar vardır. Aynı anda kaç yaratık gösterilebileceği, bunların ekranda hareket ettirilme kuralları, çözünürlükleri, renk sayıları, çarpışmaları gibi birçok kriter ve sınırlama mevcuttur.

Atari'de 4 oyuncu ve 4 füze şeklinde toplamda 8 yaratık bulunmaktadır. Bu 8 yaratık birbirinden bağımsız hareket edebilirler ve arkaplanı etkilemezler. Yani çok az bir zaman harcayarak ekranda 8 yaratık göstermek mümkündür. Ancak oyuncular ve füzeler aynı özelliklerde değillerdir. 4 füze bir arada kullanıldığında fazladan 1 oyuncu elde edilebilir. Bunun nedenlerini birazdan göreceğiz.

Atari'de Yaratıkların Hareket Etme Prensibi

Yaratıklar iki boyutlu oldukları için iki eksende hareketleri söz konusudur; X ve Y eksenleri. Genellikle her iki eksen için birer hafıza adresi kullanılarak yaratık pozisyonlarını değiştirmek mümkündür. Ancak Atari'de yaratıklar yalnızca X ekseninde bu şekilde hareket ettirilebilirler. Dikeyde ise hareket biraz farklı bir biçimde gerçekleşmektedir. Çünkü Atari'de yaratıklar dikeyde tüm ekran yüksekliğini kaplamaktadırlar.

Şekil 4.

Resimde görülen kırmızı, yeşil, mavi ve sarı bloklar her bir yaratığın çizilebileceği alanları sembolize etmektedirler (normalde ekranda böyle barlar görmeyeceksiniz). Yaratıkların çizim genişlikleri sabitken, yükseklik olarak bir sınırlama yoktur. Bir yaratık tüm ekran boyunda olabilir. Örnek olarak resimdeki uzay gemisi, çarpı sembolü, iki yönlü ok birer yaratık olduğu gibi PLAZMA #6 yazısı da tek bir yaratıktır.

Bu yaratıklar hafızanın çeşitli bölümlerinden grafik verisi okuyabilirler. Ancak hafıza adresleri belirlendikten sonra hep sabit bir adresten veri okudukları için grafik verilerini hafıza üzerinde kaydırarak yaratıkları Y yönünde hareket ettirmiş oluruz. Bu işlem uzay gemisi için oldukça hızlı yapılabilirken, PLAZMA #6 yazısının bulunduğu yaratıkta daha uzun süren bir işlemdir. Kısacası yaratık grafiğinin yüksekliği arttıkça Y eksenindeki hareket de orantılı bir biçimde daha çok zaman almaktadır. Fakat X eksenindeki hareket yaratığın grafik verisinden kesinlikle etkilenmez ve yalnızca bir hafıza adresini değiştirerek yaratık hızlıca yeniden pozisyonlandırılabilir.

Oyuncular

Önceki bölümde gördüğümüz 4 yaratık aslında oyunculara tekabül etmektedir. Oyuncuların yatay çözünürlükleri 8 pixeldir. Bu aslında oldukça düşük bir çözünürlüktür. Ancak elbette ki birden fazla yaratık yan yana getirilerek 16, 24, 32 hatta füzeler de kullanılarak 40 pixel genişliğe ulaşmak mümkündür. Yaratıklar ekranda gösterilirken her bir pixel 2 pixel genişliğinde gösterilmektedir. Yani 8 pixel genişliğindeki bir yaratık ekranda 16 pixellik bir alan kaplayacaktır.

Şekil 5.

Yaratıklar yatay eksende 2 ya da 4 kat, dikey eksende ise 2 kat genişletilebilirler. Yatayda 2 kat genişletilen bir yaratık 16 yerine 32 pixel, 4 kat genişletilen ise 64 pixel kaplayacak şeklinde görüntülenir. Yani yaratık haritasında yer alan her bir bit normalde 2, 2 kat genişletildiğinde 4, 4 kat genişletildiğinde 8 pixel genişliğinde ekrana çizilir.

Oyuncuların her biri hafızada 256 bytelık alanlardan veri okurlar. Aslında bu 256 byte'ın tamamı ekran alanına sığmamaktadır. İlk 8 byte ekranın üstünden dışarıda kalmaktadır. Ekranın görüntülenebilen alanı 240 byte kabul edilebilir. Bu durumda alanın sonunda yer alan yine 8 bytelik bir bölge daha görüntülenemez. Eğer yaratıklar Y ekseninde iki kat genişletilecek olursa bu durumda 256 bytelik alanın ilk 128 byte'ı grafik verisi olarak kullanılır ve her satır 2 kez tekrar eder. Ancak bu durum tüm yaratıkların hafıza yerleşimlerini değiştiren bir durumdur. Bunu ilerde göreceğiz.

Füzeler

Füzeler, oyuncularla büyük oranda benzerlikler içerirler. En temel farklılığı genişliklerinin 8 pixel yerine 2 (yazıyla "iki" :)) pixel olmasıdır. Elbette ki bu hayalinizdeki füzeyi çizebilmek için yeterli bir genişlik değildir. Ancak yine de füzeler mini kurşunlar atmak için kullanışlı bir yöntemdir. Peki niye 2 pixel ile sınırlıyız? Aslında bu sınır hakkında net bir görüş ortaya koymak zor da olsa benim söyleyebileceğim Atari donanımının maksimum 5 oyuncu niteliğinde yaratık destekleyebildiğidir. Bu oyunculardan 4'ü olduğu gibi kullanılırken 1 oyuncu dikey olarak 4'e bölünmüş ve 4 farklı füze olarak kullanılmış varsayılabilir. Füzeler de aynı oyuncular gibi tüm ekran yüksekliğinde basılabilir ve farklı farklı pozisyonlandırılabilirler. Ancak bu defa tek bir byte 4 farklı füzeyi ifade eder. Bu da demektir ki füzeleri dikey olarak hareket ettirirken bit bazlı ek hesaplamalar yapmamız gerekir. Şimdilik bu kadar detaya girmeden füzelerin yapısını incelemeye devam

Şekil 6.

Görüldüğü gibi birkaç farklı model füze elde edebiliyoruz. Dikeyde füze verilerini uzatarak daha farklı füzeler modellememiz de mümkün. Ancak bunların yerine birden fazla füzeyi yan yana kullanarak daha büyük füzeler elde etmemiz de bir başka kullanışlı yöntem olabilir. Ayrıca istersek 4 füzeyi birlikte 5. bir oyuncu olarak kullanabiliriz. Unutmamamız gereken şey her bir füzenin bağımsız bir X koordinatının olduğudur. Yani 4 füzeyi yan yana getirmek istediğimizde aşağıdaki gibi bir yöntem izlememiz gerekir.

ele temizle
lda
sta
adc
sta
adc
sta
adc
sta
şelde bayra##n#
#X Koordinati
FUZE3 X

(carry flag)

Burada FUZE(n) X şeklinde geçen tanımlar henüz hafıza adreslerinden bahsetmemiş olduğumuz için yapılmış geçici tanımlardır.

Oyuncular ve Füzeler'in Hafıza Haritası

Oyuncu ve füzelerin dikey genişleme özelliğine göre iki farklı hafıza yerleşimleri vardır. Eğer dikey olarak genişlemişlerse hafızada 1 kilobyte, normalde ise 2 kilobyte yer kaplarlar. Bunun nedeni ise iki kat genişlemiş yaratıkların dikeyde her iki satırda bir yeni grafik verisi okumasından dolayı yarı yarıya az veriye ihtiyaç duymasıdır. Şimdi sırayla hafıza haritalarını verelim.

1) Tek Satır Çözünürlüğü

Şekil 8.

Oyuncu ve Füzeler'in Hafıza Adresleri

$02C0 : Oyuncu 0 ve Füze 0'ın rengi.

$02C1 : Oyuncu 1 ve Füze 1'in rengi.

$02C2 : Oyuncu 2 ve Füze 2'nin rengi. $02C3 : Oyuncu 3 ve Füze 3'ün rengi.

$D000 : Yazarken; Oyuncu 0'ın X koordinatı. Okurken; Füze 0'ın oyun alanı çarpışma kontrolü.

$D00A : Yazarken; Oyuncu 1'in X koordinatı. Okurken; Füze 1'in oyun alanı çarpışma kontrolü.

$D002 : Yazarken; Oyuncu 2'nin X koordinatı. Okurken; Füze 2'nin oyun alanı çarpışma kontrolü.

$D003 : Yazarken; Oyuncu 3'ün X koordinatı. Okurken; Füze 3'ün oyun alanı çarpışma kontrolü.

$D004 : Yazarken; Füze 0'ın X koordinatı. Okurken; Oyuncu 0'ın oyun alanı çarpışma kontrolü.

$D005 : Yazarken; Füze 1'in X koordinatı. Okurken; Oyuncu 1'in oyun alanı çarpışma kontrolü.

$D006 : Yazarken; Füze 2'nin X koordinatı. Okurken; Oyuncu 2'nin oyun alanı çarpışma kontrolü.

$D007 : Yazarken; Füze 3'ün X koordinatı. Okurken; Oyuncu 3'ün oyun alanı çarpışma kontrolü.

$D008 : Yazarken; Oyuncu 0'ın yatay genişliği (0-normal, 1-iki kat, 3-dört kat). Okurken; Füze 0'ın oyuncu çarpışma kontrolü (0, 1, 2, 3-Oyuncu 3).

$D009 : Yazarken; Oyuncu 1'in yatay genişliği (0-normal, 1-iki kat, 3-dört kat). Okurken; Füze 1'in oyuncu çarpışma kontrolü (0, 1, 2, 3-Oyuncu 3).

$D00A : Yazarken; Oyuncu 2'nin yatay genişliği (0-normal, 1-iki kat, 3-dört kat). Okurken; Füze 2'nin oyuncu çarpışma kontrolü (0, 1, 2, 3-Oyuncu 3).

$D00B : Yazarken; Oyuncu 3'ün yatay genişliği (0-normal, 1-iki kat, 3-dört kat). Okurken; Füze 3'ün oyuncu çarpışma kontrolü (0, 1, 2, 3-Oyuncu 3).

$D00C : Yazarken; Füze 0'ın yatay genişliği (0-normal, 1-iki kat, 3-dört kat). Okurken; Oyuncu 0'ın oyuncu çarpışma kontrolü (2-Oyuncu 1, 3).

$D00D : Yazarken; Füze 1'in yatay genişliği (0-normal, 1-iki kat, 3-dört kat). Okurken; Oyuncu 1'in oyuncu çarpışma kontrolü (1-Oyuncu 0, 3).

$DOOE : Yazarken; Füze 2'nin yatay genişliği kat, kat). Okurken; Oyuncu 2'nin oyuncu çarpışma kontrolü (15Oyuncu 0, 1, 3).

$DOOF : Yazarken; Füze 3'ün yatay genişliği kat, kat). Okurken; Oyuncu 3'ün oyuncu çarpışma kontrolü (15Oyuncu 0, 1).

Bu adres açıklamalarında bazı kurala ya da mantığa uymayan noktalar bulabilirsiniz. Örneğin oyuncuların diğer tüm oyuncularla çarpışma kontrollerinin olmaması gibi. Bunlar hata değil Atari'nin bazı kuralları ya da donanımsal sınırlandırmalar olarak değerlendirilmelidirler.

Oyuncu ve Füzeler'in Ekranda Gösterilmesi

Şu ana kadar öğrendiklerimizin bir işe yaraması için öncelikle bu yaratıkları ekranda nasıl göstereceğimizi bilmemiz gerekiyor. Aslında bu oldukça basit bir işlem. Bu işi gerçekleştirebilmemiz için yukarıda öğrendiğimiz adreslere Antic ve GTIA çipleri arasında bir köprü gibi çalışan iki tane daha adres eklememiz gerekiyor.

$022F (DMACTL): Bu adres oyuncu ve füzelerin haricinde diğer grafik ekranı ile ilgili bayrakları da taşıyan bir adrestir. Yazı dizimizin birinci sayısında (Plazma #5'de) grafik ekranı açma ve görüntü listeleri konularında da bu adresi görmüş ve kullanmıştık. Şimdi bu adresteki bitlerin anlamlarını inceleyelim.

Bit 0 (değer 1): Dar oyun alanını aç. Bit 1 (değer 2): Normal oyun alanını aç. Bit 2 (değer 4): Füzeleri aç. Bit 3 (değer 8): Oyuncuları aç. Bit 4 (değer 16): Yaratıklar için tek satır çözünürlüğünü aç. Bit 5 (değer 32): DMA'yı aç. Bit 0 + Bit 1 (değer 3): Geniş oyun alanını aç. $022F adresine örnek olarak $1f değeri verdiğimiz durumda;

$1f = 00011111 - Geniş oyun alanı + füzeler + oyuncular + tek satır çözünürlüğü açık anlamına gelecektir. Ancak bu işlem henüz yaratıkları görüntülememiz için yeterli değildir. Çünkü yaratıkların görüntülenmesini kontrol eden anahtarları içeren bir adres daha vardır.

$D01C (GRACTL) : Bu adres grafik kontrol adresidir. Oyuncular ve füzelerin ikisinden birinin ya da her ikisinin gösterilip gösterilmeyeceğine karar verir.

Bit 0 (değer 1): Füzeler görünür. Bit 1 (değer 2): Oyuncular görünür. Bit 0 + Bit 1 (değer 3): Hem füzeler hem oyuncular görünür.

Bu adresin değeri 0 olduğunda oyuncular ve füzeler görüntülenemezken, 3 değeri verildiğinde her ikisi de görüntülenebilir.

Oyuncu ve füzeleri görüntüleme örneği:

lda
sta
lda
sta
#Ş1£
$022f ;
#$03
#d0lc ;
DMACTL
GRAGTL

Bu iki adrese doğru değerler verildiğinde oyuncular ve füzeler artık görüntülenebilirler. Ancak elbette ki grafik haritaları ve pozisyonlarının da düzgün bir biçimde ayarlanması gerekmektedir.

Her İki Düzlemde Hareket Eden Oyuncu Örneği

Şimdi ilk çalışan örneğimizde ekranda daire çizen bir X yaratığı görelim. Bu yaratık için 0 numaralı oyuncuyu kullanacağız.

Dairesel hareketi elde etmek için yatayda kosinüs, dikeyde sinüs fonksiyonu kullanmamız gerekir. Kosinüs tablosu sinüs tablosundan elde edilebildiği için yalnızca sinüs tablosu oluşturmamız yeterli olacaktır. Kosinüs tablosu sinüs tablosunun 90 derece, yani ilerisindeki değerleri okuyarak elde edilebilir. Ancak bu durumda sinüs tablosunun sonunu geçeceği için sinüs tablosu hafızada peş peşe iki kez tekrar ettirilerek bu problem çözülebilir.

Sinüs tablosunu hesaplatmanın birçok yolu vardır. Bunu doğrudan assemblerdan da hesaplatabiliriz. Ancak ben genellikle çapraz geliştirmenin gücüne olan inancımdan bu tür hesaplamaları PC'de yapmayı tercih ediyorum (Bkz: Test Platformu köşesi, Plazma #1, #2, #3, #4). Şimdi kısa bir JavaScript koduyla internet tarayıcı ekranımıza sinüs tablosunu yazdıralım.

sinus.htm
<script>
for(i - O;
(
2567
84 * Math.floor(83.9 * Math.sinl(i / 128
ız 0)
document.write(",");
document .writela);
a -
1£(i
)
</script>

Bu programın çıktısını aşağıdaki kodun sonlarında

(sinus şeklinde işaretlenmiş iki alana kopyalamamız gerekiyor. Kopyaladığımızda görüntü 84,86,88,90, .... , 75,77,79,81" şeklinde olmalı. Eğer bu işlem size zor geliyorsa Plazma #6'nın yanında gelen ek dosyalardan hazır kaynak koda erişebilirsiniz.

Şekil 9.

oyuncu hareketi.a

* Math.PI));

Atari 800 XL/XE - Bölüm 2

sta $f8
BASLANGIC ADRESI - $0600 clc
!to "oyuncu hareketi.xex",plain adc #$08
sta endOfBlock
* — BASLANGIC ADRESI-6 ldy #$00
$££f£f, BASLANGIC ADRESI, BITIS ADRESI lda #$00
Dongul sta
* — BASLANGIC ADRESI iny
;yarat#klar#n bellek adreslerini belirle bne Dongul
lda $6a inc $£8
sec ldx $£8
sbec #$08 epx #ŞEf endOfBlock - *-I1
sta $6a bne Dongul
sta $d407 ; PMBASE HI rts
sta YaratikBellegitl
lda #$00 ;oyuncunun bulundugu alani temizle
sta YaratikBellegi

;yaratık ve füzeleri aç

lda #$03
sta $d0ld ; GRACTL
;grafik ekrani ac
ldy #$1f
sty $022f ; DMACTL
rengi
lda #$aa
sta $02c0 ; Oyuncu 0 rengi
;tüm yaratik bellegini temizle
İsr YaratikBelleginiTemizle
adresini belirle
lda YaratikBellegi
sta $f5
lda YaratikBellegitl
ele
adc #$04
sta $f6
;kesme rutini ayarla
ldy #<Rutin
ldx #>Rutin
lda #$07
jsr $e45c ; SETVBV
jmp *
şana rutin
Rütin
temizle
jsr OyuncuyuSil
;oyuncuyu yeni y koordinatinda olustur
jsr OyuncuyuOlustur
şeski y pozisyonunu kaydet
lda
sta OyuncuYEski
;oyuncuyu yeni x koordinatina tasi
lda OyuncuXx
sta $d000 ;
;sinus tablosuna gore oyuncuya
;dairesel hareket yapt#r
ldy SinusPozisyonu
lda SinusTablosut64,y
ele
adc #$28
sta OyuncuXx
lda SinusTablosu,y
ele
ade #$20
sta OyuncuYy
;sinus tablosu uzerinde ilerle
ine SinusPozisyonu
jmp $e462 ; RETURN
#2kb'lik yaratik bellegini temizle
YaratikBelleginiTemizle
lda YaratikBellegi
sta $İ7
lda YaratikBellegitl

Oyuncu 0 X pozisyonu

OyuncuyuSil
ldy OyuncuYEski
lda #$00
Dongu2 sta ($£5),y
iny
cpy #HaritaSonu-HaritaBasi
bne Dongu2
rts
olustur
OyuncuyuOlustur
ldx #$00
ldy Oyuncuy
Dongu3 HaritaBasi,x
sta ($£5),y
iny
inx
cpx #HaritaSonu-HaritaBasi
bne Dongu3
rts
HaritaBasi !byte
!byte
!byte
!byte
!byte
!byte
!byte
!byte
!byte
!byte
!byte
HaritaSonu - *
OyuncuX !byte
OyuncuYy !byte
OyuncuYEski !byte
SinusPozisyonu !byte
YaratikBellegi !byte
SinusTablosu !byte
!byte
BITIS ADRESI -— *
$02e0,
$02e1,
500000000
$10000001
#11000011
$01100110
$00111100
$00111100
$01100110
$11000011
$10000001
500000000
©2900
,0

sinus tablosu| sinus tablosu|

BASLANGIC ADRESI

Bu örnekte henüz öğrenmediğimiz bazı kısımlar geçiyor. Bu kısımlara takılmadan yaratıklarla ilgili öğrendiğimiz bölümleri incelemenizi tavsiye ediyorum.

Füze Atan Oyuncu Örneği

Aşağıda ateş eden bir uzay gemisi örneği göreceğiz. Kullanılacak yaratıklar Oyuncu 0, Füze 0, Füze 1, Füze 2 ve Füze 3.

Atari 800 XL/XE - Bölüm 2

lda OyuncuXx
sta $d000 ; Oyuncu 0 X pozisyonu
olustur
İsr OyuncuyuOlustur
;fuzeleri olustur
FuzeleriOlustur
;kesme rutini ayarla
ldy #<Rutin
ldx #>Rutin
lda #$07
jsr $e45c ; SETVBV
İmp *
lda Fuze2X
cmp #$e0
oyuncu fuze.a bne Devam2
lda #$48
sta Fuze2X
BASLANGIC ADRESI - $0600 Devam2 inc Fuze3X
!to "oyuncu fuze.xex",plain lda Fuze3X
cmp #$e0
* — BASLANGIC ADRESI-6 bne Devam3
BASLANGIC ADRESI, BITIS ADRESI lda #$48
sta Fuze3X
* — BASLANGIC ADRESI Devam3 inc Fuze4X
;yarat#klar#n bellek adreslerini belirle lda Fuze4Xx
lda $6a cmp #$e0
sec bne Devamâ
sbc #$08 lda #$48
sta $6a sta Fuze4X
sta $d407 ; PMBASE HI Fuzelx
sta YaratikBellegitl sta $d004 ; Fuze 0 X pozisyonu
lda #$00 lda Fuze2Xx
sta YaratikBellegi sta $d005 ; Fuze 1 X pozisyonu
lda Fuze3X
;yarat#k ve fuzeleri ac sta $d006 ; Fuze 2 X pozisyonu
lda #$03 lda Fuze4x
sta $d0ld ; GRACTL sta $d007 ; Fuze 3 X pozisyonu
; grafik ekrani ac RETURN
ldy #$1f yaratik bellegini temizle
sty ; DMACTL YaratikBelleginiTemizle
lda YaratikBellegi
ve fuze rengi sta, 9
ida i lda
; sta a
lda #$99 ; Oyuncu 1 ve ele
sta $02cl ; Fuze 1 rengi ade #$08
lda #$cc ; Oyuncu 2 ve sta endOfBlock
sta $02c2 ; Fuze 2 rengi ldy #$00
lda #$ee ; Oyuncu 3 ve lda #$00
sta $02c3 ; Fuze 3 rengi Dongul sta ($f9),y
in
;tüm yaratik bellegini temizle bne Dongul
İsr YaratikBelleginiTemizle inc $fa
ldx $fa
;oyuncunun adresini belirle cpx : endOfBlock - *-1
yda bne Dongul
sta rts
sta
lda ;oyuncuyu olustur
ele OyuncuyuOlustur
adc #$03 ldx #$00
sta $f8 ldy Oyuncuy
ele Dongu3 I1da HaritaBasil,x
ade #$01 sta
sta $f6 iny
inx
x pozisyonu
cpx #HaritaSonul-HaritaBasil
bne Dongu3
rts
;fuzeleri olustur
FuzeleriOlustur
ldx #$00
ldy FuzeY
Dongu4 I1da HaritaBasi2,x
sta ($f7),y
iny
inx
cpx #HaritaSonu2-HaritaBasi2
bne Dongu4
rts
HaritaBasil !byte
!byte $11000000
!byte $11110000
!byte $11001000
!byte $11000100
!byte $11111110
!byte $11111111
!byte $11111111
HaritaSonul - *
HaritaBasi2 !byte
!byte $11010111
!byte
HaritaSonu2 - *
OyuncuXx !byte $40
Oyuncuy !byte $7c
FuzelX !byte $48
Fuze2X !byte $70
Fuze3X !byte $98
!byte $c0
FuzeY !byte $81
YaratikBellegi !byte 0,0
*
BITIS ADRESI
$02e0, $02e1, BASLANGIC ADRESI

Çarpışma Örneği

Çarpışma örneğine biraz daha detay katarak ivmeli hareket eden yaratıkları da görmüş olacağız. Bu örnekte Oyuncu 0 ve Oyuncu 1 kullanılıyor. Her iki oyuncunun da durum, hız, ivme, x ve y koordinatlarından oluşan birer yapısı var. Ayrıca 16 bit toplama ve 8/16 bit yer değiştirme (swap) işlemleri için TOPLA16, DEGISTIR8, DEGISTIR16 isminde 3 adet makro kullanıldı. Bu sayede ACME'de makro kullanımını da görmüş oluyoruz.

Şekil 11.

oyuncu carpismasi.a

BASLANGIC ADRESI $0600
!to "oyuncu carpismasi.xex",plain
;16 bit toplama
!macro TOPLA16 .a, .b (
lda .atl
ele
ade .b*tl
sta .atl
lda .a
ele
ade .b
sta .a
bec .out
inc
)
;8 bit yer degistirme
!macro DEGISTIR8 .a,
lda .a
Sta St9
lda .b
sta
lda
sta
bi
$
.a
$£9
b
)
;16 bit yer degistirme
!macro DEGISTIR16 .a, .b (|
*DEGİSTIR8 .a;
*DEGISTIR8 .a41, .btl
*
BASLANGIC ADRESI-6
lword $£fff, BASLANGIC ADRESI, BITIS ADRESI
*
BASLANGIC ADRESI
;yarat#klar#n bellek adreslerini belirle
lda $6a
sec
sbe
sta
sta
sta
lda
sta
#$08
$6a
$d407 ; PMBASE HI
YaratikBellegitl
#$00
YaratikBellegi
fuzeleri ac
#$03
$d0ld ;
;yarat#k ve
lda
sta GRACTL
iny
;grafik ekrani ac bne Dongul
ldy #$1f ine
sty $022f ; DMACTL ldx $f8
cpx : endOfBlock - *-1
;oyuncularin yatay pozisyonlari bne Dongul
Ol rts
sta $d000 ; Oyuncu 0 X pozisyonu
lida y pozisyonlarina
sta $d001 ; Oyuncu 1 X pozisyonu #goöre olustur
OyunculariOlustur
renkleri lda YaratikBellegi
lda #$aa sta $f5
sta $02c0 ; Oyuncu 0 rengi lda YaratikBellegitl
lda #$cc ele
sta $02cl ; Oyuncu 1 rengi adc #$04
sta $f6
;tüm yaratik bellegini temizle 1
İsr YaratikBelleginiTemizle ldx #$00
ldy Ol Y
olustur Dongu2 HaritaBasi,x
jsr OyunculariOlustur sta ($£5),y
iny
;kesme rutini ayarla inx
ldy #<Rutin cpx #HaritaSonu-HaritaBasi
ldx #>Rutin bne Dongu2
lda #$07
İsr $Şed45c ; SETVBV inc $f6
jmp * 2
ldx #$00
şana ldy 02 Y
Rutin Dongu3 HaritaBasi,x
lda Ol Durum sta ($£5),y
beg Oyuncu2Hareketli iny
şeger oyuncu 1 hareket halindeyse inx
*TOPLA16 Ol Hiz, Ol Ivme cpx #HaritaSonu-HaritaBasi
*TOPLA16 Ol Hiz bne Dongu3
lda Ol Xt1 rts
sta $d000 ; Oyuncu 0 X pozisyonu
jmp CarpismaKontrolu HaritaBasi !byte $00011000
Oyuncu2Hareketli !byte $00111100
şeger oyuncu 2 hareket halindeyse !byte $01111110
*TOPLA16 02 Hiz, 02 Ivme !byte
*TOPLA16 02 X, O2 Hiz !byte
lda 02 X1t1 !byte &11111111
sta $d001 ; Oyuncu 1 X pozisyonu !byte $11111111
;carpisma kontrolu #11111111
CarpismaKontrolu ibyte #11111111
lda $d00c ; Oyuncu O - Oyuncu 1 !byte $11111111
cmp #$02 ; carpisma kontolu !byte
bne RutinSonu !byte $01111110
;Carpisma bayraklarini sifirla !byte $01111110
lda #$00 !byte
sta $d0le ; Carpisma temizleme !byte $00011000
durum ve hizlarini degistir HaritaSonu - *
*DEGIİSTIR8 Ol Durum, 02 Durum
*DEGIİSTIR16 Ol Hiz, O2 Hiz Ol Durum $01
;pes pese carpisma olusmamasi icin Ol Hiz !byte $00,$00
;oyuncularin arasinda carpisma Ol Ivme !byte $08,$00
;sonrasi belirli bir mesafe birak ol X !byte $00,$30
lda Ol ol !byte $74
ele
adc #$08 02 Durum !byte $00
sta 02 Xt1 02 Hiz !byte $00,$00
sta $d001 ; Oyuncu 1 X pozisyonu 02 Ivme !byte $f8,$£ff
RutinSonu 02 X $00,$7c
jmp $e462 ; RETURN o2 Xx !byte $74
#2kb'lik yaratik bellegini temizle YaratikBellegi !byte 0,0
YaratikBelleginiTemizle
lda YaratikBellegi BITIS ADRESI -— *
sta lword $02e0, $02e1, BASLANGIC ADRESI
lda YaratikBellegitli
sta $f8
ele

adc #$08 Değerlendirme

sta endOfBlock
ldy #$00
lda #$00 Bu bölümde net bir biçimde "Oyuncular ve Füzeler", daha genel

Döngü sta ($f7),y tanımıyla "Yaratıklar" konusunu Atari'ye özelleştirilmiş bir biçimde görmüş olduk. Ancak unutmayın ki donanım destekli yaratıklar her ne kadar bilgisayardan bilgisayara farklılıklar gösterse de, kullanım amacı olarak aynıdırlar. Bir bilgisayar üzerinde bu konuyu iyice anladıktan sonra diğer bilgisayarlarda bu konuya kolayca adapte olabilirsiniz. Genellikle;

- ..demek ki Atari'de 8 pixel genişliğinde olan yaratıklar Amiga'da 16, Commodore 64 ve 128'de 24 pixel genişliğindeymiş. Amiga'da da Atari'deki gibi istenilen yükseklikte gösterilebiliyormuş yaratıklar ancak Commodore'da 21 pixel yüksekliğindelermiş ve daha uzun bir yaratık göstermek istenilirse multiplexer isimli bir yöntem kullanılıyormuş."

gibi kıyaslamalarla birçok donanımı daha iyi anlamak ve birbirlerine göre avantajlarını / dezavantajlarını tartmak mümkündür.

İkinci bölümün sonunda henüz Atari'de çok temel kavramları öğrenmiş durumdayız. Aslında klavye, joystick kontrolleri, kesme rutinleri gibi birkaç konuyu daha gördükten sonra basit bir oyun yazmanız için yeterli donanım bilgisine ve örnek kaynak kodlara sahipsiniz. Dilerseniz bir sonraki yazıyı beklemek yerine internet tarayıcınızın adres çubuğuna "http://www.atariarchives.org" yazın ve bir şeyler yapabilmek için bilgi eksikliğiniz olan kısımları araştırmaya başlayın. Kolay gelsin.

emir (at) akaydin (nokta) com