Gönderen Konu: Zx Spectrum için Assembler Araç Zinciri oluşturmak  (Okunma sayısı 51897 defa)

0 Üye ve 3 Ziyaretçi konuyu incelemekte.

Çevrimdışı ozayturay

  • Retroman
  • ***
  • İleti: 76
  • Commodore Forever
Ynt: Zx Spectrum için Assembler Araç Zinciri oluşturmak
« Yanıtla #15 : 12 Şubat 2012, 15:14:22 »
ZX için exomizer benzeri bir cross packer varsa tavsiye edeceğiniz F12 tuşuna da onu koyalım DevKitRetro'da. :)
http://www.retrodergi.com - http://www.e-turay.com

* Commodore 64C, 1541-II
* Amiga 500, Cortex Floppy Emu

* XBox (TSOP Flash, XBMC)
* Wii (SoftMod, USB Loader GX)
* PS3 Slim (Rogero Cobra, webMAN + mmCM)
* PS2 (FHDB, OPS2L)
* PS1 (ModChip)
* XBox360 (JTAG, Aurora)

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2881
  • Advanced User Simulator
    • ae unutmadan
Ynt: Zx Spectrum için Assembler Araç Zinciri oluşturmak
« Yanıtla #16 : 12 Şubat 2012, 15:39:03 »
ZX için exomizer benzeri bir cross packer varsa tavsiye edeceğiniz F12 tuşuna da onu koyalım DevKitRetro'da. :)

Olmaz mı, aynısının tıpkısı.
Hatta yeni versionu iki hafta önce çıktı, hem de eskisinden daha merdane, şu anda ondan iyi paketleyici yok piyasada,

http://www.speccy.org/metalbrain/exo_v4.zip

tabiiki pasmo'nun coder'ından yine :D

acaba sorduğun başka bişey mi, tabii bilemiyorum, windows'da paketliyor, zx üzerinde açıyor. Ama 1k-4k arası size coding ile uğraşanlar için ancak, yoksa normal bir kodlama işi için sıkıştırma yapmak biraz gereksiz iş yükü gibi geliyor. Lakin depacker 140byte civarı zaten.

Çevrimdışı ozayturay

  • Retroman
  • ***
  • İleti: 76
  • Commodore Forever
Ynt: Zx Spectrum için Assembler Araç Zinciri oluşturmak
« Yanıtla #17 : 12 Şubat 2012, 15:57:05 »
Cruncherların amacı programın diskette veya kasette daha az yer kaplaması, sfx özelliği sayesinde hafızaya en hızlı şekilde açılması.

PC'de UPX'i senelerdir kullanırım, C64'de Exomizer en iyi çözüm gibi görünüyor.

ZX'den pek anlamam ama nasıl kullanıldığını çözüp tarif edebilirsen F12'ye atayabiliriz.

Edit: Cruncher'lar özellikle resim, müzik, sinüs tablosu gibi uzun datalar içeren programları sıkıştırmak için kullanılıyor. Yoksa zaten derlendiğinde 256 byte altında olan bir programı 190 küsür byte decruncher ekleyerek boyutunu büyütmenin bir mantığı yok tabi ki. :)
http://www.retrodergi.com - http://www.e-turay.com

* Commodore 64C, 1541-II
* Amiga 500, Cortex Floppy Emu

* XBox (TSOP Flash, XBMC)
* Wii (SoftMod, USB Loader GX)
* PS3 Slim (Rogero Cobra, webMAN + mmCM)
* PS2 (FHDB, OPS2L)
* PS1 (ModChip)
* XBox360 (JTAG, Aurora)

Çevrimdışı Alco

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2130
  • "Kahraman olmak, dürüst olmaktan kolaydır" Luigi P
    • Sizin Amstrad
