Gönderen Konu: CPC'de Assembler ile imtihanım...  (Okunma sayısı 27003 defa)

0 Üye ve 1 Ziyaretçi konuyu incelemekte.

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #15 : 01 Aralık 2018, 12:14:37 »
Kod: [Seç]
;-------------------------------------------------------;
; CPC RUTINI #02 - EKRAN EFEKTI ;
; EKRANI BAS ASAGI CEVIRME ;
; 01-12-2018 / HADES ;
; PROGRAM UZUNLUGU 59 BYTE ;
;-------------------------------------------------------;
org &8000

ld ix,&c000
ld hl,&ff80

ld b,25
loopxx push bc
push hl
push ix

ld c,4
loop01 ld b,80
loop00 ld a,(ix+0)
ld d,a
ld a,(hl)
ld (ix+0),a
ld a,d
ld (hl),a
inc ix
inc hl
djnz loop00
ld de,&07b0
add ix,de
ld de,&0850
sbc hl,de
dec c
jr nz,loop01

pop ix
pop hl
pop bc
ld de,80
sbc hl,de
add ix,de
djnz loopxx
ret

Çevrimdışı Fero

  • RAAT
  • Retroman
  • *
  • İleti: 34
  • guy.brush
    • Ferhat Tanman
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #16 : 01 Aralık 2018, 13:13:13 »
Benzer yollardan geçmekte olan biri olarak bu hissiyatının assembler'ın öğrenme eğrisinin dik olmasından kaynaklandığını söylemek istedim. Başlangıçta koda baktığında hiç bir şey anlamıyorsun. Tek tek komutları çözsen bile kodun bütünü bir şey ifade etmiyor. Sonra yavaş yavaş desenler oluşmaya başlıyor. Ancak belli bir etkinliğe ulaştıktan sonra olaylar değişiyor. Sabır lazım yani.

Bunu okuduktan sonra daha da bir motive oldum :) Sabırlıyımdır. Boşa kürek çekmediğimi bildiğim sürece üşenmem.


wizofwor harika bir tespit yapmış, konu ancak bu kadar güzel özetlenebilirdi.

Asıl sıkıntı benim bulabildiğim kaynakları anlamakta biraz zorlanmam. Daha çok temel şeyleri anlamadan "ben ekrana resim basıcam" diye girmem hata oldu :)

Ekrana resim basma hedefinize ulaştığınıza göre;

Bu aşamada kod yazmaya ara verip, yavaş yavaş Z80 işlemcisinin mimarisini (Amstrad'ın değil, sadece işlemcinin mimarisini!) ve içerdiği komutları tanımanızda fayda var. Zilog Z80 CPU User Manual'ı tavsiye ederim. İlk okuduğunuzda her şeyi anlayamamanız gayet doğal. Sakın moralinizi bozmayın, tekrar tekrar okudukça zaman içerisinde parçalar yerine oturmaya başlayacaktır. Kendinizi hazır hissettiğinizde kodlamaya geri dönebilirsiniz.

Son olarak,
  • kod yazım disiplinini korumak,
  • takibi güç "data overwrites code" türü hatalara izin vermemek için org direktiflerinin küçükten büyüğe doğru sıralanmasını sağlamak,
  • gelecekte bu sayfayı sizden başka Z80 programcılarının da referans olarak kullanabileceğini göz önüne almak,
amacıyla, Assembly kodumuza 'küçük mutlu ağaçlar' ekleyelim. ;)

Valla çiçek gibi oldu kod :) Açıkcası bir süredir Unreal Engine 'da hazırladığım bazı screen efektleri shader olarak yazabilmek için HLSL 'e sarmıştım ancak cpc ile uğraştığım şu kısa aralık bile bana kat kat daha zevkli geldi. Korkunç derecede zor görünmesine rağmen iyi kötü bir sonuca ulaşıldığında bir o kadar da tatmin edici. Artık bunun peşini kolay kolay bırakmam gibi görünüyor. Verdiğiniz bilgilerden ziyade, vakit ayırıp şu kodu düzenlemeniz bile benim için altın değerinde. :)

