Gönderen Konu: Skate'in ZX Spectrum Maceraları - Vol 1  (Okunma sayısı 1623 defa)

0 Üye ve 1 Ziyaretçi konuyu incelemekte.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 199
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #15 : 04 Mayıs 2022, 07:29:51 »
Dokuzuncu versiyonda çok ufak bir ilerleme var, sonuç hala titreşen noktalar şeklinde. Ama artık her şeyi yapıyoruz, tarama da yakalatıyoruz, noktaları silme rutinimiz de son haline ulaşmış olmasa da döngü şeklinde değil, açık ve hızlı çalışıyor.

Kod: [Seç]
    ; end of frame

    ; wait for the next frame
    ei
    ld a, 0
    out (0xfe), a       
    halt
    di

Burada sonraki frame'i bekletiyoruz. "ld a, 0" ve "out (0xfe), a" border rengini değiştirip tarama bölgesini görmek için ekleyip o şekilde unuttuğum bir parça, lüzumlu değil. Geri kalan "ei", "halt", "di" benim o zamanki mantığıma göre şunu yapıyor. Kodun başındaki "di" kesme rutinlerini kapatıyor. Ben çizimimi yapıyorum, işim bitiyor. Bu noktada kesme rutinlerini açıp "halt" ile yeni bir kesme rutini tetiklenene dek işlemciyi boşa çekiyorum. Kernel'in kesme rutini çalıştığı noktada tekrar kesme rutinlerini kapatıp sonraki frame'e yelken açıyorum. Ancak burada henüz bilmediğim ve @Ref ile bir telefon görüşmemizde öğrendiğim bir şey var. O da kernel'in tarama yakalama işlemi sonrası epey bir tstate'i çöpe attığı. Bunu ilerleyen versiyonlarda çözeceğiz.

Kod: [Seç]
    ; clear plots
i = 0
    WHILE i < 256
        pop hl
        ld (hl), 0
i = i + 1
    ENDW

Bu rutin ideale yakın. Peş peşe 256 kere "pop / ld" ile sadece çizdiğimiz noktaların dokunduğu byteları temizliyor. Ancak buradaki sorun "ld (hl), 0" opcode'unun benim düşündüğüm gibi en az tstate yiyen versiyon olmayışı. Sıfır gibi sabit bir değer yerine bir değişken kullansak daha az tstate harcamış oluyoruz. Bunu da sonradan fark edip düzelteceğim.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 199
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #16 : 04 Mayıs 2022, 07:44:32 »
Onuncu versiyonumuzda artık elle tutulur bir şeye ulaşmış durumdayız. Hala eksikleri varsa da güzel olan ekranda bir titreme olmadan noktalar dolaşıyor. Ama kaç tane nokta dolaşıyor? Saymakla uğraşmasam da net cevabım şudur "256'dan az". Aslında 256 nokta çiziyoruz ve bunu bir frame'e sığacak zamanda çizdirebiliyoruz, frame taşması yaşanmıyor. Ancak ZX Spectrum 48k'da da çalışmasını hedeflediğimiz için double buffer kullanma şansımız yok. Yani bizim o anda ekrana çizmek istediğimiz bir noktanın Y koordinatı o anda ışın taramasının bulunduğu Y koordinatından küçükse o nokta sonraki frame'de görünür olacak şekilde ekrana henüz çizilemiyor ama biz sonrasında da tüm noktaları temizleyerek o noktanın asla çizilememesini sağlamış oluyoruz. Bu sorunla daha sonra mücadele edeceğiz.

Kod: [Seç]
    ld b, 0
mainLoop:

phaseX:
    ld hl, sinX
    ld a, l
    add a, b
    ld l, a
    ld l, (hl)
    ld h, 0

    ; put pixel
    ;ld hl, (plotX)
    ld de, orBit
    add hl, de
    ld c, (hl)

    ld a, l
    and %11111000
    rrca
    rrca
    rrca
    ld e, a
    ;ld d, 0    ; orBit high byte is subtracted from lines table high bytes to get rid of this line

    ld a, (counter)
    add a, 2
    ld (counter), a
    jr NZ, skipHiIcrement
    ld hl, plotYlookup+2
    inc (hl)
skipHiIcrement:
    ld hl, plotYlookup+1
    ld (hl), a

plotYlookup:
    ld hl, (sinY)
    add hl, de
    ld a, (hl)
    or c
    ld (hl), a
    ; end of put pixel

    ; push pixel memory address to stack
    push hl

    djnz mainLoop

