1541'i Anlamak (9)

Eveeet, sevgili arkadaşlar... Uzun süren 1541 muhabbetinin de sonuna geldik. Bugün, önce eski bölümlerdeki bazı baskı hatalarını düzelteceğiz. Sonra DISKMON ile ilgili bir iki ufak ayrıntıyı açıklayıp esas konumuza geleceğiz. Esas konumuz, relatif dosya kullanımı... İlk hata 23. sayının düzeltmelerle ilgili paragraflarında. Şimdi o sayının 54. sayfasının ilk kolonunun son 6 satırına bakın. Bahsedilen karakterin doğrusunun O olmadığını herhalde anlamışsınızdır. Doğrusunu klavyedeki P ve * tuşları arasındaki tuşun üzerine bakarak görebilirsiniz. Hemen bundan sonra gelen 3-5 satırda (yani ikinci sütunun başları) gördüğünüz PRINT, INPUT ve GET komutlarının arkasında boşluk değil, diyez işareti olacaktı. Şimdi, 55. sayfanın orta sütunundaki dört satırlık programa bakalım. İlk satırı hatalı görünüyor, değil mi? Tabii ki, 70 sayısı yerine TO kelimesi gelecekti. Eşittir'den sonra da, | rakamı olmalıydı. Yani doğrusu:

40 FOR I-1 TO 256

Aynı sayfanın en sonunda başlayıp diğer sayfada devam eden program da hatalardan payını almış. 20 numaralı satırında tırnak işaretleri arasında diyez işareti olacaktı. Gelelim 56. sayfaya... Orta sütundaki programın 170 numaralı satırında iki tane 18 var. İkincisi 19 olmalıydı. 57. sayfada ise üç değişik hata yakaladım. İlk sütundaki uzun programın 140 numaralı satırındaki eşittir işareti yerine artı işareti gelmeli. Orta sütundaki son programdan önce gelen cümlede, “Örneğin bunu 8 yapalım” deniyor. Halbuki, 9 yapmaya çalışıyoruz. 57. sayfadaki son program örneğinin 30 numaralı satırında da bir gariplik var. Tabii ki, I harfi ile 1 sayısı arasında eşittir karakteri olmalı... Sıra geldi 24. sayıdaki hatalara. Bu sayı 23. sayı kadar zengin değil, ama hatalar genellikle program örneklerinin içine sızmış. Kötü sonuçları olabilir... İlk hata 35. sayfanın orta sütunundaki dört örnek programdan üçüncüsünde. 70 numaralı satırında yeralan I harfi yerine 1 rakamı gelmeli. Sağdaki kolonun ilk programında da, 20 numaralı satırdaki N$ yerine X$ yazmazsanız, program bir işe yaramaz. Şimdi 36. sayfaya geçelim. 5-110

Sıralı dosyaların en büyük sorunu, ortalardaki bir kayıt için dosyanın en baştan okunması ve ortadaki bir kayıtta doğrudan değişiklik yapılamamasıydı. Relatif dosya kullanımı ile bu sorunlar ortadan kalkıyor.

