Retrojen Forum

Dijital Sanat => Kodlama => Konuyu başlatan: hades - 15 Ocak 2014, 22:46:00

Başlık: Z80 Makine diline meraklı olan?
Gönderen: hades - 15 Ocak 2014, 22:46:00
"6502 Makine diline meraklı olan?" başlığı olurda "Z80 Makine diline meraklı olan?" başlığı olmaz mı?

1985'te 48K ZX Spectrum sahibi olup ilk sene oyun oynayıp kendi çapımda Basic öğrendikten sonra Z80 öğrendim. Kaynak ise zamanın meşhur elektronik dergilerinden Elo Elektronik'te çıkan Z80 bölümüydü. Spectrum'um ölünceye kadar makine dilinde programlar yazardım. Kasetten assembler editör yükle, kısa rutinler yaz (mesela oyun yükleme sırasında çıkan ekranı ters çevir vs..) denemeler yap vs.. 
Sonrasında C64'e takılıp bu sefer 6510 ile ilgilendim.
2009'da ise Z80'e ve dolayısıyla Spectruma dönüş yaptım.

Başlığı açtım ama içeriği nasıl olacak bilmiyorum. Z80 komutlarından mı başlasam, yoksa ufak rutinler mi yazsam karar veremiyorum.

Hafızada 4K'lık bir bölgeyi temizleyen (sıfırla dolduran) bir rutin yazalım bari.

LD HL,$8000
LD DE,$8001
LD BC,$1000
LD (HL),0
LDIR
RET

$8000-$9000 arasını "0" ile dolduruyoruz.

(Ref, Alco ve diğer Z80 bilenlerin katkılarını bekliyoruz.)



Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: memrah - 16 Ocak 2014, 02:54:24
Hades, darilma ama bir elestiride bulunacagim;

Cocukken, henuz teknik kitaplari anlayabilecek kadar ingilizce bilmezken, Turkiye'de ZX Spectrum icin cikmis bir iki Turkce kaynaktan Z-80 makine dilini anlamaya calisirdim. (Ne yazik ki ELO Elektronik'teki makine dili yazilarindan haberdar degildim o zamanlar) Anlayamamamin yegane sebebi yukarida ornegini verdigin LDIR komutu tarzinda anlatim yapan, yani ornegi veren ama adim adim aciklamayan kaynaklardi :D

Evet 4K'lik bir bolgeyi 0'la doldurdun ama hic Z-80 bilmeyen birisine anlatirken, asagidaki bilgileri de vermek onemli bence.

LDIR komutu, bellekteki herhangi bir alani baska bir alana kopyalamak icin kullanilan dongusel komutlardan birisidir. (Bir digeri icin bkz. LDDR)

Calisma sekli:

LDIR komutu yurutulmeden once 3 yazmac gerekli parametreler ile yuklenir.

HL ciftine, kopyalanmak istenen (kaynak) alanin baslangic adresi,
DE ciftine hedef alanin baslangic adresi,
BC ciftine ise baslangic adresinden itibaren kac byte kopyalanacagi yuklenir.

Ardindan LDIR komutu verilerek kopyalama gerceklestirilir.

Gercekte LDIR komutu bir islemler dongusunu baslatir. Adim adim incelersek, LDIR komutu verildiginde, ilk olarak;

LD (DE),(HL) islemi ile DE'nin isaret ettigi adrese HL'nin isaret ettigi adresteki deger yuklenir.

Ardindan DE ve HL 'nin degerleri 1 arttirilir ve BC 'nin degerinden ise 1 eksiltilir. Dongu kontrol degiskeni olarak BC yazmaci kullanilir ve dongu BC'nin degeri 0 oluncaya kadar tekrar eder. Komutun calisma suresi kopyalanacak byte miktarina bagli olarak degisir.

Hades'in verdigi ornekte, hedef alan, kopyalanacak kaynak alanin sadece 1 byte ilerisinde oldugu icin, kaynak alanin ilk byte'inda tutulan deger (Hades'in orneginde 0) hemen bir ilerisindeki adrese yazilacak.  Ardindan da HL ve DE yazmaclari birer arttirilacagi icin bir bu defa bir onceki adimda hedef alanda olan adres bu kez kaynak alana girecek, ve icerisinde tutulan deger (0) yine kendisinden sonraki adrese kopyalanacak. Bu da BC'deki deger yani $1000 (dec.4096) sifirlanana kadar, yani 4096 kere tekrarlanarak, 4K'lik bir RAM alanini 0'larla dolduracaktir.

Bu tarz bir kullanim ornegin ekran bellegi bolgesini (ZX Spectrum'da 16384 ten baslayan 6912 byte) sifirlamak sureti ile ekrani silmek amaci ile kullanilabilir. Tabi kullanim alani bununla sinirli degildir.

LDIR genel olarak son derece kullanisli bir komuttur.

Yani ne bileyim, eger amac hic bilmeyenler icin bir kaynak olusturmaksa boyle biraz "Z-80 Machine Code for Dummies" tarzinda yazmak lazim sanki.  :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: memrah - 16 Ocak 2014, 03:14:21
Aslinda biraz tersten basladik, daha LD, ADD, SUB vs ogretmeden LDIR dedik ama, madem dongulerden bahsettik, Z-80 makine dilinin en temel ve basit dongu komutu DJNZ'den bahsedip kacayim. Sabaha yetistirmem gereken bir is var ve ben daha yarisini bile bitiremedim.

Z-80 Makine dili'nin esnek komutlarindan biri olan DJNZ, 255 defa'ya kadar tekrarlanmasi istenen islemleri bir donguye sokmak icin kullanilabilir.  Dongu kontrol degiskeni olarak B yazmaci kullanilir. B yazmacindaki sayi 0'dan buyuk oldugu surece, DJNZ komutu isletildiginde, komutun isaret ettigi adrese atlanir.

B yazmacindaki deger her DJNZ komutu calistirildiginda bir eksiltilir ve 0'a ulastiginda, DJNZ komutunun isaret ettigi adrese atlama yapilmaz. Onun yerine DJNZ komutundan bir sonraki komuta atlanir.

Ornegin asagidaki rutin NOP komutunu 128 kere calistirir:

LD B,128
islemyok:
NOP
DJNZ islemyok
RET

DJNZ'nin acilimi eger yanlis hatirlamiyorsam Decrease and Jump if Not Zero idi.

Bir de, DJNZ ile goreceli atlamalar yapilir. Yani atlanacak adres, o anki adresin en fazla 128 byte ilerisi veya 128 byte gerisi olabilir.

Bana musade.. Mikrofon Z-80 bilen diger arkadaslarda....
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 16 Ocak 2014, 07:27:59
En iyisi hem komutlardan bahsetmek hem de kısa rutinler yazmak.  Şu anda cepten yazıyorum akşam evde daha rahat birşeyler yazarım.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 16 Ocak 2014, 09:04:00
Oh burası coşmuş, hatta memrah da gelmiş! Ansiklopedi gibi olur burası şimdi, eğer bu başlık çok büyürse bunu düzenleyip bir bölüm yapacağıma söz veriyorum :)

Alıntı
Yani ne bileyim, eger amac hic bilmeyenler icin bir kaynak olusturmaksa boyle biraz "Z-80 Machine Code for Dummies" tarzinda yazmak lazim sanki.  :)
Kesinlikle katılıyorum, hatta bu konuda bir yöntem önereceğim, 10 yıllık bir eğitmen olarak yeni öğrenenlerin basamaklı yazımları daha iyi kavradığını farkettim. Üssteki düz paragrafı şöyle birşeye çevirince daha anlaşılır olabiliyor. Tabii takdir sizin, bu benim yöntemimdir.


LD (DE),(HL) islemi ile DE'nin isaret ettigi adrese HL'nin isaret ettigi adresteki deger yuklenir.

Ardindan DE ve HL 'nin degerleri 1 arttirilir ve BC 'nin degerinden ise 1 eksiltilir. Dongu kontrol degiskeni olarak BC yazmaci kullanilir ve dongu BC'nin degeri 0 oluncaya kadar tekrar eder. Komutun calisma suresi kopyalanacak byte miktarina bagli olarak degisir.
....

Yukarıdaki tanım LDIR'i harika açıklıyor olsa da, şöyle yazınca daha bir sadeleşiyor sanki:

LDIR:
   1. (hl) deki byte'ı (de)'ye kopyalar
   2.  HL ve DE yi arttırır BC'yi eksiltir
   3.  BC = 0 olana kadar bu işlemleri tekrar eder.

Ne dersiniz?
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 16 Ocak 2014, 16:23:26
* z80'in temel işlemci, adresleme yapısı, registerları, flagleri nelerdir?
* G/Ç birimleri nasıl kontrol edilir?
* Opcode nedir? z80 hangi işlevsel gruplarda hangi opcodeları barındırır?
* z80 programlama için farklı platformlarda alternatif compiler, monitor, emulator/simulator toolları nelerdir?
* Matematiksel işlem temelleri, floating point v.b. konular...
* z80 tabanlı bilgisayarlarda grafik/sprite, ses kullanımı (burada ZX Spectrum, Amstrad CPC gibi cihazlar ayrı ayrı ele alınabilir)

Bu şekilde ilerlenirse ben dahil birçok kişi faydalanabilir. Hello world example'ı olarak memory'de bir bölgeyi sıfırlamak güzel ama o bölgeyi sıfırlayan kodu yazıp başarıyla çalıştıran kişinin hevesinin kursağında kalacağı nokta o bölgenin sıfırlandığını nasıl kontrol edeceğini bilmediği noktadır. :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: memrah - 16 Ocak 2014, 17:38:47
* z80'in temel işlemci, adresleme yapısı, registerları, flagleri nelerdir?
* G/Ç birimleri nasıl kontrol edilir?
* Opcode nedir? z80 hangi işlevsel gruplarda hangi opcodeları barındırır?
* z80 programlama için farklı platformlarda alternatif compiler, monitor, emulator/simulator toolları nelerdir?
* Matematiksel işlem temelleri, floating point v.b. konular...
* z80 tabanlı bilgisayarlarda grafik/sprite, ses kullanımı (burada ZX Spectrum, Amstrad CPC gibi cihazlar ayrı ayrı ele alınabilir)

Bu şekilde ilerlenirse ben dahil birçok kişi faydalanabilir. Hello world example'ı olarak memory'de bir bölgeyi sıfırlamak güzel ama o bölgeyi sıfırlayan kodu yazıp başarıyla çalıştıran kişinin hevesinin kursağında kalacağı nokta o bölgenin sıfırlandığını nasıl kontrol edeceğini bilmediği noktadır. :)

Dogru. Zaten mesajimda da dedigim gibi ise tersten basladik. Eger isi hic bilmeyenlere ogretmeyi amaclayan birsey olusturulacaksa, LDIR, DJNZ vs. bir yana, CPU nedir, register nedir, adres nedir kadar temele inilmeli bence. Keske bunu yapmis olan Turkce kitaplar benim cocuklugumda Turkiye'de mevcut olsaydi.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 16 Ocak 2014, 19:22:28
Skate'nin önerisi gayet mantıklı. (Final sınavı sorusu gibi olmuş :))

Alıntı
z80'in temel işlemci, adresleme yapısı, registerları, flagleri nelerdir?

Z80, 8bitlik bir işlemci olup 8bitlik data hattına, 16 bitlik adres hattına ve çeşitli kontrol sinyallerine sahip bir işlemcidir. 64KByte adresleyebilir. Normal memory adreslemesinin yanında çeşitli IO komutları sayesinde 64K IO bölgesi adresleyebilir.
Registerler :

Program Kontrol Registerleri:
PC : Program Counter. İşlemcinin a onda çalışmakta olduğu hafıza adresini gösterir.
SP : Stack Pointer. Yığın işlemleri için kullanılacak bölgenin başlangıç adresini gösterir. Kullanıcı tarafından değiştirilebilir.

Genel amaçlı kullanılan registerler:
A, B, C, D, E, H, L ve yapılan işlemin sonucuna göre değişen bitlere sahip F (Flag) registeri.

Yukarıdaki 8 bitlik registerlerden B ve C, D ve E, H ve L birlikte kullanılarak BC, DE, HL registerleri 16 bitlik olarak kullanılabilir.

Ayrıca Alternate register denilen AF', BC', DE' ve HL' registerleri vardır. Bu registerlere doğrudan erişim yoktur. EX AF,AF' komutu ile AF register çifti AF' register çiftiyle, EXX komutuyla ise BC, DE, HL register çiftleri BC', DE', HL' register çiftleriyle yer değiştirir. Daha doğrusu bu register çiftlerinde tutulan değerler yer değiştirir. Mesela LD BC,$4000 - LD DE,$5000 ve LD HL,$6000 olsun.
EXX komutuyla $4000, $5000 ve $6000 değerleri Alternate registerlere aktarılır. Alternate registerlerdeki değerler asıl registerlere aktarılır. POP ve PUSH komutlarını kullanmaya gerek kalmadan Alternate registerleri geçici olarak saklama yeri gibi düşünebilirsiniz.

İndex registerleri:
Z80'de iki adet index registeri bulunur ve 16bitlik yapıdadır. IX ve IY olarak adlandırılır. Gerekirse sanki 8 bitlik iki registerden oluşmuş gibi kullanılabilir. Alt 8 bitleri için LX, LY ve üst 8 bitleri için HX, HY olarak adlandırılan  -undocumented opcodes- komutları bulunmaktadır.

I Registeri : Interrupt kontrol registeridir
R Registeri: Dinamik Ramler için kullanılan Refresh registeridir.

Son olarak IFF1 (Interrupt Flip Flop 1) ve IFF2 (Interrupt Flip Flop 2) registerleri bulunmaktadır. Herhangi bir IRQ veya NMI oluştuğunda içerikleri değişmektedir.


FLAG'lar:

Yapılan işleme göre durum değiştiren bitlerdir.

7.bit - S - Sign biti
6.bit - Z - Zero biti
5.bit - Kullanılmıyor.
4.bit - H - Half Carry biti
3.bit - Kullanılmıyor.
2.bit - P - Parity biti
1.bit - N -
0.bit - C - Carry biti

(Ref bit açıklamalarını sen yapıver.)


Alıntı
G/Ç birimleri nasıl kontrol edilir?
Z80 özellik olarak G/Ç komutlarına sahiptir. IN ve OUT komutlarıyla herhangi bir donanımla bilgi alışverişi yapabilir.
Mesela ZX Spectrumun ekran belleği, donanımsal olarak IO adreslemeli bir yapıda olsaydı komutlarımız aşağıdaki şekilde olacaktı.

LD BC,$4000 ; 16384 ekran belleğinin başlangıç adresi.
LD A,$FF ; Akümülatöre $FF (255) sayısını yerleştiriyoruz.
OUT (C),A ; 16384 numaralı ekran belleği adresine aküdeki değeri yazıyoruz.

Normalde ZX Spectrumda ekran belleğine aşağıdaki şekilde yazarız.

LD A,$FF
LD ($4000),A

veya

LD HL,$4000
LD (HL),$FF ;(Skate'in dikkati sonucu düzeltildi.)

Z80'nin G/Ç komutlarına sahip olması donanım tasarımı açısından büyük esneklik sağlar. Nitekim Spectrum'un joystickleri IN komutuyla okunur.

Devam edecek...
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 16 Ocak 2014, 19:34:37
Bak şimdi oldu. :) Eline sağlık Hades.

Ben z80 ile hemen hiçbirşey kodlamamış olsam da epey bir z80 asm öğrendim birkaç sene önce C128 sahibi olduğum zaman. Son derece hakim olduğum bir donanımda z80 kullanmak çok daha keyifli oldu elbette ki. Ama öğrendiğimle kaldım ve aradan geçen zamanla da epey unuttum.

Bir diğer z80 merakı bende Amstrad CPC platformunda üst üste bob rekoru kırıldığı dönemde "ulan şunların ellerine vermek lazım" diye düşündüğüm sıralarda gelip gitmişti, yine bir anlık gaz sonuçsuz kalmıştı. :)

Yakın zamanda ise Batman Forever demosu çıktığında artık "tutmayın ulan beni, tutmayın küçük enişteyi!" diye bağırmaya başlamıştım ancak o sıralar Atari 800XL ve Amiga 1200'le eş zamanlı uğraşıyor olduğum için maymun iştahlılık etmemem lazım demiş ve bırakmıştım uğraşmayı.

Bak bu dört etti. :) Artık bu forum başlığı da beni z80 kodlamaya itmezse bir daha ömür boyu tek satır z80 kodu yazmayacağıma eminim. O yüzden hadi, dökün bakalım bilgileri ortaya. Ben parmaklarımı çatırdatıyorum şu anda. Hazır ve nazır bekliyorum. ;)

Ufak bir düzeltme: Hades kardeşim, en son örnekteki $255, $FF olacak tabii ki. Kodları denemek isteyen olursa kafa karışıklığı olmasın diye belirttim.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 16 Ocak 2014, 21:30:44
Alıntı
Opcode nedir? z80 hangi işlevsel gruplarda hangi opcodeları barındırır?

