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

0 Üye ve 4 Ziyaretçi konuyu incelemekte.

Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 209
    • The Blog of Mert Börü
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #45 : 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 ;)

Çevrimdışı Skate

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

Ç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 #47 : 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.

Çevrimdışı Skate

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

Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 209
    • The Blog of Mert Börü
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #49 : 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.

Ç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 #50 : 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...

Çevrimdışı Skate

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

Çevrimdışı hades

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

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Spectrum'da IRQ + BASIC ?
« Yanıtla #53 : 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?


Çevrimdışı Ref

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

Çevrimdışı nightlord

  • RAAT
  • Tedavideki Retromanik
  • *
  • İleti: 389
    • Night Network
Ynt: Z80 Makine diline meraklı olan?
« Yanıtla #55 : 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) ş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.

Çevrimdışı hades

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

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Karakter setini deviriyoruz.
« Yanıtla #57 : 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

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ekranı 1 pixel sola kaydırmak.
« Yanıtla #58 : 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

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ekranı 1 pixel sağa kaydırmak.
« Yanıtla #59 : 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