BASIC ÖĞRENİYORUM (DERS 1)

Herkese merhaba, bu sayımızdan itibaren eski dostumuz C64 ile konuşabileceğimiz bir dil olan BASIC derslerine başlayacağız. (1 dil bir insan, 2 dil insan) bu gıcık espriyi yaptıktan sonra dersimize geçelim. Öncelikle bilinmesi gereken bilgisayarın temel yapısı; bu yapıyı çözdükten sonra BASIC öğrenmek çok kolaylaşacaktır, zira programcı olmanın temeli budur. Bilgisayarın 5 ana ünitesini inceleyelim: 1) Giriş ünitesi (INPUT), 2) Çıkış ünitesi (OUTPUT), 3) Bellek Ünitesi (MEMORY), 4) Aritmetik Mantık Ünitesi (ARITHMETIC LOGIC UNIT A.L.U), 5) Yönetim Ünitesi (CENTRAL PROCESSING UNIT C.P.U)

Bilgisayar elektronik bir makinedir diyoruz. O halde nasıl oluyor da bir dizi aritmetik işlem, alfabetik bilgi akımı mümkün oluyor? Temelde iki çeşit elektrik sinyalinden bahsetmekteyiz. Bunlar düşük voltajlı sinyal ve yüksek voltajlı (genelde 5 volt) sinyalleridir. Elektrik dilinde iki nokta arasında potansiyel enerji farkı varsa voltaj farkı da vardır. Bu prensibe dayanarak “bit”ler dediğimiz 0 ve 1’leri oluşturmak mümkündür. Eğer voltaj farkı sıfır volt ise 0 “bit”ini, voltaj farkı 5 volt ise 1 “bit”ini oluşturmuş oluruz. ”Bit”lerin 8 tanesi bir arada olursa 1 “byte” denir. Bütün harfleri bir dizi 0 ve 1’leri bir araya getirerek yani kodlama sistemini kullanarak oluşturmak mümkündür.

PROGRAMLAMAYA GİRİŞ 
Bilgisayarı programlanabilen bir makine olarak düşünmek gerekir. Yapılan işler hız-
lı ve hacim itibariyle kabarıkta olsa, programı basamak,basamak alırsanız  her işlemin 
çok basit olduğunu görürsünüz. İlk programı küçük bir hesap makinesi ile de rahatça yapı-
labilecek bir işlem üzerinde kuralım. Bilgisayara iki tane rakam verelim ve bu rakamları 
toplayarak neticesini ekrana yazmasını isteyelim. 
10 INPUT A 
20 INPUT B 
30 LET TP=A+B 
40 PRINT TP 
50 END

Yukarıdaki programa bakınca ilk dikkat edilen özellik, programın satırlardan oluşması ve her satırın da bir numara ile başlamasıdır: örneğin 10, 20... gibi. Bu numaralara satır numaraları (Statement Number) denir. Satır numaraları küçükten büyüğe doğru artar. Bu düzenlemeyi bilgisayarın kendisi yapmaktadır. Satır numaraları 1 ile 63999 arasında tam sayı ve pozitif olan sayılardır. Programın akışına göre düzenlenmelidirler. Yani A ve B’nin değerini vermeden, toplamı oluşturan TP değerini hesaplamak mümkün olamayacağından, programdaki 30 no’lu satıra 10 numarası vermekle çalışabilen bir program yapmak mümkün değildir. Dikkat edilecek bir diğer özellikte satır numaralarının onar onar artmış olmasıdır. Bu numaralar birer birer arttırılabilirdi ve program da pekâlâ çalışırdı. Bu değerin onar onar arttırılmasındaki amaç, eğer ileride araya başka satırlar ilave etmek gerekirse programın genel akışını bozmadan bunu gerçekleştirmek içindir. Aksi halde ilave edilen satırdan sonraki satırların numaralarını tekrar düzenlemek gerekecektir. Demek ki programın genelinde bir değişiklik yapmadan 10 no’lu satırla 20 no’lu satır arasına 11, 12, 13, 14, 15, 16, 17, 18, 19 nolu satırları ilave etmek mümkündür.