Opcode : Operation Code. Yani bir işlemcinin yapacağı işlemi belirten koddur. İşlemci o anki opcode'a göre ne işlem yapacağını bilir. Z80'de komutların opcode'ları aşağıdaki şekilde olabilir.
(Opcode'lar hexadecimal formatta verilmiştir)
(nn : $00..$FF arasında bir baytlık değer)
(nnnn : $00 ... $FFFF arasında iki baytlık bir değer)

Tek baytlık ve parametre almayan opcode'lar. (00 : NOP, 76 - HALT, C9 - RET vs..)
Tek baytlık ve bir parametre alan opcode'lar. (06 nn : LD B,nn - DE nn : SBC A,nn vs...)
Tek baytlık ve iki parametre alan opcode'lar. (21 nn nn: LD HL,nnnn - FC nn nn : CALL M,nnnn vs..)

İki baytlık ve parametre almayan opcode'lar. (ED B8 : LDIR - DD E5 : PUSH IX vs..)
İki baytlık ve bir parametre alan opcode'lar. (DD 7E nn : LD A,(IX+nn) - DD AE nn : XOR (IX+nn) vs..)
İki baytlık ve iki parametre alan opcode'lar. (DD 21 nn nn : LD IX,nnnn - FD 22 nn nn : LD (nnnn),IY vs..)

Üç baytlık ve bir parametre alan opcode'lar. (FD CB nn 06 : RLC (IY+nn) - DD CB nn FE : SET 7,(IX+nn) vs..)


Daha basit bir ifadeyle Z80 komutları 1, 2, 3 veya 4 bayt uzunluğunda olabilir.
Teorik olarak 256 komut var gibi gözüksede CB, DD, ED, FD opcode'ları birer önkod olup devamında 1, 2 veya 3 bayt daha olabilir. Ön koda sahip komutlarla beraber toplam komut sayısı 705 dir. Eğer undocumented opcode'ları da sayarsak toplam komut sayısı 1278 olmaktadır. (Yanlış saymış olabilir. Kontrol edebilirsiniz)

(Kaynak http://clrhome.org/table/ (http://clrhome.org/table/))

Devam edecek....
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 17 Ocak 2014, 17:15:21
"6502 Makine diline meraklı olan?" başlığı olurda "Z80 Makine diline meraklı olan?" başlığı olmaz mı?
Aman diyeyim! Bu tür çekişmeli başlıklar çok tehlikeli. Şimdi biri çıkar "CPUlar Üzerine: Bölünerek Azalma" şeklinde bir başlık açar ve ortalık karışır. Lütfen, uzak duralım böyle şeylerden.

Bak bu dört etti. :)
Beş olabilir mi? Senin çocukken eline bir yerlerden Z80 kitabı geçmişti diye hatırlıyorum. Ama ilgili başlığı TRDS'de bulamadım.


Ders materyali vermek lazım biraz:

http://www.z80.info (http://www.z80.info)

http://jemu.winape.net (http://jemu.winape.net)
http://www.oshonsoft.com/z80.html (http://www.oshonsoft.com/z80.html)
http://winape.net (http://winape.net)

Spectrum Basic ve Z80 Makine Kodu(Türkçe) (http://retrojen.org/lib/mag/get.php?i=00&mag=Spectrum-Basic-ve-Z80-Makine-Kodu&hash=p)
Programming The Z80 (Rodnay Zacks) (https://www.google.com.tr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&sqi=2&ved=0CDcQFjAB&url=http%3A%2F%2Fwww.z80.info%2Fzip%2Fzaks_book.pdf&ei=DEjZUrfkCpKrhAfjzYCgDg&usg=AFQjCNGypsUp7i0MQCOuYCo_nGcnLJIpyw&sig2=hE4GjWkW8LpdzkuXP9Nxyw&bvm=bv.59568121,d.bGQ)

Not: Kendi adıma materyal ve link türü eklemeleri sadece buraya yapacağım ki takip etmesi kolay olsun.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 17 Ocak 2014, 18:07:00
Ben de pek vakit bulamıyorum bu ara ama kendi kullandığım araç zincirini dağıtılabilir hale getirerek tek pakete topladım.

download (lütfen kurulum kısmını da okuyun):
9.7MB Zip dosyası ZxToolchain Windows XP/7/8 (https://arda.kisafilm.org/fish/get/serve.php?b=zxtoolchain-retrojen.zip&d=24)


Bu araç zincirinde neler var?
1. Context Text editör ve z80 assembler vurgulayıcı
2. Registry makroları (tek tuşla derleme ve emülatörde test etmek için)
3. Pasmo derleyici
4. Specemu 3.1 zx spectrum emülatör

Ek araçlar:
5. Zx Paintbrush - Zx Grafik editörü
6. SevenUp Animasyonlu Sprite editörü (asm data olarak çıktı verir)
7. Vortex Tracker II - Ay müzik editörü - bolca örnek müzik

Kurulum:
Paketi herhangi bir klasöre ayıklayın (unzip) ve executekeys.reg dosyasını çalıştırarak context makrolarını kayıt defterine giriniz. (eğer registry dosyasını çalıştırmazsanız F9 ve F10 tuşları çalışmaz)

Kullanım:
Çalışmaya başlamak için Context klasörüne girip ConTEXT.exe dosyasını çalıştırın.

Yazdığınız kodu ".asm" olarak kayıt ederseniz F9 ve F10 executekeys çalışır hale gelir.

F9 = Pasmo ile derle (kodunuzu kaydeder ve pasmo ile derler, zx spectrum tap dosyası oluşturur)
F10 = Specemu ile çalıştır. (Pasmo'nun oluşturduğu dosyayı specemu ile açar)

Eğer yazdığınız kodun otomatik olarak çalışmasını istiyorsanız kodunuzun sonuna başlangıç adresini END direktifi ile vermeniz gerek. Örnek (örnek kod "deneme.asm" olarak proje klasöründe bulunmaktadır, ekranı temizler, siyaha boyar):

Kod: [Seç]
org 32768

ld hl, 16384
ld de, 16385
ld bc, 6912
ld (hl),0
ldir

end 32768

ORG direktifi programın derleneceği adresi belirtir, END direktifi sayesinde teyp dosyasına eklenen loader'a otomatik olarak USR 32768 komutu eklenir böylece kodunuz yüklendikten hemen sonra otomatik olarak çalıştırılır.

Sorun varsa:
Eğer bunu yapmanıza karşın specemu teybi yüklemiyorsa Specemu içinde Options > Options > Tape > [tape playback options] kısmındaki 4 seçeneği de işaretleyin.


Bu araç zincirini Compiler/editor/emulator vs. kendiniz hazırlamak isterseniz daha önce bunu çok detaylı şekilde anlatmışım: http://retrojen.org/pano/index.php?topic=189.0 (http://retrojen.org/pano/index.php?topic=189.0)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 17 Ocak 2014, 20:52:34
Z80'i spectrum üzerinde kullanacaklar için kodlama donanım püf noktaları:

Zx spectrum belleği 4 bölümden oluşuyor:

0-16383 arası ilk 16k adresler ROM adresidir, değiştirilemez, her zaman ROM bulunur, page edilemez (+3 hariç).

16384-32767 adresleri arası 16k, "contended" gecikmeli hafızadır. İşlemci bu bölge üzerinde hangi işlemi yaparsa yapsın, görüntüyü oluşturan işlemci (ULA) tarafından bekletilir. İşlemci bu bölgede işlem yaparken %20 civarı yavaş çalışır. Bu yüzden bu bölgeye genelde kod konmaz.

32767-49151 arası 16k sabit hafızadır, genelde kalıcı kod bu bölgeye yerleştirilir.

49152-65535 arası son 16k ise page edilebilen hafızadır. Bu kısımdaki RAM bir out komutu ile sayfa çevrilebilir, böylece 128k hafızaya ulaşılır. Bu sayfalardan 5 numaralısı aynı zamanda ULA tarafından bağımsız olarak adreslenebilir. Böylece ekran için Double Buffer olarak kullanılabilir.

Yani, kodunuzun başlangıç adresi 32768 ve üstünde olmalı.

16384-32767 ($4000-$8000) aralığında yazma/okuma işlemlerini minimalde tutmak gerekiyor.

Ula Karlanma Hatası:
Z80 işlemcisi her bir opcode okuma işlemini yaptığında IR yazmaç çiftini adres bus'ına koyar (R yazmacı belleği tazelemek için kullanılıyor). Eğer I yazmacı 64-127 arasında olursa ULA'nın kafası karışıyor ve işlemci habire belleği okumak istiyor sanıyor. Böyle olunca ekranı oluşturmak için yapması gereken ram okumasını yapamamaya başlar böylece ekranı çizmek için bir önce okuduğu veriyi tekrar kullanır. Böylece ekranda bozulmalar olur. Bu spectrum'un işleyişinde herhangi bir problem oluşturmaz. Bu efekt sıkça oyunlarda kullanılmıştır. Aynı efekt hades'in yazdığı "searching for the roots" demoda da mevcuttur. Bu efekti görebilmek için Snow destekleyen bir emülatöre ya da gerçek makinede test etmeye ihtiyacınız vardır. Specemu'da snow efekti desteklenmektedir.

Yüzer Bus:
Bu tasarım vurdumduymazlığı zx spectrumda raster senkronizasyonu için kullanılabilir. Eğer z80 takılı olmayan bir donanım portundan okuma yapmaya kalkarsa onun yerine ULA'nın ekran çizmek için kullandığı byte değerini okur. Bu değer eğer 255 ise o sırada border çizmeye başlamış demektir. Bu durum cobra, arcanoid, sidewize gibi oyunlarda yırtılmasız çizimler yapmak için kullanılmıştır.

Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: memrah - 17 Ocak 2014, 21:00:58
Ufak tefek kisa denemeler icin ZXSpin'in dahili assembler'ini kullaniyorum ben.  Yeni baslayanlar icin kod parcaciklarini yazip aninda calistirarak sonuc gorebilme acisindan pratik bir cozum olabilir. Ayrica araclar arasinda debugger da var.

Yanliz her nedense bazen assembler'in editor bolumu copy/paste islemlerinde sacmaliyor. Ya bir bug var ya da benim bolca patchlenmis windows'um ile ilgili bir sorun yuzunden oluyor. WOS'ta bu sorundan bahseden kimseye rastlamadim.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 17 Ocak 2014, 22:06:04
WOS'ta bu sorundan bahseden kimseye rastlamadim.

Rastlamazsın çünkü ZX Spin'in assembler'ını yazan Marko iş henüz emekleme aşamasındayken bir bunalıma girerek speccy scene'inden 15 aylığına kayboldu, aynı anda projenin başındaki paul ile bir kavgalaşma durumuna girdiler, assembler tarafı alpha aşamasında kaldı. İçinde zilyon tane bug var. Sonra marko birkaç girişim daha yaptı fakat sonunda baygınlık geldi sanırım. Üzerinde sayaç olan sürümler marko'ya ait. Bir de onları dene istersen. Tabii spectrum development ile uğraşan herkes bir şekilde irc'de bu muhabbete şahit olduğu için zx spin ile bir maceraya girmekten imtina etmiştir. Böylece hiç soru oluşmamış olabilir.

Assembler'ı bir kenara, debugger da aynı problemlerden muzdarip. Yani o assembler ve debugger bayağı problemli ve yarım. Ciddi bir projeye girişmemek gerek onunla. Ufak testler yapılabilir.

Bu arada Marko çok kral adamdır, harbiden bu kadar dost canlısı ve alçak gönüllü bir ingiliz bulmak bir hayli zor. Herhalde bu yüzden stres bindi sonunda adamın üzerine :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: memrah - 17 Ocak 2014, 22:16:03
Assembler'ı bir kenara, debugger da aynı problemlerden muzdarip. Yani o assembler ve debugger bayağı problemli ve yarım. Ciddi bir projeye girişmemek gerek onunla. Ufak testler yapılabilir.

Yok, zaten ben de en fazla 30-40 satirlik denemeler icin kullaniyorum. Ciddi ve uzun projeleri o editor'de yazdigimi dusunmek bile istemiyorum, cunku bir anda abuk sabuk bir bolum yok oluyor, bir bakiyorsun, bilmem kac satir asagida peyah olmus.

Emulator'e entegre assembler fikrinin bana cazip gelmesinin sebebi cok esnek olmasi, emule edilen makineye isredigin gibi bellek ve donanim mudahalesi yapabilmen, Z80 registerlarini, AY registerlarini oldugu gibi gorebilmen, binary datalari rahatlikla isteden adres alanina aktarabilmen, istedigin noktada memory dump/snapshot alabilmen, vs. Yani keske SPIN'deki assembler ve debugger sorunlarindan tamamen arindirilsa. Nefis olurdu.

Senin Specemu+Pasmo ikilisini bir inceleyecegim.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 17 Ocak 2014, 23:18:35
Emulator'e entegre assembler fikrinin bana cazip gelmesinin sebebi cok esnek olmasi, emule edilen makineye isredigin gibi bellek ve donanim mudahalesi yapabilmen, Z80 registerlarini, AY registerlarini oldugu gibi gorebilmen, binary datalari rahatlikla isteden adres alanina aktarabilmen, istedigin noktada memory dump/snapshot alabilmen, vs. Yani keske SPIN'deki assembler ve debugger sorunlarindan tamamen arindirilsa. Nefis olurdu.

Senin Specemu+Pasmo ikilisini bir inceleyecegim.

specemu'nun debugger'ı spin'inkinden 3-5 kat iyidir, özellikle başkasının programını incelerken ihtiyacın olan abuk subuk breakpointler var, mesela rom'dan geri dönüşlerde falan durdurabiliyorsun, ula'nın çizim anı başladığında/bittiğinde durabiliyor ve en önemlisi realtime çizim özelliği var. Yani opcode'ları step step takip ederken ister timinge bağlı çizim yaptırabiliyorsun (böylece 100% doğru oluyor), ister test için çizimin anında görüntüye yansımasını seçebiliyorsun.

Specemu UI, Zx spin'inki kadar başarılı değil fakat zamanla alışıyor insan. Specemu'nun en büyük avantajı ise neredeyse 100% emüle ediyor spectrum'u. Hatta makine ısındığında oluşan timing farklarını, zx spectrum görüntüsünün asortik özelliği olan Ula color ramping'i destekleyen tek emülatör. Buna göre ula inverse bit arası geçişte acaip bir ton farkı yaratıyor.

Yeni başladığımda ben de spin öneriyordum hep, ama sonra baktım ki bu felaketlere yol açabiliyor, vazgeçtim. Mesela hades yazdığı kodun snow yarattığını asla anlamamış, o şekilde teslim etmişti kodu yarışmaya. Sonra pouet'te "abicim ne yaptınız siz?" tarzı öneri dolu mesajlar gelmişti :) Halbuki hepsi zxspin yüzünden :D
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 17 Ocak 2014, 23:30:38
Dostlar,

Bu başlığın gidişatı bence çok karışacak. Evet bilgi dolu olacak ama karman çorman, bodoslama girilmiş bir şekilde. Skate'in verdiğini biraz daha genişletip belli bir outline çıkarmak ve ondan sonra da her başlığı tıpkı Nes Programlama (http://retrojen.org/pano/index.php?topic=541.msg4198;topicseen#msg4198)'daki gibi ayrı bir topic'de ele almak daha mantıklı olmaz mı? Ya da girişelim, sonra Ref ayıklar ve düzenler mi diyoruz :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 18 Ocak 2014, 09:29:42
Ya da girişelim, sonra Ref ayıklar ve düzenler mi diyoruz :)

Girişin!
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 19 Ocak 2014, 17:05:51
Daha önce cgtr'de açmış olduğum "Z80 assembler öğreniyoruz" başlığına yazdığım mesajları buraya kopyalıyorum. Ayrıca bazı düzeltmeler/eklemeler yaptım.


DERS 1

Z80 8 bitlik bir mikroişlemcidir. 8 data hattına ve 16 adres hattına sahiptir. 16 adres hattıyla 65536 bellek hücresi adreslenebilir ve bunlar adresler 0 ... 65535 arasındadır. Bu adres aralığı ZX-spectrumda, 0 ... 16383 arasında ROM, 16384 ... 65535 arasında RAM olarak belirlenmiştir. (Spectrum'un bellek düzeni ayrı bir yazı konusudur.)

Bir "byte" 8 "bit" ten oluşur ve bir "bit" sadece "0" veya "1" değerini alabilir. Buna göre bir byte 00000000 ..... 11111111 arasında 256 değer alabilir. Bu değerler 0 ... 255 arasında yazılabilir.
Her bitin bir sayı değeri vardır. Bitler sağdan sola doğru dizilmiştir ve 0. bit, 1. bit ..... 7. bit olarak tanımlanır.

Bitler : 7 6 5 4 3 2 1 0

0. bit : 1
1. bit : 2
2. bit : 4
3. bit : 8
4. bit : 16
5. bit : 32
6. bit : 64
7. bit : 128

değerine sahiptir. Bu sayıları toplarsak 255 değerini elde ederiz. Z80'de herhangi bir biti "0" veya "1" yapmamızı sağlayan komutlar bulunmaktadır.

Bu kısa bilgilerden sonra yavaş yavaş komutlara giriş yapabiliriz.

Komutları genel olarak birkaç gruba ayırabiliriz. (unuttuklarım olabilir.)

1-Yükleme komutları/yığın komutları - Tamamlandı
2-Sıçrama/geri dönüş komutları - Tamamlandı
3-Aritmetiksel/mantıksal komutlar - Tamamlandı
4-Arttırma/azaltma komutları - Tamamlandı
5-Kaydırma/döndürme komutları - Tamamlandı
6-Karşılaştırma komutları - Tamamlandı
7-Bit düzeyinde işlem yapan komutlar - Tamamlandı

8-Blok işlem yapan komutlar/giriş-çıkış komutları - Hazırlanacak
9-Diğer komutlar - Hazırlanacak.

Komutları görmeye başlamadan önce register kavramını inceleyelim.
Her mikroişlemcide bulunan ve adına register denilen işlem birimleri vardır.
Bu registerler ile yükleme, aritmetik işlemleri vs. yapılır. Z80'de A, B, C, D, E, H, L, Flag, SP, IX, IY registerleri vardır. SP, IX ve IY 16 bitlik register, diğerleri 8 bitlik registerdir. Ayrıca B ve C registerleri bir araya gelerek 16 bitlik BC registeri olarak kullanılabilir. Aynı durum D ve E, H ve L registerleri içindir. Böylece elimizde kullanma durumuna göre 3 adet daha 16 bitlik register hazır olur.
Flag registeri, o an işlenen bir komuta, yapılan işe göre çeşitli durumlar alabilen ve her biti farklı amaçlar için kullanılan bir registerdir. Mesela bir toplama işleminde "elde" var mı, sonuç "0" mı gibi durumları belirten bir registerdir. Bazı işlemlerde bu "durum"ları kontrol etmemiz/değiştirmemiz ve program içinde şartlı işlemler yapmamız gerekebilir.




DERS 2 - YÜKLEME KOMUTLARI :

Yükleme komutları bir registere, bir register çiftine veya bir adrese sabit bir sayı, başka bir registerin içeriği veya herhangi bir adresin içeriğini yüklemek için kullanılır.

Derslerimizde daha anlaşılır olması bakımından aşağıdaki kısaltmaları kullanacağız.

Komutun biçimi LD hedef,kaynak şeklindedir.

d : mesafe,
r : register,
rp : register çifti,
nn : bir baytlık sayı,
nnnnn : iki baytlık sayı,
(nnnn) : adres,
(rp) : Bir register çiftinde bulunan sayının belirttiği adresin içeriği anlamına gelmektedir.

ÖRNEK : LD BC,16384 olsun, LD A,(BC) komutuyla, BC register çiftinde bulunan 16384 numaralı adresin içeriği Aküye yüklenir.

Z80'de oldukça çok adresleme modları vardır ve bunları bilmemiz gerekiyor.


1- LD r,nn --> Bir registere bir baytlık sayı yüklenir.

Örnek : LD A,0 ---> A registerine (Aküye) sabit 0 sayısı yüklenir.
Örnek : LD L,255 -> L registerine 255 sayısı yüklenir.

Bu adresleme modunda A,B,C,D,E,H,L registerlerine bir baytlık sabit sayı yüklenir.
Bu adresleme moduna LD (HL),nn ;LD (IX+d),nn ve LD (IY+d),nn komutlarıda dahildir. Son üç komut ile ilgili registerlerin gösterdiği adrese nn sabit sayısı yüklenir.


2- LD rp,nnnn ---> Bir register çiftine 2 baytlık bir sayı yüklenir.

Örnek : LD BC,32000 ---> BC register çiftine 32000 sayısı yüklenir.
Örnek : LD HL,0 -------> HL register çiftine 0 sayısı yüklenir.

Bu adresleme modunda BC,DE,HL,IX,IY ve SP registerlerine iki baytlık sabit bir sayı yüklenir.
LD BC,nnnn
LD DE,nnnn
LD HL,nnnn
LD IX,nnnn
LD IY,nnnn
LD SP,nnnn


3- LD r,r ---> Bir registere başka bir registerin içeriği yüklenir.

Örnek : LD D,A ----> D registerine A registerinin içeriği yüklenir. D ile A'da aynı değer bulunur. A'nın içeriği kaybolmaz.

Bu adresleme modunda A,B,C,D,E,H,L registerlerinin herhangi birinden herhangi birine yükleme yapılır. Kaynak ve hedef registerler aynı olabilir. Yani LD C,C gibi bir komut olabilir
.
Ayrıca I (İnterrupt) ve R (Refresh) registerleri sadece A registeriyle birlikte kullanılır.
LD I,A
LD R,A
LD A,R
LD A,I


4- LD rp,rp ----> Bu adresleme modunda sadece SP registerine HL, IX veya IY registerlerinden yükleme yapılabilir.

LD SP,HL
LD SP,IX
LD SP,IY


5- LD (rp),r ----> Bu modda ise A,B,C,D,E,H ve L registerlerinden herhangi birinin içeriği (HL), (IX+d), (IY+d) 'ye yüklenir.
Bu registerlerden sadece A registeri (BC), (DE) ve (nn) ile birlikte kullanılabilir.

LD (HL),r
LD (IX+d),r
LD (IY+d),r

Sadece A registeri ile kullanılan komutlar.
LD (BC),A
LD (DE),A
LD (nnnn),A

HATIRLATMA : Parantez içindeki ifadeler, ilgili registerlerin kendisine değil, gösterdikleri adrese yükleme yapılacağını belirtir.
ÖRNEK : LD BC,60000 ile BC registerine 60000 sayısısı yükleyelim. LD A,210 komutu ile aküye 210 sayısını yükleyelim. LD (BC),A komutu ile Aküdeki 210 sayısını 60000 adresine yüklemiş oluruz. Eğer hedef adres sabit ise, register çifti kullanılmadan LD (nnnn),A komutuyla ilgili adrese yükleme yapılır. Örneğimizden devam edersek LD A,210 ; LD (60000),A şeklinde kullanabiliriz.

6- LD r,(rp) ----> Bu modda bir register çiftinin gösterdiği adresin içeriği A,B,C,D,E,H,L registerlerinden birine yüklenir. (rp) ise (BC),(DE),(HL),(IX+d),(IY+d),(nnnn) olabilir. (BC),(DE) ve (nnnn) sadece A registeri ile kullanılabilir.

LD r,(HL)
LD r,(IX+d)
LD r,(IY+d)

Sadece A registeri ile kullanılan komutlar.
LD A,(BC)
LD A,(DE)
LD A,(nnnn)

ÖRNEK : LD HL,22528 ; LD D,(HL) Bu örnekte HL registerinde belirttiğimiz adresin içeriği D registerine yüklenir. Eğer kaynak adres sabit ise LD A,(nnnn) komutu kullanılabilir.

Son iki adresleme modu biraz karışık olup dikkatli kullanmak gerekir.


7- LD rp,(nnnn)----> Bu adresleme modunda kaynak adresteki sayının kendisi değil, sayının belirttiği adresin ve bir fazlasının içeriği yüklenir.
ÖRNEK : 60000 adresinde 100, 60001 adresinde ise 20 olsun. LD HL,(60000) komutunu verdiğimizde HL'ye 60000 değil  256*20+100 sayısı yüklenir. Formül 256*(nnnn+1)+(nnnn)'dır.

Bu modda BC,DE,HL,IX,IY ve SP registerleri kullanılır.
LD BC,(nnnn)
LD DE,(nnnn)
LD HL,(nnnn)
LD IX,(nnnn)
LD IY,(nnnn)
LD SP,(nnnn)


8- LD (nnnn),rp ----> Yukarıdaki adresleme modunun tersidir ve herhangi bir register çiftindeki sayıları (nnnn) ve (nnnn+1) ile belirtilen adreslere kopyalar.
ÖRNEK : LD HL,22528 ; LD (30000),HL  komutlarıyla HL register çiftinde bulunan 22528 sayısın LOW-BYTE'ı 30000 adresine, HIGH-BYTE'ı 30001 adresine yüklenir.

Bu son modda da BC,DE,HL,IX,IY ve SP registerleri kullanılır.
LD (nnnn),BC
LD (nnnn),DE
LD (nnnn),HL
LD (nnnn),IX
LD (nnnn),IY
LD (nnnn),SP

EK BİLGİ : BC,DE,HL register çiftlerinde kullanılan ilk harfler HIGH byte, ikinci harfler LOW byte değerini taşır.


Yükleme komutlarında kullanılan adresleme modları bu kadar.




DERS 3 - SIÇRAMA VE GERİ DÖNÜŞ KOMUTLARI

Kaldığımız yerden devam ediyoruz. Sıçrama komutları iki bölüme ayrılır.
1- Mutlak sıçrama komutları,
2- Göreceli sıçrama komutları.

Hem mutlak sıçrama komutları, hem de göreceli sıçrama komutları kendi aralarında şartsız ve şartlı olarak ikiye ayrılır.

1 - MUTLAK SIÇRAMA KOMUTLARI
Mutlak sıçrama komutlarında hedef adresin kendisi yazılır. Bu komutlar işlev bakımından ikiye ayrılır. Birincisi CALL komutu, ikincisi JP komutudur. CALL komutu şöyle çalışır. Ana program çalışırken CALL komutuna sıra geldiğinde, program CALL komutuyla belirtilen adresteki başka bir programı çalıştırır ve program sonuna mutlaka olması gereken RET komutuyla ana programa geri döner. Ana programda CALL komutundan sonraki komut işletilir.
JP komutuyla ise program ilgili adrese sıçrar ve oradan çalışmaya devam eder.
CALL komutu örnek :

ld a,0
call renk
ld a,1
call renk
ld a,2
call renk
...
...
...

renk out (254),a
xor a
out (254),a
ret
...
...

JP komutu örnek :

ld hl,4000h
ld a,(hl)
jp devam
....
...
...
devam out (254),a
....
...

CALL ve JP komutlarında adres 0 ile 65535 arasında olabilir.
Mutlak sıçrama komutlarında HL,IX ve IY registerleride kullanılabilir. Bu komutlar JP (HL), JP (IX) ve JP (IY) dır.

2 - GÖRECELİ SIÇRAMA KOMUTLARI
Bu sıçrama komutlarında, hedef adresin kendisi değil, adrese olan uzaklık belirtilir. Bu uzaklık parametresi -geçen derste gördüğümüz "d:mesafe" ile gösterilir- 0-127 arasındaysa, şıçrama ileri yöndedir. 128-255 arasında ise geri yöndedir. Dolayısıyla bu komutlarla ancak program içerisinde kısa mesafelere sıçrayabilirsiniz.

Sapılacak adres gerideyse kaç bayt olduğu 256-d formülüyle bulunur. Programlarımızı yazarken etiket kullandığımız için kaç bayt ileri veya geri gittiğimiz program derlenirken hesaplanır. Eğer mesafe sınırlar dışındaysa derleyici hata verecektir.
Göreceli sıçrama komutu JR ile gösterilir ve Jump Relative'nin kısaltmasıdır. Eğer yazdığınız program kısa ve programı sürekli çalıştıracaksanız JR komutunu, uzunsa JP komutunu kullanabilirsiniz.

Örnek :
start ld a,0
loop1 ld b,1
...
...  Aradaki program 128 bayttan uzun olmamalıdır.
...
jr loop1


GERİ DÖNÜŞ KOMUTLARI :
Geri dönüş komutları ana programı bir kez çalıştırıp sonlandırmak için ve CALL ile sıçranılan alt programlardan ana programa dönüş için kullanılan komutlardır. Geri dönüş komutlaı da şartsız ve şartlı olarak ikiye ayrılır.
En çok kullanacağımız şartsız geri dönüş komutudur ve RET ile gösterilir. Return'un kısaltmasıdır.
RET komutuna benzer "RETI" ve "RETN" komutları vardır. "RETI" interrupttan geri dön, "RETN" Maskelenez İnterruptan geri dön demektir.

ŞARTLAR :

Şart dediğimiz durumlar, o an işlenen bir komuta göre "F" registerinin değişen bitlerini kontrol ederek öğrenilir. "F" (Flag) registerinin bitleri aşağıdaki gibi tanımlanmıştır.

7.bit : Sign (işaret) biti,
6.bit : Zero (sıfır) biti,
5.bit : Tanımsız,
4.bit : Half Carry biti,
3.bit : Tanımsız,
2.bit : P/V (Parity/Overflov) Eşlik/Taşma biti,
1.bit : A/N (Add/Subtract) Toplama(0)/Çıkartma(1) biti,
0.bit : C (Cary) Elde biti.

Bazı komutlar bu bitlerden birden fazlasını değiştirebilir.

ŞARTLI MUTLAK SIÇRAMA KOMUTLARI :

CALL Z,adres ; "Zero" biti "1" ise sıçra,
CALL NZ,adres ; "Zero" biti "0" ise sıçra,
CALL C,adres ; "Carry" biti "1" ise sıçra,
CALL NC,adres ; "Carry" biti "0" ise sıçra,
CALL P,adres ; "Sign" biti "1" (pozitif) ise sıçra,
CALL M,adres ; "Sign" biti "0" (negatif) ise sıçra,
CALL PE,adres ; "P/V" biti "1" ise çağır,
CALL PO,adres ; "P/V" biti "0" is çağır.

JP Z,adres
JP NZ,adres
JP C,adres
JP NC,adres
JP P,adres
JP M,adres
JP PE,adres
JP PO,adres

ŞARTLI GÖRECELİ SIÇRAMA KOMUTLARI :

JR Z,mesafe
JR NZ,mesafe
JR C,mesafe
JR NC,mesafe
DJNZ mesafe

DJNZ mesafe komutu özel olarak B registeri içindir. Açılımı "Decrement and Jump if Not Zero" dur. Yani B registerinin değerini bir azalt, registerin değeri "0" olmadıysa sıçra demektir.

ŞARTLI GERİ DÖNÜŞ KOMUTLARI :
Aynı şartlı sıçrama komutlarında olduğu gibi geri dönüşlerde de bazı şartlar kontrol edilebilir ve geri dönüş işlemi yapılabilir.

RET C
RET NC
RET Z
RET NZ
RET M
RET P
RET PE
RET PO

Bu konu oldukça önemlidir ve program içinde döngü yaparken bazı durumları kontrol için gereklidir.




DERS 4 - ARİTMETİKSEL/MANTIKSAL KOMUTLAR :

1-ARİTMETİKSEL KOMUTLAR :

Adındanda anlaşılacağı üzere Z80 registerleriyle işlem yaparken 8 bitlik veya 16 bitlik toplama ve 8 bitlik çıkarma yapabiliriz.
Z80'de gerek toplama gerekse çıkartma işlemlerinde "C" (elde) biti kullanıp kullanmamamızı sağlayan komutlar vardır.
Aritmetik komutlarında çarpma ve bölme komutları yoktur.

8 bitlik toplam ve çıkartma komutları sadece Aküyle kullanılır. Yani sadece Aküyü kullanarak toplama/çıkartma yapabiliriz. Yapılan işlemin sonucu Aküde tutulur. 16 bitlik toplma işlemlerde HL, IX ve IY registerleri kullanılır ve sonuç hedef registerde tutulur. İşlemin sonucunda "Z,C,S,H,V" bitleri etkilenir.

-- TOPLAMA KOMUTLARI --

a) "C" biti (Elde biti) kullanılan toplama komutları:

a-1) 8 bitlik toplama komutları

ADC A,(HL) --> HL registerinde tutulan sayının gösterdiği adresin içeriği ile Akünün içeriği "C" biti kullanılar toplanır. Sonuç Aküde tutulur.

ADC A,(IX+d) ve ADC A,(IY+d) :  Yukarıdaki komut gibidir. Ancak IX ve IY registerlerinde tutulan sayıya "d" ile belirtilen sayı eklenerek bulunan yeni değerin gösterdiği adresin içeriği Aküye yüklenir.

ADC A,r --> Akü ile herhangi bir registerin içeriği "C" biti kullanılarak toplanır ve sonuç Aküde tutulur. "r" yerine A,B,C,D,E,H,L gelebilir.

ADC A,nn --> Akü ile 8 bitlik sabit bir sayı, "C" biti kullanılarak toplanır ve sonuç Aküde tutulur.

a-2)16 bitlik toplama komutları:

"C" biti kullanılan 16 bitlik toplama komutları sadece HL registeriyle kullanılır.

ADC HL,BC --> HL ile BC'nin içeriği "C" biti kullanılarak toplanır ve sonuç HL'de tutulur.
ADC HL,DE --> HL ile DE'nin içeriği "C" biti kullanılarak toplanır ve sonuç HL'de tutulur.
ADC HL,HL --> HL ile HL'nin içeriği "C" biti kullanılarak toplanır ve sonuç HL'de tutulur.
ADC HL,SP --> HL ile SP'nin içeriği "C" biti kullanılarak toplanır ve sonuç HL'de tutulur.

NOT : Bir register kendisiyle toplandığında registerdeki değer 2 ile çarpılmış olur.
NOT : "C" biti toplama sırasında sonucu etkiler. Etkilememesi için "C" bitinin sıfırlanması gerekir. "CCF" komutu "Clear Carry Flag" demektir ve "C" bitini "0" yapar.


b) "C" biti (Elde biti) kullanılmaya toplama komutları :

b-1) 8 bitlik komutlar:

Bu tip komutlarda "C" bitinin durumu dikkate alınmaz. İşlem yapılır ve sonuç Aküde tutulur.

ADD A,(HL)
ADD A,(IX+d)
ADD A,(IY+d)

ADD A,r --> "r" yerine A,B,C,D,E,H,L gelebilir.

ADD A,nn

b-2) 16 bitlik komutlar :

"C" bitinin durumu dikkate alınmaz, sonuç hedef registerde tutulur.
Hatırlatma : Bir komuttan sonra yazılan ilk parametre hedef, ikinci parametre kaynaktır.

ADD HL,BC
ADD HL,DE
ADD HL,HL
ADD HL,SP

ADD IX,BC
ADD IX,DE
ADD IX,IX
ADD IX,SP

ADD IY,BC
ADD IY,DE
ADD IY,IY
ADD IY,SP


-- ÇIKARTMA KOMUTLARI --

a) "C" biti (Elde biti) kullanılan komutlar:

a-1) 8 bitlik çıkartma komutları:

SBC A,(HL)
SBC A,(IX+d)
SBC A,(IY+d)

SBC A,r

SBC A,nn

a-2) 16 bitlik çıkartma komutları:

SBC HL,BC
SBC HL,DE
SBC HL,HL
SBC HL,SP


b) "C" biti (Elde biti) kulllanılmayan komutlar.

Bu kategoride sadece 8 bitlik komutlar mevcuttur.

SUB A,(HL)
SUB A,(IX+d)
SUB A,(IY+d)

SUB A,r

SUB A,nn

NOT : Çıkartma işleminde "C" biti sonucu etkiler. Etkilememesi için "C" bitinin set edilmesi gerekir. "SCF" komutu (Set Carry Flag) demektir ve "C" biti "1" yapar.


2 - MANTIKSAL KOMUTLAR :

Mantıksal komutlarla Aküdeki değer ile başka bir değer arasında bit düzeyinde AND (ve), OR (veya), XOR (özel veya) işlemi yapabiliriz.
Komutları görmeden önce bu işlemlerin nasıl olduğunu görelim.
Komutlar bit düzeyinde işlem yaptığı için hedef ile kaynak arasındaki etkileşim aynı numaralı bitler arasında olur.

a) "AND" işlemi:

AND işleminde bir birine karşılık gelen bitlerin her ikiside "1" ise hedef bit "1" olur. Diğer durumlarda hedef bit "0" değerini alır.

 0 AND 0 = 0
 0 AND 1 = 0
 1 AND 0 = 0
 1 AND 1 = 1

AND komutuyla istediğimiz bitleri "0" yapabiliriz. AND işlemi bit düzeyinde çarpma işlemidir.

AND (HL)
AND (IX+d)
AND (IY+d)

AND r --> "r" yerine A,B,C,D,E,H,L gelebilir. Akü ile kaynak register arasında AND işlemi yapılır.

AND nn --> Akü ile 8 bitlik sabit sayı arasında AND işlemi yapılır.

ÖRNEK :

Aküdeki değeri ikili sistemdem gösterelim ve
%11001011 (203) olsun. Kaynak ise;
%00101101 (45) olsun. AND işleminin sonucu;
---------
%00001001 (9) olur

Akünün herhangi bir bitini "0" yapmak için, 255-bitin sayısal değeri=, AND komutunun parametresi olarak kullanılır. Sonuç Aküde yer alır.
Yukarıdaki örnekten devam edelim ve 3. bitini (normalde "1") "0" yapalım.
3. bitin sayısal değeri 8'dir. (ilk dersimizi hatırlayın). Sayımız 255-8=247 olur ve ikili sistemde %11110111 ile gösterilir.

%11001011 (203)
%11110111 (247)
---------
%11000011 (195)

Gördüğünüz gibi 3. biti "0" yaptık. Eğer birden fazla biti "0" yapmak gerekiyorsa, ilgili bitlerin sayısal değerlerini toplarız ve 255 ten çıkartırız.


b) "OR" işlemi:

OR işleminde bir birine karşılık gelen bitlerin her ikiside "0" ise hedef bit "0" olur. Diğer durumlarda hedef bit "1" değerini alır.

 0 OR 0 = 0
 0 OR 1 = 1
 1 OR 0 = 1
 1 OR 1 = 1

OR komutuyla istediğimiz bitleri "1" yapabiliriz. OR işlemi bit düzeyinde toplama işlemidir.

OR (HL)
OR (IX+d)
OR (IY+d)

OR r --> "r" yerine A,B,C,D,E,H,L gelebilir. Akü ile kaynak register arasında OR işlemi yapılır.

OR nn --> Akü ile 8 bitlik sabit sayı arasında OR işlemi yapılır.

ÖRNEK :

Aküdeki değeri ikili sistemdem gösterelim ve
%11001011 (203) olsun. Kaynak ise;
%00101101 (45) olsun. OR işleminin sonucu;
---------
%11101111 (239) olur

Akünün herhangi bir bitini "1" yapmak için, ilgili bitin sayısal değeri, OR komutunun parametresi olarak kullanılır. Sonuç Aküde yer alır.
Yukarıdaki örnekten devam edelim ve 5. bitini (normalde "0") "1" yapalım.
5. bitin sayısal değeri 32'dir. (ilk dersimizi hatırlayın). Sayımız 32 olur ve ikili sistemde %00100000 ile gösterilir.

%11001011 (203)
%00100000 (32)
---------
%11101011 (235)

Gördüğünüz gibi 5. biti "1" yaptık. Eğer birden fazla biti "1" yapmak gerekiyorsa, ilgili bitlerin sayısal değerlerini toplarız ve OR komutunun parametresi olarak kullanırız.

c) "XOR" işlemi:

XOR işleminde bir birine karşılık gelen bitlerin her ikiside aynı ise hedef bit "0" olur. Diğer durumlarda hedef bit "1" değerini alır.

 0 XOR 0 = 0
 0 XOR 1 = 1
 1 XOR 0 = 1
 1 XOR 1 = 0

XOR komutunu kullanarak herhangi bir bitin "0" ve "1" arasında dönüşümünü sağlayabiliriz.

XOR (HL)
XOR (IX+d)
XOR (IY+d)

XOR r --> "r" yerine A,B,C,D,E,H,L gelebilir. XOR A komutu Aküyü sıfırlar.

XOR nn --> Akü ile 8 bitlik sabit sayı arasında XOR işlemi yapılır.

ÖRNEK :

Aküdeki değeri ikili sistemdem gösterelim ve
%11001011 (203) olsun. Kaynak ise;
%00101101 (45) olsun. XOR işleminin sonucu;
---------
%11100110 (230) olur


Aküdeki değerin 7. bitini "1" iken "0", "0" iken "1" yapalım. Hangi bitin durumunu değiştireceksek Akü ile o bitin sayısal değeri arasında XOR işlemi yaparız.

%11001011 (203) Aküdeki eski değer.
%10000000 (128) 7. bitin değeri.
---------
%01001011 (75) Aküdeki yeni değer.

Gördüğünüz gibi diğer bitlere dokunmadan 7. bitin durumunu değiştirdik. "1" iken "0" oldu. Aynı işlemi tekrar edelim.

%01001011 (75) Aküdeki eski değer.
%10000000 (128) 7. bitin değeri.
---------
%11001011 (203) Aküdeki yeni değer.

Diğer bitlere dokunmadan 7. biti "0" durumundan "1" durumuna getirdik.
XOR komutunu istediğimiz bit(ler) için "0/1" anahtarı gibi kullanabiliriz.

Unuymayalım, XOR komutunda karşılıklı gelen bitlerin durumları aynıysa sonuç "0", farklıysa "1" olur.


NOT : AND, OR ve XOR komutları sadece Aküyle kullanılır. Yapılan işlem sonucunda Aküdeki değer değişir. Ayrıca "Flag" registerindeki bitler etkilenir.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 19 Ocak 2014, 17:26:09
Kısa bir aradan sonra derslere devam ediyoruz. Ancak sıradaki derse geçmeden önce ilk mesaja kısa bir ek yaptım ve bu ek için aşağıdaki bilgileri 2. DERS "yükleme komutları" içinde ele almamız uygun olacaktır.

YIĞIN KOMUTLARI :

Yığın dediğimiz yer, bir mikroişlemcinin çalışması sırasında bazı registerlerin değerlerinin ve alt rutin çağırma komutlarında geri dönüş adresinin saklandığı bir RAM bölgesidir. Bu adresi Z80 de LD SP,Adres ile değiştirmek mümkündür.
Registerler yığına tek olarak değil register çifti olarak kaydedilir.

PUSH rp ile register çifti yığına atılır, POP rp ile yığından geri alınır. rp yerine AF,BC,DE,HL,IX,IY gelebilir.
Programda PUSH ve POP komutlarını kullanırken dikkatli olmak gerekir. Özellikle iç içe olan döngülerde kullanılan PUSH/POP komutları programın yanlış çalışmasına yol açabilir.
Yığın aynı zamanda geri dönüş adresini tuttuğu için alt rutinlerde daha fazla dikkat etmek gerekir.

.....
.....
29997 CALL ALTRUTİN (32000)
30000 LD A,0
.....
.....


-ALT RUTİN-
32000 PUSH BC
.......
.......
RET

Yukarıdaki örnek hatalıdır. Ana programdaki CALL komutunun adresi 29997 olsun ve CALL 32000 ile alt rutine gidilsin. İşlemci CALL komutunu gördüğünde, bir sonraki komutun (örnekte LD A,0) adresini (30000) yığına atar ve alt rutine gider. Alt rutinde ise PUSH BC ile BC'deki değer de yığına atılmıştır ve bu 0 ile 65535 arasında herhangi bir değer olabilir. Alt rutindeki işler yapılıp RET komutu işlendiğinde, işlemci yığından iki byte alıp bunu geri dönüş adresi olarak kullanacak ve ana programa kaldığı yerden devam edecektir. Oysa örneğimizde geri dönüş adresi olarak yığından 30000 değil, BC deki değer okunacaktır. Bu hatanın önüne geçmenin iki yolu vardır. İlki CALL komutundan önce ilgili registerleri yığına atmak ve CALL komutundan sonra bu registerleri yığından geri almaktır. Diğeri ise alt rutinde ilk iş olarak registerleri yığına atmak, RET komutundan hemen önce ilgili registerleri yığından geri almaktır.

......
PUSH ..
PUSH ..
CALL altrutin
POP ..
POP ..
......

veya

......
CALL altrutin
......

altrutin
PUSH ..
PUSH ..
.....
.....
POP ..
POP ..
RET

Kesin kural : Program içinde ne kadar PUSH komutu varsa o kadar POP komutu olmalıdır.

Bir başka konu ise yığına en son atılan değer, yığından ilk olarak alınır. Bu işlemi üst üste koyulan tuğlalar gibi düşünebilirsiniz. Üst üste 5 tuğla koyduğunuzda alt sıralardakini alamazsınız. Altlardakini almak için en üsten itibaren tuğlaları indirmeniz gerekmektedir. Bu nedenle PUSH/POP komutlarında register sıralamanıza dikkat etmelisiniz.

