AMIGA ASSEMBLER
Retro bilgisayar
Bu bölümde geçen ay kaldığımız yerden devam edeceğim. İsterseniz hemen programımızın açıklamasına geçelim. Açıklamadan sonra bu ay assembler'da mevcut tüm komutları kısa kısa açıklayacağım. Ardından da (herhalde bu ayki yer yetmez) intuition library'si içinde dolaşmaya devam edeceğiz.
Dilerseniz programımızın diğer kısımlarını incelemeden geçelim; zira artık hep aynı temel source rutinini kullanıyoruz. Bu sefer rutinimizde geçen aya göre değişen satırlar şöyle:
*Yeni bir alt rutin eklenmiş durumda: İNİTBITMAPS.
*PUTGFX alt rutinine baktığınızda, bu rutinin değişmiş olduğunu görebilirsiniz.
*Ayrıca label listelerinin bulunduğu yerde de yeni birkaç label mevcut. Bunların isimleri şöyle: SBITMAP, DBITMAP, SRAST, DRAST.
Structure ismi : RastPort Ait olduğu library : graphics.library Kapladığı yer: 100 byte
Ofset Tip Tanımı 0 longword Layer 4 longword BitMap 8 longword AreaPtrn 12 longword TmpRas 16 longword AreaInfo 20 longword GelsInfo 24 byte Mask 25 byte FgPen 26 byte BgPen 27 byte AOlPen 28 byte DrawMode 29 byte AreaPtSize 30 byte linpatcnt 31 byte >dummy< (boş b 32 word Flags 34 word LinePtrn 36 word cp_x 38 word cp_y 40 longword minterm[0] 44 longword minterm[1] 48 word PenWidth 50 word PenHeigth 52 longword Font 56 byte AlgoStyle 57 byte TxFlags 58 word Txheight 60 word TxWidth 62 word TxBaseline 64 word TxSpacing 66 longword RP_User 70 }ilersi için 96 }rezerve edilmiştir
Daha önce de belirttiğim gibi, bu rutin yardımıyla pencere kenarını bozmadan pencere içerisine grafik koyabilmekteyiz. Bütün bu yeni eklemeleri de anlayabilmek için, dilerseniz ilk önce bitmap structure'ına göz atalım. Bitmap structure'ını Tablo I'de bulabilirsiniz. Gelelim bu structure'ın detaylı bir açıklamasına. İlk longword olan Layer, rastport'a bağlı olan layer'ı gösteren bir pointer'dır. Şu sıralar layer'larla ilgimiz olmadığı için bu bilgiyi geçiyorum. Fakat merak edenler varsa, bu layer'ların nerede kullanıldığını kısaca bir tanımlayayım. Layer'lar window'lar üst üste geldiklerinde ("overlapping") altta kalan kısımların kesilmesinden oluşan parçalara verilen addır. İki window üst üste geldiklerinde altta kalan ve gözükmeyen parça silinecektir. Window'lar tekrar ayrı ayrı gösterildiğinde ise bu silinen kısmı telafi etmek gerekecektir. Buna da sistemi yazanlar gayet basit bir çözüm bulmuşlar: Layers library. Bu library ve fonksiyonları sayesinde bu kesilen kısımlar gayet sistematik bir şekilde kontrol altında bulundurulmakta. İki window ya da screen üst üste bindiğinde sistem rutinleri silinen kısmı ilk önce bir buffer'a kopyalarlar. Daha sonra window'lar ayrı olarak yerleştirildiğinde de bu buffer'daki bilgi tekrar yerine konularak penceremizin içeriği kurtarılmış olur. Nasıl, çok basit değil mi?
Structure ismi: BitMap Ait olduğu library : graphics.library Kapladığı yer: 40 byte
Ofset Tip Tanımı 0 word BytesPerRow 2 word Rows 4 byte Flags 5 byte Depth 6 word >dummy< 8 longword Planes[1 12 longword Planes[2 16 longword Planes[3 20 longword Planes[4 24 longword Planes[5 28 longword Planes[6 32 longword Planes[7 36 longword Planes[8
Tablo I ■ RastPort ve BitMap
structure 'lan
Rastport structure'ımızdaki ikinci longword ise Bitmap. Bu da, bundan sonra hepimizin kullanacağı bir pointer ve Rastport'a ait bitmap'i gösteriyor. Bunun için de tabii ki bitmap'imizin daha önceden açılmış olması gerekmekte. Bu bitmap'i rastport'a bağladığımızda, rastport structure'ındaki bütün özellikler bitmap'lerde de var olacaklardır. Bunun için bitmap ve rastport kullanırken devamlı bunları birbirine bağlamayı unutmamalıyız. Üçüncü longword AreaPtrn adını taşımakta. Bu longword yardımıyla graphics.library'deki AreaFill fonksiyonunu kullandığımızda doldurulacak bölgeyi tanımladığımız pattern ile doldurur. Pattern'ı başka bir structure ile tanımlamamız gerekli. İleride bunun nasıl yapılacağını da göreceğiz. Bu pattern structure'ımın boyutunu da sisteme tanıtmalıyız. Bunun için de AreaPtSz byte'ını kullanmalıyız.
AMIGA ASSEMBLER
TmpRas ikincil (temporary) bir rastport'u göstermektedir. Bunu, rastport structure'ına zarar vermek istiyorsak kullanabiliriz. Fakat bunu kullanmak bir hayli karışıktır. Bu yüzden buna ilerde daha detaylı değinmeyi düşünüyorum. AreaInfo, yine AreaFill fonksiyonunda kullanılmak için bir longword'dur ve doldurulacak alan hakkında önemli bilgiler içeren structure'ı gösteren bir pointer'dır. GelsInfo longword'u da bir önceki longword gibi bir pointer ve Gels'leri tanımlamak için kullanılan structure'ı gösteriyor. Gels'ler, bildiğimiz boblardan başka bir şey değil. Ancak tümüyle library kontrolünde yapıldığı ve kullanıldığı için bunlarda hiçbir sorun çıkmaz. Mask, rastport'umuzda kullanılabilecek olan maskeleme bitplane'ini (Deluxe Paint'de stencil fonksiyonu) gösteren başka bir pointer'dır. Ne kadar çok pointer var değil mi? Programınızın her model Amiga'larda çalışmasını istiyorsanız, bütün bu kurallara dikkat etmeniz gerekiyor. Aksi takdirde gelecekte çıkabilecek tüm Amiga modellerinde de programlarınız bir guru mesajı vermekten öteye gidemezler!
FgPen ve BgPen birer byte'lık data'lardır ve rastport'taki kalem ve zemin rengini belirlemek için kullanılır. Bundan sonraki byte AOlPen ismini taşır ve areafill fonksiyonunda dış çerçevenin rengini belirleyen byte'dır. DrawMode, boyama, yazı yazma ve çizgi çizmede kullanılacak çizim modunu belirlemek için kullanılır. Amiga işletim sisteminin 4 ayrı çizim modu vardır: JAM1, JAM2, COMPLEMENT ve INVERSVID. JAM1 (=0) modunda zemin renk, çizim rengiyle AND'lenir. JAM2'de (=1) ise kullanılan işlem OR'dur. COMPLEMENT (=2) modunda XOR işlemi yapılır. INVERSVID (=4) ise yazıların negatif olarak basılmasını sağlar.
LinePtrn byte'ı o anki çizgi çizim maskesini gösterir. Bundan sonraki byte kullanılmaz. Sadece bundan sonraki dataların çift sayılı bir adrese denk gelmelerini sağlamak içindir. Bu yüzden bu byte'a dummy adını vermişler. Flags ile ne çeşit ekran kullanıldığını anlayabiliriz. Bu word'ün içeriğindeki her bir bit, başka bir anlam taşır. Bu bitlerin dökümü Tablo II'de yer almakta. Bir sonraki word'ümüz LinePtrn adını taşır ve çizgi maskesini tanımlamak için kullanılır. Bu çizim maskesi sadece bir piksel enindeki çizgiler için kullanılır. Daha yukarıdaki çizgi maskesi ise daha geniş çizgiler çizerken kullanılacak olan maskeyi tanımlamak için kullanılmakta. Ardından gelen iki word olan cp_x ve cp_y grafik kursorunun o anki ekran pozisyonunu gösterir.
minterms[8], blitter işlemlerinde kullanılan minterm bilgisini (blitter işlem kodunu belirler) taşır. Blitter ve minterm hakkında daha detaylı bilgiyi diğer assembler yazımda detaylı olarak açıklayacağım. Bundan sonraki iki word PenWidth ve PenHeight, çizim kalemimizin boyutlarını belirlemeye yarar. TextFont longword'u kullanılan font'un structure'ını gösteren bir pointer. AlgoStyle yazı yazarken kullanılacak yazım modunu belirler. Bu yazım modu yardımıyla aynı fontla değişik stillerde (italik, altı çizgili ya da bold) yazılar yazabilmek mümkün. Tablo III'te bu yazı stilleri ve kodları yer almakta. Bundan sonraki 5 data, kullanılan fontla ilgili bazı bilgiler içeriyor. İlk bilgimiz TxFlags. Bu word, kullanılan fontun tipini belirleyen flag'lerin yer aldığı word'dür. Bu flag'lerin anlamlarını Tablo IV'de görebilirsiniz. TxHeight, kullanılan fontun yüksekliğini, TxWidth ise genişliğini gösteren iki word'dur. TxBaseline, fontun taban çizgisinin font içinde ne kadar yükseklikte kaldığını belirler. TxSpacing ise her karakter arasında bırakılacak boşluğu gösteren bir word'dur. Son longword'ümüz olan RPJUser, özel kullanımlar için ayrılmıştır. Bundan sonra gelen 32 byte'lık alan ise ilerki gelişmeler için rezerve edilmiştir.
Rastport structure'ını da bitirdiğimize göre artık Bitmap structure'ına geçebiliriz. Bu hayli kısa bir structure (40 byte). Bu yüzden fazla yer kaplayacağını sanmam. Yine bu structure'ı düzenli bir şekilde ofset değerleriyle tablo olarak veriyorum (Tablo V).
BytesPerRow ile, o bitmap'te satır başına düşen byte sayısı belirlenir (=(piksel sayısı/8)+1). Rows, satır adedini belirler. Flags, bize o bitmap'de kullanılan flag'leri gösterir. BitMap structure'ımızdaki 5. byte olan Depth o bitmap içersinde kullanılan bitplane adedini gösterir. Pad adıyla tanımlanan word boştur ve ileriki kullanımlar için rezerve edilmiştir. 8. byte'tan sonra yer alan tablo, bitmap'e ait tüm bitplane'leri gösteren bir tablodur. Sırayla her bir longword'de bitplane'lerin adresleri yer alır. Gördüğünüz gibi sistem structure'ları aslında 8 bitplane için rezerve edilmiş. Bu ilerde yapılabilecek geliştirmeler içindir. Her konuda olduğu gibi Amiga library'ler ve structure'lar ilerki gelişmelere yönelik hazırlanmış. Bu şekilde bilgisayar devamlı kendini yenileyebilmekte. Oysa Amiga'dan üstün birçok bilgisayar geliştirilemediğinden batmış durumda (bu bilgisayarlar en güzel örnek Archimedes bilgisayarı). İlerisi için düşünülüp rezerve edilen byte'lara dokunmamanızı öneririm. Programınız KickStart'ın yeni versiyonlarında sorun çıkarabilir.
Programımızda açıklayacağım iki altyordamdan biri INITBITMAPS. Burada ilk önce graphics.library base'ini A6'ya atıyoruz. Bu şekilde bundan sonra jsr - xxx(A6) komutu kullandığımızda graphics.library'den bir fonksiyon kullandığımıza emin olabiliriz. Her zaman bir library fonksiyonunu çağırmadan önce doğru library base adresini A6 register'ına atın. Aksi halde böyle saçma sapan bir hata epey değişik sonuçlar doğurabilir. Siz de programı yazmak için harcadığınız sürenin en azından 2 katını hatayı aramak için geçirirsiniz. Bazen böyle çok ufak hatalar göze çarpmaz. Her neyse, gelelim sonraki satırlara. Burada yeni bir library fonksiyonu görüyoruz: INITBITMAP. Bu fonksiyon yardımıyla bir bitmap açabiliriz. Bunun için fonksiyonu çağırmadan önce bazı register'lara değerler atamalıyız. Bu değerlerden ilki, bitmap structure'ını barındırabilecek büyüklükte bir hafıza alanı. Bu alanın aynı anda çalışabilecek başka programlar tarafından da yanlışlıkla silinmesini engellemek için bölgeyi BLK komutu ile rezerve etmeliyiz. Hafıza ayırmak için bir diğer yöntem de exec.library'sindeki AllocMem fonksiyonu. Fakat bunu daha ilerde göreceğiz. Bitmap structure'ımızın bulunacağı hafıza bölgesinin başlangıç adresini A0 register'ına atmalıyız. D0'a bitmap'de kullanılacak bitplane adedini gireriz. D1 ve D2 register'ları da bitmap'imizin kaç piksel büyüklüğünde olacağını belirlemek içindir. InitBitMap fonksiyonunun library ofseti, -390 ($186)'dır. Bitmap'imize ait bitplane'lerin her birinin adresini de belirlememiz gerekmekte. Bunu aşağıda yapacağız.

Bu alt rutindeki ikinci kullanılan library fonksiyonu InitRastPort. Kullanımı gayet basit. Açılacak RastPort structure'ını barındıracak bir hafıza bölgesinin adresini A1'e atamamız ve fonksiyonu çağırmamız yeterli. Fonksiyonun library ofseti -198 (=$c6).
InitBitMap ve InitRastPort fonksiyonlarının parametrelerini Tablo V'te görebilirsiniz.
InitRastPort fonksiyonunu çağırdıktan sonra structure için ayrılan bölgede sadece bazı temel datalar değişecektir. Bunlar şöyle: Mask, FgPen, BgPen ve LinePtrn isimli datalar -1 ($ffff) değerini; DrawMode datası ise 1 (=JAM2) değerini alır. Font dataları ve pointer'ı, kullanılan sistem fontunu gösterir. Bu yüzden RastPort structure'ındaki BitMap datasını değiştirmemiz gerekmekte. Bunu da 'move.l #SBITMAP,SRAST+4' satırıyla gerçekleştirdim. Az önce açtığımız bitmap structure'ının adresini (=SBITMAP) RastPort structure'ımızın (=SRAST) 4. byte'ından sonrasına longword olarak yazıyoruz. Böylece SBITMAP, SRAST structure'ına bağlı bir structure olacaktır. Şimdi de demin belirttiğim gibi bitmap structure'ındaki bitplane adreslerini doğru olarak girmemiz gerekmekte. Bir bitplane kullandığımız için sadece 8. ofsetteki longword'a PIC'in adresini yazıyoruz. PIC, programın sonunda tanımlanmış olan bir label. Bura-
Tanımı bit numarası Anlamı
MODE 640 15 Med-res PLNCNTMSK 14,13,12 Bitplane adedi (binary olarak) PF2PRI 7 Double playfield'de 2.playfield'i üste getirir. HOLDNMODIFY 11 HAM modunu açar. DBPLF 10 Double playfield modunu açar. INTERLACE 2 Interlace ekran açar. COLORON 13 Renkli grafik modunu açar/kapatır. Tablo II - RastPort structure'u grafik modu flag'ları
Tanımı Değeri Açıklama FSF NORMAL 0 Hiçbir özellik yok. FSF EXTENDED 8 Geniş font (60 kolonluk yazı ekranı) FSF ITALIC 4 İtalik yazı FSF BOLD 2 Bold yazı FSF_UNDERLINED
Tablo III- Font
1 Altı çizili yazı stilleri (kombinasyon yaratmak için değerleri toplayınız.)
Tanımı FPF ROMFONT FPF DISKFONT FPF TALLDOT FPF WIDEDOT FPF PROP. FPF REMOVED
Değeri 1 2 4 16 32 128
Açıklama Font ROM'da yer almakta. Font disketten yüklenmiştir. hires non-interlace modunda kullanmak için. lores interlace modu için font. Proporsiyonal font. Font hafızadan silinmiştir.
Tablo IV - Font flag'ları

da INCBIN kullanarak hem hafıza ayırıyoruz, hem de disketten bir data dosyası (binary) okuyoruz. Bundan sonra gelen satırlar hemen hemen deminkilerin aynısı. Değişen tek şey sadece son beş satır:
lea DBITMAP,a3
move.l RASTPORT.aO
move.l 4(a0),al
move.l 8(al),8(a3)
rts
Burada daha önce OpenWindow fonksiyonundan elde ettiğimiz
window'a ait RastPort structure'ının adresini AO'a, bizim açmış
olduğumuz DBITMAP structure'ının adresini ise A3'e atıyoruz.
Ardından da window'a ait RastPort'un 4. byte'ından sonra gelen
longword'u Al'e kopyalıyoruz. Bu, window'umuza ait olan Bit-
Map structure'ının adresidir. Son satırla da bu BitMap structure-
'ındaki ilk bitplane adresini alıp bizim RastPort structure'ına ilk
bitplane adresi olarak yazıyoruz. Bu şekilde DBITMAP'in bitp-
lane'iyle window'un bitplane'i aynı yerde olmakta.
Gelelim bir sonraki alt rutinimiz olan PUTGFX'e. Burada açmış olduğumuz bitmap'lerden birindeki resim datasını diğerine (ekrana) kopyalamamız gerekmekte. Daha önce anlattığım yöntem sistem kurallarını hiçe sayarak çalıştığından, window'un kenarlarını tahrip etmekteydi. Burada ise graphics.library'den bir fonksiyon kullanacağız. Bu fonksiyonun adı BltBitMap ve amacı bir bitmap'e ait bitplane'lerden dörtgen bir alanı başka bir bitmap structure'ına ait bitplane'lere kopyalamak. Fonksiyonu çağırmadan önce yine doğru library base adresini A6'ya atıyoruz. Bundan sonraki satırlarda fonksiyonun ihtiyacı olan bazı parametreleri çeşitli register'lara yazıyoruz. Bu parametreler ve ait oldukları register'lar şöyle:
A0-srcBitMap: Source (kaynak) BitMap structure'ının adresi. A1-destBitMap: Destination (sonuç) BitMap structure'ının adresi.
A2-tempA: Source ile destination aynı bitplane'deyse ve bu kopyalanacak dörtgenle sonuç dörtgenin koordinatları çakışıyor-
Fonksiyon ismi: OldOpenLibrary Bulunduğu library: 'exec.library' Ofseti: -408 (=-$198) Parametreler: * giriş bilgileri: LibName->a1 * çıkış bilgileri: d0->LibBase ya da 0
Fonksiyon ismi: Text
Bulunduğu library: 'graphics.library' Ofseti: -60 (=-$3c) Parametreler: * giriş bilgileri: String -> a0; RastPort -> a1; Count -> d0 * çıkış bilgileri: yok
Fonksiyon ismi: InitBitMap Bulunduğu library: 'graphics.library' Ofseti: -390 (=-$186) Parametreler: * giriş bilgileri: BitMap-> a0; Depth -> d0; Width -> d1; Height -> d2 * çıkış bilgileri: yok
Fonksiyon ismi: InitRastPort Bulunduğu library: 'graphics.library' Ofseti: -198 (=-$c6) Parametreler: * giriş bilgileri: RastPort -> a1 * çıkış bilgileri: yok
Fonksiyon ismi: BltBitMap Bulunduğu library: graphics.library' Ofseti:-30 (=-$1 e) Parametreler: * giriş bilgileri: SrcBitMap - > aO; DestBitMap -> a1; TempA -> a2 SrcX -> dO; SrcY -> d1; DestX -> d2; DestY -> d3 SizeX -> d4; SizeY -> d5: Mınterm -> d6; Mask -> d7 * çıkış bilgileri: yok Tablo 5 - Library Fonksiyonları sa bu register hafızada boş bir alanı göstermelidir. Bu alanın boyutu kopyalanacak alan * bitplane sayısı kadar olmalıdır. Daha ilerde bu opsiyonu daha detaylı göreceğiz.
D0-srcX: Source bitplane'lerinden kopyalanacak alanın sol üst köşesine ait x koordinatı.
D1-srcY: Kopyalanacak alanın sol üst köşesinin y koordinatı. D2-destX: Kopyalanacak dörtgenin destination bitplane'leri üzerinde basılacağı x koordinatı.
D3-destY: Dörtgenin destination bitplane'lerinde basılacağı y koordinatı.
D4-sizeX: Kopyalanacak dörtgenin genişliği (piksel olarak). D5-sizeY: Dörtgenin yüksekliği. D6-minterm: Kopyalama şekli:
$c0= direkt kopyalama $30= kopyalama sırasında resim dataları negatiflenir. $50= sadece destination ekranındaki resim bilgilerini negatifler. D7- Kopyalamada kopyalanacak bitplane'lere ait flag'ler. Herbir bit bir bitplane'i temsil eder. Bu şekilde dilerseniz resimdeki bazı bitplane'leri kopyalamayabilirsiniz. Normal bir kopyalama için buraya 255 değeri (=$ff) yazmanız gerekmekte.
Bu fonksiyonun da açıklamasını Tablo V'de düzenli olarak görebilirsiniz.
Ehh, geçen ayki programın açıklamasını sonunda bitirebildim. Ne dersiniz, bu program sayesinde yeni birçok şey öğrendiniz değil mi? Bu aylık bu kadar bilgi yeter herhalde. Artık köşemin geri kalan kısmında da assembler komutlarının tablosunun ilk kısmını (Tablo VI) koyuyorum. Önümüzdeki iki ay boyunca bu tabloyu tamamlayacağım. Buradaki komutlar ile ilgili örnekleri ilerledikçe programlarımız içinde göreceksiniz. Tablonun ilk kolonunda adresleme şeklini <ea> ile belirleriz. Adresleme kolonundaki altkolonlarda da o komutun gösterilen adresleme tipiyle çalışıp çalışmadığını; Flag'ler kolonunda komut kullanıldığında etkilenen flag'leri görebilirsiniz. Buradaki <-> işareti uygun flag'ın etkilenmediğini, <0> ise 0 konumuna geldiğini belirler. <*> sembolü flag'in değiştiğini, <1> flag'ın 1 olduğunu, <U> ise belirsiz konum olduğunu gösterir.
İlk kolonda 2-3 komutun içindeki bazı harflerin cc olduğunu göreceksiniz. Bu cc harfleri yerine Tablo VII'deki branch komut eklerinden birini koyabilirsiniz.

xx: Anlamı: İşlevi:
T true-doğru sonuç 1'mi? F false-yanlış sonuç 0'mı? HI high-yüksek sonuç > verilen değer? LS low/same-alçak/aynı sonuç <= verilen değer? CC Carry clear-Carry sönük Carry flag'ı 0 mı? CS Carry set-Carry yanık Carry flag'ı 1 mi NE not equal-eşit değil EQ equal-eşit
Sonuç, değere eşit değil mi? Sonuç, değere eşit mi? VC Overflow clear-Ovf, sönük Sonuçta taşma yok mu? VS Overflow set-Ovf, yanık Sonuçta taşma var mı? PL Plus-pozitif Sonucun durumu pozitif mi? MI Minus-negatif Sonucun durumu negatif mi? GE Greater/equal-büyük/eşit Sonuç >= verilen değer? LT Less than-daha az Sonuç < verilen değer? GT Greater than-daha çok Sonuç > verilen değer? LE Less/equal-az veya eş Sonuç <= verilen değer? Tablo VII - Bxx, DBxx ve Sxx koşullu branch komutlarında xx yerine gelebilecek takılar.