INPUT, LET, PRINT komutları

10 numaralı satırı biraz daha detaylı inceleyelim. INPUT A: input komutu ile A basit değişkeninden oluşmaktadır. INPUT komutu (girdi) anlamına gelmektedir. Bilgisayar dilinde INPUT kendisinden sonra gelen değişkenin, bu durumda A’nın sayısal değerini klavye yolu ile vermek için kullanılır. Programın tamamını bilgisayarın hafızasına girdikten sonra programı çalıştırmak için RUN komutunu yazıp RETURN tuşuna basmak gerekir. Bu durumda bilgisayar ilk olarak 10 INPUT A satırını

C64 TÜRKİYE #8 3 okuyacaktır. Satırda INPUT komutu olduğundan bizden A değişkenini isteyecektir. Bunu belirtmek için de ekrana bir soru işareti yazar. A değişkeninin değeri 5 olsun, şimdi 5 yazıp RETURN tuşuna basın. Bu işlemi yaparken yazılan 5 rakamını ekranda görmek mümkündür. İleride göreceğimiz gibi bilgisayar A değişkeni için hafızasında ayırdığı yere 5 rakamını yerleştirecektir.

Bilgisayar daha sonra ikinci satır olan 20 INPUT B satırına geçecektir. Burada ki durum da ilk satıra benzediği için ekranda soru işareti görülecektir. Bu demektir ki bilgisayar B değişkeninin değerini istemektedir. B değişkeninin değeri 3 olsun, 3 yazıp RETURN tuşuna basarak bu işlemi de tamamlayalım. Bilgisayar bir sonraki satırda bilgileri değerlendirmeye başlayacaktır. 30 LET TP = A + B satırında LET komutu kendinden sonraki verilen ifadenin geçerli olmasını mümkün kılan bir deyimdir. Burada TP denilen bir değişken daha vardır. Hemen belirteyim, değişkenlerin bir harf ile olması şartı yoktur. A, B değişkenler olduğu gibi TP de bir değişkendir. TP = A + B ifadesi ile bilgisayara deniliyor ki A değişkeninin değeri ne ise onu al, B değişkeninin değeri ne ise onu da al, topla ve bu toplamı TP değişkeni ile ifade edilen hafızaya yerleştir. Bu da LET komutu kullanılarak yapılır. Bazı bilgisayarlarda LET komutunu kullanmaya gerek yoktur. O zaman bu satır 30 TP = A + B şeklindedir. O halde 30 numaralı satırdan sonra bilgisayar TP adında bir değişken oluşturdu. Bu değişkene ait olan hafızada A ve B’nin sayısal toplamı olan 8 vardır. 40 PRINT TP satırındaki PRINT komutu kendisinden sonra gelen değişkenin sayısal değerini ekrana yazmak için kullanılır. Bilgisayar ekrana bağlı değil de printer’a bağlı ise TP değişkeninin sayısal değeri bu defa kağıt üzerine yazılacaktır. Ekran kullandığımıza göre ekrana 8 rakamı yansıyacaktır. Demek ki 50 END satırındaki END komutu programın sonu geldiğini gösterir. Her programın sonunda END komutunu kullanmak gerekir.

PROGRAMIN ÇALIŞTIRILMASI Her satırı yazıp hafızaya yerleştirdikten sonra programı çalıştırmak için RUN komutunu yazmak gerekir. Şimdi RUN yazın, ekranda çıkacak işlem aşağıdaki gibi olacaktır. ? 5 ? 3 8 5 ile 3’ün toplamı 8’dir. Bilgisayar daha sonra hazır anlamına gelen READY mesajını yazarak kontrolü kullanıcıya bırakır.

