80'li yılların ortalarında, ufacık bilinçsiz bir çocukken tanıştığım Atari 800 XL ile yaşadığım çocukluk aşkının 20 seneden uzun bir mazisi vardır. Ancak ne yazık ki aramızdaki elektrik kalıcı olamadı. Atari, bu 20 seneyi aşkın sürenin en fazla 2-3 senesinde benim hayatımda aktif olarak yer aldı. Çocukluk yıllarımda daha ilkokula gitmezken tanıştığım bu cici bilgisayar beklenenden erken öksürüp tıksırmaya başlayınca, o yılların en popüler bilgisayarı Commodore 64 hayatımda girdi. Artık Atari'nin Commodore ile mücadele etmesi söz konusu değildi. Duygusal Atarim, Commodore ile olan aşkımıza olan kıskançlığından dolayı kısa süre sonra kör oldu (GTIA çipi yandı). Ben de Commodore ile olan aşkımdan kör olmuş olsam gerek, o güzelim bilgisayarı amelyat ettirmeye tenezzül etmedim ve diri diri gömdüm. Ancak yıllar sonra ruhu intikam için geri döndü (Atari800WinPlus Emulatörü).
Şekil 1.
Atari'yi terk etmemde geçerli sebeplerim olduğunu düşünmüştüm hep. Ne de olsa Atari çok daha eski ve ilkel bir bilgisayardı. Commodore 64 ise geleceğin teknolojisi idi. Commodore her konuda Atari'den üstündü. Atarinin o kötü grafikli oyunlarının Commodore versiyonlarıyla mücadele etmesine olanak yoktu. Ne de olsa Commodore hız, görüntü, ses konularında Atari'den kat kat üstündü. Kim takar Atari'yi!!!
Bir çocuğun bakış açısından böyle bir imaj oluşturduğu için Commodore firmasını binlerce kez tebrik etmek lazım. Çünkü yukarıdaki paragrafta geçen düşüncelerden çok azı gerçeği yansıtıyor. Evet, Atari 800 serisi Commodore 64'den yaklaşık 3 sene önce piyasaya sürülmüştü. Yani takvimsel olarak daha eski bir teknolojiydi. Evet, Commodore 64'ün SID çipi eşsizdi. Atari'nin POKEY çipinin sağladığı ses özellikleri ne olursa olsun, sonuçta kulağa ulaşan ses hep Commodore 64'de daha kaliteliydi. Evet, Commodore 64'de 25 satır yani 200 pixel yükseklik varken Atari'de 24 satır, 192 pixel yükseklik mevcuttu. Ancak bunların haricinde Atari, Commodore'dan birçok açıdan çok daha üstün bir bilgisayardı.
Şimdi sırayla Atari'nin sahip olduğu üretim tarihine göre çok üstün olan özelliklerini inceleyelim.
"Bırakın beni, ben kendi kendimi test ederim" diye haykıran, test programları içinde gelen eşsiz aletin ana test ekranı
Şekil 2.
Atari, ana işlemci olarak 6502, görüntü için ANTIC ve GTIA, ses ve giriş/çıkış birimleri için ise POKEY çiplerini kullanır. Atari'nin işlemcisi 1.79 Mhz hıza sahiptir. Hafızası 64K RAM ve 24K ROM'dan oluşur. Cihazın üzerinde 2 joystick portu, çeşitli ek donanım ve kartuş portları bulunmaktadır.
Şekil 3.
Atari, 6502 mimarisini olduğu gibi almış ve kullanmıştır. Commodore 64'de olduğu gibi 6502'ye giriş/çıkış birimleri ekleyerek 6510 gibi özel bir işlemci geliştirme yoluna gidilmemiştir. Bunun yerine POKEY çipi hem ses, hem de seri giriş/çıkış işlemleri için kullanmak tercih edilmiştir.
Atari grafik ve donanım destekli yaratıklar (spritelar) için iki ayrı çipten destek alır. Aslında yapı itibariyle grafiklerin iki katmandan oluştuğunu söyleyebiliriz.
ANTIC çipi Atari'nin bütün text ve grafik modlarını, yatay ve dikey ekran kayması gibi donanım destekleri sağlayan çiptir. Bu çipi en güçlü kılan özellik görüntü listesi (display list) adı verilen, Amiga'nın Copper'ına benzer bir özelliğe sahip olmasıdır. Bu söz konusu görüntü listesi ile her bir satırda (raster/tarama satırı) gösterilecek grafik/text modu değiştirilebilir. Commodore 64'de $d012 tarama adresiyle zahmetlice yapılan birçok iş, bu özellik yardımıyla zahmetsizce yapılabilir. Ayrıca bu özellik, Atari'nin basic dilinden de kolayca kullanılabilme avantajına sahiptir. İlerleyen bölümlerde bu konuyu tekrar ele alacağız.
ANTIC çipi elde ettiği görüntüyü GTIA (ilk üretilen Atarilerde CTIA) çipine aktarır.
GTIA (George's Television Interface Adapter) çipinin asli görevi görüntü sinyallerini televizyona iletmektir. Ancak bu sinyalleri televizyona ulaştırmadan önce görüntünün üzerine yaratıkları basan da yine bu çiptir. GTIA'in yetenekleri bununla da sınırlı kalmaz. Yaratık çarpışmaları, öncelik sıraları ve tüm grafik verilerinin (ANTIC çipinin sağladıkları da dahil olmak üzere) parlaklık kontrolleri bu çip tarafından kontrol edilir. Çipin yeni modellerinde sağladığı bir diğer özellik ise ANTIC çipine ek olarak 3 yeni grafik modunu kullanıma açmasıdır. Bu grafik modları daha fazla renk kullanımına izin verir ancak çözünürlükleri oldukça düşüktür (80x192).
Şekil 4.
Atari 800 XL toplam 16 farklı grafik modu destekler. Atari 800 XE modelleri ise * ile işaretlenmiş 4 adet grafik modunu desteklemezler. Desteklenen grafik modları aşağıdaki tabloda verilmiştir.
|
Grafik Modu |
Açıklama |
Çözünürlük |
Renk |
Parlaklık |
Tarama Satırı |
Byte/Satır |
|
0 (Antic 2) |
1x1 text |
40x24 |
1 |
2 |
8 |
40 |
|
1 (Antic 6) |
2x1 text |
20x24 |
5 |
- |
8 |
20 |
|
2 (Antic 7) |
2x2 text |
20x12 |
5 |
- |
16 |
20 |
|
3 (Antic 8) |
4 renk grafik |
40x24 |
4 |
- |
8 |
10 |
|
4 (Antic 9) |
2 renk grafik |
80x48 |
2 |
- |
4 |
10 |
|
5 (Antic A) |
4 renk grafik |
80x48 |
4 |
- |
4 |
20 |
|
6 (Antic B) |
2 renk grafik |
160x96 |
2 |
- |
2 |
20 |
|
7 (Antic D) |
4 renk grafik |
160x96 |
4 |
- |
2 |
40 |
|
8 (Antic F) |
Tek renk yüksek çözünürlük |
320x192 |
1 |
2 |
1 |
40 |
|
9 (GTIA 1) |
16 parlaklık seviyesi |
80x192 |
1 |
16 |
1 |
40 |
|
10 (GTIA 2) |
9 renk grafik |
80x192 |
9 |
- |
1 |
40 |
|
11 (GTIA 3) |
16 renk grafik |
80x192 |
16 |
- |
1 |
40 |
|
12* (Antic 4) |
Çok renkli 1x1 text |
40x24 |
4 |
- |
8 |
40 |
|
13* (Antic 5) |
Çok renkli 1x2 text |
40x12 |
4 |
- |
16 |
40 |
|
14* (Antic C) |
2 renk grafik |
160x192 |
2 |
- |
2 |
20 |
|
15* (Antic E) |
4 renk grafik |
160x192 |
4 |
- |
2 |
40 |
Tablo 1
* = Yalnızca Atari 800 XL'in desteklediği grafik modları
Şekil 5.
POKEY çipi 4 adet 8 bit ses kanalı desteği sağlar. Ses kanallarının her biri kendi bağımsız frekans, dalga biçimi ve ses düzeyi parametrelerine sahiptir. Daha kaliteli ses elde etmek için 8 bitlik 4 ses kanalı yerine, kanalları 2'şer 2'şer gruplayarak 16 bitlik 2 ses kanalı elde etmek de mümkündür. Hatta istenildiği taktirde 1 adet 16 bitlik ve 2 adet 8 bitlik toplamda 3 ses kanalı kullanma olanağı da vardır.
POKEY çipi ses desteğinin yanı sıra tüm giriş/çıkış işlemlerinden de sorumlu olan çiptir. Özelilkle klavye ile ilgili 6 bitlik bir tarama desteği sağlar. Yani 64 tuşa kadar tuş kontrolü yapabilir. Bunların yanı sıra CTRL, SHIFT, BREAK gibi özel tuşları da farklı biçimlerde algılayabilir.
SKRES, SEROUT, SERIN, SKCTL, SKSTAT isminde 5 farklı register; BREAK, K, SIR, ODN, XD, T1, T2, T4 şekilnde 8 farklı IRQ kesmesi içerir.
Bunların yanı sıra POKEY'de ses kanallarını kullanan 3 adet sayaç mevcuttur. Bu sayaçlar kullanılmaya başlandığında ses kanalları resetlenir. Bu sayaçlar genellikle rastgele sayı üretmek için kullanılmaktadır.
Şekil 6.
Atari bu konuda oldukça esnek tasarlanmıştır. 1088 KB'a (>1MB) kadar ek hafıza destekler. Standart kaset donanımın yanında 5.25 disk drive desteği de mevcuttur. Ayrıca aynı senelerde çıkan diğer birçok platformun aksine Atari'nin ek donanımları standartlaşmış ve bu donanımları destekleyen birçok uygulama ve oyun yayınlanmıştır.
Atari 800 serisinde gelen basic dili oldukça gelişmiş bir basic dilidir. Bu dili en güçlü kılan özellik donanım özelliklerinin birçoğuna rahatça erişebilmesidir. Özellikle grafik modları ve grafik komutları açısından zengin bir dildir. Ayrıca bir grafik modu açıkken satır satır program çalıştırmak için de özel tasarlanmıştır. Atari Basic'i, birçok grafik modu için ekranın alt bölümünde bir text alanı ayırır ve imleç bu alanın sınırlarından dışarı çıkamaz. Bu sayede ekranın üst tarafında bir grafik varken alt tarafta hala basic komutlarını görmek mümkündür. Bununla ilgili hemen bir örnek görelim.
Aşağıdaki satırları Atari 800 XL/XE modellerinin açılış ekranlarında sırayla yazıp Return (Enter) tuşuna basın.
graphics 7 color 1 plot 10,10 color 3 plot 15,10 color 2 plot 20,20 drawto 123,38 graphics 0
Bu komutları girdikçe yukarıda anlatılmak istenen kullanışlılığı göreceksiniz. Elbette ki bu grafik modları tam ekran olarak da basicden kullanılabilirler.
Komutların çıktısı bu şekilde olacaktır.
Şekil 7.
Atari basici ne kadar gelişmiş olursa olsun, 2 Mhz'in altındaki bir bilgisayar söz konusu olduğunda makine dili kullanımı kaçınılmaz bir hal alıyor. Atari'de makine dilinden program yazabilmek için sahip olunması gereken temel bilgi, 6502 assembler programlama bilgisidir. Bu temele sahip olunması durumunda aşılması gereken iki engel daha vardır.
Assembler programı yazabilecek rahat bir ortam oluşturmak.
Atari'nin hazıfa yapısı ve donanımsal özelliklerini öğrenmek.
İlk madde için ihtiyacımız olan şey assemblerdan programlarımızı yazabileceğimiz bir editör/derleyici. Atari üzerinde bu güne kadar bu amaçla en sık kullanılmış derleyici "Atari Assembler Editor" ya da kısaltılmış ismiyle "Atari ASM Edit" kartuşudur. 8 KB'lık bir ROM'a sahip olan kartuş, zamanına göre çok üstün özelliklere sahiptir. Özellikle program içersinde hata yakalamak için (debugging) çok kullanışlı fonksiyonları vardır. Tek eksiği 8 KB'lık hafızaya sığdıramadıkları için hata mesajlarının yalnızca sayısal kodlardan ibaret olmasıdır. Kısacası bir hata aldığınızda ekranda hatanın tanımını değil yalnızca kodunu görürsünüz ve kartuşun dökümanından bu hata kodunun ne anlama geldiğini araştırmanız gerekir. Bu kartuşu kullanmak isterseniz temel kullanım bilgileri aşağıda örneklerle verilmiştir.
Kartuşu taktığınızda "EDIT" yazan bir ekran karşınıza gelecek. Bu ekranda Basic'den program yazar gibi satır numaralarıyla program yazabilirsiniz. Dikkat etmeniz gereken husus, satır numarasından sonra 1 değil en az 2 boşluk bırakmanız gerektiğidir. Örnek program:
10 *= $0600 20 LDA #$C4 30 STA $02C6 40 RTS
Programımızı yazdıktan sonra "LIST" komutuyla programın listesini alabilir ve istediğiniz taktirde "NEW" komutuyla listeyi temizleyebilirsiniz. Programı yazdık ancak program henüz derlenmedi. Programı derlemek için "ASM" komutunu kullanmamız gerekiyor. ASM komutunu yazıp "Return" tuşuna bastığımızda aşağıdaki gibi bir çıktı almamız lazım.
ASM 0000 10 *= $0600 0600 A9C4 20 LDA #$C4 0602 8DC602 30 STA $02C6 0605 60 40 RTS
Eğer aşağıdaki çıktıyı aldıysak programı düzgün bir biçimde derlemeyi becermişiz demektir. Daha sonra programı çalıştırmak ve olası hataları takip etmek için "Edit" bölümünden "Debug" bölümüne geçiş yapmamız gerekiyor. Bunun için kullanacağımız komut "BUG" komutu. Programı çalıştırmak için ise go (git) anlamına gelen "G" harfini kullanacağız. Bu harfin yanına programın başlangıç adresini hexadecimal olarak yazmamız gerekiyor. Kısacası bundan sonra yazmamız gereken komutlar ve ekranda göreceğimiz çıktılar şu şekilde olmalı;
BUG DEBUG G 0600 0003 A=C4 X=00 Y=00 P=B0 S=12
Bu çıktının yanısıra ekran renginin yeşile döndüğünü herhalde fark etmiş olmanız lazım. İşte minik programımızın yaptığı iş de aynen bu. $02C6 hafıza adresi arkaplan renginin tutulduğu adres. $C4 yerine farklı değerler yazarak Atari'nin güzel renk paletini incelemeniz mümkündür.
Son olarak "Debug" moddan çıkıp "Edit" moduna geri dönmek için "X" komutunu kullanıyoruz. Örnek:
X EDIT
Bundan sonra programı değiştirmeye devam edebilir ya da yeni bir program yazmaya girişebilirsiniz. Basic dilinde olduğu gibi aynı satır numarasını tekrar yazıp "Return" tuşuna basarsanız, önceki satır yenisiyle değiştirilecek, yeni satır eskisinin üzerine yazılacaktır.
Programın sonucu Atari'de bu şekilde görünecektir.
Şekil 8.
Programlarınızı derlerken alabileceğiniz hata kodlarının anlamları aşağıdaki listede orijinal dokümanından alındığı şekliyle verilmiştir.
1 : Insufficient memory for assembly
2 : The number xx cannot be found for the "DEL xx,yy" command
3 : Error in specifying an address in mini-assembler
4 : File cannot be loaded
5 : Undefined reference label
6 : Syntax error in a statement
7 : Label defined more than once
8 : Buffer overflow
9 : No label given before "=".
10 : Byte expression is greater than 255
11 : Null string used where invalid
12 : Address or address type specified is incorrect
13 : Phase error: inconsistent result found from pass 1 to pass 2
14 : Undefined forward reference
15 : Line too large
16 : Source statement not recognized by assembler
17 : Line number too large
18 : LOMEM command attempted after other commands/instructions
19 : No starting address given
Program yazmayı, çalıştırmayı öğrendik. Ancak Atari Assembler Editor'ün yetenekleri çok fazla. Eğer gerçekten bu kartuş hoşunuza gider ve kullanmak isterseniz daha fazla detay için "www.atariarchives.org" sitesini gezmenizi öneririm. Özellikle aşağıdaki adreste ihtiyacınız olan diğer komutların bir kısmını bulabilirsiniz.
http://www.atariarchives.org/roots/chapter_5.php
Biz şimdi bu kartuşu kullanmak yerine farklı bir yol çizeceğiz.
Atari Assembler Editor'ün nasıl kullanıldığını gördük. Ancak günümüzde Atari üzerinde çalışmak o kadar da pratik bir yol değil. Birçoğumuzun elinde çalışır halde bir Atari bile yok (ben de dahil olmak üzere). Olanların da çalışmalarını kaset ya da 5.25 disketlere emanet etmek isteyeceklerinden şüpheliyim. Dolayısıyla nostaljik sebepleri bir kenara bırakacak olursak PC ve emülatör kullanarak Atari için program yazmak en güvenilir ve rahat çözüm olacaktır.
Atari için uzun süre çapraz geliştirme ortamımı hazırlamak için araştırmalar yaptım. Bazı açık kaynak kodlu amatörce geliştirilen projelerde kullanılan çapraz geliştirme araçlarını gördüm, inceledim. Ancak dönüp dolaşıp eski bir dost olan ACME Crossassembler'da karar kıldım. Aslında ACME genellikle Commodore 64'e yönelik olarak hazırlanmış bir derleyici. Ancak sonuç olarak 6502 her halikarda 6502'dir. Yani ACME'nin üreteceği binary kodlar Atari'de çalışabilecek durumda olacaklar. Peki bu durumda herşey çözülmüş oluyor mu? Ne yazık ki hayır, biraz daha çaba sarf edeceğiz.
Problemlerimiz neler? ACME'nin üreteceği binary dosyaları Atari'nin hafızasına istediğimiz adresten yükletmek ve çalıştırmak zahmetli bir iş olacaktır. Commodore 64'ün *.prg dosya formatında dosyanın ilk iki byte'ı 16 bitlik bir hafıza adresi içerir ve bu sayede Commodore 64 dosyayı hafızaya nereden yükleyeceğini bilir. Ancak Atari'de durumlar biraz farklı.
Araştırmalarım sonunda Atari'nin otomatik olarak program yüklendiği gibi çalışabilen bir EXE formatını buldum. PC EXE'leriyle karıştırılmaması için genellikle XEX şeklinde uzantı kullanıyorlar. Bu dosyalar kolaylıkla yüklenebiliyor ve çalıştırılabiliyorlar.
Bu dosya formatı programın başlangıç ve bitiş adreslerine ihtiyaç duyar. En temel haliyle format şu şekilde verilebilir.
Kullanacağımız kısaltmalar:
BA : Başlangıç Adresi
BT : Bitiş Adresi
XEX Dosya Yapısı:
2 byte : $ffff (dosya başlığı)
2 byte : BA (16 bit)
2 byte : BT (16 bit)
N byte : Programı bu bölüme yazıyoruz
2 byte : $02e0
2 byte : $02e1
2 byte : BA (16 bit)
Eğer byteları tek tek sıralayacak olursak.
$ff, $ff, BA(alt 8 bit), BA(üst 8 bit), BT(alt 8 bit), BT(üst 8 bit), ... , $e0, $02, $e1, $02, BA(alt 8 bit), BA(üst 8 bit)
Böyle bir byte dizilimiyle karşılaşıyoruz.
Şimdi yukarıda verdiğimiz dosyanın ACME'den nasıl oluşturulduğunu görelim. Atari Assembler Editor için yaptığımız örneğin aynısını ACME'den kullanarak hazırlayalım.
renk.ata
BASLANGIC_ADRESI = $0600 !to "renk.xex",plain * = BASLANGIC_ADRESI-6 !word $ffff, BASLANGIC_ADRESI, BITIS_ADRESI * = BASLANGIC_ADRESI lda #$c4 sta $02c6 jmp $a000 BITIS_ADRESI = * !word $02e0, $02e1, BASLANGIC_ADRESI
Bu örneğin tek farkı sonunda "RTS" yerin" JMP $a000" kullanmamız. Bunun nedeni ise otomatik olarak çalıştırılan programlar Basic'den çağırılmıyorlar. Bu durumda da geri döneceğimiz nokta Basic olmadığı için programdan çıktığımız takdirde bilgisayar reset atıyor ve bunun gibi bir örnekte sonucu göremiyebiliyoruz. Basic'e dönmeden sonucu görmek istersek "RTS" yerine "JMP *" kullanabiliriz. Bu durumda programımız çalışacak ve sonunda sonsuz döngüye girerek kilitlenecektir. Ancak ekran renginin değiştiğini gözlemleyebiliriz. Atari'de Basic'in başlangıç adresi $a000'dır. "jmp *" yerine "jmp $a000" kullandığımız durumda programımız çalışıyor ve basic ekranına güvenli bir şekilde ulaşmış oluyoruz.
Şimdi yukarıdaki örneği inceleyelim. İlk olarak BASLANGIC_ADRESI isimli bir sabit tanımlıyoruz. $0600 rastlantısal bir adres değil. Otomatik olarak çalıştıracağımız programlarımızı bu adrese yerleştirmemiz önemli. Tabii ki istediğimiz taktirde programımız farklı bir hafıza adresine de yerleşebiliyor. Fakat yine de ilk olarak başlangıç adresinin $0600 verilmesi gerekiyor. Daha sonra program istenilen adrese dallanabiliyor.
!to "renk.xex",plain
Bu satırda dikkat etmemiz gereken noktalar şunlar. "renk.xex" derlenmiş programın kaydedileceği dosya ismi. Ancak asıl önemli olan ondan sonraki "plain" parametresi. Eğer ACME'yi Commodore 64'e yönelik kullanıyor olsaydık buraya "cbm" yazardık. Bu sayede otomatik olarak başlangıç adresi programın başına eklenirdi. Kısacası ACME'nin Atari'ye özel bir dosya formatı desteği olsaydı buraya "ATR" gibi birşey yazıp doğrudan programımızı yazmaya geçebilirdik. Ancak ne yazık ki ACME'nin henüz Atari'ye özel bir desteği bulunmuyor. Ama ACME'nin yapımcıları, ACME'nin farklı 6502 tabanlı platformlarda kullanılabileceğini öngördükleri için "plain" parametresini eklemeyi ihmal etmemişler. Bu parametrenin yaptığı şey ise dosyanın başına, sonuna hiçbirşey eklememek ve düz bir binary dosya oluşturmak. Biz bu özelliği kullanarak kendi istediğimiz bir dosya formatını oluşturabiliyoruz.
* = BASLANGIC_ADRESI-6
XEX dosyalarının 6 bytelık bir başlığı (header) bulunuyor. Biz de burada başlangıç adresinin 6 byte öncesine denk gelecek şekilde başlık için pozisyon ayarlaması yapıyoruz.
!word $ffff, BASLANGIC_ADRESI, BITIS_ADRESI
Bu satır dosyanın başlığını oluşturuyor. !word 16 bitlik değerleri doğrudan yazmamızı sağlıyor. Eğer byte byte yazacak olsaydık bu satırı şu şekilde kullanabilirdik. !byte $ff, $ff, <BASLANGIC_ADRESI, >BASLANGIC_ADRESI, <BITIS_ADRESI, >BITIS_ADRESI
* = BASLANGIC_ADRESI
Programın başlangıcına geldik. Aslında bu satırı yazmasak da tam 6 bytelık bir başlık tanımladığımız durumda aynı noktada olmamız gerekiyor. Ancak hem programın daha rahat okunması için hem de bir tedbir olarak bu satırı ekledik.
BITIS_ADRESI = *
Programın bitiş adresini baştan tanımlamak mantıklı bir yol değildir. Çünkü program uzayıp kısaldıkça bitiş adresi değişecektir. Her defasında bu adresi bulmaya uğraşmak da çok mantıklı bir seçenek değildir. Bu yüzden programın sonuna geldiğimizde "*" sembolünü kullanarak program adres sayacının değerini BITIS_ADRESI'ne eşitliyoruz. Bu da doğrudan olarak başlıktaki yerini alıyor.
!word $02e0, $02e1, BASLANGIC_ADRESI
$02e0 ve $02e1 adresleri Atari'nin disk işletim sistemi tarafından kullanılan adresler. Programın sonuna eklediğimiz BASLANGIC_ADRESI'de yine programın çalıştırılacağı başlangıç adresinin yer aldığı yer.
Elbette ki bu örneği unutmuş değiliz. Atari'de ekrana yazı yazdırmanın birkaç farklı yolu var. Şimdilik diğer hafıza adreslerine çok bulaşmadan yalnızca ekran adreslerine kopyalama yaparak nasıl ekrana yazı yazdırıldığını görelim.
merhaba_dunya.ata
BASLANGIC_ADRESI = $0600 EKRAN = $9c40 !to "merhabadunya.xex",plain * = BASLANGIC_ADRESI-6 !word $ffff, BASLANGIC_ADRESI, BITIS_ADRESI * = BASLANGIC_ADRESI ldx #$00 dongu lda YAZI,x sta EKRAN+82,x inx cpx #YAZI_SONU-YAZI bne dongu jmp $a000 YAZI !text "merhaba",0,"dunya" YAZI_SONU = * BITIS_ADRESI = * !word $02e0, $02e1, BASLANGIC_ADRESI
Atari'nin text ekranının başlangıç adresi $9c40'dır. Programın başında EKRAN sabitine bu değeri veriyoruz. Daha sonra bir döngü ile YAZI'da tanımladığımız karakterleri ekrana basıyoruz. Toplamda kaç karakterin kopyalanacağını YAZI'nın bitimine koyduğumuz YAZI_SONU adresiyle YAZI'nın farkını alarak bulabiliyoruz.
EKRAN'ın başlangıcı basic'de imleçin dolaşabildiği alanın biraz dışında kalıyor. EKRAN'a 82 ekleyerek basic'de "READY" yazan satırın tam altına yazıyı yazdırmış oluyoruz.
Şekil 9.
Son olarak dikkat edilmesi gereken nokta "!text"in Atari'nin ASCII karakter kodlarına uygun sonuç üretmediğidir. Küçük harfler söz konusu olduğunda bir problem yaşamazsak da diğer birçok karakter (boşluk karakteri de dahil olmak üzere) farklı sonuçlar verecektir. Bu yüzden, gerektiği yerde, karakter kodlarının kullanılması gerekiyor. Örneğin boşluk karakteri !text ile yazdırıldığında $20 (32) karakter kodunu oluşturur. Bu Commodore 64'de boşluğa denk gelirken Atari'de @ karakterine denk gelir. Atari'de boşluk karakteri 0 kodundadır. Bunun için "merhaba dunya" yerine "merhaba",0,"dunya" yazmamız gerekiyor.
Atari'de Assembler'dan grafik ekranı açmak oldukça kısa bir program parçasıyla yapılabiliyor. Örnek vermek gerekirse;
LDA #$00 STA $022f LDA #<GORUNTU_LISTESI STA $0230 LDA #>GORUNTU_LISTESI STA $0231 LDA #$22 STA $022f
bu program parçası istenilen grafik modunu açabilir. $022f adresiyle Antic çipini yönetebiliyoruz. Bu adrese 0 değeri verdiğimizde Antic çipi kapanıyor. Böylece Antic çipinin okuduğu görüntü listesini (display list) değiştirme imkanı elde ediyoruz. $0230 ve $0231 adresleri bu listenin işaretçisi. $0230'a listenin yer aldığı hafıza adresinin alt byteını, $0231'e ise üst byteını koyuyoruz. Örneğin görüntü listemiz $2560 adresinde yer alıyor ise $0230'a $60, $0231'e $25 değeri vermemiz gerekiyor. Son olarak $022f adresine $22 değerini yazarak yeniden Antic çipini aktif ediyoruz ve yeni ekran görüntümüzle karşılaşıyoruz.
Buradaki soruişaretleri şunlar. $00, $22 gibi değerler nereden geliyor? Görüntü listesi tam olarak nasıl birşey?
$022f adresi tanımlamalarda genellikle SDMCTL şeklinde kısaltılmıştır. Anlamı DMA kontrol registerını kaydet demektir. Bu adrese yazılan değerler birer komut olarak algılanır. Yani $00 - Antic çipini kapat anlamına gelirken $22 - Antic çipini aktive et anlamına gelir.
Görüntü listesi komutlar ve bu komutların parametrelerinden oluşan bir listedir. Bu yönüyle Amiga'nın Copper'ına benzetilebilir. Yukarıdaki program parçasında hangi grafik modunun açılacağı belirtilmemiştir. Bu tamamen görüntü listesinde yer alan değerlerle belirlenir.
Görüntü listelerinde kullanılabilecek komutlar aşağıdaki gibidir.
Boş Tarama Satırı Kodları:
$00 : 1 boş satır
$10 : 2 boş satır
$20 : 3 boş satır
$30 : 4 boş satır
$40 : 5 boş satır
$50 : 6 boş satır
$60 : 7 boş satır
$70 : 8 boş satır
Görüntü Kodları:
$02 : Text Mod 0
$03 : Text Mod *
$04 : Text Mod *
$05 : Text Mod *
$06 : Text Mod 1
$07 : Text Mod 2
$08 : Grafik Mod 3
$09 : Grafik Mod 4
$0A : Grafik Mod 5
$0B : Grafik Mod 6
$0C : Grafik Mod *
$0D : Grafik Mod 7
$0E : Grafik Mod *
$0F : Grafik Mod 8
(*) ile işaretli modlar basicden kullanılamayan modlardır.
Sıçrama Kodları:
$01 : Adrese sıçra
$41 : Adrese sıçra ve taramayı yakalamayı bekle
Örneğin;
* listeye $06 değeri yazılarak ANTIC 6 (bkz: Tablo 1) moduna geçilebilir.
* 8 satır, yani 1 normal karakter yüksekliği boşluk vermek için $70 değeri kullanılabilir.
* $01 komutu ile liste içersinden bir hafıza adresine sıçramak ve listeye oradan devam etmek mümkündür. $41 komutu ise sıçrama ve tarama yakalanana kadar bekleme anlamlarına gelmektedir. $01 ya da $41'den sonra gelen 16 bitlik adres, sıçranacak hafıza adresidir. Listenin başlangıç adresinin verilmesi durumunda sabit olarak o listeye uygun olan grafik ekranı açık kalacaktır.
Görüntü listesinin özellikleri bunlarla da bitmez. Görüntü kodları yalnızca 0,1,2 ve 3 numaralı bitler kullanılacak verilebilmektedir. 4,5,6 ve 7 numaralı bitler ise farklı özellikleri devreye sokarlar. Yani;
%XXXXYYYY
YYYY : Görüntü kodu
XXXX : Ek parametreler
şeklinde düşünülebilir. Bu parametreler şunlardır:
Bit 4: Dikey Kayma (Vertical Scroll). [Görütü kodu+$10]
Bit 5: Yatay Kayma (Horzontal Scroll). [Görütü kodu+$20]
Bit 6: Hafıza Taraması Yükleme (Load Memory Scan). [Görütü kodu+$40]
Bit 7: Görüntü Listesi Kesmesi (Display List Interrupt). [Görütü kodu+$80]
Eğer 6. biti yani "Hafıza Taraması Yükeleme"yi kullanacak olursak görüntü listesinde bu görüntü kodunun ardından gelen iki byte ekran adresinin başlangıcına işaret eder. Yani görüntü kodunu $06 yerine $06+$40 = $46 şeklinde kullanacak olursak yine ANTIC 6 grafik modu açmış oluruz ancak bu defa sonrasında gelen 2 byte’ın değeri ile ekran adresinin farklı bir adrese kaydırılması sağlanmış olur. Bu işlem farklı satırlar için defalarca tekrarlanabilir.
Şimdi bu öğrendiklerimizi bir araya getiren bir örnek görelim.
grafik.ata
BASLANGIC_ADRESI = $0600
SDMCTL=$022F
SDLSTL=$0230
SDLSTH=$0231
RENK0=$02C4
RENK1=$02C5
RENK2=$02C6
RENK3=$02C7
RENK4=$02C8
!to "grafik.xex",plain
* = BASLANGIC_ADRESI-6
!word $ffff, BASLANGIC_ADRESI, BITIS_ADRESI
* = BASLANGIC_ADRESI
; Renkleri Ayarla
lda RENK3
sta RENK1
lda RENK4
sta RENK2
; Grafik Ekranini Ac
lda #0
sta SDMCTL
lda #<GORUNTU_LISTESI
sta SDLSTL
lda #>GORUNTU_LISTESI
sta SDLSTH
lda #$22
sta SDMCTL
jmp $a000
; Yazilar
SATIR1 !TEXT 0,0,0,0,0,0,"satir",0,"bir",0,0,0,0,0
SATIR2 !TEXT 0,0,0,0,0,0,"satir",0,"iki",0,0,0,0,0
SATIR3 !TEXT 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
!TEXT "satir",0,0,"uc",0,0,0,0,0,0,0,0,0,0
SATIR4 !TEXT 0,0,0,0,0,0,"satir",0,"dort",0,0,0,0
; Goruntu Listesi
GORUNTU_LISTESI
; Bos Satirlar
!byte $70,$70,$70,$70,$70,$70,$70,$70
; Antic 6 Grafik Modu + Hafiza Taramasi Yukleme
!byte $46
; Ekran Hafizasini SATIR1'e Ayarla
!word SATIR1
; Bos Satirlar
!byte $70,$70,$70,$70
; Antic 7 Grafik Modu + Hafiza Taramasi Yukleme
!byte $47
; Ekran Hafizasini SATIR2'ye Ayarla
!word SATIR2
; Bos Satir
!byte $70
; Antic 2 Grafik Modu + Hafiza Taramasi Yukleme
!byte $42
; Ekran Hafizasini SATIR3'e Ayarla
!word SATIR3
; Bos Satirlar
!byte $70,$70,$70,$70
; Antic 6 Grafik Modu + Hafiza Taramasi Yukleme
!byte $46
; Ekran Hafizasini SATIR4'e Ayarla
!word SATIR4
; Bos Satirlar
!byte $70,$70,$70,$70,$70
; Adrese Sicra ve
; Tarama Yakalanana Kadar Bekle
!byte $41
; Sicranacak Adres
!word GORUNTU_LISTESI
BITIS_ADRESI = *
!word $02e0, $02e1, BASLANGIC_ADRESI
Bu örnek ANTIC 6, ANTIC 7, ANTIC 2 ve tekrar ANTIC 6 grafik modu açarak her bir modda birer satır yazı yazar. Ancak bu yazı yazma işlemi ekrana bir çıktı vererek değil hafızada yazıların bulunduğu adresler ekran adresi olarak değiştirilerek yapılır. Kısacası ANTIC çipinin ve bu çipin bize sağladığı görüntü listesi özelliğinin gücünden yararlanır.
Şekil 10.
Atari ile ilgili anlatılacak daha çok fazla konu var. Araştırmalarım sonunda Atari'nin yapabilecekleri, donanımını kullanma gücü ve sınırları ile ilgili çok ilginç bilgiler edindim. Elbette ki ister istemez benim 20 yıllık aşkım olan ve yine 6502 mimarisinden gelen Commodore 64 ile de sık sık mukayese ettim. İlginç olan şudur ki bir iki konu haricinde Atari 800 XL/XE modelleri Commodore 64'ü ezip geçiyor. Atari'nin piyasadan silinmesinin ardından Commodore 64'ün uzun yıllar varlığını sürdürebilmesi ve Atari'ye göre satış rakamlarındaki büyük fark, Commodore firmasının başarısını kanıtlayan öğelerden biri. Bunca yıl boyunca kandırılmışız. Atari Commodore'dan daha üstün bir bilgisayarmış (her konuda olmasa da). :)
Aslında bu yazıyı bir yazı serisi olarak tasarlamamıştım. Yazının çıkış noktası ACME kullanarak Atari üzerinde nasıl çapraz geliştirme yapılabileceğini anlatmaktı. Ama yazıyı yazmaya gelince işler bazen değişiyor. Beklediğimden çok daha fazla detaya girmek durumunda kaldım. Bu da bir bakıma bu yazının devamı olacağını gösteriyor.
Daha anlatılacak neler mi var? Öncelikle donanımda gelen "Oyuncular ve Füzeler" konusundan bahsetmek çok eğlenceli olacaktır. Böyle bir başlık atmak bile başlı başına bir zevk :) Ayrıca biraz daha intro/demoya yönelik olarak kayan yazılar, grafik ekranına şekiller çizdirme, renkler ve parlaklık değerleri ile yapılabilecek efektler gibi konular işin olmazsa olmazları gibi duruyor. Tabii ki kesme rutinleri, ses özellikleri ve diğer birçok konu bu yazının birden bile fazla devam yazısı olabileceğini gösteriyor.
Bu yazıyı hazırlarken birçok kaynaktan yararlandım. Ne de olsa bu platformla en son uğraştığımda 8-9 yaşlarındaydım. O zamanlar öğrendiğim 3-5 basic komutunun üzerine epey bir bilgi eklemem gerekti haliyle. Bu yazıyı hazırlamadan önceki birkaç aylık öğrenme sürecimi de hesaba katacak olursak, tek tek faydalandığım bütün kaynakların listesini veremesem de temel olarak kullandığım iki kaynağı belirtmek isterim:
Atari Archives:
http://www.atariarchives.org/
Wikipedia'da Atari 800:
http://en.wikipedia.org/wiki/Atari_800
Atari Archives çok geniş bir arşiv. Giriş sayfasındaki görüntü ilk bakışta içeriksiz bir reklam sitesi gibi dursa da aşağıdaki banner benzeri linklere tıkladıkça o linklerin hepsinin altında büyük birer bilgi hazinesi yattığını görüyorsunuz. İngilizce okuma düzeyi yeterli olan herkese tavsiye ederim.
Bir sonraki sayıda 2. bölümde görüşmek dileğiyle, hoşçakalın. [televizyonvari bir bitiriş oldu... ;)]
emir (at) akaydin (nokta) com