plazma - amatör bilgisayar kültürü

Amiga Assembly Kursu - 2

Şemseddin 'Endo' Moldibi

Amiga Assembly Kursumuzun 2. bölümüne hoş geldiniz. Önceki sayımızda sizin de fark etmiş olacağınız gibi, bu yazı programcı olmayanlara değil, daha çok, programcılığı (Assembly, C veya en az bir programlama dilini) biliyor olup Amiga’da 68000 Assembly ile program yazmak isteyenlere yönelik. Ancak bu, programlamaya yeni başlayanları korkutmasın, bu şekilde öğrenmek zor olduğu kadar zevklidir de.

Önceki sayımızda 68000 register’ larını, veri transfer komutlarını ve Amiga’nın hafıza yapısı konuları incelemiş, basit bir kodu nasıl derleyeceğimizi öğrenmiştik. Bu sayımızda 68000 komutlarını öğrenmeye devam edecek, donanım register’ larını kısaca tanıyacağız, ardından çeşitli örnek kodları inceleyeceğiz, son olarak biraz daha görsel sonuçlar görebileceğimiz ilginizi çekeceğini umduğum bir örnek kod ile devam edeceğiz. Bunu yaparken henüz öğrenmediğimiz bazı konulara girmek zorunda kalacağız, ancak ileriki sayılarda bu konuların tümüne sırasıyla değineceğiz.

Öncelikle örnekleri kolaylıkla test edebilmeniz için hazırladığım asmpro.adf isimli dosyayı; eğer gerçek bir Amiga kullanıyorsanız boş bir diskete yazın (bunu yapan programları Internet’ten bulabilirsiniz), eğer WinUAE Amiga emulatörü kullanıyorsanız ayarlarınızı aşağıdaki gibi yapın, df0’a asmpro.adf dosyasını gösterin, ayarlarınızı kaydedin ve emulatörü başlatın. Sistem bu disketten boot ederek açılacak ve karşınıza AsmPro çıkacaktır.

WinUAE ayarlarınızda 68020 işlemci, AGA chipset (en azından ECS), 3.1 veya 2.0 kickstart rom dosyası ve ~4 MB fastram seçin.

Kodlarınızı rahatça yükleyip kaydetmek için bir harddisk oluşturmanızı tavsiye ederim. Hatta asmpro.adf disketindeki dosyaları harddiskinize kopyalayıp oradan da çalışabilirsiniz.

AsmPro ilk açıldığında gelen ekranda kullanacağınız ram tipi ve miktarını seçebilirsiniz. Şimdilik ~100 KB CHIP RAM seçebilirsiniz.

1. 68000 BCC Komutları (Dallanma Komutları)

68000 işlemcilerde genel olarak CC (Conditional Code) komutları adı verilen bir grup komut vardır. Bunlar çoğunlukla program içinde dallanmaya yarayan BCC komutlarıdır:

1.1. BCC Komutları (Koşullu Dallanma Komutları):

BCC komutlarının genel kullanım şekli aşağıdaki gibidir:

Bcc.S <label>
Bcc.W <label>

Burada komutu takip eden .S ve .W sonekleri (suffix) dallanmanın mesafesine göre belirlenir; .S kısa mesafe (short range: -128, +127 byte), .W ise uzun mesafe (word range: -32768, +32767 byte) dallanma anlamındadır.

Normalde belirtmediğiniz takdirde derleyiciniz en uygun olanı seçecektir.

BCC Komutları listesi aşağıdadır:

BCS Carry Bit Set
BLS Lower or Same
BEQ EQual (Z-bit Set)
BNE Not Equal (Z-bit Clear)
BHI HIgher than
BCC Carry Bit Clear

BPL PLus (N-bit Clear)
BMI Minus (N-bit Set)
BVC V-bit Clear (No Overflow)
BVS V-bit Set (Overflow)
BRA BRanch Always

BLT Less Than
BLE Less than or Equal
BGT Greater Than 
BGE Greater than or Equal

İngilizce açıklamalarından komutların işlevlerini kolayca çıkarabilirsiniz. Burada dallanma komutlarına genel bir isim olarak kullanılan BCC ile dallanma komutlarından biri olan BCC arasındaki benzerlik aklınızı karıştırmasın.

