HADES BASIC #3
HADES BASIC’in son bölümüne hoş geldiniz. Bu bölümde 6 adet yeni komut ekliyoruz. Aşağıda komutların neler olduğunu, nasıl kullanıldığını bulabilirsiniz.
1 – MIRROR : Ekran görüntüsünü yatay veya dikey olarak çevirebilirsiniz. Ekranda eğer yazı varsa çevirme işleminde sorun olmayacaktır. Eğer tuşlardaki grafikleri kullanarak bir şeyler çizmişseniz şekliniz bozuk çıkacaktır.
MIRROR H : Ekranı yatay olarak çevirir. MIRROR V : Ekranı dikey olarak çevirir.
2 – INV : Bu komutla ekrana yazacağınız yazıları inverse (negatif) olarak yazdırabilirsiniz. Komutu INV : PRINT “.......” şeklinde kullanırsanız yazdıklarınız ekrana negatif olarak çıkar. PRINT komutunu ikinci kez kullandığınızda yazılar normal olarak ekrana çıkar. Yani INV komutu sadece kendinden sonra gelen PRINT komutu için yazıları negatif hale getirir.
3 – FONT x : Hafızaya yüklediğiniz bir fontu aktif hale getirmek için kullanılır. X değeri 0 ila 7 arasında olmalıdır. POKE 53272 yerine kullanılır. Eğer “X” değeri kullanılmazsa yani sadece FONT olarak kullanılırsa default ROM karakter seti seçilmiş olur. Aşağıda x değerlerine karşılık gelen font adresleri verilmiştir.
X=0 Æ $0000-$07FF X=1 Æ $0800-$0FFF X=2 Æ $1000-$17FF X=3 Æ $1800-$1FFF X=4 Æ $2000-$27FF X=5 Æ $2800-$2FFF X=6 Æ $3000-$37FF X=7 Æ $3800-$3FFF
FONT 2 komutu default ROM karakter setini seçer. Yani $1000-$1800 adreslerine bir karakter seti yüklerseniz FONT 2 komutu ile seçemezsiniz.
4 – SPEED x : Kursörün yanıp sönme hızını ayarlayabilirsiniz. X değeri 0 ila 255 arasında olmalıdır. X değeri verilmezse default yanıp sönme hızına geri dönülür. Default değer 33’tür. Space tuşuna basılı tutarak cursörün hızını kontrol edebilirsiniz.
5 – SCREEN x : Ekranın açık veya kapalı olmasını sağlar. X değeri 0 veya 1 olmalıdır. SCREEN 0 : Ekran kapalı SCREEN 1 : Ekran açık
6 – DELAY x : Program içinde x değeri kadar milisaniye gecikme sağlar. X=0 iken en uzun gecikme sağlanır (256 msn).
C64’ün esnek bir işletim sistemine sahip olması nedeniyle yeni komut eklemek çok kolay olmaktadır. Yeni bir komut eklemek için önce komutun yapacağı işi normal bir program olarak yazın. Programınızın çalıştığından emin olduktan sonra gerekli adresleri kullanarak parametreleri programa aktarın. Gerekiyorsa parametre sınır değerlerini kontrol edin. Bir kez alıştıktan sonra istediğiniz komutu ekleyebilirsiniz. Mesela aklımda BASIC içinden interrupt kullanarak 1x1 text scroll yapan bir komut eklemek vardı. Program içinde SCROLL satır,hız,”text” komutunu kullanarak hiç makine dili bilmeden smooth scroll yapmak mümkün olacaktı.
Gevezeliği bir tarafa bırakıp aşağıdaki programı satır satır yazmaya başlayın. Kim bilir belki C64’e ekleyecek 1-2 yeni komut aklınıza gelebilir.
*=$c000
lda
#<yeni
ldx
#>yeni
sta
$0308
stx
$0309
rts
yeni
lda
$7a
ldx
$7b
sta
$fb
stx
$fc
lda
#<comset
ldx
#>comset
sta
$fd
stx
$fe
ldx
#$00
ldy
#$00
loop0
jsr
$0073
sta
$02
loop1
lda
($fd),y
cmp
$02
bne
nextcom
iny
tya
cmp
comlen,x
bne
loop0
exec
txa
asl
tax
lda
comexe+1,x
pha
lda
comexe,x
pha
rts
nextcom
lda
comlen,x
clc
adc
$fd
sta
$fd
bcc
next0
inc
$fc
next0
inx
cpx
commax
bne
loop1
lda
$fb
ldx
$fc
sta
$7a
stx
$7b
jmp
$a7e4
;---------------------------------------------------------------------------------------;
commax
.byte 6
comlen
.byte 5,3,3,5,6,5
comset
.text "mirr"
; MIRR
.byte $b0
; OR
.text "inv"
; INV
.byte $46,$91,$54
; F "ON" T
.text "speed"
; SPEED
.text "screen"
; SCREEN
.text "delay"
; DELAY
comexe
.word mirror-1
.word inv-1
.word font-1
.word speed-1
.word screen-1
.word delay-1
mirror
jsr
$73
; parametre varmı kontrol et
bne
mir0
; varsa git.
mir_err
jmp
$af08
; yoksa “syntax error” yazdır
mir0
cmp
#$56
; parametre “V” mi?
beq
vertical
; evetse “vertical” kısmına git
cmp
#$48
; değilse kontrol et. “H” mi?
bne
mir_err
; değilse hata yazdır. Evet ise devam et.
horizontal
lda
#$00
; Akü=0
ldx
#$18
; X=0
sta
up
; Aküdeki değer “UP” değişkenine
sta
byte
; Aküdeki değer “BYTE” değişkenine
stx
down
; X’teki değer “DOWN” değişkenine
one_line
ldy
byte
; Y registerine “byte” değişkenini yükle
horiz
ldx
up
; X registerine “up” değişkenini yükle
jsr
scrcalc
; ekran ve renk belleği adreslerini hesapla
lda
$fb
; $FB adresindeki değeri al
sta
$fd
; $FD adresine kopyala
lda
$fc
; $FC adresindeki değeri al
sta
$fe
; $FE adresine kopyala
lda
$02
; $02 adresindeki değeri al
sta
$04
; $04 adresine kopyala
lda
$03
; $03 adresindeki değeri al
sta
$05
; $05 adresine kopyala
lda
($fd),y
; ekrandaki karakteri al
pha
; yığına at
lda
($04),y
; renk belleğindeki değeri al
pha
; yığına at
ldx
down
; X registerine “down” değişkenini yükle
jsr
scrcalc
; ekran ve renk belleği adreslerini hesapla
lda
($02),y
; renk belleğindeki değeri al
sta
($04),y
; kopyala
lda
($fb),y
; ekrandaki karakteri al
sta
($fd),y
; kopyala
pla
; yığındaki değeri al
sta
($02),y
; renk belleğine yaz
pla
; yığındaki değeri al
sta
($fb),y
; ekrana yaz
iny
; Y registerinin içeriğini 1 arttır
cpy
#$28
; $28 (40) oldu mu ?
bne
horiz
; olmadıysa tekrarla.
Yukarıdaki kısımda değişkenlere ilk değerleri yüklendikten sonra, ilk önce X registerine yüklenen “UP” değişkeninin değerine göre (ilk satır için) ekran ve renk belleklerinin adresi hesaplanıyor. Bu adresler yedekleniyor. Daha sonra “BYTE” değişkeninin değerine göre ekran belleğindeki ve renk belleğindeki değerler okunup yığına atılıyor. Sonra X registerine “DOWN” değişkeni yükleniyor ve (en alt satır için) ekran ve renk belleği adresleri elde ediliyor. Daha sonra ekran ve renk belleğindeki değerler okunuyor. Bu değerler daha önce yedeklediğimiz adreslere yazılıyor. Daha sonra ise yığındaki değerler geri alınıp o anki renk ve ekran belleğine geri yazılıyor. Böylece en üst ve en alttaki satırların ilk byte’ları yer değiştirmiş oluyor. Y registerinin değeri 1 arttırılıp 40 olup olmadığı kontrol ediliyor. 40 olmadıysa aynı satırların bir sonraki byte’ları için işlemler tekrarlanıyor.
ldy
#$00
; Y registerini sıfırla
sty
byte
; “BYTE” değişkenine kopyala
inc
up
; “UP” değişkenini 1 arttır
dex
; X registerini 1 azalt.
stx
down
; “DOWN” değişkenine kopyala
cpx
#$0c
; X= $0c mi? (12-yani ekranın ortasındaki satır)
bne
horiz
; olmadıysa işlemleri yeni satır için tekrarla.
jmp
$a7e4
; olduysa kontrolü Basic Rom’a devret
scrcalc
lda
$ecf0,x
; Rom’daki ekran belleği LOW adres değerini al
sta
$fb
; $FB adresine kopyala
sta
$02
; $02 adresine kopyala
lda
scr_hi,x
; Tablodan ekran belleği HIGH adres değerini al
sta
$fc
; $FC adresine kopyala
clc
; “carry” bitini sıfırla
adc
#$d4
; #$D4 ile topla
sta
$03
; $03 adresine kopyala (Renk belleği HI byte)
rts
; geri dön
;---------------------------------------------------------------------------------------;
vertical
ldx
#$00
; X=0
lda
#$04
; AKÜ=4
stx
$fb
; X’in değerini $FB adresine yaz
sta
$fc
; Akünün değerini $FC adresine yaz
stx
$fd
; X’in değerini $FD adresine yaz
clc
; elde bitini sıfırla
adc
#$d4
; #$D4 ile topla ve renk bellek adresini elde et
sta
$fe
; $FE adresine yaz
ldx
#$00
; X=0 Æ Satır sayacı olarak kullanılacak
vert1
lda
#$27
; AKÜ=27
sta
right
; sağ değişkenine yaz
ldy
#$00
; Y=0
vert0
sty
left
; sol değişkenine yaz
ldy
right
; sağ değişkenini al
lda
($fb),y
; ekran belleği sağdaki adresi oku
pha
; yığına at
lda
($fd),y
; renk belleği sağdaki adresi oku
pha
; yığına at
ldy
left
; sol değişkenini al
lda
($fd),y
; renk belleği soldaki adresi oku
ldy
right
; sağ değişkenini al
sta
($fd),y
; renk belleği sağdaki adrese yaz
ldy
left
; sol değişkenini al
lda
($fb),y
; ekran belleği soldaki adresi oku
ldy
right
; sağ değişkenini al
sta
($fb),y
; ekran belleği sağdaki adrese yaz
ldy
left
; sol değişkenini al
pla
; yığından geri al
sta
($fd),y
; renk belleği soldaki adrese yaz
pla
; yığından geri al
sta
($fb),y
; ekran belleği soldaki adrese yaz
dec
right
; sağ değişkenini 1 azalt
iny
; y'yi (sol değişkeni) arttır
cpy
#$14
; 20 mi?
bne
vert0
; değilse tekrarla
lda
$fb
; ekran belleği adresi LOW byte’ı al
clc
; elde bitini sıfırla
adc
#$28
; #$28 (40) ile topla
sta
$fb
; Adrese geri yaz
sta
$fd
; $FD adresine yaz
bcc
no_hi
; “Elde” yoksa git
inc
$fc
; $FC adresindeki değeri 1 arttır
inc
$fe
; $FE adresindeki değeri 1 arttır
no_hi
inx
; X registerini 1 arttır
cpx
#$19
; $19 (25) oldu mu? (25 satır oldu mu?)
bne
vert1
; olmadıysa yeni satır için işlemleri tekrarla
jmp
$a7e4
; Kontrolü Basic Rom’a devret.
scr_hi
.byte 4,4,4,4,4,4,4
; Ekrandaki her satırın adresinin
.byte 5,5,5,5,5,5
; HIGH byte’larının bulunduğu tablo
.byte 6,6,6,6,6,6,6
.byte 7,7,7,7,7
up
.byte 0
; Yukarı değişken sayaç adresi
down
.byte 0
; Aşağı değişken sayaç adresi
left
.byte 0
; Sol değişken sayaç adresi
right
.byte 0
; Sağ değişken sayaç adresi
byte
.byte 0
; Satırdan okunacak byte için sayaç
;---------------------------------------------------------------------------------------;
inv
lda
#$12
; “inverse” özelliğinin kodu
jsr
$ffd2
; Aktif hale getir
jmp
$a7e4
; Kontrolü Basic Rom’a devret
;---------------------------------------------------------------------------------------;
font
jsr
$73
; Komuttan sonra bir karakter var mı
beq
font1
; yoksa git
jsr
$b79e
; Evet var. Sayıyı veya değişkeni al
cpx
#$08
; sonucu 8 ile karşılaştır
bcs
font_err
; 8’e eşitse veya 8’den büyükse hata komutu
txa
; X registerini Akü’ye transfer et
asl
; 2 ile çarp
clc
; Elde bitini sıfırla
adc
#$10
; #$10 (16) ile topla
.byte $2c
; Bilgisayarı kandırma sayısı ☺
font1
lda
#$14
; Default Rom Karakter Set seçme değeri
sta
$d018
; $D018 kontrol registerine yaz
jmp
$a7ae
; Kontrolü Basic Rom’a devret
font_err
jmp
$b248
; “illegal quantity error” mesajını yazdır.
;---------------------------------------------------------------------------------------;
speed
jsr
$73
; Komuttan sonra bir karakter var mı?
beq
norm
; yoksa git
jsr
$b79e
; Evet var. Sayıyı veya değişkeni al
.byte $2c
; Bilgisayarı kandır
norm
ldx
#$33
; Normal değer.
stx
$dc05
; İlgili registere yaz.
jmp
$a7ae
; Kontrolü Basic Rom’a devret.
;---------------------------------------------------------------------------------------;
screen
jsr
$b79b
; Komuttan sonraki parametreyi al
cpx
#$02
; 2 ile karşılaştır
bcs
scr_err
; büyük veya eşitse hata mesajını yazdır
lda
$d011
; Ekran kontrol registerini oku
cpx
#$01
; X registerinin değeri 1
beq
on
; ise ekran açılacak.
off
and
#$ef
; değilse ekranı kapat.
.byte $2c
; bilgisayarı kandır
on
ora
#$10
; ekranı aç
sta
$d011
; ekran kontrol registerine yaz
jmp
$a7ae
; Kontrolü Basic Rom’a devret.
scr_err
jmp
$b248
; “illegal quantity error” mesajını yazdır.
;---------------------------------------------------------------------------------------;
delay
jsr
$b79b
; Komuttan sonraki parametreyi al.
delay1
jsr
$eeb3
; Romdaki 1ms gecikme rutinine git
dex
; X registerini 1 azalt.
bne
delay1
; 0 olmadıysa tekrarla
jmp
$a7ae
; Kontrolü Basic Rom’a devret.
;---------------------------------------------------------------------------------------;
.end
; Programın sonu.
C64’e yeni komutlar eklediğimiz bu yazı dizisi burada sona eriyor. Program döküm ekinde listeyi bulabilirsiniz. Bir sonraki sayının program döküm ekinde ise HADES BASIC’in tamamını vereceğim. Ayrıca yeni komutlarla ilgili örnek programlar yer alacak.