Buradaki en önemli değişimlerden biri artık b registerını ve "djnz" opcode'unu kullanıyor olmamız. djnz b register'ını bir azaltıp, sıfıra gelmediği sürece döngüye devam etmeyi sağlayan, sıfıra gelince döngüyü sonlandırıp devam etmesine yarayan, x86 ASM'deki "cx register'ı ve loop opcode'u" ikilisinin bir benzeri. Önceki versiyonlarda djnz'yi bilsem de tüm registerları rahatça kullanabilmek adına kullanmamıştım. Bu aşamada artık b'yi boşa çıkarıp bu iş için kullanma vaktimiz gelmiş durumda.

Henüz tablolarımız tamam değil. Bu nedenle bu versiyonda eklenen bazı kısımlara çok değinmiyorum, zaten yanlış yöntemler. Önümüzdeki versiyonlarda bu kısımları toparlayacağız.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 199
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #17 : 04 Mayıs 2022, 08:06:57 »
On birinci versiyona geldiğimiz şu noktada ışın taraması kovalama işi ile ilgili biraz canım sıkkın. Çünkü o iş hem uğraştıracak, hem yeterince esnek olmayacak. Örneğin noktaları farklı sinüs tablolarına göre çizdirdikçe, 3 boyutlu dönen noktalar gibi başka efektlere dönüştürdükçe, efektin zamanlaması değiştikçe önceki çözüm çöpe gidip, bir yenisiyle uğraşmam söz konusu olabilir. Ama en azından mevcut haliyle 256 noktayı görebilmek için şöyle ümit verici bir durum var. Aslında çizilemeyen nokta sayısı o kadar da yüksek değil. Yani tek bir noktayı basan rutini yeterince optimize edebilirsek belki ışın taraması kovalamayla hiç uğraşmayabilir, o işi 256'den fazla nokta basma ya da farklı efektlere ötelemiş oluruz.

Bu ümitlerle bir kaç optimizasyon yaptım.

Kod: [Seç]
    ; reset d register which is untouched in the main loop
    ld d, 0

    ; reset loop counter
    ld b, 0

d register'ının orBit tablo değerinin high byte'ını aldığını ve bu yüzden diğer tablolardan değer çıkardığımızı hatırlarsınız. Bu versiyonda d'yi tamamen boşa çıkararak sadece;

Kod: [Seç]
    ; find char column
    ld a, l
    and %11111000
    rrca
    rrca
    rrca
    ld e, a

...

plotYlookup:
    ld hl, (sinY)
    add hl, de
    ld a, (hl)
    or c
    ld (hl), a
    ; end of put pixel

Bu şekilde kullanıyoruz. Yani bir noktada e'ye bir değer verip, ileride "add hl, de" şeklinde 16 bitlik bir toplama yapıyoruz. Ama d döngü içerisinde hiç değer değiştirmediği ve başta da sıfıra eşitlendiği için sorun olmuyor, hl'e asıl amacımız olan 8 bitlik değeri 16 bitlik register kullanarak eklemiş oluyoruz.

Kod: [Seç]
    ; clear plots
    xor a
i = 0
    WHILE i < $100
        pop hl
        ld (hl), a
i = i + 1
    ENDW

Sonunda daha önce de bahsetmiş olduğum "ld (hl), 0"ın "ld (hl), a"ya kıyasla 3 tstate fazla tuttunu fark etmiş olacağım ki bu noktada düzeltmiş ve 3*256-4 = 764 tstate boşa çıkarmış oldum. Accumulator'ün değerini sıfırlamak için eklediğimiz "xor a" 4 tstate tutsa da 256 kere tekrar eden kod sayesinde kendisini fazlasıyla affettiriyor. Ancak burada tekrar eden bir kod olmasa, sadece bir kerelik bir işlem olsa "xor a" ile birlikte kullandığımızda 1 tstate zararda olacaktık.

Evet, optimizasyonlarımızı yaptık. Daha önce ölçtüğümden aklımda kaldığı kadarıyla CPU kullanımını %90'lardan %70'lere kadar gerilettik. Ama hala noktaların bazıları gözükmüyor. Demek ki daha radikal değişikliklere ihtiyacımız var.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 199
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #18 : 04 Mayıs 2022, 08:23:27 »
On ikinci versiyonda öncelikle kesme rutini işine el atıyoruz. @Ref'in telefonda bahsettiği konuyu araştırıyor ve ZX Spectrum 48k'nın kernel'inde yer alan bir bloğa özel bir çözüm buluyoruz. 128k modelleriyle de uyumlu olması açısından kendi tablomuzu üreterek kesme rutini ile ilgili çözümümüzü üretiyoruz.