@hades abi zaten senin elinden birşey kurtulmuyor. Volkan senin bu işe sarmana ayrıca sevinecek :)
"Never pay more than 20 bucks for a computer game."

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
CPC'de karakter seti değiştirme hakkında.
« Yanıtla #17 : 01 Aralık 2018, 22:05:48 »
Daha önce Spectrum için yazdığım karakter seti değiştirme kodlarını CPC için düzenlemeye karar verdim.
Öğrendiğim kadarıyla cpc'de karakter seti lower romda $3800-$3fff adresleri arasında. lower rom disable edildiğinde tuşlara basınca ekrana bir şey yazılmaması gerekiyor veya -ram devrede olduğu için- o anda font datalarını okuduğu adreste abuk subuk değerler olabileceği için ekranda karışık bir şeyler olması gerekiyor.

org &8000

di
ld hl,&c9fb
ld (&0038),hl

call &b909    ;lower romu disable et
ei
ret


call komutu yerine doğrudan out komutunu mu kullanmak gerekiyor yoksa?

Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 208
    • The Blog of Mert Börü
Ynt: CPC'de karakter seti değiştirme hakkında.
« Yanıtla #18 : 02 Aralık 2018, 00:10:26 »
Daha önce Spectrum için yazdığım karakter seti değiştirme kodlarını CPC için düzenlemeye karar verdim.

Amstrad CPC ailesi bu konuda çok esnek. Hem Assembly seviyesinde hem de BASIC içerisindeki SYMBOL ve SYMBOL AFTER komutları yardımıyla karakter setini dilediğinizce değiştirebilirsiniz.

Amstrad CPC 6128 User Manual





Ek referanslar:

http://www.cpcwiki.eu/forum/programming/modify-the-font-appearance/

https://www.sean.co.uk/books/amstrad/amstrad4.shtm

call komutu yerine doğrudan out komutunu mu kullanmak gerekiyor yoksa?

Bu sorunun yanıtı, yapmak istediğiniz işi bitirdikten sonra 'geri döneceğiniz yere' bağlı.

Eğer Lower ROM’u disable edip, tüm işleriniz bittikten sonra;
  • RET komutu ile BASIC’e geri dönecekseniz, bu durumda firmware üzerinden CALL yapmanızda fayda var. Bu işlem sonunda ROM’a ait son state A içerisinde saklanır. Lower ROM’u tekrar enable etmek için, A’ya eski değerini yükleyip CALL &B906 yapmanız yeterli olur. - (Hatırlatmakta fayda görüyorum; CALL &B909 ile Lower ROM’u disable etmeniz, tamamen iptal ettiğiniz anlamına gelmez. Firmware’den yapacağınız herhangi bir CALL, Lower ROM’u tekrar geri getirecektir!)
  • BASIC’e asla geri dönmeyecekseniz (bkz: intro/demo/oyun türü kodlar), bu durumda OUT kullanmanızda ve Lower ROM’u sonsuza dek kapatmanızda fayda var.
Eğer amacınız sadece karakter setini değiştirmekse, ROM ile ilgili hiçbir işlem yapmanıza gerek yok. Bu işi BASIC yardımıyla kolaylıkla halledebilirsiniz.

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2866
  • Advanced User Simulator
    • ae unutmadan
Ynt: CPC'de karakter seti değiştirme hakkında.
« Yanıtla #19 : 02 Aralık 2018, 13:22:55 »
Daha önce Spectrum için yazdığım karakter seti değiştirme kodlarını CPC için düzenlemeye karar verdim.

Amstrad CPC ailesi bu konuda çok esnek. Hem Assembly seviyesinde hem de BASIC içerisindeki SYMBOL ve SYMBOL AFTER komutları yardımıyla karakter setini dilediğinizce değiştirebilirsiniz.
...
Eğer amacınız sadece karakter setini değiştirmekse, ROM ile ilgili hiçbir işlem yapmanıza gerek yok. Bu işi BASIC yardımıyla kolaylıkla halledebilirsiniz.

öhö öhhö... Akışı bölmiyim diye kendimi tutmaya çalıştım, ama konuyu spectruma bağlama şansı bulunca duramıyorum biliyorsunuz. Sanırım matahari de benim gibi aynı soruyu soruyor kafasında... "Spectrum için yazdığım karakter seti değiştirme kodları" acaba ne iş yapıyordu?