arası satır numaralarına sahip uzun programın içinde muhtelif hatalar var. İlk hata 30 numaralı satırda. Bu satırdaki ikinci eşittir karakteri yerine dolar sembolü gelecekti. 42 ve 45 numaralı satırlarda ise PRINT komutlarının ardından önce diyez karakteri, sonra 2 rakamı gelmeliydi. 56 numaralı satırdaki büyüktür işaretinin solunda bir de küçüktür işareti yeralmalıydı. 24. sayıdaki son hata 36. sayfanın sağ kolonunun alttan 24. satırında (boş satırları saymıyoruz) O satırda yeralan 8 rakamı yerine A harfi gelmeli. Gelelim DISKMON üzerine söyleyeceklerimize... İnşallah görmüşsünüzdür, 25. sayının Program Döküm Eki'nin son sayfasında DISKMON'a dair bir düzeltme yeralıyor. O olmadan DISKMON'u çalıştıramazsınız. Eğer bir okuyucumuz bizi uyarmasaydı, imkanı yok bu hataların farkına varamazdık. Teşekkür ederiz. Eğer hâlâ başka hatalar varsa, çekinmeden mektup yazabilirsiniz. DISKMON ile açıklamaları yaptığımız sayımızda, birkaç noktayı anlatmayı unutmuşuz. DISKMON'dan X vererek çıktığınızda, ekranın sol üst köşesinde bazı komutlar yazar. Bunlar, BASIC'inize DISKMON tarafından kazandırılmış yeni birkaç komuttur. Şimdi bu komutları birer birer görelim. DLOAD: Disketten bir program yüklemek için kullanılır. DLOAD"isim" şeklinde kullanılır ve 8 ile aynı işi yapar. Eğer ekranda disketin directory listing'i varsa, programın adının olduğu satırın başına DLOAD yazıp RETURN tuşuna basmak yeterli olacaktır. Eskiden LOAD yazmak ve sonra da ismin sonuna ,8: koymak gerekiyordu. Ancak DLOAD komutu LOAD"isim",8,1 yerine geçmez. DSAVE: Diskete bir program save etmek için kullanılır. Kullanımı DSAVE"isim" şeklindedir ve SAVE"isim",8 komutunun yaptığını yapar. DVERIFY: Disketteki bir dosya ile hafızadaki programı karşılaştırarak aynı olup olmadıklarını kontrol eder. DVERIFY olarak kullanılır ve VERIFY ile aynı işe yarar. DIR: Disketin directory'sini ekrana listelemekte kullanılır. Sadece DIR olarak yazılır, parametresi yoktur. DISKMON'un içinden çağrılan $ komutu ile aynı şekilde davranır. Dosya isimleri yirmişer yirmişer yazılır. Bu bekleme sırasında RUN/STOP ile listeleme durdurulabilir veya başka bir tuş ile sonra gelen dosya isimleri görülebilir. DISK: 1541'e bir komut göndermeye yarar. Kullanımı DISK"komut" şeklindedir. Normal BASIC'de kullanılan OPEN 1,8,15,"komut":CLOSE 1 komut dizisine karşılık gelir. DERROR: 1541'in hata kanalını okur ve gelen mesajı ekrana yazar. DMON: X ile DISKMON'dan çıktıktan sonra DMON ile tekrar DISKMON'a dönebilirsiniz. Aynı işi SYS 49152 ile de yapabilirsiniz. Artık gelelim bu ayın asıl konusuna: Relatif dosyalama... Geçen sayıda derinlemesine incelediğimiz sıralı dosyaların en büyük sorunu, ortalardaki kayıtları okumak için dosyanın en baştan okunmaya başlanması (yani, inanılmaz zaman kaybı) ve orta yerdeki bir kaydın üzerinde doğrudan değişiklik yapılamaması idi. Relatif dosya kullanımı ile evvelallah bu sorunların üstesinden geleceğiz. Relatif dosyalamada her kaydın bir numarası vardır. Önemli olan, her bir kaydın aynı uzunlukta olması gerekliliği. Her bir kaydın uzunluğu aynı olduğu ve önceden bilindiği için ve aynı zamanda dosyanın disket üzerinde nerede başladığı da bilindiği için, DOS'un herhangi bir kaydın yerini çabucak bulması mümkün olmakta.

