ÇİZGİ KURSÖR
Retro bilgisayar
(Programlar C64ASM V1.1 ile compile edilecek şekilde yazılmıştır)
ÇİZGİ KURSÖR
NEREDEN : İSTANBUL NİCK / GRUP(LAR) : HADES / HI3S WEB SİTE : WWW.HI3S.ORG HTTP://HADES6510.SITEMYNET.COM
Eğer C64’ün yanıp sönen kare şeklindeki kursöründen sıkıldıysanız aşağıdaki kısa programla (sadece 96 byte uzunluğundadır) kursörünüz artık PC’lerin DOS zamanındaki kursörü şeklinde olacaktır. Peki bu değişiklik nasıl oluyor? Yeni kursörümüz aslında bir sprite’dır ve interrupt tekniği kullanılmıştır. Normal kursörün satır ve sütun değerleri okunarak programda sprite’ın X ve Y koordinat değerlerine dönüştürülmektedir.
*=$0801
.word nextline
.word 2004
; 2004
.byte $9e
; SYS
.text "2061"
; 2061
.byte 0
; komutu
nextline
.word 0
sei
;interruptları durdur
lda
#<cursor
;programın low byte’ını
sta
$0134
;interrupt vektörünün low byte’ına yaz
lda
#>cursor
;programın high byte’ını
sta
$0315
;interrupt vektörünün high byte’ına yaz
ldx
#$00
;X registerini sıfırla
txa
;Akü’ye X registerinin değerini yükle
loop0
sta
$03c0,x
;Sprite data adresine 0 yaz
inx
;sayacı 1 arttır
cpx
#$40
;#$40 (64) oldumu ?
bne
loop0
;olmadıysa tekrarla
lda
#$ff
;çizgi şekli olması için $ff sayısını
sta
$03c0+21
;sprite’ın uygun data adresine yaz
lda
#$03c0/64
;sprite data başlangıcını
sta
$07f8
;1. sprite pointerine yaz
lda
#$01
;1. Sprite’ı
sta
$d015
;görünür yap
cli
;interruptları başlat
rts
;programı bitir
cursor
lda $d3
;normal kursörün sütun pozisyonunu oku
cmp #$1d
;$1d (19) ile karşılaştır
bcc no_extra
;$1d’den küçükse git
ldx
#$01
;sprite’ın extra x koordinatı var
.byte $2c
;bilgisayarı kandırma sayısı
no_extra
ldx
#$00
;sprite’ın extra x koordinatı yok
stx
$d010
;spritelar için extra x koordinat adresi
asl ;sütun değerini 2 ile çarp asl ;sonucu 2 ile çarp asl ;önceki sonucu 2 ile çarp clc ;”carry” bitini sıfırla adc #$18 ;$18 (24) ile topla sta $d000 ;1. sprite’ın X koordinat adresine yaz. Burada biraz bilgi verelim. Yukarıda 3 defa asl komutunu kullandık. Peki neden böyle bir işlem yaptık? Normalde kursörün sütun değerini olduğu gibi sprite’ın x koordinatına veremeyiz. Eğer verirsek sprite’ımız sadece 1 pixel ilerlemiş olur. Bir karakter normalde 8 pixel genişliğindedir. Kursör dediğimiz şekil aslında bir karakterdir ve reverse space karakterinden başka bir şey değildir. Kursörün bir sonraki sütuna gitmesi demek sprite’ımızında 8 pixel ilerlemesi demektir. Kursörün sütun değeri*8 sayısı bize sprite’ın X koordinatını verecektir. Assemblerde bir sayıyı 8 ile çarpmak, o sayıyı 3 defa sola kaydırmak yani 3 defa ASL komutu kullanmak demektir. Buraya kadar tamam. Peki $18 (24) sayısı nereden geliyor. Bir sprite’ın ekranda tamamen görünür halde olması için X koordinatı $18 olmalıdır. Bu sayıyı 3 ASL komutu sonunda elde ettiğimiz sayıyla toplarsak işimiz tamam olacaktır. lda $d6 ;kursörün satır değerini oku asl ; 2 ile çarp asl ; bir daha 2 ile çarp asl ; son kez 2 ile çarp clc ;”carry” bitini sıfırla adc #$32 ;$32 (50) ile topla sta $d001 ;1. sprite’ın Y koordinat adresine yaz. Yukarıdaki açıklamanın bir benzerini satır değeri için yapıp sonucu sprite’ın Y koordinat adresine yazdığımızda kursörün o anki pozisyonunda birde sprite göstermiş oluruz. inc $d027 ;1. sprite’ın rengini değiştir. jsr $ffea ;zamanı ilerlet ve stop tuşunu kontrol et. jmp $ea61 ;Romdaki interrupt rutinine geri dön. .end Geldik son açıklamaya. Kendi yazdığımız bir interrupt rutininin çalışması bitince son komutun normalde JMP $EA31 veya $EA81 olması gerekir. $EA81 deki komutlar $EA31’den başlayan komutların devamıdır. Peki aradaki $50 (80) byte’ta neler olmaktadır? İlk önce Stop tuşu kontrolü ve zaman ilerletme yapılıyor. Sonra kursörün yakılıp söndürülmesi ve kursörle ilgili karakter ve renk işlemleri yapılıyor. Daha sonra ise teyp tuşlarına basılıp basılmadığı ve teyp motor on / off işlemleri yapılıyor. En son olarak ise klavye kontrolü yapılmakta ve $EA81 adresine gelinmektedir. $EA81’den itibaren ise sırayla Y, X ve A registerleri yığından geri alınıp interrupt rutini bitirilmektedir. Bizim rutinimizde ise önce JSR $FFEA ile bir işlem yapılmakta ve JMP $EA61 ile çıkış yapılmaktadır. Eğer JMP $EA31 kullansak kursör işlemleri yapılacak, JMP $EA81 kullansak tuşlar çalışmaz hale gelecek. Bu nedenle önce JSR $FFEA ile stop tuşunun kontrol edilmesini sağlıyoruz, sonrada kursör işlemlerine hiç uğramadan geri kalan işler için JMP $EA61 komutuyla işimizi bitiriyoruz.