İŞARETLER EKRANA NASIL GELİR?

Her C-64 kullanıcısı cihazının nasıl işlediğini merak eder. Burada bilgisayarın içinde neler olduğunu açıklayacağız. Bir işaretin ekrana gelişi tüm bilgisayarlarda prensip olarak aynıdır. Konunun daha iyi anlaşılabilmesi için burada C-64'ü alacağız ve bu bilgisayarla ilgili örnekler vereceğiz. Klavye üzerinde bir tuşa basıldığında bu işletim sistemi tarafından değerlendirilir ve bilgisayar tarafından anlaşılabilecek bir sayıya çevrilir. Bu sayılara ASCII kodları adı verilir. Bu işlemler kısa bir programla kolaylıkla gösterilebilir. Aşağıdaki BASIC satırlarını yazdıktan sonra (RUN) ile çalıştırın:

10 GET A$: IF A$—-” “THEN 10
20 PRINT ASC(A$);:GOTO 10

Şimdi bu satırlarda neler olup bittiğine bakalım. 10. satırdaki (GET) komutu ile klavye kontrol edilir ve sonuç A$ değişkenine kaydedilir. Eğer hiçbir tuşa basılmamışsa A$ değişkeni boş kalır ve bilgisayarın tanıdığı işaretlerden biri olarak kabul edilmez. Bu satırda yer alan IF komutu programın 20. satıra atlamasını engeller ve her şeyi baştan başlatır. Fakat herhangi bir tuşa basıldığında A$'a o tuşun sahip olduğu işaret kaydedilecektir ve program 20. satıra atlayacaktır. Bu satırda ASC(A$) komutu ile işaret kendisine ait ASCII koduna çevrilecek ve PRINT ile ekranda görülecektir. GOTO 10 ile program tekrar başa dönecek ve böylelikle sonsuz bir döngü içine girilecektir (RUN/STOP tuşuna basılana kadar). ASCII kodlarının ekranda gözükmesi halinde diğer tüm adımlar C-64'ün işletim sisteminde de aynıdır. Yalnız işletim sistemi makine dili ile yazıldığı için tüm

1. Tuşa basma

2. Ekran gösterim kodlarına dönüşüm

3. Karakter matrisinin ROM'dan alınması

ASCİ!

Ekran gösterim kodu

Bir işaretin klavyeden ekrana dek izlediği yol

seti okunurken bellek dağılımı