(edit: araştırdım buldum, sanırım bu programı kastetmiş: http://retrojen.org/pano/index.php?topic=539.msg4244#msg4244 )

Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 208
    • The Blog of Mert Börü
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #20 : 03 Aralık 2018, 16:08:51 »
Link için teşekkür ederim Ref.

Anladığım kadarıyla 'karakter setini değiştirmek' ile kastınız, karakter setini sıfırdan oluşturmak (ya da başka bir set ile değiştirmek) değil, mevcut set üzerinde değişiklikler yapmak. O zaman, benzer bir örnek teşkil etmesi açısından, hades hocamın Spectrum için yaptığını Amstrad için yapalım.

Ekteki kod, Amstrad karakter setindeki 'A' (büyük a) harfini ters çeviriyor. Lower ROM, port, vs. gibi karmaşık işlere girmiyorum. Firmware kullanarak karakter setini dump etmek dışında, gerisi tamamen standart Z80 kodu. İşlem bittikten sonra kod BASIC'e geri dönüyor. Bu aşamadan itibaren BASIC'teki büyük A harfinin ters basıldığını test edebilirsiniz.

Umarım yeterince basit bir örnek yazmayı becerebilmişimdir. Size yol göstermesi açısından koda bolca açıklama ekliyorum. Takıldığınız bir yer olursa, lütfen sormaktan çekinmeyiniz.

Kod: [Seç]
LET CONST_Char_A = 65
LET CONST_TotalBytesPerChar = 8
LET CONST_Char_A_Offset = CONST_Char_A * CONST_TotalBytesPerChar

LET ADDR_CHAR_FULLSET = &5000
LET ADDR_CHAR_A = ADDR_CHAR_FULLSET + CONST_Char_A_Offset

;----------------------------------------------------------------
; CODE Segment
; Invert character 'A' - chr$(65)
;----------------------------------------------------------------

org &4000

;------ Dump full character set -------------------------

ld de,0 ; First character in the table
ld hl,ADDR_CHAR_FULLSET ; Addr to dump character map data
call &bbab ; Firmware Call = TXT SET M TABLE

;------ Perform inverting! ------------------------------

ld hl,ADDR_CHAR_A ; 1st line addr of char 'A'
ld de,ADDR_CHAR_A + 7 ; 8th line addr of char 'A'
ld c,4 ; Number of times to swap
; Step#1 = Swap 1st and 8th lines
; Step#2 = Swap 2nd and 7th lines
; Step#3 = Swap 3rd and 6th lines
; Step#4 = Swap 4th and 5th lines

Invert: ld a,(hl) ; A = top line
ex af,af' ; save A (by swapping A and A')
ld a,(de) ; A' = bottom line
ld (hl),a
ex af,af' ; restore A (by swapping A and A')
ld (de),a
inc hl ; next upper line
dec de ; previous lower line
dec c
jr nz,Invert

ret


Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #21 : 03 Aralık 2018, 19:20:57 »
Teşekkürler @matahari ustad. Verdiğiniz ipucu çok işime yaradı.

Programı winape'nin Assemblerinde yazıp derliyoruz. Emülatör ekranında call 32768 yazarak çalıştırıyoruz ve yeni karakter seti emrinizde. Eğer tekrar call 32768 yazarsanız karakter seti normale dönüyor.

Son olarak karakter setini sadece Bank1 ve Bank2 içerisinde gösterebiliyoruz. Örnekte rutinin bittiği yerde karakter seti başlıyor.


Kod: [Seç]
;-------------------------------------------------------;
; CPC RUTINI #03 - YENI KARAKTER SETI ;
; VERTICAL MIRROR KARAKTER SETI ;
; 03-12-2018 / HADES ;
; PROGRAM UZUNLUGU 58 BYTE ;
;-------------------------------------------------------;
org &8000

; LET ADDR_CHAR_FULLSET = &6000
;------ Dump full character set -------------------------

ld de,0 ; First character in the table
ld hl,new_font ;ADDR_CHAR_FULLSET ; Addr to dump character map data
call &bbab ; Firmware Call = TXT SET M TABLE

                ld      ix,new_font ;&6000;Yeni karakter seti baslangic adresi
                ld      de,2048         ;Karakter setinin byte sayaci
loop01          ld      b,8             ;Okunan byte icin islem sayaci
                ld      a,(ix+0)        ;Setten bir bayt okuyoruz
loop00          rl      a               ;7. biti "elde" bitine yukluyoruz
                                        ;diger bitler sola kayiyor
                rr      c               ;C registeri bit dondurme icin kullanylacak
                                ;"Elde" bitini 7. bite yukluyoruz diger bitler saga kayiyor
                djnz    loop00          ;islemi 8 kez tekrarliyoruz
                ld      (ix+0),c        ;C registerindeki degeri yeni set icin ram'e yaziyoruz.
                inc     ix              ;Set adresini 1 arttir
                dec     de              ;Bayt sayacini 1 azalt
                ld      a,d
                or      e
                jr      nz,loop01       ;0 olmadiysa islemleri tekrarla