LIST, Satır Numaraları ve Program Akışı Daha önce de belirttiğim gibi satır numaraları küçükten büyüğe doğru artar. Bu artış onar onar olabileceği gibi birer birer de olabilir. Satır numaraları programın akışına göre düzenlenmelidirler. Numaralama yanlış yapıldığında aşağıdaki örnekte olduğu gibi yanlış netice alınacaktır.

Bilgisayar bu satırları hafızasına aldıktan sonra satır numaralarına göre sıraya koymaktadır. Hafızada ne olduğunu görmek için yani programı listelemek için LIST deyimi kullanılır. Şimdi LIST yazıp RETURN tuşuna basalım: 10 INPUT A 15 LET TP=A+B 30 INPUT B 40 PRINT TP 50 END Bu programa RUN demek mümkün olmayacaktır. Sebebi ise bilgisayar 15 no’lu satıra geldiği zaman B değişkeninin değerini bilmediği için toplama işlemini yapamayacaktır. (HADES’in notu: C64’te eğer sayısal bir değişkene herhangi bir değer verilmeden o değişkenle işlem yapılması durumunda değişkenin değeri sıfır kabul edilerek işlem yapılır.) O halde programdaki satırlara numara verirken, numaralar problemin çözümü için gereken işlem sayısına paralel olarak artmalıdır. Bence en iyisi programı yazarken önce satır numaralarını küçükten büyüğe doğru sıralamalı, sonra yazı kısımlarını işlem sırasına göre doldurmaktır. BASİT DEĞİŞKENLER Evet arkadaşlar bu aylık benden bu kadar, önümüzdeki dersimizde (Aritmetik Operatörler, İfadeler ve Komparatörler) REMARK ve PRINT komutlarını inceleyip bol bol örnekler göreceğiz. Buraya kadar gördüğünüz gibi BASIC dili çok kolay anlaşılır bir dildir, her ne kadar günümüzde pek kullanılmasa da bazen bize gerekebilecek ve en önemlisi 68K işlemcili bilgisayarlarda süper iş görecek sade ve stabil bir dildir. Önümüzdeki sayıda görüşmek üzere, BİR COMMODORE ALIN ONUNLA KALIN ☺

HEXADECIMAL VE ASCII MEMORY DUMP 
;=======================================================================================; 
; hexadecimal ve ascii memory dump programı 
     ; 
; C64 TÜRKİYE dergisi sayı 8 için hazırlanmıştır 
     ; 
; 10-05-2005 / ismail "hades" şahin  
     ; 
; hades@amigaturk.com 
www.c64turkiye.com  www.amigaturk.com  c64turkiye@amigaturk.com ; 
;=======================================================================================; 
*=$0801 
prg 
.word nextline 
.word 2005 
.byte $9e 
.text "2061" 
.byte 0 
nextline 
.word 0
start etiketli yere kadar olan kısımda LIST komutuyla göreceğiniz 2005 SYS2061 
satırını oluşturuyoruz. 
start  
lda 
#$0d  
;yeşil renk kodu 
jsr 
$e536 
dex 
stx 
$d020 
stx 
$d021 
stx 
$fb 
stx 
$fc

Yukarıdaki bölümde karakter rengi yeşil olacak şekilde ekranı siliyoruz ve ekran silindikten sonra X registerinin değerini 1 azaltarak "0" yapıyoruz. Bu değeri $D020 ve $D021 adreslerine vererek ekran renklerini siyah yapıyoruz. Ayrıca daha sonra kullanacağımız $FB ve $FC adreslerini sıfırlıyoruz. lda #<text1 ldy #>text1 jsr $ab1e lda #$3a jsr $ffd2 lda #$24 jsr $ffd2

Önce ekrana biraz yazı yazıyoruz sonra ":" ve "$" karakterlerini basıyoruz. adres_gir jsr hex_byte_in sta $fc ;high bayt jsr hex_byte_in sta $fb ;low bayt