Relatif kelimesi de buradan gelmekte. Aranan kayıt, dosyanın başlangıç adresine oranla (relatif veya göreceli olarak) bulunmakta. Relatif dosya kullanımını aşağıdaki taslağa göre biçimlendirebiliriz: Bir relatif dosya hazırlamak: 1) Dosya açılır ve bu arada bir kaydın kaç karakter uzunlukta olduğu belirtilir. 2) Başlangıç için kaç tane kayıt için yer ayrılması gerektiği bildirilir. 3) Dosya kapatılır. Açılmış bir relatif dosyaya yeni bir kayıt yazmak: 1) Dosya açılır. 2) Yeni kaydın kaç numaralı kayıt olduğu bildirilir. 3) Kayıt yazılır. 4) Dosya kapatılır. Açılmış bir relatif dosyadan eski bir kaydı okumak: 1) Dosya açılır. 2) Okunacak kaydın kaç numaralı kayıt olduğu bildirilir. 3) Kayıt okunur. 4) Dosya kapatılır. Genel hatlarını bu şekilde verebileceğimiz olayın ayrıntılarına girelim Relatif dosya açarken de OPEN komutunu kullanıyoruz. Önce genel formatını görelim:

OPEN dn,8,ia,“dosya,L,”
* CHR$(uzunluk)

“DN” (dosya numarası) ve “İA” (ikincil adres) parametrelerini sıralı dosyalardan biliyorsunuz. Geçen sayımızda da belirttiğimiz gibi “ia” ile belirlediğiniz ikincil adres aracılığı ile DOS'a bir kanal ayırmasını söylüyorsunuz. Ve gene geçen bölümümüzde söylediğimiz gibi, dosyalara ayrılabilecek en fazla üç kanal olduğu için aynı anda iki relatif dosyanın açık olması imkansız. Çünkü relatif dosyalar, bu yazının ileri bölümlerinde göreceğiniz nedenlerle, iki kanal birden kullanır. Bu nedenle, eğer bir relatif dosya açıksa en fazla bir de sıralı dos-

ya açık olabilir. Tabii bu, iki relatif dosyayı aynı anda kullanamazsınız demek değil... Yapacağınız, ikincisini kullanmadan önce, birincisini CLOSE ile kapatmak. Biz yine OPEN komutumuza dönelim. Dosya adından sonra yazdığımız L harfi, DOS'a verdiğimiz isim altında relatif dosya açmasını belirtir. Arkasından gelen byte'da da dosyanın bir kaydının kaç karakter uzunluğunda olduğu saklıdır. Dikkatli okuyucular hemen görmüşlerdir. Bir kaydın uzunluğunu vermek için CHR$ komutunu kullanıyoruz. Ancak CHR$'in parametresi 0-255 arası bir değer alabilir. Demek ki, daha uzun kayıtlar kullanamıyoruz. Aslına bakarsanız relatif dosyalarda herbir kaydın uzunluğu en az 1, en fazla da 254 karakter olabilir. Bir başka deyişle, hiçbir kayıt bir bloktan uzun olamaz. Eh, bir blok 256 karakter aldığına ve bunların ilk ikisi dosyada bir sonra gelen blokun adresini gösterdiğine göre bize 254 byte yer kalıyor. Örneğin K adında bir relatif dosya açalım. Bu dosyanın içine stok bilgilerimizi yazalım. Stoktaki her kalem mal için saklanacak bilgiler ve uzunlukları da şöyle olsun:

Kayıt numarası: 4 basamak İsim: 15 karakter Mal kodu: 5 karakter Alış fiyatı: 6 basamak Satış fiyatı: 6 basamak karakter eder. Demek ki, her kaydımız 36'şar karakter uzunluğunda olacak. Şimdi böyle bir dosya yaratalım.

OPEN 1,8,2,“K,L,” 4 CHRS$(36)