ret
new_font
end

Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 208
    • The Blog of Mert Börü
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #22 : 03 Aralık 2018, 20:28:49 »
Teşekkürler @matahari ustad. Verdiğiniz ipucu çok işime yaradı.

Rica ederim, hades hocam. İşinize yaramasına çok sevindim. 8)

karakter setini herhangi bir yerde gösterebiliyoruz.

Maalesef hayır!

Neden?

Z80 işlemci birim zamanda 64K (16K x 4 Bank) adresleyebilir.

Bank#0: &0000-&3FFF - (RAM)
Bank#1: &4000-&7FFF - (RAM)
Bank#2: &8000-&BFFF - (RAM)
Bank#3: &C000-&FFFF - (RAM)

Amstrad için konuşursak;

CALL komutu ile herhangi bir firmware fonksiyonu çağırdığınızda, Z80 geçici olarak Lower ROM için Bank#0 ve Upper ROM için Bank#3’ü READ ONLY olarak aktive eder. Bu durumda 64K’lık hafıza haritası şu şekilde değişir:

Bank#0: &0000-&3FFF - (Lower ROM)
Bank#1: &4000-&7FFF - (RAM)
Bank#2: &8000-&BFFF - (RAM)
Bank#3: &C000-&FFFF - (Upper ROM)

Bu sebeple, karakter setimiz (ve firmware çağırımından sonra hayatta kalmasını istediğimiz diğer kod ve veriler) sadece Bank#1 ve Bank#2 (ortadaki 32K) içerisinde olmalıdır. İşte bu yüzden intro/demo/oyun yazarken firmware’i kapatıp, 64K’nın tamamına hakim oluyoruz. ;)

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #23 : 03 Aralık 2018, 21:24:05 »
Ufak bir sorum olacak.
Alıntı
Amstrad için konuşursak;

CALL komutu ile herhangi bir firmware fonksiyonu çağırdığınızda, Z80 geçici olarak Lower ROM için Bank#0 ve Upper ROM için Bank#3’ü READ ONLY olarak aktive eder. Bu durumda 64K’lık hafıza haritası şu şekilde değişir:

Bank#0: &0000-&3FFF - (Lower ROM)
Bank#1: &4000-&7FFF - (RAM)
Bank#2: &8000-&BFFF - (RAM)
Bank#3: &C000-&FFFF - (Upper ROM)


Bank#3 adreslerinde aynı zamanda Screen Memory var. CPC ilk açılışta/resette Upper Rom devrede mi? Yoksa sistem daha sonra 16K Lower Rom + 48K Ram olarak mı düzenleniyor?

İlk paylaştığım kodlarda ekran belleğinden okuma yaparak işlem yapıyordum. Bu durumda Upper Rom'un devre dışı gözüküyor.