Bu bölümde ilk önce adresin HIGH baytını klavyeden girip $FC adresine saklıyoruz. 
Sonrada LOW baytını girip $FB adresinde saklıyoruz. 
ldy 
#$00 
ldx 
#$06 
clc 
jsr 
$fff0

Yukarıdaki komutlarla kursörün yerini belirliyoruz. Y registerine kursörü koyacağımız yerin sütun değerini, X registerine ise satır değerini vererek Kernal Rom’daki PLOT rutinine sıçrıyoruz.

C64 TÜRKİYE  #8                                                                                                                                                5 
lda 
#<text2 
ldy 
#>text2 
jsr 
$ab1e 
lda 
#<text3 
ldy 
#>text3 
jsr 
$ab1e
Ekrana birşeyler yazdırıyoruz ve asıl bölüme geçiyoruz. 
dumper 
lda 
#$10 
sta 
line
Ekranda bir seferde kaç satır gösterileceğini ayarlıyoruz. 
line_dump 
lda 
#$20 
jsr 
$ffd2 
lda 
$fc 
jsr 
mem_to_scr 
lda 
$fb 
jsr 
mem_to_scr 
lda 
#$3a 
jsr 
$ffd2 
lda 
#$20 
jsr 
$ffd2
Önce bir adet "boşluk" basıyoruz. Programın başında girdiğimiz adresin önce HIGH 
baytını, sonrada LOW baytını hex olarak ekrana yazdırıyoruz. Son olarak ":" ve "boşluk" 
karakterlerini basıyoruz 
one_line_dump 
ldy 
#$00 
loop1  
lda 
($fb),y 
sta 
temp_scr,y 
jsr 
mem_to_scr 
lda 
#$20 
jsr 
$ffd2 
iny 
cpy 
#$08 
bne 
loop1

Bu bölümde bir satıra hex dump yapıyoruz. Y registerini sıfırlayıp bayt sayacı olarak kullanıyoruz. LDA komutuyla hafızadan o anki baytı alıyoruz ve geçici olarak saklıyoruz. Hafızadan okuduğumuz baytı JSR komutuyla HEX formatlı olarak ekrana yazdırıyoruz. Ekrana bir baytı yazdırdıktan sonra bir adet "boşluk" basıyoruz. Y registerini (bayt sayacı) 1 arttırıp 8 ile karşılaştırıyoruz. 8 olmadıysa hafızadaki bir sonraki bayt için LOOP1 etiketli yere sıçrıyoruz. 8 olduysa program aşağıdan devam ediyor. ascii ldy #$00 ascii_dump lda temp_scr,y cmp #$20 bcc no_ascii cmp #$60 bcs no_ascii .byte $2c no_ascii lda #$2e jsr $ffd2 iny cpy #$08 bne ascii_dump

Burada ise daha önce hafızadan okuyup geçici olarak sakladığımız baytların varsa ascii karşılığını ekrana yazdırıyoruz. İlk olarak Y registerini sayaç olarak kullanmak üzere sıfırlıyoruz. Sakladığımız ilk baytı alıyoruz. Önce "boşluk" karakterinden küçük olup olmadığını kontrol ediyoruz. Eğer küçükse "no_ascii" yazan yere gidiyoruz ve ekrana