Bu listedeki tüm komutlar, .S ve .W eki ile kullanılabilir, .S hafızada daha az yer kapladığından ve daha hızlı olduğundan mümkün olan her durumda tercih edilir.

NOT: 68000 işlemcilerin üst modellerinde (68020+) .L eki ile 32 bitlik mesafelerde dallanma yapılabilir. Ancak 68000 işlemci de .L ekli BCC komutları desteklenmemektedir.

waitclick:
        btst        #6,$bfe001
        bne.s        waitclick
        rts

Ayrıca DBcc (Decrement and branch conditionally) komutlarını da bu listeye eklemeliyiz. DBcc komutları (DBeq, DBne, DBpl vb.) verilen data register’ını bir azaltır ve koşul SAĞLANMADIĞI sürece veya verilen data register’ı sıfırın altına düşmediği sürece dallanma işlemini gerçekleştirir.

start:
        moveq        #4,D0
loop:
        nop        ;buraya kodlar girilir
        dbeq        D0,loop
        rts

Burada BEQ komutu ile DBEQ komutu arasındaki önemli farka değinmemiz gerek: BEQ komutu işlemin sonucu sıfır İSE dallanır, DBEQ komutu ise işlemin sonucu sıfır olana dek dallanır, sıfır olduğunda ise döngüden çıkılır.

NOT: Önce data register’ının değerinin sıfır olup olmadığına bakılır, sonra değer bir azaltılır, ilk karşılaştırmanın sonucu sıfır değilse dallanma gerçekleşir. Yani DBEQ komutundan çıkıldığında D0 register’ında $FFFF değeri olacaktır.

NOT 2: Verilen register’ın sıfır ile karşılaştırma işlemi 16 bit (word) olarak yapılır ve register’ın değeri yine word olarak azaltılır. Sayaç register’ındaki değer başlangıçta $12340000 ise DBcc komutundan sonra $1234FFFF değeri olacaktır.

Ayrıca yukarıdakilere ek olarak DBF ve DBRA komutlarını söyleyebiliriz, bu iki komut koşula (condition) bakmaksızın sadece register’ın değeri sıfır olana dek dallanma işlemi yapar. Genel olarak koşulsuz döngüler için kullanılırlar.

2. Hardware Registerlar’ı

Hardware register’ları işlemcinin doğrudan custom chiplere uluşabilmesini sağlayan adreslerdir. RAM ve ROM’da bulunmazlar. Normal şartlarda, eğer bir utility veya sistem uyumlu, multitasking bir uygulama geliştiriyorsanız bu adreslere doğrudan erişmeniz gerekmez, hatta erişmemeniz daha doğru olur. Bu adreslere dolaylı olarak ulaşmanızı sağlayacak kütüphaneler vardır. Kütüphaneler konusuna ileride detaylı olarak değineceğiz.

Ancak demo (ve hatta çoğu oyun) programları bu adreslere doğrudan erişim yapılarak yazılır. Bu bölümde ileride çok defa karşılaşacağımız bu adresler hakkında kısa bilgiler vereceğim:

Hardware register’larının 68000 üzerindeki base (taban) adresi $DFF000’dır.

Yani verilen chip adreslerini bu taban adrese ekleyerek ulaşacağınız adresi bulabilirsiniz.

68000 adresi = (chip adresi) + $DFF000

Örneğin Joystick/Mouse bilgisini okumak için kullanılan adres $DFF00A için genelde sadece $00A register’ı denir.

Aşağıdaki listede donanım register’larının adreslerini ve kısa açıklamalarını bulabilirsiniz. Listede R/W olarak verilen kısım register’ın sadece okunabilir ya da sadece yazılabilir olduğunu ifade eder.

W write-only, yalnız yazılabilir; R read-only, yalnız okunabilir; ER early-read DMA için kullanılır; S strobe yazma işlemi yapıldığında bir olay tetiklenir.