—> Normal durumda bellek dağılımı | H H H | RAM Karakter seti RAM LA 1 > (RAM —m” kumanda İşletim sistemi | | 0 40960 49152 53248 57344 65535 işlemler kat kat hızlı gerçekleşmektedir. Fakat biz burada kullanılan makine dili rutinlerini daha yakından incelemeyeceğiz. Şu ana kadar ASCII kodlarının nasıl hesaplandığını gördük fakat asıl karakterler ekrana gelene kadar birçok adımla daha karşılaşacağız. Bu adımlardan ilki ise ASC kodlarının ekran kodlarına dönüştürülmesidir. Bu dönüşüm sadece ve sadece Commodore bilgisayarında yapılır. Bunun nedenini şöyle açıklayabiliriz: Bilgisayarda maksimum 256 ASCII kodu mevcuttur, fakat bu 256 kodun her biri için ekranda bir işaret gösterilemez. Örneğin RETURN, fonksiyon veya cursor kontrol tuşlarını düşünün. Bunların her biri ayrı ayrı işlevlere sahiptirler fakat ekranda bir karakter ile gösterilmezler. Mümkün olduğu kadar çok karakterin ekranda gözükebilmesi için (en fazla 256) işlevi olan fakat ekranda gösterilmeyen ASCII kodları elenip yeni bir tabela düzenlenmelidir. ASCII tabelasında olduğu gibi 64. sırada bulunmaz. Ekran gösterim kodlarının bulunduğu tabelada bu sefer en başta yani sıfırıncı sırada yer alır. Aslında ASCII tabelasının tekrar düzenlenmesinin başka sebepleri de vardır. Ekran gösterim kodlarının Videocontroller (VIC)'ın gösterilecek karakterleri oluşturma şekli ile yakından ilişkisi vardır. Ekranda gösterilen tüm işaretlere ait bilgiler bir ROM (Read Only Memory-Sadece okunabilir bellek)'de kayıtlıdır. Bu ROM'da karakterler bir bütün halinde yer almazlar; herhangi bir şekilde olmaları lazımdır. Ekranda gösterilen her işaret 8x8 noktadan oluştuğu için her satırda 8 nokta bulunmaktadır. (Resim 1) Her karakterin bir satırında bulunan noktaların konumu 0 ile 255 arası bir sayı ile belirlenir. Bu nedenle bir işaret için gerekli olan 8 satır ROM'un belleğinde arka arkaya bulunur. Örnek olarak ROM belleğinin 0 ile 7 arası baytları, <A> harfi ile 8 ile 15 arası baytları kaplar. Eğer bilgisayar ekranda <A> harfinin gelmesini isterse videocontroller'a “1” sayısını bildirir. Videocontroller bu durumda karakterlerin şeklinin kayıtlı olduğu ROM'dan 1 no'lu karakteri alır ve ekranda gösterir. Şimdi kontrol tuşları aradan çıkartıldıktan sonra ASCII tabelasının neden yeni baştan organize edildiğini sorabilirsiniz. Eğer eski tabela kullanılsa idi çıkarılan kodların yerleri boş kalacaktı ve lüzumsuz yere hafıza kaybına neden olacaktı. Şu anda C-64'ün tüm karakterleri hafızada sadece 4096 bayt işgal etmektedir. Daha önce belirtildiği gibi bir işaret için 8 bayt kullanılır. Toplam 256 işaret olduğundan 256 x 8 = 2048 bayt kullanılır. Küçük ve büyük harfler için ayrı ayrı karakter setleri bulunduğu için bu toplam 4096 bayt yapar. Zaten ROM'un kapasitesi de daha fazla değildir. Şu ana kadar Videocontroller'in bir işareti ekrana getirirken neler yaptığını gördük, fakat eğer ekran tamamıyla dolarsa ne olacak? Bu durumda bilgisayarın belleğinde tüm ekranın kayıtlı olduğu ve videocontroller tarafından sürekli okunan bir alan mevcuttur ve 1024 ile 2023. adresler arasında bulunur. Burada ekran yine ekran gösterim kodları ile kaydedilir. Denemek için şu satırı yazabilirsiniz:

Belleğin 1. baytı, C-64'ün karakter setini veya videocontroller'in kumanda adreslerini görmesini sağlar.

PRINT “ CLR POKE 1024,1
RETURN

Tahmin ettiğiniz gibi ekranın sol üst köşesinde A harfi görülecektir. Aynı şeyi ekranın sağ alt köşesine de uygulayabilirsiniz:

PRİNT “ CLR ”: POKE 2033,1
RETURN

Şimdi tüm yukarıda anlatılanları gösteren bir BASIC-Demo göreceğiz. Fakat programın listesini incelemeye başlamadan bazı ek bilgiler verelim. Bir işaretin biçiminin karakter ROM'unda bulunabilmesi için o işaretin ekran gösterim kodu 8 ile çarpılır. Bu cümle tamamıyla doğrudur fakat yeterli değildir. Zira karakterler bilgisayarın belleğinde 53248. adresten itibaren yer alır. Bu nedenle daha önce elde ettiğimiz çarpımı bu sayıya ilave etmeliyiz. İnceleyeceğimiz küçük demoda daha başka sorunlarla da karşılaşıyoruz. Öncelikle BASIC'ten karakter ROM'unu doğrudan doğruya okutamayız zira bu alanda Videocontroller'in kumanda adresleri ve Soundcontroller yer almaktadır. Resim 2'de bunu daha detaylı olarak görebilirsiniz. Yukarıda belirtilen sorunun giderilmesinde C-64'de bir demiryolu makası gibi çalışan 1. adres kullanılır. Bu adresin aldığı değere göre C-64 karakter setini veya videocontroller'ın kumanda adreslerini algılar. Fakat burada C-64 oldukça gereksiz bir şekilde karakter setini okurken işletim sistemini otomatik olarak devreden çıkartır. Bu durumda bilgisayar klavyeden yazılmış hiçbir şeyi algılayamaz. BASIC'den karakter ROM'unun okunması bu şekilde olanaksız hale geldiği için ufak bir makine dili program yazılmalıdır ve demoda bu alt program 32000. satırda yer almaktadır. Şimdi BASIC-Demo'muzu incelemeye başlayalım. İlk satır demonun işleyişi ile ilgili değildir. Burada DATA'lar halinde 32000. satırda bulunan makine dili programı hafızaya yerleştirilir. 20. satırda BA değişkenine üçüncü 32, dördüncü 16, beşinci 8, altıncı 4, yedinci 2 ve en sağdaki 1 olsun. Herhalde bunların üstel olduğunu fark etmişsinizdir.

karakter-ROM'un temel adresi olan 53248 yüklenir. 30. satırda daha önce görüldüğü gibi klavye sorulur ve elde edilen A$ değişkeni ASCII koduna çevrilir. 40. ve 50. satırlarda küçük bir program hilesi kullanılmıştır. ASCII kodlarının ekran gösterim kodlarına çevrilmesinde öncelikle 40. satırda ekran silinir ve A$ yazısal dizisi ekranın sol üst köşesine yazılır. Bilindiği gibi ekran belleğinde A$'ın içeriği ekran gösterim kodu şeklinde bulunur. Böylelikle uygun adres okunduğunda istenen değer kolaylıkla elde edilebilir. Bu okuma işlemi 50. satırdaki PEEK (1024) komutu ile gerçekleştirilir. Ayrıca 50. satırın başka bir görevi daha vardır: A$'daki işaretle karakter ROM'undaki başlangıç adresi hesaplanır. (Ekran gösterim kodu sekiz ile çarpılır ve karakter ROM'unun temel adresine eklenir.) Daha sonra 60 ile 170. satırlar arasında tam 8 defa tekrarlanan bir döngü bulunur. Bu döngünün görevi karakterin her bir satırını okumak ve ekrana vermektir. AD değişkeni her seferinde o anda okunan satırın değerini almaktadır. 70. satırda hesaplanan bu değeri 80. ve 90. satırlar makine dili programa bildirmek için hazırlık yaparlar. 100. satırda SYS komutu ile program işleme sokulur. 110. satırda 253 no'lu adresde bulunan karakter satır değeri BY değişkenine yüklenir. Bundan sonra 120 ve 160. satırlar arasında yeni bir döngüye girilir. 130. ve 140. satırlar BY değişkeninde bulunan sayıyı yorumlama görevine sahiptirler. İşaretin üzerinde bulunan her nokta bir yıldıza (*) karşılık gelmektedir. Buna karşılık işaretteki her boşluk için ekranda bir nokta gösterilmektedir. Her bir karakter satırda sekiz adet nokta bulunduğunu biliyoruz. Şimdi her bir noktaya bir sayı verelim. Soldan itibaren ilk nokta 128, ikinci 64,

“LÜTFEN BİR TUŞA BASIN” 128, 64, 32, 16, 8, 4, 2, 1'dir. Eğer bir satırda birden fazla nokta varsa bunlara karşı gelen değerler teker teker toplanır. Örnek olarak bir satırda en soldaki ve en sağdaki noktalar varsa bu satır 129 değerini alır (soldaki için 128 + sağdaki için 1). 130. ve 140. satırlarda yer alan (BY AND 2^J) komutu BY sayısına karşılık gelen noktaları belirler. Eğer BY değişkeninde kayıtlı olan sayı ikinin herhangi bir üssü olduğu belirlenirse ekranda bir (*) işareti belirir. Aksi taktirde 140. satırda boş yerlere bir nokta konulur. 170. satır cursoru bir sonraki satırın başlangıcına getirir ve son satır oluşana dek sekiz defa kullanılır.

Böylelikle program tamamlanmış olur. Aslında Videocontroller'de olup bitenler tamamen aynıdır. Eğer programı BASIC ile yazıp çalıştırırsanız C-64'ün her bir karakterinin nasıl yapıldığını görebilirsiniz. Yalnız BASIC-Demo'nun Videocontroller'dan defalarca yavaş çalıştığını unutmayın. Son olarak işaretlerin monitör üzerinde nasıl oluştuğuna kısaca değineceğiz. Videocontroller'ın ürettiği sinyal monitörde üçe ayrılır: Resim bilgilerini taşıyan sinyal (monokromlarda BAS, renklilerde FBAS) ve yatay ile dikey yönlerde katod ışığını etkileyen sinyaller. Bu bilgi pek fazla değildir ama konumuz için daha fazlası gereksizdir.

Bilgisayarınızın hesaplayabileceği en büyük değer, alışılmadık bir sayı olan 1.70141183E+38'dir. 0'a yakın en küçük sayı ise 2.03873588E-39'dur. Acaba bilgisayarları dizayn edenler bu tuhaf değerleri nereden buldular?.. Tamsayıların bilgisayarlarda ikilik sistemde saklandığını pek çok kimse biliyor, ancak acaba bilgisayar, ondalık kesirleri ve bilimsel notasyonla yazılan sayıları nasıl düşünüyor? Neden bilgisayar sonuç olarak ekranda “6” değerini göstermesine rağmen 36'nın karekökünün 6'ya eşit olmadığını söylüyor. Bu soruları ve diğer pek çoğunu yanıtlamak için floating-point sayıların karmaşık ve şaşırtıcı dünyasında bir araştırma yapacağız. Araştırmanın sonunda BASIC dilinin en önemli ve karışık bölümlerinden birinin iyi bir değerlendirmesini yapabileceksiniz. Bilgisayarın bize sonuç olarak verdiği sayılarda göründüğünden daha başka şeyler olduğunu daha iyi anlamak için direk moddan şu satırı girin:

A-6:B- SOR(36): PRINT A,B:
IF A< >B THEN PRİNT
“A VE B EŞİT DEĞİL”

Bilgisayar A ve B değeri olarak “6” sayısını verecektir, fakat bu arada A ve B'nin eşit olmadıkları sonucuna varacaktır. Eğer A ve B'nin bellekte saklanış şekline bakacak olursak aşağıdakini görürüz:

A: 13164000 B: 13164001

Belli ki A ve B, bilgisayarın içinde farklı sayılar. Ancak bu, “6” gibi basit bir sayının “131 64 0 0 0” olarak beş bayt halinde saklandığı tuhaf düzeni nasıl açıklarız?

TUHAF DÜZEN

BASIC'te nümerik değişkenlere verilen bütün sayı değerleri “ikisi en önemli bit'i tamamlayan ve biri 128 fazlası üssü temsil eden 4 bayt'lık normalize mantis (bir logaritmanın ondalık kısmı)” olarak tanımlanabilen bir floating-point düzeninde saklanırlar. Bu karmaşık terminoloji topluluğu sizi ürküttüyse floating-point sayıların saklanış şeklinin basitleştirilmiş bir örneği kaygılanacak bir şey olmadığını gösterecektir. Standart bilimsel notasyonda yazılmış bir sayıyla başlayalım: 4 x 10^3

Bu nicelik BASIC'te 4E3, 0.4E4, 40E2 veya hepsi 4000 sayısına eşit başka değişik şekillerde ifade edilebilir. Burada “E” harfi “on sayısının kuvvetlerinin sayısı” anlamında kullanılmaktadır. “E”'yi açıklamanın bir yolu da ondalık noktanın, basamaklara göre kaydığını düşünmektir. Örneğin 0.4E4'ün değerini bulmak için 0.4'ü 0.40000 şeklinde yazın (istediğiniz kadar 0 koyabilirsiniz), sonra da ondalık noktayı dört basamak sağa kaydırarak 4000.0'i bulun. “E”nin arkasına gelen sayıya “üs”, önüne gelen sayıya ise “mantis” denir. Burada 10, esas alınan başlama sayısıdır ve “taban” olarak adlandırılır. Bütün gerçek sayılar üslü bir tabanın, mantis katı şeklinde ifade edilebilirler. Bir mantis'i 0.1'den büyük veya eşit ve 1.0'dan küçük bir ondalık kesire çevirerek veya “normalize ederek” onu daha kullanışlı bir duruma getirebilirsiniz. Bundan sonra üs ile denklik sağlanabilir. Örneğin, 4000'in normalize şekli 0.4E4'tür, çünkü mantis 0.1 ile 1 arasındadır. 40E2, 400E1 ve 4000E0 gibi diğer şekillerin hepsinin değeri aynıdır, fakat normalize değildirler. Birkaç çeşitli değerler ve normalize floating-point karşılıkları:

123 — 0.123E3 54.321 — 0.54321E2 0.5 — 0.5E0 6 — 0.6E1 0.05 — 0.5E-1 0.00064 — 0.64E-3

Dikkat ettiyseniz son iki örneğin üsleri negatif sayılardan oluşuyor. Negatif bir üs ondalık noktayı üs sayısı kadar sola kaydırma olarak da açıklanabilir. Bu şekilde 0.64E-3, 0000.64E-3 (yine istediğiniz kadar 0 koyabilirsiniz) olarak yazılabilir ve E-3'e bakarak ondalık noktayı 3 basamak sola kaydırıp 0.000064 sayısını elde edersiniz. Şimdi mantis, taban, üs ve normalizasyon kavramlarının anlaşılmaz olmadıklarını görmüş olduk. Bu floating-point düzeninde yazılamayan herhangi bir sayı var mı? Eğer üs herhangi büyüklükte bir sayı olabiliyorsa, yanıt “Hayır, bütün sayılar floating-point düzeninde yazılabilirler.” olacaktır. Negatif sayılar negatif bir mantis ile yazılırlar. Negatif mantis'i (0'dan daha küçük sayı) negatif üs ile (ondalık noktayı sola kaydırma) karıştırmayın. Floating-point temsilinin en büyük yararlarından biri çok büyük sayı değerlerini sınırlı bir boşlukta saklayabilmektir. 100,000 sayısını normalize floating-point karşılığı olan 0.1E6 ile karşılaştırın. Bu sayının karesi olan 10,000,000,000 sayısı 0.1E11 olarak yazılırken bu karenin 30 sıfırlı kübünün floating-point yazılışı sadece 0.1E31'dir. 0'a çok yakın küçük sayılar için de benzer bir saklama avantajı vardır. Bazı bilgisayarların içindeki çiplerdeki devreler arasındaki uzaklık 2 mikron olabilmektedir (veya daha az). Bu metrenin 2 milyonda biri olan uzaklık, yani 0.000,002m normalize floating-point olarak 0.2E-5 olarak rahatlıkla yazılabilir. Floating-point notasyonu aynı zamanda “sabit nokta” notasyonundan daha etkilidir. Sabit nokta notasyonunda ondalık noktanın sağında sadece belli sayıda basamak bulunabilir. Örneğin bu sayı 2 ise 123.2345 sayısı 123.23 olarak saklanır. Noktadan sonra ikinci basamağın gerisi de kalan basamaklar yuvarlak hale getirilir veya atılırlar. Sabit nokta notasyonunun dezavantajı gösterilmesi mümkün en küçük pozitif sayının 0.01 (2 basamaklı sabit nokta düzeninde) olmasıdır. 0.0032 gibi daha küçük bir sayı yalnızca 0.00 olarak gösterilebilir. Floating-point notasyonu da ondalık basamakların sayısını 2'yle sınırlayabilir, ancak yine çok küçük değerleri gösterebilecektir: 0.0032'nin, 0.32E-2 olduğu gibi.

İKİLİK SAYILAR DÜNYASI

Hemen hepimiz bilgisayarların bilgilerini 0 ve 1'lerden oluşan binary (ikilik) sayılar şeklinde sakladıklarını biliyoruz. Binary kelimesi “2 tabanlı” sayı sisteminin diğer ismidir. Bu arada floating-point değerlerin daha önceki örneklerde olduğu gibi taban yerine esasen 2'li tabanda saklandıklarını tahmin edebilirsiniz. Gerçekte de bu böyledir. Sayılar, bilgisayar içinde normalize 2 tabanlı düzende saklanırlar. Okuyucuların muhtemelen çoğu ikilik tamsayılarla önceden ilgilenmişlerdir: 2'li tabanda 1101 (1101_2 şeklinde gösterilir) 10'lu tabanda 13'e eşittir. 11111111 = 255 vb. Ondalık sayı sisteminde her basamağın 10'un bir katını (basamak değeri) temsil ettiği gibi binary veya ikili sayı sisteminde her basamak 2'nin belirli bir katına eşittir. Örneğin 1504 ondalık sayısı için “1000'ler basamağında 1, 100'ler basamağında 5, 10'lar basamağında 0, 1'ler basamağında 4” bulunduğunu düşündüğümüz gibi 1101 ikilik sayısını “8'ler basamağında 1, 4'ler basamağında 1, 2'ler basamağında 0, 1'ler basamağında 1” şeklinde görebiliriz. Hesaplama (1*8 + 1*4 + 0*2 + 1*1) ondalık karşılık olarak 13 sayısını verecektir. Şimdiye kadar tamsayılarla uğraştık. Bir de kesirler var. 0.5 ondalık kesrini ikilik sayı olarak nasıl gösterebiliriz? Çok basit, on'lu tabanda 0.5 = iki'li tabanda 0.1'dir. Yine her şey basamak değerlerine dayanıyor. On'lu tabanda ondalık noktanın sağındaki ilk basamak 10'da birleri (1/10), ikinci basamak yüz'de birleri vb. temsil eder. İkilik sistemde, ikilik noktanın (diğer ismi radix noktası) sağındaki ilk basamak yarımları (1/2), sonraki basamak dörtte birleri, sonraki sekizde birleri, sonra da onaltıda birleri vb. temsil ediyor. Böylece 0.1101 ikilik kesri şu şekilde açıklanabilir:

0.1101— 1*(1/2) * 0*(1/8) * 1*(1/16) 0.5 4 0.25 4 0 4 0.0625 0.8125 ondalık

1*(1/4) +

İkilik bir kesrin ondalık karşılığını bulmanın başka bir yolu daha var. Örneğin 0.058 ondalık kesrini “binde 58” olarak okuduğumuz gibi 0.1101 ikilik kesrini “onaltıda 13” şeklinde okuyabiliriz, çünkü 1101 13'e eşittir ve 0.1101'in en sağındaki basamak onaltıda birler basamağıdır. Eğer 13/16'yı bölerek ondalık sayıya çevirirsek önceki sonuç olan 0.8125'i elde ederiz. Bilgisayar yalnızca ikilik yapıda değil, aynı zamanda bayt yapılıdır. Bir bayt 8 ikilik basamaktan oluşan bir gruptur. İkilik kesirler bilgisayarda en kolay biçimde bayt düzeninde saklanırlar. Örnek olarak 0.1101001 ikilik kesrini düşünelim. Yine bunu bit'lerine göre ondalığa çevirebiliriz.

— 1*(1/2) 4 1*4(1/4) * 1*(1/16) * 8*(1/32) * 0*(1/64) * 0*(1/128) 4 1*(1/256) - 0.81640625

Diğer metodu kullanacak olursak önce ondalık karşılığı 209 olan tamsayı ikilik kısmı (11010001) alıp bunu 256'ya böleriz (çünkü baştaki ikili kesrin en sağındaki bit 256'da birler basamağındadır). 209/256 işleminin sonucu yine yukarıdaki gibi

0.81640625 olacaktır.

0.11010001, — 11010001,/256 — 209/ 256-0.81640625

209 sayısı, bayt'ın en solundaki bit'in değeri 128 olduğundan 11010001'in 1*128 + 1*64 + 0*32 + 1*16 + 0*8 + 0*4 + 0*2 + 1*1 = 209 biçiminde yazılışından ileri gelmektedir. Bütün bu yolların BASIC'teki floating-point saklama şekliyle nasıl ilgili olduklarını görmeden önce başka bir örneğe daha ihtiyacımız var. Ondalık bir kesri normalize etmenin ondalık noktayı mantis'in en önemli basamağının soluna kaydırmak demek olduğunu gördük. Bu hareketi üssün değerini değiştirerek denkleştiriyorduk. İkilik kesirleri normalize etmek için de aynı mantıkla çalışan benzer bir işlem yapılıyor. 209 ondalık sayısını düşünelim. Bu sayıyı normalize ikilik floating-point değerinde şöyle ifade edebiliriz: 1) 209'u 2'nin kuvvetinin bir katı olarak yazalım:

ik katı olduğundan) — 11010001.E0 (burada E, “*2A ” yerinde kullanılmıştır).

2) Radix noktasını en soldaki sıfır olmayan bit'e (8 basamak sola) kaydıralım:

0.11010001

3) Bu kaydırma işlemini, üssü 8 arttırarak denkleştirelim:

0.11010001E8

İşlemin sağlamasını yapmak için 0.11010001 ikilik kesrini alarak 2^8 ile çarpalım. Daha önceden 0.11010001'in 0.81640625'e eşit olduğunu gördük ve 2^8'in 256 olduğunu biliyoruz. Öyleyse 0.81640625 * 256 = 209'dur. Alternatif olarak

0.11010001, 209/256'dır ve 209/256 * Bu yazımda da bir şey kaybetmiyoruz.

DERİNLİKLERE DOĞRU

Eğer buraya kadar olan kısmı özellikle ikilik kesirler ve normalizasyon bölümlerini iyice anladıysanız, floating-point sayıların bilgisayar içinde nasıl saklandığına yakından bakabiliriz. Burada Floating-Point Çeviricisi programından bahsedeceğiz. Bu program, herhangi bir sayının bilgisayarın içinde nasıl temsil edildiğini görebilmemiz için, floating-point değişkeninde bulunan bilgiyi ekranda göstermektedir. Program ayrıca belleğe direkt olarak data değerleri girmenize ve bilgisayarın bunları nasıl bir floating-point niceliği olarak yorumladığını görmenize olanak sağlamaktadır. Program, en başta ilk tanımlanan değişkenin saklandığı bellek adresine bakıyor. Bu bellek adresi “değişkenler pointer'ının başlangıcı” yoluyla bulunuyor. Bu pointer C-128'de 47 ve 48 adreslerinde, C64'te ise 45 ve 46 adreslerinde saklanan iki baytlık bir sayıdır (gelecek ayki C64'ün BELLEK HARİTASI yazı dizisinde bu adresler hakkında detaylı bilgi bulabilirsiniz). Satır 70, hangi bilgisayarın kullanıldığını belirtiyor. Satır 80 ise pointer'ın başlangıç adresi için uygun bir değer seçiyor. Satır 90, aşağıdaki standart formülü kullanarak 2 baytlık pointer'ı bir bellek adresine dönüştürüyor:

Adres = (pointer'ın ilk baytı) + 256 * (pointer'ın ikinci baytı)

Bu adres programın ilk değişkeninin yerleştiği yerdir. Her değişken için 7 bayt bellek ayrılır. Floating-point değişkenlerinin saklanma düzeni aşağıdaki gibidir:

Byte Kapsam Byte — Kapsam 1 İsimli 5 Mant2 2 İsim2 6 — Mant3 7 Mant4 4

Her değişkenin iki karakterden oluşan bir ismi olabilir (esasında sadece ilk iki karakter dikkate alınır). Bu karakterler İsim1 ve İsim2'de saklanırlar. Eğer değişkenin tek karakterlik bir ismi varsa bu karakter İsim1'de saklanır ve İsim2 0 değerini alır. Kalan 5 bayt üs ve değişkenin floating-point değerinin mantisidir. Her bayt 0-255 arası bir değer alabilir. Üs “128-fazlası” bir değer olarak saklanır, ki bu da basit anlamda gerçek değere 128 eklenmesi demektir. Burada gösterilebilecek en küçük üs 0 olarak saklanan -128'dir. Mümkün olan en büyük üs ise 255 olarak saklanan 127'dir. Bu üslerin aslında 2'nin kuvvetleri olduğunu hatırlayın. Normalize mantis dört baytta saklanır. Ancak burada bir karmaşık nokta daha var. Mantis önceden normalize edildiğinden (radix noktası en soldaki 0 olmayan bit'in soluna getirildiğinden) en soldaki bit'in daima 1 olduğunu gördük. İşte burada çok akıllıca bir mantık devreye giriyor. Çok dikkatli okuyun. Üssün, mantis'in en soldaki bit'i daima 1 olacak şekilde düzenlendiğini biliyoruz ve bu yüzden burada yani en soldaki bit'te 1 değerini saklamamız gerekmiyor. Esasında, bu bit mantis'in negatif mi yoksa pozitif mi olduğunu göstermek için kullanılıyor. Eğer mantis negatif ise en sol bit'te 1 saklanıyor. Eğer pozitif ise burada saklanan değer 0 oluyor. Ancak en soldaki bit'te ne saklandığına bakmaksızın bu bit'in değerinin daima 1 olduğunu biliyoruz (en azından bilgisayar biliyor). Bu bit'te ayrıca ne saklandığına bakarak mantis'in işaretini öğreniyoruz. Çok akıllıca, değil mi? Şimdi programımıza geri dönelim ve bilginin nasıl okunup gösterildiğini görelim. X0 değişkeni için üs ve 4 mantis baytı S1-S5 adreslerinde yer alıyorlar. Satır 260 bu adreslerin sakladıkları değerleri bulmak için PEEK komutunu kullanıyor. Bu 5 bayt V1-V5 değişkenlerinde saklanıyor. Satır 1010'daki rutin bu 5 baytı yazıyor ve yorumluyor. Üs, satır 1030'da “128-fazlasını” çıkartarak hesaplanıyor. Mantis ise satır 1040'ta diğer 4 bayttan bulunuyor. V2 mantis'in en soldaki baytını saklıyor. En soldaki baytının daima 1 olması gerektiğini hatırlayın. 128 OR V2 ifadesi gerçek değerine bakmaksızın bit'i 1 yapıyor. İlk mantis baytının 256'da birlerin sayısı olarak düşünülebileceğini görmüştük. İkinci mantis baytı (1/256) pozisyonundadır. Benzer şekilde üçüncü ve dördüncü mantis baytları (1/256)^2 ve (1/256)^3'ü temsil ederler. Satır 1040 mantis'in değerini hesaplamanın etkili bir örneğini göstermektedir. Çömez bayt (en sağda

4

ALAK EMRE KİNG 161 65 AK ORK AK ORK ÖR OK AR OK OR OK AK OR RK OR OK OK KAR AK OR KR ORK AR OR KR KK OR AK OK OR KOK O OK OK OR KOK KK olan) V5 önce 256'ya bölünür. Sonraki bayt olan V4 buna eklenir ve sayı tekrar 256'ya bölünür. Şimdi V5'i 2562'ne bölmüş olduk. Bundan sonra çıkan sayı V3 ile toplanır ve tekrar 256'ya bölünür. Son olarak düzeltilmiş en önemli mantis bayt'ına V2 eklenir ve çıkan 256'ya bölünür. Şimdi kendinizi satır 1040'taki MN değişkenin aşağıdaki değeri sakladığına inandırmanız için biraz cebir alıştırması yapmaya gerek duyabilirsiniz. V2/256 4 V3/2562 4 V4/2563 * V5/2564