Kod: [Seç]
im2Jump = $fdfd

...

    ; set irq
    ld hl, im2Jump
    ld (hl), 0xc3
    inc l
    ld (hl), low irq
    inc l
    ld (hl), high irq
    ld a, high im2Table
    ld i, a
    im 2
    ei

...

irq:
    ei
    ret

...

    ALIGN $100
im2Table:
    BLOCK 257, low im2Jump

Artık kernel tarama yakalattıktan sonra ek zaman harcamıyor, bizim kendi yarattığımız "irq" labelına düşüyor kod. Bu kısmı aşağıdaki sitede çok güzel açıklamışlar. Ben de bu paylaştığım linkten öğrendim.

http://www.breakintoprogram.co.uk/computers/zx-spectrum/interrupts

Normalde "irq" içerisinde tüm değişkenleri girişte kaydedip, çıkışta eski değerlerine çevirmek gerekiyor. Ancak irq içinde hiç bir işlem yapmayıp, dolayısıyla hiç bir değer bozmadığım için şimdilik bu şekilde bırakmayı uygun gördüm.

Bu noktada derleyicinin low / high byte alma yazım biçimini de öğrenmiş oluyorum. Örneğin daha önce;

Kod: [Seç]
ld h, orBit >> 8

olarak kullandığım kısmı

Kod: [Seç]
ld h, high orBit

olarak değiştirmişim.

Kod: [Seç]
BLOCK 257, low im2Jump

bu şekilde de kullanımlarım var. Yani 6502 ASM'de genellike < ve > sembolleriyle ifade ettiğimiz 16 bitlik bir sayının alt ve üst 8 bitini al ifadesi SjASMPlus'da sembol yerine "low", "high" ön ekleri ile karşılığını bulmuş.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 199
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #19 : 04 Mayıs 2022, 08:46:05 »
On üç o kadar da uğursuz gelmemiş, sondan bir önceki versiyonumuz. Sonunda z80'de tablodan değer okumayı öğreniyoruz ve her şeyi olması gereken şekilde tabloluyoruz, bit shifting falan da kalmıyor. Z80'de kilit noktalardan biri tabloları kullanım sırasına göre sıralamakmış. Tabii bu 256 byte kaplayan ve $100'lük bloklara düzgün yerleştirilmiş tablolar için geçerli. Bu nedenle daha önce 16 bit olarak kullandığım tabloları da low ve high byte tabloları olarak ikiye bölüyorum. Kritik noktalar şuraları.

Kod: [Seç]
    ; --- put pixel

    ; get X position from sine table
    ld a, d
    add a, b
    ld l, a
    ld h, high sinX
    ld l, (hl)

    ; get or bit pattern for given x in character position
    inc h   ; orBit is right after sinX
    ld c, (hl)

    ; find char column
    inc h   ; charPosition is right after orBit
    ld e, (hl)

    ; find plot address
    ld l, b
    inc h ; sinYLo is right after charPosition
    ld a, (hl)
    or e
    inc h ; sinYHi is right after sinYLo
    ld h, (hl)
    ld l, a

    ; set pixel using OR
    ld a, (hl)
    or c
    ld (hl), a

    ; --- end of put pixel

Bu rutin "put pixel" olarak isimlendirilmiş durumda ancak aslında sadece nokta koymuyor, aynı zamanda X ve Y'de iki sinüs tablosundan da okuma yapıyor. Burada önceki versiyonlara kıyasla bize büyük avantaj sağlayan şey şu oluyor. Bir tablodan bir değer okuyoruz. O değeri okurken doğrudan "L" registerına alıyoruz. HL ile okuma yapacağımız için low byte doğrudan hazır hale geliyor. High byte'ı ise bir önceki tablodan bir fazla değerde olduğu için "inc h" dememiz yetiyor ki bu sadece 4 tstate harcayan bir opcode. Commodore 64'de tabloların hafızada ne sırada durduklarının bir önemi yokken yapısı gereği Z80'de önem teşkil ediyor.