Bu register’ları kullanılırken okunabilir/yazılabilir olmalarına dikkat etmelisin, asla okunabilir bir regsiter’a veri yazmaya kalkmayın ya da yazılabilir bir register’ı okumayın. Bu makinenin kilitlenmesine sebep olur.

2.1. Hardware Register’ları Listesi

BLTDDAT (000,ER) : Blitter RAM'e veri kopyalarken kullanır. Kullanmayınız

DMACONR (002,R) : DMA kontrol, tüm DMA durumlarını bu adresten okuyabilirsiniz

VPOSR (004,R) : Dikey tarama MSB (most significant bit)

VHPOSR (006,R) : Yatay/Dikey tarama pozisyonu

DSKDATR (008,ER) : Disk DMA tamponu. Kullanmayınız

JOY0DAT (00A,R) : Joystick-mouse 0 verisi (dikey, yatay)

JOY1DAT (00C,R) : Joystick-mouse 1 verisi (dikey, yatay)

CLXDAT (00E,R) : Sprite/görüntü çarpışma verisi (oku ve temizle)

ADKCONR (010,R) : Ses, disk kontrol register'ı

POT0DAT (012,R) : Pot sayacı (dikey,yatay)

POT1DAT (014,R) : Pot sayacı (dikey,yatay)

POTGOR (016,R) : Pot port data

SERDATR (018,R) : Seri port data ve durumu

DSKBYTR (01A,R) : Disk data byte'ı ve durumu

INTENAR (01C,R) : Interrupt enable bitleri

INTREQR (01E,R) : Interrupt request bitleri

DSKPTH (020,W) : Disk adres pointer'ı (üst 3 bit)

DSKPTL (022,W) : Disk adres pointer'ı (alt 15 bit)

DSKLEN (024,W) : Disk DMA data uzunluğu (word)

DSKDAT (026,W) : Disk DMA data yazma

REFPTR (028,W) : Kullanmayınız. (Refresh pointer)

VPOSW (02A,W) : Dikey tarama MSB (yaz)

VHPOSW (02C,W) : Yatay/Dikey tarama pozisyonu (yaz)

COPCON (02E,W) : Coprocessor (Copper) kontrol register'ı

SERDAT (030,W) : Seri port data ve stop biti (yaz)

SERPER (032,W) : Seri port periyod/kontrol

POTGO (034,W) : Pot port data yaz/başla

JOYTEST (036,W): ???

STREQU (038,S) : Yatay senkronizasyon strobe adresi

STRVBL (03A,S) : Yatay senkronizasyon strobe adresi

STRHOR (03C,S) : Yatay senkronizasyon strobe adresi

STRLONG (03E,S) : Yatay senkronizasyon strobe adresi

BLTCON0 (040,W) : Blitter kontrol register'ı 0

BLTCON1 (042,W) : Blitter kontrol register'ı 1

BLTAFWM (044,W) : Blitter mask değeri (Kaynak A, ilk word)

BLTALWM (046,W) : Blitter mask değeri (Kaynak A, son word)

BLTCPTH (048,W) : Blitter pointer C (üst 3 bit)

BLTCPTL (04A,W) : Blitter pointer C (alt 15 bit)

BLTBPTH (04C,W) : Blitter pointer B (üst 3 bit)

BLTBPTL (04E,W) : Blitter pointer B (alt 15 bit)

BLTAPTH (050,W) : Blitter pointer A (üst 3 bit)

BLTAPTL (052,W) : Blitter pointer A (alt 15 bit)

BLTDPTH (054,W) : Blitter pointer D (hedef) (üst 3 bit)

BLTDPTL (056,W) : Blitter pointer D (hedef) (alt 15 bit)

BLTSIZE (058,W) : Blitter boyut/başla (genişlik, yükseklik)

BLTCMOD (060,W) : Blitter modulo C

BLTBMOD (062,W) : Blitter modulo B

BLTAMOD (064,W) : Blitter modulo A

BLTDMOD (066,W) : Blitter modulo D

BLTCDAT (070,W) : Blitter kaynak C data register'ı

BLTBDAT (072,W) : Blitter kaynak B data register'ı

BLTADAT (074,W) : Blitter kaynak A data register'ı

DSRSYNC (07E,W) : Disk okuması için sync patern register'ı