C64 TÜRKİYE #8 6 "." karakterini basıyoruz. Eğer okunan bayt "boşluk" karakterinden büyükse bu sefer (Å) karakterinden büyük olup olmadığını kontrol ediyoruz. Eğer büyükse yine "no_ascii" yazan yere gidiyoruz. Eğer küçükse yani okunan bayt $20-$60 arasındaysa ekrana basıyoruz. Fakat burada $2C bayt'ı bilgisayarı kandırmak için kullanıyoruz. $2C değeri "BIT" komutunun kodu olup kullandığı parametre 2 baytlıktır. Bu parametreler ise "no_ascii" yazan yerdeki "LDA #$2E" komutunun baytlarıdır. Dolayısıyla "BIT $A92E" gibi bir komut yazmış oluyoruz. Bu durumda komut sırası .... BCS NO_ASCII - BIT $A92E - JSR $FFD2 şeklinde olmaktadır. Dolayısıyla Aküdeki değer değişmemiş olmakta ve bu değerin ASCII karşılığını yazdırmış oluyoruz. Normalde "no_ascii" yazan yere gelindiğinde Aküye $2E değeri yüklenmektedir ve $2E'nin ascii karşılığı "." karakteridir. Bu nedenle hafızadan okunan baytların ascii karakter karşılığı yoksa "." basılmaktadır. Bu işlemleri 8 defa tekrarlıyoruz ve sonra program aşağıdan devam ediyor. new_line lda #$0d jsr $ffd2

Yukarıdaki iki komutla bir alt satıra geçiyoruz. 
mem_setup 
lda 
$fb 
clc 
adc 
#$08 
sta 
$fb 
bcc 
no_inc_fc 
inc 
$fc 
no_inc_fc 
dec 
line 
bne 
line_dump