Ynt: Zx Spectrum için Assembler Araç Zinciri oluşturmak
« Yanıtla #18 : 13 Şubat 2012, 12:15:58 »
"Satılık Araba Kar Zinciri, İhtiyacı Olana" başlıklarından sonra bu "Zx Spectrum için Assembler Araç Zinciri oluşturmak" başlığı fazla elitist geldi gözüme. Kapatın şu elitleri!

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2881
  • Advanced User Simulator
    • ae unutmadan
Ynt: Zx Spectrum için Assembler Araç Zinciri oluşturmak
« Yanıtla #19 : 13 Şubat 2012, 15:33:29 »
"Satılık Araba Kar Zinciri, İhtiyacı Olana" başlıklarından sonra bu "Zx Spectrum için Assembler Araç Zinciri oluşturmak" başlığı fazla elitist geldi gözüme. Kapatın şu elitleri!

Eheh, evet başlığı koyarken biraz esinlendim :D İhtiyacı olana satılık takmatik z80 araç zinciri.

Örnek Z80 Kodlarına devam edeyim:
Şartlı sıçrama komutlarına birkaç örnek de benden gelsin:
önce DJNZ, pratik bir opcode.

DJNZ, basic'deki for...next döngüsüne benzer.
Örnek:


        ld B,16    ; For b=0 to 16 gibi
loop1   
       
        ...        ; Buraya tekrar edecek kodu ekleyin
       

        DJNZ loop1



B'ye yüklediğiniz rakam kadar tur atacak bu program.

Tabiiki bu halde maksimum 255 tekrar yapılabilir. Daha fazla tekrar için şöyle bişey yapabilirsiniz:

        LD BC, 9999 ; burada 9999 tur atılacak
                    ; 16 bitlik register çifti kullanarak (max.65535)
loop1

        ...         ;Tekrar edilecek kodunuzu tam buraya ekleyin
       
        DEC BC       
        LD A,B       
        OR C         
        JR NZ, loop1 

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2881
  • Advanced User Simulator
    • ae unutmadan
Ynt: Zx Spectrum için Assembler Araç Zinciri oluşturmak
« Yanıtla #20 : 21 Şubat 2012, 15:58:10 »
Belki de en önemli işlerden biri, interrupt kurulumu yapmak.  Interrupt denilen şey, "kesme isteği" olarak çevrilmiş Türkçeye, kesme denilen şey ise, işlemcinin o sırada yaptığı işi bırakıp başka bir adrese zıplamasını sağlayan bir zamanlayıcı. Zx spectrumda saniyede 50 intterupt oluşur.

z80 işlemcide 3 adet kesme modu mevcut. Bunlar IM0 IM1 ve IM2.

Kesme modu 0 iken, kesmeleri bir aygıt kontrol ediyor demektir. Yani genişleme yuvasından takılan bir aygıt olabilir. Bu modda bus'tan bir byte okur ve ona göre hareket eder, bu komut genellikle RSTx komutu olur.

Mod 1 iken işlemci kesme modunu kendi kontrol ediyor demektir ki bu genel olarak servis modu olarak adlandırılır. Zx Spectrumda servis rutini 0x0038 'de tutulmakta, bu adresin özelliği bir byte'lık RST38 komutu ile ulaşılabilinmesi. Basitçe saniyede 50 kere kesme uygulanır, ve bu kesme sırasında RST38 çağrılır. 38h servis rutininde yapılan iki şey var, frames isimli sistem değişkeni bir arttırılır ve klavye okunur.

Mod 2 ise vector jump denilen bir  zıplama şekli. Düşük byte databus'tan okunur, yüksek byte ise I yazmacında tutulan değerdir. Yani vektör= I*256+databus . Problem şu ki, zx spectrumda bustan gelecek verinin ne olacağını tutturmak çok zor (floating bus problemi, ula da aynı veri yolunu kullandığı için oradaki değeri ula değiştirebiliyor). Bu durumda IM2 vektörünün nereyi işaret ettiği konusunda 256 farklılık olabiliyor. Bu işi genellikle o rutine bir tablo yerleştirerek çözüyoruz.