Burada, her basamağı basamak değeriyle bölerek ondalığa çevirdiğimiz 0.1101 örneğine benzer bir mantık güdülmektedir.

1/2 4 1/4 4 0/8 4 1/16 — 1/2 * 1/22 4 0/23 4 1/24

Satır 1050 en önemli baytın (EBÖB) değerini kontrol ederek mantis'in işaretini (SN) belirliyor. V2'nin EÖB'si ancak eğer bit 1'e eşit olduğunda 128 veya daha büyük bir değere sahip olur. Bu yüzden bütün negatif mantisler 128'e eşit veya büyük ve bütün pozitif mantisler 128'den küçük bir

V2 değeri alırlar. Satır 1060, hesaplanan işaret, mantis ve üs ile X0 değişkeninin gerçek değerini gösterir. Program aslında gerçekten SN*MN*2^EX hesaplamasını yapmamaktadır, çünkü çarpım ve üs almayı yuvarlak hale getirirken meydana gelen hatalar sonuçların doğruluğunu kısıtlamaktadır. Eğer isterseniz bu hesabın sonucu verecek ifadeyi programa kendiniz koyabilirsiniz. Eğer program içinde X'e basarsanız program değer girme moduna girer. Bu modda X0 değişkeninde saklanacak 5 baytı kendiniz verebilirsiniz. Bu sefer satır 1010'daki aynı rutin bu değerleri üs/mantis düzenine dönüştürecektir. 5. baytı (V5) hafifçe değiştirdiğinizde X0'ın gösterilen değerinin değişmediğini göreceksiniz. Ekranda gördüğümüz sayılarda bu sık sık olmaktadır. Örneğin, 64'ün karekökünün (SQR(64)) 6'dan ne kadar farklı olduğuna bakalım. Programın 20. satırı X0'ı 36'nın karekökü olacak şekilde tanımlamaktadır. Eğer programı ilk çalıştırdığınız anda direkt RETURN tuşuna basacak olursanız, X0 değerini koruyacaktır. SQR(64) için saklanan baytlar şu şekilde gösterilir:

131, 64, 0, 0, 1 Şimdi 6 değerini girin ve bu sefer: 131, 64, 0, 0, 0 şeklinde saklandığını görün. Çömez baytın 1 sayılık farkı, ekran gösterimi açısından önemli değildir. Ancak iş 6 ile SQR(36)'yı karşılaştırmaya gelince bu fark önem kazanır. Şimdi X'e basarak mod değiştirin. 131, 64, 0, 0, 2 değerlerini girin. Bu değer ekranda 6.00000001 olarak gösterilecektir. Bu deneyi başka sayılarla yapın ve ekranda gösterilen değerin iç değerlerdeki değişmelere karşı ne kadar hassas olduğunu görün. Konuyu toparlarken bu programla tam olarak neyin gösterildiğinden emin olmanız için, SQR(36)'ya eşit olan X0'ın sonuçlarını inceleyelim. Bir kez daha SQR(36)'nın iç değerleri 131, 64, 0, 0, 1'dir. Üs 131 eksi 128, yani 3'tür. Mantis'in EÖB'si 64, yani ikili olarak 01000000'dir. Bu baytın en solundaki bitin 1 olarak düşünüldüğünü hatırlayın. Burada 0 olması onun pozitif bir mantis olduğunu göstermekte.

Bu baytın en soldaki bitini ondalık karşılığı 192 olan 11000000 olacak şekilde 1 ile değiştirin. Şimdi sağdan sola doğru gösterilen değerleri kullanarak mantis'i hesaplayalım.

mantis = (((1/256 + 0)/256 + 0)/256 + 192)/256 veya mantis = 1/256^4 + 192/256 = 1/4294967296 + 0.750 000 000 233