PUSH BC
PUSH HL
....
....
....
POP HL
....
....
POP BC

Gördüğünüz gibi en son HL'yi yığına attık. Yığındaki en son değer HL'nin değeridir. Arada yapılan işlemlerden sonra yığında bulunan değeri geri alıp kullanacaksak bunu POP HL ile yapmalıyız. POP HL yerine POP BC yazarsak, yığından geri alınan değer BC'ye yüklenecektir.




DERS 4 : ARTTIRMA VE AZALTMA KOMUTLARI

Z80'de register ve adresteki değeri arttırmak için arttırma ve azaltma komutları vardır. Azaltma komutu DEC’tir ve decrement’in kısaltmasıdır. Aynı şekilde arttırma komutu INC’tir ve increment’in kısaltmasıdır.

DEC komutu ile herhangi bir registerin veya adresin içeriği 1 azaltılır. Registerin veya adresin içeriği 0 iken azaltma yapılırsa yeni değer 255 veya 65535 olur.
Aynı şekilde INC komutu ile herhangi bir registerin veya adresin içeriği 1 arttırılır. Registerin veya adresin içeriği 255 veya 65535 iken arttırma yapılırsa yeni değer 0 olur.

Azaltma komutları :

DEC A
DEC B
DEC C
DEC D
DEC E
DEC H
DEC L
DEC BC
DEC DE
DEC HL
DEC IX
DEC IY
DEC SP
DEC (HL)
DEC (IX+d)
DEC (IY+d)

Arttırma komutları : Yukarıdaki listedeki DEC’lerin yerine INC getirilecek.

NOT : Bazı komutlarda (IX+d) ve (IY+d) gibi ifadeler bulunmaktadır. Bu yazım şekli IX veya IY registerinde tutulan değere “d” kadar bir sayı ekleneceğini belirtir. “d” değeri (+0...+127) veya (-0...-128) arasında bir sayı olabilir.
IX’de 5040h olsun, INC (IX+10h) ile 5040h+10h=5050h adresinin içeriği 1 arttırılır. Aynı şekilde DEC (IX-40h) ile 5040h-40h=5000h adresinin içeriği 1 azaltılır.





DERS 5 : KAYDIRMA / DÖNDÜRME KOMUTLARI :

Z80 kaydırma ve döndürme komutları bakımından epeyce zengindir. Bu komutları açıklamalı olarak aşağıda alfabetik sıraya göre veriyorum.

DÖNDÜRME KOMUTLARI :

RL r : Sola döndür.
-------------------
Carry biti kullanılarak 9 bitlik bir döndürme işlemi yapılır. İlgili registerdeki / adresteki bütün bitler bir sola kayar. 7. bit Carry’e, Carry’de daha önce bulunan değer 0. bite yüklenir.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

RLA : Aküyü sola döndür.
------------------------
RL r komutunun sadece A registeri için kullanılan bir şeklidir. Görevi aynıdır. Yani RL A yerine RLA kullanabilirsiniz. RL A komutu 2 byte iken RLA 1 byte’tır.

RLC r : Carry’i kullanmadan sola döndür.
----------------------------------------
RL r gibidir. Ancak döndürme işlemi 8 bitliktir. Registerdeki / adresteki bitler bir sola kayar. 7. bit Carry’e ve 0. bite yüklenir. Carry’de daha önce bulunan değer işleme konmaz.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

RLCA : Aküyü carry’i kullanmadan sola döndür.
---------------------------------------------
RLC r komutunun sadece A registeri için kullanılan bir şeklidir. Görevi aynıdır. Yani RLC A yerine RLCA kullanabilirsiniz. RL A komutu 2 byte iken RLA 1 byte’tır.

RLD : Sola basamak döndür. (Rotate Left Digit)
------------------------------------------------
Bu komut ile (HL)’nin (HL registerinin gösterdiği adresin içeriği) üst 4 biti (7..4) Akünün alt 4 bitine (3..0), (HL)’nin alt 4 biti (3..0) (HL)’nin üst 4 bitine (7..4), Aküde daha önce bulunan alt 4 bit (3..0) (HL)’nin alt 4 bitine (3..0) kopyalanır.


RR r : Sağa döndür.
-------------------
Carry biti kullanılarak 9 bitlik bir döndürme işlemi yapılır. İlgili registerdeki / adresteki bütün bitler bir sağa kayar. 0. bit Carry’e, Carry’de daha önce bulunan değer 7. bite yüklenir.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

RRA : Aküyü sağa döndür.
------------------------
RR r komutunun sadece A registeri için kullanılan bir şeklidir. Görevi aynıdır. Yani RR A yerine RRA kullanabilirsiniz. RR A komutu 2 byte iken RRA 1 byte’tır.

RRC r : Carry’i kullanmadan sağa döndür.
----------------------------------------
RR r gibidir. Ancak döndürme işlemi 8 bitliktir. Registerdeki / adresteki bitler bir sağa kayar. 0. bit Carry’e ve 7. bite yüklenir. Carry’de daha önce bulunan değer işleme konmaz.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

RRCA : Aküyü carry’i kullanmadan sağa döndür.
---------------------------------------------
RRC r komutunun sadece A registeri için kullanılan bir şeklidir. Görevi aynıdır. Yani RRC A yerine RRCA kullanabilirsiniz. RR A komutu 2 byte iken RRA 1 byte’tır.

RRD : Sağa basamak döndür. (Rotate Right Digit)
------------------------------------------------
Bu komut ile (HL)’nin (HL registerinin gösterdiği adresin içeriği) alt 4 biti (3..0) Akünün alt 4 bitine (3..0), (HL)’nin üst 4 biti (7..4) (HL)’nin alt 4 bitine (3..0), Aküde daha önce bulunan alt 4 bit (3..0) (HL)’nin üst 4 bitine (7..4) kopyalanır.


KAYDIRMA KOMUTLARI :

SLA r : Sola aritmetik kaydır.
------------------------------
İlgili registerdeki / adresteki bitler bir sola kayar. 7. bit Carry’e yüklenirken, 0. bite 0 yüklenir. Bu komut ile registerdeki/adresteki değer 2 ile çarpılmış olur.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

SRA r : Sağa aritmetik kaydır.
------------------------------
İlgili registerdeki / adresteki bitler bir sağa kayar. 0. bit Carry’e yüklenirken, 7. bit tekrar 7. bite yüklenir. Yani 7. bitin içeriği değişmez.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

SRL : Sola mantıksal kaydır.
----------------------------
İlgili registerdeki / adresteki bitler bir sağa kayar. 0. bit Carry’e yüklenirken, 7. bite 0 yüklenir. Bu komut ile registerdeki/adresteki değer 2’ye bölünmüş olur.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

SLL : Sola mantıksal kaydır.
----------------------------
İlgili registerdeki / adresteki bitler bir sola kayar. 7. bit Carry’e yüklenirken, 0. bite 0 yüklenir. Bu komut ile registerdeki/adresteki değer 2 ile çarpılmış olur.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

SLL komutu standart Z80 komut tablosunda bulunmaz. Undocumented opcodes olarak listelenmiştir.
(Not:SLA-SRA-SLL-SRL komutlarında kafam karıştı. Bir yanlışlık var gibi)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 19 Ocak 2014, 23:34:50
Bu arada, zx spectrum ve ti hesap makineleri için bir online editör/derleyici mevcut. Zx spectrum'a tap (teyp) dosyası olarak derleyebiliyor. Üye olursanız kaynak kodunuzu kaydedebiliyorsunuz.

http://clrhome.org/asm/ (http://clrhome.org/asm/)

ayrıca dilerseniz burada oluşturduğunuz .tap dosyalarınızı online zx spectrum emülatörüne yükleyerek sadece browser üzerinde zx spectrum kodlayabilirsiniz.

http://retrojen.org/project/emulators/zxspectrum/ (http://retrojen.org/project/emulators/zxspectrum/)  (birazdan retrojen etkinlikleri menüsüne eklenecektir)


Bu arada hades destan yazmış, bu iyi bir kaynak olacak gibi. Acaba bir wiki mi kursak?
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Adamın Biri - 20 Ocak 2014, 08:32:58
Hades, Z80 Türkiye dergisi mi geliyor yoksa?
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 20 Ocak 2014, 17:50:48
Hades, süpersin kardeşim. İki gün bakmadım arada döktürmüşsün.

Bu haftaiçi vakit bulup z80 ile (Amstrad CPC platformunda) birşeyler yapmaya başlayacağım. Biliyorum aranızda ZX Spectrum'cu daha fazla. Ama renk paleti başta olmak üzere ( Ref sakin ol kardeşim :) ) hiç birşeyi beni çekmedi bu güne kadar. Amstrad CPC'de ise bob rekorları, demolar v.s. hep ilgimi çekmiştir. Elimde de ZX Spectrum yok bile ama bir CPC 464'üm var (her ne kadar PC ile dosya transfer imkanım henüz olmasa da). Özetle z80 ise C128 ya da Amstrad CPC'dir benim olayım. C128 şimdi biraz geride dursun, önce yeni şeyler keşfedebileceğim bir cihaz olarak CPC'ye dalmak istiyorum. Bakalım ortaya ne çıkacak. Büyük ihtimalle C64'de daha önce kodladığım efektlerden birini CPC'de kodlamayı deneyerek başlarım işe. Hello world olarak efekt ister bu deli gönül. Unreleased bir efektim var, gayet uygun bu iş için. Stay tuned... :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 20 Ocak 2014, 20:02:10
Elimde de ZX Spectrum yok bile ama bir CPC 464'üm var (her ne kadar PC ile dosya transfer imkanım henüz olmasa da). Özetle z80 ise C128 ya da Amstrad CPC'dir benim olayım.
464<=>PC iletişimi çok kolay ve verimli bir yöntem değil. Kaset adaptör kullanabilirsin ya da line-out-in mod yapabilirsin. Bahsettiğim bu mod için bir uygulama videosu da vereyim:

Load Amstrad CPC464 games from PC to real Amstrad: Add a cassette socket input to an Amstrad CPC464 (http://www.youtube.com/watch?v=SoCVMxy4sZU#ws)

Ama benim tavsiyem CPC 6128 almandır. Hem günümüzde çıkan demo ve oyunların 128K isteklerini karşılamış olursun hem de seni yormayacak bir şekilde 3.5" PC disket sürücüsü takabilirsin (http://www.plazma-dergi.org/dergi/07/chunk/ch08.html). Ondan sonra diyelim ki WinApe (http://winape.net) üzerindeki Assembler ve Debugger'dan faydalanarak bir uygulama geliştirir ve bunu hemen emulatörden PC üzerindeki diskete kaydedersin. Sonra da bunu CPC'de küt diye çalıştırırsın.

Benim gözümde; çalışan bir 6128'e 50 lira civarı verilebilir. GG, Sahibinden ve forum ilanlarında çıkıyor arasıra. Hatta 33baba(Murat)'yı da arabilirsin.

Monitörün varmı bilmiyorum ama yoksa sana bir besleme ve bir de RGB2Scart (http://www.cpcmania.com/Docs/scart/scart.htm) lazım. O aşamaya gelince yazarım onları da. Plazma'da ve benim blogda bu konularda bilgi var. Hatta Plazma'daki yazıda temel komutlar falan da olacaktı.

Alıntı
Büyük ihtimalle C64'de daha önce kodladığım efektlerden birini CPC'de kodlamayı deneyerek başlarım işe. Hello world olarak efekt ister bu deli gönül. Unreleased bir efektim var, gayet uygun bu iş için. Stay tuned... :)
CRTC (http://www.cpcwiki.eu/index.php/CRTC) ve Gate Array (http://www.cpcwiki.eu/index.php/Gate_Array) konuları var. Aklında olsun CPC'de CRTC (http://www.cpcwiki.eu/index.php/CRTC) diyince, sizdeki SID mevzusu gibi birkaç çeşit var. Bunlar arasında özellikle demolarda ortaya çıkan minör farklar mevcut. Ama o farklardan dolayı çalışmayan demolar mevcut. Gerçi senin Optimus ile muhabbetin de vardı sanırım. Belki o da bahsetmiştir bu tür olaylardan falan.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 20 Ocak 2014, 20:21:29
Ders 6 - Karşılaştırma Komutları

Karşılatırma komutları Aküdeki değer ile 8 bitlik sabit bir sayı, herhangi bir registerdeki değer ve bir hafıza adresindeki değer karşılaştırılır.
Karşılaştırma sonucuna göre Flag registerindeki S,Z,H,P/V,N,C bitlerinden bazıları değişir.

İlgili komutlar:

CP A
CP B
CP C
CP D
CP E
CP H
CP L

CP nn

CP (HL)
CP (IX+d)
CP (IY+d)



Ders 7 - Bit Komutları

Z80'in Bit düzeyinde işlem yapan komutları vardır. Bu komutlarla bir registerdeki veya bir hafıza adresindeki herhangi bir biti test edebilir, "0" veya "1" yapılabilir.

BIT Komutu:
Bu komut ile ilgili bitin "0" olup olmadığını kontrol edilir. Eğer kontrol edilen bitin değeri "0" ise Flag registerindeki "Z" biti "1" olur. "1" ise "Z" biti "0" olur.

BIT b,A
BIT b,B
BIT b,C
BIT b,D
BIT b,E
BIT b,H
BIT b,L

BIT b,(HL)
BIT b,(IX+d)
BIT b,(IY+d)

"b" 0 ila 7 arasında bir sayı olmalıdır.

Örnek

LD HL,60000
BIT 7,(HL)
JR Z,devam
....
....
devam NOP
...
Önce HL registerine 60000 değerini yüklüyoruz. Sonra 60000 adresinde tutulan sayının 7. bitinin "0" olup olmadığını test ediyoruz. Eğer "0" ise programda devam etiketli bölüme sıçrama yapıyoruz. Değilse sıçrama yapmadan programa devam ediyoruz.


SET Komutu:

SET komutuyla herhangi bir registerin veya hafıza adresin içeriğin seçilen biti "1" yapılır.

SET b,A
SET b,B
SET b,C
SET b,D
SET b,E
SET b,H
SET b,L

SET b,(HL)
SET b,(IX+d)
SET b,(IY+d)

"b" 0 ila 7 arasında bir sayı olmalıdır.


RES Komutu:

RES komutuyla herhangi bir registerin veya hafıza adresin içeriğin seçilen biti "0" yapılır.

RES b,A
RES b,B
RES b,C
RES b,D
RES b,E
RES b,H
RES b,L

RES b,(HL)
RES b,(IX+d)
RES b,(IY+d)

"b" 0 ila 7 arasında bir sayı olmalıdır.

Başlık: Karakter setiyle oynayalım :)
Gönderen: hades - 20 Ocak 2014, 22:55:27
47 byte uzunluğunda bir rutin. Öylesine yazdım. Karakter setini değiştiriyor.

Kod: [Seç]
;------------------------------------------------;
; SPECTRUM FONT - 01
; 20-01-2014
; Vertical mirror char set
;------------------------------------------------;
org $8000 ;Program $8000(32768)den başlıyor


ld ix,$3d00 ;Romdaki karakter seti başlangıç adresi
ld iy,newchar ;Yeni karakter setinin başlangıç adresi
ld hl,temp ;Geçici işlem adresi
ld de,768 ;Karakter setinin byte sayacı
loop01 ld b,8 ;Okunan byte için işlem sayacı
ld a,(ix+0) ;Romdaki setten bir bayt oku
loop00 rl a ;7. biti "elde" bitine yükle
;diğer bitler sola kayıyor
rr (hl) ;"Elde" bitini 7. bite yükle
;diğer bitler sağa kayıyor
djnz loop00 ;İşlem 8 kez yapılıncaya kadar tekrarla
ld a,(hl) ;Geçici işlem adresini oku
ld (iy+0),a ;Okunan değeri yeni set için ram'e yaz.
inc ix ;Rom adresini 1 arttır
inc iy ;Ram adresini 1 arttır
dec de ;Bayt sayacını 1 azalt
ld a,d
or e
jr nz,loop01 ;Sıfır olmadıysa işlemleri tekrarla
ld hl,newchar ;yeni karakter setinin başlangıç
dec h ;adresinin 256 eksiğini
ld (23606),hl ;sistem değişkenine yükle
ret ;bitir

temp defb 0

org $8100
newchar
end $8000
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: ozayturay - 21 Ocak 2014, 01:06:12
Hades, Z80 Türkiye dergisi mi geliyor yoksa?

47 byte uzunluğunda bir rutin. Öylesine yazdım. Karakter setini değiştiriyor.

Kod: [Seç]
;------------------------------------------------;
; SPECTRUM FONT - 01
; 20-01-2014
; Vertical mirror char set
;------------------------------------------------;

Kesin geliyor.  ;D
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 21 Ocak 2014, 07:13:45
Onu bilemem de, bir wiki kurdum, birkaç girdi yaptım, gün içinde tamamlarım, buraya atılan başlıkları orada düzenleyeceğim, ya da direkt oraya atıp buraya linkleri verebiliriz.

Güzel görünüyor kanımca. Retrojen Forum sitesini daha fazla yavaşlatmaması adına *şimdilik* zx.gen.tr alan adı altına kuruldu, ikisi de retrojen'dir.

http://zx.gen.tr/wiki/index.php?title=Ana_Sayfa (http://zx.gen.tr/wiki/index.php?title=Ana_Sayfa)

edit:
şu başlıkta toplanıyorlar:

http://zx.gen.tr/wiki/index.php?title=Kategori:Z80_%C4%B0%C5%9Flemci_Komutlar%C4%B1 (http://zx.gen.tr/wiki/index.php?title=Kategori:Z80_%C4%B0%C5%9Flemci_Komutlar%C4%B1)

(şimdilik sadece Z80 başlığı ve birkaç alt başlık var)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 21 Ocak 2014, 19:27:44
Hades, Z80 Türkiye dergisi mi geliyor yoksa?

47 byte uzunluğunda bir rutin. Öylesine yazdım. Karakter setini değiştiriyor.

Kod: [Seç]
;------------------------------------------------;
; SPECTRUM FONT - 01
; 20-01-2014
; Vertical mirror char set
;------------------------------------------------;

Kesin geliyor.  ;D

Maalesef gelmiyor.

Bu arada yukarıdaki programı 5 byte kısaltıyoruz. İşyerinde aklıma geldi.

1 - ld hl,temp komutu silinecek.
2 - rr (hl) komutu rr c olarak değişecek. (rr ile c arasında boşluk var.)
3 - ld a,(hl) komutu silinecek.
4 - ld (iy+0),a komutu ld (iy+0),c olarak değişecek.
5 - temp defb 0 satırı silinecek.

5 byte deyip geçmeyin :)
Başlık: Karakter setiyle oynamaya devam.
Gönderen: hades - 21 Ocak 2014, 20:06:41
Spectrumun karakter setini başaşağı çeviriyoruz. Güle güle kullanın.

Kod: [Seç]
;------------------------------------------------;
; SPECTRUM FONT - 02
; 21-01-2014
; Horizontal mirror char set
; Program uzunluğu 35 Byte
;------------------------------------------------;
org $8000 ;Program $8000(32768)den başlıyor


ld ix,$3d00 ;Romdaki karakter seti başlangıç adresi
ld hl,newchar+7 ;Yeni karakter setinin başlangıç adresi
ld de,16 ;Yeni ram adresi için eklenecek değer
ld c,96 ;Toplam karakter sayısı
loop01 ld b,8 ;Karakter byte sayacı
loop00 ld a,(ix+0) ;Romdan karakter datasını oku
ld (hl),a ;Ram'e yaz
inc ix ;Rom adresini 1 arttır
dec hl ;Ram adresini 1 azalt
djnz loop00 ;byte sayacını 1 azalt. Sıfır değilse işlemleri tekrarla
add hl,de ;Yeni Ram adresini elde et
dec c ;Karakter sayacını 1 azalt
jr nz,loop01 ;Sıfır değilse işlemleri tekrarla.
ld hl,newchar ;Yeni karakter setinin başlangıç
dec h ;adresinin 256 eksiğini
ld (23606),hl ;sistem değişkenine yükle
ret ;bitir.

org $8100
newchar
end $8000

Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 22 Ocak 2014, 16:11:43
Tüm döküman ve örnekler için teşekkürler Hades. Ayrıca Ref'e de development enviroment ile ilgili paylaşımı için teşekkür ederim.

Ben dün gece çalışmalara başladım. Amstrad CPC için CTRL+F9 ile doğrudan emülatörde sonucunu görebildiğim bir dev env kurdum kendime. İnternette bu konuda çok başarılı bir tutorial var. Bkz:

http://pushnpop.net/articles-76.html (http://pushnpop.net/articles-76.html)

Epey bir yol kat ettim. Başlangıçta 464 ve 6128 arası farklılıkları bilmediğim için epey bir gol yedim. Sonra bunları da öğrendim ve problemlerimi çözdüm. İlk fırsatta (umarım bu akşam) C64'de yapıp henüz yayınlamadığımı bahsettiğim bir efektimi CPC'ye port etmiş olucam. Özellikle hız farkını çok merak ediyorum. Bakalım CPC'de ilk yaptığım versiyon C64'den ne kadar daha hızlı olacak ve z80'in derinlerine indikçe en son ne kadar daha optimize edebilicem.

Bu birinci yöntem. Bununla tamamen speed optimization tricklerini öğrenmeyi planlıyorum. İkinci olarak da 256b ya da altı bir size'da bir efekt yapmayı deneyeceğim. Bu sayede de size optimization tricklerini öğrenmiş olucam. Sonrasında işi daha ileri götürüp götürmeyeceğim şu an için muallakta. Ama hazır başlamış ve bir gecede epey bir şey yapmışken olayı en az bu dediğim aşamalara kadar ilerleteceğim kesin.

Bu arada 256b derken CPC'nin ürettiği executableların headerlarını falan katmıyorum işin içine. Benim bahsettiğim yazdığım kodun size'ını 256b'da tutmak. Yoksa şimdilik scene'de yayınlanacak bir ürünün derdinde değilim.

Hades'e bu başlığı açarak verdiği gaz için tekrar teşekkürler. Ne zamandır Amstrad CPC'ye dalmak istiyordum. :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 22 Ocak 2014, 20:17:55
İlk fırsatta (umarım bu akşam) C64'de yapıp henüz yayınlamadığımı bahsettiğim bir efektimi CPC'ye port etmiş olucam. Özellikle hız farkını çok merak ediyorum. Bakalım CPC'de ilk yaptığım versiyon C64'den ne kadar daha hızlı olacak ve z80'in derinlerine indikçe en son ne kadar daha optimize edebilicem.

İkinci olarak da 256b ya da altı bir size'da bir efekt yapmayı deneyeceğim. Bu sayede de size optimization tricklerini öğrenmiş olucam.

Ne zamandır Amstrad CPC'ye dalmak istiyordum. :)

Sabırsızlıkla bekliyoruz..
Bu arada bir CPC grubu kurulur mu diye sorsam erken mi olur?
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 22 Ocak 2014, 20:30:43
Her şeye uzun uzun cevap yazarım normalde ama bu sefer şununla yetinicem. Evet, erken olur. :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 22 Ocak 2014, 21:34:58
Her şeye uzun uzun cevap yazarım normalde ama bu sefer şununla yetinicem. Evet, erken olur. :)

Forum tartışması başlığında hep söylemek istedim ama bir türlü yeri gelmemişti, bu forumda "wall of text" çok sevilen birşeydir. Kendinizi tutmayınız, yazınız. Okuyanlar, TLDR de yapmayalım, konu ilginizi çekiyorsa okuyalım.

Bu sefer kısa olsun ama bir dahaki sefere gerekçeli cevaplar bekliyoruz Skate :) eheh..
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 23 Ocak 2014, 01:01:07
Geçekçe basit. Örneğin ben Atari 800XL'e epey bir daldım ve şu anda C64'ün 5'te 1'i kadar olsa da Amstrad CPC'nin en az 100 katı kadar hakimim Atari 800XL donanımına. Ama buna rağmen C64'de yaptığım 256b'lık rottoprojo64'ü Atari'ye zar zor 384b olarak port edebildim (ki ikisi de 6502 tabanlı biliyorsunuz). Sonra JAC! bir Atari scener'ı olarak kalktı benim 384b'ı alıp 256b'a sıkıştırdı rottoprojoXL diye. Bana sorsanız "imkansız" derdim ve bunu diyebilmek için de çok mantıklı gerekçelerim vardı. Ama elbette ki o benim C64'e kıyasla bilmediğim 5'te 4'lük kısım JAC!'ın kısa sürede bunu başarmasını sağladı. Gerçi o adam da bence normal değil, her Atari scener'ı da başaramazdı. O herif de süper hayvan bir coder.

JAC!'ın Pouet Profili: http://www.pouet.net/user.php?who=4177 (http://www.pouet.net/user.php?who=4177)
JAC!'ın kodladığı aşmış bir 8-bit development toolu: http://wudsn.com/ (http://wudsn.com/)

Yani bir platforma yeterince hakim olmadığınız zaman her zaman elinize almaya mahkumsunuz. :) Bu saatten sonra "bakın intro kodladım, scroll bile geçiyor!" diye scene grubu kurmayı kendi açımdan son derece anlamsız buluyorum. Kısa sürede Batman Forever'ı devirecek bir demo çıkaramayacağım da kesin. Bu nedenle "şu aşamada erken olur" diyorum. İlerde Amstrad CPC'de o güne kadar yapılmamış orjinallikte ya da teknik kalitede bir efekt yapacak hale gelirsem artık grup mu kurarım, bir gruba mı girerim, Plush'a CPC section mı açarım, kendi adıma mı yayınlarım, o zaman karar veririm. Şu an için scene'de kimsenin benim ekrana nasıl kernel rutinlerini kullanmadan daha hızlı dot bastığımı merak ettiğini sanmıyorum. :) Retrojen bence bu aşamalar için güzel bir paylaşım platformu olabilir. İşe scene'i bulaştırmaya gerek yok. Yoksa sonuç;

http://www.akaydin.com/zamazingo/ (http://www.akaydin.com/zamazingo/)

Tecrübe konuşuyor. :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 23 Ocak 2014, 04:57:38
Sabahlarken öğrendiğim şeyleri sizinle paylaşmak istiyorum.

1) Daha önce linkini verdiğim tutorial'da snapshot dosyası inject edilerek emülatörden yükleme yapıldığı taktirde kernel call yapılamıyor. Bu nedenle uzun süre herşeyin native metodunu bulmam gerekti ve bu beni çok zorladı.

Örnek:
Kod: [Seç]
ld a,2
call $bc0e

diyebileceğim yerde;

Kod: [Seç]
ld bc,$7f00 ; Gate array port'u oluyor kendileri
ld a,$10001110 ; Alt 2 bit grafik modu (yukarıdaki örnekteki ld a,2'dekine denk)
out (c),a ; Port'a gönder

yapmak zorunda kalmıştım. Ama uzun süre bu sıkıntıyı çektikten sonra bir şeyi fark ettim. Bunun tek nedeni diskten yükletmiyor, snapshot'ı çakıyor olmamdı. Sanırım başta bir kez ROM->RAM aktarımı gibi bir şey oluyor, snapshot'dan yükletildiğinde eğer o bölge sıfırlarla doluysa üzerine yazılıyor v.s. Tam olarak sebebini anlamamış olsam da sorun bundan kaynaklı. Debugger'dan bakıldığında snapshot'dan yüklenmiş durumda $b900 sonrası boş gözükürken diskten yüklendiğinde dolu gözüküyor.

2) Tutorial'ın sorunlu olduğu bir yer var. O da disk oluşturmak için cpcfs'in kullanıldığı yer. cpcfs kesinlikle tutorialdaki parametrelerle çalışmıyor. Başka versiyonu bulurum demiştim ancak çoktan discontinued olmuş o proje. Biri kalkmış cpcxfs diye bir versiyonunu yapmış. Ama o da binary'i istediğim şekilde disk'e yerleştirmemi sağlayamadı. En son alternatif olarak iDSK diye bir tool buldum. Süper bir tool ve işimi çözdü.

https://code.google.com/p/cpcsdk/downloads/detail?name=iDSK_015.7z&can=2&q=

Tutorial'a ait dosyalarda CreateDSK.bat'ın içindeki;

Kod: [Seç]
cpcfs Generated\%1% f
cpcfs Generated\%1% p -e -b Generated\Main.bin,0x100,0x100
satırlarını iDSK'i ve yanında gelen dll dosyasını cpcfs.exe'nin bulunduğu klasöre kopyaladıktan sonra;

Kod: [Seç]
iDSK Generated\%1% -n
iDSK Generated\%1% -i Generated\Main.bin -f -e 100 -c 100 -t 1
şeklinde değiştirmeniz yeterli olacaktır.

Artık snapshot değil doğrudan disk imajından auto run ediyor ve kernel calllarını yapabiliyorum.

Bu gece efekti kodlamaktan çok bunlarla uğraştım. Ama hem kernel disabled olduğu durumda yapmam gerekenleri öğrenmiş oldum, hem de platforma ve development tool chainine daha da aşina olmuş bulundum.

Önümüzdeki gecelerde efekt ortaya çıkacaktır, artık pek engel kalmadı. :)

Not: Yukarıda yanlış anlamış olabileceğim yerleri bilen biri düzeltir ve açıklarsa sevinirim. Örneğin snapshot dosyasından yüklendiğinde kernel call yapılamaması durumunu doğru anlamış mıyım, emin değilim.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 23 Ocak 2014, 12:14:17
2) Tutorial'ın sorunlu olduğu bir yer var. O da disk oluşturmak için cpcfs'in kullanıldığı yer. cpcfs kesinlikle tutorialdaki parametrelerle çalışmıyor. Başka versiyonu bulurum demiştim ancak çoktan discontinued olmuş o proje. Biri kalkmış cpcxfs diye bir versiyonunu yapmış. Ama o da binary'i istediğim şekilde disk'e yerleştirmemi sağlayamadı. En son alternatif olarak iDSK diye bir tool buldum. Süper bir tool ve işimi çözdü.