COP1LCH (080,W) : Coprocessor lokasyonu 1 (üst 3 bit)

COP1LCL (082,W) : Coprocessor lokasyonu 1 (alt 15 bit)

COP2LCH (084,W) : Coprocessor lokasyonu 2 (üst 3 bit)

COP2LCL (086,W) : Coprocessor lokasyonu 2 (alt 15 bit)

COPJMP1 (088,S) : Coprocessor restart (ilk lokasyon)

COPJMP2 (08A,S) : Coprocessor restart (ikinci lokasyon)

COPINS (08C,W) : Coprocessor tarafından kullanılır

DIWSTRT (08E,W) : Görüntü alanı başlangıcı (sol üst dikey-yatay pozisyon)

DIWSTOP (090,W) : Görüntü alanı bitişi (sağ alt dikey-yatay pozisyon)

DDFSTRT (092,W) : Data fetch başlangıç (yatay pozisyon)

DDFSTOP (094,W) : Data fetch bitiş (yatay pozisyon)

DMACON (096,W) : DMA kontrol (yaz)

CLXCON (098,W) : Çarpışma kontrol register'ı

INTENA (09A,W) : Interrupt enable bitleri

INTREQ (09C,W) : Interrupt isteği

ADKCON (09E,W) : Audio, disk, UART kontrol

AUD0LCH (0AO,W) : Ses kanalı 0 DMA data'sı (üst 3 bit)

AUD0LCL (0A2,W) : Ses kanalı 0 DMA data'sı (alt 15 bit)

AUD0LEN (0A4,W) : Ses kanalı 0 uzunluk

AUD0PER (0A6,W) : Ses kanalı 0 periyot

AUD0VOL (0A8,W) : Ses kanalı 0 ses

AUD0DAT (0AA,W) : Ses kanalı 0 data

AUD1LCH (0B0,W) : Ses kanalı 1 DMA data'sı (üst 3 bit)

AUD1LCL (0B2,W) : Ses kanalı 1 DMA data'sı (alt 15 bit)

AUD1LEN (0B4,W) : Ses kanalı 1 uzunluk

AUD1PER (0B6,W) : Ses kanalı 1 periyot

AUD1VOL (0B8,W) : Ses kanalı 1 ses

AUD1DAT (0BA,W) : Ses kanalı 1 data

AUD2LCH (0C0,W) : Ses kanalı 2 DMA data'sı (üst 3 bit)

AUD2LCL (0C2,W) : Ses kanalı 2 DMA data'sı (alt 15 bit)

AUD2LEN (0C4,W) : Ses kanalı 2 uzunluk

AUD2PER (0C6,W) : Ses kanalı 2 periyot

AUD2VOL (0C8,W) : Ses kanalı 2 ses

AUD2DAT (0CA,W) : Ses kanalı 2 data

AUD3LCH (0D0,W) : Ses kanalı 3 DMA data'sı (üst 3 bit)

AUD3LCL (0D2,W) : Ses kanalı 3 DMA data'sı (alt 15 bit)

AUD3LEN (0D4,W) : Ses kanalı 3 uzunluk

AUD3PER (0D6,W) : Ses kanalı 3 periyod

AUD3VOL (0D8,W) : Ses kanalı 3 ses

AUD3DAT (0DA,W) : Ses kanalı 3 data

BPL1PTH (0DC,W) : Bit plane 1 pointer (üst 3 bit)

BPL1PTL (0DE,W) : Bit plane 1 pointer (alt 15 bit)

BPL2PTH (0E0,W) : Bit plane 2 pointer (üst 3 bit)

BPL2PTL (0E2,W) : Bit plane 2 pointer (alt 15 bit)

BPL3PTH (0E4,W) : Bit plane 3 pointer (üst 3 bit)

BPL3PTL (0E6,W) : Bit plane 3 pointer (alt 15 bit)

BPL4PTH (0E8,W) : Bit plane 4 pointer (üst 3 bit)

BPL4PTL (0EA,W) : Bit plane 4 pointer (alt 15 bit)

BPL5PTH (0EC,W) : Bit plane 5 pointer (üst 3 bit)