Bir diğer önemli optimizasyonumuz ise önceden boşa çıkarmış olduğumuz d registerını artık "de" registerıyla ilgili kullanımımız da iptal olduğu için frame sayacına çeviriyoruz. b'de de nokta sayacı bulunuyor.

Kod: [Seç]
    ; d register is the frame counter
    ld d, 0

...

    ; get X position from sine table
    ld a, d
    add a, b
    ld l, a
    ld h, high sinX
    ld l, (hl)
    ...

Bu sayede bu kod bloğunda hem her nokta için bir ileriden okuma yapmayı sağlarken hem de d'nin değerinin eklenmesiyle frame'den frame'e de ilerleyen biçimde okuma yapılması sağlanıyor. Önceki gibi ek sayaçlar, işlemlerden kurtulup, sadece registerlarla işimizi çözmüş oluyoruz.

En çok dikkat edilmesi gereken şey tabloların sıralı olması. İki tablonun yerini değiştirdiğiniz gibi kod kullanımı aynı kaldığı sürece program düzgün çalışmayacaktır. Tablolar iki yönde de sıralanabilirler. "inc h" yerine "dec h" kullanarak önceki tabloya geçiş yapma seçeneğimiz de var.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 199
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #20 : 04 Mayıs 2022, 09:00:45 »
On dördüncü ve şu an için son versiyonumuza geldik. Bu versiyonda sadece biraz kod toparlama var.

Kod: [Seç]
    ; definitions
debug       = 1
stackSize   = 512
im2Jump     = $fdfd

Kodumuz artık böyle tanımlarla başlıyor, efektin ne kadar CPU harcadığını görmek için eklediğimiz çerçeve renkleri "debug" parametresi ile açılıp kapatılabiliyor.

Kod: [Seç]
    ; set border color for debugging
    IF debug == 1
        ld a, 1
        out ($fe), a
    ENDIF

...

    ; set border color for debugging
    IF debug == 1
        ld a, 4
        out ($fe), a
    ENDIF

Ekte "first.zip" dosyasında tüm proje klasörünü ziplenmiş biçimde bulabilirsiniz.

...ve filmin ilk sahnesine ulaştık. Şu anda sahip olduğumuz efekt güzel bile gözükmeyen, yeterince dinamik olmayan sinüs hareketi yapan 256 noktadan ibaret. Ama şu aşamadan sonra ağırlıklı olarak keşfetmekten ziyade kodlamakla uğraşacağım bir aşamaya geldiğimi düşünüyorum. Bu nedenle sizinle bu gelişim sürecini paylaşmak istedim. Yeni başlayanlara biraz katalizör olabilir diye umuyorum. Zamanla bu rutini daha da optimize edeceğim ve farklı efektlerin de altyapısını oluşturacak elbette ki. Yani bu yazıların en başında belirttiğim gibi, henüz filmin ortasındayız, sonunda değil. Lütfen herhangi bir yorum yapmak ya da soru sormaktan çekinmeyin. ZX Spectrum dünyasına yeni adım atmış biri olarak da teknik olsun olmasın her türlü tavsiyeye son derece açığım. Bir ZX Spectrum +2 ve sd card reader edinmeyle ilgili tavsiyeler de buna dahil elbette ki. ;)

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 192
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #21 : 04 Mayıs 2022, 09:26:23 »
@Skate 6510'dan sonra Z80'de de ustalığınını konuşturmussun. Üstelik bu kadar kısa bir sürede olmasına rağmen. Z80 artık gençlerin yetenekli ellerinde.
Eline sağlık, ayrıca çok güzel bir tutorial olmuş.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 199
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #22 : 04 Mayıs 2022, 09:38:48 »
@Skate 6510'dan sonra Z80'de de ustalığınını konuşturmussun. Üstelik bu kadar kısa bir sürede olmasına rağmen. Z80 artık gençlerin yetenekli ellerinde.
Eline sağlık, ayrıca çok güzel bir tutorial olmuş.

Teşekkür ederim İsmail. Hele ki o gençlerden biri olarak beni kastediyorsan moralim yerine geldi sabah sabah. :)

@matahari bana dün bir optimizasyon önermişti. Yazıyı bitirene kadar kafayı odaklayamadım. Yazı bittikten sonra önerdiği noktada değil ama başka bir yerde aynı tavsiye yerini buldu, biraz daha tstate traşladık. Değişen kısım.