https://code.google.com/p/cpcsdk/downloads/detail?name=iDSK_015.7z&can=2&q= (https://code.google.com/p/cpcsdk/downloads/detail?name=iDSK_015.7z&can=2&q=)
ManageDSK (http://cpcrulez.fr/emulateurs_UTIL-DSK-manageDSK.htm)'yı denedin mi? Pek ihtiyaç duymasam da gerekince bunu kullanıyorum.

Bir de DSKları yazmak-okumak-yönetmek-oluşturmak için elinin altında mutlaka kurulu olması gereken CPCDiskXP (http://www.cpcmania.com/cpcdiskxp/cpcdiskxp.htm) var. DSK editor kısmından NEW diyip sonra da ADD Files ile istediğin dosyaları eklersin. Kısacası bununla DSK üzerinde her tür numarayı çekebilirsin.

Eğer bunları deneyip de beğenmediysen sebeplerini öğrenmek isterim.



Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 23 Ocak 2014, 12:37:06
@Alcofribas: Şu anda Mac üzerinde olduğum için direk test edemedim ancak bu tür toolları hep GUI'li bildiğim kadarıyla. Command line parametreleri ile çalışıyorlar mı bilemiyorum. Ancak iDSK tam istediğim gibi command line'dan herşeyi yapabiliyor, zaten console tool'u. Söz konusu olan compile dediğim anda tüm tool chaininin otomatik çalışıp emülatör'de DSK'nın yükletilip çalıştırılması olduğu zaman GUI'li toollar işimi görmüyor. Başka zamanlarda kullanışlı olduklarına eminim tabii ki.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 23 Ocak 2014, 13:03:20
@Alcofribas: Şu anda Mac üzerinde olduğum için direk test edemedim ancak bu tür toolları hep GUI'li bildiğim kadarıyla. Command line parametreleri ile çalışıyorlar mı bilemiyorum.
Her ikisi de CL destekliyor. Ekte info-readme dosyaları var. Ama seni iDSK kadar mutlu eder mi bilemem. Daha sonra başka tecrübelerin olursa onları da duymak isteriz.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 23 Ocak 2014, 13:20:28
ManageDsk eğer dökümantasyonu eksik değilse binary dosya eklerken start ve execute adres belirtmemize izin vermiyor. Belki başka bir çözümü vardır ama dediğim gibi iDSK çok temiz, parametreler derli toplu. Örnek vereyim cpcfs'de parametreler şu şekilde.

Kod: [Seç]
cpcfs Generated\%1% p -e -b Generated\Main.bin,0x100,0x100

şimdi burada hangi parametre start address, hangisi execute address bunu göremiyorsun bile. Ezberlemek lazım. Virgülden sonra ilki şu, ikincisi şu falan filan.

Kod: [Seç]
ManageDsk -C -A*.BIN -Stoto.dsk
boşluksuz ve case sensitive parametre kullanımı ( hiç haz etmem :) ), start, execute adresler için bir parametre bulunmaması (en azından dökümantasyonunda eksik) v.s.

Kod: [Seç]
iDSK Generated\%1% -i Generated\Main.bin -f -e 100 -c 100 -t 1

herşey parametrelere bölünmüş, case sensitive değil, cillop gibi. :)

Bu bağlamda hoşuma gitti. GUI'si olmaması da daha lightweight bir tool olmasını ve "bu ancak arayüzden yapılabiliyor, command line'da karşılığı yok" gibi ihtimalleri ortadan kaldırıyor.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: matahari - 23 Ocak 2014, 13:26:03
Merhabalar,

"Z80 Makine diline meraklı olan?" başlığını görünce hiç üzerime alınmadım. Ne de olsa benimki meraktan da öte :P

Her ne kadar yeni projemle ilgili olarak haftanın 7 günü yoğun-ötesi çalışsam da, dayanamayıp bu reply'ı yazmak zorunda hissettim kendimi. Z80 bağımlısı olmak böyle birşey  ;)

Haddim olmayarak, bu başlık altında paylaşılan bulguların/bilgilerin çok dağınık olduğunu belirtirsem, umarım bana kırılmazsınız. hades'in Z80 komut seti listesi ve Spectrum karakter seti ile ilgili örnekleri, Skate'in Amstrad için kod geliştirme ortamına aşina olma çabası, Ref'in Spectrum için kullandığı araç zincirini dağıtılabilir hale getirdiği paket, ve üstüne tuz biber olarak Alcofribas'ın Amstrad kasetçalar mod videosu... Emeği geçen herkese teşekkürler. Herşey iyi niyetle kaleme alınmış ve fakat birbirine karışmış durumda. Takip etmekte zorlandığımı itiraf etmeliyim.

@Skate:

Öncelikle, seni çabalarından dolayı gönülden kutluyorum. İlk Amstrad intronu/demonu heyecanla beklediğimi belirtmek isterim.

http://pushnpop.net/articles-76.html (http://pushnpop.net/articles-76.html) adresindeki Amstrad kod geliştirim ortamını/yöntemini kullanıp kullanmamak, tamamen yiğidin yoğurt yeme tarzı ile ilintili. "Senin gibi tecrübeli bir yazılımcının bir bildiği vardır" diyerek burnumu sokmayacağım. Çok daha basit yöntemler varken, neden kod yazma > derleme > disk oluşturma > iDSK > autorun > WinAPE benzeri bir zincirleme reaksiyon kurduğunu merak ettim. Bu yöntemin diğerlerine göre bir avantajı mı var? Paylaşırsan sevinirim.

@all_forum_members:

Bu başlığı takip eden ve Amstrad üzerinde kod yazmak isteyenlere fikir vermesi açısından, izninizle kendi kod geliştirme ortamımı/yöntemimi paylaşayım. İşinize yarayabilir...

- Amstrad için PC üzerinde kod yazıyorsam, sadece WinAPE kullanıyorum! WinAPE'in içindeki editörde (F3) kodumu yazıp, assemble edip, gereken satırlara breakpoint koyup kodu çalıştırıyorum. Eğer hafızada debug/disassemble etmem gereken bir yer varsa, pause (F7) ile dondurup tüm registerları/belleği inceleyebiliyorum. - Bu süreçte, WinAPE dışında başka hiçbir programa ihtiyacım olmuyor. Less is more ;)

- Amstrad için Amstrad üzerinde kod yazıyorsam, 30 yıl öncesine geri dönesim gelmiş demektir. Bu durumda açıyorum 6128'i, yüklüyorum HiSoft Devpac assembler'ı, başlıyorum eski usül kod yazmaya. Eğer kod çalışırken debug etmem ve/veya breakpoint eklemem gereken bir yer varsa, onu 6128'in arkasına takılı olan Multiface II ile hallediyorum. - (NOT: Bu nostaljik yöntemi, efektif olmaması açısından tavsiye etmiyorum. Ancak bazı durumlarda kaçınılmaz oluyor. Örneğin, şu anda mevcut olan hiçbir Amstrad emülatörü cycle-precise değil. Kaset yükletme, port okuma, vs. türü hassas işlemler için zorunlu olarak bu yöntemi kullanıyorum.)

@Skate:

Gate Array için "firmware vs low-level port programming" konusu ile ilgili olarak, Retrojen Sayı 0 ve Sayı 1'de kaleme aldığım çalışmalara bir gözatmanı tavsiye ederim. Örneğin; Sayı 1, sayfa 9, sütun 2, "Mercek Altında" başlığında RMR register'ına firmware'i aşarak nasıl eriştiğimizi görebilirsin. Hem sabahlamana gerek kalmaz, hem de üstte verdiğin kod örneğindeki RMR register'ına %10001110 yüklemen durumunda sadece ekran mode'unu değiştirmekle kalmadığını, aynı zamanda Upper & Lower ROM'u da devre dışı bıraktığını ve interrupt counter'ı resetlediğini de görebilirsin! Firmware ile ilgili yaşadığın sorunlardan bu şekilde kurtulayım derken, farkında olarak/olmayarak RMR register'ında neleri set ettiğine dikkat etmende fayda var.

Madem Amstrad üzerinde 256 byte işine soyundun, o zaman ilk optimizasyonu hemen yapalım ;)

Kod: [Seç]
ld bc,$7f00
ld a,$10001110
out (c),a

yerine

Kod: [Seç]
ld bc,$7f00 + %10001110
out (c),c

yazarak 2 byte kazanabilirsin.

ÖNEMLİ NOT: Kodundaki $ (address pointer) işaretini % (binary) ile değiştirdim. İkisi farklı şey. Sanırım C64 ve/veya Amiga'dan kalma bir alışkanlık. Trace etmesi zor bir bug'a sebep olabilir.

Umarım faydalı olabilmişimdir.
Parity bit'iniz açık olsun...
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 23 Ocak 2014, 14:07:35
Matahari, seni bizi gözetlediğin daldan indirebilmiş olmak ne harika :) Bahsettiğin bir konu beni de ilgilendirdiği için cevap vermek istedim, aslında kendi cevabını kendin vermişsin, tabii bu durum CPC'ye tam oturmuyor.

Çok daha basit yöntemler varken, neden kod yazma > derleme > disk oluşturma > iDSK > autorun > WinAPE benzeri bir zincirleme reaksiyon kurduğunu merak ettim. Bu yöntemin diğerlerine göre bir avantajı mı var?

...

Ancak bazı durumlarda kaçınılmaz oluyor. Örneğin, şu anda mevcut olan hiçbir Amstrad emülatörü cycle-precise değil.

Normalde winape'in kod düzenleyicisinin bir benzeri ZX Spin'de bulunuyor. Senin dediğin herşey orda mümkün fakat cycle-exact değil. Diğer taraftan spectrum camiası bu konuda çok şanslı, elimizde birden fazla cycle-exact emülatör mevcut, bunların en kabul göreni de specemu. Bu sebepten emülatör üzerinde geliştirme yapmak yerine specemu'ya işi bağlamak gerekiyor.

Acaba amstrad üzerindeki geliştirme maceranı da pc<->amstrad bağlantısı yaparak değiştiremez misin? Skate'in zincirinin son halkasına diske göndermek yerine, seri porttan veri gönderen program eklesen mesela?

edit:

Alıntı
Herşey iyi niyetle kaleme alınmış ve fakat birbirine karışmış durumda. Takip etmekte zorlandığımı itiraf etmeliyim.

Kesinlikle katılıyorum, forum ortamı bu tür işler için uygun değil, wiki'yi kurdum, içini bu başlıktaki bilgileri toparlayacak şekilde dolduruyorum (elbette siz vaktiniz olduğunca yardım ederseniz daha bir anlamlı olur):

http://retrojen.org/wiki (http://retrojen.org/wiki)

Burada sadece deneyimler paylaşılmalı, dersler/tutorialler wikiye atılabilir.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 23 Ocak 2014, 14:23:25
@Matahari: Kardeşim öncelikle ascii karakterlerine sağlık. :) Emin ol development platformumu oturttuktan sonra en çok başını ağrıtacağım kişilerden birisin. Hatta bu mesajı yazdığına pişman bile olabilirsin. C64 programming öğrendiğim yıllarda Mert Hekimci (Digahole / Onslaught) bana yardımcı olmak istemiş, sonra çok pişman olmuştu. Ben adamı yakaldım mı bırakmam, sorularla bunaltırım. :D

Bu başlığın dağınık olduğu en başından birden fazla kişi tarafından belirtildi zaten, biri de bendim. Ancak ben bencilce bir hareketle start-up için yeterli gazı alıp sonra kendi yolumu çizdim. Çünkü zaten chip z80 olsa da örnekler ve development tool chain'i ZX Spectrum üzerineydi ve benim ilgim Amstrad CPC'yeydi.

WinAPE üzerinde doğrudan kod yazma mevzusuna gelince, bu senin de dediğin gibi benim genel development tercihlerimi karşılamıyor. C64'de de 10 seneyi aşkın bir süredir tamamen cross development kullanıyorum, buna emülatör üzerinde development yapmamak da dahil. Yani benim favori text editörümü açıp, tek bir compile tuş kombinasyonu ile sonucu görmem, label, macro v.s. kullanabilmem, compile aşamalarının arasına scripting dilleri falan sokabilmem lazım. Hatta Glance ile geliştirdiğimiz projelerde bildiğin makefile kullanıyorduk. Emülatör üzerinde kod yazmak bu nedenle benim açımdan pek ideal değil. Uyuşturucu bağımlılığı gibi birşey bu, bir kere alıştın mı bırakamıyorsun bu konforu. :)

Verdiğim linkteki tool chain'in özelliklerini inceledin mi bilmiyorum. Source code içersinden breakpoint koyabilmek gibi özellikler de içeriyor. Yani ben kodu derlemeden önce BRK_hello tarzı birşey yazıyorum kodun istediğim yerine, compile ettiğimde WinAPE o noktada breakpoint konulmuş şekilde beklemeye başlıyor. Yani emülatörü doğrudan kullanmıyor olmanın bu tür konularda bana kaybettirdiği bir şey de yok.

Bu arada incelemeden soruyorum, WinAPE'in içinde gelen tool label, macro kullanımına izin veriyor mu? Araya scripting dilleri sokabiliyor muyuz? Yoksa doğrudan hafıza adreslerine mi yazıyoruz? Bu yukarıda yazdıklarımı Vice ve diğer bildiğim birçok emülatörde de olduğu gibi doğrudan hafızaya yazdığımızı ön görerek belirttim.

Amstrad CPC üzerinde, yani emülatörün kendisinde olmayan, cihaz üzerinde emülasyonla çalışan label, macro destekli bir Assembler'ı da iki açıdan tercih etmem.

1) Emülatör içindeki klavye key map'ine alışmam gerekmesi.
2) Assembler'ın da hafızada yer kaplaması. Kartuş bile olsa source codeları RAM'e yazması gerekecektir diye tahmin ediyorum.

Ben hayatımda Amstrad CPC kullanmamış bir adamım. CPC'cilerin ezbere bildiği karakter map ve klavye düzenini bilmiyorum.

Sabahlama mevzusuna gelince, hiç kullanmadığın bir chip sete sahip hiç kullanmadığın bir donanım için cross development platformunu kendi ihtiyaçların doğrultusunda kurmak istiyorsan ve bu seni sabahlatmıyorsa çok doğru bir tutorial bulmuşsun demektir. :) Benim bulduğum tutorial kusursuz olsa zaten sabahlamazdım. Disk toolunda bahsettiğim problem gibi alternatiflerini araştırmam gereken şeyler çıktı karşıma. Zaten snapshot'ı inject ettiğimde kernel call yapamıyor olmam ile ilgili birşey bulmam da çok kolay olmadı tahmin edersin. Çünkü;

1) Sebebin snapshot kullanımı olduğunu anlamak da zamanımı aldı. C64'de snapshot kullansan da kernel call yapabilirsin. Bunun nedenini hala tam anlamış değilim. ROM -> RAM aktarımı falan demem bu yüzden. Yani ancak kernel rutinleri ROM'dan RAM'a aktarılıyor, sonra snapshot bunları overwrite ediyorsa bu bana mantıklı geldi. Onun dışında sebebini anlayamadım. Biz C64'de kernel rutinlerini doğrudan ROM'dan çağırırız. Burada ya olay farklı işliyor ya da hala bana kimsenin açıklamadığı başka bir nedeni var ki bu konuda senden yardım bekliyorum Matahari kardeşim. :)
2) Snapshot sorununu algıladıktan sonra da Amstrad CPC için otomatik DSK oluşturup, binary'i start ve execute adresleriyle içine push edebileceğim bir tool araştırmam gerekti. Abi platformu daha önce hiç kullanmamışım. DSK yapısını bile bilmiyorum. Toolların bir kısmı discontinued. Elbette ki zaman alıyor araştırma yapmak.

Alıntı
%10001110 yüklemen durumunda sadece ekran mode'unu değiştirmekle kalmadığını, aynı zamanda Upper & Lower ROM'u da devre dışı bıraktığını ve interrupt counter'ı resetlediğini de görebilirsin!

Elbette ki bilmediğim birçok şey vardır ancak gate array portu konusunda dökümanları baştan sona okudum. Hatta snapshot olayının yarattığı sorunu uzun süre 2. ve 3. bitleri değiştirerek çözmeyi düşündüm, belki sorun ROM'ların disabled olmasından kaynaklanıyordur diye. Ama sorunun o olmadığını sonra fark ettim. Ben öğrenme aşamasında tutorial yazacak kadar ileri gitmem. :) Bu nedenle de az önce dökümanda okuduğum tüm bitlerin anlamlarını belirtmedim source code commentinde. Demek istediğim üstekini alttaki gibi çözdümü vurgulamaktı.

Senin Retrojen'deki yazılarını elbette ki biliyorum, elimde hard copy olarak duruyor her iki sayı da. :) Elbette ki hepsinden yararlanıcam zaman içinde. Ancak daha tool chainimi oturtma, opcodeları inceleme aşamasındayken ve bu işe iki akşamımı ayırmışken senin yazıların dahil okumam gereken yüzlerde dökümanı okumamış olduğumu tahmin edebiliyorsundur. Retrojen'in forumunda bunları tartışıp Retrojen'de yayınlanmış makaleleri okumamak çok ironik olurdu zaten. :) Dediğim gibi Matahari kardeşim, olayı değerlendirirken sadece Amstrad CPC'ye değil z80'e de yabancı olduğumu aklında bulundurmanı isterim. Ben büyük bir keyifle keşfediyorum, takılıyorum. Öyle ciddi bir derdim de yok. Olsa zaten herşeyden önce seninle kontağa geçerdim "abi, şu bob rekorunu kırmamız lazım, akşama müsait misin?" şeklinde. ;)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: matahari - 23 Ocak 2014, 14:36:07
Acaba amstrad üzerindeki geliştirme maceranı da pc<->amstrad bağlantısı yaparak değiştiremez misin? Skate'in zincirinin son halkasına diske göndermek yerine, seri porttan veri gönderen program eklesen mesela?
@Ref:
(CC: @Skate)

Elbette, herşey mümkün.

Yıllar içinde edindiğim tecrübe, bana Occam'ın Usturası prensibinden (http://tr.wikipedia.org/wiki/Ockham'%C4%B1n_Usturas%C4%B1 (http://tr.wikipedia.org/wiki/Ockham'%C4%B1n_Usturas%C4%B1)) şaşmamam gerektiğini öğretti. İster retro ortam olsun, isterse son model bir konsol... Kod geliştirme ortamımı mümkün olduğunca yalın tutmaya çalışarak, oluşması muhtemel sorunların sayısını azaltmış oluyorum. Aynı sonucu elde edebildiğim sürece, tercihimi basit ve yalın olandan yana kullanıyorum.

Amstrad için kod yazarken WinAPE'i tercih etmemin sebebi de bu. Evet, cycle-precise değil, ama işin %99'unu yapmak için yeter de artar. (Geri kalan %1'lik bölüm için zaten gerçek Amstrad üzerinde testlerimi yapıyorum.) Bu da hem işimi hızlandırıyor, hem de muhtemel bug'lardan beni uzak tutuyor.

İlk mesajımda belirttiğim üzere, her yiğidin yoğurt yemesi farklı  ;)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: matahari - 23 Ocak 2014, 14:43:19
@Matahari: Kardeşim öncelikle ascii karakterlerine sağlık. :) Emin ol development platformumu oturttuktan sonra en çok başını ağrıtacağım kişilerden birisin. Hatta bu mesajı yazdığına pişman bile olabilirsin. C64 programming öğrendiğim yıllarda Mert Hekimci (Digahole / Onslaught) bana yardımcı olmak istemiş, sonra çok pişman olmuştu. Ben adamı yakaldım mı bırakmam, sorularla bunaltırım. :D

@Skate:

Keşke vaktim olsa da, daha çok katkıda bulunabilsem. Maalesef, çok yoğun çalışıyorum. Bugün büyük bir istisna sonucu kendime vakit ayırabildim. Eğer sorularınızı uzun süre yanıtlayamazsam ve/veya aylarca ortalıktan kaybolursam, lütfen bunu iyiye/hayıra yorunuz. Biliniz ki kod yazıyorum ;)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 23 Ocak 2014, 14:50:12
Matahari geceyarısı yorgun argın işten eve gelir. Tam anahtarı kapıya sokacakken kapıyı Skate açar ve sırıtır. :D
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 23 Ocak 2014, 15:28:13
Şubat'ın biri mi olur bilemiyorum ama bundan sonraki ilk toplantımızın başlığını veriyorum: Z80 Gönül Dostları Sofrası

Ayrıca; her türlü Z80 sorularınız ehven fiyatlarla, muhabbet arasında veya mesajlaşmada matahari'ye sorulur. Fiyatlandırma soru içeriklerine göre yapılacaktır. Toplu sorumlarda cazip fiyat ve ödeme seçenekleri sunulur. Ödemeler soru teslimi ile alınır. Yanıtlar tartışmaya açık değildir. İster al kullan, ister duvarına süs diye as. Arızalı-sağlam hesabı :)

Not: Lütfen takas teklif etmeyiniz. Bir tane 6502 yanıtı vereyim yerine şunu alayım türü mesajlara yanıt verilmeyecektir.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 23 Ocak 2014, 15:38:24
Abi, fiyatı siz belirleyin, açık çek. Bana artık biri şu snapshot kullanıldığında kernel call yapamamamı açıklasın ya. :) Cihazın çalışma presiplerini anlamama yardımcı olacak çünkü. O yanıtı kendim bulabilmem için hardware guide'ını hatmetmem lazım. Bir shortcut rica ediyorum yalnızca bu mevzu için.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: matahari - 23 Ocak 2014, 16:22:44
Cihazın çalışma presiplerini anlamama yardımcı olacak çünkü. O yanıtı kendim bulabilmem için hardware guide'ını hatmetmem lazım.

Bunu şimdiden yapmanda fayda var. Sorularının yanıtlarını kolayca bulacaksın.

Bir shortcut rica ediyorum yalnızca bu mevzu için.

Şöyle özetleyeyim;

Interrupt'lar açıkken ve/veya Upper & Lower ROM devredeyken (bir diğer deyişle firmware hayattayken), hafızanın bazı bölümlerine yazman aletin crash olmasına sebep olur. Bu yüzden, snapshot'ını yüklemeye çalıştığın kodun, RMR register'ına ve interrupt'lara ne yaptığı çok önemli.

Eğer firmware hayattayken snapshot alınacaksa ve/veya hafızaya kod inject edilecekse, bu durumda firmware'in &A400-&BFFF arasında kullandığı tampon bölgenin (keyboard routine'leri, disk routine'leri, firmware callback referansları, vs. bu bölgede duruyor!) ve BASIC buffer'ının tutulduğu &0000-&0100 arasındaki bölgenin korunması gerekir. Interrupt'lar açıkken ve/veya Upper & Lower ROM devredeyken hafızanın bu iki bölgesine yazmak, firmware'i crash ettirir. İşte bu yüzden, 64K'nın tamamını kullanmak isteyen oyunlar/demolar, firmware'i devre dışı bırakmak için önce DI komutu ile interrupt'ları durdurur, ardından RMR register'ının 2 ve 3. bit'lerini set ederek Upper & Lower ROM'u devredışı bırakır.

Amstrad BASIC mode'undayken aleti freeze edip, nasıl bir memory map kullandığını incelemeni tavsiye ederim.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 23 Ocak 2014, 16:23:47
Abicim, ben ödeme için gelmiştim. Arkadaşlar yanıtı yollamış sanırım... Ekte faturamızı takdim edeyim...
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 23 Ocak 2014, 17:50:10
@Alcofribas: Fatura için ödeme süresini 3 gün belirlemişsin. Yasal süresi 1 hafta kardeşim. Üzerine yasal faiz uygula, z80 gönül dostları sofrasında faiziyle öderim. :)

@Matahari: Bu açıklama çok faydalı oldu, özellikle de memory mapdeki zeropage'in dışında hangi kısımların korunması gerektiği ile ilgili. Ancak burada soruna neden olan şey tam olarak bu mu emin değilim. Çünkü hakim olmadığım iki kademe var.

1) SNA dosyasını üreten toolun bu dosyayı tam olarak nasıl ürettiği. (Eve gidince ilk bunu incelemeyi düşünüyorum)
2) WinAPE'in SNA dosyasını memory'e nasıl inject ettiği. Belki zaten bu alanları skip ediyor olabilir.

Benim kodumun başında clear interrupt komutu vardı zaten. Ama sorun tam olarak bu değil. Ben sorunumu C64 ile kıyaslayarak ifade edeyim en iyisi, o şekilde kafa karışıklığımı daha iyi anlatabilirim.

C64'de $01 adresi RAM/Kernel ROM/Basic ROM/ROM Charset v.s. çeşitli bellek alanlarını açıp kapamaya yarar. Şimdi ben bir snapshot inject etsem bile önemli olan $01'in o anki durumudur. Eğer ben $01'in Kernel bitini set etmişsem iş bitmiştir. C64 emülatöründen kernel adreslerini listelediğimde kodlar görüntülenir, çünkü RAM'in o bölgesi boş da olsa ben o anda doğrudan ROM'u görüyorumdur ve bir kernel call yaptığımda $01 doğru değerdeyse kernel rutini mutlaka çağırılır, sorun çıkmaz.

Amstrad CPC'de ise yaşadığım durum şu. Upper/Lower ROM'u enable etsem bile eğer SNA'dan yükletmişsem kodumu kernel komutlarının bulunduğu bölgeler Monitör'den baktığımda 0 bytelarıyla dolu, diğer bir anlamda boş gözüküyor. Ancak DSK'dan yüklettiğimde ise bu alanda kodları görüntüleyebiliyorum ve call ettiğimde doğal olarak çalışıyor.

Aklımdaki sorular.

1) Kernel rutinleri bir noktada RAM'e aktarılıyor mu? Biz kernel call yaptığımızda ROM'dan değil de RAM'den mi çağırmış oluyoruz bu kodları?
2) Eğer ROM'dan çağırıyorsak paralel olarak bu alanları RAM olarak kullanabiliyor muyuz? Yani diyelim 64K'lık alanla sınırlıyız. Ben $bc00 civarı adresleri hem RAM'de farklı bir kod olacak şekilde kullanıp, gerektiğinde ROM'u enable edip, call'umu yapıp, tekrar RAM'e çevirdiğimde RAM'deki kodlarım duruyor mu? C64'de bu böyle çalışıyor çünkü. $01'in değerine göre o alanda bazen ROM, bazen RAM görüntülenebiliyor. ROM olduğu durumda da readonly çalışıyor doğal olarak.