BPLSPTL (0EE,W) : Bit plane 5 pointer (alt 15 bit)

BPL6PTH (0F0,W) : Bit plane 6 pointer (üst 3 bit)

BPL6PTL (0F2,W) : Bit plane 6 pointer (alt 15 bit)

BPLCON0 (0FC,W) : Bit plane kontrol register'ı

BPLCON1 (0FE,W) : Bit plane kontrol reg. (kayma değeri)

BPLCON2 (100,W) : Bit plane kontrol reg. (öncelik kontrolü)

BPL1MOD (104,W) : Bit plane modulo (tek plane'ler)

BPL2MOD (106,W) : Bit plane modulo (çift plane'ler)

BPL1DAT (10C,W) : Bit plane 1 data (paralel->seri)

BPL2DAT (10E,W) : Bit plane 2 data (paralel->seri)

BPL3DAT (110,W) : Bit plane 3 data (paralel->seri)

BPL4DAT (112,W) : Bit plane 4 data (paralel->seri)

BPL5DAT (114,W) : Bit plane 5 data (paralel->seri)

BPL6DAT (116,W) : Bit plane 6 data (paralel->seri)

SPR0PTH (120,W) : Sprite 0 pointer (üst 3 bit)

SPR0PTL (122,W) : Sprite 0 pointer (alt 15 bit)

SPR1PTH (124,W) : Sprite 1 pointer (üst 3 bit)

SPR1PTL (126,W) : Sprite 1 pointer (alt 15 bit)

SPR2PTH (128,W) : Sprite 2 pointer (üst 3 bit)

SPR2PTL (12A,W) : Sprite 2 pointer (alt 15 bit)

SPR3PTH (12C,W) : Sprite 3 pointer (üst 3 bit)

SPR3PTL (12E,W) : Sprite 3 pointer (alt 15 bit)

SPR4PTH (130,W) : Sprite 4 pointer (üst 3 bit)

SPR4PTL (132,W) : Sprite 4 pointer (alt 15 bit)

SPR5PTH (134,W) : Sprite 5 pointer (üst 3 bit)

SPR5PTL (136,W) : Sprite 5 pointer (alt 15 bit)

SPR6PTH (138,W) : Sprite 6 pointer (üst 3 bit)

SPR6PTL (13A,W) : Sprite 6 pointer (alt 15 bit)

SPR7PTH (13C,W) : Sprite 7 pointer (üst 3 bit)

SPR7PTL (13E,W) : Sprite 7 pointer (alt 15 bit)

SPR0POS (140,W) : Sprite 0 dikey-yatay start pozisyon data

SPR0CTL (142,W) : Sprite 0 dikey bitiş pozisyonu ve kontrol register'ı

SPR0DATA (144,W) : Sprite 0 image data register'ı A

SPR0DATB (146,W) : Sprite 0 image data register'ı B

SPR1POS (148,W) : Sprite 1 dikey-yatay start pozisyon data

SPR1CTL (14A,W) : Sprite 1 dikey bitiş pozisyonu ve kontrol register'ı

SPR1DATA (14C,W) : Sprite 1 image data register'ı A

SPR1DATB (14E,W) : Sprite 1 image data register'ı B

SPR2POS (150,W) : Sprite 2 dikey-yatay start pozisyon data

SPR2CTL (152,W) : Sprite 2 dikey bitiş pozisyonu ve kontrol register'ı

SPR2DATA (154,W) : Sprite 2 image data register'ı A

SPR2DATB (156,W) : Sprite 2 image data register'ı B

SPR3POS (158,W) : Sprite 3 dikey-yatay start pozisyon data

SPR3CTL (15A,W) : Sprite 3 dikey bitiş pozisyonu ve kontrol register'ı

SPR3DATA (15C,W) : Sprite 3 image data register'ı A

SPR3DATB (15E,W) : Sprite 3 image data register'ı B

SPR4POS (160,W) : Sprite 4 dikey-yatay start pozisyon data

SPR4CTL (162,W) : Sprite 4 dikey bitiş pozisyonu ve kontrol register'ı

SPR4DATA (164,W) : Sprite 4 image data register'ı A

SPR4DATB (166,W) : Sprite 4 image data register'ı B

SPR5POS (168,W) : Sprite 5 dikey-yatay start pozisyon data

SPR5CTL (16A,W) : Sprite 5 dikey bitiş pozisyonu ve kontrol register'ı

SPR5DATA (16C,W) : Sprite 5 image data register'ı A

SPR5DATB (16E,W) : Sprite 5 image data register'ı B

SPR6POS (170,W) : Sprite 6 dikey-yatay start pozisyon data

SPR6CTL (172,W) : Sprite 6 dikey bitiş pozisyonu ve kontrol register'ı

SPR6DATA (174,W) : Sprite 6 image data register'ı A

SPR6DATB (176,W) : Sprite 6 image data register'ı B

SPR7POS (178,W) : Sprite 7 dikey-yatay start pozisyon data

SPR7CTL (17A,W) : Sprite 7 dikey bitiş pozisyonu ve kontrol register'ı

SPR7DATA (17C,W) : Sprite 7 image data register'ı A

SPR7DATB (17E,W) : Sprite 7 image data register'ı B

COLOR00 (180,W) : Renk değeri 00

COLOR01 (182,W) : Renk değeri 01

...

COLOR31 (1BE,W) : Renk değeri 31

Bu register’lara şimdilik sadece göz atmanız yeterli. Birçok konuda size fikir verecektir. İleride blitter, copper, ses ve görüntü alanları ile ilgili bu register’lara çokça ihtiyaç duyacağız.

3. Örnek Program 1 – ASCII2Hex Converter

Aşağıdaki örnek kod A0’da adresini verdiğiniz 8 karakterlik ifadeyi okuyup D0’da hexadecimal değerini döndürür. Açıklamalar kodun içindedir.

start:
        ;try adresini A0'a koy
        ;tohex isimli altrutini cagir
        lea        try(pc),a0
        jsr        tohex
        rts

;
; Ascii -> Hex Cevirici
; A0: string baslangic adresi
; Sonuc: D0 (longword)
; Degisen register'lar: D0/D1/D2/A0
;
tohex:
        ;D0 = 0, D1 = 0, D2 = 0
        clr.l        d0
        clr.l        d1
        moveq        #0,d2
.loop:
        ;A0'in gosterdigi yerden
        ;1 byte'i D0'a oku
        move.b        (a0)+,d0

        ;hexit altrutinini cagir
        bsr.s        .hexit

        ;D2'nin degerini 1 arttir
        ;8 olmadiysa loop'a git
        addq        #1,d2
        cmp        #8,d2
        bne.s        .loop

        ;sonucu D1'den D0'a kopyala
        ;ve programdan cik
        move.l        d1,d0
        rts

.hexit:
        ;D0'daki deger 'a' ($61)'den kucukse
        ;nolowercase'e git, deger a-f degildir
        ;aksi halde 'a'-10 ($51) cikart
        ;boylece deger 'a' ise $0A kalir
        ;ve out'a dallan
        cmp.b        #'a',d0
        blt.s        .nolowercase
        sub.b        #'a'-10,d0
        bra.s        .out
        
.nolowercase:        
        ;D0'daki deger 'A' ($41)'den kucukse
        ;nouppercase'e git, deger A-F degildir
        ;aksi halde 'A'-10 ($31) cikart
        ;boylece deger 'A' ise $0A kalir
        ;ve out'a dallan
        cmp.b        #'A',d0
        blt.s        .nouppercase
        sub.b        #'A'-10,d0
        bra.s        .out
        
.nouppercase:
        ;D0'daki deger '0'-'9' arasi ($30-$39)
        ;'0' cikart ve byte degerini elde et
        sub.b        #'0',d0
.out:
        ;sonucu tutacak olan D1 registerini
        ;4 bit sola kaydir (1 nibble, yarim byte)
        ;ve elde edilen D0'daki deger ile OR'la
        ;sonuc yine D1'de durur
        lsl.l        #4,d1
        or.b        d0,d1
        rts

try:
        dc.b        "3a06DfC0"

4. Örnek Program 2 – Copper Bar

Aşağıdaki kod örnek bir copper listesidir. Henüz bu konulara girmemiş olmamıza rağmen hardware register’ları ile ilgili olduğundan burada yer verdim (biraz da ilginizi çekmek için), önümüzdeki sayıda copper ve görüntü alanları (display fields) hakkında daha detaylı bilgi bulabilirsiniz. Şimdilik sadece yazıp inceleyiniz.

;
; Ornek Copper List
;

;bazi hardware register ofsetleri
bplcon0 = $100
bplcon1 = $102
bpl1mod = $108
diwstrt = $08E
diwstop = $090
ddfstrt = $092
ddfstop = $094
color00 = $180
color01 = $182
cop1lc  = $080
copjmp1 = $088
dmacon  = $096
bpl1pth = $0E0
bpl1ptl = $0E2

start:
        ;Custom Chip taban adresi
        lea     $dff000,a0
        ;1 bitplane (tek renk)
        move.w  #$1200,bplcon0(a0)
        move.w  #0,bplcon1(a0)
        move.w  #0,bpl1mod(a0)
        ;goruntunun baslangic/bitisi
        move.w  #$0038,ddfstrt(a0)
        move.w  #$00d0,ddfstop(a0)
        move.w  #$2c81,diwstrt(a0)
        move.w  #$f4c1,diwstop(a0)
        ;bitplane adresini copper
        ;liste yerlestir
        move.l  #bitplane,d0
        move.w  d0,cl
        swap    d0
        move.w  d0,ch
        ;copper listesinin baslangic
        ;adresini yaz
        move.l  #copperlist,cop1lc(a0)
        ;copper’i tetikle
        move.w  copjmp1(a0),d0
        ;dma’lari ayarlar
        move.w  #$8380,dmacon(a0)
        ;sol tusa basilana kadar bekle
.leftclick:
        btst    #6,$bfe001
        bne.s   .leftclick
        rts

        ;copper list ve bitmap daima
        ;CHIP Ram’de durmalidir

        section data,data_c

copperlist:
        dc.w    bpl1pth
ch:   dc.w    0
        dc.w    bpl1ptl
cl:   dc.w    0
        ;sprite’i kapat
        dc.w    $0120,$0000
        dc.w    $0122,$0000
        ;$96 raster satirini bekle
        dc.w    $9601,$ff00
        ;color00’a (zemin rengi,$0180)
        ;RGB $678 degeri gir
        dc.w    $0180,$0678
        dc.w    $9701,$ff00
        dc.w    $0180,$0789
        dc.w    $9801,$ff00
        dc.w    $0180,$089a
        dc.w    $9901,$ff00
        dc.w    $0180,$09ab
        dc.w    $9a01,$ff00
        dc.w    $0180,$0567
        ;copper listesini bitir
        dc.w    $ffff,$fffe

;Bitplane icin bos alan ayir

bitplane:
        ds.b    320*256

Yukarıdaki örnek kodda Bitmap için gerekli boş hafıza alanını kodun içinde ayırdık. Elbette birçok durumda bunun için Exec library’nin hafıza ayırma fonksiyonlarını (memory allocation functions, AllocMem) kullanmamız gerekir. Ancak bir süre daha örnek kodlarımızı bu şekilde yapmaya devam edeceğiz. Library’ler konusuna ise daha ileriki sayılarda gireceğiz.

Bu sayıdaki yazımızın sonuna geldik. Bu sayıda dallanma komutlarını öğrendik ve hardware registerler’ı hakkında bilgi edindik, örnek kodlarla da öğrendiklerimizi uygulamış olduk. Ayrıca dergi ile birlikte AsmPro’yu doğrudan çalıştırabileceğiniz bir ADF dosyasını bulabilirsiniz. Buradaki örnek kodları disketin içindeki sources klasöründe bulabilirsiniz.

Bir sonraki sayıda görüşmek üzere hosçakalın.

Kaynaklar:

  1. Amiga Machine Language – Abacus

  2. Amiga Hardware Reference Manual

  3. Programming the 68000 - Steve Williams. (c) 1985 Sybex Inc

plazma - 2008