Şimdi, dosya açmanın ikinci adımına geçelim. Ne demiştik? Başlangıç olarak kaç tane kayıt için yer ayrılması gerektiğini bildirmeliydik. Bunun için de yapacağımız iş, DOS'a son kayda bir şey yazmasını istemek olacak. Başlangıçta hiçbir kayıt yoktu ve dosyada da yeni kayıtlar için hiçbir yer ayrılmamıştı. Ancak diyelim ki biz 100 numaralı kayda bir şey yazmak istedik. Bu durumda DOS'un yapacağı iş, önce RECORD NOT FOUND hatasını vermek (ki, bunu hiç dikkate almıyoruz. Çünkü DOS, hata vermesine rağmen işine devam ediyor) ve sonra da 1-100 arası kayıtlar için yer hazırlamak olacaktır. En sonunda da 100 numaralı kaydın üzerine istediğimiz bilgiyi yazacaktır. Demek ki, relatif dosya açmak ile relatif dosyaya bir kayıt girmek birbirine çok yakın. Öyle ise sırası gelmişken, relatif dosyaya nasıl yeni kayıtlar girdiğimizi de görelim. Önce DOS'a hangi kaydı yazmak istediğimizi belirtmeliyiz. Bunun için önce 15 numaralı komut kanalını açıyoruz. Tabii, daha önce programın başında açmamışsak. Geçen bölümde bu kanalın açılması ve kapatılması ile ilgili söylediklerimizi hatırlayın. Neyse, açık olan komut kanalından da aşağıda gördüğünüz biraz uzunca bir komutu gönderiyoruz:

PRINT# dn,“P” 4 CHR$(ia) *
CHRS(k1) 4 CHRS(k2) *
CHR$(byte)

“dn” ile komut kanalının bağlı olduğu dosya numarasını kastediyoruz. “ia” ise, relatif dosyanın bağlı olduğu ikincil adres. Sıra geldi k1 ve k2 parametrelerine... Bir relatif dosyada, disketin hafızası yettiği sürece, en fazla 65535 kayıt yeralabilir. Bunu ancak iki byte halinde verebiliriz, çünkü her byte 0-255 arası değer alabilir. Dolayısı ile kayıt numaramızı öyle iki parçaya ayırıyoruz ki, k1 + 256*k2 işlemi sonunda kayıt numarasını elde edebilelim. Bu tür işlemi bundan önce de defalarca yaptık. “byte” parametresi ise, verilen kayıt numarası altında saklanan bilginin kaç numaralı byte'ından itibaren okuma veya yazma işleminin yapılacağını belirtir. Bu genellikle 1 olacaktır, çünkü kaydı baştan okumak daha mantıklı. Ancak, kimi durumlarda (örneğin sadece mal kodu gibi belli bilgiler okunacaksa) bu sayı daha farklı da olabilir. Şimdi aşağıdaki minik program yardımı ile, herbiri 36 karakterden oluşan 1500 kayıtlık bir dosya oluşturalım ve adına da RL diyelim.

100 OPEN 15,8,15
110 K- 1500
120 K2-INT(K/256)
130 Kl -K-K2*256
140 OPEN 1,8,2,“RL,L,”
4 CHR$(36)
150 4 CHR$(2) 4
CHR$(K1) 4 CHRS(K2) 4 CHRS(1)
160
170 CLOSE 1
180 CLOSE 15
Programı çalıştırdığınızda yaklaşık
10 dakika sürecektir. En sonda kır-
mızı ışık yanıp sönerse, dikkate alma-
yın. Eğer disketinizde 230 blok civa-
Tında boş yer varsa, sonuçta istediği-
niz dosyayı elde edeceksiniz. Kl ve
K2 hesaplamasını 110-130 arası satır-
larda görmektesiniz. 140'da dosya
kayıt uzunluğu verilerek açılıyor.
150'de ise 1500 numaralı kaydın ilk
byte'ı üzerine pozisyonlandırılma ya-
pılıyor. Sonra da bu byte'a CHR$
(255) yazıyoruz. Aslında başka şey-
ler de yazabilirdik, ancak DOS ken-
disi boş kayıtlar yaratırken hepsini
255 karakter kodu ile doldurur. Biz

de aynısını yapalım dedik. Şimdi sıra geldi bu dosyaya yeni kayıtlar girmeye. Daha önce, aşağıdaki gibi bir yapı belirlemiştik. Kayıt numarası: 4 basamak İsim: 15 karakter Mal kodu: 5 karakter Alış fiyatı: 6 basamak Satış fiyatı: 6 basamak

Dosyamıza bilgileri kaydederken