Kod: [Seç]
    ; find char column
    inc h   ; charPosition is right after orBit
    ld a, (hl)

    ; find plot address
    ld l, b
    inc h ; sinYLo is right after charPosition
    or (hl)
    inc h ; sinYHi is right after sinYLo
    ld h, (hl)
    ld l, a

Kodu parça parça optimize ettiğim için şimdi bütününe bakarak çok daha güzel şeyler bulunabilir.

matahari

  • Ziyaretçi
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #23 : 04 Mayıs 2022, 12:48:23 »
@Skate zor olanı başardı; kendisini aştı. Yıllardır kimsenin eline su dökemediği C64 scene ortamının verdiği rehaveti bir kenara bıraktı, hiç bilmediği sulara yelken açarak sıfırdan Z80 öğrenmeye başladı. Bunu gizliden gizliye değil, Sokrates misali "Bildiğim tek şey, Z80 hakkında hiçbir şey bilmediğimdir" şeklinde açıkça ifade ederek, camiadan gelebilecek tüm fikir, eleştiri ve ukalâlıklara göğüs gerecek yüreklilikle yaptı. Kod geliştirme ortamı için gereken araç-gereç seçiminden tutun da eserlerini sergileyebilmek için domain name almaya kadar her detayı kafasında planlamış olsa gerek, hem yazdığı kodları forumda paylaştı hem de bu süreç içerisinde edindiği olumlu/olumsuz tüm tecrübeleri kaleme alıp yazılı literatüre katkıda bulundu. Sonuçta Skate, ilk ZX Spectrum projesinde yapması gerekenden çok daha fazlasını üreterek/paylaşarak kendisine yakışanı yaptı; risk aldı ve zor yolu seçti. Kendisini hem çok takdir ediyor, hem de tüm kalbimle kutluyorum!

"O kod böyle olmalıydı", "Bu kod şöyle optimize edilmeliydi" benzeri sözler sarf etmek haddim değil. Sonuçta, karşımda yılların scene tecrübesine sahip sıkı bir yazılımcı var. Su yolunu bulur. Olur da şaşar ise, sorularını sorabileceği bir oyun geliştiricinin her zaman yanında olduğunu kendisi zaten gayet iyi biliyor.

Skate’in azim ve başarılarının diğer yazılımcılara örnek olmasını umar, yıllarca scene ortamının tozunu attıran tüm kodlama ustalarının vakti geldiğinde "bir sonraki zorlu kulvar" olan profesyonel oyun geliştirme işine sıçrayacak cesareti göstermesini içtenlikle dilerim.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 199
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #24 : 04 Mayıs 2022, 12:56:01 »
@Skate zor olanı başardı; kendisini aştı. Yıllardır kimsenin eline su dökemediği C64 scene ortamının verdiği rehaveti bir kenara bıraktı, hiç bilmediği sulara yelken açarak sıfırdan Z80 öğrenmeye başladı. Bunu gizliden gizliye değil, Sokrates misali "Bildiğim tek şey, Z80 hakkında hiçbir şey bilmediğimdir" şeklinde açıkça ifade ederek, camiadan gelebilecek tüm fikir, eleştiri ve ukalâlıklara göğüs gerecek yüreklilikle yaptı. Kod geliştirme ortamı için gereken araç-gereç seçiminden tutun da eserlerini sergileyebilmek için domain name almaya kadar her detayı kafasında planlamış olsa gerek, hem yazdığı kodları forumda paylaştı hem de bu süreç içerisinde edindiği olumlu/olumsuz tüm tecrübeleri kaleme alıp yazılı literatüre katkıda bulundu. Sonuçta Skate, ilk ZX Spectrum projesinde yapması gerekenden çok daha fazlasını üreterek/paylaşarak kendisine yakışanı yaptı; risk aldı ve zor yolu seçti. Kendisini hem çok takdir ediyor, hem de tüm kalbimle kutluyorum!

"O kod böyle olmalıydı", "Bu kod şöyle optimize edilmeliydi" benzeri sözler sarf etmek haddim değil. Sonuçta, karşımda yılların scene tecrübesine sahip sıkı bir yazılımcı var. Su yolunu bulur. Olur da şaşar ise, sorularını sorabileceği bir oyun geliştiricinin her zaman yanında olduğunu kendisi zaten gayet iyi biliyor.