SNA ile ilgili iki teorim var. Birincisi SNA bloğu olduğu gibi overwrite ediyor. İkincisi de daha o bloğa birşey transfer edilemeden (Basic mode'a geçmeden v.s.) çok erken biçimde snapshot çalıştırılıyor, ben interruptları da disable ediyorum ve o alan boş kalıyor.

Dediğim gibi bana biri "kernel call'ları RAM'den yapılıyor, rutinler önce RAM'e transfer ediliyor" dediğiniz anda "tamam şimdi oldu" diyeceğim. Ama olay böyle değilse ben upper lower ROM'u açtığımda bile kernel call yapamıyorum. Ama alet crash falan da olmuyor, kodlar gayet temiz çalışıyor. Sadece kernel call yapacağım alan monitörden bakıldığında boş gözüküyor.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 23 Ocak 2014, 20:40:34
Alıntı
Gate Array için "firmware vs low-level port programming" konusu ile ilgili olarak, Retrojen Sayı 0 ve Sayı 1'de kaleme aldığım çalışmalara bir gözatmanı tavsiye ederim. Örneğin; Sayı 1, sayfa 9, sütun 2, "Mercek Altında" başlığında RMR register'ına firmware'i aşarak nasıl eriştiğimizi görebilirsin. Hem sabahlamana gerek kalmaz, hem de üstte verdiğin kod örneğindeki RMR register'ına %10001110 yüklemen durumunda sadece ekran mode'unu değiştirmekle kalmadığını, aynı zamanda Upper & Lower ROM'u da devre dışı bıraktığını ve interrupt counter'ı resetlediğini de görebilirsin!

http://www.cpctech.org.uk/source.html (http://www.cpctech.org.uk/source.html) adresindeki kodları incelerken dikkatimi çeken bir durum vardı.
Normalde Rom'da bulunan Irq servis rutininin olduğu adrese EI-RET komutu koyuluyordu.
Demekki rutinde ilk olarak

.scr_set_mode equ &bc0e
org &8000
nolist
;;--------------------------------------------------
;; clear screen
ld a,1
call scr_set_mode

;;--------------------------------------------------
;; STEP 1 -  Unlock CPC+ additional features
di
ld b,&bc
ld hl,sequence
ld e,17
.seq
ld a,(hl)
out (c),a
inc hl
dec e
jr nz,seq
ei
;;----------------------------------------------------------
;; STEP 2 - Install a interrupt handler
;; disable interrupts
di
;; interrupt mode 1 (call to interrupt handler at &0038)
im 1


;; &c9 corresponds to the opcode RET
;; &fb corresponds to the opcode EI
;; RET opcode takes 3us, EI opcode takes 1us
;; write EI,RET to interrupt handler at &0038
ld hl,&c9fb
ld (&0038),hl
;; enable interrupts
ei


satırları ile Lower Rom devre dışı bırakılıyormuş. CPC'nin hw yapısını bilmediğim için ROM bölgesine yazma yapılıyor gibi gözüksede EI komutundan sonra aslında Ram'de hiç bir iş yapmayan bir irq kodu çalışmış oluyordu. Güzel fikirmiş aslında.
Başlık: Spectrum'da IRQ + BASIC ?
Gönderen: hades - 27 Ocak 2014, 19:47:03
Tam Ref'e göre bir soru.

Yazdığım kodlarda IM 2'yi kullanıyorum ama Basic ekranına geri dönüş yapmayıp normal rutinde JR ile döngü yapıyorum.
Hem Irq kullanıp hem Basic nasıl kullanılır? Aklıma IM 1 kullanmak geliyor ama nasıl olacak?

Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 28 Ocak 2014, 04:54:59
Anladığım kadarıyla bir basic programı çalışırken, diğer taraftan asm ile müzik çaldırmak istiyorsun.

Spectrumda bir tek IM2'yi kullanabiliyoruz. IM1 ROM'a göre zıplıyor, dolayısı ile yapacak bişey yok.

IM2'yi kurması da gıcık aslında. Çünkü şöyle bir durum var. IM2 işaretçi adresinin hesaplanacağı adres şu şekilde hesaplanıyor (evet suyunun suyu şeklinde):

Adresin üst byte'ı I yazmacında tutuluyor. Fakat alt byte'ı takılı olan aygıt belirliyor. Eğer bir aygıt takılı değil ise, floating bus sebebi ile bu alt byte random olabiliyor. Dolayısı ile IM2 kurmak için 257 byte'lık bir alanı *aynı* byte'lar ile doldurmak gerekiyor ki, adres nereye düşerse düşsün pointer değişmesin.

Örnek. Diyelim ki I'yı 254 yaptınız. Bu şekilde IM2 pointer'ının okunacağı adres (yüksek byte'a göre) 65024 oldu. Fakat IM2 düşük byte 0-255 arasında rast gele bir değer. Dolayısı ile eğer düşük byte 0 olursa sizin kesme rutininizin bulunacağı adres 65024 ve 65025 byte'larından hesaplanacak. Eğer bu adreslerin ilkinin değeri "1", ikincisinin değer i"0" olursa, interrupt olduğunda, 255 adresine zıplanır.  Fakat IM2 düşük byte başka bir rakam olsa, zıplanacak adres başka bir lokasyondan hesaplanacağı için, IM2 başka bir yere zıplar.

Ben asmp multicolor aracını kodlarken şöyle bir yöntem izledim. 65024'den itibaren 257 byte boyunca #FD ile doldurdum. I'ya 254 yükleyince her durumda IM2 vektörü #FDFD oluyor, yani 65021'e zıplanıyor. Bu adrese istediğin şekilde dallanabilirsin, ben timing için yaptığım için buraya RET girdim, böylece halt ile durduktan sonra IM2 olduğu gibi program senkronize olarak devam ediyor.

Dikkat, Interrupt rutini asla 32768'den aşağıda olmamalı!

Senin durumunda ise basic çalışsın istiyorsun, fakat IM1 servis rutinide çalışsın istiyorsun. Bu durumda servis rutininin yaptığı işi senin yapman gerek.

Neyse benim kodu asmp'den copy-paste ediyorum:

Önce IM2'yi kuralım
Kod: [Seç]
di  ;interrupt'ı kapatalım

ld hl,65021

ld (hl),#C3 ;jump kodunu yerleştirelim, dikkat bu şekilde yapmak mecburi değil
inc hl         ;vektör tablosunu 253'le değil başka bir rakamla doldurursanız
ld hl, #c0   ;istediğiniz yere zıplatırsınız zaten
inc hl
ld hl, #c7  ; yani #C3 #C0C7 (JP 47040)
                 

ld   hl,65024  ;şimdi aralığı FD ile dolduracağız.
ld   de,65025
ld   (hl),253
ld   b,e
ld   c,e
ldir

ld   a,254  ;Artık IM2'yi kurabiliriz.
ld   i,a
im   2 ;im2'ye geçtik

ei  ;interruptlar açık


Bu da basic'i çalışır durumda tutmanın bir yöntemi:
Kod: [Seç]
org #C0C7  ;yukarıdaki örneğe göre kod 47040'dan başlamalı.

di  ;alışkanlık
ld (stackpointer),sp ;mecbur değilsen sp'yi yazmayabilirsin
ld sp,stackpointer   ;garanti olsun diye yerini de değiştiriyorum (18 byte'lık bir yer lazım)

Push HL   ;basic'in kullandığı yazmaçları saklayalım
Push BC
Push DE
Push AF 

exx         ;söylentiye göre basic için alternatif yazmaçları saklamaya gerek yok
Push HL   ;ama yine de koyalım bir kenara
Push BC
Push DE

CALL muzik  ;müziğimizi çalalım

rst 56 ;ROM'daki servis rutini, klavyeyi okur, sayacı ilerletir

LD sp,stackpointer-14 ;basic'e dönmeden önce herşeyi geri yerleştirelim
Pop DE
Pop BC
Pop HL

exx
pop af
pop de
pop bc
pop hl

ld sp,(stackpointer) ;herşeyi geri aldık
;IM1 ;Bu noktada IM1 işletsek, basic'e olduğu gibi geri dönülmüş olur.
ei  ;interrupt'ı çalıştır.
ret  ;geri dön, dilerseniz RETI de kullanabilirsiniz.

stackpointer:
defb 0

Bu koda göre IX/IY registerini kullanamazsınız, basic kullanıyor, istiyorsanız onları da kaydetmelisiniz.

Bu efektif yöntem mi bilmiyorum ama benim kullandığım yöntem bu. Özetlersek (değerler decimal):

1. IM2 için 257 byte uzunluğunda vektör tablosu oluştur. (tablo 220'lerden oluşursa adres 220*256+220= 56540 olacak)
2. I'yı bu tablonun başına point et.
3. vektör tablosundaki adrese rutinini koy
4. rutin başladığında basic değişkenlerini sakla (PUSH <hepsi>)
5. işini yap: (CALL x)
6. basic servis rutinini çağır (rst 56)
7. basic değişkenlerini geri çağır (POP <hepsi>)
8. geri dön (reti/ret)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: nightlord - 31 Ocak 2014, 20:33:00
Yıllar içinde edindiğim tecrübe, bana Occam'ın Usturası prensibinden (http://tr.wikipedia.org/wiki/Ockham'%C4%B1n_Usturas%C4%B1 (http://tr.wikipedia.org/wiki/Ockham'%C4%B1n_Usturas%C4%B1)) şaşmamam gerektiğini öğretti. İster retro ortam olsun, isterse son model bir konsol... Kod geliştirme ortamımı mümkün olduğunca yalın tutmaya çalışarak, oluşması muhtemel sorunların sayısını azaltmış oluyorum. Aynı sonucu elde edebildiğim sürece, tercihimi basit ve yalın olandan yana kullanıyorum.

Amstrad için kod yazarken WinAPE'i tercih etmemin sebebi de bu. Evet, cycle-precise değil, ama işin %99'unu yapmak için yeter de artar. (Geri kalan %1'lik bölüm için zaten gerçek Amstrad üzerinde testlerimi yapıyorum.) Bu da hem işimi hızlandırıyor, hem de muhtemel bug'lardan beni uzak tutuyor.

İlk mesajımda belirttiğim üzere, her yiğidin yoğurt yemesi farklı  ;)

C64'de durum biraz yiğit ve yoğurt olayından farklı :) WinAPE assembler'ının yetilerini bilmiyorum tabi ama örneğin Vice üzerinde kod yazmak (çok basit programlar veya büyük programlara basit tweak'ler hariç) çok zor. Araya iki satır kod eklemek için kodu o noktadan itibaren n bayt ileri kaydırmak. değişkenler ve rutin adresleri için etiket kullanamamak falan insanı çıldırtmak için birebir. Artı biz demo efektlerinde sürekli bir takım hileler yaptığımız ve bazı hesapları tablolara attığımız veya bazı döngüleri açtığımız için tablo ve kod ürettirme aşamalarını emülatör içinde yapamıyoruz. Skate'in bahsettiği makefile'lar o yüzdendi. bol miktarda başka tool'da build sürecinin parçası olmak zorunda kalıyor C64'de. Yani biz o toollar olmadan aynı sonucu alamıyoruz genelde.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 03 Şubat 2014, 22:06:21
8-Blok işlem yapan komutlar/giriş-çıkış komutları

Kaldığımız yerden devam ediyoruz. Blok işlemden kastettiğimiz tek komutla birden fazla işlem yapılmasıdır.

Blok Transfer Komutları
LDI

HL'nin gösterdiği adresin içeriği DE'nin gösterdiği adrese yüklenir, DE ve HL 1 arttırılır BC 1 azaltılır.

Kullanma şekli:
LD HL,Kaynak
LD DE,Hedef
LD BC,Byte Sayacı
LDI

LDI komutunu aşağıdaki komutlar gibi düşünün.

LD A,(HL)
LD (DE),A
INC HL
INC DE
DEC BC


LDIR

LDI gibidir ama işlemler BC=0 oluncaya kadar tekrarlanır.

Kullanma şekli:
LD HL,Kaynak
LD DE,Hedef
LD BC,Byte Sayacı
LDIR

LDIR komutunu aşağıdaki komutlar gibi düşünün.

loop LD A,(HL)
LD (DE),A
INC HL
INC DE
DEC BC
LD A,B
OR C
JR NZ,loop

LDD

HL'nin gösterdiği adresin içeriği DE'nin gösterdiği adrese yüklenir, DE, HL ve BC 1 azaltılır.

Kullanma şekli:
LD HL,Kaynak
LD DE,Hedef
LD BC,Byte Sayacı
LDI

LDD komutunu aşağıdaki komutlar gibi düşünün.

LD A,(HL)
LD (DE),A
DEC HL
DEC DE
DEC BC


LDDR

LDD gibidir ama işlemler BC=0 oluncaya kadar tekrarlanır.

Kullanma şekli:
LD HL,Kaynak
LD DE,Hedef
LD BC,Byte Sayacı
LDIR

LDDR komutunu aşağıdaki komutlar gibi düşünün.

loop LD A,(HL)
LD (DE),A
DEC HL
DEC DE
DEC BC
LD A,B
OR C
JR NZ,loop


Blok Karşılaştırma Komutları
CPI

Aküdeki değer ile HL registerinin gösterdiği adresin içeriği karşılaştırılır. Sonuç aynıysa Z flag "1" olur. HL 1 arttırılır, BC 1 azaltılır.

Kullanma şekli:
LD HL,adres
LD A,Sayı
LD BC,Bayt sayacı
CPI

CPI komutunu aşağıdaki komutlar gibi düşünün.

CP (HL)
INC HL
DEC BC

CPIR

CPI gibidir. İşlemler A=(HL) veya BC=0 oluncaya kadar tekrarlanır.

Kullanma şekli:
LD HL,adres
LD A,Sayı
LD BC,Bayt sayacı
CPIR

CPIR komutunu aşağıdaki komutlar gibi düşünün.

loop CP (HL)
JR Z,bitir
INC HL
DEC BC
LD A,B
OR C
JR NZ,loop
....
bitir ....

CPD

Aküdeki değer ile HL registerinin gösterdiği adresin içeriği karşılaştırılır. Sonuç aynıysa Z flag "1" olur. HL ve BC 1 azaltılır.

Kullanma şekli:
LD HL,adres
LD A,Sayı
LD BC,Bayt sayacı
CPD

CPD komutunu aşağıdaki komutlar gibi düşünün.

CP (HL)
DEC HL
DEC BC

CPDR

CPD gibidir. İşlemler A=(HL) veya BC=0 oluncaya kadar tekrarlanır.

Kullanma şekli:
LD HL,adres
LD A,Sayı
LD BC,Bayt sayacı
CPIR

CPIR komutunu aşağıdaki komutlar gibi düşünün.

loop CP (HL)
JR Z,bitir
DEC HL
DEC BC
LD A,B
OR C
JR NZ,loop
....
bitir ....


Giriş / Çıkış komutları daha sonra.
Başlık: Karakter setini deviriyoruz.
Gönderen: hades - 03 Şubat 2014, 22:16:13
Sıradaki program ile Spectrum'un karakter setini 90 derece sola yatırıyoruz.

Kod: [Seç]
;------------------------------------------------;
; SPECTRUM FONT - 03
; 21-01-2014
; Program uzunluğu 35 Byte
;------------------------------------------------;
org $8000

ld ix,$3d00
ld iy,newchar+7
ld de,8
ld h,96
loop02 ld c,8
loop01 ld b,8
push iy
ld a,(ix+0)
ccf
loop00 rl a
rl (iy+0)
dec iy
djnz loop00
inc ix
pop iy
dec c
jr nz,loop01
add iy,de
dec h
jr nz,loop02

ld hl,newchar
dec h
ld (23606),hl
ret

org $8100
newchar
end $8000
Başlık: Ekranı 1 pixel sola kaydırmak.
Gönderen: hades - 03 Şubat 2014, 22:28:30
Ekranı bir pixel sola kaydırıyoruz.

Kod: [Seç]
;-----------------------------------------------;
; BIR PIXEL SOLA KAYDIRMA ;
;-----------------------------------------------;

org $8000

ld hl,22527
ld c,192
nextline ld b,32
or a
nextbyte rl (hl)
dec hl
djnz nextbyte
dec c
jr nz,nextline
ret

end $8000
Başlık: Ekranı 1 pixel sağa kaydırmak.
Gönderen: hades - 03 Şubat 2014, 22:32:46
Ekranı bir pixel sağa kadırıyoruz.

Kod: [Seç]
;-----------------------------------------------;
; BIR PIXEL SAĞA KAYDIRMA ;
;-----------------------------------------------;

org $8000

ld hl,16384
ld c,192
nextline ld b,32
or a
nextbyte rr (hl)
inc hl
djnz nextbyte
dec c
jr nz,nextline
ret

end $8000
Başlık: Ekran başaşağı
Gönderen: hades - 03 Şubat 2014, 22:40:24
Ekrandaki görüntüyü renkleriyle beraber başaşağı çeviriyoruz.

Kod: [Seç]
;-------------------------------------------------------;
; HORIZONTAL FLIP SCREEN ;
; 10-01-2009 hades/ret ;
;-------------------------------------------------------;

org $8000 ;program 32768 (8000h) adresinden başlıyor.

main ld de,$4000 ;ekran belleği başlangıç adresi.
ld hl,$57e0 ;ekran belleği sol alt posizyon adresi.
ld c,$60 ;24 karakter*8pixel=192 pixel satırının yarısı 96.
call loop1 ;alt rutine git.
ld de,$5800 ;renk belleği başlangıç adresi
ld hl,$5ae0 ;renk belleği sol alt pozisyon adresi.
ld c,$0c ;24 karakter satırının yarısı.

loop1 ld b,$20 ;Bir satırdaki karakter sayıcısı (32).
loop0 ld a,(de) ;DE registerinin gösterdiği adresteki değeri oku.
push af ;Aküyü yığına at.
ld a,(hl) ;HL registerinin gösterdiği adresteki değeri oku.
ld (de),a ;Aküdeki değeri DE'deki adrese yaz.
pop af ;Akünün önceki değerini yığından al.
ld (hl),a ;AKüdeki degeri HL'deki adrese yaz.
inc de ;DE'yi 1 arttır.
inc hl ;HL'yi 1 arttır.
djnz loop0 ;Karakter sayıcısını 1 azalt, 0 olmadıysa işlemleri tekrarla.
push de ;DE'yi yığına at.
ld de,$40 ;DE'ye 40h (64) değerini ver.
sbc hl,de ;HL'deki değerden DE'deki değeri çıkart ve sonucu HL'ye yaz.
pop de ;DE'nin önceki değerini yığından al.
dec c ;sayacı 1 azalt.
jr nz,loop1 ;sayaç 0 olmadıysa işlemleri tekrarla.
ret ;geri dön

end $8000
Başlık: Ekran yönünü değiştiriyoruz.
Gönderen: hades - 03 Şubat 2014, 22:47:04
Kod: [Seç]
;-------------------------------------------------------;
; VERTICAL FLIP SCREEN ;
; 10-01-2009 hades/ret ;
;-------------------------------------------------------;
org $8000

main ld hl,$4000
ld de,$401f
ld c,$c0
loop1 ld b,$10
loop0 push bc
push hl
ld a,(hl)
call rotate
ld (tempa),a
ld a,(de)
call rotate
pop hl
ld a,(tempb)
ld (hl),a
ld a,(tempa)
ld (de),a
inc hl
dec de
pop bc
djnz loop0
call newadr
jr nz,loop1
color ld hl,$5800
ld de,$581f
ld c,$18
loop5 ld b,$10
loop4 ld a,(hl)
push af
ld a,(de)
ld (hl),a
pop af
ld (de),a
inc hl
dec de
djnz loop4
call newadr
jr nz,loop5
ret
rotate ld b,8
ld hl,tempb
loop2 rr a
rl (hl)
djnz loop2
ld a,(hl)
ret
newadr push bc
ld bc,$30
ex de,hl
add hl,bc
ex de,hl
ld bc,$10
add hl,bc
pop bc
dec c
ret
;---------------------------------------------
tempa defb 0
tempb defb 0
end $8000
Başlık: code - code - code
Gönderen: hades - 23 Şubat 2014, 15:01:28
Daha önce yazmış olduğum bir rutinin düzenlenmiş hali. Ekranın ilk satırındaki yazıyı uzatıyor gibi bir şey.

Kod: [Seç]
;-------------------------------------------------------;
;                  SCREEN  STRECHER ;
;                 23-02-2014 / HADES ;
; (255 byte code + text) ;
;-------------------------------------------------------;
org $8000

main call $0d6b ;CLS command
ld a,2 ;S(creen) kanalını
call $1601 ;açıyoruz.
ld b,endmsg-msg
ld hl,msg
loop0 ld a,(hl)
rst $10 ;PRINT command
inc hl
djnz loop0
ld b,60 ;efekt başlangıç gecikmesi
call delay01
;------------------------------------------
line7 call la47004020
;------------------------------------------
line6 call la46004700
call la40204120
;------------------------------------------
line5 call la45004600
call la47004020
call la41204220
;------------------------------------------
line4 call la44004500
call la46004700
call la40204120
call la42204320
;------------------------------------------
line3 call la43004400
call la45004600
call la47004020
call la41204220
call la43204420
;------------------------------------------
line2 call la42004300
call la44004500
call la46004700
call la40204120
call la42204320
call la44204520
;------------------------------------------
line1 call la41004200
call la43004400
call la45004600
call la47004020
call la41204220
call la43204420
call la45204620
;------------------------------------------
line0 ;; call la42004300
call la44004500
call la46004700
call la40204120
call la42204320
call la44204520
call la46204720
;------------------------------------------
ld b,80 ;efekt bitiş gecikmesi
call delay01
xx jp main
;------------------------------------------
la41004200 ld hl,$4100
ld de,$4200
jr transfer
;------------------------------------------
la42004300 ld hl,$4200
ld de,$4300
jr transfer
;------------------------------------------
la43004400 ld hl,$4300
ld de,$4400
jr transfer
;------------------------------------------
la44004500 ld hl,$4400
ld de,$4500
jr transfer
;------------------------------------------
la45004600 ld hl,$4500
ld de,$4600
jr transfer
;------------------------------------------
la46004700 ld hl,$4600
ld de,$4700
jr transfer
;------------------------------------------
la47004020 ld hl,$4700
ld de,$4020
jr transfer
;------------------------------------------
la40204120 ld hl,$4020
ld de,$4120
jr transfer
;------------------------------------------
la41204220 ld hl,$4120
ld de,$4220
jr transfer
;------------------------------------------
la42204320 ld hl,$4220
ld de,$4320
jr transfer
;------------------------------------------
la43204420 ld hl,$4320
ld de,$4420
jr transfer
;------------------------------------------
la44204520 ld hl,$4420
ld de,$4520
jr transfer
;------------------------------------------
la45204620 ld hl,$4520
ld de,$4620
jr transfer
;------------------------------------------
la46204720 ld hl,$4620
ld de,$4720
;------------------------------------------
transfer ld bc,$20
ldir
;------------------------------------------
delay ld b,1 ;efekt gecikmesi
delay01 halt
djnz delay01
ret
;------------------------------------------
msg defb 22,0,0 ;AT 0,0
defb 16,2 ;INK 2
defm "SCREEN STRECHER-23.02.2014-HADES"
;------------------------------------------
endmsg end $8000
;------------------------------------------
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 24 Şubat 2014, 14:42:49
yukarıdaki kodun sonucu şunun gibi bişey:

(https://retrojen.org/pano/proxy.php?request=http%3A%2F%2Fi.imgur.com%2FAF3E5dN.png&hash=c46dbe54f570a2f940a27254162b1f56)

gibi bişey çünkü yumuşak bir animasyon var.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 09 Mart 2014, 12:10:00

LDIR komutu, bellekteki herhangi bir alani baska bir alana kopyalamak icin kullanilan dongusel komutlardan birisidir. (Bir digeri icin bkz. LDDR)

Calisma sekli:
...

@memrah, açıklamalarını wiki'ye ekledim, istemezsen düzeltebiliriz (ya da düzeltebilirsin (http://zx.gen.tr/wiki/index.php?title=LDIR&action=edit)).

http://zx.gen.tr/wiki/index.php?title=LDIR (http://zx.gen.tr/wiki/index.php?title=LDIR)
Başlık: İlk ekran satırında bir efekt.
Gönderen: hades - 09 Mart 2014, 16:32:27
Kod: [Seç]
;---------------------------------------------------------------;
; SCREEN EFFECT ;
; 09-03-2014 / HADES ;
; CODE + TEXT 155 BYTE ;
;---------------------------------------------------------------;

org $8000

main xor a
out (254),a
call $0d6b
ld a,2
call $1601

ld hl,$5800
ld de,$5801
ld bc,767
ld (hl),%00000111
ldir

text ld b,endmsg-msg
ld hl,msg
loop00 ld a,(hl)
rst $10
inc hl
djnz loop00

ld b,80 ;efekt başlangıç
delay00 halt ;gecikmesi
djnz delay00

ld d,0
loop01 ld hl,$471f
ld b,8
call scroll
dec h ;$461f
ld b,7
call scroll
dec h ;$451f
ld b,6
call scroll
dec h ;$441f
ld b,5
call scroll
dec h ;$431f
ld b,4
call scroll
dec h ;$421f
ld b,3
call scroll
dec h ;$411f
ld b,2
call scroll
dec h ;$401f
ld b,1
call scroll
dec d
jr nz,loop01
jr text ;başa dön
;------------------------------------------------------------------
scroll push hl
ld c,32
or a
newbyte rl (hl)
dec hl
ld e,3 ;efekt gecikmesi
delay01 dec e
jr nz,delay01
dec c
jr nz,newbyte
pop hl
djnz scroll
ret
;-----------------------------------------------------------------
msg defb 22,0,0 ;AT 0,0
defm "SCREEN EFFECT -09.03.2014- HADES"
;-----------------------------------------------------------------
endmsg end $8000
;-----------------------------------------------------------------


Bu kodları "Spectrum için kod örnekleri" isimli bir başlık açıp oraya taşısak nasıl olur?
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: memrah - 09 Mart 2014, 22:04:25
@memrah, açıklamalarını wiki'ye ekledim, istemezsen düzeltebiliriz (ya da düzeltebilirsin (http://zx.gen.tr/wiki/index.php?title=LDIR&action=edit)).

http://zx.gen.tr/wiki/index.php?title=LDIR (http://zx.gen.tr/wiki/index.php?title=LDIR)

Hades'in mesajlarinin bir araya getirildigi bir dokuman var mi? Saka maka ciddi bir Turkce Z-80 (+ZX Spectrum) kaynagina donusmeye basladi olay.
Eline saglik Hades.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 09 Mart 2014, 22:41:38

Hades'in mesajlarinin bir araya getirildigi bir dokuman var mi? Saka maka ciddi bir Turkce Z-80 (+ZX Spectrum) kaynagina donusmeye basladi olay.
Eline saglik Hades.

wiki'deki başlıklar hades'in yazdıklarından hareketle, birkaç kaynağı daha buluşturuyor. Ama daha yolun çok başındayız. Şimdilik bir avuç komut var, ama bunu çok uzun soluklu bir proje olarak düşünelim, ayda bir bile olsa konut açıklasak 1-2 sene içinde tamamlanır.

http://zx.gen.tr/wiki/index.php?title=Kategori:Z80_İşlemci_Komutları (http://zx.gen.tr/wiki/index.php?title=Kategori:Z80_%C4%B0%C5%9Flemci_Komutlar%C4%B1)

El atmaktan çekinmeyiniz.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 04 Temmuz 2014, 21:55:48
Bir süredir kod yazmıyordum. 1-2 gün önce kodları karıştırırken bulduğum kodu adam ettim. Asıl yapmak istediğim hafızadaki bir texti 8x8 scroll yapmaktı. Fakat gözüm yemedi. Bunun üzerine kodda biraz değişiklik yaptım. Program listesindeki "retrojen" yazısını 8x8 karakter büyüklüğünde renk belleğine basıyor.

Kod: [Seç]
;---------------------------------------------------------------;
; 8x8 TEXT ;
; 04-07-2014 / HADES ;
; CODE + TEXT 104 BYTE ;
;---------------------------------------------------------------;

org $8000

main ld hl,$4000
ld de,$4001
ld bc,6143
ld (hl),255
ldir

ld b,textend-text
ld hl,$5800
ld ix,text
ld c,4
nextchar push bc
push ix
ld a,(ix+0)
ld ix,(23606) ;charset base
ld de,0
ld c,a
loop01 ld b,8
loop00 inc de
djnz loop00
dec c
jr nz,loop01
add ix,de ;karakter data adresi

ld c,8
nextbyte ld b,8
ld a,(ix+0)
nextbit rla
jr nc,nocolor
ld (hl),6 ;renk
jr cont
nocolor ld (hl),0
cont inc hl
djnz nextbit
inc ix
ld de,24
add hl,de
dec c
jr nz,nextbyte
ld de,$f8
sbc hl,de
pop ix
inc ix
pop bc
dec c
jr nz,next
ld c,4
ld hl,$5900
next djnz nextchar
ret

text defm "rEtRoJeN"
textend

end $8000
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 06 Temmuz 2014, 01:39:15
(https://retrojen.org/pano/proxy.php?request=http%3A%2F%2Fi.imgur.com%2FtXa5iZc.png&hash=e1c03d27576d67cf01b9958acb59e9f6)

Bu sefer basinç ile derledim, sonuç böyle oldu :D
Başlık: 8x8 text scroll
Gönderen: hades - 11 Temmuz 2014, 00:17:48
Hafızadaki bir texti 8x8 büyüklüğünde kaydıran program.

Kod: [Seç]
;-------------------------------------------------------;
;                  8x8 TEXT SCROLL ;
;                 10-07-2014 / HADES ;
; (153 bytes code) + text ;
;-------------------------------------------------------;
org $8000

main call $0d6b ;CLS command
ld a,2 ;S(creen) kanalını
call $1601 ;açıyoruz.

ld a,17
rst $10
xor a
out (254),a
rst $10

ld hl,22528
ld de,22529
ld bc,767
ld (hl),%00000101
ldir

again ld b,textend-text
ld ix,text
loop03 push bc
push ix
ld a,(ix+0)
ld ix,(23606) ;charset base
ld de,0
ld c,a
loop01 ld b,8
loop00 inc de
djnz loop00
dec c
jr nz,loop01
add ix,de ;karakter data adresi

ld b,8
ld de,temp
loop02 ld a,(ix+0)
ld (de),a
inc ix
inc de
djnz loop02

ld c,8 ;7 ;karakter data bit sayacı
nextbit ld b,8 ;karakter satır yüksekliği
ld de,temp
nextpos ld a,22 ;AT komutu
rst $10

ld hl,(pos)
ld a,h ;satır numarası (0)
rst $10
ld a,l ;sütun numarası (31)
rst $10
inc h
ld (pos),hl
ld a,(de)
rla ;karakterin 7.biti
ld (de),a
jr nc,space
ld a,$2e ;ekrana nokta basıyoruz
jr cont
space ld a,$20
cont rst $10
inc de
djnz nextpos
call scroll
ld hl,31
ld (pos),hl
dec c
jr nz,nextbit
nextchar pop ix
pop bc
inc ix
djnz loop03
jr again
;-----------------------------------------------------------------------------
scroll push bc
ld d,8
repeat ld hl,18431
ld c,64
nextline ld b,32
or a
nextbyte rl (hl)
dec hl
djnz nextbyte
dec c
jr nz,nextline
halt ;scroll delay
; halt ;delay
dec d
jr nz,repeat
pop bc
ret
;-----------------------------------------------------------------------------
pos defw 31
temp defb 0,0,0,0,0,0,0,0
text defm "8x8 text scroll by HADES/RET. "
defm "10-07-2014 "
textend
end $8000
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 22 Temmuz 2014, 12:59:56
Bugün wiki'ye birkaç yeni başlık ekledim, ama bir tanesini buraya duyurmaya değer,

http://zx.gen.tr/wiki/index.php?title=Z80_Bayraklar%C4%B1 (http://zx.gen.tr/wiki/index.php?title=Z80_Bayraklar%C4%B1)

Z80 Flag'lerini daha iyi anlamak adına fazladan birkaç cümle içeriyor.

Kaynakça geniş ama Türkçeleştirme için kütüphanemizde bulunan "Spectrum Basic ve Makine Kodu" isimli kitaptan yararlandım.

Bir de bir z80 komut tablosu koydum, buradaki başlıkların kırmızı olanlarını doldurmak isterseniz buyrun:

http://zx.gen.tr/wiki/index.php?title=Z80_Komut_Tablosu (http://zx.gen.tr/wiki/index.php?title=Z80_Komut_Tablosu)
Başlık: Ynt: Z80 Makine diline meraklı olan? - Ekran Genişletici
Gönderen: hades - 03 Ağustos 2014, 17:31:24
İki gün önce iş yerinde beyin kıvrımlarımın derinliklerinde birden ortaya çıkan bir fikir dün birkaç saat içinde hayat buldu. Bugün ise biraz optimizasyon yaptım.
Program ekranın sol yarısında ne varsa X yönünde 2 kat genişletiyor. Renklerle ilgili bir işlem yapmıyoruz. Çünkü kafam basmadı :) 
Güle güle kullanın.

Kod: [Seç]
;-------------------------------------------------------;
;                 EKRAN GENİŞLETİCİ ;
;                 03-08-2014 / HADES ;
; 123 bytes code ;
;-------------------------------------------------------;
org $8000

; ld hl,ekran
; ld de,$4000
; ld bc,6144
; ldir

setup ld hl,$400f
ld (source),hl
ld l,$1f
ld (target),hl ;hl=$401f

wait ld b,h ;efekt başlangıç gecikme sayacı ($40)
delay halt
djnz delay

ld c,3 ;ekran blok sayacı
loop04 ld b,8 ;blok satır sayacı
loop03 push bc
ld c,16 ;satır karakter sayacı
ld hl,(source)
ld ix,(target)
loop02 push hl
push ix
ld d,8 ;karakterin dikey pixel sayacı
loop01 call expand
dec ix
call expand
inc ix
inc h ;hl=hl+256
illegalcommand inc ixh ;ix=ix+256
dec d
jr nz,loop01
pop ix
pop hl
dec ix
dec ix
dec hl
dec c
jr nz,loop02

ld de,$20 ;bir alttaki pixel satırının
ld hl,(source) ;adresini hesapla
add hl,de
ld (source),hl
ld hl,(target)
add hl,de
ld (target),hl
pop bc
djnz loop03

ld de,$0700 ;sonraki blok adres hesapla
ld hl,(source)
add hl,de
ld (source),hl
ld l,$1f
ld (target),hl
dec c
jr nz,loop04
ret

expand ld b,4 ;karakter bit sayacı
loop00 ld a,(hl)
rr (hl)
rr e
ld (hl),a
rr (hl)
rr e
djnz loop00
ld (ix+0),e
ret

source defw 0
target defw 0

;ekran incbin "aticatac_ekran.bin"

end $8000
;=============================================================================
Başlık: IM 2 (Interrupt Mode 2) SETUP
Gönderen: hades - 21 Şubat 2015, 01:14:33
Z80'de interrupt kurulumu biraz karışıktır. (Benim anlamam bile uzun sürdü. :) )
Bu işlemi aşağıdaki kod ile oldukça basit bir hale getirdim. İnterrupt vektör tablosu ile programın çalışma adresi aynı olup hiç bir sorun çıkmamaktadır. Vektör tablosu $8000 - $8101 arasında olup, bu aralığı 257 adet $81 ile dolduruyoruz. $81 değeri aynı zamanda ADD A,C komutuna karşılık gelmektedir. Dolayısıyla USR 32768 yazdığımızda sanki normal bir program varmış gibi ADD A,C komutları çalışmakta ve $8101'e gelindiğinde IM 2 ayarlama programı çalışmaktadır.

Kod: [Seç]
;==============================================================;
; Z80 IM2 (INTERRUPT MODE 2) SETUP        ;
;==============================================================;
org $8000
;--------------------------------------------------------------;
vectab defs 257,$81 ;$81 ADD A,C komutu
;--------------------------------------------------------------;
start di ;interruptı durdur
ld a,$80 ;vektör tablosunun
ld i,a ;yüksek baytını yaz
im 2 ;mod 2'ye geç
ei ;interruptı başlat
halt ;1/50 saniye bekle
;--------------------------------------------------------------;
; Buradan itibaren $8181'e kadar 119 baytlık yer var.    ;
;--------------------------------------------------------------;
normalkod_example ld hl,22528
loop00 inc (hl)
jr loop00
;==============================================================;
org $8181
;--------------------------------------------------------------;
interrupt push af
push bc
push de
push hl
push ix
push iy
;--------------------------------------------------------------;
interrupt_example xor a
out (254),a
ld bc,545
delay dec bc
ld a,b
or c
jr nz,delay
inc a
out (254),a
;--------------------------------------------------------------;
pop iy
pop ix
pop hl
pop de
pop bc
pop af
;--------------------------------------------------------------;
ei
ret
;--------------------------------------------------------------;
end $8000
; end start
;==============================================================;
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 21 Şubat 2015, 19:42:32
interrupt rutininin başına ve sonuna pushlar ve poplar eklemek 131 ts'yi boşa harcamak oluyor, onu rutini tasarlayacak kişiye bırakmak gerek. Kodu olabildiğince dökümante edersek iyi olur, hiç bilmeyenler bir bakışta amacın ne olduğunu anlar. Örneğin, interrupt_example sembolü sonrasındaki kod nasıl bir iş yapıyor, neden o işi yapıyor? Neden delay veriyorsun mesela? Spectrumu bilmeyenler için güzel açıklamalar içerebilir.

Bir dipnot, HALT (http://zx.gen.tr/retrojenwiki/index.php?title=HALT) 1/50s beklemez, sonraki interrupta kadar bekler, bu 1 cycle da olabilir, sonsuza kadar da sürebilir.
Başlık: Oyunlardan Ekran Araklama
Gönderen: hades - 27 Nisan 2015, 21:42:07
Yazdığım kodları denemek için bazen tam ekran görüntü lazım oluyor. Kullandığım emulator SpecEmu. Bu emulatörde File menüsünde Save Screen seçeneği var ama .scr uzantılı save yaptığı için işime yaramıyor.
Oyunların loading ekranları daha güzel olduğu için bu ekranları alıyorum.
 
1 - Öncelikle tape yükleme normal hızda olmalı.
2 - Loading ekranı tamamlanınca File --> Save Binary File seçip açılan pencerede önce ekranı save edeceğimiz klasörü seçiyoruz. (Ben her zaman kodların olduğu klasörü seçiyorum.)
oyunadı_ekran.bin yazarak kaydet'e basıyoruz.
3 - Save Binary File penceresine geri dönünce "Memory adress" kısmına 16384, "lenght.." kısmına 6912 yazıyoruz ve "save" butonuna basıyoruz.
4 - Kod yazarken
etiket incbin "oyunadı_ekran.bin" komutu yazıyoruz. Böylece ekran görüntüsünü programa ekliyoruz.
5 - Son olarak
ld hl,etiket
ld de,$4000
ld bc,6912
ldir
komutlarını programda kullanarak resmi ekrana çıkartıyoruz. Gerisi ise size kalmış.
Başlık: Yatay ekran genişletici
Gönderen: hades - 27 Nisan 2015, 21:58:29
5. sayfa #72. numaralı mesajda yazdığım rutinin yeni hali. Eskisinde renklerle ilgili bir işlem yapmıyorduk. Bu versiyonda her şey tamam.

Kod: [Seç]
;==============================================================;
;                 YATAY EKRAN GENİŞLETİCİ                ;
;                 01-02-2015 / HADES                     ;
; UZUNLUK : 170 BYTE                     ;
;==============================================================;
org $8000

ld hl,screen
ld de,$4000
ld bc,6912
ldir
ld b,100
wait halt
djnz wait
call main
uloop jr uloop
;--------------------------------------------------------------;
main ld hl,$400f
ld (source),hl
ld l,$1f
ld (target),hl
ld c,3
loop04 ld b,8
loop03 push bc
ld c,16
ld hl,(source)
ld ix,(target)
loop02 push hl
push ix
ld d,8
loop01 call expand
dec ix
call expand
inc ix
inc h
illegalcommand inc ixh
dec d
jr nz,loop01
pop ix
pop hl
dec ix
dec ix
dec hl
dec c
jr nz,loop02
ld de,$20
ld hl,(source)
add hl,de
ld (source),hl
ld hl,(target)
add hl,de
ld (target),hl
pop bc
djnz loop03
ld de,$0700
ld hl,(source)
add hl,de
ld (source),hl
ld l,$1f
ld (target),hl
dec c
jr nz,loop04

ld hl,$580f
ld de,$581f
ld c,24
loop06 push bc
ld b,16
loop05 ld a,(hl)
ld (de),a
dec de
ld (de),a
dec hl
dec de
djnz loop05

ld bc,48
add hl,bc
ex de,hl
ld c,64
add hl,bc
ex de,hl
pop bc
dec c
jr nz,loop06
ret
;--------------------------------------------------------------;
expand ld b,4
loop00 ld a,(hl)
rr (hl)
rr e
ld (hl),a
rr (hl)
rr e
djnz loop00
ld (ix+0),e
ret
;--------------------------------------------------------------;
source defw 0
target defw 0
;--------------------------------------------------------------;
screen incbin "aticatac_ekran.bin"
;--------------------------------------------------------------;
end $8000
;==============================================================;
Başlık: Dikey Ekran Genişletici
Gönderen: hades - 27 Nisan 2015, 22:07:51
Ekrandaki görüntüyü renkleriyle birlikte Y ekseninde 2 kat genişletiyoruz.

Kod: [Seç]
;==============================================================;
;                 DİKEY EKRAN GENİŞLETİCİ                ;
;                 30-01-2015 / HADES                     ;
; UZUNLUK : 220 BYTE                     ;
;==============================================================;
org $8000

ld hl,screen
ld de,$4000
ld bc,6912
ldir
ld b,100
wait halt
djnz wait
call main
uloop jr uloop
;--------------------------------------------------------------;
main ld b,11
ld iy,srctab
tabloop push bc
ld l,(iy+0)
ld h,(iy+1)
ld e,(iy+22)
ld d,(iy+23)
push de
pop ix
call uzat
inc iy
inc iy
pop bc
djnz tabloop
ld hl,$4400
ld ix,$4020
call uzat1
ld hl,$4200
ld ix,$4400
ld c,2
call loop01
ld hl,$4100
ld ix,$4200
ld c,1
call loop01
ld hl,$4000
ld de,$4100
ld bc,$20
ldir

ld b,12
ld hl,$5960
ld de,$5ac0
loop02 push bc
ld bc,32
push hl
push bc
ldir
pop bc
pop hl
ldir
ld bc,64
sbc hl,bc
ex de,hl
sla c
sbc hl,bc
ex de,hl
pop bc
djnz loop02
ret
;--------------------------------------------------------------;
uzat push ix
call uzat1
ld de,$20
pop ix
add ix,de
uzat1 ld c,4
loop01 ld b,$20
loop00 ld a,(hl)
ld (ix+0),a
inc ixh
ld (ix+0),a
dec ixh
inc hl
inc ix
djnz loop00
ld de,$e0
add hl,de
inc d
add ix,de
dec c
jr nz,loop01
ret
;--------------------------------------------------------------;
srctab defw $4860,$4840,$4820,$4800
defw $40e0,$40c0,$40a0,$4080
defw $4060,$4040,$4020
destab defw $50c0,$5080,$5040,$5000
defw $48c0,$4880,$4840,$4800
defw $40c0,$4080,$4040
;--------------------------------------------------------------;
screen incbin "aticatac_ekran.bin"
;--------------------------------------------------------------;
end $8000
;==============================================================;
Başlık: Simetrik Ekran
Gönderen: hades - 27 Nisan 2015, 22:11:46
Ekranın üst yarısını alıyoruz ve alt yarısına simetrik olarak kopyalıyoruz.

Kod: [Seç]
;==============================================================;
;                 YATAY SİMETRİK EKRAN                   ;
;                 01-02-2015 / HADES                     ;
 ; UZUNLUK : 111 BYTE                     ;
;==============================================================;
org $8000

ld hl,screen
ld de,$4000
ld bc,6912
ldir
ld b,100
wait halt
djnz wait
call main
uloop jr uloop
;--------------------------------------------------------------;
main ld b,64
ld hl,$4000
ld de,$57e0
loop00 push bc
ld bc,$20
ldir
ld bc,$40
ex de,hl
sbc hl,bc
ex de,hl
pop bc
djnz loop00
call copy
call copy
call copy
call copy

ld b,12
ld hl,$5800
ld de,$5ae0
loop02 push bc
ld bc,32
ldir
ld bc,64
ex de,hl
sbc hl,bc
ex de,hl
pop bc
djnz loop02
ret
;--------------------------------------------------------------;
copy push hl
push de
ld b,8
loop01 push bc
push hl
push de
ld bc,$20
ldir
pop de
pop hl
inc h
dec d
pop bc
djnz loop01
pop de
pop hl
ld bc,$20
add hl,bc
ex de,hl
sbc hl,bc
ex de,hl
ret
;--------------------------------------------------------------;
screen incbin "aticatac_ekran.bin"
;--------------------------------------------------------------;
end $8000
;==============================================================;
Başlık: Bir Daha Simetrik Ekran
Gönderen: hades - 27 Nisan 2015, 22:14:25
Bu kez ekranın sol yarısını simetrik olarak sağ tarafa kopyalıyoruz.

Kod: [Seç]
;==============================================================;
;                 DİKEY SİMETRİK EKRAN                   ;
;                 30-01-2015 / HADES                     ;
; UZUNLUK : 94 BYTE                      ;
;==============================================================;
org $8000

ld hl,screen
ld de,$4000
ld bc,6912
ldir
ld b,100
wait halt
djnz wait
call main
uloop jr uloop
;--------------------------------------------------------------;
main ld ix,$4000
ld hl,$401f
ld c,192
loop02 push bc
ld b,$10
loop01 ld a,(ix+0)
ld c,8
loop00 rra
rl (hl)
dec c
jr nz,loop00
inc ix
dec hl
djnz loop01
ld de,16
add ix,de
ld de,48
add hl,de
pop bc
dec c
jr nz,loop02
color ld hl,$5800
ld ix,$581f
ld c,$18
loop04 ld b,$10
loop03 ld a,(hl)
ld (ix+0),a
inc hl
dec ix
djnz loop03
ld de,16
add hl,de
ld de,48
add ix,de
dec c
jr nz,loop04
ret
;--------------------------------------------------------------;
screen incbin "aticatac_ekran.bin"
;--------------------------------------------------------------;
end $8000
;==============================================================;
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: i_r_on - 28 Nisan 2015, 00:55:11
Z80'i merak ettiğim zamanlarda hali hazırda x86 assembly bilgim vardı. Kitabı açıp kurcaladığımda mimarisinin, komut setlerinin neredeyse aynı olduğunu gördüğümde uygulama yapmak için bende fazla heyecan uyandırmamıştı. Zaten bildiğiniz üzere Zilog'un kurucusu Federico Faggin'in eli her iki işe de değmiş. 6502'de de benzer bir hikaye var, oradaki ana kahraman da Chuck Peddle sanırım. Intel vs Zilog ve Motorola vs MOS.

Yazılımdan girmedik giremedik derken geçenlerde ebay'den 5 adet Z80 sipariş etmeye çalıştım. Aliexpress'te güzelce kullandığım karta ebay nanik yaptı. O iş de böylece yarım kaldı.

Şimdi buradaki kod örneklerini görünce şu blok transfer olayı bana baya bir değişik geldi. Bu LDIR komutunun eşleniği bildiğiniz başka bir işlemcide var mı acep? x86'da olduğunu hatırlamıyorum.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 29 Nisan 2015, 20:24:41
Şimdi buradaki kod örneklerini görünce şu blok transfer olayı bana baya bir değişik geldi. Bu LDIR komutunun eşleniği bildiğiniz başka bir işlemcide var mı acep? x86'da olduğunu hatırlamıyorum.

Birkaç kural var,
-tüm 8080A komutları Z80'de bulunuyor.
-tüm 8080A yazmaçları Z80'de bulunuyor.
-tüm 8080A programları z80 üzerinde çalışabilir ("çalışabilir"=8080A'nın 11 adet kullanılmayan komut kodları z80'de başka komutlara karşılık gelir.)
-z80 programları genellikle 8080A üzerinde çalışmaz.

 z80 geri yönde 8080'e benzerken aslında bir üst modeli gibi düşünülebilir. z80'de 3 katı fazla yazmaç, 2 adet ekstra bayrak, iki katı fazla komutvar, bu ekstra komutlardan biri de LDI/LDIR.  Lazımsa Wiki'de LDIR'in 8080A karşılığı var ve bir hayli şişkin bir kod: http://en.wikipedia.org/wiki/Zilog_Z80#Example_code (http://en.wikipedia.org/wiki/Zilog_Z80#Example_code)

edit:
kendi mesajımı okuduğumda sorulan soruya cevap vermediğimi farkettim, ldir'e benzer bir komut var mı bilmiyorum :) ama z80'de de ldir pek kullanılmaz lakin çok yavaş bir komut: 21 ts. ram az, zaman bol ise kullanılır genelde.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: i_r_on - 30 Nisan 2015, 01:06:08
@Ref : Ciddi hız kazandırsaydı işe yarardı ancak bu şekilde silikon israfı olmuş. LDIR'ı interrupt kesebiliyor mu diye baktım da, kesebiliyormuş. Tüy dikmemişler en azından :) Tek avantajı herhalde basit kod yazılmasını sağlamak, daha az komut ve bu sayede ram kazanmak.
Başlık: Herhangi bir satırda 1x1 scroll rutini.
Gönderen: hades - 02 Mayıs 2015, 22:31:59
Spectrumun Vic gibi bir grafik çipi olmadığı için basit bir text scroll yapmak bile ekran belleğinin garip yapısından dolayı biraz uğraştırıcıdır.
Aşağıdaki rutinde scroll yapacak satırın numarası değiştirilerek istenilen satırda 1x1 scroll yapılmaktadır.

Kod: [Seç]
;==============================================================;
;                 1X1 TEXT SCROLL        ;
;                 01-05-2015 / HADES                     ;
; UZUNLUK : 129 BYTE CODE + TEXT         ;
;==============================================================;
org $8000

;--------------------------------------------------------------;
; Borderi siyah yap.
;--------------------------------------------------------------;
xor a
out (254),a
again call main
jr again
;--------------------------------------------------------------;
; Scroll yapılacak satır numarasını al ve
; ekran adresini hesapla.
;--------------------------------------------------------------;
; Scroll yapılacak satır 0-7 arasında ise
; ekran adresi $401f.
;--------------------------------------------------------------;
main ld a,(line_nr)
line_0007 cp 8
jr nc,line_0815
ld hl,$401f
jr devam
;--------------------------------------------------------------;
; Scroll yapılacak satır 8-15 arasında ise
; ekran adresi $481f.
;--------------------------------------------------------------;
line_0815 cp 16
jr nc,line_1623
ld hl,$481f
jr devam
;--------------------------------------------------------------;
; Scroll yapılacak satır 16-23 arasında ise
; ekran adresi $501f.
;--------------------------------------------------------------;
line_1623 ld hl,$501f
devam ld (base),hl
;--------------------------------------------------------------;
; Satır numarasına göre son kolonun adresini
; hesapla ve asıl ekran adresini elde et.
;--------------------------------------------------------------;
sla a
sla a
sla a
sla a
sla a
or l
ld (base),a
;--------------------------------------------------------------;
ld b,tend-text ;text uzunluğu max.256
ld hl,text
nextchar push bc
push hl
;--------------------------------------------------------------;
; Okunan karakterin data adresini hesapla.
;--------------------------------------------------------------;
ld a,(hl)
ld hl,(23606)
ld de,0
loop01 ld b,8
loop00 inc de
djnz loop00
dec a
jr nz,loop01
add hl,de ;font data adresi
;--------------------------------------------------------------;
; Font datalarını kopyala.
;--------------------------------------------------------------;
ld b,8
ld de,temp
copy ld a,(hl)
ld (de),a
inc hl
inc de
djnz copy
;--------------------------------------------------------------;
; 8 ekran satırını 8 kez 1 pixel sola kaydır.
;--------------------------------------------------------------;
ld e,8
loop05 push de
ld hl,(base) ;ekran satırının son adresi
;--------------------------------------------------------------;
; 8 Ekran satırını 1 pixel sola kaydır.
;--------------------------------------------------------------;
ld c,8
ld de,temp
loop04 push hl
;--------------------------------------------------------------;
; Font datasının 1 bit sola kaydır ve ekrana bas.
; O anki ekran satırını bir piksel sola kaydır.
;--------------------------------------------------------------;
ld b,32
ld a,(de)
rl a
ld (de),a
loop03 rl (hl)
dec hl
djnz loop03
;--------------------------------------------------------------;
pop hl
inc de
inc h
dec c
jr nz,loop04
;--------------------------------------------------------------;
; Scroll hızını ayarla.
; İstenirse sadece HALT komutları kullanılabilir.
;--------------------------------------------------------------;
ld de,5555
delay dec de
ld a,d
or e
jr nz,delay
; halt
; halt
;--------------------------------------------------------------;
pop de
dec e
jr nz,loop05
;--------------------------------------------------------------;
pop hl
inc hl
pop bc
djnz nextchar
ret
;--------------------------------------------------------------;
line_nr defb 23 ;satır numarası
;--------------------------------------------------------------;
temp defb 0,0,0,0,0,0,0,0
base defw 0
;--------------------------------------------------------------;
text defm " ...Herhangi bir satirda 1x1 "
defm "text scroll rutini 02-05-2015"
defm " FALAN FILAN INTER MILAN !'^+"
defm "%&/()=?_£#${[]}\|.;,:  "
;--------------------------------------------------------------;
tend end $8000
;==============================================================;

Başlık: Aynı satırda 2x1 ve 1x1 text scroll rutini
Gönderen: hades - 13 Eylül 2015, 15:09:18
Bir üstteki 1x1 scroll rutinine eklediğim bir kaç komut ile istenilen satırda sadece 2x1 veya 2x1-1x1 scroll yapıyoruz. 2x1 scroll yapılacak kolon sayısını ayarlamak mümkün.

Kod: [Seç]
;==============================================================;
;                 2X1 VE 1X1 TEXT SCROLL        ;
;                 13-09-2015 / HADES                     ;
; UZUNLUK : 141 BYTE CODE + TEXT         ;
;==============================================================;
org $8000

;--------------------------------------------------------------;
; Borderi siyah yap.
;--------------------------------------------------------------;
xor a
out (254),a
again call main
jr again
;--------------------------------------------------------------;
; Scroll yapılacak satır numarasını al ve
; ekran adresini hesapla.
;--------------------------------------------------------------;
; Scroll yapılacak satır 0-7 arasında ise
; ekran adresi $401f.
;--------------------------------------------------------------;
main ld a,(line_nr)
line_0007 cp 8
jr nc,line_0815
ld hl,$401f
jr devam
;--------------------------------------------------------------;
; Scroll yapılacak satır 8-15 arasında ise
; ekran adresi $481f.
;--------------------------------------------------------------;
line_0815 cp 16
jr nc,line_1623
ld hl,$481f
jr devam
;--------------------------------------------------------------;
; Scroll yapılacak satır 16-23 arasında ise
; ekran adresi $501f.
;--------------------------------------------------------------;
line_1623 ld hl,$501f
devam ld (base),hl
;--------------------------------------------------------------;
; Satır numarasına göre son kolonun adresini
; hesapla ve asıl ekran adresini elde et.
;--------------------------------------------------------------;
sla a
sla a
sla a
sla a
sla a
or l
ld (base),a
;--------------------------------------------------------------;
ld b,tend-text ;text uzunluğu max.256
ld hl,text
nextchar push bc
push hl
;--------------------------------------------------------------;
; Okunan karakterin data adresini hesapla.
;--------------------------------------------------------------;
ld a,(hl)
ld hl,(23606)
ld de,0
loop01 ld b,8
loop00 inc de
djnz loop00
dec a
jr nz,loop01
add hl,de ;font data adresi
;--------------------------------------------------------------;
; Font datalarını kopyala.
;--------------------------------------------------------------;
ld b,8
ld de,temp
copy ld a,(hl)
ld (de),a
inc hl
inc de
djnz copy
;--------------------------------------------------------------;
; 8 ekran satırını 8 kez 1 pixel sola kaydır.
;--------------------------------------------------------------;
ld e,8
loop05 push de
ld hl,(base) ;ekran satırının son adresi
;--------------------------------------------------------------;
; 8 Ekran satırını 1 pixel sola kaydır.
;--------------------------------------------------------------;
ld c,8
ld de,temp
loop04 push hl
;--------------------------------------------------------------;
; Font datasının 1 bit sola kaydır ve ekrana bas.
; O anki ekran satırını bir piksel sola kaydır.
;--------------------------------------------------------------;
ld b,32
ld a,(de)
;--------------------------------------------------------------;
                        push    af              ;eklendi
                        push    hl              ;eklendi
;--------------------------------------------------------------;
rl a
ld (de),a
loop03 rl (hl)
                        dec     hl
djnz loop03
;--------------------------------------------------------------;
;                       Aşağıdaki Komutlar Eklendi
;--------------------------------------------------------------;
                        pop     hl
                        pop     af
ld      b,16     ;2x1 scroll yapacak kolon sayısı
rl      a
loop030 rl      (hl)
                        dec     hl
                        djnz    loop030
;--------------------------------------------------------------;
pop hl
inc de
inc h
dec c
jr nz,loop04
;--------------------------------------------------------------;
; Scroll hızını ayarla.
; İstenirse sadece HALT komutları kullanılabilir.
;--------------------------------------------------------------;
ld de,5555
delay dec de
ld a,d
or e
jr nz,delay
; halt
; halt
;--------------------------------------------------------------;
pop de
dec e
jr nz,loop05
;--------------------------------------------------------------;
pop hl
inc hl
pop bc
djnz nextchar
ret
;--------------------------------------------------------------;
line_nr defb 23 ;satır numarası
;--------------------------------------------------------------;
temp defb 0,0,0,0,0,0,0,0
base defw 0
;--------------------------------------------------------------;
text defm " ...Herhangi bir satirda 2x1 "
                        defm    "ve 1x1 mixed "
defm "text scroll rutini 13-09-2015"
defm " FALAN FILAN INTER MILAN !'^+"
defm "%&/()=?_£#${[]}\|.;,:  "
;--------------------------------------------------------------;
tend end $8000
;==============================================================;

Başlık: 1x2 Scroll Rutini
Gönderen: hades - 13 Eylül 2015, 20:58:34
Text Scroll yapmaya devam ediyoruz. Yazıyı Y ekseninde 2 kat büyüterek kaydırıyoruz.
Not : Programdaki loop030 rl (hl) ve loop032 rl (ix+$20) komutlarını nop ile değiştirip tekrar deneyin.

Kod: [Seç]
;==============================================================;
;                 1X2 TEXT SCROLL        ;
;                 13-09-2015 / HADES                     ;
; UZUNLUK : 194 BYTE CODE + TEXT         ;
;==============================================================;
org $8000

;--------------------------------------------------------------;
; Borderi siyah yap.
;--------------------------------------------------------------;
xor a
out (254),a
again call main
jr again
;--------------------------------------------------------------;
; Scroll yapılacak satır numarasını al ve
; ekran adresini hesapla.
;--------------------------------------------------------------;
; Scroll yapılacak satır 0-7 arasında ise
; ekran adresi $401f.
;--------------------------------------------------------------;
main ld a,(line_nr)
and 22 ;max line number
line_0007 cp 8
jr nc,line_0815
ld hl,$401f
jr devam
;--------------------------------------------------------------;
; Scroll yapılacak satır 8-15 arasında ise
; ekran adresi $481f.
;--------------------------------------------------------------;
line_0815 cp 16
jr nc,line_1623
ld hl,$481f
jr devam
;--------------------------------------------------------------;
; Scroll yapılacak satır 16-23 arasında ise
; ekran adresi $501f.
;--------------------------------------------------------------;
line_1623 ld hl,$501f
devam ld (scrbase),hl
;--------------------------------------------------------------;
; Satır numarasına göre son kolonun adresini
; hesapla ve asıl ekran adresini elde et.
;--------------------------------------------------------------;
sla a
sla a
sla a
sla a
sla a
or l
ld (scrbase),a
;--------------------------------------------------------------;
ld b,tend-text ;text uzunluğu max.256
ld hl,text
nextchar push bc
push hl
;--------------------------------------------------------------;
; Okunan karakterin data adresini hesapla.
;--------------------------------------------------------------;
ld a,(hl)
ld hl,(23606)
ld de,0
loop01 ld b,8
loop00 inc de
djnz loop00
dec a
jr nz,loop01
add hl,de ;font data adresi
;--------------------------------------------------------------;
; Font datalarını kopyala.
;--------------------------------------------------------------;
ld b,8
ld de,fontdata
copy ld a,(hl)
ld (de),a
inc hl
inc de
djnz copy
;--------------------------------------------------------------;
; 8 ekran satırını 8 kez 1 pixel sola kaydır.
;--------------------------------------------------------------;
ld e,8
loop05 push de
ld hl,(scrbase) ;ekran satırının son adresi
push hl
pop ix
;--------------------------------------------------------------;
; 8 Ekran satırını 1 pixel sola kaydır.
;--------------------------------------------------------------;
ld c,4
ld iy,fontdata
loop04 push ix
push hl
;--------------------------------------------------------------;
; Font datasını 1 bit sola kaydır ve ekrana bas.
; O anki ekran satırını bir piksel sola kaydır.
;--------------------------------------------------------------;
ld b,32
ld a,(iy+0)
ld d,a
rl a
ld (iy+0),a
loop03 rl (hl)
dec hl
djnz loop03
pop hl
push hl
ld b,32
ld a,d
inc h
rl a
loop030 rl (hl)  ;nop
dec hl
djnz loop030

ld b,32
ld a,(iy+4)
ld d,a
rl a
ld (iy+4),a
loop031 rl (ix+$20)
dec ix
djnz loop031
pop ix
push ix
ld b,32
ld a,d
inc ixh
rl a
loop032 rl (ix+$20) ;nop
dec ix
djnz loop032
;--------------------------------------------------------------;
go pop ix
pop hl
inc iy
inc h
inc h
inc ixh
inc ixh
dec c
jr nz,loop04
;--------------------------------------------------------------;
; Scroll hızını ayarla.
; İstenirse sadece HALT komutları kullanılabilir.
;--------------------------------------------------------------;
ld de,5555
delay dec de
ld a,d
or e
jr nz,delay
; halt
; halt
;--------------------------------------------------------------;
pop de
dec e
jr nz,loop05
;--------------------------------------------------------------;
pop hl
inc hl
pop bc
djnz next
ret
next jp nextchar
;--------------------------------------------------------------;
line_nr defb 22 ;satır numarası
;--------------------------------------------------------------;
fontdata defb 0,0,0,0,0,0,0,0
scrbase defw 0
;--------------------------------------------------------------;
text defm " ...Herhangi bir satirda 1x2 "
defm "text scroll rutini 13-09-2015"
defm " FALAN FILAN INTER MILAN !'^+"
defm "%&/()=?_£#${[]}\|.;,:  "
;--------------------------------------------------------------;
tend end $8000
;==============================================================;
Başlık: Makine Dilinde Daire Çizdirmek
Gönderen: hades - 13 Eylül 2015, 22:59:58
Kod: [Seç]
;===============================================================;
; CIRCLES EXAMPLE ;
; 13-09-2015 / HADES ;
; UZUNLUK : 51 BYTE CODE ;
;===============================================================;

org $8000

call $0d6b ;ekranı sil
out (254),a
ld b,27
loop00 push bc
call circle
ld a,(yaricap)
sbc a,3
ld (yaricap),a
pop bc
djnz loop00
ret
;--------------------------------------------------------------;
circle ld a,(x_koor) ;x koordinat değeri
call $2d28
ld a,(y_koor) ;y koordinat değeri
call $2d28
ld a,(yaricap) ;r yarıçap değeri
call $2d28
call $232d ;daire çiz
ld hl,$2758
exx
ret
;--------------------------------------------------------------;
x_koor defb $7f
y_koor defb $50
yaricap defb $50

end $8000
;=============================================================;
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 14 Eylül 2015, 23:10:09
Bu son paylaştığın çember rutini ROM'u kullanıyor. Dolayısı ile Sinclair Basic diyebiliriz :D ve tebrikler, sbasic'deki en yavaş rutini bulabilmişsin :) Bu çizgi çizdirme yöntemi (söylenenin aksine yüzlerce farklı rutin gördüm şimdiye kadar) pek de hızlı sayılmaz ama eğrileri destekliyor. Aslında çizilen şekil bir daireden çok, bir eğri. Aynı rutini düz çizgiler çizmek için kullanılan DRAW komutu da paylaşıyor. Şöyle ki, normalde draw komutu bir noktadan diğerine düz bir çizgi çekerken, sonuna eklediğiniz opsiyonel bir parametre sayesinde eğri de çizebiliyor.

örnek:
1 PLOT 100,100
2 DRAW 50,50,30  <- buradaki 30 değeri çizginin düz değil çok çok eğrilmiş halidir ve üst üste birkaç çember çizer

Yani çizgi çizmenin bol fonksiyonlu ama çoooook yavaş bir yolu. Fakat, eğri çizmenin en güzel yolu Bresenham abimizin yöntemi. Çizgi çizmek isteyen herkes bu yöntemi ezberden bilmeli. Elimin altında kendi yazdığım bir kod yok, bu sebepten bir sonraki en iyi şeye siz çemberfili insanları yönlendireyim:

https://bitbucket.org/boriel/zxbasic/src/4dedae817cc97aec7ff25d787acc85ff8db69e77/library-asm/circle.asm?at=default&fileviewer=file-view-default

Bu boriel's basicde kullanılan Bresenham algoritması direkt compile edip çalıştırılabilecek birşey değil, lakin koordinatları buluyor ama noktalama için başka bir rutine ihtiyacı var, üşenmeyen onu da yazıp güzel bir çember çizdirebilir. Elbette ki çember çizmenin daha hızlı yöntemleri de var, ama bu tartışma akademik bir tabana kaymaya başladı, susuyorum :)



Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: witchdoktor - 16 Eylül 2015, 15:01:57
Elbette ki çember çizmenin daha hızlı yöntemleri de var, ama bu tartışma akademik bir tabana kaymaya başladı, susuyorum :)

İşin ilginci 8/16-bit bilgisayarlarda hep çember çizmenin nasıl olduğunu bulmaya çalışırız ama bir programda çember çizme gereksinimi çok istisnai bir durumdur; bir paint programı ya da benchmarking amaçlı değilse çember çizimi çok fuzulidir...
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 16 Eylül 2015, 18:49:22
Elbette ki çember çizmenin daha hızlı yöntemleri de var, ama bu tartışma akademik bir tabana kaymaya başladı, susuyorum :)

İşin ilginci 8/16-bit bilgisayarlarda hep çember çizmenin nasıl olduğunu bulmaya çalışırız ama bir programda çember çizme gereksinimi çok istisnai bir durumdur; bir paint programı ya da benchmarking amaçlı değilse çember çizimi çok fuzulidir...

Çemberi çizdirmek konusunda katılıyorum, belki bu sebepten CIRCLE komutunun yavaşlığı hiç rahatsız etmedi beni, demekki hiç lazım birşey değilmiş :) Ama ekranda dairesel hareketler yapan spritelar varsa küçük bir ihtimal de olsa işe yarayabilir gidecekleri yolun hesabı yapılması gerekiyor ve tablo tutmak için ram'de yer kalmadıysa.
Başlık: 1x1 Dıştan İçe Mirror Text Scroll
Gönderen: hades - 16 Eylül 2015, 22:44:16
Kod: [Seç]
;==============================================================;
; 1X1 MIRROR TEXT SCROLL - 1 (DIŞTAN İÇE);
;                 15-09-2015 / HADES                     ;
; UZUNLUK : 183 BYTE CODE + TEXT         ;
;==============================================================;
org $8000

;--------------------------------------------------------------;
; Borderi siyah yap.
;--------------------------------------------------------------;
xor a
out (254),a
again call main
jr again
;--------------------------------------------------------------;
; Scroll yapılacak satır numarasını al ve
; ekran adresini hesapla.
;--------------------------------------------------------------;
; Scroll yapılacak satır 0-7 arasında ise
; ekran adresi $401f.
;--------------------------------------------------------------;
main ld a,(line_nr)
line_0007 cp 8
jr nc,line_0815
ld hl,$401f
jr devam
;--------------------------------------------------------------;
; Scroll yapılacak satır 8-15 arasında ise
; ekran adresi $481f.
;--------------------------------------------------------------;
line_0815 cp 16
jr nc,line_1623
ld hl,$481f
jr devam
;--------------------------------------------------------------;
; Scroll yapılacak satır 16-23 arasında ise
; ekran adresi $501f.
;--------------------------------------------------------------;
line_1623 ld hl,$501f
devam ld (base_r),hl
ld (base_l),hl
;--------------------------------------------------------------;
; Satır numarasına göre son kolonun adresini
; hesapla ve asıl ekran adresini elde et.
;--------------------------------------------------------------;
sla a
sla a
sla a
sla a
sla a
or l
ld (base_r),a
sub $1f
ld (base_l),a
;--------------------------------------------------------------;
ld b,tend-text ;text uzunluğu max.256
ld hl,text
nextchar push bc
push hl
;--------------------------------------------------------------;
; Okunan karakterin data adresini hesapla.
;--------------------------------------------------------------;
ld a,(hl)
ld hl,(23606)
ld de,0
loop01 ld b,8
loop00 inc de
djnz loop00
dec a
jr nz,loop01
add hl,de ;font data adresi
;--------------------------------------------------------------;
; Font datalarını kopyala.
;--------------------------------------------------------------;
ld b,8
ld de,temp_r
copy_r ld a,(hl)
ld (de),a
inc hl
inc de
djnz copy_r

ld b,8
ld hl,temp_r
copy_l ld a,(hl)
ld (de),a
inc hl
inc de
djnz copy_l
;--------------------------------------------------------------;
; 8 ekran satırını 8 kez 1 pixel sola kaydır.
;--------------------------------------------------------------;
ld e,8
loop05 push de
ld ix,(base_r) ;ekran satırının son adresi
ld iy,(base_l) ;ekran satırının ilk adresi
;--------------------------------------------------------------;
; 8 Ekran satırını 1 pixel sola kaydır.
;--------------------------------------------------------------;
ld c,8
ld de,temp_r
ld hl,temp_l
loop04 push ix
push iy
;--------------------------------------------------------------;
; Font datasının 1 bit sola kaydır ve ekrana bas.
; O anki ekran satırını bir piksel sola kaydır.
;--------------------------------------------------------------;
ld b,16 ;32
ld a,(de)
rl a
ld (de),a
loop03_l rl (ix+0)
dec ix
djnz loop03_l
;--------------------------------------------------------------;
; Font datasının 1 bit sağa kaydır ve ekrana bas.
; O anki ekran satırını bir piksel sağa kaydır.
;--------------------------------------------------------------;
ld b,16 ;32
ld a,(hl)
rl a
ld (hl),a
loop03_r rr (iy+0)
inc iy
djnz loop03_r
;--------------------------------------------------------------;
pop iy
pop ix
inc de
inc hl
inc ixh
inc iyh
dec c
jr nz,loop04
;--------------------------------------------------------------;
; Scroll hızını ayarla.
; İstenirse sadece HALT komutları kullanılabilir.
;--------------------------------------------------------------;
ld de,4555
delay dec de
ld a,d
or e
jr nz,delay
; halt
; halt
;--------------------------------------------------------------;
pop de
dec e
jr nz,loop05
;--------------------------------------------------------------;
pop hl
inc hl
pop bc
djnz nextchar
ret
;--------------------------------------------------------------;
line_nr defb 23 ;satır numarası
;--------------------------------------------------------------;
base_r defw 0
base_l defw 0
temp_r defb 0,0,0,0,0,0,0,0
temp_l defb 0,0,0,0,0,0,0,0
;--------------------------------------------------------------;
text defm " ...Herhangi bir satirda 1x1 "
defm "mirror text scroll rutini "
defm "16-09-2015 / HADES"

;--------------------------------------------------------------;
tend end $8000
;==============================================================;
Başlık: 1x1 İçten Dışa Mirror Text Scroll
Gönderen: hades - 16 Eylül 2015, 22:47:51
Bir üstteki rutinde ufak bir değişiklikle scroll yönü değişiyor.

Kod: [Seç]
;==============================================================;
; 1X1 MIRROR TEXT SCROLL - 2 (İÇTEN DIŞA);
;                 15-09-2015 / HADES                     ;
; UZUNLUK : 182 BYTE CODE + TEXT         ;
;==============================================================;
org $8000

;--------------------------------------------------------------;
; Borderi siyah yap.
;--------------------------------------------------------------;
xor a
out (254),a
again call main
jr again
;--------------------------------------------------------------;
; Scroll yapılacak satır numarasını al ve
; ekran adresini hesapla.
;--------------------------------------------------------------;
; Scroll yapılacak satır 0-7 arasında ise
; ekran adresi $401f.
;--------------------------------------------------------------;
main ld a,(line_nr)
line_0007 cp 8
jr nc,line_0815
ld hl,$400f
jr devam
;--------------------------------------------------------------;
; Scroll yapılacak satır 8-15 arasında ise
; ekran adresi $481f.
;--------------------------------------------------------------;
line_0815 cp 16
jr nc,line_1623
ld hl,$480f
jr devam
;--------------------------------------------------------------;
; Scroll yapılacak satır 16-23 arasında ise
; ekran adresi $501f.
;--------------------------------------------------------------;
line_1623 ld hl,$500f
devam ld (base_r),hl
ld (base_l),hl
;--------------------------------------------------------------;
; Satır numarasına göre son kolonun adresini
; hesapla ve asıl ekran adresini elde et.
;--------------------------------------------------------------;
sla a
sla a
sla a
sla a
sla a
or l
ld (base_r),a
inc a
ld (base_l),a
;--------------------------------------------------------------;
ld b,tend-text ;text uzunluğu max.256
ld hl,text
nextchar push bc
push hl
;--------------------------------------------------------------;
; Okunan karakterin data adresini hesapla.
;--------------------------------------------------------------;
ld a,(hl)
ld hl,(23606)
ld de,0
loop01 ld b,8
loop00 inc de
djnz loop00
dec a
jr nz,loop01
add hl,de ;font data adresi
;--------------------------------------------------------------;
; Font datalarını kopyala.
;--------------------------------------------------------------;
ld b,8
ld de,temp_r
copy_r ld a,(hl)
ld (de),a
inc hl
inc de
djnz copy_r

ld b,8
ld hl,temp_r
copy_l ld a,(hl)
ld (de),a
inc hl
inc de
djnz copy_l
;--------------------------------------------------------------;
; 8 ekran satırını 8 kez 1 pixel sola kaydır.
;--------------------------------------------------------------;
ld e,8
loop05 push de
ld ix,(base_r) ;ekran satırının son adresi
ld iy,(base_l) ;ekran satırının ilk adresi
;--------------------------------------------------------------;
; 8 Ekran satırını 1 pixel sola kaydır.
;--------------------------------------------------------------;
ld c,8
ld de,temp_r
ld hl,temp_l
loop04 push ix
push iy
;--------------------------------------------------------------;
; Font datasının 1 bit sola kaydır ve ekrana bas.
; O anki ekran satırını bir piksel sola kaydır.
;--------------------------------------------------------------;
ld b,16 ;32
ld a,(de)
rl a
ld (de),a
loop03_l rl (ix+0)
dec ix
djnz loop03_l
;--------------------------------------------------------------;
; Font datasının 1 bit sağa kaydır ve ekrana bas.
; O anki ekran satırını bir piksel sağa kaydır.
;--------------------------------------------------------------;
ld b,16 ;32
ld a,(hl)
rl a
ld (hl),a
loop03_r rr (iy+0)
inc iy
djnz loop03_r
;--------------------------------------------------------------;
pop iy
pop ix
inc de
inc hl
inc ixh
inc iyh
dec c
jr nz,loop04
;--------------------------------------------------------------;
; Scroll hızını ayarla.
; İstenirse sadece HALT komutları kullanılabilir.
;--------------------------------------------------------------;
ld de,4555
delay dec de
ld a,d
or e
jr nz,delay
; halt
; halt
;--------------------------------------------------------------;
pop de
dec e
jr nz,loop05
;--------------------------------------------------------------;
pop hl
inc hl
pop bc
djnz nextchar
ret
;--------------------------------------------------------------;
line_nr defb 23 ;satır numarası
;--------------------------------------------------------------;
base_r defw 0
base_l defw 0
temp_r defb 0,0,0,0,0,0,0,0
temp_l defb 0,0,0,0,0,0,0,0
;--------------------------------------------------------------;
text defm " ...Herhangi bir satirda 1x1 "
defm "mirror text scroll rutini "
defm "16-09-2015 / HADES"

;--------------------------------------------------------------;
tend end $8000
;==============================================================;
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 20 Nisan 2022, 23:29:17
@hades İlerleme var mı? Yeni teknikler paylaşmayacak mısın bizimle? Hep ecnebilerle paylaşıyorsun örneklerini. Yerli ve milli ortamları da unutma. Belki @matahari 'den optimizasyon desteği de alırız.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 20 Nisan 2022, 23:35:57
Z80 olsun, ne olursa olsun mu, platform tercihi var mı bu başlıkta? Hani arada ben de bir şeyler karalayacak olursam nede karalayayım, onu bileyim en azından. :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 20 Nisan 2022, 23:40:52
Z80 olsun, ne olursa olsun mu, platform tercihi var mı bu başlıkta? Hani arada ben de bir şeyler karalayacak olursam nede karalayayım, onu bileyim en azından. :)
Süreklilik arz edecekse ayrı açmakta fayda var. Ama tek gecelik birşey ise burası da olur. Konu dallanırsa taşırız da. Çok da dert değil.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 20 Nisan 2022, 23:47:24
Nasıl başlasak peki? Kar mı yağdıralım? Kamerayı kar tanelerinden birine mi koysam değişiklik olsun diye? :D
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 20 Nisan 2022, 23:55:26
Kar tavsiye ederim zira Z80 dünyası için bir nevi Hello World demek  ;D
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 21 Nisan 2022, 09:09:52
Z80 olsun, ne olursa olsun mu, platform tercihi var mı bu başlıkta? Hani arada ben de bir şeyler karalayacak olursam nede karalayayım, onu bileyim en azından. :)

hadesin örnekleri zx spectrum örnekleri. Bu sebepten görüntü spectruma göre üretiliyor.

ama doğrusu itirazım yok, z80 tek başına daha güçlü gibi, bir sürü tek byte'lık zıplama komutu zx spectrum rom'una sıkıştığı için heba oluyor. Belki z80'i özgür bıraksak daha iyi bir makine bile tasarlayabileceğizdir :D
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 21 Nisan 2022, 12:16:49
Kaldığımız yerden ufak tefek kodlar paylaşmaya devam. Bir süredir farklı ekran silme rutinleri karalıyordum. 7-8 tane var. Bazen daha önce yazdığım rutinlerde optimizasyon yapıyorum veya farklı bir kod ile yeniden yazıyorum.
İlk örnek ekranı yukarıdan ve aşağıdan başlayarak ekranın ortasına doğru pixel satırları şeklinde siliyor.


Kod: [Seç]
;========================================
;    CLS ROUTINE #01-a
;   22.02.2022 / HADES
; CODE LENGHT: 107 BYTES
; (MAIN CODE : 89 BYTES)
;========================================
org $8000
;----------------------------------------
; setup 18 bytes
;----------------------------------------
setup ld hl,$4000
ld de,$4001
ld bc,6143
ld (hl),255 ; fill value
ldir
ld b,40
wait halt
djnz wait
;----------------------------------------
maincode ld b,$08
ld de,$4000
ld hl,$57e0
call common

ld b,$04
ld de,$4800
ld hl,$4fe0

common ld (top),de
ld (bot),hl

loop02 push bc
ld c,$08

loop01 ld b,32
xor a ;cls value
ld hl,(top)
ld de,(bot)

loop00 ld (hl),a
ld (de),a
inc hl
inc de
djnz loop00

halt

ld hl,(top)
inc h
ld (top),hl
ld hl,(bot)
dec h
ld (bot),hl
dec c
jr nz,loop01

ld bc,$f820
ld hl,(top)
add hl,bc
ld (top),hl

ld hl,(bot)
sbc hl,bc
inc hl
ld (bot),hl
pop bc
djnz loop02
ret
;----------------------------------------
top dw 0
bot dw 0
;----------------------------------------
  end $8000
;========================================

Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 21 Nisan 2022, 15:12:11
@hades ve @Ref

Bunları hızlıca denemek için en pratik Speccy emulator hangisi? En uyumlu olması falan değil de kodu deneyip sonuç görebileceğim. Hatta bunu bu başlığın ilk mesajını editleyip ekleyin de bence. Birkaç kaynak eki de olursa epey faydalı olur.

Bir de hades, bize arada soru da sorsana. Belki katılmak isteyenler olur. Hatta Z80 tips&tricks de öğretsene.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 21 Nisan 2022, 17:18:07
Ben az önce development platformumu kurdum. Ben ZXSpin'de kalmışım. Modern development tool chain diye aratınca emülatör olarak ZEsarUX tavsiye etti. Bazı gariplikleri var, her defasında "tekrar gösterme" dediğim halde çıkan popupları vs ama remote debugging için ayarları yerli yerinde gözüküyor.
Bu arada indirdiğim Visual Studio Code pluginleri bir tane de embedded emülatöre sahipler, doğrudan Visual Studio Code içinde de derleyip çalıştırabiliyorum projerleri.

Edit: Ekran görüntüsü ekledim.

ZEsarUX'u derlemekle uğraşmak istemeyenler için binaryler şu URL'den bulunabiliyor.

https://github.com/chernandezba/zesarux/releases

Assets kısmına tıklayın.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 21 Nisan 2022, 20:12:06
vscode güzel olmuş bunu nasıl oluşturacağımızı adım adım anlatabilmen mümkün müdür?
sanırım şurda bir benzeri var:

https://dotneteer.github.io/spectnetide/

edit:
önemli not: bu VS code tabanlı emülatörler demo kalitesinde ürün üretmek için gerekli keskinlikte değillermiş
şu anda demo yazmak için halen pasmo+specemu öneriyorum. En azından orjinal makinede çalışacağı garanti gibi olur.

zesarux'u yapan adam aktif olarak uğraşıyor, güzel emülatördür, ama gui rezalet geliyor bana. alışana iyi. Zamanlaması falan da %98 iyi. bildiğim kadarıyla bir tek HALT contention'u desteklemiyor, onu da bozmak çok zor, sorun yaratmıyor.

edit2:
ZX Spectrum zamanlama testlerini iliştirdim, kullandığınız emülatörde çalıştırıp deneyebilirsiniz.

FPGA testi çok zorlu bir test, onu geçen emülatörü time critical demo kodlamak için kullanabiliriz sanırım.
https://spectrumcomputing.co.uk/forums/viewtopic.php?t=3666
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: matahari - 21 Nisan 2022, 21:03:20
Bunları hızlıca denemek için en pratik Speccy emulator hangisi?

@Alcofribas, bu soruyu sadece Windows PC için değil, aynı zamanda Intel/Apple Silicon Mac için de sordun, değil mi? ;)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Alco - 21 Nisan 2022, 21:24:13
Bunları hızlıca denemek için en pratik Speccy emulator hangisi?

@Alcofribas, bu soruyu sadece Windows PC için değil, aynı zamanda Intel/Apple Silicon Mac için de sordun, değil mi? ;)
:) Evet evet... MAC ortamını da ihmal etmeden herkes bildiği platformu yazsın. Hatta bilhassa MAC ortamına ağırlık verelim.