bu yapıyı korumamız gerekir. Yani kayıt numarası ilk 4 karakteri, isim ise sonra gelen 15 karakteri kapsamalı. Aynı şey mal kodu, alış fiyatı ve satış fiyatı için de geçerli. Böyle bir yapıyı nasıl sağlayabiliriz? Bunun en kolay yolu sayısal değişkenler yerine string'lerle uğraşmaktır. Yukarıdaki her bilgi birimi için KN$, IS$, MK$, AF$ ve SF$ değişkenlerini ayıralım. Bunların arka arkaya eklenmesi ile oluşacak ve diskete yazılacak değişkene de K$ diyelim. Doğrudan doğruya K$=KN$ + IS$ + MK$ + AF$ + SF$ demek yanlış olacaktır. Eğer malın adı 15 karakterden kısa ise, arkadan gelen mal kodu ve fiyat bilgileri olmaları gereken yerden daha önce gelecektir. Dolayısı ile ismi boşluk karakteri ile 15 karaktere tamamlamalıyız. Aynı şey tam tersi durum için de geçerli. Eğer isim 15 karakterden uzunsa, 36 karakteri aşarız. Bu da hataya yolaçar. Bu durumda da malın adının ilk 15 karakterini almalı, gerisini gözardı etmeliyiz. Tüm bunları aşağıda gösterildiği gibi yapabiliriz. İlk satırda SP$ değişkeninin içine 15 tane boşluk koyuyoruz. Sonra tüm değişkenleri olmaları gereken uzunluklara indirip, sonra da kısa kalanları SP$ ekleyerek uzatıyoruz. Sonunda da K$ değişkenini oluşturuyoruz.

10 SP$-“ »
15 K$-LEFT$(KN$ 4 SP$,4)
20 K$-K$4 LEFT$(IS$ 4 SP$,15)
25 K$ — K$ 4 LEFT$(MK$ * SP$,5)
30 K$-K$4 LEFT$(AF$ 4 SP$,6)
35 LEFT$(SF$ 4 SP$,6)

Programımızın bir yerinde KN$, IS$, MK$, AF$ ve SF$ içine istediğimiz değerleri yerleştirdik, K$'i oluşturduk ve 15 numaralı kayıt olarak dosyaya yerleştirmek istedik. Yapacağımız, dosyayı açıp, 15 numaralı kaydın birinci pozisyonlama yaptıktan sonra K$'i diskete göndermek. Yani:

10 OPEN 15,8,15
15 OPEN 1,8,2'RL,L?
*CHRS(36)
20 KN$- “0015”
25 IS$-“COMMODORE 64”
30 MK$- “15623”
35 AF$-“400000”
40
45
50 K$-LEFT$(KN$ 4 SP$,4)
55 K$-K$4 LEFT$(S$ 4
60 K$-K$4 LEFT$(MK$ * SPS,5)
65 K$-K$-4 LEFT$(AF$ 4 SPS,6)
70 K$-K$4 LEFT$(SF$ 4 SPS,6)
75 PRİNT # -- CHRS(2)
4 CHR$(15)4 CHR$(0) 4
80 PRİNT #1,K$;
85 CLOSE 1
90 CLOSE 15

80 numaralı satırda noktalı virgül kullandığımıza dikkat edin! Bildiğiniz gibi, böyle yapmazsak, kaydın sonuna otomatik olarak CHR$(13), yani RETURN kodu eklenmekte. Bu da, zaten 36 karaktere tamamladığımız kaydın uzunluğunu 37'ye çıkararak hataya yolaçardı. Ancak bu tabii ki her zaman noktalı virgül kullanmak zorunda olduğumuz anlamına gelmez. Eğer yukarıdaki gibi kayıtları oluşturursak (veya sizin BASIC marifetlerinize uygun daha güzel bir programla...), kayıtları geri okumak için kullanacağımız tek yöntem, geçen sayıda da gördüğümüz GET ile okuma yöntemidir.

65

SEYFETTİN ÇANKAYA