Zx Spectrum Kodlama Örnekleri
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.