Merhaba arkadaşlar,
Amiga assembler üzerindeki içsel yolculuğum devam ediyor. Bana entresan gelen noktaları, düşüncelerimi, bir takım code snippetlerini, çabalarımdan örnek videoları vs, izin verirseniz bu başlık altında paylaşmak istiyorum. Hem benim için geri dönüp bakabileceğim bir günce, hem de ilgi duyan ve yeni başlayan arkadaşlar için ufak tefek fikirler ve saç baş yolduran problemlere çabuk çözümler bulabilecekleri bir yer haline gelebilir (gelemeyebilir de). Burada paylaşacaklarımın internet üzerinde kolay bir arama ile direk bulunamayacak ve kendi çabalarımla bir sonuca eriştirdiğim şeyler olması konusuna dikkat edeceğim. Tabii bana harika gelen bazı çözümler, konunun uzmanı arkadaşlarımıza bir şaka gibi gelebilir. Onların yorumları bence hepimiz için ayrıca değerli olacaktır.
Müsaadenizle başlayayım:
Bir süredir Scoopex'den Photon'un Amiga Hardware Programming (https://www.youtube.com/watch?v=p83QUZ1-P10&list=PLc3ltHgmiidpK-s0eP5hTKJnjdTHz0_bW) adlı video tutorial'ını takip ediyorum. Daha önceki başka bir başlıkta söylediklerimi tekrar edeyim: Photon'un epey psychedelic bir anlatım tarzı var. 20 dakika boş konuşup sonra 10 saniyede okyanusun dibine götürüyor getiriyor sizi. Ağır kuzey ülkeleri aksanlı bir İngilizce de beni benden alıyor. Açıkcası geri ala ala seyredilmesi taraftarıyım. Dalgınlıkla minik bir kısmı kaçırıp 'yav bu abi ne diyor?' noktasına çok hızlı gelebiliyorsunuz. Yine de bitmiş bir tutorial olduğu, protracker, deluxe paint, IFF Converter, Player61 gibi toolları da detaylı anlattığı için çok tavsiye ediyorum.
Bahsettiğim bu tutorialın başlangıç kısımlarında bir rasterline'ı, copper kullanmadan ekranın tepesinden aşağıya doğru kaydırma diye nispeten kolay bir kısmı anlatığı birkaç video var. Burada tepeden başlayıp ortayı biraz geçen ve ekranın en altına inmeden geri döndürdüğü bir örnek kod yazdırıyor ve konuyu geçiyor. Ben de büyük bir hevesle durumdan vazife çıkarıp rasterline'ı en alt satıra kadar indirip öyle çıkartmak gibi bir homework edindim kendime. Yaptım da hiç sorun olmadı. 1 pixel kalınlığında bir line en tepeden en aşağı kadar kayıyor, çarpıp geri dönüyor ve mouse'un sol tuşu ile de çıkabiliyorsunuz. Dikkat: Copper aktif ediliyor ama hiç kullanılmıyor burada. Aşağıdaki video'da görebilirsiniz:
Not a valid vimeo URL
Bu noktada source kodum şu şekilde: Link (https://bitbucket.org/toygar/codewarriors-amiga-assembler-diary/src/master/sources/rasterline_single.S).
Tutorial ilerlemeye devam etti ve bu rasterline'ı hem copper kullanarak yapacağız ve hem de aynı anda kalınlaştıracağız şimdi. Yani üstteki örnek 1 pixel kalınlığında iken mesela 10 pixele çıkartacağız. Ne kadar kolay değil mi? Değilmiş... Photon, rasterline'ı alt tarafa kadar indirmediği için hemen kalınlaştırmayı yapıp geçti gitti ama aynı şevkle girişen ben aşağıdaki video'daki durum ile karşılaştım. Aşağıya yakın bir yerlerle rasterline'ın nasıl bozulduğuna dikkat edin lütfen.
Not a valid vimeo URL
Bu noktada source kodum şu şekilde: Link (https://bitbucket.org/toygar/codewarriors-amiga-assembler-diary/src/master/sources/rasterline_bad.S).
Tabi tutorial kalınlığı renklendirerek devam etti. Ben hala problemimin sebebini tam anlayamadığım için aynı şekilde bug'lı olarak ilerledim. Renklendirilmiş halde sorun daha da bariz görünüyor:
Not a valid vimeo URL
Bu noktada source kodum şu şekilde: Link (https://bitbucket.org/toygar/codewarriors-amiga-assembler-diary/src/master/sources/rasterline_color_bad.S).
Sorunu sizler de gördüğünüze göre gelelim bunun sebebine ve çözümüne.
Raster için ekran en üst satır $02c ve en alt satır $12c ile ifade ediliyor. Dikkat ederseniz en alt satır numarasının büyüklüğü yüzünden bu değeri bir word içinde saklamamız ve kontrol etmemiz lazım. Eğer olur da bir byte içerisinde tutmak hatasına düşersek ekran line numarası $02c ile başlayıp birer birer artarak önce $02d, sonra $02e... vs şekilde $12c olana kadar artarak giderken $0ff'den geçecek ve byte ile tuttuğumuzdan $00'dan sonra başa dönerek ölümcül bir hata yapmış olacağız. O yüzden çizeceğimiz rasterline'ın numarasını (veya kalınlığa göre bir numara aralığını) word olarak tutmak zorundayız. Aslında karşılaştığım sorunun ana sebebi de bu. Ama ben word yerine byte kullanmak gibi bir hata yapmadım. İlginç ama Copper bu iş için byte kullanacak şekilde dizayn edilmiş ve word kullanamıyor!!.
Bu işi bilenler çoktan anladılar durumu ama benim gibi newbie'ler için biraz daha açıklamaya çalışayım. Copper kullanırken siyah arka ve beyaz rasterline'ı yukarıdan aşağıya kaydırmak için basitçe şu aşağıdaki işlemleri yapıyorsunuz. İyice karışmasın diye geri dönüş kısmını eklemedim buraya ama eminim tahmin edebilirsiniz nasıl olacağını..
- raster için en üst ekran pozisyonuna ($02c) kadar bekleme koy
- background rengini siyaha değiştir
- y = $02c
- çizime başlamak için raster'a başlangıç ekran pozisyonuna (y dedik buna) kadar bekleme koy
- background rengini beyaza değiştir
- rasterline için bitiş ekran pozisyonuna (y+kalınlık diyelim) kadar bekleme koy
- background rengini siyaha değiştir
- y++ ve go to 4
Copper'ın emirleri bir longword (yani double-word) şeklinde bir listeye yazılıyor ve adına geleneksel şekilde CopperList deniyor. Aşağıda iki satırlık bir copperlist var, açık olsun diye her longword satırını iki word şeklinde yazdım ve tüm byte'ları açık açık gösterdim:
dc.w $2c07,$fffe
dc.w $0180,$0000
dc.w $ffff,$fffe
Son satır copperlist için 'end' komutu. İlk satırdaki $fffe bir önceki word'de tanımlanan satır ve kolon'a kadar raster beklemesi ayarlar. İkinci satırda $180 background rengini ikinci word'deki değere ($0RGB) set ediyor yani siyah. Bizi ilgilendiren birinci satırdaki ilk word. Dikkat ederseniz satır (2c) ve kolon (07) byte değerler şeklinde verilmiş. Copper sadece bu şekilde çalışıyor yani sorunumuzdaki $ff numaralı satırı geçerken $00'a döneceğiz ve aslında $100'de olmamız gerekirken raster bekleme noktamızda problem yaratacak. Copper dizaynının buna çözümü şöyle:
dc.w $2c07,$fffe
dc.w $180,0
dc.w $ffdf,$fffe
dc.w $1007,$fffe
dc.w $180,$fff
dc.w $1107,$fffe
dc.w $180,0
dc.w $ffff,$fffe
Yani, $ff numaralı satırı geçeceksek bunu copper'a bir uyarı ile belirtmemiz gerekiyor. 3.satır bu uyarı için (dc.w $ffdf,$fffe). Yani $ff nolu satırın $df nolu kolonu için bir bekleme set ediyoruz. Bundan sonra gelecek $ff'den daha düşük her satır numarasını copper $100 sayısının üstüne ekleyerek işleme alacaktır. Sorun çözüldü, değil mi? Değil ne yazık ki..
Statik bir rasterline yapacaksak, yani ekranda kaymayacak ve sadece duracaksa sorun çözüldü. Veya 1-pixel bir line kaydıracaksak yine sorunu çözdük. Ama kalın bir line kaydıracaksak $ff nolu satır için dinamik rutinler kullanmaktan başka bir şansımız kalmıyor. Yani copperlist'i programımız run ederken on-the-fly değiştirmeliyiz. Öyle ki kalın line'ımız $ff nolu satıra yaklaşırken, içinden geçerken, ve sonrasında olmak üzere bu durumları ayrı ayrı ele almak zorundayız. Ya, bu kadar basit bir örnek için nedir bu çektiğimiz, yapılır mı bu arkadaş dediğinizi duyar gibiyim: Amiga yazılımcılığına hoşgeldiniz! :)
Final çözümüm şu şekilde:
Tek renk kalın line için copperlistimizi şu hale getiriyoruz:
copper:
dc CPRFETCHMODE,0 ; slow fetch node, AGA compatibility
dc.w CPRBITPLANECNTL,$0200 ; disable bitplanes
dc.w CPRRASTERLINECLR,$222
dc.l $2f07fffe
dc.w CPRRASTERLINECLR,$000
start:
dcb.l 8
end:
dcb.l 8
dc.l $2b07fffe
dc.w CPRRASTERLINECLR,$222
dc.l $fffffffe
Start ve End etiketlerinin hemen sonralarına dikkat edin lütfen. Bomboş bir alan var orada, toplam 16 longword'lük. Orayı dinamik dolduracağız ve her bir programın ana döngüsünde copperlistin o kısmını tekrar yazacağız. Bu dinamik yazılımı yapan tek renk için kod şu şekilde:
.b:
moveq #8-1,d1
move.l #start,a0
move.l #end,a1
.b1:
move #$01fe,(a0)+
move #$0000,(a0)+
move #$01fe,(a1)+
move #$0000,(a1)+
DBF d1,.b1
move d7,d1
add #BARTHICKNESS,d1
cmp #$ff,d1
blo .c
bhi .d
.c: ; 1st section
move.l #start,a0
move.b d7,(a0)+
move.b #$07,(a0)+
move #$fffe,(a0)+ ; end 1st word
move #CPRRASTERLINECLR,(a0)+
move #$0fff,(a0)+ ; end 2nd word
move.l #end,a0
add #BARTHICKNESS,d7
move.b d7,(a0)+
sub #BARTHICKNESS,d7
move.b #$07,(a0)+
move #$fffe,(a0)+ ; end 1st word
move #CPRRASTERLINECLR,(a0)+
move #$0000,(a0)+ ; end 2nd word
move #$ffdf,(a0)+
move #$fffe,(a0)+ ; end 3rd word
jmp .f
.d:
cmp #$ff,d7
bhi .e ; 2nd section
beq .d1
move.l #start,a0
move.b d7,(a0)+
move.b #$07,(a0)+
move #$fffe,(a0)+ ; end 1st word
move #CPRRASTERLINECLR,(a0)+
move #$0fff,(a0)+ ; end 2nd word
move #$ffdf,(a0)+
move #$fffe,(a0)+ ; end 3rd word
move.l #end,a0
add #BARTHICKNESS,d7
move.b d7,(a0)+
sub #BARTHICKNESS,d7
move.b #$07,(a0)+
move #$fffe,(a0)+ ; end 1st word
move #CPRRASTERLINECLR,(a0)+
move #$0000,(a0)+ ; end 2nd word
jmp .f
.d1:
move.l #start,a0
move.b d7,(a0)+
move.b #$07,(a0)+
move #$fffe,(a0)+ ; end 1st word
move #CPRRASTERLINECLR,(a0)+
move #$0fff,(a0)+ ; end 2nd word
move #$ffdf,(a0)+
move #$fffe,(a0)+ ; end 3rd word
move.l #end,a0
add #BARTHICKNESS,d7
move.b d7,(a0)+
sub #BARTHICKNESS,d7
move.b #$07,(a0)+
move #$fffe,(a0)+ ; end 1st word
move #CPRRASTERLINECLR,(a0)+
move #$0000,(a0)+ ; end 2nd word
jmp .f
.e: ; 3rd section
move.l #start,a0
move #$ffdf,(a0)+
move #$fffe,(a0)+ ; end 1st word
move.b d7,(a0)+
move.b #$07,(a0)+
move #$fffe,(a0)+ ; end 2nd word
move #CPRRASTERLINECLR,(a0)+
move #$0fff,(a0)+ ; end 3rd word
move.l #end,a0
add #BARTHICKNESS,d7
move.b d7,(a0)+
sub #BARTHICKNESS,d7
move.b #$07,(a0)+
move #$fffe,(a0)+ ; end 1st word
move #CPRRASTERLINECLR,(a0)+
move #$0000,(a0)+ ; end 2nd word
Programımız kalın veya ince için artık düzgün çalışıyor:
Not a valid vimeo URL
Bu noktada source kodum şu şekilde: Link (https://bitbucket.org/toygar/codewarriors-amiga-assembler-diary/src/master/sources/rasterline.S).
Alacalı rasterline için gereken değişiklikleri yapmak kolay bundan sonra. Asıl göstermek istediğim kısmı geçtiğimiz için artık detaya girmeme gerek yok ama sizin için son kodu aşağıya ekiyorum.
Not a valid vimeo URL
Bu noktada source kodum şu şekilde: Link (https://bitbucket.org/toygar/codewarriors-amiga-assembler-diary/src/master/sources/rasterline_color.S).
Umarım açıklayıcı olabilmişimdir. Buralara kadar okuduysanız teşekkür ederim. Selamlar sevgiler.
Harikasın!
Asıl sizler harikasınız @Alcofribas .
Nazik sözlerin için çok teşekkür ederim. Detaya da gireriz, hiç yormaz valla. Sevilen bir konuya harcanan emek hiç yorucu olmuyor. Önce hemen setup'ımı ve nasıl kurulabileceğini yazayım. İlerleyen zamanlarda ve daha sonraki girdilerde örnek üzerinden satır satır da geçer, asm komutlarına, hw registerlarına, copper, blitter, sprite komutlarına vs de bakarız. Tabii ki bu nadide toplulukta bunları benden kat kat iyi bilenler vardır mutlaka. Onların katkısı çok daha değerli, ama ben de siz istediğiniz sürece ve zaman bulabildiğim sürece yazarım tabii. Tekrar etmeliyim, başta bahsettiğim Photon'un tutorial'ının sonlarına doğru geliyorum artık. Eğer bu güncede o tutorial'dan sıkıştırılmış bir bilgi toparlağı çıkarabilirsem sevineceğim. Çünkü epey dağınık anlatıyor. Bu günce hiçbir işe yaramazsa en azından bu işe yarar belki -- yine de bu işe ilgisi olan arkadaşlara gözü kapalı tavsiye ediyorum Photon'un tutorial'ını.
Amiga assembler'a hızlı girebilmek ve verdiğim örnekleri derleyip çalıştırmak için en 'basic' setup'ım aşağıdaki gibi.
Not: Mac OS kullanıyorum, Windows'ta çok farklı değildir diye ümitliyim. 'Neden WinUAE değil?' diyen arkadaşlar, Mac'de WinUAE yok - keşke olsaydı ama adı üstünde WINuae :(.
- FS-UAE (FS-UAE Launcher.app & FS-UAE Arcade.app) indirelim: Link (https://fs-uae.net/)
- Kickstart v1.3 indirelim: <Burada bunu veremem biliyorsunuz. Ama eminim bu sizi durduramaz.>
- FS-UAE Launcher'ı kuruyoruz. Paketin içinden FS-UAE Arcade de çıkıyor, bunu kurmaya gerek yok.
- FS-UAE Launcher'ı çalıştırıyoruz. Sol üstteki menü ikonundan 'Import Kickstart'ı seçiyoruz ve download ettiğimiz Kickstart dosyasının içinde bulunduğu folder'ı gösteriyoruz. Bu aşamada birden fazla Kickstart'ı aynı dizin içine koyup tek seferde import edebiliriz.
(https://i.ibb.co/zQ6J8Tr/importkickstart.png) (https://ibb.co/KbKwNpX)
- Üst orta kısımdan 4.ikonu seçiyoruz (Hard Drives). Orada ilk kutunun sağındaki ilk ikonu tıklayıp bir dizini hard disk olarak gösteriyoruz. Bu dizinin içine tüm sourcelarımızı ve toollarımızı direk koyacağız. Size örnek olsun diye 'work' dizinimi zipleyerek ekliyorum bu girdiye, direk onu kullanabilirsiniz. İçinde AsmTwo ve önceki örneklerin source'ları var. Aslında bir yerden sonra dizinleri düzenlemeye başlıyorsunuz, yeni hard disk dizinleri ekliyorsunuz ama hızlı başlamak için bir dizin yeterli.
(https://i.ibb.co/0mcpgSB/adddirectoryashdd.png) (https://ibb.co/Ntsg8P1)
- Configs and Games yazan kısmın altındaki kutucuğa konfigurasyonunuz için bir isim yazın ve sağındaki buton ile kaydedin.
(https://i.ibb.co/v3T07bC/saveconfig.png) (https://imgbb.com/)
- Emulator kurulumu bu kadar. Start'a basın ve başlayın. CLI'de 'work:asmtwo' yazarsanız derleyiciniz çalışacak. Dikkat buradaki 'work', PC'deki dizininizin ismi. AsmTwo uygulaması da bu dizinin içinde olacak zaten.
(https://i.ibb.co/HPYXLKh/cli.png) (https://ibb.co/09ZQpns)
- AsmTwo çalıştıktan sonra ilk soruya 'c' (yani chipmem), ikinciye de 200 (yani 200KB lik bir alanda çalışsın AsmTwo) diyoruz.
(https://i.ibb.co/b7hvSPp/asmtwoconfig.png) (https://ibb.co/ZNsgnVy)
- 'Ready' ve cursor'u gördükten sonra 'r' (yani bir source dosyası yükle) diyeceğiz ve bir hata mesajı alacağız 'Req.Library not found !!!'. Bunu önemsemeyin. 'FILENAME>' sorusuna source'unuzun ismi neyse onu giriyorsunuz, mesela 'rasterline.S'. Dizini girmenize gerek yok zaten AsmTwo 'work' içinde çalışıyor ve source da orada. Source dosyasının byte olarak uzunluğunu söyleyecek size. Tekrar gelen cursorda 'a' diyoruz (yani assemble). İki pass atacak, hata yoksa gelen cursorda 'j' diyelim (yani jump) ve çalıştıralım.
(https://i.ibb.co/djmtYJq/asmtwocomplie.png) (https://ibb.co/FmHXTqM)
- Çalıştı sanırım, umarım..
- 'rasterline.S' örneğini kullandıysanız, sol mouse tuşu ile kodunuzu durdurup assembler'a dönebilirsiniz. Döndükten sonra (veya en başta isterseniz) ESC'ye basarak source'unuzu editleyebilirsiniz ve tekrar ESC ile cursor'a dönebilirsiniz. Ama Amiga üzerinde source-editing bir işkence tabii. Hard diskinizden bir dizini gösterdiniz ve source dosyanız da orada, unutmayın. Sourcelarınızı direk en sevdiğiniz editor neyse onunla kullandığınız işletim sistemi üzerinden editleyin ve mutlu olun.
(https://i.ibb.co/VCxNHB4/asmtwoeditor.png) (https://ibb.co/DMYbGK2)
Bu kadar..
Kolay, değil mi?
AsmTwo aslında yine Photon tarafından AsmOne'dan forklanmış bir version. Bence varolan diğer AsmOne ve AsmPro versiyonlarının hepsinden çok daha iyi çalışıyor. Tabi orjinal AsmOne'ın kullanım klavuzu var sadece: Link (https://drive.google.com/file/d/0B_gsEVgQKS_2Y190R1d2OGNSd1U/view?usp=sharing). Vaktiniz olursa mutlaka okumanızı tavsiye ederim. Çok çabuk okunuyor zaten.
Benim hali-hazırda kullandığım ortam burada anlattığıma çok yakın. Bence böyle epey rahat çalışılıyor. Açıkcası tam anlattığım minimalistlikte başladım. Sonrasında sayısız save-state ve ClassicWB'nin System.HDF'i ile devam ettim. Zaten ilerledikçe siz de buna benzer şekilde değişeceksiniz ama başlamak için yukardaki basit adımları izlemek gayet yeterli.
Bir deneyin, seveceksiniz ;) .
Sevgiler, selamlar.