@hades Sen sadece kendini yazdığın ortamı söylesen yeter. Bak mesela bana Amstrad için sorsan WinApe emulatörü (http://winape.net/) yükle derim fazla detaya girmeden. F6'ya bas ve Assembler'ı aç, kodunu yaz, sonra F9 ile compile et ve gerekince F8 ile debugging i de ihmal etme derdim.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 21 Nisan 2022, 21:31:56
vscode güzel olmuş bunu nasıl oluşturacağımızı adım adım anlatabilmen mümkün müdür?

Çok fazla benzerini gördüm. Benim ilerlediğim yol şu oldu. Önce şuradan ilk teknoloji isimlerini gördüm.

http://www.breakintoprogram.co.uk/computers/zx-spectrum/assembly-language/z80-development-toolchain

Sonra Visual Studio Code'un içindeki extensions bölümüne çeşitli extensionlar ekledim. O extensionları da VS Code kullanan bazı örnek z80 projelerinin config dosyalarından görüp denedim.

Ekte kırmızı ile işaretlediğim ikisi en önemlileri, syntax highlighting ve debugging için lazım olanlar. Diğerleri olmasa da olurduk tayfası. :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 21 Nisan 2022, 21:38:11
Bir tek alışmakta zorlandığım şey şu oldu.

Normalde 6502'den alışık olduğun hex kullanımı şu;
$ffff

CPC'de zar zor alıştığım hex formatı;
&ffff

Şimdi bu toolchain'de sjasmplus diye bir compiler kullanınca başıma açılan bela;
#ffff

Sharp nedir ya? CSS'de RGB color code kullanır gibi hissediyorum sürekli kendimi. :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 21 Nisan 2022, 21:47:42
Ben context+pasmo+specemu kullanıyorum. Context'te z80.chl dosyasını düzenledim. Z80 komutları, registerleri, flag ve conditions, pasmo komutları farklı renklerde gösteriliyor.

Geçenlerde Z80 komutları üç harfli olsa nasıl olur diye düşündüm. Mesela Ld yerine mov olacak. Halt - hlt gibi.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 21 Nisan 2022, 22:11:27

Şimdi bu toolchain'de sjasmplus diye bir compiler kullanınca başıma açılan bela;
#ffff

sjasmplus rusların sevdiği assembler. O yüzden biraz antin kuntin işler ve sanırım default olarak pentagona derliyor, switchleri spectruma ayarlamayı unutma. Pasmo her yola gelir. ister öyle kullan ister öbürü. Söylentiye göre sjasmplus pasmodan iyiymiş. Ama şu anda pasmo-sjasmplus dışında dişe dokunur ZX assembleri yok. Çok iyi z80 derleyiciler var ama bu ikisi zx spectrum dosya tipleri yaratabiliyorlar, basic headerleri falan ekleyebiliyorlar gerekirse basic bile yazabiliyorsun falan. Bunlardan hariç 7-8 tane daha derleyici var, ama isimleri bile aklımda değil, biri design design'in yazdığı o aklımda kalmış.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 21 Nisan 2022, 22:39:41
şu konuda fikri olan var mıdır?

[SAVESNA] RAM <0x4000-0x4001> will be overwritten due to 48k snapshot imperfect format.

Gerçekten de kod çalıştıktan sonra 4000/4001'i bozabiliyor. Böyle bilinen bir bug mı var snapshot formatında?

Çok da etkilemiyor, sonuçta normal binary'i yükletince düzgün çalışıyor. Sadece snapshot üzerinden çalışan sistemde bu sorun çıkıyor. Default'da NEX diye bir alternatif ile gelmişti, ben SNA'yı tercih ettim. Tekrar NEX'e mi geçsem acaba? O da şu Spectrum Next projesinin bir standardı mıdır nedir tam anlamadım gerçi.

Edit: Burada açıklanmış.
https://bitbandit.org/20161101/hacking-the-sjasmplus-z80-assembler/
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 22 Nisan 2022, 01:26:08
Sonunda TAP üretmeyi de öğrendim. Biraz daha ilerleyeyim, SJAsmPlus'ı merak edenler varsa tecrübelerimi paylaşacağım.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 22 Nisan 2022, 01:44:10
şu konuda fikri olan var mıdır?

[SAVESNA] RAM <0x4000-0x4001> will be overwritten due to 48k snapshot imperfect format.

Gerçekten de kod çalıştıktan sonra 4000/4001'i bozabiliyor. Böyle bilinen bir bug mı var snapshot formatında?


evet yanlış hatırlamıyorsam SNA formatı 80'lerin kartuşlarının ürettiği bir format olduğu için biraz sorunlu. sen freeze ettiğinde son kalınan PC'yi stack'e push ediyor. Dolayısı ile SP nerdeyse oraya 2 byte'lık Program Counter bilgisi yazılıyor. herşeyi yükledikten sonra RET işletiliyor ve program kaldığı yerden devam ediyor.
Bu işlem, eğer o bölgede bir data varsa orayı bozuyor elbette. Çoğunlukla zararsız bir işlem ama zamanında bu problemi kırılmayan oyunlar yapmak için kullanan oyunlar da var. O tür oyunları çift kasetli teyple kopyalıyorlardı :P
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 24 Nisan 2022, 20:58:30
Bunu demin yanlış başlığa göndermişim, silip tekrar buraya gönderdim, bilginize.

Şöyle bir durumla karşılaştım. Zannedersem programcıdan ziyade psikolog yardımı lazım bana. SjASMPlus kendini Assembler yerine Compiler sanmaya başladı sanırım. :)

