Zx Spectrum Kodlama Örnekleri

Retrojen Wiki sitesinden
Gezinti kısmına atla Arama kısmına atla

Sıkça Sorulan Sorular

Soru 1 (HADES): 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?

Cevap 1 (REF): 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 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: 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)


Soru 2 (İLKER): Örnek kodlardan biri ekrandaki resmi dikey olarak ters çeviriyor (Vertical Flip). Ancak ben bunu denemek için ekranda bir oyundan resim olsun istiyorum bunu yapabilir miyim?

Cevap 2 (MEMRAH): Soyledigini yapmanin bir suru yolu var. En basitlerinden bahsedeyim. ZX Spin kullandigini varsayarak, herhangi bir SCR dosyasini Spin'in emulasyon penceresine cekersen zaten icerigini spectrum'da 16384'ten itibaren ekran bellegine yukler. Elimizde bir tane SCR dosyası olsun. SCR dosyasini bir kenara (ornegin masa ustune) alıyoruz. Uzerinde calistigin kodu assemble et. Daha sonra eger 128 modunda isen EDIT menusunden SCREEN moduna gecmeni tavsiye ederim ki editor surekli ekrani silmeye kalkmasin. Daha sonra SCR dosyasini SPIN'in ana penceresi uzerine surukle ve birak... Resim ekranda... Daha sonra RANDOMIZE USR XXXXX ile kodu calistirabilirsin..

Diger yollar, oyunlarin TAP dosyasinin icine tape browser ile girip SCREEN$ dosyasini 16384 ile 16384+6912 arasina yuklemek, vs.

(istedigin oyunun TAP dosyasini indir, Spin'de Tape Browser'da ac, uzunlugu 6912 olan dosya ekran dosyasidir, bunu bul, LOAD "" CODE 16384,6912 yaz ve TAPE' i baslat)

Açıklamalı Örnek Kodlar

HADES ÖRNEK 01 - HAFIZADA 4K'LIK BİR BÖLGEYİ TEMİZLEYEN BİR RUTİN:

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

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

Açıklaması:

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 sınırlı degildir.

LDIR genel olarak son derece kullanisli bir komuttur.

DJNZ (Decrease and Jump if Not Zero):
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



HADES ÖRNEK 02 - VERTICAL MIRROR CHAR SET:
-------------------------------;
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 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
  djnz loop00 ;İşlem 8 kez yapılıncaya kadar tekrarla
  ld (iy+0),c ;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
     
  org $8100  
newchar    
  end $8000  


HADES ÖRNEK 03 - HORIZONTAL MIRROR CHAR SET:
-------------------------------;
SPECTRUM FONT - 02
20-01-2014
Horizontal mirror char set ( Program 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  


HADES ÖRNEK 04 - SPECTRUM KARAKTER SETİNİ 90 DERECE SOLA YATIR:
-------------------------------;
SPECTRUM FONT - 03
20-01-2014
Program 35 byte
-------------------------------;
  org $8000 ;Program $8000(32768)den başlıyor
  ld ix,$3d00 ;Romdaki karakter seti başlangıç adresi
  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  


HADES ÖRNEK 05 - EKRANI BİR PIXEL SOLA KAYDIRMAK:
-------------------------------;
BIR PIXEL SOLA KAYDIRMA
-------------------------------;
  org $8000 ;Program $8000(32768)den başlıyor
  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  


HADES ÖRNEK 06 - EKRANI BİR PIXEL SAĞA KAYDIRMAK:
-------------------------------;
BIR PIXEL SAĞA KAYDIRMA
-------------------------------;
  org $8000 ;Program $8000(32768)den başlıyor
  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  


HADES ÖRNEK 07 - HORIZONTAL FLIP SCREEN:
-------------------------------;
HORIZONTAL FLIP SCREEN
10-01-2009 hades/ret
-------------------------------;
  org $8000 ;Program $8000(32768)den 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  



HADES ÖRNEK 08 - VERTICAL FLIP SCREEN:
-------------------------------;
VERTICAL FLIP SCREEN
10-01-2009 hades/ret
-------------------------------;
  org $8000 ;Program $8000(32768)den başlıyor
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  


HADES ÖRNEK 09 – SCREEN STRECHER:
-------------------------------;
SCREEN  STRECHER
23-02-2014 / HADES / 255 byte code + text
-------------------------------;
  org $8000 ;Program $8000(32768)den başlıyor
main call $0d6b ;CLS command
  ld a,2 ;(Screen) 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 "Scr HADES"  
  end $8000  


HADES ÖRNEK 10 – SCREEN EFFECT:
-------------------------------;
SCREEN  EFFECT
09-03-2014 / HADES / CODE + TEXT 155 BYTE
İlk ekran satırında bir efekt
-------------------------------;
  org $8000 ;Program $8000(32768)den başlıyor
     
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 "09.03.2014- HADES"  
     
endmsg end $8000  


HADES ÖRNEK 11 – 8x8 TEXT:
-------------------------------;
8x8 TEXT
04-07-2014 / HADES
CODE + TEXT 104 BYTE
-------------------------------;
  org $8000 ;Program $8000(32768)den başlıyor
     
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  
loop1 ld b,8  
loop0 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  


HADES ÖRNEK 12 – 8x8 SCROLL:
-------------------------------;
8x8 SCROLL
10-07-2014 / HADES
CODE + TEXT 153 BYTE
-------------------------------;
  org $8000 ;Program $8000(32768)den başlıyor
     
main call $0d6b ;CLS command
  ld a,2 ;Screen 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"  
  defm "10-07-2014 "  
textend    
  end $8000  


HADES ÖRNEK 13 – EKRAN GENİŞLETİCİ:
-------------------------------;
EKRAN GENİŞLETİCİ
03-08-2014 / HADES
123 bytes code
-------------------------------;
  org $8000 ;Program $8000(32768)den başlıyor
  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  


Ayrıca Bakınız

Kategori:Z80 İşlemci Komutları | Z80 Bayrakları | category:Z80 İşlemcisi Özellikleri

Kaynakça

Bu başlık İlker Görkem tarafından derlenmiştir.

Hades | Ref | ilkerg