İçindekiler
Selam sevgili okuyucular. VIC kursuna kaldığımız yerden devam ediyoruz. Hatırlayacağınız gibi bir önceki bölümün sonunda ekranda tek bir raster çizgisi göstermiştik. Bu bölüme daha çok raster cizgisi göstererek başlayacağız.
Programımızın IRQ rutini bölümü değişecek sadece. En başta IRQ hazırlama rutini aynen kalacak. Sadece IRQ kesintisinin olacağı satırı değiştirip biraz daha ekranın ortasına alacağız.
IRQ Rutininde tek raster çizgisi koyarken ne yapmıstık?
satır başına gelene kadar bekle
renk değiştir
bir sonraki satıra kadar bekle
ekranın efektten sonraki rengini ver
IRQ'dan çık (jmp $ea81)
Bu sefer birden fazla raster satırına renkler vereceğimiz için şöyle bir değişiklik yapıyoruz
satır başına gelene kadar bekle
renk değiştir
bir sonraki satıra kadar bekle
renk değiştir
bir sonraki satıra kadar bekle
...
renk değiştir
bir sonraki satıra kadar bekle
ekranın efektten sonraki rengini ver
IRQ'dan çık (jmp $ea81)
Efektin dikey olarak ekranda ne kadar kalın olmasını istersek, o kadar çok satır için bu işlemi tekrarlayacagız. Bu örnekte $60 satır için bu işlemi tekrarlayacağız.
Programın tamamını raster2.a64 adlı dosyada görebilirsiniz. Biz şimdi burada IRQ rutinini inceleyeceğiz.
;; ------------------------------------------------
IRQRutini:
inc $d019
ldy #2
gecik1:
dey
bne gecik1
ldx #$00
dongu:
lda renk_tablo,x
sta $d020
sta $d021
ldy gecikme_tablo,x
gecik2:
dey
bne gecik2
inx
cpx #$60
bne dongu
lda #$00
sta $d020
sta $d021
jmp $ea81
;; ------------------------------------------------
Şimdi detaylara geçelim.
IRQRutini:
inc $d019
ldy #2
gecik1:
dey
bne gecik1
Buraya kadarki bölüm önceki program ile aynı. IRQ sinyalini aldıktan sonra çizgilerimizin düzgün bir şekilde satır başından başlamaları için küçük bir gecikme ile başlıyoruz.
ldx #$00
dongu:
$60 tane satırı tek tek kodlamak istemediğimiz için bir döngü hazırlıyoruz. Döngümüzde sayaç olarak X registerini kullanacağız.
lda renk_tablo,x
sta $d020
sta $d021
Satırların tek tek alacakları renkleri kolay erişim ve editleme için bellekte bir tabloya koyacağız. Tablo diye bahsettiğimiz şey bellekteki ardışık bir grup bayttan başka birşey değil. Bu komutlarla indexli adresleme kullanarak bellekte "renk_tablo" adresinden başlayan tablomuzdan sıradaki rengi (yani n'inci rengi, n X registerinde o an yazılı olan değer) alıp, VIC'in ekran ve çerçeve rengi registerlerine gönderiyoruz.
ldy gecikme_tablo,x
gecik2:
dey
bne gecik2
Bu komutlarla her satırda bir gecikme yapıyoruz. Dikkatli okurların aklına şu soru gelebilir. Neden gecikme değerlerini bir tablodan okuyoruz? VIC ekrana datayı sabit hızda gönderiyordu. Dolayısıyla bizim her satırda beklememiz gereken süre sabit olmalı, çünkü VIC bir alt satıra hep sabit bir hızla geçiyor olmalı.
Bu çok haklı bir soru. Cevabı ise biraz karmaşık. Şu an cevabın sadece bir bölümünü vereceğiz. Devamını kursun bu bölümünde bulacaksınız.
VIC'in ekrana bilgileri sabit hızda gönderdiği doğru. Fakat VIC bunu yapabilmek için her 8 satırda bir kere 6510'u kısa bir süreliğine "donduruyor". "Nasıl yani?" dediğinizi duyabiliyorum. Merak etmeyin daha sonra bu konuyu bütün detayları ile anlatacagım. Şu an anlamanız gereken şey şu. 8 satırda bir kere VIC 6510'u kısa bir süre durduruyor ve bazı işlemler yapıp sonra tekrar başlatıyor. Bu esnada ekrana sinyal göndermeye devam ediyor çünkü ekran ondan pixel bilgilerini sabit bir hızda almak zorunda. Düşünün... Eğer 6510 durdurulduğu satırda, diğer satırlarda işlettiği kadar komut işletmeye kalkarsa geç kalır. Çünkü zaten durdurulduğu için zaman kaybediyor.
İşte bu yüzden bizim yazdığımız kodun da 8 satırda bir diğer satırlardan daha az bekleme yapması gerekiyor. Yukarıda gördüğünüz komutlarla, her defasında bekleme miktarını tablodan alarak değiştiren bir gecikme rutini yazmış oluyoruz.
inx
cpx #$60
bne dongu
Burada da bütün raster satırlarımızı çizmeyi sağlayan ana döngümüzün kontrol noktasındayız. Döngünün sayacı olan X registerindeki değeri artırıp, henüz $60 olup olmadığını kontrol ediyoruz.Buradaki $60 değerini azaltarak efekt alanını daraltmayı deneyebilirsiniz
lda #$00
sta $d020
sta $d021
jmp $ea81
Bu komutlara vardığımızda artık bütün satırları çizmiş durumdayız. O yüzden ekrana efektin dışındaki bölgede alacağı rengi verip, IRQ rutininden çıkıyoruz.
Raster2.a64 dosyasına baktığınızda IRQ rutininin hemen ardından !align 255,0 satırını göreceksiniz. Bunu takiben de her biri $60 bayt uzunluğunda olan renk ve gecikme tablolarını göreceksiniz. Burada align satırı ile tabloların C64 belleğinde tam olarak bir sonraki bloğun başından (yani $c100) başlamasını sağlıyoruz. Bunu neden yaptığımızı açıklayalım.
6510 da indexli adresleme komutları (lda renk_tablo,x vs) her zaman sabit hızda (yani sabit sayıda cycle yiyerek) çalışmazlar. Eğer index registerindeki (X veya Y) değer tablonun taban adresine (mesela renk_tablo) eklendiği zaman bir sonraki bloktan bir adres elde ediliyorsa, normalden 1 cycle fazla harcanır. Örneğin
lda $c080,x
komutunun kac cycle sureceği X registerindeki değere göre değişir. Eğer X registerinde $7f veya daha küçük bir değer varsa bu komut 4 cycle sürer. Oysa X registerinde $80 veya daha büyük bir değer varsa bu komut $c100den sonraki bir adrese (yani $c080'in içinde olduğundan bir sonraki bloğa) eriştiği için 5 cycle sürer.
Biz kodumuzda bu kadar hassas bir zamanlama ile gecikme döngüleri yazmaya çalışıyorken, o döngüleri yazarken kullandığımız komutların hızları da değişirse çok zor durumda kalırız. Bunun olmaması için kullandığımız tabloları bellekte öyle yerleştirmeliyiz ki, bir bloktan taşıp başka bloğa yayılmasınlar. Burada 2 adet $60 baytlık tabloyu bir bloğun başından başlatarak emin oluyoruz ki ikisine de erişirken hep sabit hızda çalışacak komutlarımız.
Bu programı anladığınız zaman biraz renk tablosundaki değerlerle oynayın. Hatta biraz Gecikme tablosundaki değerlerle de oynayarak raster efektlerinde zamanlamayı tutturamazsanız oluşan görüntüleri de görün. Üstüne gidin bir çay için, bir tenefüs verin sonra gelin devam edelim. Şimdi çok eğlenceli ve "janjanlı" bir bölüme başlayacağız.