Z80'e yeterince hakim olmadığım için zaman kazanmak adına bazı durumlarda dokümantasyona bakmayıp, deneme & yanılma ile ilerlediğim oluyor. En son optimizasyon için geri dönüp, tüm kodun üzerinden geçerim, tcycleları azaltırım diyordum. Ama SjASMPlus compiler gibi davranıp, normalde CPU'da yer almayan opcode parametrelerini aşağıdaki görseldeki gibi üç opcode'a derlemek gibi saçmalıklar yapıp, bir de bunlarla ilgili warning bile vermiyor, az önce fark ettim. Bu ciddi bir sıkıntı değil benim açımdan, zaten optimizasyon noktasına geçtiğimde hiç bir zaman source code'a güvenmem, her daim binary çıktısı üzerinden kontrol ederim. Ama açıkçası şaşırttı böyle davranıyor olması. Bana "add de, de" diye bir şey yok demiyor da hl'nin değerini de ile iki kez swap ederek hallediyor işi.

Sizin kullandığınız Assemblerlarda böyle şeyler yaşadığınız oldu mu? Z80 dünyasında normal kabul edilen bir şey midir yoksa SjASMPlus biraz amacını mı aşmış?

Kontrol ettiğimde proje açıklamalarında "cross-compiler" diye de geçiyor. Bir de özellik listesinde şöyle bir madde var.


Sanırım benim yaşadığım "and more" kısmına tekabül ediyor.

Edit: Adamlar daha geçen ay eklemişler bu özelliği. En azından warning verseymiş, compiler flaglerinden öyle bir şey açılabiliyor mu araştırıyorum şimdi.

31.3.2022 - 1.19.0
- added Amstrad CPC devices ("AMSTRADCPC464", "AMSTRADCPC6128") - by Oli Wilkinson
- added Amstrad CPC save snapshot and CDT (`SAVECPCSNA`, `SAVECDT`) - by Oli Wilkinson
- added `SAVE3DOS` (like SAVEBIN with +3DOS header)
- the deprecated "ok" warning suppression is removed, use "<warning-id>-ok" comment or -Wno-...
- new temporary label suffix syntax "_b" and "_f", enabling them for all expressions
- fix `--longptr` mode to keep 32b address when `DS 0` is used
- added fake instructions adc|add|sbc|sub de,bc|de|hl|sp
- dec|inc|pop|push will accept also single-comma multiarg in --syntax=a mode
- DUP/REPT will now accept also zero count (skipping the block)
- DEFL labels can be defined even as late as in last pass
- bugfixes (macros, listing, file names in errors, SLD reversepop data)

Edit 2:
--nofakes                Disable fake instructions (deprecated, use --syntax=F)

Ha şöyle... :)

Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 24 Nisan 2022, 22:39:07
Evet birçok assemblerde fake instructions özelliği var, pasmo'da olmadığı için ben hiç kullanmadım ama bazen ordan burdan kod arakladığımda bakıyorum hata alıyorum. Yani kullananlara rastladım.

Bu arada hazır girişmişken sana bir uyarı vereyim, eğer IX ve IY registerlerini kullanıyorsan "ula snow" hakkında bir araştırma yap, ekranda parazite neden olan durumlar var, emülatörünün de "ula snow" seçeneğini mutlaka aç.

Demo işlerini test için specemu dışında bir emülatör önermiyorum. Sonra yazdığın kod gerçek donanımda çalışmazsa şaşırma.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 24 Nisan 2022, 23:37:36
emülatörünün de "ula snow" seçeneğini mutlaka aç.

Ula ben de bu snow efektini nasıl yaptı diyordum, şimdi anlaşıldı. :D

Bu konuda iki seçenek var, snow harici genel bir "Enable ULA artifacts" seçeneği var, onu da açtım ben. Sanırım VIC'deki grey dots problemi gibi şeyler bunlar di mi?

Bkz: https://github.com/dirkwhoffmann/virtualc64/issues/395
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 25 Nisan 2022, 09:34:47
Daha önce farklı ekran silme rutinleri karaladığımı yazmıştım. Bu mesajda yine farklı bir ekran silme rutinini adım adım açıklamaya çalışacağım. İlk olarak Spectrum'un[ garip ekran adreslemesinden bahsedelim. Spectrum'un ekran belleği $4000-$57FF arasında yer alır ve 6144 byte uzunluğundadır. Ancak bu adresler lineer değildir. Yani "ben $4000'den başlayıp $57FF'e kadar her şeyi rahatça ekrana basarım" diyemiyoruz. Ekran 3 bloktan oluşur. Her blok kendi içinde 8 text satırı ve her text satırı da 8 pixel satırı olarak düzenlenmiştir. Yani bir ekran bloku 64 pixel satırından oluşur. Bir blok 2048 byte uzunluğundadır.
Bir pixel satırı 32 byte uzunluğundadır. İlk pixel satırı -ekranın en üstündeki- $4000-$401F arasındadır. Lineer olmayan ekran yapısı nedeniyle bir alttaki pixel satırı $4020 yerine $4100 adresinden başlar ve 8 pixel satırının son adresi $4700'dir. Başka bir deyişle bir karakter satırını oluşturan 8 pixel satırının adresleri arasında 256 byte fark vardır. Bir sonraki karakter satırının ilk pixel satır adresi ise $4020'dir. Bunu da şöyle ifade edelim. Karakter satırlarının aralarındaki adres farkı 32'dir.

0. karakter satırı
0. pixel satırı: $4000
1. pixel satırı: $4100
...
...
7. pixel satırı: $4700

1. karakter satırı
0. pixel satırı: $4020
1. pixel satırı: $4120
...
...
7. pixel satırı: $4720
...
...
7. karakter satırı
0. pixel satırı: $40e0
1. pixel satırı: $41e0
...
...
7. pixel satırı: $47e0

Bu ön bilgiden sonra silme rutinimizi tasarlamaya başlayabiliriz. Silme rutinimiz ekranı iki karakter genişliğinde kolonlar halinde yukarıdan aşağıya pixel satırlarını silecek. Rutinin çalışma adresi $8000 olsun. İlk olarak ekranı $FF ile doldurarak silme işleminin istediğimiz gibi olup olmadığını kontrol etmiş olacağız.

ld hl,$4000
        ld de,$4001
        ld bc,6143
        ld (hl),$ff
        ldir

araya biraz gecikme koyalım

        ld b,30
wait    halt
        djnz wait


Artık işleme başlayabiliriz. Ekranı temizlemek demek ekranın ilgili adresine 0 yazmak demektir. Bunun için xor a ile aküyü sıfırlayıp daha sonra ilgili adrese aküdeki değeri yazacağız. Ekran adresimizi tanımlayalım.

        xor a           ; aküyü sıfırla
        ld ix,$4000     ; ekran başlangıç adresi
        ld (ix+0),a     ; iki karakter genişliği şartımız olduğu için
        ld (ix+1),a     ; bir sonraki kolonu da siliyoruz


Şimdi bir alttaki pixel satırını silmemiz gerekiyor. Bunun için ix registerinde $4100 olması lazım. Yani bir önceki değerin 256 fazlası olmalı. Kısa bir özet geçeyim. Z80 her ne kadar 8 bitlik işlemci ve registerleri de buna bağlı olarak 8 bitlik olsa da registerler çift olarak kullanılabilir ve bu sayede 16 bitlik işlemler yapılabilir. Ayrıca Z80'in IX ve IY registerleri ise gerçek 16 bitlik registerlerdir. İşin güzel tarafı bu iki register ayrı ayrı low ve high registerlermiş gibi komutlara sahiptir. Ancak bu komutlar Z80'in standart komut listesinde yer almaz ve undocumented command olarak tanımlanmıştır.
Bu kısa bilgiden sonra LD IX,$4000 komutunu LD IXH,$40 - LD IXL,$00 olarak düşünebiliriz. Yapmamız gereken IXH kısmının $41 olması. Bunun için ise INC IXH komutunu kullanıyoruz. Eğer bu işlemi bir döngü içinde 8 kez yaparsak bir karakter satırını oluşturan 8 pixel satırını temizlemiş oluruz. Bunun için temizleme kısmında bir sayaç tanımlamamız gerekir. Bunun için de b registerini kullanacağız.
Sayacın başlangıç değeri 8 olmalı ki istediğimiz sayıda pixel satırını temizlemiş olalım. Daha sonra sayacı 1 azaltıp sayaç 0 olana kadar işlemleri tekrarlamalıyız. Bunun için ise sayaç olarak B registerini ve sadece B registerine özel DJNZ komutunu kullanacağız. Programın yeni hali şu şekilde olacaktır.


        xor a           ; aküyü sıfırla
        ld ix,$4000     ; ekran başlangıç adresi