Örneğin I yazmacını 254 olarak ayarlayalım. Bu durumda IM2 vektörü 65024'den başlayacak, ve 256 byte'lık bir sapma olabilecek yani 65280'e kadar. (tablomuzu 257 byte olarak hazırlıyoruz)

Buradaki püf noktasını vermek istiyorum, ki bu bilgi bitpazarlarının yeri kadar gizli kalmış bir sırdır, ayarladığımız bu adres zıplanacak olan adres değil, zıplanacak olan adresi gösteren adrestir. Yani Örneğin databus 255 olsun (ki genellikle interrupt oluştuğunda %99 databus 255'tir) ve I ise 254 olsun, IM2 65280'i işaret edecek ve oraya biz ne koyarsak oraya zıplayacak. Örneğin 65280 ve 65281'de FDh FDh (65021) varsa bu durumda IM2 doğrudan 65021'e zıplar.

Ben kendi kullandığım kodu veriyorum:

 
Kod: [Seç]

org 65021
JP 40000  ;interrupt rutininizi 40000'e koyun.

org 32768
di ;interrupt ayarı yapmadan önce kesmeleri kapatalım

ld   hl,65024 ;tabloyu oluşturacagız, 65024<->65280 arasında
ld   de,65025
ld   (hl),253
ld   b,e
ld   c,e
ldir          ;tablo hazır, aralığı 253'lerle doldurduk.

ld   a,254    ; kesme rutinini tablomuzu gösterecek sekilde ayarlayalim
ld   i,a        ; I yazmacı 254'ü gösterdiginde bus'taki degere göre vektör 65024<->65280 arasında kalacakır.
im   2          ; interrupt mode 2 aktif
        ei          ; interruptlar? açalım

Şimdi buradaki ilk kısımda 257 byte'lık bir FDh tablosu oluşturuluyor, ve interrupt modu o tabloyu işaret ediyor, böylece databusdaki değişmeler sonuca etki edemiyor. Bu kod bir kere çalıştığında artık kesmeler bizim istediğimiz adrese yönlenecek, o adreste de JP 40000 olduğu için her 1/50 saniyede bir 40000 adresine gidilecek demektir.

Interrupt rutini çalıştığında otomatik olarak di çalıştırılır. Yani interrupt rutininden dönmeden önce ei ve ret kullanmayı unutmayın.

Alternatif olarak, eğer 48k için kodlama yapıyorsanız ve FD tablosu için 257 byte harcamak niyetinde değilseniz romdaki FF tablosunu kullanabilirsiniz. 48k Rom'unda 14446'dan başlayıp 15615'e kadar giden devasa bir FF tablosu vardır. Buradaki veriyi kullanarak ve I'yı 59 haline getirerek IM2 zıplama adresini tablo kullanmadan 65535'e dönüştürürsünüz. 65535'e ise 18h (=JR n) yerleştirdiğinizde ve 65535'den sonraki adres 0 olduğu için, romdaki ilk byte olan 243 alınacak ve dolayısıyla -12 geri zıplanacak (JR 243 =-12 göreli zıplar) ve 65524'e düşmüş olacaksınız. Buraya da nihayet kodunuzu yerleştirebilirsiniz. Fakat bu kod 128k'da çalışmayabilir, çünkü o tablo 128k'da 128k editör kodu ile doldurulmuş. +3/+2A'da ise FF yerine 00'lardan oluşuyor. Yani dediğim gibi 48k ile limitli bir opsiyon, fakat ekleyeyim, üst modellerde 48k rom'a dönmek mümkün, programı 48k modunda yükledikleri sürece 128k ve +3'de de çalışacaktır.

Kolay gelsin.

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: Zx Spectrum için Assembler Araç Zinciri oluşturmak
« Yanıtla #21 : 21 Şubat 2012, 20:36:36 »
                     org     8000h

                        di
                        ld      hl,irq
                        ld      (0feffh),hl
                        ld      a,0feh
                        ld      i,a
                        im      2
                        ei
xxx                     jr      xxx

irq                     ld      bc,540
wait00                  dec     bc
                        ld      a,b
                        or      c
                        jr      nz,wait00
                        inc     a
                        out     (254),a
                        ld      b,80
wait01                  djnz    wait01
                        ld      b,32
                        ld      hl,22528
loop00                  ld      (hl),%00001000
                        inc     hl
                        djnz    loop00
                        dec     a
                        out     (254),a
                        ei
                        ret


Kodun sonucu aşağıdaki resimde.

Bu mesajı hafta sonu atacaktım ama üşendim. Ref benden önce interrupta dalmış.
Benim kullandığım metod ise şöyle.

di -------------------- interruptı durduruyoruz
ld      hl,irq --------- kullanıcının interrupt rutini başlangıç adresi hl registerine yazıyoruz
ld      (0feffh),hl --- bu adresi FEFF  ve FF00 adresine yazıyoruz (vektör abimiz olur kendileri)
ld      a,0feh ------- Vektörümüzün High baytını aküye,
ld      i,a ------------ aküyüde i (interrupt) registerine yazıyoruz.
im      2 ------------- interrupt modunu 2 yaptıktan sonra
ei -------------------- interruptı başlatıyoruz

buradan sonrası normal rutin olacak veya
xxxx    jr  xxxx ile sonsuz döngüye girsin.

irq ..............

buradan itibaren interrupt rutini bulunacak.

Rutinin en son satırları ise

ei
ret

komutları olmalı.

Keşke zx'in romundaki interrupt rutini C64'teki gibi ramdaki vektör üzerinden tekrar roma sıçrasa ne güzel olurdu. Reset rutininde

ld hl,oldirq
ld (ramvector),hl

komutlarıyla setup olsa, romdaki irq rutininde ise

ld hl,(ramvector)  ---- hl'ye ramdaki vektörde tutulan adresi yükle
jp (hl) ----- hl'de tutulan adrese zıpla. (oldirq adresine sıçrayacak)
oldirq ......  ;burada ise romdaki normal rutin bulunacak
         ........
komutları olsa, Bizde hiç kasmadan

di
ld hl,myirq    -------- kendi rutinimizin başlangıç adresini hl'ye yazıyoruz.
ld (ramvector),hl --- bu adresi vektöre kopyalıyoruz.
ei

ile kendi rutinimizi aktif hale getirsek çok güzel olurdu. Rutinimizin sonunda ise jmp oldirq ile roma zıplayıp devam etsek süper olurdu aslında.

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2881
  • Advanced User Simulator
    • ae unutmadan
Ynt: Zx Spectrum için Assembler Araç Zinciri oluşturmak
« Yanıtla #22 : 22 Şubat 2012, 01:23:02 »
                     org     8000h

                        di
                        ld      hl,irq
                        ld      (0feffh),hl
                        ld      a,0feh
                        ld      i,a
                        im      2
                        ei


benim metod ile aynı, data bus'ının herzaman 255 olduğunu kabul ediyor bu rutin. Problem şu ki, IM2 aslında donanım interruptu. Dolayısıyla böyle kullanımda sorunlar çıkabiliyor. Ama ne zaman, belkide hiç önemli değil, mesela kempston joystick takılı iken senin demo çalışmaz. Ya da interface1. Divide problem çıkarmıyormuş fakat divide+ yine databus'a random değerler bırakabiliyormuş.  Yani senin irq setupın çıplak zx spectrum için oluyor. Birçok demo programcısı için belirli bir setup istemek kolaydır. Bu demoyu izlemeden önce tüm aygıtlarınızı sökünüz diye bir mesaj gösterebilirsin, yüklerken mesela. :D Yine dediğim gibi, birçok durumda bu setup gayet düzgün. Fakat eğer programın garip davranırsa emülatörün aksesuarlarını kapat :D

Alıntı
Keşke zx'in romundaki interrupt rutini C64'teki gibi ramdaki vektör üzerinden tekrar roma sıçrasa ne güzel olurdu. Reset rutininde

Aslında +2 ve +3'de ALL RAM modu var. Böylece IM1 rutinini senin söylediğin gibi değiştirebiliyorsun. Yani rom yerine ram page edebiliyorsun. Sözü gelmişken yineleyeyim, Spectrum camiasında en uyumlu ve en gelişkin makine olarak +2A/B kabul ediliyor. Hem gelişkin bir sayfalama/gecikme yapısı var, hem de 128k kullanma kılavuzundaki değerlere göre düzenlenmiş. :) Ama pek yaygın değiller, bu sebepten eski yöntemlerle çalışmak şart. Bu arada IM1'in ram'daki bir vektöre göre yönlenmemesi tamamen z80'in tasarımıyla ilgili. IM1 direkt olarak rst 38 çağırıyor. Orda da rom var. IM2 varken rom'un ramdeki bir değişkeni kontrol etmesi zaman kaybı olarak düşünülmüştür belkide.

Alıntı
xxx                     jr      xxx
Interrupt oluşması için komutun tamamlanması gerekiyor. Yanlış hatırlamıyorsam (bakmaya üşendim) JR n, 7tstate tutuyordu. Bu senin interrupt kodunda 7tstate'lik bir sapmaya sebep olabilir, çünkü interrupt'un oluşmasını 7tstate'lik aralıklarla gerçekleştirebilirsin. Senin kodda herhangi bir kullanıcı girişi vs olmadığı için büyük bir problem değil ama, sonsuz döngü yaratmak yerine araya bir HALT eklesen daha sağlıklı olacaktır.
xxx
ei
halt
jr xxx

gibi bişey

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: Zx Spectrum için Assembler Araç Zinciri oluşturmak
« Yanıtla #23 : 23 Şubat 2012, 20:45:01 »
Ref bu kadar bilgiden sonra birşeyler yaparsın artık. ZX'le ilgili daha neler biliyorsundur kimbilir?

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2881
  • Advanced User Simulator
    • ae unutmadan
Ynt: Zx Spectrum için Assembler Araç Zinciri oluşturmak
« Yanıtla #24 : 24 Şubat 2012, 13:59:51 »
Ref bu kadar bilgiden sonra birşeyler yaparsın artık. ZX'le ilgili daha neler biliyorsundur kimbilir?

Heheh, ben demodan ziyade tool kodlamayı seviyorum. Aşağı yukarı yılda 2 tool çıkarırım genelde windows tabanlı, ya da zx-windows çaprazında çalışan araçlar. Bu sırada çok şey öğreniyor insan ama, o öğrendiklerimi intro/demoya çevirecek vakit yok.

Örneğin, yeni bir ekran modu önerim var, şu günlerde onunla uğraşıyorum. En verimli şekilde multicolor kullanımıyla, 48k üzerinde tam erkran multicolour bir grafik oluşturmak. Aslında bu tam bir scene işi. Güzel bir demoda dikkat çeker kesinlikle. Fakat, ben bunu bir tool olarak kodluyorum yine. Yani bu işi otomatize eden bir program yazıyorum ki herkes asmp modunda grafik oluşturabilsin.

Becerebilecekmiyim bilmiyorum, bu yoğunlukta gidilecek yol uzun, ama vakit çok az :D

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: Zx Spectrum için Assembler Araç Zinciri oluşturmak
« Yanıtla #25 : 08 Mart 2014, 20:43:30 »
Bugün win7 kurdum. Crimson'u ayarlayıp kodların bulunduğu klasörleri düzenledim. Aynı kodu 3-4 yere kaydetmişim. Kodlamaya devam.