Sonra bu mantis'i 3. kuvvetinde olan 2 ile çarpalım.

sonuç = 0.750000000233 * 23 = 6.00000000186 = 6 (9 önemli basamağa kadar yuvarlanmış halde). Diğer sayılarla da denemeler yaparak BASIC dilinin iç matematik yapısını daha iyi ve daha etraflıca anlayacaksınız. Artık bu değerleri programda deneyerek neden 1.70141183E38'in mümkün en büyük ve 2.93873588E-39'un en küçük değer olduğunu görebilirsiniz. Bir daha sefere birisi size bilgisayarların asla hata yapmadığını söyleyecek olursa, ona ilk örneğimizi gösterin ve neden bilgisayarın 36'nın karekökünün 6'ya eşit olmadığını düşündüğünü anlatın. Eğer onların sınırlamalarını bilmez ve çalışma prensiplerini anlamazsak bilgisayarlar şüphesiz hatalı duruma düşeceklerdir.

BİR

SAYIYI BİLGİSAYAR İÇİNDE SAKLANDIĞI ŞEKLE ÇEVİRME

10.234 sayısını alalım. Bu değerin floating-point karşılığını şu şekilde hesaplayabilirsiniz: 1. Bölüm 0.1 ile 1 arasında olana kadar değeri 2'ye bölün:

10.234/2 = 5.117 5.117/2 = 2.5585 2.5585/2 = 1.27925 1.27925/2 = 0.639625

Bu, 4 bölme işlemi aldığından üs değerimiz 4 olacaktır. Üssü 128 fazlası düzenine çevirin: 4 + 128 = 132 2. Son bölümü 256 ile çarpın:

0.639625 * 256 = 163.744