loop00  ld b,8
        ld (ix+0),a     ; iki karakter genişliği şartımız olduğu için
        ld (ix+1),a     ; bir sonraki kolonu da siliyoruz
        inc ixh         ; ix=ix+256
        djnz loop00


İlk karakter satırnı oluşturan 8 pixel satırını temizledik. Artık bir sonraki karakterine geçebiliriz. Ancak bir sorun var. İkinci karakter satırının ilk pixel adresi $4020. İlk aklımıza gelen ix registerine $4020 vererek temizleme kısmını tekrar yazmak. Fikir güzel ama 24 ekran satırı için aynı işlemi yapmak gereksiz yere hafıza kullanmak demektir. Ne yapabiliriz? Temizleme rutinini ortak olarak kullanıp bir CALL komutuyla çağırmak. İlk çözüme göre önemli miktarda hafızadan tasarruf edebiliriz. Başka bir çözüm deneyebiliriz. Biraz matematik yapacağız.
İlk karakter satırı temizlendiğinde IX registerindeki değer artık $4800 olmuştur. Bizim istediğimiz IX'in $4020 olması. Yapmamız gereken $4800'den $4020 elde etmek. Bunun için iki yol var. İlk olarak $4800'den $07E0 çıkartabiliriz. Ben çıkartma işlemi yerine daha büyük bir sayı ile toplayıp aynı sonucu elde ediyorum. Sebebi ise IX komutu için çıkartma komutunun olmaması.
Bu toplama işlemini DE registerini kullanarak yapıyoruz.
8 karakter satırımız olduğu için aynı işlemi 8 kez yapmamız  ve bir sayaç kullanmamız lazım. Elimizdeki 8 bit registerlerden A ve B registerlerini kullandık. Yeni sayaç olarak C registerini kullanacağız. Sayaç değeri 8 olacak ve B registerinden önce kullanmak zorundayız. Daha sonra sayacı 1 azaltıp 0 olup olmadığına bakmalıyız. 0 ise işimiz bitmiş demektir. Sayaç her azaltılıp döngüye girildiğinde bir sonraki karakter satırında işlem yapan sayaç çalışmaya başlar. Bu arada HALT komutunu kullanarak hızımızı bira düşüreceğiz. Yoksa 1 sn'de ekran temizlenecektir.

        halt
        ld de,$f820
        add ix,de
        dec c
        jr nz,loop01


Kodun başına LD C,8 satırını ekleyeceğiz. Kod aşağıdaki hale gelecek.

        xor a           ; aküyü sıfırla
        ld ix,$4000     ; ekran başlangıç adresi
        ld c,8          ; karakter satır sayacı
loop01  ld b,8          ; pixel satır sayacı
loop00  ld (ix+0),a     ; iki karakter genişliği şartımız olduğu için
        ld (ix+1),a     ; bir sonraki kolonu da siliyoruz
        inc ixh         ; ix=ix+256
        djnz loop00     ; pixel sayacını 1 azalt, 0 değilse işlemleri tekrarla
        halt            ; biraz bekle
        ld de,$f820     ; Bir sonraki karakter satırını
        add ix,de       ; hesapla
        dec c           ; karakter satır sayacını 1 azalt
        jr nz,loop01    ; 0 değilse işlemleri tekrarla


Buraya kadar olan kısımda bir ekran blokunu temizlemiş olduk. Artık bir sonraki ekran blokuna geçebiliriz. Ekran bloklarının adres farkı 2048'dir. IX registerine baktımızda $4100 olduğunu görürüz. Bu sayıya $0700 ekleyerek bir sonraki blok adresini elde ederiz. Ekran 3 bloktan oluştuğu için blok sayacı tanımlıyoruz ve başlangıç değeri 3 olmalı. Yeni blok adresini elde ettikten sonra sayacı azaltıp işlemleri tekrarlayacağız.
Kodun yeni hali.

        xor a           ; aküyü sıfırla
        ld ix,$4000     ; ekran başlangıç adresi
        ld l,3          ; blok sayacı
loop02  ld c,8          ; karakter satır sayacı
loop01  ld b,8          ; pixel satır sayacı
loop00  ld (ix+0),a     ; iki karakter genişliği şartımız olduğu için
        ld (ix+1),a     ; bir sonraki kolonu da siliyoruz
        inc ixh         ; ix=ix+256
        djnz loop00     ; pixel sayacını 1 azalt, 0 değilse işlemleri tekrarla

        halt            ; biraz bekle
        ld de,$f820     ; Bir sonraki karakter satır
        add ix,de       ; adresini hesapla
        dec c           ; karakter satır sayacını 1 azalt
        jr nz,loop01    ; 0 değilse işlemleri tekrarla

        ld de,$0700     ; bir sonraki blok
        add ix,de       ; adresini hesapla
        dec l           ; blok sayacını 1 azalt
        jr nz,loop02    ; 0 değilse işlemleri tekrarla


Buraya kadar olan kısımda ekranın soldan iki kolonunu yukarıdan aşağıya doğru pixel pixel sildik. Şimdi bu işlemi tüm kolonlar için yapmak gerekiyor. Specrum ekranı 32 kolondan oluştuğu ve biz de iki kolon kullanarak işlem yaptığımız için kolon sayacımızı 16 olarak tanımlıyoruz. IX registerine bakıp iki sonraki kolon için işlemlerimizi yapıp ve gerekli komutları ekleyip silme rutinimizi bitiriyoruz.


        org $8000

        ld hl,$4000
        ld de,$4001
        ld bc,6143
        ld (hl),$ff
        ldir
        ld b,30
wait    halt
        djnz wait

cls     xor a           ; aküyü sıfırla
        ld ix,$4000     ; ekran başlangıç adresi
        ld h,16         ; kolon sayacı
loop03  ld l,3          ; blok sayacı
loop02  ld c,8          ; karakter satır sayacı
loop01  ld b,8          ; pixel satır sayacı
loop00  ld (ix+0),a     ; iki karakter genişliği şartımız olduğu için
        ld (ix+1),a     ; bir sonraki kolonu da siliyoruz
        inc ixh         ; ix=ix+256
        djnz loop00     ; pixel sayacını 1 azalt, 0 değilse işlemleri tekrarla

        halt            ; biraz bekle
        ld de,$f820     ; Bir sonraki karakter satır
        add ix,de       ; adresini hesapla
        dec c           ; karakter satır sayacını 1 azalt
        jr nz,loop01    ; 0 değilse işlemleri tekrarla

        ld de,$0700     ; bir sonraki blok
        add ix,de       ; adresini hesapla
        dec l           ; blok sayacını 1 azalt
        jr nz,loop02    ; 0 değilse işlemleri tekrarla

        ld de,$e802     ; iki sonraki kolon
        add ix,de       ; adresini hesapla
        dec h           ; kolon sayacını 1 azalt
        jr nz,loop03    ; 0 değilse işlemleri tekrarla

        ret             ; mutlu son

        end $8000


Not: Eğer HALT komutunu DJNZ komutundan önce kullanırsanız ekran silme işlemi daha yavaş olur.

Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 25 Nisan 2022, 14:32:39
Bu arada herkes sürekli ZX Spectrum'un video memory layout'u için çok garip, kötü falan diyor. Halbuki bence çok çok iyi. Üç nedeni var.

1) Zaten satır başlarını tablodan okuyabiliyoruz. Bu durumda istediği kadar saçma bir adreslemeye sahip olsun, hatta hafızanın dört bir yanına serpiştirilmiş olsun, bizi etkilemiyor.
2) Satır başından sonrası yana doğru sıralı gidiyor ki bu ne demek? Polygon rutinlerinin son derece hızlı olabilmesi demek. Henüz en hızlı yöntem hangisi diye incelemedim ancak stack bölgesi olarak polygonun yatay çizgisinin başını işaret edecek olursak sanırım push push push şeklinde çizim yapabiliriz.
3) Ekranın üç bölgeye ayrılmış olması da o kadar kötü bir şey değil. Logo alanı, diğer grafik öğeleri buna göre tasarlanıp, efekt çizim alanı için kendi içinde tutarlı bir alan belirlenebilir. Dediğim gibi tablo kullanıldığında bunun da bir önemi kalmıyor ancak ben video memory layout'u beğendim. Saçma gibi gözüken ama aslında Commodore 64'ünküne tercih edeceğim biçimde.

Tabii dez avantajı yok değil. Yukarıdan aşağı XOR fill yapmak gerektiğinde kodun tamamen unrolled yazılması gerekir. Yine de @Ref'den de duymuştum bu lafı, @hades de şimdi benzerini söylemiş. O "garip adresleme" aslında o kadar da garip ya da dez avantajlı sayılmaz. Sağa doğru ilerledikçe sıralı gitmesi çoğu durumda yeterli.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: ssg - 25 Nisan 2022, 21:47:29
CPC'de zar zor alıştığım hex formatı;
&ffff

BASIC'te evet ama assembly'sinde (MAXAM, GENA3 vs) yine "#" kullanılıyordu. GW-BASIC'in de hex syntax'i "&H"tir mesela. Sanırım BASIC'likle alakalı.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 25 Nisan 2022, 22:09:21
Bu arada herkes sürekli ZX Spectrum'un video memory layout'u için çok garip, kötü falan diyor. Halbuki bence çok çok iyi. Üç nedeni var.

1) Zaten satır başlarını tablodan okuyabiliyoruz. Bu durumda istediği kadar saçma bir adreslemeye sahip olsun, hatta hafızanın dört bir yanına serpiştirilmiş olsun, bizi etkilemiyor.
2) Satır başından sonrası yana doğru sıralı gidiyor ki bu ne demek? Polygon rutinlerinin son derece hızlı olabilmesi demek. Henüz en hızlı yöntem hangisi diye incelemedim ancak stack bölgesi olarak polygonun yatay çizgisinin başını işaret edecek olursak sanırım push push push şeklinde çizim yapabiliriz.
3) Ekranın üç bölgeye ayrılmış olması da o kadar kötü bir şey değil. Logo alanı, diğer grafik öğeleri buna göre tasarlanıp, efekt çizim alanı için kendi içinde tutarlı bir alan belirlenebilir. Dediğim gibi tablo kullanıldığında bunun da bir önemi kalmıyor ancak ben video memory layout'u beğendim. Saçma gibi gözüken ama aslında Commodore 64'ünküne tercih edeceğim biçimde.

Tabii dez avantajı yok değil. Yukarıdan aşağı XOR fill yapmak gerektiğinde kodun tamamen unrolled yazılması gerekir. Yine de @Ref'den de duymuştum bu lafı, @hades de şimdi benzerini söylemiş. O "garip adresleme" aslında o kadar da garip ya da dez avantajlı sayılmaz. Sağa doğru ilerledikçe sıralı gitmesi çoğu durumda yeterli.

16 bitlik HL registerine göre ayarlamışlar, inc h yapınca bir satır aşağı iniyorsun, inc l yapınca bir sütun yana gidiyorsun. o şikayetler genelde sprite basmakla ilgili, özellikle ekranı 3 parçası arasında geçiş yapacaksan sıkıntı oluyor, dediğin gibi onu da tablo ile hallediyorsun. Sonuçta o layout spectrumun özelliklerinden biri, oric'inki biraz saçma gelir bana ama o da oric'e özgü bir görüntü üretiyor, appleii'nin yeşilli pembeli görüntüsü bir ayrı görsel. Sonuçta o dönemin bütün bilgisayarları kendine has bir görsel üretiyor sadece o layout'un ekranda temsili yüzünden.

Ama birkaç şikayetimiz var layoutla ilgili, ama dediğin gibi, o kadar da kötü değil.


@hades kodun tamamı varsa ekleyebilir misin? parça parça anlatmışsın ama bir arada da bitmiş hali gibi bir asm dosyası kolay denemek için iyi oluyor.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 26 Nisan 2022, 03:50:31
Bitmap converter'ımı da yazdım, sorunsuz çalışıyor. Ancak şöyle bir durumla karşılaştım emülatörde. Gerçek cihaz olmadan deneyemiyorum da. Hatırlıyorum @hades'in 256 bytelarından birinde de border koyu tonlarda çıkmıştı, @hades 7DX Party'de bana emülatörden bir ayar yaptırmıştı. Sanırım benzer bir durumla karşı karşıyayım.

Şimdilik sadece 8 açık renk tonunu kullandım. Visual Studio Code içindeki plugin olarak gelen emülatör'de düzgün görünüyor renkler. Ama ZX Spin'de saçmalıyor biraz. Aşağıda ikisini de attachlıyorum. Bu durumu bana açıklayabilir misiniz? Yani gerçek cihazda nasıl görünüyor, ZX Spin neden böyle bir şey yapıyor? Başta init etmeyi unuttuğum bir şeyler mi var? Ben sadece 4000 ve 5800'e transfer ediyorum datayı, başka bir şey yaptığım yok an itibariyle.

Edit: Renkleri düzelten ayarı bulup, onu da ekledim mesaja. Ancak işte sorum gerçek 48k/128k cihazlarda ne oluyor? Bu ayar gerçek cihazda hangi durumda ortaya çıkıyor? Hakim değilim konuya.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 26 Nisan 2022, 04:36:35
Bitmap converter scriptimi şuradan yayınladım. Henüz sadece 8 açık renk palete göre çıktı verebiliyor. Daha geliştireceğim, geliştirdikçe buraya push ederim.

https://github.com/c64skate/zx-spectrum-bitmap-converter
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 26 Nisan 2022, 09:42:04
Alıntı
@hades kodun tamamı varsa ekleyebilir misin? parça parça anlatmışsın ama bir arada da bitmiş hali gibi bir asm dosyası kolay denemek için iyi oluyor.

@Ref mesajın sonunda kodun tamamı var zaten.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 26 Nisan 2022, 11:47:41
Edit: Renkleri düzelten ayarı bulup, onu da ekledim mesaja. Ancak işte sorum gerçek 48k/128k cihazlarda ne oluyor? Bu ayar gerçek cihazda hangi durumda ortaya çıkıyor? Hakim değilim konuya.

Abi tekrar uyarıyorum, specemu dışında bir emülatör önermiyorum. zx spin'den kaçınmanı öneriyorum, zamanının iyi emülatörüydü ama 10 senedir güncellenmiyor, onu yapan adam sıfırdan başlayıp specemu'yu yazdı sonra.

Ula64 ek bir modern donanım (modern dediğim yine 20 sene oldu ahah, ama sayılmaz) o seçeneği kapalı tutuyorsun.

gerçek 48K/128K cihazlarda bildiğin göz yakan fosforlu renkler var. Register şu şekil 3 bit 8 normal renk ink + 3 bit 8 normal renk paper + 1 bit bright renk + 1 bit flash efekti. (Evet pc'de bright modlar daha canlı görünüyor ama, BORDER alanında bright kullanılmadığı için ana hat tasarımında normal tonları tercih ediyoruz genelde, brightlar yerine göre kullanılır).

Ula64 modu palet oluşturuyor, ve oradaki attribute byte indeksine göre boyuyor hücreyi. Ula64 eski oyunları da hiçbir müdahaleye gerek bırakmadan başka renklerle gösterebildiği için güzel hibrid bir format, fakat bunu gerçek donanımda görmek için makineden ULA'yı söküp yeriene SLAMula adında bir fpga takman gerekiyor. O yüzden emülatörler dışında yaygınlaşmadı. Dolayısı ile ulaplus, ula+, ula64 görünce o seçeneği kapatıyoruz.

 Ama ula color ramping'i aç, o gerçek spectrum davranışıdır. O da şu, ula koyu bir renkten açık bir renge anında değişemiyor, pixeller arası garip bir değişim oluyor voltaja göre, onu her spectrumda görürsün. Ama varla yok arası bir efekt aslında, büyük ekran tv'lerde RF bağlantıda daha belirgin oluyor. Ekte foto koyuyorum, pixellerin sağ tarafında hafif bir aydınlanma var. Bu efekti kullanan bir iki demo var, ama emülatörlerde hakkını vererek izleyemiyorsun.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 27 Nisan 2022, 21:02:20
Hatasıyla, sevabıyla ilk çalışan versiyon. :)

Şimdi biraz adam ve optimize etmem lazım. Sonrasında paylaşırım maceralarımı.

Edit: Emülatörlerle uğraşmak istemeyenlere kolaylık olsun diye link ekledim.

http://speccy.akaydin.com/
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: matahari - 27 Nisan 2022, 21:39:01
Hatasıyla, sevabıyla ilk çalışan versiyon. :)

"Deniz sakinken dümeni herkes tutar, gerçek kaptan fırtınalı havada belli olur" misali, emektar ZX Spectrum’a yazdığın daha ilk ürünle ustalığını konuşturmuşsun. Harikasın @Skate! 8)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 27 Nisan 2022, 22:39:03
"Deniz sakinken dümeni herkes tutar, gerçek kaptan fırtınalı havada belli olur" misali, emektar ZX Spectrum’a yazdığın daha ilk ürünle ustalığını konuşturmuşsun. Harikasın @Skate! 8)

Çok teşekkür ederim @matahari, bu sözleri bir z80 gurusundan duymak benim için çok değerli. :)
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 27 Nisan 2022, 23:24:25
Eline sağlık @Skate. Başlangıç böyleyse ilerleyen zamanlarda yapabileceklerin kimbilir nasıl olur?

Efektin kod uzunluğu ve hız bakımından 6510 versiyonu arasında bir karşılaştırma yapman mümkün mü?
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 28 Nisan 2022, 02:12:04
Bilmeyenler açısından da belirteyim, @hades ile yaş farkımız olsa da 90larda aynı scene grubunda yer alarak scene maceramıza başladık. 25 seneyi aşkın bir geçmişimiz olduğu için samimi hitap ediyorum İsmail'e, yoksa tabii ki abimdir. :)

Eline sağlık @Skate. Başlangıç böyleyse ilerleyen zamanlarda yapabileceklerin kimbilir nasıl olur?

Teşekkür ederim İsmail. Sadece yorumun için değil, böyle genel ve davetkâr bir başlık açarak Z80 programlamaya beni çeken faktörlerden biri olduğun için de ayrıca teşekkür ederim.

Efektin kod uzunluğu ve hız bakımından 6510 versiyonu arasında bir karşılaştırma yapman mümkün mü?

Bu soru başkasından gelse detaylı açıklamaya çalışırım ama sen hem 6502 hem Z80 ASM'ye hakimsin, üzerine donanımcısın. Yani bana sorarsan zaten bildiğin soruyu sormuşsun.

Mimarileri çok farklı iki işlemci oldukları için 6502 ve Z80'i kod uzunluğu açısından kıyaslamayı şu aşamada doğru bulmuyorum. Söz konusu olan efekt plot rutini olduğu zaman kapladıkları kod alanları, kullandıkları tablo uzunlukları çok farklı değil. Aslında bu konuda çok daha net konuşabilirdim. Ama Z80'e hakim değilim, 6502 ile doğdum sayılır. Yani şimdi "Z80'de aynı kod daha çok yer kaplıyor" gibi bir beyanda bulunacak olsam, büyük ihtimalle benim Z80'deki acemiliğimden kaynaklanan yanıltıcı bir beyan olur. Bir de Z80'e ve / veya ZX Spectrum'a özel bu işi yapmanın daha doğru yolları olabilir. Ben henüz o yolları keşfedebilmiş değilim. O yüzden kodu bildiğim kalıplarla yazdığımda sonuç çok da farklı olmuyor.

Hıza gelince şu şekilde bir benchmarking yapılabilir diye düşünüyorum. Belli işlevlerin tek bir frame içerisinde yüzde kaç işlemci gücü yediği. Örnek veriyorum, 256 plot'u silme rutinini ölçmüştüm, %7.22 CPU yiyor. Ancak silme rutinine yardımcı olmak için plot rutininin içine dahil edilmiş kısmı da sayarsak, o kısım %3.97 CPU harcıyor. Yani toplamda %11.19 gibi bir CPU'yu silme rutini harcıyor. C64'de %7.22 dediğim kısma karşılık gelen %5.2'ye düşüyor. Daha hızlı gibi gözüküyor ilk bakışta. Ama diğer %3.97'ye karşılık gelen plot rutininin içindeki kısım ise çok daha büyük oluyor. Ama yine toplamda devasa bir fark oluşmuyor sonuçta.

Peki bu hesap kitabı yapıyorum da neden detayları ya da kaynak kodu paylaşmıyorum? Çünkü hala öğrenme aşamasındayım. İki gün sonra "yahu ben ne saçmalamışım" diyeceğim şeyi örnek gibi paylaşmayı doğru bulmuyorum. Biraz daha kod içime sinsin, elbette ki yukarıdaki sayıları nasıl hesapladığımla beraber detaylarına girerim.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 28 Nisan 2022, 17:27:43
Hatasıyla, sevabıyla ilk çalışan versiyon. :)

Şimdi biraz adam ve optimize etmem lazım. Sonrasında paylaşırım maceralarımı.

Edit: Emülatörlerle uğraşmak istemeyenlere kolaylık olsun diye link ekledim.

http://speccy.akaydin.com/

oooh subdomain bile açmışsın :D Gerisi gelir herhalde :D
matahariye katılıyorum, ustalığını gösteriyorsun. Senden daha azını da beklemezdim zaten.
bir tek şu emülatördeki ula+ sorununu halletmen gerek bence.  snapshot yükletiyorsun sanırım, jsSpeccy bile ula+ ekran açmış.

Biraz da spectrum öveyim o zaman, Spectrumun güzel tarafılarından biri kolay giriş yapabiliyor olmak. Basit yapısı sayesinde bir sürü şey öğrenmek gerekmiyor, bir iki nazı var, sonra dümeni nereye tutacağını seçmek kalıyor. Emülatörü bol, geliştirme ortamı çeşitli. Her yola geliyor.

şimdi bir de @memrah gelse de spectrum ortamı şenlense :D
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Skate - 28 Nisan 2022, 21:35:09
bir tek şu emülatördeki ula+ sorununu halletmen gerek bence.  snapshot yükletiyorsun sanırım, jsSpeccy bile ula+ ekran açmış.

jsSpeccy default ayarlarında, snapshot değil TAP kullanıyorum. HTML source'una bakarsan görebilirsin zaten.

Yeri gelmişken kodun alakası kalmadı ilk paylaştığım versiyonla. CPU kullanımı %90'lardan %70'lere geriledi. Hala mıncıklıyorum kodu, Z80 trickleri öğreniyorum.

Kod: [Seç]
emu = JSSpeccy(document.getElementById('jsspeccy'), {zoom: 2, sandbox: false, machine: 48, autoStart: true, autoLoadTapes: true, openUrl: 'tap/first.tap' })
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: MuzafferB - 09 Aralık 2022, 13:50:25
download (lütfen kurulum kısmını da okuyun):
9.7MB Zip dosyası ZxToolchain Windows XP/7/8 (http://arda.kisafilm.org/fish/get/serve.php?b=zxtoolchain-retrojen.zip&d=24)
Hocam dosyayi indiremedim, hala duruyor mu acaba?
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 27 Nisan 2023, 01:20:08
download (lütfen kurulum kısmını da okuyun):
9.7MB Zip dosyası ZxToolchain Windows XP/7/8 (http://arda.kisafilm.org/fish/get/serve.php?b=zxtoolchain-retrojen.zip&d=24)
Hocam dosyayi indiremedim, hala duruyor mu acaba?
@MuzafferB
bunu görmemişim.
evet dosya duruyor. fakat artık sunucumuz güvenli https kullandığı için adresin başını düzeltmek gerekiyor:

Yani yeni adres şöyle olacak:

https://arda.kisafilm.org/fish/get/serve.php?b=zxtoolchain-retrojen.zip&d=24 (https://arda.kisafilm.org/fish/get/serve.php?b=zxtoolchain-retrojen.zip&d=24)

Diğer bağlantıyı da güncelledim.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: Ref - 27 Nisan 2023, 01:47:48
Bu arada @Skate 'in kullandığı VsCode gibi modern bir text editöre henüz alışamadım. :D debuggerler falan iç içe, güzel birşey, fakat bir taraftan beceremedim de diyebiliriz.

Ama vscode'un güzelliklerinden de faydalanmak istedim, özellikle eski toprak context'te bulunmayan özellikler, örneğin bir kelimeyi seçtiğinizde onu kod içerisinde başka nerelerde kullanılmış gösteriyor olması gezinmeyi epey hızlandırıyor. Neyse sistemi aynı tutup editörü vscode'a nasıl çıkaracaksınız derseniz şöyle bir yöntem izledim ben.

1. VsCode'u kurun, çalıştırın. ctrl+shift+x basın ve pasmo aratın, kurun.
2. Ctrl+shift+P tuşuna basınca bir satır açılıyor, oraya "Preferences: Open Keyboard Shortcuts (JSON)" yazıyorsunuz ve seçiyorsunuz. Klavye kestirmeleri config dosyası geliyor.
3. boş dosya gelecektir belki sadece köşeli parantezler vardır, onu silin, şu kodu yapıştırın ve sonra ctrl+s ile kaydedin:
Kod: [Seç]
[
    {
        "key": "f9",
        "command": "workbench.action.tasks.runTask",
        "args": "compile"
    },
    {
        "key": "f10",
        "command": "workbench.action.tasks.runTask",
        "args": "run"
    }
]
4. şimdi projeniz için boş bir klasör oluşturun, örneğin klasörünüz masa üzerinde "zxprojeleri" olsun. (ileride 6.basamağı yapamayanlar için: ben bunu manuel olarak yaptım. klasörünüze ".vscode" diye bir klasör oluşturup içine boş bir "tasks.json" dosyası oluşturun. Böylece klasörü açtığınızda tasks hazır olacak)
5. vscode ile file>open folder seçin ve bu klasörü açın.
6. şimdi yukarıda f9 f10 tuşları için bir tasks.json dosyası oluşturmamız gerekiyor. Ctrl+Shift+P basın ile bu sefer "Tasks: Configure Task" yazın ve "Create tasks.json file from template" seçin, şablonlar arasından  "Others" seçin. (NOT. 4.basamakta elle oluşturduysanız sadece yandan tasks.json'u seçin)
7. şimdi şu kodu tasks.json dosyasına ekleyin ve kaydedin:
Kod: [Seç]
{
    "version": "2.0.0",
    "tasks": [
      {
        "label": "compile",
        "type": "shell",
        "command": "D:\\zxtoolchain-retrojen\\ConTEXT\\pasmo.exe",
        "args": [
            "-v",
            "--tapbas",
            "${file}",
            "${fileDirname}/${fileBasenameNoExtension}.tap"
        ],
        "group": "build",
        "presentation": {
          "reveal": "silent",
          "panel": "new"
        },
        "problemMatcher": [],
        "options": {
          "cwd": "${workspaceFolder}"
        }
      },
      {
        "label": "run",
        "type": "shell",
        "command": "D:\\zxtoolchain-retrojen\\ConTEXT\\SpecEmu.exe",
        "args": [
          "${fileDirname}/${fileBasenameNoExtension}.tap"
        ],
        "group": "test",
        "presentation": {
          "reveal": "silent",
          "panel": "new"
        },
        "problemMatcher": [],
        "options": {
          "cwd": "${workspaceFolder}"
        }
      }
    ]
  }
 

bu kurulumda zx-toolchain'in D:\zxtoolchain-retrojen\ olarak kurulduğunu varsaydım. başka bir yerde ise ona göre bunu düzenlersiniz. çift \\ slashlere dikkat.

tüm dosyaları kaydedin. vscode'u kapatıp açın.
F9- dosyanızı kaydeder ve pasmo ile compile eder.
F10-dosyanızı specemu üzerinde çalıştırır.

Örneğin test etmek için,
1. klasörünüzü vscode > open folder seçerek açın.
2. klasörünüzde vscode içinde yeni bir dosya oluşturun  örnek "test.asm"
3. yeni dosyanın içinde dosya tipini soran bir metin görürseniz oradaki linke tıklayarak "pasmo" olarak seçin.
şu metni yapıştırın:

Kod: [Seç]
org 32768
ld hl,16384
ld de,16385
ld (hl),144
ld bc,256
ldir
di
halt
end 32768

şimdi F9'a basın. dosya derlenecek. ardından F10'a basın.
 

ekranda üstteki specemu görüntüsü varsa herşey yolundadır.


Elbette ek olarak skate'in önerdiği eklentileri de kurun derim.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: MuzafferB - 28 Nisan 2023, 22:13:05
Tesekkurler!

download (lütfen kurulum kısmını da okuyun):
9.7MB Zip dosyası ZxToolchain Windows XP/7/8 (http://arda.kisafilm.org/fish/get/serve.php?b=zxtoolchain-retrojen.zip&d=24)
Hocam dosyayi indiremedim, hala duruyor mu acaba?
@MuzafferB
bunu görmemişim.
evet dosya duruyor. fakat artık sunucumuz güvenli https kullandığı için adresin başını düzeltmek gerekiyor:

Yani yeni adres şöyle olacak:

https://arda.kisafilm.org/fish/get/serve.php?b=zxtoolchain-retrojen.zip&d=24 (https://arda.kisafilm.org/fish/get/serve.php?b=zxtoolchain-retrojen.zip&d=24)

Diğer bağlantıyı da güncelledim.
Başlık: Ynt: Z80 Makine diline meraklı olan?
Gönderen: hades - 20 Mayıs 2023, 10:45:26
Hafızadaki bir ekran görüntüsünü yukarıdan aşağıya sütunlar halinde ekran belleğine transfer eden kısa bir rutin.
Önce bir karakterlik alanı transfer edip sonra attr bilgisini kopyalıyor. Halt komutlarını arttırarak gecikmeyi ayarlayabilirsiniz.

Kod: [Seç]
;=============================================;
; SCREEN TRANSFER ROUTINE #1                  ;
; 14.05.2023 - HADES/RET                      ;
; CODE LENGHT: 120 BYTES + screen data        ;
;=============================================;
org $8000
;---------------------------------------------;
maincode ld hl,screen+6144
ld (color),hl
ld hl,$5800
ld (attr),hl

ld ix,screen
ld iy,$4000
ld h,32
loop03 ld l,3
loop02 ld c,8
loop01 ld b,8
loop00 ld a,(ix+0)
ld (iy+0),a
inc ixh
inc iyh
djnz loop00
   
push hl
ld de,32
ld hl,(color)
ld a,(hl)
add hl,de
ld (color),hl

ld hl,(attr)
ld (hl),a
add hl,de
ld (attr),hl
pop hl

ld de,$f820
call newadr

dec c
jr nz,loop01

ld de,$0700
call newadr

dec l
jr nz,loop02

ld de,$e801
call newadr

push hl
ld hl,(attr)
ld de,$fd01
add hl,de
ld (attr),hl

ld hl,(color)
add hl,de
ld (color),hl
halt
halt
pop hl
dec h
jr nz,loop03

uloop jr uloop

newadr add ix,de
add iy,de
ret
;---------------------------------------------;
color dw 0
attr dw 0
;---------------------------------------------;
screen incbin "uridium_ekran.bin"
;---------------------------------------------;
end $8000
;=============================================;
[/font]

  [ You are not allowed to view attachments ]
  [ You are not allowed to view attachments ]