Skate’in azim ve başarılarının diğer yazılımcılara örnek olmasını umar, yıllarca scene ortamının tozunu attıran tüm kodlama ustalarının vakti geldiğinde "bir sonraki zorlu kulvar" olan profesyonel oyun geliştirme işine sıçrayacak cesareti göstermesini içtenlikle dilerim.

Güzel ve nazik sözlerin için tekrar tekrar teşekkür ediyorum @matahari.

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 3093
  • Advanced User Simulator
    • ae unutmadan
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #25 : 04 Mayıs 2022, 18:09:56 »
@Skate tüm hızıyla 6502 denizinden çıkarak kumsala vardı, şimdi ekstra registerleri gelişiyor ve z80'de gezerleri uzaktan izliyor. Yaptıklarını taklit ederek aralarına karışıyor :) Ama bu hızla giderse yakında liderleri olabilir :D Forumda bir z80 rüzgarı esiyor ki bundan en çok ben memnunum herhalde.

IM2 hakkında bir detay eklemek istiyorum, ZX Spectrumda "floating bus" denilen bir olay var. Şimdi tam ezberimde yok ama özetle Z80, spectruma takılı aygıtlardan alınan datayı bus'a koyuyor ve orda kalıyor. Buna ULA da dahil. Eğer bir aygıt takılı değilse ve o anda ula ram'den grafik belleğini okuyorsa, okuduğu bu byte'ı bus'a koyuyor.

şimdi burada şöyle bir sorun olabiliyor, IM2 vektörünün bir byte'ı bus'tan geldiği için, eğer interrupt öncesinde z80 port okumaya çalışmışsa, IM2 vektörün 0-255 arasında bozuluyor. Bu sebepten geleneksel olarak IM2'yi kurarken 256 byte'lık bir jump table yapılması tercih ediliyor.  Bu davranışı hades'in başlığında örnek bir kodla paylaşmıştım:

https://retrojen.org/pano/index.php?topic=539.msg4328;topicseen#msg4328

Bazı emülatörler bu davranışı da desteklemediği için yazdığın ve sağlam sandığın kod, gerçek makinede çalışmayabilir. Bu sebepten "ne oluyor burda" diye takılıp kalma diye hatırlatma olarak yazmak istedim.

https://sinclair.wiki.zxnet.co.uk/wiki/Floating_bus

Bu özellik 48K'larda çok tutarlı çalışıyor ve floating bus, raster interrupt yerine kullanıldığı oluyor. Ama 128k için aynı şeyi söyleyemiyorlar, pek araştırmadım, bu bilgiler kulaktan dolma, hatalı olabilir.

Çevrimdışı ssg

  • RAAT
  • Retromanik
  • *
  • İleti: 19
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #26 : 04 Mayıs 2022, 19:42:33 »
@Skate, bu kadar kısa sürede benden çok daha ileri gitmişsin. Benim Z80 tecrübem ortaokulda opkod tablosu ezberlediğim vaziyette kaldı (21 00 40 11 00 c0 01 00 40 ed b0) :)

Ama bu beni gaza getirdi, acaba CPC için bir cross-platform development ortamı oluşturabilir miyim diye düşünmeye başladım.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 199
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #27 : 04 Mayıs 2022, 20:22:59 »
IM2 hakkında bir detay eklemek istiyorum, ZX Spectrumda "floating bus" denilen bir olay var. Şimdi tam ezberimde yok ama özetle Z80, spectruma takılı aygıtlardan alınan datayı bus'a koyuyor ve orda kalıyor. Buna ULA da dahil. Eğer bir aygıt takılı değilse ve o anda ula ram'den grafik belleğini okuyorsa, okuduğu bu byte'ı bus'a koyuyor.

şimdi burada şöyle bir sorun olabiliyor, IM2 vektörünün bir byte'ı bus'tan geldiği için, eğer interrupt öncesinde z80 port okumaya çalışmışsa, IM2 vektörün 0-255 arasında bozuluyor. Bu sebepten geleneksel olarak IM2'yi kurarken 256 byte'lık bir jump table yapılması tercih ediliyor.  Bu davranışı hades'in başlığında örnek bir kodla paylaşmıştım:

https://retrojen.org/pano/index.php?topic=539.msg4328;topicseen#msg4328

Bazı emülatörler bu davranışı da desteklemediği için yazdığın ve sağlam sandığın kod, gerçek makinede çalışmayabilir. Bu sebepten "ne oluyor burda" diye takılıp kalma diye hatırlatma olarak yazmak istedim.