Sanırım $8000-$BFFF arasındaki bir kod içinde geçen CALL komutu donanımsal olarak takip ediliyor ve adres Bank0 veya Bank3 aralıklarında ise otomatik olarak romlar aktif hale getiriliyor. (Z80'den çıkan /M1 sinyali="0" ve Databus =&CD ise bu kontrol işlemi yapılabilir gibi.)

Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 208
    • The Blog of Mert Börü
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #24 : 03 Aralık 2018, 22:09:35 »
Bank#3 adreslerinde aynı zamanda Screen Memory var.

Doğru.

CPC ilk açılışta/resette Upper Rom devrede mi? Yoksa sistem daha sonra 16K Lower Rom + 48K Ram olarak mı düzenleniyor?

Amstrad CPC ailesi ilk açılış/Reset sırasında, hafızayı

Bank#0: &0000-&3FFF - (Lower ROM)
Bank#1: &4000-&7FFF - (RAM)
Bank#2: &8000-&BFFF - (RAM)
Bank#3: &C000-&FFFF - (Upper ROM)

şeklinde düzenliyor. Bu sebeple ekranda çok kısa bir süre için garbage data (aslında Upper ROM'u) görüyoruz.

Sanırım $8000-$BFFF arasındaki bir kod içinde geçen CALL komutu donanımsal olarak takip ediliyor ve adres Bank0 veya Bank3 aralıklarında ise otomatik olarak romlar aktif hale getiriliyor.

Açılış/Reset prosedürünün sonunda, &A600-&BFFF adresleri arasında 'Firmware Adres Tablosu' oluşturuluyor. Bu tablo sayesinde, herhangi bir firmware CALL yapılması (örneğin CALL &BB18 çağırılması) durumunda, geçici olarak hangi Bank'in aktive edileceği ve o Bank'te hangi adrese Jump edileceği önceden bilinmiş oluyor.

Açılış/Reset prosedürü tamamlanır tamamlanmaz ROM'lar devre dışı kalıyor, 64K'nın tamamı

Bank#0: &0000-&3FFF - (RAM)
Bank#1: &4000-&7FFF - (RAM)
Bank#2: &8000-&BFFF - (RAM)
Bank#3: &C000-&FFFF - (RAM)

şeklinde kullanıcıya teslim ediliyor. Ekrana Copyright bilgileri + 'Ready' yazılıyor, ardından da BASIC devreye giriyor.

İlk paylaştığım kodlarda ekran belleğinden okuma yaparak işlem yapıyordum. Bu durumda Upper Rom'un devre dışı gözüküyor.

Siz açmadığınız, yani bir firmware CALL yapmadığınız ve/veya BASIC'te yazılmış bir kodu RUN etmediğiniz sürece, Lower/Upper ROM hep kapalı.

Firmware çağırımlarının çok hantal olması, her CALL yüzünden tekrarlanan Bank switching sebebiyle kaybedilen zamandan kaynaklanıyor. Özellikle Upper ROM'un aktive edilmesini gerektiren firmware CALL'lar, ekran hafızası ile çakışması sebebiyle, görüntünün flicker etmemesi için ekran çizimi tamamlandıktan ve henüz başlamamışken çağırılıyor. Eğer bu koşul sağlanmamışsa, koşul sağlanana dek bekleniyor! İşte bu yüzden mümkün olduğunca firmware kullanmamaya (ve hatta tamamen kapatmaya) özen gösteriyoruz.

* NOT: Yukarıdaki bilgilere ek olarak, Amstrad CPC 6128'de ROM Bank sayısının 2 değil 3 olduğunu belirtmekte fayda var. Üstte anlattığım her şey birebir geçerli, sadece fazladan 1 ROM Bank daha var.


Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #25 : 05 Aralık 2018, 19:48:59 »
Verdiğiniz bilgiler için çok teşekkürler.
CPC'nin tasarımı gerçekten ilginçmiş. Bu arada interrupt rutinine baktım. interrupt rutini firmware adres tablosuna jump yapıyormuş. Her ne kadar hafıza tamamen Ram gibi gözükse bile restart adresleri yüzünden &0000'dan itibaren kod yazmak riskli olabilir. Bu durumda şöyle bir sorum olacak.
Yazdığımız kodda herhangi bir firmware call olsun veya olmasın, kodumuzu yazmaya başlayabileceğimiz en küçük adres kaçtan başlıyor?
Ek soru : Yıllar önce elo elektronik dergisinde amstrad ile ilgili bir yazıda "300 Hz interrupt" ifadesi geçiyordu. Böyle bir şey var mı?

Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 208
    • The Blog of Mert Börü
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #26 : 06 Aralık 2018, 00:22:20 »
Verdiğiniz bilgiler için çok teşekkürler.

Rica ederim.

Yazdığımız kodda herhangi bir firmware call olsun veya olmasın, kodumuzu yazmaya başlayabileceğimiz en küçük adres kaçtan başlıyor?

Normal koşullarda, 64K'lık hafızanın &0170-&A600 adresleri arasında kalan bölümünü, BASIC + Assembly language ile kod yazmak amacıyla kullanabilirsiniz. &C000-&FFFF arasındaki ekran hafızasına da her zaman erişebilirsiniz.

Amstrad CPC ailesinde hafızanın en kritik bölgesi, &0000-&003F adresleri arasında kalan ve 'RST Area' olarak bilinen 64 byte'lık alandır. Interrupt'lar açık ve BASIC devrede olduğu sürece bu minik bölgeye dokunmamakta fayda var.

Ancak, şöyle bir istisna söz konusu; Eğer,
  • Tüm interrupt'ları kapattıysanız,
  • Lower/Upper ROM'ları disable ettiyseniz,
  • BASIC kullanmayacaksanız,
  • Hiçbir şekilde firmware call yapmayacaksanız,
o zaman, bu minik alanı kullanabilirsiniz.

Amstrad CPC ailesi, Assembly language ile 'low-level' kodlama yapmanız ve yukarıda sıralanan koşulları sağlamanız durumunda, 64K'nın tamamını (!) kullanmanıza izin verir. RST Area ve Firmware Adres Tablosu’na ait yerleri bile kullanabilirsiniz. Hatta, normalde &BFFF adresinde bulunan Stack'in yerini bile değiştirebilirsiniz. ;)

Yıllar önce elo elektronik dergisinde amstrad ile ilgili bir yazıda "300 Hz interrupt" ifadesi geçiyordu. Böyle bir şey var mı?

Sözünü ettiğiniz makaleyi bilmiyorum, ama "300 Hz interrupt" ifadesi ile ne kastedildiğini açıklayabilirim.

Amstrad CPC ailesinde saniyede 300 kez (her frame'de 6 kez X 50 frame) FAST TICKER olarak bilinen bir interrupt oluşur. Bu interrupt'ın gerçekleşmesi durumunda, Z80 işlemci önce tüm interrupt'ları disable eder, ardından da &0038 adresini CALL eder. Normal koşullarda bu adreste 3 byte'lık (C3, 41, B9) jp &B941 kodu bulunur. Bu sebeple her interrupt'ta &B941 adresine jump edilir, o adresten sistemi idame ettirmek için gerekli birkaç firmware çağırısı yapılır, bu işlem bittikten sonra tüm interrupt'lar tekrar açılır ve hayat kaldığı yerden devam eder. Bu işlem her frame'de 6 kez tekrar edilir.

İşin en keyifli yanı, FAST TICKER interrupt oluşumunda gidilen &0038 adresinin içindeki 3 byte'lık kodu değiştirerek, kendi interrupt kodlarımızı yazabiliyor olmamız.

Örneğin;
  • FAST TICKER interrupt'ının düzenli olarak gerçekleşmesini, ama kıymetli zamanımızı çalmaması için 'hiçbir iş yapmamasını' istiyorsanız, &0038 adresine EI (&FB), RET (&C9) yazmanız yeterli.
Kod: [Seç]
ld hl,&C9FB
ld (&0038),hl
  • Her FAST TICKER interrupt sırasında 'içeriğini sizin belirleyeceğiniz' özel bir işin yapılmasını istiyorsanız, &0038 adresine jump etmek istediğiniz adresi (C3, ADDR_LOWBYTE, ADDR_HIGHBYTE) şeklinde yazabilirsiniz.
NOT: Yukarıdaki her iki durumda &0038 adresi üzerinde bir değişiklik yapmadan önce DI komutu ile interrupt'ları kapatmanız, işiniz bittikten sonra da EI komutu ile interrupt'ları tekrar açmanız gerekir.

Çevrimdışı Fero

  • RAAT
  • Retroman
  • *
  • İleti: 34
  • guy.brush
    • Ferhat Tanman
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #27 : 03 Ocak 2019, 08:29:13 »
Ödevi şöyle bırakayım :) Hades 'in yaptığının tersi şeklinde aşağıdan yukarı doğru siliyor. Kodun tamamı ve resim dosyası da ekte mevcut. Bunu yaparken screen memory 'i komple yanlış anladığımı fark ettim. Şimdi iyice taşlar yerine oturdu. Skate 'in paletle ilgili fikrini de uygulamayı deneyeceğim. Umarım becerebilirim.

Kod: [Seç]
cls: ld hl,&ffcf
call clear
ld hl,&ffbb
call clear
ld hl,&ffa7
call clear
ld hl,&ff93

clear: ld a,25 ;rows
clear02: ld c,8 ;lines
push hl
clear01: ld b,20 ;Video Mem +-14
clear00: ld (hl),0
dec hl
ld d,100
delay00: dec d
jr nz,delay00
djnz clear00
ld de,2048-20 ;previous/next row.
sbc hl,de ;previous line
dec c
jr nz,clear01
pop hl
ld de,80 ;previous/next line.
sbc hl,de ;previous line
dec a
jr nz,clear02
ret
"Never pay more than 20 bucks for a computer game."

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2866
  • Advanced User Simulator
    • ae unutmadan
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #28 : 03 Ocak 2019, 09:51:27 »

  • FAST TICKER interrupt'ının düzenli olarak gerçekleşmesini, ama kıymetli zamanımızı çalmaması için 'hiçbir iş yapmamasını' istiyorsanız, &0038 adresine (C9, FB) RET, EI yazmanız yeterli.

önce EI, sonra RET (FB C9) olmayacak mı o, yoksa amstrad PC'yi azaltarak mı ilerliyor :D Olur olur, komut işletmek için vblank bekleyen sistemden herşey beklenir. 80'ler makineleri çok çılgınca saçmalıklar yapmış, derme çatma sistem hepsi. Commodore disk sürücüsünü 10 kat yavaşlatarak kullanıyor, amstrad rom'a erişmek için bekliyor, Oric ekranı HAM modu gibi boyuyor, spectruma başlamaya gerek yok... BBC, Acorn neler yaptı kimbilir... Neyse...

Peki eğer ROM'da işlenen komutun uzun sürerek, sayfa eski haline çevrilmeden çizime başlandığı oluyor mu? Yani basic kullanırken bir şekilde anlık bile olsa ekranı garbage haline getirebilmek mümkün mü?

Ayrıca, @fero,
ekteki grafikte raat#5 metni görüyorum ama partide bunu göstermedin. Yoksa ben mi kaçırdım? Yoksa amstradda batman demo açıldı diye misafilrler kaçar ihtimaliyle mi gizlediniz bu çizimi?

Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 208
    • The Blog of Mert Börü
Ynt: CPC'de Assembler ile imtihanım...
« Yanıtla #29 : 03 Ocak 2019, 11:47:07 »
  • FAST TICKER interrupt'ının düzenli olarak gerçekleşmesini, ama kıymetli zamanımızı çalmaması için 'hiçbir iş yapmamasını' istiyorsanız, &0038 adresine (C9, FB) RET, EI yazmanız yeterli.
önce EI, sonra RET (FB C9) olmayacak mı o, yoksa amstrad PC'yi azaltarak mı ilerliyor :D

Uyarı için çok teşekkür ederim Ref.

LD (addr), reg16 instruction format gereği, 16-bit register içindeki değer hafızaya low-byte ve high-byte şeklinde ters yazılacağı için (C9, FB) sıralaması doğru. Maalesef açıklamasını yanlış yazmışım. Elbette doğrusu EI, RET şeklinde olacak. Gözümden kaçmış, özür dilerim.

Orijinal mesajımdaki muğlak cümleyi şu şekilde düzeltip, bir de örnek ekledim:

  • FAST TICKER interrupt'ının düzenli olarak gerçekleşmesini, ama kıymetli zamanımızı çalmaması için 'hiçbir iş yapmamasını' istiyorsanız, &0038 adresine EI (&FB), RET (&C9) yazmanız yeterli.
Kod: [Seç]
ld hl,&C9FB
ld (&0038),hl

Sanırım böylesi daha açıklayıcı oldu. Daha önce örnek kod yazmak neden aklıma gelmedi acaba?! :o

Olur olur, komut işletmek için vblank bekleyen sistemden herşey beklenir. 80'ler makineleri çok çılgınca saçmalıklar yapmış, derme çatma sistem hepsi. Commodore disk sürücüsünü 10 kat yavaşlatarak kullanıyor, amstrad rom'a erişmek için bekliyor, Oric ekranı HAM modu gibi boyuyor, spectruma başlamaya gerek yok... BBC, Acorn neler yaptı kimbilir... Neyse...

Bu listeye, ekranda kar yağarken görüntünün netleşmesi için ZX Spectrum'un 'lambalı amfi misali' ısınmasını beklememizi de ekleyebilir miyiz? ;)

Peki eğer ROM'da işlenen komutun uzun sürerek, sayfa eski haline çevrilmeden çizime başlandığı oluyor mu? Yani basic kullanırken bir şekilde anlık bile olsa ekranı garbage haline getirebilmek mümkün mü?

ROM'da yapılan işlerin birçoğu (hepsi değil, örneğin teyp/disk erişim routine'leri hariç) ona göre tasarlanmış, toplamda belli bir süreyi asla geçmiyorlar. BASIC ile ekranı garbage etmek elbette mümkün, hele bir de READ/DATA/POKE kombinasyonu ile 'inline' machine code eklenirse iyice kontrolden çıkabilir. :)