Bu bölümde ilk olarak hafızadan okuyacağımız yeni yerin adresini hesaplıyoruz. $FB adresinde okuma yaptığımız adresin LOW baytı bulunmaktadır. Bu adresteki değeri 8 ile toplayıp geri yazıyoruz. (Her seferinde 8 bayt okuduğumuz için 8 ile topluyoruz). Toplama sonucunda elde biti varsa (yani sonuç 255'ten büyükse -"C" biti "1" ise-) bu sefer $FC adresindeki HIGH baytı bir arttırıyoruz. Eğer elde biti "0" ise yani sonuç 255 veya küçükse "no_inc_fc" yazan yere gidiyoruz. Burada ise daha önce tanımlamış olduğumuz ekranda bir seferde gösterilecek satır sayısını bir azaltıyoruz. “0” olmadıysa “line_dump” yazan yere gidip ekranda 16 satır gösterilinceye kadar işlemleri tekrarlıyoruz. f_keys jsr $ffe4 cmp #$85 ;F1 - Sonraki sayfa beq next_page cmp #$86 ;F3 - Önceki sayfa beq old_pages cmp #$87 ;F5 - Yeni adres beq restart cmp #$88 ;F7 - Çıkış bne f_keys jmp $a474 ;Basic'e geri dön restart jmp start next_page .byte $2c old_pages dec $fc ldy #$00 ldx #$08 clc jsr $fff0 jmp dumper

Burası ekranda 16 satır yani 16*8=128 bayt dump edildikten sonra basılması gereken "F(onksiyon)" tuşlarının kontrol edildiği bölümdür. Önce bir JSR komutuyla tuşları okuyoruz ve "F" tuşları olup olmadığını kontrol ediyoruz. "F1" ile "next_page" yazan yere gidiyoruz. Daha önce bahsettiğimiz şekilde "BIT" komutuyla bilgisayarı kandırıyoruz ve kursörün yerini belirleyip dump etme işine tekrar başlıyoruz. "F3" ile daha önceki sayfayı ekrana getiriyoruz. Bunun için o anki hafıza adresinin HIGH baytının tutulduğu $FC adresinin değerini 1 azalttıktan sonra kursörün yerini belirliyoruz ve başa dönüyoruz. "F5" ile farklı bir adresi dump etmek için programın en başına zıplıyoruz. "F7" ile programdan çıkıyoruz.

Burası altrutinlerin olduğu bölümdür. 
hex_byte_in  
jsr 
hex_key_in  
;high nibble 
jsr 
key_to_mem 
asl 
asl 
asl 
asl 
sta 
$fb 
jsr 
hex_key_in  
;low nibble 
jsr 
key_to_mem 
ora 
$fb 
sta 
$fb 
rts 
Klavyeden bir baytlık hex sayı girme ve bu sayıyı hafızaya saklama bölümüdür. Önce 
klavyeden hex karakter girilen alt rutine gidiyoruz. Geri dönüşte aküde bulunan tuş değe-
rinin sayısal karşılığını almak için bir başka alt rutine gidiyoruz. Buradan geri dönüşte 
ise elimizdeki sayıyı 4 kez sola kaydırıp high nibble olarak $FB adresine saklıyoruz.Aynı 
alt rutinlere bir kez daha uğruyoruz ve daha önce high nibble olarak sakladığımız değerle
R işlemi yaptıktan sonra aynı adrese yazıyoruz. 
O
hex_key_in  
jsr 
$ffe4 
ldx 
#$00 
control 
cmp 
key_table,x 
bne 
next 
jsr 
$ffd2 
rts 
next  
inx 
cpx 
#$10 
bne 
control 
jmp 
hex_key_in
Bu kısımda klavyeden sadece hex sistem tuşlarına basılıp basılmadığını kontrol edi-
yoruz. Önce klavye taranıyor. Tarama sonunda Aküdeki değeri bir sayaca göre tablodaki 
değerle karşılaştırıyoruz. Eğer karşılaştırma sonucunda basılan tuş tabloda varsa karak-
ter ekrana basılıyor ve rutinden çıkılıyor. Yoksa klavye tekrar taranıyor. 
key_to_mem  
ldx 
#$00 
loop0  
cmp 
key_table,x 
beq 
val_read 
inx 
cpx 
#$10 
bne 
loop0 
val_read 
lda 
val_table,x 
rts
Bu kısımda basılan tuşa göre hafızaya alınacak sayı elde ediliyor. Aküdeki değer 
bir tablo ile karşılaştırılıyor. Karşılaştırma sonucu eşitlik varsa, kullanılan sayacın 
değeri kullanılarak başka bir tablodan hafızaya yazılacak değer okunuyor ve rutinden 
çıkılıyor.  
mem_to_scr  
pha 
lsr 
lsr 
lsr 
lsr 
jsr 
convert 
pla 
and 
#$0f 
convert 
tax 
lda 
key_table,x 
jsr 
$ffd2 
rts

Geldik son alt rutine. Burada yapılan iş hafızadan okunan bir baytı hex olarak ekrana yazdırmak. İlk olarak hafızadan okunan bayt daha sonra tekrar kullanılmak üzere yığına atılıyor. Sonra HIGH nibble değerini ekrana yazdırmak için 4 kez sağa kaydırılıyor. Elde edilen değer sayaç olarak kullanılarak, sayaca göre tablodan okunan değer ekrana yazdırılıyor. Daha sonra yığındaki değer geri alınarak $0F sayısı ile AND işlemi yapılıyor. Böylece LOW nibble elde ediliyor. Sayaç işlemleri bir kez daha yapılıp hafızadaki bir sayı hex olarak ekrana yazdırılmış oluyor.

key_table 
.text "0123456789abcdef" 
;basılması gereken tuş tablosu 
val_table 
.byte 0,1,2,3,4,5,6,7,8,9 
;tuşlara göre sayısal değerler 
.byte 10,11,12,13,14,15 
line  
.byte 16 
;ekrana basılacak satır sayısı 
text1  
.text "   c64 turkiye hex-ascii dump program" 
.byte $0d 
.text " 10-may-2005    code: hades of ascraeus" 
.byte $0d,$0d 
.text "f1:next    f3:prev.   f5:new     f7:exit" 
.byte 13,13 
text2  
.text " adres" 
.byte 0 
text3  
.text " hexadecimal memory dump  ascii " 
.byte $0d 
.text " ===== ======================= ========" 
.byte $0d,0 
temp_scr 
.byte 0,0,0,0,0,0,0,0 
;geçici saklama bölgesi 
.end