DİLLER bsr.L INITBITMAPS bsr.L PRINTTEXT EVENTWAIT: bsr.L PUTGFX move.l WINDOWPTR,a0 bsr.L EVENT cmpi.l #$200,d4 beq.s ENDALL bra.s EVENTWAIT ENDALL: move.l INTBASE,a6 move.l WINDOWPTR,a0 CLOSE2: jsr -72(a6) move.l INTBASE,a6 move.l SCREENPTR,a0 CLOSE 1: jsr -66(a6) move.l 4,a6 move.l GFXBASE,a1 jsr -414(a6) EXIT2: move.l INTBASE,a1 jsr -414(a6) EXIT1: movem.l (a7)+,d0-d7/a0-a6 rts INITLIBS: move.l 4,a6 lea INTNAME,a1 clr.l dO jsr -408(a6) beq.s EXIT1 move.l d0,INTBASE lea GFXNAME,a1 clr.l d0 jsr -408(a6) beq.s EXIT2 move.l d0,GFXBASE rts INITSCREEN: move.l INTBASE,a6 lea NEWSCREEN.a0 jsr -<strong>19</strong>8(a6) beq.s CLOSE 1 move.l d0,SCREENPTR move.l d0,MAINSCREENPTR move.l ' SCREENPTR,a0 add. I #$54,a0 move.l a0,RASTPORT move.l INTBASE,a6 lea NEWWINDOW,a0 jsr -204(a6) beq.L CLOSE2 move.l d0,WINDOWPTR rts EVENT: move.l 4,a6 move.l 86(a0),a0 move.l a0,MSGPORTADRESI move.b 15(a0),d1 moveq #0,d0 bset dl,d0 jsr -318(a6) move.l MSGPORTADRESI.a0 jsr -372(a6) move.l d0,al move.l $14(a1),d4 jsr rts *378(a6) PRINTTEXT: clr.l d0 clr.l d1 move.l move.l GFXBASE,a6 RASTPORT,a1 move.l #140,d0 move.l #220,dl jsr -240(a6) move.l RASTPORT.a1 move.l #TEXT,a0 move.l #[TEXTEND-TEXT-1 |,d0 jsr rts -60(a6) PUTGFX: move.l GFXBASE,a6 lea SBITMAP,a0 lea move.l DBITMAP,al #5,d0 move.l #20,d1 move.l #5,d2 move.l move.l #20,d3 #630,d4 move.l move.l #100,d5 #$c0,d6 move.l #255,d7 move.l #0,a2 jsr rts -30(a6) INITBITMAPS: move.l GFXBASE,a6 lea SBITMAP,a0 move.w #l,d0 move.w #640,d1 move.w #255,d2 jsr -390(a6) lea SRAST,a1 jsr move.l -<strong>19</strong>8(a6) #SBITMAP,SRAST+4 lea move.l SBITMAP,a1 #PIC,8(a1) lea DBITMAP,a1 move.w #1,d0 move.w #640,d1 move.w #255,d2 jsr -390(a6) lea jsr DRASTal -<strong>19</strong>8(a6) move.l #DBITMAP,DRAST+4 lea DBITMAP,a3 move.l RASTPORT,a0 move.l 4(a0),a1 move.l 8(al),8(a3) rts MSGPORTADRESI: dc.l 0 INTNAME: dc.b 'intuition.library',0 GFXNAME: dc.b 'graphics.library',0 even INTBASE: dc.l 0 GFXBASE: RASTPORT: dc.l dc.l 0 0 NEWSCREEN: dc.w 0,0,640,256,1 dc.b 0,1 dc.w $8000,1 dc.l WINDOWPTR: dc.l 0,0,0,0 0 NEWWINDOW: dc.w 0,0,640,256 dc.b dc.l 0,1 $200,$1008,0,0,WINDOWTITLE SCREENPTR: dc.l 0,0 dc.w 640,256,640,256,15 WINDOWTITLE: dc.b 'AMIGA DÜNYASI ASSEMBLER' dc.b ' KURSU ÖRNEK <strong>19</strong>.1 ',0 MAINSCREENPTR: dc.l 0,0 DEPO: dc.w dc.l 340,60,340,60,15 0 SBITMAP: blk.b 50,0 SRAST: blk.b 100,0 DBITMAP: blk.b 50,0 DRAST: blk.b 100,0 TEXT: dc.b "Window içine tek bitplane resim kopyalama...",0 TEXTEND: d dc.l 0 PIC: incbin "RESIM.bm" AMIGA DÜNYASI 36
DERLEYİCİLER ASSEMBLER’da YENİ UFUKLAR Evet, geçen ay kaldığımız yerden devam ediyoruz. Bu bölümde geçen ay anlattığım CWAIT, CMOVE ve CEND komutlarının pratikte nasıl kullanıldıklarını göreceğiz. Bu komutlar 68000* in komutları arasında değiller. Bu yüzden de bu komutları programımızda kullanmaya kalkıştığımızda, hex karşılıklarını programımıza data satırları olarak eklemeliyiz. Bunu da ya direkt dc.b kullanarak, ya da makro kullanarak yapabiliriz. Biliyorsunuz. MSeka'nın makro özelliği sayesinde dilerseniz yeni komutlar yaratabilirsiniz. Makroları daha tanımayanlara, geçen ayki Master- Seka yazısını okumalarını öneririm. Unutmayın, makroları her zaman source'unuzun başına girmelisiniz. Her neyse, gelelim kendimize gerekli olacak olan üç komutu yaratmaya. CWAIT: MACRO IF NARG=2 dc.b 2,l,$ff,$fe ELSE FAİL ENDM CMOVE: MACRO IF NARG=2 dew 2,4 ELSE FAİL ENDM CEND: MACRO IF NARG=0 dew $fffffffe ELSE FAİL ENDM Evet, üç makromuz da hazır. Peki bunları nasıl kullanacağız Gayet basit, normal komutları nasıl kullanıyorsak aynı şekilde. İşte aşağıda birkaç ufak örnek: CMOVE $0f00,$0180 CWAIT $07,$40 CWAIT $01,$f0 CMOVE $1200,$0100 CEND Bunları hemen MSeka'da yazmaya kalkışmayın. Bir sonuç elde edemezsiniz. Dilerseniz şimdi bu üç yeni komutumuzu nasıl* kullanacağımızı görelim: * CMOVE ,: Bu komut yardımıyla herhangi bir copper register'ına istediğimiz değeri yazabiliriz. Komutu oluşturan makroya bir göz atarsak, komuta ikiden farklı sayıda parametre girersek MSeka'nın bu source'u FAİL komutu yüzünden compile etmeyeceğini görürüz. Makro içersinde gelen parametreleri neden ters yerleştirdiğimi anlatmayacağım. Zaten geçen ayki yazıyı dikkatli okuyup öğrenenler bunu bilirler. * CWAIT ,: Tarama ışının istenilen ekran koordinatına gelmesi beklenir. Bu ekıan kpctt "... u ui byte olarak x, y koordi- ""•ı şeklinde girmelisiniz. x koordinatı her zaman :ek sayı olmalıdır; aksi halde programınız hatalı çalışır. Burada da parametreleri makroda ters yerleştirdim. Bu komut da. aynı bir önceki gibi, ikiden farklı parametre sayısında hata mesajı verilmesine sebep olur. * CEND: Copper listesinin sonunu belirler. Parametre kullanılmamalıdır, aksi halde FAİL hata mesajını verir. Evet, bu komutları programımıza nasıl ekleyeceğimize birazdan geleceğim. Fakat ilkönce birşeyi açıklığa kavuşturmak istiyorum. Bu, copper listemizi copper cipine nasıl aktaracağımız. Burada sistem rutinlerinden de faydalanabiliriz, copper registerlarından da. İlki kullanılacağı zaman graphics.library'nin açılmış olmasını gerektirir. Oysa çok fazla hafıza harcayacak programlarda bu bir dezavantajdır, ikincisinde ise copper listesini set ede- biliriz, yani copper cipine listemizi tanıtabiliriz. Fakat programdan çıkış olduğunda eski copper listesini aktif hale getirmek için. graphics.library'yi başlangıçta mutlaka açmalı ve o anki copper'ın adresini saklamalıyız. Ancak bundan sonra copper listesini set eder ve programdan çıkışta da yine Cem GENCER graphics.library*! kullanarak eski copper'ı aktif yapabiliriz. Bunlardan hangisini kullanacağınız artık size kalmış; benden açıklaması. Ben bütün örnek programlarda ilkini kullandım. * Copper listesinin library yardımıyla set edilmesi: Bunun için graphics.library'deki GFXBASE structure'ını kullanacağız. Bu structure'daki gereksiz kısımları atlıyorum. İsteyen assembler köşesini takip ederek structure açıklamalarını inceleyebilir. GfxBase structure'ı, graphics.library açıldığında base adresinden sonrasında bulunan structure'dır. GfxBase structure'ında 50. (=$32) ofsetteki long-word, aktif olan copper'ın adresini gösterir. Programımızda biz sadece bu adresteki bilgiyi longword olarak bir değişkene (örneğin SysCopper) kopyalarız. Ardından da 50. ofsetteki longword'e kendi copper listemizin başlangıç adresini yazarız. Bunu da ister label kullanarak, istersek de direkt adres yazarak yapabiliriz. Direkt adres yazarken, copper listesinin bu adreste bulunduğunu garantilemeliyiz. Bunu da, source'ta copper listesinden önce ORG ve LOAD komutlarını yazarak ya da copper listemizi word word o adresten sonrasına kopyalayarak yapabiliriz. Eh. bir hayli opsiyon var değil mi Bunlardan en basiti, hiç kuşkusuz label kullanarak. Aşağıdaki satırları programınıza eklerseniz, copper'ı hiç sorun olmadan set ve reset edebilirsiniz, move.l GfxBase,a6 ; graphics.library başlangıcı move.l 50(a6),SysCopper ; sistem copper'ını saklar, move.l #Copper,50(a6) ;bizim copper'ı aktif yapar. . Bunun bir de çıkışı var. Çıkış rutininize de şu satırları eklemeniz gerekmekte: move.l GfxBase,a6 ; graphics.library başı. move.l SysCopper,50(a6) ; Eski copper'ı aktif hale getirir. * Copper listesinin copper yardımıyla set edilmesi: Bu yöntemde listemizi set etmek için copper'ı kullanıyoruz. Copper register'larında iki register bu işimizi görmekte. Bunlardan ilki olan $0080 ve $0082'ye copper listemizin adresini yazıyoruz. Hardware Reference Manual kitabında bu adreslerin ismi COPİLCH ve COPİLCL olarak geçmekte. Buradan adresimizin üst word'ünün $0080 register'ına, alt word'un da $0082'ye yazılacağını anlayabiliyoruz. Fakat bunu daha kısa yapmanın yolu, adresimizi $0080 register'ına direkt longword olarak yazmamız. Bu şekilde zaten üst longword $0080'e, alt' longword'da $0082'ye gidecektir. Eee, daha ne bekliyoruz Copper listemizin adresini yazdık; fakat copper cipi, bu adresin aktif copper olarak kullanılmasının da onaylanmasını ister. Bunu da $0088 register'ına herhangi bir değer yazarak yapabiliriz. Bu register'ın ismi COPJMP1. Register bir strobe register'ı. Bu, buraya yapılacak herhangi bir işlemin copper'ı aktif hale getireceğini tanımlar, move.l #Copper,$dff080 ; Copper adresini yaz. clr.w $dff088 ; Copper cipine yeni listeyi bildir. Copper'ı aktif hale getirdik. Peki programdan çıkmak istediğimiz zaman nasıl eski copper'ı set edeceğiz Bunun için demin de belirttiğim gibi programımızın başında eski copper adresini sak-