Mantis'in EÖB'ı olarak bu sayının tamsayı kısmını (163) alın. Ancak 128 çıkartın (çünkü 128'den büyük ve orijinal sayımız olan 10.234 pozitif)

Mantis EÖB = 163 - 128 = 35

3. Önceki sonucun kesirli kısmını alın (0.744) ve 256 ile çarpın:

0.744 * 256 = 190.464

Mantis'in sonraki EÖB'ı bu sonucun tamsayı kısmıdır.

Mantis bayt 2 = 190

4. 3. adımı mantis'in son iki değerini bulmak için iki kez daha tekrar edin:

0.464 * 256 = 118.784 Mantis bayt 3 = 118 0.784 * 256 = 200.704

Bu son değeri en yakın tam sayı olan 201 ile yuvarlanmış hale getirerek Mantis'in çömez bitini elde edin.

Mantis ÇB = 201

5. 10.234 sayısı bilgisayarda aşağıdaki gibi saklanacaktır:

132 35 190 118 201

Bu sonucun sağlamasını yazının sonundaki programla yapabilirsiniz.

PROGRAM ADI * FP CEVİRİCİ 00300 REM SAKLANAN
FLOATIİNG-POİNT'E <1863>
80010 PRİNT "<CLROFLOATİNG-POİNT CEVİRİCİ 00310 PRİNT 3PRİNT DEGİSTİRMEK İCİN
sı: <aa3> XI CİKMAK ICİN G TUSLARINA BASIN)" <a23>
00015 PRİNT — — 00320 PRİNT * SAKLANAN 5 DEĞERİ GİRİN
KO İLK DEGİSKEN OLM 255) 1 >
ALI <820> — 00330 INPUT “İLK
00030 >" <216> — 00340 IF THEN PRİNT
©0040 DEF 218 <193>
FAZI NOT <813> — 00350 IF THEN END <a1s>
00070 İF THEN <163> — 00360 INPUT “İKİNCİ VezVALCX
©0080 THEN REM DEĞİ <188>
SKEN BASLANGIC <875> — 00370 INPUT "UCUNCU
00090 DEGİSKEN BASLANGI 24) <esa>
cı <157> — 00380 INPUT "DORDUNCU
00100 <e36>
SV*E:REM KO'IN SAKLANDIĞI ALAN — 00388 INPUT "BESİNCİ
90110 IF NOT THEN BANKI caza>
REM SA ©0400 POKE Sİ,Vİ:POKE S3,V31PO
KLANAN DEĞERLERE 2: KE 84,VA:POKE S5,VS
60210 PRİNT "(MOD DEGĞİSTİRMEK İCİN XI CİK 60410 GOSUB 1616 <144>
MAK İCİN G TUSLARINA BASIN)" — 31a
PRİNT "FLOATİNG-POİNT DEGERİNİ GİRİ 01000 REM HESAPLAMA <ess>
Noam <875> 81010 PRİNT Ve; V3r Var VS <aaı>
INPUT X&TİF THEN 260 <215> REM -- US, MANTIS, İSARET - <aa7>
©0230 IF THEN END <017> 01030 <136>
©0240 IF THEN PRİNT 01048
316 OR Va)y/ase
<187) THEN SN<-1 <as3>
00260 (S2) (S3 01060 PRİNT *<RVSOFF
(S4) (S5) *<RVSOFF>
#0270 GOSUB 1018
218 <834> — g1aza RETURN <cite>

»

GN | dd

Modern ve verimli diller BASIC'i liderlik koltuğundan etmeye çalışıyorlar. Bu yeni lider adayları, amaçlarına erişecek yeteneğe sahipler mi?

Kullanıcı kendisi için en doğru programlama dilini ararken, zorunlu olarak program oluşturmanın farklı yöntemleriyle karşı karşıya gelir. Burada kullanıcının karşısına çıkan, “Top-Down”, “yapılandırılmış” ve hatta “modüler” gibi kavramlardır. Özellikle bu bu kavrarnların son ikisi, Commodore 64'ün BASIC'inden başka bir dile geçmek isteyen kullanıcı açısından, oldukça yabancıdır. İlk kavramın adlandırdığı yöntemi o zaten kendi C-64'ünde kullanmaktadır: Program, tek bir parça (dolayısıyla bir bütün) olarak yazılır, önceden katı kurallarla belirlenmiş bir yapıya sıkı sıkıya uygun olmak zoründadır. Bu yapı satır numaralarından başlar, kılı kırk yararcasına sıkı dikkat isteyen syntax (yazım) denetimine kadar uzanır. yapılmak zorunda kalınan bir sürü atlama, programın okunabilirliğini giderek ortadan kaldırır. İki haftalık bir uğraşın sonunda kullanıcı, bir sürü ufak değişiklik sonucunda ortaya çıkan asla okunamayacak haldeki bilmecelerle karşı karşıya kalır. bu durumun çözümünü belki Assembler (Makine dili) sağlayabilir. Dergimizin eski sayılarında Baytan Bitirmez arkadaşımızın makine dilini öğreten bir dizisi yayınlan- Makine diline geçmeyi arzu etmeyen kullanıcılar ise bunun alternatiflerini aradıklarında, C-64 ve C-128 için favori diller olarak PASCAL, COMAL ve C'ile karşılaşacaklardır.

62

Bu diller arasında doğrudan bir karşılaştırma denemesi pek başarılı olamaz, çünkü aralarındaki büyük farklar bu türden bir denemeyi boşa çı- . Yalnız bu üç dilin ortak bir özelliği olduğu söylenebilir (bir istisna dışında): Bu diller hem C-64 hem

Yalnız C dili henüz sadece C-128'de kullanılabiliyor. Haydi bu dil karmaşasının içine doğru' bir geziye çıkalım. İlk hedefimiz COMAL.

BASIC 4 PASCAL - COMAL

COMAL (COMmon Alghorithmic Language), 1973 yılında doğdi Amaçlanan, programcı olmayan şilerin kolayca öğrenebileceği ve aynı zamanda üstün bir programlama dilinin gereklerini yerine getirebileci bir dil oluşturmaktı. Dili geliştirenler, BASIC'in basitliğiyle PASCAL” ın verimliliğini tek bir dilde kaynaştırmak istiyorlardı. Bu dildeki bazı komutları BASIC'- ten tanıyorsunuz. Aslında bunların hepsi, yapı komutları. Döngüler yalnızca FOR...NEX ile oluşturulmuyor. Bu dilde daha çok REPEAT. NTIL, WHIİLE...ENDWHILE, CA-SE..ENDCASE ve IF...THEN...EL-SE.....ENDIF gibi yapılar kullanılıyor. Bu döngü komutlarının yardımıyla, GOTO komutunda ortaya çıkabilen açık olmayan atlamalar engellenebiliyor. Belki buna inanmayacaksınız, ama GOTO'yu tümüyle unutabilirsiniz bu dil “yapı katili” olmadan iş beceremeyenler, COMAL içinde de GOTO'yu kullanabilirler. Commodore 64 için farklı iki COMAL versiyonu va Versiyonlardan biri olan 0.14, Public Domain disket olarak alınabiliyor. Diğer versiyon ise PC'lerdeki öncellerinden daha verimli olduğu iddia edilen bir kartuş. COMAL geliştirilirken PASCAL'- ın örnek alınmış olduğu olgusu, yalnızca yapı komutlarından kaynaklanmıyor. Programcının işini son derece kolaylaştıran bir olanak, prosedi leri programının içine eklemleyebilmesi. Burada açıklayıcı bir söze gerek var. C-64 BASIC, prosedür tanımaz, bu dilde prensip olarak yalnızca altprogramlar sözkonusudur. CO-MAL 'da bu altprogramlar BASI: te olduğu gibi GOSUB ile çağrılmazlar, her birinin kendine özgü adları vardır. Böylece satır numaralarını içeren atlamalara gerek kalmaz. Prosedür, kendi adıyla çağrılır. PROC ile ENDPROC arasındaki tüm komut- Tar yerine getirilir. Bu sayede prı

WHİLE yapısı

(WHİLE koşulu DO

ENDWHİLE )

Komut listesi

REPEAT Yapısı

REPEAT

UNTİL koşulu

Komut listesi LOOP yapısı LOOP —( ENDLOOP Komut listesi

EXİT WHEN koşulu ram açıkça görülebilen modüllere ayrılmış olur. Bunlar ileride ana programda hiçbir değişiklik gerektirmeksizin kendi içlerinde değişiklikler yapılmasına olanak sağlarlar. Prosedürlere değerler aktarılabilir: Bu da BASIC programcısının hiç tanımadığı bir olgudur. İyi, BASIC'te programcı ana programda kullanılmış olan değişkenlerle çalışır. Peki, değişkenin değiştirilmemesi gerektiğinde ne yapar? Bu durumda COMAL, değişkenlerin kalize edilmesi olanağını verir. Programcı, bir değişkenin bir prosedür içinde, ana programın içinde ya da yalnızca tek bir alt programın içinde erişilir olup olmadığını belirleyebilir. Böylece doğabilecek bir isim karmaşası baştan engellenmiş ve programın tüm kısımlarına bakabilme olanağı da korunmuş olur. COMAL, bu prosedürleri diskette depolayabilir, böylece programın uzunluğu yalnızca disket kapasitesiyle sınırlı hale gelir. Fonksiyonlar, prosedürlerle akraba sayılabilirler. Bunlar ek olarak değerleri geri verme olanağı da sağlarlar. Bir fonksiyonu çağırıp buna bir değer aktarabilir, bunu işleyebilir ve bir sonuç elde edebilirsiniz. Böylece bir fonksiyon bir değişkene bağlanabilir. Açımlamalar biraz karmaşık olan bu konuyu daha kolay anlaşılır hale getirebilir. COMAL dili, C-64'ün verimlilik düzeyini çok aşmayı sağlayan bazı başka komutlar da içerir. Grafik ve ses, COMAL'ın kendine özgü komutlarının yardımıyla sorunsuz bir biçimde yazmakta olduğunuz programa sokulabilir. Grafik alanında COMAL'ın yeteneklerini ölçebilmek için Resim 2 bir fikir verebilmektedir. Burada makine dilinin herhangi bir katkısı yoktur. Ama COMAL, hemen tüm diğer dillerde olduğu gibi makine rutinlerine eklenme olanağı da sağlamaktadır. Tüm bu olanakların yanı sıra dosya yönetimi ve Floppy erişimi için kapsamlı komutlar içeriyor olması, COMAL'da yazılmış kapsamlı programların herhangi bir engelle karşılaşmamasını sağlıyor. COMAL hakkında anlatılanlardan etkilendiyseniz, kısa sürede bir COMAL disketi ya da kartuşu edinmeye çalışın.

Resim 1: Önemli Comal yapılarının yazım diyagramları

PASCAL

Gezimize devam edip PASCAL'a geliyoruz. Bu dil COMAL'a örnek olmuş. Aralarındaki en önemli fark ise, dilin türünden kaynaklanıyor. Gerek COMAL gerekse BASIC'in tümüyle çevirici diller olmalarına karşın, PASCAL yalnızca karşılık gelen bir derleyiciyle birlikte kullanılabiliyor. Bunu zorunlu kılan, tüm derleyici dillerde ortak olan bir özellik: Değişkenlerin programın başında tanımlanmaları zorunlu. Hepiniz bunu C-64 BASIC'inden tanıyorsunuz. Bu durumda programın içinde bir yerde ortaya çıkan bir değişkeni çevirici önceden tanıyor olacaktır. Ayrıca hemen bu değişkenin türünü de (sayısal ya da harfsayısal) belirleyecektir. Çevirici program olarak daima “birlikte işlediğinden”', bir değişken için gerekli bellek alanı onun ilk ortaya çıkışında ayrılmaktadır. Derleyici, bir PASCAL programından tümüyle kendi başına işleyebilen bir makine dili programı üretir. Bu sırada değişkenler için gerekli yeri sağlayan bir çevirici sözkonusu değildir. Dolayısıyla derleyicinin baştan hangi değişkenlerin kullanılacağını, bunların uzunluklarını bilmesi ve derleme sırasında gerekli alanı buna göre ayarlaması gerekir. Bu nedenle PAS-CAL'de değişkenler programın başlangıcında deklare edilir. Zorunlu olarak gereken komutlar bu sırada koyu olarak yazılırlar. BASIC'ten tanıdığımız üç farklı değişken türü vardır: Integer (tamsayı), Floating Point (kayar nokta) ve String (yazısal dizi). Bugün piyasada bulunabilen PASCAL versiyonları, beşer tamsayı ve kayar noktalı sayı türleri içeriyorlar. Bunlara bir de yalnızca “doğru” ve “yanlış” olarak denetlenen Boole değişkenleri ekleniyor. Bunlar genellikle döngü koşullarında sık kullanılıyor. Herhalde en zor kullanılan tür, göstergeyle sunuluyor. Bu gösterge değişkeni, örneğin sizin verdiğiniz bir değeri içermez. Çoğu zaman burada değerin bellekte bulunduğu yerin başlangıç adresi gizlidir. Resim 3, bu soyut süreci açıklamayı amaçlamaktadır. Bir başka ilginç veri türü ise RECORD (kayıt) olarak adlandırılır. Bu tür, özellikle dosya yönetiminde kullanılır. Buna ufak bir örneği Resim 4'te görebilirsiniz. Tüm RECORD kendine özgü bir ada sahiptir. Bunun içindeki ögeler, yine, RECORD'la ayrılamaz biçimde bağlı olan bağımsız değişkenler oluştururlar. Bunlar yalnızca RECORD'un adıyla birlikte anılabilirler. “isim” değişkenini ““ad- RECORD'unda işlemek isterseniz, programda şu tanımlamayı yapmanın gerekir: Adres-isim Bu karmaşık yazı biçiminden kurtulunabilmesi için, PASCAL'da DO-WITH komutu vardır. Bu yolla RE-CORD adının verilmesi gereksiz hale gelir. Bu veri türü en çok dosya yönetimi alanında kullanılır. Çünkü komple veri cümlelerinin işlenmesini çok kolaylaştırır. Tabii ki PASCAL, dosyaların işlenmesi için gerekli tüm komutlara sahiptir. Henüz var olmayan, hızlı bir biçimde kendine özgü prosedür ya da fonksiyon olarak programlanmasıdır. Prensipte bunlar da aynen COMAL'daki gibi çalışır. Ama parametre aktarımı sırasında prosedür ya da fonksiyon için değişkenlerin yeniden deklare edilmesi zorunludur. Bir prosedür içindeki değişkenler daima yerel olarak geçerlidir. Derleyicinin verimiyle bağlantılı olarak, tüm program için kullanılabilecek daha global değişkenlerin deklare edilmesi olanağı bulunabilir. Böylece PASCAL'in önemli fonksiyonlarını sıralamış olduk. Derleyiciyi satın alırken dikkat etmeniz gereken konu, verimliliğin derleyiciden derleyiciye değişebilirliğidir. Bu durum özellikle C-64/C 128 için grafik ve ses yeteneklerinin kullanılabilmesi açısından önemlidir.

Resim 2. Comal, C-64'ün tüm grafik özelliklerini kullanır.

Modern: C

Genç bir dil son zamanlarda PASCAL'i geçmeye çalışıyor: C. Bu dil, aslında işletim sistemi Unix olan büyük makineler için geliştirildi. Ama ev bilgisayarları ve kişisel bilgisayarlarda da yaygın bir ilgi gördü. AMIGA ya da Atari ST gibi bilgisayarlarda işletim sistemleri zaten C ile yazılmış durumda. C'nin komut sayısının düşük olması, işletmek için küçük bir makine dili gövdenin yeterli olmasına olanak veriyor. Aslında tüm C derleyicileri 28 ana komutun dışında da komutlar içerirler. Ama bu ek komutlar aslında C komut seti yardımıyla oluşturulmuş fonksiyonlardan başka bir şey değildirler. Bilgisayar basınında C, daima “makineye yakın” bir dil olması nedeniyle övgü almaktadır. Tabii bu durum işletim sistemi C ile yazılmış makineler için söz konusudur. Burada tüm rutinler önceden kullanıma hazır vaziyettedir. Program-

“a” değişkeni, “München” metnine ilişkin bir göstergedir.

0300H
$ 0300H'nın içeriği
Bİ ü
KA
2
im
& c
h

0305H

Resim 3. Göstergeler, yalnızca adresleri içeren değişkenlerdir.

ramcı her fonksiyonla işletim sistemine erişebilmektedir. Buna ek olarak tüm C derleyicilerinde tüm önemli fonksiyonları içeren kapsamlı kütüphaneler yer almaktadır. Artık yalnızca PASCAL konusunda anlattığımız gösterge tekniğini kullanır hale gelmeniz yeterlidir. Aksi takdirde C ile uğraşırken çok kısa sürede pes edebilirsiniz. C'de bir derleyici dil olduğundan, değişkenlerin daima, programların ya da fonksiyonların başında tanımlanmaları gerekmektedir. Tabii C'de de, COMAL'de ve PASCAL'de olduğu gibi, tüm yapı komutları mevcuttur. C'de bir prensip daha var: Programcı istediği her şeyi yapabilir. Ama bu durum, olağanüstü disipline edilmiş bir programlama stilini zorlar, derleyici yalnızca syntax (yazım) hatalarını fark eder. Hatalı harf bileşimleri, döngülerde hatalı üst sayılar ya da alan taşmaları çoğu derleyiciyi pek ilgilendirmez. Bu durumlarda hatanın aranması bir işkenceye dönüşebilir. C-128 kullanılırken -C-64 için henüz bir C derleyicisi yoktur- C derleyicisi yalnızca dilin öğrenilmesine yarar. Daha büyük program paketlerinin oluşturulmasında C dili C-128'e pek uygun değildir. Ayrıca C-128'de C'nin hızı BASIC'inkinden pek fazla değildir. Ama mutlaka C diline girmek isteyen bir kullanıcı, biraz daha paradan çıkmayı göze alıp farklı bir bilgisayar satın almayı tercih etmelidir.

BASIC'in işi bitti mi?

Buraya kadar anlattıklarımıza göre BASIC çoktan unutulmuş olmalıydı. Yapılandırılmış programlama olgusu, C-64 BASIC'e tümüyle yabancıdır. C-128'de prosedürleri ve fonksiyonları tanımaz. Bütün bunların BASIC'i turnuvadan elemeye yeterli kusurlar olduğu zannına kapılabilirsiniz. Fakat bir şeyi kesinlikle unutmamak gerekiyor: BASIC eskiden olduğu gibi şimdi de en çok kullanılan dil. Bir defa BASIC, makinenin içinde yer almış durumda. Yani makineyi açtığınız anda BASIC'e erişiyorsunuz. BASIC'le çok kapsamlı programlar yapmayı başarmış olan her kullanıcı, bu iş sırasında mutlaka sık sık sınırlara çarpmıştır. İşte bu noktada PASCAL ve COMAL gerçek birer alternatif oluşturmaktadırlar. Son derece kapsamlı görevler kolayca ve makine diline gerek duyulmaksızın yerine getirilebilmektedir. Geriye kalan tek sorun mali konudadır, bu da her kullanıcının kendisinin çözmesi gereken bir sorundur.

Resim 4. Pascal'da RECORD'lar, dosya işlemesini kolaylaştırırlar.