Gönderen Konu: Z80 Makine diline meraklı olan?  (Okunma sayısı 104457 defa)

0 Üye ve 6 Ziyaretçi konuyu incelemekte.

Çevrimdışı memrah

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 188
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #15 : 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.

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2882
  • Advanced User Simulator
    • ae unutmadan
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #16 : 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

Çevrimdışı Alco

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2133
  • "Kahraman olmak, dürüst olmaktan kolaydır" Luigi P
    • Sizin Amstrad
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #17 : 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'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 :)

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2882
  • Advanced User Simulator
    • ae unutmadan
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #18 : 18 Ocak 2014, 09:29:42 »
Ya da girişelim, sonra Ref ayıklar ve düzenler mi diyoruz :)

Girişin!

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #19 : 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.

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #20 : 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)

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2882
  • Advanced User Simulator
    • ae unutmadan
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #21 : 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/

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/  (birazdan retrojen etkinlikleri menüsüne eklenecektir)


Bu arada hades destan yazmış, bu iyi bir kaynak olacak gibi. Acaba bir wiki mi kursak?

Çevrimdışı Adamın Biri

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 170
    • Sadece bir müze...
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #22 : 20 Ocak 2014, 08:32:58 »
Hades, Z80 Türkiye dergisi mi geliyor yoksa?

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 175
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #23 : 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... :)

Çevrimdışı Alco

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2133
  • "Kahraman olmak, dürüst olmaktan kolaydır" Luigi P
    • Sizin Amstrad
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #24 : 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

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. Ondan sonra diyelim ki WinApe ü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 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 ve Gate Array konuları var. Aklında olsun CPC'de 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.

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #25 : 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.


Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Karakter setiyle oynayalım :)
« Yanıtla #26 : 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

Çevrimdışı ozayturay

  • Retroman
  • ***
  • İleti: 76
  • Commodore Forever
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #27 : 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
http://www.retrodergi.com - http://www.e-turay.com

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

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

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2882
  • Advanced User Simulator
    • ae unutmadan
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #28 : 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

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

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)

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #29 : 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 :)