https://sinclair.wiki.zxnet.co.uk/wiki/Floating_bus

Bu özellik 48K'larda çok tutarlı çalışıyor ve floating bus, raster interrupt yerine kullanıldığı oluyor. Ama 128k için aynı şeyi söyleyemiyorlar, pek araştırmadım, bu bilgiler kulaktan dolma, hatalı olabilir.

Elbette ki detaylarını çok iyi bilemiyorum, yani 128k modellerinde bu konu ile özel bir sorun varsa tabii ki sıkıntı olur. Ancak floating bus benim yabancı olduğum bir konsept değil. Commodore 64'de de benzer mimaride çok fazla trick kullanırız. Ninja'nın FLI üzerine 6 sprite basmada kullandığı teknik, lft'nin safe VSP'yi kodlarken kullandığı teknik hep bu floating bus olayına benzer. Yani rastgele hafızanın bir yerine dallanma, dallanabileceği yerlere aynı kodun kopyalarını yerleştirme gibi şeylere alışığım. Bu bağlamda benim anladığım şey 48k ile 128k arasında bu tarz bir fark olmasından ziyade 48k'nın kernel'ı içinde peş peşe 257 byte boyunca $ff yer alması. Bu sayede kendi kodun içinde tablo yaratmadan kernel'deki tabloyu kullanarak işi çözebiliyorsun. 128k modellerinde ise o 257 bytelık tabloyu kendi koduna eklemen gerekiyor (ki nitekim benim kodumda mevcut). 256 değil 257 byte olma nedeni de pointer rastgele 256 bytelık alanda herhangi bir yere işaret edebiliyor ancak byte değil word okuyor, bu yüzden 256 bytelık alanın son byteına denk gelirse 1 ekstra byte daha okuması gerekiyor.

Tahminimce bu konuda bir sorun çıkmayacaktır. Benzer olarak nitelediğim örnekleri incelemek isterseniz linkleri paylaşıyorum.

The Ninja-Method

lft's Safe VSP

Emülatörler elbette ki crash edebilir ama benim beklentim gerçek cihazda sorun çıkmaması yönünde.

Bu arada tüm güzel sözlerin, desteğin ve Z80'e olan ilgimdeki payın için tekrar teşekkürler @Ref.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 199
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #28 : 04 Mayıs 2022, 20:32:13 »
@Skate, bu kadar kısa sürede benden çok daha ileri gitmişsin. Benim Z80 tecrübem ortaokulda opkod tablosu ezberlediğim vaziyette kaldı (21 00 40 11 00 c0 01 00 40 ed b0) :)

Ama bu beni gaza getirdi, acaba CPC için bir cross-platform development ortamı oluşturabilir miyim diye düşünmeye başladım.

Tekrar teşekkürler Sedat. CPC'de ben Speccy'e benzer bir ortam kurmamıştım ama yine cross development yapıyordum. İstediğim text editörüyle kodu geliştiriyordum ancak en son WinAPE içinden derliyordum. Kaynak kodu düzenlemek için doğrudan WinAPE'in içinde gelen Assembler'ı kullandığım da oluyordu. Ekte ekran görüntüsünü paylaşıyorum.

Şu anda Speccy için kullandığım geliştirme ortamını birebir CPC için de kullanabilirim elbette ki. Ama @Fero zamanında "CPC'de racon bu" demişti, ben de çok sorgulamamıştım. Derleniyor mu derleniyor sonuçta.

Amaan, büyük projelere girişelim de derdimiz development ortamımızın konforsuzluğu kalsın. :)

Çevrimdışı ssg

  • RAAT
  • Retromanik
  • *
  • İleti: 19
Ynt: Skate'in ZX Spectrum Maceraları - Vol 1
« Yanıtla #29 : 04 Mayıs 2022, 20:40:42 »
Kaynak kodu düzenlemek için doğrudan WinAPE'in içinde gelen Assembler'ı kullandığım da oluyordu.

Evet, ben Run SSG Run introsunu partide o düzenekle yazmıştım. Hatta bir indirection file (https://github.com/ssg/run-ssg-run/blob/master/introwrap.asm) ile dosyaları da açmana gerek kalmıyor. Ama VS Code içinde emülatör ekranı, source debugging ihtimalleri vs kulağa güzel geliyor. Yoksa haklısın, esas olan projedir :)