You are on page 1of 100

S STEM PROGRAMLAMADA LENECEK BELL BA LI KONULAR:

1- Fonksiyon göstericiler
2- Gösterici göstricileri
3- Kesmeler
4- Bellekte kalacak programlar
5- Haberle/menin temelleri (seri haberler/me paralel haberle/me)
6- Disk i/lemleri(fat root)
7- Kendi kendini ça89ran fonksiyonlar (recursive fonksiyonlar)
8- Yararl9 sistem fonksiyonlar9 kullan9m9
9- Korumal9 mod hakk9nda temel bilgiler
10- Parcing algoritmalar9
11- /lemci kavram9 ve programlanmalar9
12- Veri tabanlar9n9n olu/turulmas9 hakk9nda bilgiler
13- Özel problemler

Kaynaklar :
1- PC Intern
2- Art of C(schildth)

LER C

FONKS YON GÖSTER C LER :

void fonk (void)


{
.....
.....
}
De8i/kenlerde oldu8u gibi fonksiyonlar da memory’de yer kaplamaktad9r ve adresleri vard9r. Bir
fonk ba/lang9ç adresi özel olarak tan9mlanm9/ fonk göstericisinin içerisine yerle/tirilebilir.

Fonksiyon Göstericilerinin Genel Biçimi

[fonksiyonun geri dönü/ de8erinin türü](*gösterici ismi)([param]);

void (*fonk) (void) : *fonk yan9ndaki () olmasa bir fonksiyonun prototipi oldu8u anlam9na
gelir!!! geri dönü/ de8eri void türden bir adres
Bir fonksiyon göstericisine her türlü fonksiyonun ba/lang9ç adresi yerle/tirilemez geri/ dönü/
de8ri ve parametreleri belli türden olan fonksiyonlar yerle/tirilebilir.

Örne8in burada p fonksiyon göstericisine geridönü/ de8eri ve parametresi void olan bir
fonksiyonun adresi yerle/tirilebilir.

1
Fonksiyon gösterici bildiriminde parametre parantezinin içerisi bo/ b9rak9l9rsa o fonksiyon
göstericisine atanacak fonksiyon adreslerinde parametre ko/ulu aranmaz.

(void) olursa parametresi olmamal9d9r.


() her tür parametre de8eri kabul olur.

FONKS YONLARIN BA LANGIÇ ADRESLER N N ELDES :

C'de bir fonksiyon ismi/nden sonra parantez aç9lmaz ise yani fonk ça89rma operatörü kullan9lmaz
ise o ifade fonksiyonun ba/lang9ç adresi gösteren adres sabiti olarak ele al9n9r.

FONKS YON GÖSTER C S YOLUYLA FONKS YONUN ÇAOIRILMASI:

Asl9nda () operatörü unary postfix bir operatördür. öncelik tablosunun en yüksek düzeyinde
bulunur. görevi program9n ak9/9n9 operamd9 olan adrese yönlendirmektir. yani operant bir fonk
adresi olmak zorundad9r. bu durumda fonksiyon göstericisi yard9m9 ile bir fonksiyon () opeartörü
ile ça89r9labilir. fonksiyon gösatericisi ile fonksiyon ça89rman9n bir yolu daha vard9r. (*p)();
fonksiyon göstericisi iki yolla kullan9lsada okunabilirlik aç9s9ndan ço8u kez (*p)() /eklinde
ça89rma pnin bir fonksiyon göstericis oldu8unu aç9kça belirtti8i için daha çok tercih edilir.

FONKS YON GÖSTERC LER N N PARAMETRE DEO KEN OLARAK KULLANILMASI

Bir fonksiyonun parametre de8i/keni parametre de8i/keni olabilir. bu durumda fonksiyon bir
fonksiyon ismi ile yani fonksiyon adresi ile ça89r9lmal9d9r.

FONKS YONUN GER DÖNÜ DEOER N N B R FONKS YON ADRES OLMASI


DURUMU:

Böyle fonksiyonlar9n tan9mlanmas9nda * operatörü fonksiyonun ismi ile birlikte paranteze al9n9r,
parantezimn soluna geri dönü/ de8erine ili/kin fonksiyonun geri dönü/ de8eri sa89na geri dönü/
de8erine ili/kin fonksiyonun parametre yap9s9 yaz9l9r.

void (* fonk(void)) (void)


{

---fonpoin3.c---

#include <stdio.h>

void sample(void)
{

2
printf("I am sample....\n");
}
void (*fonk(void))(void)
{
return sample;
}
void main(void)
{
void (*p)(void);

p=fonk();
p();
}

void(*(*sample(void))(void))(void)---> function returning to pointer function returning to pointer


to function

Burada sample fonksiyonunun parametresi void geri dönü/ de8eri, parametresi void geri dönü/
de8eri, parametresi void geri dönü/ de8eri void olan bir fonksiyondur.

ÇOK BOYUTLU D Z LER::

Çok boyutlu bir dizi bildirimi <tür><dizi ismi>[n1][n2] n1 ve n2 sabit ifadesi olmak
durumundad9r. Genellikle iki boyutlu dizilere rastlan9r ve bunlara genellikle matris denir. Bir çok
boyutlu dizinin elemanlar9 bellekte arda/9l bulunur ve organizasyon son boyutu bir dizi biçiminde
ele al9narak arda/9l yerle/tirilmesi biçimindedir. (ROWSIZE,COLSIZE) /eklinde tan9mlanm9/ bir
matrsin ba/lang9ç adresi matrisle ayn9 türde olan bir p pointeri içinde olsun;
p göstericisini (row,col) ile belirlenen eleman9 gösterecek /ekilde ilerletmek için
p=p+row*COLSIZE+col ifadesi yaz9l9r. bir matris bildiriminde matrsini ismi matrisin ba/lang9ç
adresini tek [] kurulan ifadeler,a[0], gibi matrisin sat9rlar9n9 gösteren adres sabitleridir.

MATR S N BA LANGIÇ ADRES N N GÖSTER C YE ATANMASI


Bir matris tan9mlarken sat9r ve sütün uzunluklar9 sabit ifadesi biçiminde belirtilmek zorundad9r
ancak bir matrisin adresini yerle/tirercek bir gösterici tan9mlamak için matrisin sutün say9s9
bilinmek zorundad9r. bu türden bir gösterici int (*p)[COLSIZE]; /eklinde tan9mlan9r. bu9
bildirimden /u anla/9l9r; p bir göstericidir p göstericisinin gösterdi8i yerde colsize uzunlu8unda
int bir dizi vard9r.

---matris1.c---
#include <stdio.h>
#include <conio.h>

3
#define COLSIZE 3

void fonk(int (*p)[COLSIZE])


{
int i,k;

clrscr();

for (i = 0; i < 2; ++i)


for(k = 0; k < 3; ++k)
printf("%d%c", p[i][k], ( k == COLSIZE-1)? '\n':' ');

}
void main(void)
{
int a[2][COLSIZE]={{2,4,6},{8,10,12}};
fonk (a);
}

D Z LER N SIRAYA D Z LMES (SORT NG)


S9raya dizme küçükten büyü8e veya büyükten küçü8e olabilir. dizileri s9raya dizmek için pek çok
algoritmik yöntem vard9r.
Belli ba/l9 yötemler:
buble sort
selection sort
quick sort
shell sort
binary tree sort
...

s9raya dizme i/leminin süresi dizinin da89l9ma göre de8i/ebilir. da89l9m rastgele ise çe/itli
simulasyon yöntemleri ile en iyi s9ralama algoritmas9n9n quicksort oldu8u belirtilmi/tir.

HER TÜRLÜ D Z Y SIRAYA D ZEN B R FONKS YONUN TASARIMI


her türlü diziyi s9raya dizebilecek bir fonksiyon a/a89daki prototiple yaz9lmaya çal9/9labilir.

void sort(void *ptr, int size, int type);

fonksiyonun birinci parametresi s9raya dizilecek dizinin ba/lang9ç adresini tutacak göstericidir.
ikincisi dizinin uzunlu8u üçüncüsü ise dizinin türüdür.

#define _INT_ 0
#define _LONG_ 1
.....

4
fonksiyon içerisinde type de8i/keni switch içerisinde kontrol edilerek uygun türden bir gösterici
yard9m9 ile s9raya dizme i/lemi yap9l9r.ancak bu /ekilde bir yap9 dizisi s9raya dizilemez çünkü
yap9n9n elemanlar9 de8i/ken olabilir. oysa "qsort" isimli standart c fonksiyonu yap9 dizisi de dahil
olmak üzere her türlü diziyi s9raya dizebilmektedir. her türlü sort algoritmas9nda dizinin iki
eleman9 algoritmik yönteme göre kar/9la/t9r9l9r, e8er ko/ul uygun ise yer de8i/tirilir. her türlü
diziyi s9raya dizen bir fonksiyon iki eleman9n kar/9la/t9r9lams9n9 kendisi içeride sa8lamaz bunun
yerine diziyi s9raya dizecek programc9n9n fonksiyonunu ça89r9r.
qsort un prototipi void qsort(void *ptr, unsigned size, unsigned width, int (*cmp)())

1. parametre s9raya dizilecek dizinin ba/lang9ç adresidir.


2. parametre dizinin toplam eleman say9s9d9r.
3. parametre dizinin bir eleman9n uzunlu8udur.
4. parametre kar/9la/t9rma fonksiyonunun adresidir.
kar/9la/t9rma fonksiyonu dizinin yerde8i/tirilme sorgulamas9n9n yap9ld989 iki eleman9n adresi ile
ça89r9lacakt9r. dolay9s9 ile bu fonksiyonun iki parametresi s9raya dizilecek dizi ile ayn9 türden olan
gösterici olacakt9r. kar/9la/t9rma fonksiyonu birinci parametre ile belirlenen eleman ikinci
parametre ile belirlenenden büyük ise pozitif herhangi bir de8ere küçük ise negatif herhangi bir
de8ere ve e/itse 0'a geri dönmelidir. algoritman9n temöel fikri iki eleman9n yer de8i/tirmek için
eleman9n türünü bilmeye gerek yoktur. ba/lang9ç adresleri ve uzunlu8u bilinse yeterlidir.

---bsort.c---
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

void bsort(void *ptr, unsigned size, unsigned width, int (*cmp)())


{
char *_ptr = (char *)ptr;
int k,i;
void *temp;

temp = malloc (width);


if (temp == NULL) {
printf("memory allocation error...\n");
exit(1);
}
for (k = 0; k < size-1; ++k)
for (i = 0; i < size-1 ; ++i)
if (cmp(_ptr + i * width, _ptr + (i + 1) * width) > 0) {
memcpy(temp, _ptr + i * width, width);
memcpy(_ptr + i * width, _ptr + (i + 1) * width, width);
memcpy(_ptr + (i + 1) * width, temp, width);
}

5
free(temp);
}

int fcompare(int *p1, int *p2);

void main (void)


{
int a[5] = {3, 8, 4, 2, 7};
int j;

clrscr();
bsort(a, 5, sizeof(int), fcompare);

for (j = 0; j < 5;++j)


printf("%d\n", a[j]);

int fcompare(int *p1, int *p2)


{
if (*p1 > *p2)
return 1;
if (*p1 < *p2)
return -1;
return 0;
}

void qsort(void *ptr, unsigned size,unsigned width, int(*cmp)());

--------qsort.c--------
#include <stdio.h>
#include <stdlib.h>

int cmp(int *p1, int *p2);

void main(void)
{
int a[] = {8, 3, 4, 5, 7, -2, 71, 47, 10, 9};
int i;

qsort(a, 10, sizeof(int), cmp);


for (i = 0; i < 10; ++i)
printf("%d\n", a[i]);

6
}

int cmp(int *p1, int *p2)


{
if (*p1 > *p2)
return 1;
if (*p1 < *p2)
return -1;
return 0;
}
----------------------

QSORT'UN PARAMETRELER

1.parametre dizinin baslanbg9c adresi


2.parametresi dizininin toplam uzunlugu
3.parametresi dizinin bir eleman9n uzunlugu
4.parametresi kars9last9rma fonksiyonunun adresidir.kars9last9rma fonksiyonunun dizi ile ayn9
turden iki gosterici parametresi olmal9d9r.Bu fonksiyon kars9last9rma i/leminin yani,s9raya dizme
i/leminin nas9l yap9lacag9n9 tan9mlamakta kullan9l9r.kars9last9rma fonksiyonunun geri donus
degeri int olmak zorundad9r.kars9last9rma fonksiyonu dizinin iki elman9n9n adresiyle qsort
taraf9ndan cag9r9lmaktad9r.Eger birinci parametre ile belirtilen eleman ikinci parametre ile
belirtilen elamandan buyukse + herhangi bir degerle, kucukse - herahngi bir degerle ve iki eleman
birbirine e/itse 0 degeriyle geri donmelidir.

QSORT LE B R YAPI D Z S N N SIRAYA D Z LMES


-----------qsort2.c-----------
#include <stdio.h>
#include <stdlib.h>

typedef struct _PERSON {


char name[30];
int no;
}PERSON;

int cmp(PERSON *p1, PERSON *p2);

void main(void)
{
PERSON x[] = {{"Ali Serçe", 123}, {"Yücel Gündüz", 153"},
{"Kaan Arslan", 518}, {"Mehmet Eraslan", 218},
{"Sacit Er", 174}, {"Güray Sönmez", 317},
{"Ay/e Er", 817}, {"Can Ak", 714},
{"Hilmi Akçao8lu", 417}, {"Hakan en", 405}};
int i;

7
qsort(x, 10, sizeof(PERSON),cmp);
for (i = 0; i < 10; ++ )
printf("%s %d\n", x[i].name, x[i].no);
}

int cmp(PERSON *p1, PERSON *p2)


{
if (p1 -> no > p2 -> no)/*bunlar yerie return strcmp(p1->name,p2->name);isme gore*/
return 1;
if (p1 -> no < p2 -> no)
return -1;
return 0;
}
------------------------------

C'de her ifdenin bir türü vard9r.Ve bi ifade için iki durum söz konusudur.Ya ifade bellekte bir yer
kaplar yani nesnedir, ya da de8ildir.

B R D Z N ÇER S NDEK DOSYALARIN BULUNMASI

Bir dizin içerisindeki dosyalar9o bulabilmek için i/letim sisteminin sundugu iki fonksiyonundan
faydalan9l9r.Bu sistem fonksiyonlar9n9n isimleri dos'ta derleyiciye gore de8i/ebilmektedir.
Borland derleyicilerinde findfirst, findnext;microsoft derleyicilerinde _findfirst, _findnext
isimleriyle bulunur.Windows alt9nda API fonksiyonu olarak FindFirstFile ve FindNextFile
fonksiyonlar9yla bu i/leri yapmak mümkümdür.

findfirst FONKS YONU

prototipi:
int findfirst(const char *filename, struct ffblk *finfo, int attrib);

Fonksiyonun prototipi "dir.h" içerisindedir.Bu fonksiyon bir dosyan9n (direstory de)bir dizinin
içerisinde olup olmad9g9na bakar, eger varsa o dosyan9n bilgilerini elde eder.

1.parametresi aranan dosya(full path ile).


2.parametresi struct ffblk turunden bir yap9 de8i/keninin adresini al9r.ffblk isimli yap9 dir.h
içerisinde belirtilmi/tir.
3.parametresi hangi ozellige sahip dosyalar9n aranacag9n9 belirtir.0 yazmak ar/iv ve read-only
dosyalar9 arat9r.bi genelde 0 yazacag9z.

Eger soz konusu dosya bulunmus ise fonksiyon 0 degeriyle bulunamad9ysa 0 d9s9 herhangi bir
deger ile geri doner.Bu fonksiyon birden fazla dosya arast9rmak için de kullan9labilir.Bu durumda
dosya ismi olarak joker karakterleri girilebilir.Kosulu saglayan birden cok dosya varsa ilkini
bulacakt9r.Kosulu saglayan diger dosyalar findnext ile bulunur.

8
findnext FONKS YONU

prototipi:
int findnext(struct ffblk *finfo);

findnext fonksiyonu her cag9r9l9dg9nda kosulu saglayan bir sonraki dosyan9n bilgilerini elde
eder.Geri donus degeri 0 ise basar9l9, 0 d9s9 ise basar9s9z demektir.tipipk bir dizin arama
algoritmas9 soyledir:

result = findfirst(......);
while(!result) {
....
....
....
result = findnext(...);
}

----------findfn.c----------
#include <stdio.h>
#include <dir.h>
#include <conio.h>

#define MAXPATH 80

void main(void)
{
char path[MAXPATH];
struct ffblk info;
int i, result;

clrscr();

printf("path=");
gets(path);
result = findfirst(path, &info, 0);
while(!result) {
printf("%-20s %ld\n", info.ff_name, info.ff_fsize);
result = findnext(&info);
}
}
----------------------------

9
B R D Z N' N ÇER S NDEK DOSYALARIN SIRALANMASI

Bunun için dizin içerisindeki bütün dosyalar dinamik olarak yarat9lan ve büyütülen bir dizi
içerisinde saklan9r.Sonra dizi qsort fonksiyonuyla s9raya dizilir.

-----------dirsort.c------------
#include <stdio.h>
#include <stdlib.h>
#include <dir.h>
#include <string.h>
#include <conio.h>

#define MAXPATH 80

int cmp(struct ffblk *p1, struct ffblk *p2);

void main(void)
{
struct ffblk *pinfo,f;
char path[MAXPATH];
int size, result, i;

clrscr();

printf("Path=");
gets(path);
size = 0;
result = findfirst(path, &f, 0);
pinfo = (struct ffblk *) malloc(sizeof(struct ffblk));
if (pinfo == NULL) {
printf("Cannot allocate memory");
exit(1);
}
if (result) {
printf("Cannot find file..\n");
exit(1);
}
for(;;) {
if(result)
break;
pinfo[size] = f;
++size;
result = findnext(&f);
if (result)
break;

10
pinfo = (struct ffblk *) realloc(pinfo, sizeof(struct ffblk)*(size+1));
if (pinfo == NULL) {
printf("Cannot allocate memory");
exit(1);
}

}
qsort(pinfo, size, sizeof(struct ffblk), cmp);
for (i = 0; i < size; ++i) {
printf("%-20s %ld\n", pinfo[i].ff_name, pinfo[i].ff_fsize);
if (i % 24 == 23) {
printf("Press any key to continue..\n");
getch();
}
}
printf("%d tane dosya dizdik", size);
}

int cmp(struct ffblk *p1, struct ffblk *p2)


{
return strcmp(p1 -> ff_name, p2 -> ff_name);/*bu isme gore dizer*/
/* if(p1 -> ff_fsize > p2 -> ff_fsize) /*bu uzunluga gore dizer*/
return 1;
if(p1 -> ff_fsize < p2 -> ff_fsize)
return -1;
retun 0;
*/
}
----------------------------------

HEAP PROBLEM

Dosya bilgilerinin bir diziye al9narak saklanmas9 dos gibi heap alan9n9n küçük ve s9n9rl9 oldugu
bir sistemde probleme yol acabilir.Önerilen yöntem heap problemi ba/lad989 zaman bütün dizinin
bir dosyaya yaz9lmas9 ve i/lemlere bir dosyada devam edilmesidir.Dosyadaki bilgilerin sort
edilebilmesi için etkin bir algoritmik yönteme gereksinim vard9r.Örne8in binary tree gibi bir
arama a8ac9 disk üzerinde kurulabilir.

KESMELER(interrupts)

KESME NED R?

Kesme mikro i/lemcinin üzerinde çal9/t989 koda ara vererek ba/ka bir kodu çal9/t9rmas9 i/lemidir.
Kesmeler ça89r9lma kaynaklar9na göre 3 k9sma ayr9l9rlar:

11
1-Yaz9l9m kesmeleri
2-Donan9m kesmeleri
3- ç/el kesmeler

Yaz9l9m kesmeleri(Software interrupts)

Yaz9l9m kesmelerinin normal fonksiyon cag9rmalar9ndan i/levsel bir fark9 yoktur.Bunlar


programc9 taraf9ndan yaz9lan INT hh makina komutuyla koda dahil edilirler.

Donan9m kesmeleri(Hardware interrupts)

Bunlar gercek i/levsel kesmelerdir.Yaz9l9m kesmeleri programc9 taraf9ndan cag9r9l9rken donan9m


kesmeleri elektriksel yolla cag9r9lmaktad9r.Her mikro i/lemcinin ve mikro denetleyicinin donan9m
kesmesi için bir INT ucu vard9r.Bu INT ucu uyar9ld9g9nda (uyar9lmas9 elektriksel olarak 5v ya da
0v gerilimle uygulanmas9 anlam9na gelir) mikro i/lemci o anda çal9/t9r9lmakta olan koda ara verir
ve ba/ka bir kodu yugulamaya ba/lar.Yani bu tur kesmelerde kesmenin olu/ mekanizmas9 d9/sal
ve elektriksel olaylara ba8l9d9r.

çsel kesmeler(Internal interrupts)

Mikro i/lemcinin bir makina kodunu cal9st9r9rken problemle kars9last9g9nda kendi kendisini
cag9rd9g9 kesmelerdir.

Donan9m Kesmelerinin ncelenmesi

80x86 mimarisinde mikro i/lemcinin INT ucuna donan9m birimleri dogrudan


baglanmam9st9r.Donan9m birimleriyle INT ucu aras9na arabirim gorevi yapan ve ismine kesme
denetleyicisi denilen ayr9 bir i/lemci bulunur.(kesme denetleyicisi=8259 (PIC=programmable
interrupt controller))
Kesme denetleyicisinin d9/sal devrelere baglanacak 8 ucu vard9r.PC mimarisinde 1 tane kesme
denetleyicisi vard9,AT'lerle beraber say9s9 2'ye c9kart9lm9st9r.2 kesme denetleyicisi kullanabilmek
için 1. kesme denetleyicisinin bir ucunu 2. kesme denetleyicisinin ozel bir ucuna baglamak
gerekir.Bu durumda bugun kulland9g9m9z sistemlerde donan9m kesmesi olusturabilecek 15 d9/sal
birim vard9r.Kesme denetleyicisinin uçlar9 kesme oluturan baska i/lemcilere bagl9d9r. Bu yolla
donan9m kesmesi olusturulmas9na IRQ (interrupt request) denir.Birinci kesme denetleyicisinin ilk
ucundan baslayarak her uca bir IRQ numaras9 verilmi/tir. Cascade baglant9da (ilk PIC'in ikinciye
baglanmas9 olay9) kullan9lan uç birinci kesme denetleyicisinin 2 numaral9 ucudur(0 baslayarak
numaraland9r9yoruz). Bu durumda IRQ 2 tan9ml9 de8ildir.Intel i/lemcilerinde toplam 256 tane
kesme numaras9 vard9r(software + hardware + internal).Yani kesme biçiminde çal9/t9r9lacak 256
tane ayr9 kod vard9r.Örne8in yaz9l9m kesmelerinde INT makina kodunun yan9na bir byte say9
yaz9l9r,bu say9 kac numaral9 kesmenin kullan9lacag9n9 belirtir.Donan9m kesmelerinde çal9/t9r9lacak
kesme numaras9 yine kesme denetleyicisi ile mikro i/lemci aras9ndaki 8 elektriksel yolla
belirlenir.Yani mikro i/lemci INT ucunun uyar9ld9g9n9 gordugunde D0-D7 uclar9na bakarak kaç
numaral9 kesmenin çal9/t9r9laca89n9 kesme denetleyicisinden al9r.

12
PC M MAR S NDE KESME OLU TURAN DI SAL DEVRELER

IRQ 0

Bu ilk kesme denetleyicisinin ilk ucudur.Intel'in 8254 zamanlay9c9 i/lemcisine bagl9d9r


(programmable interval timer).Bu zamanlama devresi saniyede 18.2 kere darbe üretecek biçimde
programlanm9/t9r.Yani bir program çal9/9rken saniyede 18.2 kere darbe olu/arak ba/ka bir kod
çal9/t9r9lmaktad9r.Bu kesme olu/tu8unda mikro i/lemci 8 numaral9 kesme kodunu (interrupt
handler) çal9/t9r9r.

8H nolu kesme kodu ne yapar:

bu kesmenin kodu temelde iki i/lemi gerçekle/tirir.


1- sistemin saatini çal9/t9r9r. i/letim sistemi yüklendi8inde RTC i/lemcisinden tarih ve zaman
bilgisini al9r ve her kesme geldi8inde zaman bilgisini artt9r9r. (frekans9 18.2 s^-1)

2- floppy motorunun durdurulmas9n9 sa8lar. floppy i/lemi bitirildi8inde motor birden


durdurulmaz çünkü küçük zaman aral9klar9 ile floppyi kullanan programlar durmamas9ndan fayda
sa8larlar. her kesme geldi8inde bu kesmenin içerisinde ayarlanm9/ bir sayaç bir eksiltilir sayaç
s9f9r olunca floppy motoru durdurulur.
Mikro i/lemcinin h9z9ndan ba89ms9z zamanlama i/lemleri:
mikro i/lemcinin h9z9ndan ba89ms9z olarak zamanlamay9 sa8lamak için iki temel yöntem akla
gelebilir.
1- mikro i/lemcinin h9z9n9 tespit ederek i/lemleri yürütmek. bu yöntem uygulanmas9 son derece
güç ve duyarl9 olmayan bir yöntemdir.
2- bilgisayar9n h9z9ndan ba89ms9z bir biçimde çal9/an zamanlay9c9 i/lemci devrelerinden
faydalanmak PC mimarisinde bir 8254 bir tane de RTC i/lemcisi bu i/lemi yapmaya adayd9r.
8254 yoluyla bu i/lemi gerçekle/tirmek dosta mümkün olsa da multitasking ba/ka sistemlerde
mümkün olmayabilir. RTC i/elmcisini programlamak windows alt9nda daha uygun gibi
görünmektedir. ancak genel olarak mimari zamanlama konusunda zay9f tasarlanm9/t9r. ancak
önemli zamanlama i/lemleri için bu i/lemi gerçekle/tirecek ayr9 kartlar kullan9labilir.

IRQ 1 ve 9 numaral9 kesme kodu

Birinci un bir numaral9 ucuna klavye denetleyicisi denilen bir i/lemci ba8l9d9r. (keyboard
controller).(klavye denetleyici genelde intel 8042 yada benzeri ir i/lemci kullan9l9r.) klavyede bir
tul/a bas9ld989 zaman klavye içindeki yerel i/lemci (intel 8048 türevi) bas9lan tu/un s9ra
numaras9n9 elde ederek kablo yolu ile seri bir biçimde bilgisayar içerisindeki klavye
denetleyicisine yollar, bu bilgiyi saklar ve IRQ 1 donan9m kesmesinin ça89r9lmas9na yol açar. IRQ
1 dolay9s9 ile ça89r9lan kesme numaras9 9 dur, bu kod klavye denetleyicisinden bas9lan tu/un
bilgisini alarak klavye tampon bölgesine yazar (memoryde). programlama dillerinde klavyeden
karakter alan fonksiyonlar do8rudan klavye tampon bölgesine bakmaktad9r. 9 numaral9 kesme
kodu bas9lan tu/ üzerinde çe//itli kontrolleri de yapar örne8in pause tu/u prog bekletir.
ctrl+alt+del reset eder. caps 9/989 yakar vs....

13
IRQ 2

Bu irq hatt9 ikinci 8259 a ba8lant9 için harcanm9/t9r.

IRQ 3 VE IRQ 4

IRQ 3 com2 com4


IRQ 4 com1 com3

Bilgisayar9n d9/ dünya ile ileti/iminin kolay sa8lanmas9 için seri ve paralel portlar9 vard9r. Seri
portlar seri ileti/imde kulan9l9rlar; seri portlar bilgisayarda 25 ve 9 uçlu erkek connector
biçiminde bulunmaktad9r. 3 ve 4 numaralar9 IRQ hatlar9na intel 8250 UART i/lemcisi ba8l9d9r.
Bu i/lemci bütün seri haberle/me i/emleri için d9/ dünya ile ba8lant9 kurmak üzere tasarlanm9/t9r.
Bu i/lemci otomatik baz9 i/lemlerin sa8anabilmesi için donan9m kesmesine ihtiyaç duymaktad9r.

IRQ 5

Bu IRQ hatt9 pc lerde harddisk kontrol i/lemcisine ba8l9yd9. Ancak AT'lerle beraber LPT2 ya da 2
numaral9 paralel port kullan9m9na b9rak9lm9st9r. Bilgisayarda paralel haberle/me için 25000 di/i
konnektör kullan9lmaktad9r. Genellikle printer kullan9m9 için bulundurulur. Özellikle printer
kullan9m9nda otomaik baz i/lemlerin sa8lanabilmesi için IRQ gereksinimi vard9r.

IRQ 6

Bu IRQ hatt9 Intel 8272 floppy denetleyici i/lemcisine ba8l9d9r(Floppy controller). Bir floppy
i/lemi bitirildi8inde o anda çal9/t9r9lmakta olan program9n haberdar edilmesnde kullan9l9r.

IRQ 7

Birinci paralel port'a atanm9/t9r.(LPT1)

IRQ0-7 aras9ndaki hatlar için ça89r9lan kesme numaralar9 08-0F aras9ndad9r. Intel 8086 i/lemcisi
00-07 aras9ndaki kesme numaralar9n9 içsel kesmeler için kullanmaktad9r. Ancak 286'larla beraber
içsel kesme say9s9 8'den 32'ye ç9kar9lm9/t9r. Yani bugün kulland989m9z mimaride 8 içsel kesme 8
IRQ kesmesiyle çak9/maktad9r.

IRQ 8
RTC devresine ba8l9d9r

IRQ 9

Bu kesem d9/sal kullan9mlara ayr9lm9/t9r.Bu IRQ'nu9n kesme numaras9 70h't9r.

14
IRQ 10(0A). 11, 12
D9/sal kullan9ma ayr9lm9/t9r

IRQ 13

Matematik i/lemciye 80287 ve 80387 matematik i/lemcilerine ba8l9d9r.

IRQ 14,15

PC lerde d9/sal kullan9mlara ayr9lm9/t9r. PS2 modellerinde harddisk denetleyici i/lemcisine


ba8l9d9r.

YAZILIM KESMELER

Yaz9l9m kesmeleri programc9n9n program koduna dahil ederek çal9/t9rd989 kesmelerdir makina
dilinde yaz9l9m kesmesi için INT makina komutu kullan9l9r. INT makina komutu 2 byte t9r
komutun hangi kesme numaras9n9 ça89r9laca89n9 anlatan bir parametresi vard9r. yaz9l9m kesmesi
için register kavram9n9 bilmek gerekir.

REGISTER NED R??

CPU ile RAM ba8lant9 halindedir. Ram’deki baz9 bilgilerin i/leme sokulabilmesi için cpu
ya çekilmesi gerekir. Bu bilgilerin cpu içinde geçiçi olarak bekletildikleri küçük bellek
bölgelerine register denir. bit uzunluklar9 mikro i/lemcinin bir hamlede yapabilece8i i/lemin
uzunlu8u ile ilgilidir. 8086 16 bit, 80286 ve sonras9 32 bit mikroi/lemcilerdir.

NOT:::
bugünkü pentium i/lemcileri 8086 gibi de çal9/abilmektedir, i/lemci 3 çal9/ma moduna
ayr9lm9/t9r.
1- gerçek mod
2- v86 modu:korumal9 modun çe/itli özelli8i ile gerçek modun çe/itli özelliklerinin kombine
edildi8i moddur.
3- protected mode : korumal9 mod mikroi/lemcinin en yüksek performansta çal9/t989 en geli/mi/
modudur.
windows alt9nda çal9/9rken dos penceresi aç9ld989nda yada bir dos prog çal9/t989nda mik.i/l. v86
modunda bir 8086 gibi çal9/9yor. bu durumda dos penceresinde çal9/mak demek 8086 i/lemcisi
ile çal9/mak anlam9na gelmektedir.

Kesme bir fonksiyon gibi çal9/9r.Yani kesmenin de parametreleri ve geri dönü/ de8eri söz
konusudur.Ancak kesmenin parametreleri register'lar içerisine yaz9l9r,geri dönü/ de8eri de
register'lar içerisinden al9nmaktad9r.

15
8086 LEMC S N N REGISTER YAPISI

8086 i/lemcisinde 14 tane register vard9r.

4 tane genel amaçl9 register vard9r.Bunlar9n isimleri AX(acumulator register), BX(base register),
CX(count register), DX(data register)'dir. Bunlar iki k9sma ayr9l9rlar.Genel amaçl9 registerlar
kendi aralar9nda iki parcan9n toplam9 biçimindedir.

AX = AH + AL
BX = BH + BL
CX = CH + CL
DX = DH + DL

AX
AH AL
BX
BH BL
CX
CH CL
DX
DH DL

Bu parçalar ba89ms9z 8 bitlik registerlar olarak da kullan9labilir. Parçalar ayr9 ayr9


olu/turulup bütün olarak kullan9labilir.

4 tane segment register vard9r:


CS(code segment register), DS(data segment register), SS(stack segment register), ES(extra
segment register).

3 tane pointer register vard9r:


BP(base pointer register), SP(stack pointer register), IP(instruction pointer register).

2 tane index register vard9r:


SI(source index register), DI(destination index register)

1 tane bayrak register vard9r(flag register):

Bütün register'lar 16 bittir.

8086 REGISTERLARININ B R B RL K(union) LE TEMS L ED LMES

16
Register yap9s9n9 temsil etmek amac9yla iki yap9 ile bir birlik kullan9lmaktad9r. Bu yap9lar
ve birlikler dos.h dosyas9 içerisinde bildirilmi/tir.

strut BYTEREGS {
unsigned char al, ah, bl, bh, cl, ch, dl, dh;
};
struct WORDReGS {
unsigned int ab, bx, cx, dx, si ,di, cflag, flags;
};
union REGS {
struct BYTEREGS h;
struct WORDREGS x;
};

union REGS B RL O N N BELLEKTEK ELEMAN YERLE M

regs.h.al regs.x.ah regs.h regs.x regs


regs.h.ah regs.x.ah regs.h regs.x regs
regs.h.bl regs.x.bx regs.h regs.x regs
regs.h.bh regs.x.bx regs.h regs.x regs
regs.h.cl regs.x.cx regs.h regs.x regs
regs.h.ch regs.x.cx regs.h regs.x regs
regs.h.dl regs.x.dx regs.h regs.x regs
regs.h.dh regs.x.dx regs.h regs.x regs
regs.x.si regs.x regs
regs.x.si regs.x regs
regs.x.di regs.x regs
regs.x.di regs.x regs
regs.x.cflag regs.x Regs
regs.x.cflag regs.x regs
regs.x.flags regs.x regs
regs.x.flags regs.x regs

C'de kesme ça89rabilmek için INT makina kodunu dogrudan kullanmak yerine kesme
ça89ran bir fonksiyon kullan9l9r.En önemli kesme ça89ran fonksiyon int86'd9r.

int86 fonksiyonunun prototipi:

int int86(int intno, union REGS *inregs, union REGS *outregs);

Bu fonksiyon ikinci parametresiyle belirtilen adresteki register bilgilerini cpu


register'lar9na kopyalayarak birinci parametresiyle belirtilen kesmeyi ça89r9r. Kesmenin çal9/mas9
bittikten snra cpu register'lar9n9n içerisindeki de8erleri tekrar üçüncü parametresiyle belirtilen
bellek bolgesine kopyalar.Fonksiyon ba/ar9 durumunda 0 degerine basar9s9zl9k durumunda 0 d9s9

17
bir degere geri doner.Bir kesmenin basar9s9z olmas9 soz konusu olmad9g9 için geri donus
degerinin pek bir anlam9 yoktur.

KESMELER N LEVLER VE SINIFLANDIRILMASI

Kesmeler gercekte makina dilinde yaz9lm9s bir cesit fonksiyonlard9r. Cag9r9lmas9 için bir
programlama diline gereksinim yoktur makina dilinde cag9r9labilir.Kesmeler i/levleri,ne gore
intel sisteminde 3 k9s9mda incelenebilir.

1-)BIOS(basic input-output system) kesmeleri


2-)DOS kesmeleri
3-)Özel kesmeler

BIOS KESMELER

1 mb adres alan9n9n son 64 k's9 olan(F0000-FFFFF) EPROM içerisinde bulunan makina


dilinde yaz9lm9s kodlard9r.EPROM içerisindeki kesme kodlar9n9n bulundugu bolgeye BIOS
denir.Kodu burda bulunan kesmeler çe/itli kontrol kartlar9n9n programlayarak i/letim sisteminden
bag9ms9z cok temel i/lemleri gercekle/tirmektedir.BIOS kesmeleri video, a/a89 seviyeli disk
i/lemleri, klavye i/lemleri gibi i/letim sistemine bile gereksinim duymayan çok temel i/lemleri
gercekle/tirmektedir.

DOS KESMELER

DOS'un bellege yuklenmesiyle yarat9l9rlar, butun DOS i/lemleri birtak9m DOS


kesmelerinin cag9r9lmas9yla saglanmaktad9r.21h numaral9 kesme DOS'un temel butun
fonksiyonlar9n9 yerine getirmektedir.

OZEL KESMELER

Ozel baz9 programlar9n bellege yukledigi kesme kodlar9d9r.Ornegin mouse i/lemleri için
33h kesmesi kullan9l9r(dos'ta).Ancak mouse.com program9n9n yuklenmesiyle bu kesme kodlar9
bellege yuklenir.

Toplam kesme say9s9 256 olmas9na kars9n bir kesme koduna gectikten sonra o kod
içersinde ismine fonksiyon denilen alt kodlar bulunabilir.Fonksiyonlar da alt fonksiyonlara
ayr9labilirler. Genellikle fonksiyon numaralar9 AH alt fonksiyon numaralar9 da AL register'9n9n
içersinde kesme ça89r9lmadan once yaz9l9r.Baz9 kesmelerin cok say9da fonksiyon ve alt kesmeleri
oldugu halde baz9 kesmelerin hiç fonksiyonu ya da alt fonksiyonlar9 yoktur.Bir kesme
ö8renebilmek için:

1-)Kesmenin ne i/ yapt9g9n9 bilmek gerekir.


2-)Kesmenin numaras9n9, fonksiyon ve alt fonksiyon numaras9n9 ö8renmek gerekir.
3-)Kesmenin parametrelerinin neler oldugu ve hangi register'lara yerle/tirilmesi gerektigi
ogrenilmelidir.

18
4-)Geri donus degerinin ne anlama geldigi ve nerelere yerlestirileceginin bilinmesi gerekir.

BAZI BIOS KESMELER NDEN ÖRNEKLER

10h KESMES

10h kesmesinin fonksiyonlar9 video i/lemlerini yapar.

VIDEO KARTLARININ EVR M

Kullan9lan ilk grafik kart9 MDA idi.Bu kartlar grafik gösteremiyordu.Ayn9 zamanda bu
kartlar renksizdi.Daha sonra grafik cal9smay9 saglayabilen 4 renkli CGA kartlar9(320x280)
tasarland9.EGA kartlar9yla birlikte çözünürlük 640x480'e ayn9 anda gosterilen renk say9s9 da 16'ya
yukseltilmi/tir.Daha sonra VGa kartlar9yla ayn9 anda verilebilen renk say9s9 256'ya
yukseltilmi/tir.Bugun SVGA kartlar9nda ayn9 anda 2^16, 2^24 renk görüntülenebilmektedir.EGA
da dahil olmak uzere eskiden ekran, ekran kart9na 9 pin'lik seri bir baglant9 kablosuyla
baglan9yordu.VGA kartlarla beraber kart ile monitor aras9ndaki bilgi aktar9m9 analog sisteme
donusturulmustur.Bugun kullan9lan monitörlere RGB(red-green-blue) monitor denir. Bu
monitörlerde 3 tane elektron tabancas9 ile her türlü renk elde edilmektedir.

VIDEO MODE KAVRAMI

VIDEO MODE NED R?

Grafik kart9 ya da ekran kart9n9n belirli çözünürlük ve renk özelliklerinin etkin duruma
getirildi8i bir çal9/ma modudur.Video modun iki bile/eni vard9r:Birincisi çözünürlüktür. kincisi
video modun ayn9 anda gösterebilece8i toplam renk say9s9d9r.Video mod gerçekte bu çal9/ma
biçimini anlatan 0-255 aras9 bir say9d9r.

Video Mode

Text Mode Grafik Mode

Renksiz Renkli Renksiz Renkli

Text mode'da ekrana bas9labilecek en kucuk birim bir karakterdir.Ve karakterler bir kal9p
olarak bas9labilir.Oysa grafik mode'da en kucuk birim 1 noktad9r.Bu noktaya pixel denir.
Monitör ve video mode durumuna göre elde edilebilecek görüntü sistemi:

19
Video mod Monitör Sonuç
Renksiz Renksiz Renksiz
Renksiz Renkli Renksiz
Renkli Renksiz Gri tonlar
Renkli Renkli Renkli

V DEO MODUN DEO T R LMES


10h,F:0
parametreler
AH->0
AL->video mode

80*25 video mode ili/kin 3 tane mode vard9r.

video mode'lar

Video Mode Çözünürlük Text/Grafik Renk say9s9


0 40*25 text mono
1 40*25 text 16
2 80*25 text mono
3 80*25 text 16(default olan mode)
4 320*200 grafik 4
5 320*200 grafik mono
6 640*200 grafik 2
7 80*25 text mono
8-12 reserved ------ ----
13 320*200 grafik 16
14 640*200 grafik 16
15 640*350 grafik mono
16 640*350 grafik 16
17 640*480 grafik mono
18 640*480 grafik 16

CURSOR'UN KONUMLANDIRMASI
int 10h
F:2 AH->2

parametreler: DH->sat9r no
DL->sutun no
BH->0 konulacak sayfa numaras9
geri dönü/ de8eri yok

bu kesme 0,0 orijininden ba/lar ve 0,0 sol üst kö/edir.[24,79 sa8 alt noktad9r.]

20
cursorun görünmememsini sa8lamak için tek yol menzil d9/9na ç9kartmakt9r. örne8in 25*80 de
cursor görünmez.

GRAF K MODDA EKRANA B R P XEL BASILMASI


INT 10h
F:0c

AH:0c
AL:color
bh:0
cx:col
dx:row

geri dönü/ de8eri yok

D SK LEMLER

Bellek nedir?

Bilgilerin sakland989 birimleri bellek denir. kiye ayr9l9rlar:

1-Ara bellek (RAM ve ROM)


RAM(random access memory)
Rom(read only memory)
EPROM
EEPROM(electrically erasable memory)(Bilgi yazarken yava/)
Yar9 iletken teknoloji, entegre devre.
2- kicil bellkeler(Disk, Floppy disk, Cd-rom, Magnetic tape..)
kincil bellekler güç gereksinimi olmadan bilgileri tutmak için kullan9l9rlar.
Disk ve floppy disk'lerin çal9/malar9 birbirlerine cok benzerdir. Temel kavramlar9 ayn9d9r. Bu
nedenle disk dendi8inde ayn9 /ey anla/9lmal9d9r.

Disk le lgili Temel Kavramlar

Disklerde bir okuyucu kafa vard9r, bu kafa yüzeye çok yak9n bir biçimde step motor
vas9tas9yla hareket eder. Disk bir motor tara9nda döndürülmektedir. Bilgiler disk üzerinde dairesel
yollara yaz9l9rlar, bu yollara track denir. Sabit disklerde bir çubku üzerine monte edilmi/ birden
fazla yüzey(platter) bulunabilir. Her yüzeyden okuma yapabilmek için bir okuma kaas9 gereklidir.
Yüzey say9s9 e/ittir kafa say9d9r. Disk ile cpu aras9nda do8rudan bir ba8lant9 oldu8u
dü/ünülmemelidir, disk i/lemlerinin yürütülmesi yerel bir i/lemci taraf9ndan yap9l9r. CPU bu
i/lemciyi programlar i/lemci disk mekani8ini hareket ettirerek bilginin disk'ten okunamas9n9 ya
da disk'e yaz9lmas9n9 sa8lar, e8er diskten okuma söz konusuysa elde edilen bilgi ismine DMA
denilen ba/ka bir i/lemci taraf9ndan belle8e aktar9l9r. Yani disk ile bellek aras9ndaki transfer
i/lemi CPU taraf9ndan yap9lmaz.

21
( ekil 1)

Disk ayn9 zamanda mant9ksal olarak sektör denilen pasta dilimlerine ayr9lm9/t9r. Bu
dilimlere sektör dilimi denir. Bir tarck'in sektör dilimi içerisinde kalan parças9na sektör denir. Bir
sektör transer edilebilecek en küçük disk birimidir. Bir sektörüm kaç byte'tan olu/aca89
formatlama s9ras9nda belirlenebilir. Bu de8er birkaç de8er aras9ndan seçilmektedir. Ancak DOS
gibi pek çok i/letim sistemi bir sektör=512 byte olarak format yapmaktad9r. Sektörlerin disk
üzerindeki yeri ne olursa olsun her sektörde e/it say9da bilgi vard9r. Bir disk'in formatland9ktan
sonraki toplam kapasitesi /u çarp9m sonucu bulunabilir:
kapasite=yüzey say9s9 * track say9s9 * sektör dilim say9s9 * 512 (=byte)

Disketlerin Parametrik Bilgileri

1-Küçük disket(3.5")
1-a)HD =2(kafa say9s9) * 80 (track) * 18 (sektör dilimi) * 512 =1.44 Mb
1-b)DD =2 * 80 * 9 * 512 = 720 Kb
2-Büyük disket(5.25")
2-a)HD =2 * 80 * 15 * 512 = 1.2 Mb
2-b)DD =2 * 40 * 9 * 512 = 360 Kb

Teknolojik geli/im = 2-b, 1-b, 1-a, 2-a

Donan9m seviyesinde en temel komut bir sektörün okunmas9 ya da yaz9lmas9na ili/kindir.


Disk'i yöneten i/lemci okunacak sektörün koordinatlar9n9 üç parametreyle al9r. Hangi yüzey,
hangi track, hangi sektör dilimi. Bir sektörün yerinin bu üç parametreyle belirtilmesine fiziksel
koordinat sistemi denir. Donan9m fiziksel kooordinat sisteminden anlamaktad9r. Yüzey say9s9
0'dan ba/layar. Disketlerde 0 ön yüz 1 arka yüzdür. Track numaras9 da 0'dan ba/lar n'e kadar
gider. En d9/taki track 0 numaral9 track'tir. Sektör dilimi 1'den ba/lar. Bir sektörün sektör
diliminin numaras9 ard9/9l gitmek zorunda de8ildir ve hangi sektörün 1 numaral9 sektör oldu8u
disk üzerinde sektör gap denilen bölgeye yaz9lmaktad9r.

Disk Okuma Ve Yazma Zamanlar9

Bir sektörün okunma ya da yaz9lma emrinin verilmesiyle bu i/lemin gerçekle/tirilmesi


aras9nda geçen zamand9r. Disk i/lemcisinin ard9/9l sektör okuma ve yazma komutlar9 vard9r. Bu
komutlarla ard9/9l sektörler daha h9zl9 bir biçimde okunup yaz9labilirler. Ancak bir hamlede track
ba/9na dü/en sektör dilimi say9s9ndan daha fazla sektör transfer edilemez.

Disk le Bellek Aras9nda Transfer /lemi

En dü/ük disk i/lemi disk ile bellek aras9nda n ard9/9l sektörün transfer edilmesi i/lemidir.
Bir sektörün transfer edilebilmesi için disk ve DMA i/lemcilerinin programlanmas9 gerekir.
Ancak kolayl9k olsun diye a/a89 seviyeli disk i/lemleri BIOS kesmesi biçiminde EPROM
içerisine yaz9lm9/t9r. 13h kesmesinin tüm fonksiyonlar9 a/a89 seviyeli disk i/lemleri için

22
kullan9lmaktad9r. Ancak C derleyicileri 13h kesmesini ça89rarak transfer i/lemini yapan özel bir
fonksiyonda bar9nd9rmaktad9r. Bu fonksiyon Borland derleyicilerinde biosdisk Microsoft
derleyicilerinde _biosdisk olarak adland9r9l9r.

biosdisk Fonksiyonunun Parametrelerinin ncelenmesi

int biosdisk(int cmd, int drive, int head, int track, int sector, int nsects, void *buf);

Fonksiyonun prototipi bios.h içerisindedir.

Parametreleri:
cmd=> 13h'9n fonksiyon numaras9d9r.
2 nolu fonksiyon sektör okumak içindir,3 nolu fonksiyon sektör'e
yazmak içindir.

drive=> Hangi sürücüye ili/kin sektör okunacakt9r.


0=>A, 1=>B, 0x80(128)=>birinci HDD, 0x81(129)=>ikinci HDD

head, track, sector=> Okunacak sektörün fiziksel koordinatlar9

nsects=> Ard9/9l kaç sektör okunaca89d9r. En az 1 en fazla sektör dilim


say9s9 kadard9r.

buf=> Bu parametre bellek transfer adresini belirtir. Ku/kusuz okuma


durumunda bu adresten ba/layan n byte bölgenin dizi
tan9mlamas9yla ya da dinamik bellek yönetimiyle tahsis edilmi/
olmas9 gerekir.

Fonksiyonun geri dönü/ de8eri i/lem ba/a9l9ysa 0, ba/ar9s9zsa 0 d9/9 bir de8erdir. Bu 0 d9/9
de8er ba/ar9s9zl989n nedeni hakk9nda bilgi de vermektedir. Bu fonksiyon ile ba/ar9s9zl989n
tescillenmesi için en az 3 kere deneme yap9lmas9 gerekir. Çünkü i/lemin baar9s9 biraz da mekanik
etkenlere ba8l9d9r.

Üç kere deneme algoritmas9:

#include <stdio.h>
#include <stdlib.h>
#include <bios.h>

#define TRYNUM 3

void main(void)
{
int result;
int i;

23
for (i = 0; i < TRYNUM,; ++i) {
result = biosdisk( ........);
if(!result)
break;
}
if(result)
printf("cannot read or write disk...\n");
exit(1);
}

Örnek:Bir sektörün ekranda görüntülenmesi.

--------------biosdisk.c--------------
#include <stdio.h>
#include <stdlib.h>
#include <bios.h>

#define TRYNUM 3
#define SECTOR_SIZE 512

typedef unsigned char BYTE;

void main(void)
{
BYTE buf[SECTOR_SIZE];
int i, result;

for (i = 0; i < TRYNUM; ++i) {


result = biosdisk(2, 0, 0, 0, 1, 1, buf);
if(!result)
break;
}
if(result)
printf("cannot read or write disk...\n");
exit(1);
for (i = 0; i < 128; ++i)
printf("%02%c", buf[i], i % 32 == 31 ? '\n' : ' ');
}
-------------------------------------

SINIF ÇALI MASI

Bir yaz9n9n 1.44 formatl9 bir diskette aranmas9:

24
norton disk edit ile bu ula/9m9 kolayl9kla yap9labiliyor.
dos alt9nda çok biyik yerel diziler açmamak gerekir çünkü steak sistemi 64 k ile s9n9rl9d9r ve
karma/9k programlarda steak problemi ile kar/9la/9labilir.
bir byte dizisi içerisinde ba/ka bir byte dizisinin aranmas9 için strstr fonksiyonunu kullanamay9z.
çünkü bu fonksiyon null karakteri görünce i/lemi keser. bu durumda bu fonksiyonun yapt989n9
yapacak ba/ka bir fonksiyon yazmak gerekir. bu fonksiyonu yazarken strncmp fonksiyonu de8il
memcmp fonksiyonunu kullanmal9y9z.

int memcmp(const void *s1, const void *s2, unsigned n)

bu fonksiyon biirinci adreste bulunan bilgi ile ikinci adreste bulunan bilginin ilk n byte 9n9
kar/9la/t9r9r. e8er iki bilgi birbirine e/itse 0 de8erine; 1>2 ise pozitif bir de8ere; 2>1 ise negatif
herhangi bir de8ere geri döner.

---------------search.c-----------------
#include <stdio.h>
#include <bios.h>
#include <string.h>
#include <stdlib.h>

/*symbolic constants*/
#define NTRACK 80
#define NHEAD 2
#define NSECTOR 18
#define SECTSIZE 512
#define NTRY 3

/*typedefs*/
typedef unsigned char BYTE;

/*function prototypes*/
int sfindstr(const BYTE *buf, const char *str, int nsect, int *last);

int sfindstr(const BYTE *buf, const char *str, int nsect, int *plast)
{
int i;
int len;

len = strlen(str);
if (*plast)
if (!memcmp(buf, str + *plast, len - *plast))

25
return 1;
else
*plast = 0;
for(i = 0; i < nsect * SECTSIZE - len + 1; ++i)
if (!memcmp(&buf[i], str, len))
return i / 512 + 1;
for (i = nsect * SECTSIZE - len; i < nsect * SECTSIZE; ++i) {
if (!memcmp(&buf[i], str, --len)) {
*plast = len + 1;
return 0;
}
}
return 0;
}

void main(int argc, char *argv[])


{
int h, t;
int result;
int last = 0;
int i;
BYTE *buf;

if (argc == 1) {
printf("Disket search utility version 1.0 \n");
printf("Usage : search <string> \n");
exit(1);
}
if (argc > 2) {
printf("Too many parameters....\n");
exit(1);
}
buf = (BYTE *) malloc (SECTSIZE * NSECTOR);
if(buf == NULL) {
printf("cannot allocate memory....\n");
exit(1);
}
for (t = 0; t < NTRACK; ++t) {
for (h = 0; h < NHEAD; ++h){
for (i = 0; i < NTRY; ++i){
result = biosdisk(2, 0, h, t, 1, NSECTOR, buf);
if(!result)
break;
}

26
if(result){
printf("Cannot read track:%d\n",t);
exit(1);
}
printf("Head: %d Track: %d\r", h, t);
result = sfindstr(buf, argv[1], NSECTOR, &last);
if(result){
printf(" string found : Head = %d track = %d sects = %d\n", h, t, result);
exit(0);
}
}
}
printf("could not found string ...\n");
}

-----------------------------------------

DOSYA S STEM KAVRAMI VE DOSYALAR

Dosya Nedir?

Dosya donan9mla ili/kisi olmayan genel bir terimdir. çerisinde bilgilerin bulundu8u disk
alanlar9na dosya denir. Bir dosyan9n parçalar9 nihayet sektörler içerisinde bulunmaktad9r.
Dosyan9n parçalar9nn sektörlere nas9l yerle/tirildi8ini dosyalar9n nas9l ele al9n9p i/leme
sokuldu8u, dosyalar9n hangi özelliklere sahip oldu8u i/letim sisteminden i/letim sistemine göre
de8i/en bir bilgidir. /letim sistemlerinin dosya i/lelerine ili/kin belirlemelerine ve kodlar9na
dosya sistemi(file system) denir. Dosya kavramsal olarak ard9/9l byte bilgilerden olu/maktad9r.
Oysa gerçekte disk üzerinde çe/itli sektörlere yay9lm9/ bir biçimde bulunur. /letim sistemlerinin
birbirlerine benzer ya da farkl9 dosya sistemleri olabilir. DOS ve WIN 3.x'in dosya sistemleri
tamamen ayn9d9r, bu dosya sisteine genellikle FAT sistemi denir. WIN 95 ve 98'in dosya
sistemleri DOS'a çok benzer, bu sistemlere çe/itli küçük ekler yap9lm9/t9r. Örne8in uzun dosya
isimleri ve 32 bit FAT algoritmas9 gibi... WIN NT'nin dosya sistemine NTFS denir, DOS'un
dosya sistemine benzemekle birlikte farkl9l9klar9 vard9r. UNIX'in dosya sistemi di8er gruptan
tamamen farkl9d9r.

DOS LET M S STEM N N DOSYA S STEM

DOS LET M S STEM N N DOSYA S STEM

DOS'un dosya sistemi Windows 3.1'inkiyle tamamen ayn9d9r. WIN95/98 sistemlerinin


dosya sistemleriyse DOS'unkinden çok az farkl9d9r(Uzun dosya isimleri ve 32 bit FAT sistemi).
lgili partion'9n herhangi bir i/letim sisteminin dosya sisemine uydurulmas9 için o sistemde
formatlama i/lemine sokulmas9 gerekir. DOS'un dosya sisteminde bir disk 4 bölümden
olu/maktad9r.

27
BOOT SECTOR

FAT

Root directory

Data

BOOT SECTOR

BOOT SECTOR diskin çe/itli parametrik bilgilerinin tutuldu8u ve sistemi yükleyen


program9n sakland989 512 byte uzunlu8unda bir sektördür. BOOT SECTOR disetlerde s9f9r9nc9
head s9f9r9nc9 track ve birinci sektöründedir(0h:0t:1s). Yani disketin ilk sektörüdür. Disklerde
BOOT SECTOR ilgili disk bölmesinin (partition) mant9ksal ilk setörüdür. BOOT SECTOR
içerik bak9m9ndan iki bölümden olu/ur. BOOT SECTOR'ün dü/ük anlaml9 byte'lar9na bios
parametre block(BPB) denir, di8er bölüm i/letim sistemini yükleyecek yükleyici program9n
bulundu8u bölümdür.

(goto)
BPB (bios parametre block)

OS loader(bootstrap program)

BPB Bölümü

BPB bölümünde diskin kullan9m9na ili/kin önemli parametrik bilgiler bulunmaktad9r.


BPB bölümünün içeri8i /öyledir.

Offset Uzunluk Anlam9


0(0) 3 byte JMP code
3(3) 8 byte OEM name and version
B(11) 1 word Sektördeki byte say9s9
D(13) 1 byte Clusterdaki sektör say9s9
E(14) 2 byte Ayr9lm9/ sektörler
10(16) 1 byte FAT kopyalar9n9n say9s9
11(17) 1 word Root directory giri/leri say9s9
13(19) 1 word Toplam sektör say9s9
15(21) 1 byte Ortam belirleyicisi

28
16(22) 1 word FAT'in kaç sektör oldu8u
18(24) 1 word Track'teki sektör dilimi say9s9
1A(26) 1 word Kafa say9s9
1C(28) 1 word Sakl9 sektörlerin say9s9

JMP code: /letim sistemini yükleyen program BPB blo8unun ötesinde bulunmaktad9r.
Yükleme i/leminin gerçekle/mesi için BPB blo8unun bir çe/it GOTO
komutuyla atlanmas9 gerekir. Burada 3 byte uzunlu8unda bir GOTO
komutu bulunmaktad9r. Intel i/lemcilerinde GOTO komutuna JMP denir.

OEM name: Buraya bilgi format program9 taraf9ndan yorum amaçl9 olarak
yaz9lmaktad9r. Genellikle diskin hangi i/letim siseminin hangi
version'9 taraf9ndan formatland989n9 belirlemek için kullan9l9r. Buradaki
bilginin de8i/tirilmesi hiçbir probleme yol açmaz.

Sektördeki byte say9s9: Burada sektör ba/9na dü/en byte say9s9 bulunmaktad9r. Madem bir
sektör 512 byte uzunlu8a ayarlanmaktad9r o halde buradaki bilgi de 00 02
biçiminde bulunmal9d9r.

Cluster kavram9: DOS'ta dosyan9n parçalar9 data bölümüne rastgele yerle/tirilir. Bir
cluster dosyan9n saklanabilece8i en küçük disk birimidir. Bir cluster
ard9/9l n sektörden olumak zorundad9r(2'nin kuvveti olmak
zorundad9r).
Yani DOS depolama birimi olarak sektör de8il cluster dü/ünür(dosyan9n
parçalar9n9 rastgele clusterlar içerisinde tutulmaktad9r).

Cluster Sisteminin Avantajlar9 ve Dezavantajlar9:

1-)Cluster sistemiyle dosyan9n disk üzerindeki parçalar9 azalt9lmaktad9r. Bu da diskin kafa


hareketinin azalt9lmas9 anlam9na gelir.
2-)Dosyan9n parçalar9n9n yerleri FAt denilen bir bölgede tutulmaktad9r. E8er cluster kavram9
olmasayd9 bu FAt bölgesi daha büyük bir yer kaplard9.
3-)Her dosyan9n son cluster'9nda kullan9lmayan bölümler olu/ur. Buna "internal fragmentation"
(içsel bölünme) denir(Diskin kullan9m oran9n9 dü/ürür).

Sürekli Ve Rastgele Yerle/im Sistemleri

Diske ya da belle8e yüklemeler ard9/9l bir biçimde yap9lsad9 belirli bir süre yükleme
bo/altma i/lemlerinden sonra kullan9lamayan küçük bo/ bölgeler olu/urdu. Örne8in bo/
bölgelerin toplam9 çok büyük olabildi8i halde ard9/9l olarak bulunmad989 için tahsis edilemezdi.
Oysa ard9/9l tahsis etme zorunlulu8u ortadan kald9r9larak bu küçük parçalar da tahsisat9n bir
parças9 haline getirirlebilmektedir. Buna rastegele yerle/im denir. Ard9/9l yerle/imdeki küçük
kullan9lmayan bölümler olu/mas9na bölünme durumu(fragmentation) denilmektedir. Rastgele
yerle/imde disk ya da RAM belirli uzunluktaki bloklara ayr9l9r ve tahsis edilecek birim bu

29
bloklara rastgele atan9r. Tabii hangi bloklarda hangi tahsisat parças9n9n bulundu8u ayr9 bir tabloda
tutulmak zorundad9r. Ancak rastgele yerle/im sisteminde bölünme durumu tamamen giderilemez.
Her blo8un sonunda kullan9lmayan küçük bo/ alanlar kal9r, bu durmuna içsel bölünme
durumu(internal fragmentation) denir.Peki bir blok ya da bir cluster ne kadar uzunlukta
olmal9d9r? Bir blo8un uzunlu8u çe/itli amaçlar göz önünde bulundurularak ayarlanabilir. Intel
i/lemcilerinde bu bloklar 4 k uzunlu8undad9r ve de8i/itirilemez. DOS i/letim sistemi disk'in
toplam uzunlu8una bakarak bir cluster'9n kaç sektör olaca89n9 otomatik bir biçimde belirler. Baz9
tür UNIX sistemlerinde bir blo8un kaç sektör olaca89 yükleyen ki/iye default de8eri bildirilerek
sorulur. 1.44 3.5" disketlerde 1 cluster=1 sektör 720 k 3.5" disketlerde 1 cluster=2 sektördür.
Sonuçta bir cluster9n kaç sektör olaca89 formatlama s9ras9nda otomatik olarak belirlenmektedir.

Ayr9lm9/ sektörler:BOOT SECTOR içerisindeki yükleyici program büyük ise FAT bölgesi BOOT
SECTOR'den hemen sonra ba/lamaz. Reserved sector say9s9 BOOT SECTOR ve
FAT bölgesine kadar uzat9lm9/ bölgenin aç sektör uzunlugunda oldu8unu
gösterir. FAT hemen BOOT SECTOR'den sonra ba/l9yorsa reserved sector 1
de8erindedir. Reserved sector say9s9 FAT öncesindeki sektör say9s9n9
belirtmektedir.

BOOT
Reserved sector=3

FAT

Bu durumda FAT bölgesinin ba/lang9c9 reservered sector alan9nda yaz9lan


sektördedir.

FAT kopyalar9n9n say9s9: FAT bölgesi istenildi8i kadar kopyadan olu/abilir. DOS standart
olarak 2 kopya FAT tutmaktad9r. FAT'in birden fazla kopyas9n9n
bulundurulmas9 ciddi anlamda bir fayda sa8lamamaktad9r. Çünkü
FAT bölgesinin güncellenmesi her iki kopya üzerinde ayn9 anda
yap9lmaktad9r.

Root directory giri/leri say9s9: Root directory'deki dosya bilgileri root directory alan9nda sakl9d9r.
Bir dosya bilgisi 32 byte yer kaplar. Yaani burada yaz9lan say9 32
ile çarp9l9r ve 512'ye bölünürse root directory bölgesinin kaç sektör
uzunlu8unda olud8u bulunur. Root bölgesinin sektör uzunlu8u data
bölgesinin yerini tespit etmek amac9yla kullan9l9r.

Toplam sektör say9s9: Burada diskteki toplam sektör say9s9 bulunmaktad9r. Malesef DOS
4.01 version'9na kadar bu bölge 2 byte olarak küçük bir biçimde
tasarlanm9/t9r. Buraya yaz9labilecek en büyük say9 65535'd9r.
65525*512=33 Mb't9r. DOS 4.01'e kadar en büyük DOS partition'9
33 mb olabilir. Ancak bu alan yetersiz kald989 için DOS 4.01
version'9nda BPB blo8u büyütülmü/ ve 20h offsetinde 4 byte
uzunlu8unda yeni bir toplam sektör say9s9 alan9 tan9mlanm9/t9r.

30
Bugünkü DOS version'lar9 önce eski 13h offsetindeki eski word
alan9na bakarlar, e8er buradaki say9 0 de8ilse toplam sektör
say9s9n9n bu alanda yaz9lan oldu8unu dü/ünürler. E8er buradaki
say9 0 ise 20h offsetinden 4 byte'l9k de8eri okurlar.

Ortam belirleyicisi: Buradaki 1 byte'l9k de8er genel olarak disk birimi hakk9nda bilgi
vermektedir. Buraddaki de8erler ve anlamlar9 da89t9lan notlarda
belirtilmi/tir.(2.37(disk id byte))

FAT'in kaç sektör oldu8u: Burada bir FAT'te FAT'in kaç sektör bilgisinden olu/tu8u bilgisi
yer almaktad9r. Bu durumda ROOT DIRECTORY bölgesinin hangi
sektörden ba/layaca89 FAT kopyalar9n9n say9s9n9n bu de8eriyle
çarp9m9 sonucu hesaplanabilir.

Track'teki sektör dilimi say9s9:Bir track'te kaç sektör dilimi old8u bilgisidir.

Kafa say9s9: Diskin kaç yüzeyden olu/tu8u bilgisini verir.

Sakl9 sektörlerin say9s9: Sakl9 sektör kullan9lmayan sektör olarak dü/ünülmü/tür. Ancak bu
de8er genellikle 0'd9r Sakl9 sektörlerin ne amaçla kullan9ld989 kesin
olarak bilinmemektedir.

LET M S STEMLER N N OTOMAT K OLARAK YÜKLENMES

Bilgisayar aç9ld989nda mikro i/lemci reset edilir ve çal9/ma otomatik olarak 1 Mb bellek
alan9n9n son 64 kb'si içerisinde bulunan EPROM bölgesinden ba/lar. EPROM, board üzerinde
ayr9 bir bölgede bulunur. Ancak i/lemci o adres bölgesine eri/meye çal9/t989nda SIMM(single
inline memory module) modülüne de8il EPROM modülüne yönlendirilmektedir. EPROM'daki
program bilgisayara ba8l9 olan ayg9tlar9n belirlenmesi ve test edilmesi i/lemlerini yapar. Örne8in
floppy sürücü kontrol edilir, ne kadar fiziksel RAM oldu8u test edilir vb... Bugün bu self testin
yan9 s9ra BIOS program9 ayn9 zamanda PNP (plug and play) testi de yapmaktad9r. Yani
bilgisayara tak9l9 olan bir kart ya da bir chip PNP teknlojisine uygun olarak yap9lm9/sa d9/ar9dan
bu kart9n hangi amaçlarla bilgisayara tak9ld989, bilgisayar9n hangi kaynaklar9n9 kulland989 tespit
edilebilir. PNP kartlar9 kaynak kullan9m parametreleri d9/ar9dan programlama yoluyla
de8i/tirilecek biçimde tasarlanm9/t9r. /letim sistemi gerekirse çe/itli çak9/malar9 çözebilir. Self-
test sonras9nda elde edilen bilgiler bir biçimde belirli bir yerde saklanmaktad9r. Self-test
sonras9nda ismine ROM yükleyisi program9 denilen(rom bootstrap program) özel bir program
çal9/maktad9r. Buradaki program s9ras9yla A ve C disklerine bakar, oran9n boot sektörünü belle8in
7C00 bölgesine yükleyerek kontrolü boot sektördeki programa b9rak9r. Yani i/letim sistemi
gerçekte boot sektördeki program sayesinde yüklenmektedir. Yani bütün i/letim sistemleri boot
sektör üzerindeki program taraf9ndan yüklenmektedir.

Mant9ksal Sektör Kavram9

31
Fiziksel olarak bir sektör h:t:s parametreleriyle belirtilmektedir. Oysa DOS i/letim
sisteminde bir sektörün yerini test etmek için 3 parametreli sistem yerine ismine mant9ksal sektör
denilen(mutlak sektör=absolute sector) tek parametreli bir koordinat sistemi kullan9lmaktad9r. Bu
koordinat sistemine göre tüm sektörlere 0'dan ba/layarak ard9/9l birer say9 kar/9l9k getirilmektedir.
Önce sektör dilimleri daha sonra kafalar daha sonra trackler de8i/tirilerek her sektöre ard9/9l bir
numara verilmi/tir. Örne8in bir disketeki numaraland9rma /öyledir.

Fiziksel sektör Mant9ksal sektör


0:0:1 0
0:0:2 1
..... …..
..... …..
0:0:18 17
1:0:1 18
..... …..
..... …..
1:0:18 35
0:1:1 36
..... …..
..... …..

Bu koordinat sisteminin amac9 parametre say9s9n9 azaltmakt9r. Bu durumda e8er diskin


parametreleri bilinirse (BPB alan9nda yazmaktad9r) mant9ksal sektörle fiziksel sektör aras9nda
dönü/üm kolayl9kla yap9labilir. DOS i/letim sisteminin absread ve abswrite isimli iki sistem
fonksiyonu vard9r. Bu fonksiyonlar parametre olarak mant9ksal sektör numaras9n9 al9rlar kendi
içlerinde fiziksel koordinat sistemine dön/türerek okuma/yazma i/lemini gerçekle/tirirler.

absread ve abswrite FONKS YONLARININ biosdisk FONKS YONUNDAN FARKLARI

1-Bu fonksiyon kendi içerisinde 3 kere denemeyi yapmaktad9r.


2-absread ve abswrite fonksiyonlar9 ile istenilen say9da sektör okunabilir.
3-Bu fonksiyonlar partition duyarl9d9r. Yani her DOS partition'9n9n ilk sektörünü 0 kabul ederek
i/lem yaparlar.

absread abswrite Fonksiyonlar9

Prototipleri:
int absread(int drive, int nsects, long lsect, void *buf);
int abswrite(int drive, int nsects, long lsect, void *buf);

prototipi dos.h içerisindedir.

drive: 0=>A
1=>B
2=>C

32
3=>D
4=>E

nsect: Ard9/9l kaç sektör okunaca89d9r.

lsect: Hangi mant9ksal sektörden ba/lanaca89d9r.

buf: Transfer adresidir.

Bu fonksiyonlar9n geri dönü/ de8eri ba/ar9l9yla 0 ba/ar9s9zsa -1 de8erine geri döner.


Hatan9n sebebini -1 de8erine geri dönüldüyse "errno" global de8i/keninin içerisine yazar.

S9n9f çal9/mas9:BPB blo8unu okuyarak disk parametre bilgilerini ekrana yazd9ran program.
Bunun için önce BPB alan9 bir yap9 içerisine kopyalan9r ve o yap9dan çekilerek
kullan9l9r. Bu i/lem için bootinfo isminde bir fonksiyon yaz9lacak ve bu
fonksiyon yaz9larak i/lemler yap9lacak.

/*------------disk.h-------------------*/
/*----------------------------------------------------------------------
Disk Header File
----------------------------------------------------------------------*/

#ifndef _DISK_H_

/* Symbolic contants */

#define SECT_SIZE 512

/* typedefs */

typedef unsigned char BYTE;


typedef unsigned int WORD;
typedef unsigned long int DWORD;

/* Boot sector */

typedef struct _BOOT {


WORD fat_len; /*fat length as sector (A)*/
WORD root_len; /*root length as sector*/
WORD fat_num; /*number of fat(A)*/
DWORD total_sec; /*total sector (A)*/
WORD bps; /*byte per sector(A)*/
WORD spc; /*sector per cluster(A)*/
WORD reserved_sect; /*reserved sector(A)*/
BYTE media_descriptor;/*media descriptor byte(A)*/

33
WORD spt; /*sector per track(A)*/
WORD root_ent; /*root entry(A)*/
WORD head_num; /*number of heads(A)*/
WORD hid_num; /*number of hidden sector(A)*/
WORD tph; /*track per head*/
WORD fat_or; /*fat director location*/
WORD root_or; /*root directory location*/
WORD data_or; /*first data sector location*/
} BOOT;

/* Function Prototypes */

int boot_info(BOOT *info, int drive);

#endif

/*----------------------------------------*/

/*-------------bootinfo.c-----------------*/
/*----------------------------------------------------------------------
Disk Implementatin File
----------------------------------------------------------------------*/
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <ctype.h>
#include "disk.h"

/* Functions */

int boot_info(BOOT *info, int drive)


{
BYTE btr[SECT_SIZE];

if (absread(drive, 1, 0, btr) == -1)


return -1;
info -> fat_len = *(WORD *)(btr + 0x16);
info -> root_len = *(WORD *)(btr + 0x11) * 32 / 512;
info -> fat_num = *(BYTE *)(btr + 0x10);
if (*(WORD *)(btr + 0x13))
info -> total_sec = *(WORD *)(btr + 0x13);
else
info -> total_sec = *(DWORD *)(btr + 0x20);
info -> bps = *(WORD *)(btr + 0xB);
info -> spc = *(BYTE *) (btr +0xD);

34
info -> reserved_sect = *(WORD *)(btr + 0xE);
info -> media_descriptor = *(btr + 0x15);
info -> spt = *(WORD *)(btr + 0x18);
info -> root_ent = *(WORD *)(btr + 0x11);
info -> head_num = *(WORD *)(btr + 0x1A);
info ->hid_num = *(WORD *)(btr + 0x1C);
info -> tph = (WORD) (info -> total_sec / info -> spt / info -> head_num);
info -> fat_or = info -> reserved_sect;
info -> root_or = info -> fat_len * info -> fat_num + info -> reserved_sect;
info -> data_or = info -> root_or + info -> root_len;
return 0;
}

#if 1

void main(int argc, char *argv[])


{
BOOT boot;
int result;

if (argc != 2) {
printf("Wrong number of arguments...\n");
exit(1);
}
if (!isalpha(argv[1][0]) || argv[1][1] != ':') {
printf("Invalid drive: %s\n", argv[1]);
exit(1);
}
printf("Ok...\n");
result = boot_info(&boot, toupper(argv[1][0]) - 'A');
if (result == -1) {
printf("Cannot get boot record...\n");
exit(1);
}
printf("Bytes per sector: %u\n", boot.bps);
printf("Sector per cluster: %d\n", boot.spc);
printf("Number of Head: %u\n", boot.head_num);
printf("Fat origin: %u\n", boot.fat_or);
printf("Root origin: %u\n", boot.root_or);
}

35
#endif

/*------------------------------------------------*/

FAT BÖLGES

FAT bölgesi bir dosyan9n parçalar9n9n hangi cluster'larda oldu8unu tutan bir bölgedir.
Genellikle 2 kopyas9 bulunur. FAT bölgesinin hangi mant9ksal bölgeden ba/lad989 ve kaç sektör
uzunlukta oldu8u BOOT SECTOR'ndeki BPB blo8u incelenerek yorumlanabilir. DOS dosya
sisteminde data bölgesi cluster numaralar9na ayr9lm9/t9r. Data bölgesinin ilk n sektörü iki
numaral9 cluster sonraki n sektörü üç numaral9 cluster vesaire olarak ard9/9l olarak
s9raland9r9lm9/t9r.
Data bölgesi DOS'a göre sektörlerden de8il cluster'lardan olu/maktad9r. lk cluster numaras9 2
olarak belirlenmi/tir.

data bölgesi
------------------
|2 |3 |4 |5 |6 |
------------------
|7 |8 |9 |10|11|
------------------
....
...
...
----------------
Örne8in data bölgesinin n'inc/ cluster'9n9n hangi mant9ksal sektörden ba/lad989
(n-2) * spc + data_or
ifadesi ile hesaplanbilir.

spc =>sektör ba/9na cluster say9s9


data_or =>data bölgesinin hangi mant9ksal sektörden ba/lad989

Örne8in n'inci cluster bilgisini elde etmek için


1. bootinfo fonksiyonu ile bpb blo8u elde edilir.
2. (n - 2) * sc + data_or ifadesi ile ilgili cluster'9n hangi mant9ksal sektörden ba/lad989 bulunur.
3.absread fonksiyonu ile spc kadar sektör okunur.

S9n9f çal9/mas9: stenilen bir cluster bilgilerini okuyan fonksiyonun tasarlanmas9

Fonksiyonun parametresi:

int read_cluster(long cno, const BOOT *bpb, void *buf);

------------disk.h-------------------
/*----------------------------------------------------------------------

36
Disk Header File
----------------------------------------------------------------------*/

#ifndef _DISK_H_

/* Symbolic contants */

#define SECT_SIZE 512

/* typedefs */

typedef unsigned char BYTE;


typedef unsigned int WORD;
typedef unsigned long int DWORD;

/* Boot sector */

typedef struct _BOOT {


WORD fat_len; /*fat length as sector (A)*/
WORD root_len; /*root length as sector*/
WORD fat_num; /*number of fat(A)*/
DWORD total_sec; /*total sector (A)*/
WORD bps; /*byte per sector(A)*/
WORD spc; /*sector per cluster(A)*/
WORD reserved_sect; /*reserved sector(A)*/
BYTE media_descriptor;/*media descriptor byte(A)*/
WORD spt; /*sector per track(A)*/
WORD root_ent; /*root entry(A)*/
WORD head_num; /*number of heads(A)*/
WORD hid_num; /*number of hidden sector(A)*/
WORD tph; /*track per head*/
WORD fat_or; /*fat director location*/
WORD root_or; /*root directory location*/
WORD data_or; /*first data sector location*/
} BOOT;

/* Function Prototypes */

int boot_info(BOOT *info, int drive);

#endif
----------------------------------------

--------------clust.c-------------------
/*-------------------------------------------------------------------

37
Disk Implementatin File
---------------------------------------------------------------------
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
#include "disk.h"

/* Functions */

int read_cluster(int drive, long cno, const BOOT *bpb, void *buf)
{
long sect_num;

sect_num = (cno - 2) * bpb -> spc + bpb -> data_or;


return absread(drive, bpb -> spc, sect_num, buf);
}

int boot_info(BOOT *info, int drive)


{
BYTE btr[SECT_SIZE];

if (absread(drive, 1, 0, btr) == -1)


return -1;
info -> fat_len = *(WORD *)(btr + 0x16);
info -> root_len = *(WORD *)(btr + 0x11) * 32 / 512;
info -> fat_num = *(BYTE *)(btr + 0x10);
if (*(WORD *)(btr + 0x13))
info -> total_sec = *(WORD *)(btr + 0x13);
else
info -> total_sec = *(DWORD *)(btr + 0x20);
info -> bps = *(WORD *)(btr + 0xB);
info -> spc = *(BYTE *) (btr +0xD);
info -> reserved_sect = *(WORD *)(btr + 0xE);
info -> media_descriptor = *(btr + 0x15);
info -> spt = *(WORD *)(btr + 0x18);
info -> root_ent = *(WORD *)(btr + 0x11);
info -> head_num = *(WORD *)(btr + 0x1A);
info ->hid_num = *(WORD *)(btr + 0x1C);
info -> tph = (WORD) (info -> total_sec / info -> spt / info -> head_num);
info -> fat_or = info -> reserved_sect;
info -> root_or = info -> fat_len * info -> fat_num + info -> reserved_sect;
info -> data_or = info -> root_or + info -> root_len;

38
return 0;
}

#if 0/*
ileride yorum sat9r9 ile kesmek yerine preprocessor kodu ile
c9karabilmek için #if kulland9k.ard9ndaki say9 0 ise #endif'e kadar
olan k9s9m kod'dan c9kar9lacakt9r
*/
void main(int argc, char *argv[])
{
BOOT boot;
int result;

if (argc != 2) {
printf("Wrong number of arguments...\n");
exit(1);
}
if (!isalpha(argv[1][0]) || argv[1][1] != ':') {
printf("Invalid drive: %s\n", argv[1]);
exit(1);
}
printf("Ok...\n");
result = boot_info(&boot, toupper(argv[1][0]) - 'A');
if (result == -1) {
printf("Cannot get boot record...\n");
exit(1);
}
printf("Bytes per sector: %u\n", boot.bps);
printf("Sector per cluster: %d\n", boot.spc);
printf("Number of Head: %u\n", boot.head_num);
printf("Fat origin: %u\n", boot.fat_or);
printf("Root origin: %u\n", boot.root_or);
}

#endif

#if 1

void main(void)
{
BOOT bpb;
BYTE *buf;
int i;
int result;

39
clrscr();
result = boot_info(&bpb, 0);
if (result == -1) {
printf("Cannot read boot sector.. Disk unusable...\n");
exit(1);
}
buf = (BYTE *)malloc(bpb.bps * bpb.spc);

result = read_cluster(0, 10, &bpb, buf);


if (result == -1) {
printf("Cannot read cluster...\n");
exit(1);
}
for(i = 0; i < 32; ++i)
printf("%02x%c", buf[i], i % 16 == 15 ? '\n' : ' ');
free(buf);
}

#endif

-------------------------------

FAT BÖLGES N N YAPISI

FAT bölgesi cluster numaralar9ndan olu/mu/ bir ba8l9 liste yap9s9 biçiminde
tasarlanm9/t9r. FAT bölgesi 12 bit, 16 bit, 32 bit omak üzere 3 çe/ittir.

16 Bit FAT

------------------------------------------------------------------------------------------
| | | 2| 3| 4| 5| 6| 7| 8| 9|
| | | | | | | | |17 | |
------------------------------------------------------------------------------------------
| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19|
| | | | | | | |18 |22 | |
-------------------------------------------------------------------------------------------
| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29|
| | |24 | |EOF | | | | |
--------------------------------------------------------------------------------------------
| | | | | | | | | | |
| | | | | | | | | | |
-------------------------------------------------------------------------------------------
| | | | | | | | | | |

40
| | | | | | | | | | |
----------------------------------------------------------------------------------------------
örnek bir dosyan9n FAT'teki s9ralamas9(8-17-18-22-24)

Önceki eleman9n sonraki elaman9 gösterdi8i listelere ba8l9 liste denir.(linked list) FAT
bölgesi FAT elemanlar9ndan olu/ur, bir FAT eleman9 16 FAT'lerde 16 bit 32 bit FAt'lerde 32 bit
ve 12 bit FAT'lerde 12 bitten olu/ur. /letim sistemi bir dosyan9n parçalar9n9n hangi cluster'larda
oldu8unu /öyle bulur. Dosyan9n ilk cluster'9n9n yerini FAt bölgesine bakmadan önce bilmek
zorundad9r. Her FAT eleman9nda bir sonraki cluster'9n hangi FAT eleman9nda oldu8u bilgisi
vard9r. Zincir özel bir say9 ile bitirilir. lk iki FAT eleman9 reserve edilmi/tir ve içerisinde özel bir
de8er vard9r.

FAT eleman9n9n içerisinde yaz9lan say9lar9n yorumlanmas9

De8er Anlam9
0000 Bo/
0001-FFEF Sonraki cluster
FFF0-FFF6 Reserved cluster
FFF7 Bad cluster
FFF8-FFFF End of file

Bir FAT eleman9nda 0000 varsa o cluster DOS taraf9ndan istenildi8i zaman tahsis
edilebilir yani bo/tur.E8er FAT elam9nda FFF(-FFFF aras9 bir de8er varsa bu i/lem FAT
zincirinin bitti8ini belitir. (Genellikle buradafi say9 FFFF biçimindedir.) E8er FAT eleman9nda
FFF7 de8eri varsa ilgili cluster fiziksel bir kusurdan dolay9 kullan9lamaz bir durumdad9r. FAT
bölgesi formatlama i/lemi s9ras9nda 0 de8erleriyle doldurulur. Ancak format program9 e8er
fiziksel kusurlu sektörler tespit ederse bu sektörlere ili/kin cluster'lar9 "bad cluster" olarak belirler
ve bu bad clusterlara ili/kin FAT elemanlar9n9 FFF7 ile doldurur. Böylece i/letim sistemi bu
bölgeye yükleme yapmaz.

16 bit FAT'te i/lemler

FAT bölgesinin BYTE *fat; gibi bir göstericinin içerisinden ba/lsad989n9 varsayal9m. Yani
fat isimli göstericinin içerisinde diskteki FAT bölgesinin bellekteki görüntüsü bulunmaktad9r. Bu
durumda n numaral9 FAT elam9n9 çekmek için *(WORD *)(fat + n *2) denklemi kullan9labilir.
Ya da bu adres WORD türünden bir göstericiye atan9p i/lemler kolala/t9r9labilir:
WORD *fwfat;
pwfat = (WORD *)fat;
pwfat[n];

12 bit FAT yap9s9

41
12 bit FAT'te 12 bit uzunlu8undad9r. Yani 3 hex digit yer kaplamaktad9r. Bu durumda
FAT bölgesi BYTE *fat; biçiminde bir gösterici taraf9ndan belirleniyorsa n'inci FAT eleman9n9n
içerisindeki de8er /u algoritmayla bulunabilir:

BYTE *fat;
WORD w;

if (n % 2 == 1) {
w = *(WORD*)(fat + n * 3 / 2);
w = w >> 4;/*w'nun dü/ük anlaml9 4 bitinin 0'lanmas9 için*/
}
else {
w = *(WORD *)(fat + n * 3 / 2);
w = w & 0x0FFF);/*w'nun yüksek anlaml9 4 bitinin 0'lanmas9 için*/
}

E8er DOS formatl9 bir diskte toplam sektör say9s9 32680'den küçükse kesinlikle12 bit
FAT büyükse 16 bit FAT vard9r demektir. (BPB alan9nda toplam sektör say9s9 yaazmaktad9r.)

12 bit FAT sisteminde FAT eleman9n9n alaca89 de8erler

De8er Anlam
000 Bo/
001-FEF Sonraki cluster
FF0-FF6 Reserved cluster
FF7 Bad cluster
FF8-FFF Zincir sonu

FORMATLAMA LEM

Formatlama i/lemi iki a/amada yürütülen bir i/lemdir. Birinci a/amaya a/a89 seviyeli
formatlama denir. A/a89 seviyeli formatlama i/letim sistemine ba8l9 de8ildir. A/a89 seviyeli
formatlama s9ras9nda sektör bo/luklar9 (sector gap) düzenlenir ve içlerine baz kritik bilgiler
yaz9l9r. Gerçekte sektör dilimleri birbirlerini izlemez, her sektör dilimiyle di8eri aras9nda sektör
bo/lu8u dedi8imiz bir alan vard9r. 2 Mb'lik disket formatland989nda bu sebepten dolay9 1.44 Mb'a
dü/er. A/a89 seviyeli formatlamadan sonra i/letim sisteminin disk organizasyonu için
organizasyon bilgilerinin yaz9lmas9 için yüksek seviyeli formatlama yap9l9r. Örne8in DOS için bu
i/lem BOOT ve BPB alan9n9n olu/turulmas9 FAT ve ROOT bölgelerinin 0'lanmas9 biçimindedir.
Harddisklerde a/a89 seviyeli formatlama i/lemi disk'i satanlar taraf9ndan ilk elden yap9lm9/t9r.
Disketler için format program9n9n birkaç seçene8i vard9r. /u (unconditional) ve /q (quick). A/a89
seviyeli formatlama i/leminden sonra bilgi kurtar9lmas9 söz konusu de8ildir.

D SK ORGAN ZASYON BOZUKLUKLARI

42
Bu tür bozukluklarda fiziksel bir bozukluk söz konusu de8ildir. Yaln9zca disk üzerindeki
organizasyona ili/kin bilgilerde bozukluk vard9r. DOS/WINDOWS için /u tür organizasyon
bozukluklar9 söz konusu olabilir.

1-)Kay9p cluster'lar(lost clusters):


Bu durumda ortada bir dosyaya ili/kin FAT zinciri vard9r. Ancak directory bölgesinde bu
zincir için bir giri/ yoktur. Bu tür durumlarda onaran programlar zincir için directory
giri/inde bir dosya giri/i olu/tururlar.

2-)Kar/9l9kl9 ba8l9 dosyalar(cross linked file):


Bu durmda iki ayr9 FAT zinciri belli bir noktadan sonra birle/erek devam etmektedir.
Onaran programlar birle/im yerinden sonraki cluster'lar9n bir kopyas9n9 ç9kartarak iki
zinciri birbirinden ay9r9r.

3-)Tahsisat hatas9(alocation error, size adjusted):


Bu durumda directory giri/indeki dosya uzunlu8u ile o dosya için FAT zincirinde
tahsis edilmi/ olan cluster uzunlu8u uyu/mamaktad9r. Onaran programlar FAT zincirini
esas alarak directory giri/indeki dosya uzunlu8unu güncellerler.

4-)FAT bozuk(File allocation table bad..):


FAT bölgesinin ilk iki eleman9 uygun de8erlerde de8ilse ya da FAT bölgesi a/9r9 derecede
bozuksa söz konusudur.

5-)Genel okuma/yazma hatas9(general failure error read/write ):


Burada BOOT sector BPB bölgesi anlaml9 bir biçimde olu/turulmam9/t9r. Ya disk foratl9
de8ildir ya da DOS formatl9 bir disk söz konusu de8ildir. Onaran program9n yapabilece8i
birsey yoktur.

Mademki bir diskin en önemli bölgesi 0. track içerisinde bulunmaktad9r. E8er bu track
bozuksa diskin tamam9 kullan9lamaz duruma dü/er(track 0 bad, disk unusable). /letim sisteminin
boot etmek için gereken dosyalar directory giri/inde yaz9 olan normal bir tak9m dosyalard9r.
Örne8in DOS i/letim sisteminde msdos.sys, io.sys ve command.com dosyalar9 sistem
dosyalar9d9r. Sistem dosyalar9n9n bir bölümü disk üzerinde önceden belirlenmi/ olan clusterlarda
bulunmak zorundad9r. Örne8in DOS'ta msdos.sys ve io.sys dosyalar9 data bölgesinin ilk
clusterlar9nda olmak zorundad9r. Bu zorunluluk boot sectr içerisindeki yükleyici program9n FAT
ve ROOT bölgelerinde inceleme gere8ini ortadan kald9rmaktad9r.

UNIX LET M S STEM N N DOSYA S STEM

Unix AT&T kurumuna ili/kin tescillli bir isimdir. de8i/ik firmalar de8i/ik unix sistemleri
yazm9/lard9r. Bunlardan baz9lar9:
UNIX
HPUNIX
SCOUNIX
XENIX

43
LINUX
Unix'in dosya sistemi ve disk organizasyonu DOS'unkinden oldukça farkl9d9r. Cluster
kavram9 yerine block kavram9 vard9r. Bir block n tane sektörden olu/ur. Bir unix disk'i a/a89daki
gibi organize edilmi/tir.

Boot Block

Super Block

i-node list

Data

Bir block'un kaç sektör oldu8u kurulum s9ras9nda kuran ki/iye sorularak belirlenir.
Genelikle 2-4-8 de8eleri kullan9l9r. BOOT BLOCK bir block uzunlu8undad9r. Ve DOS'ta oldu8u
gibi i/letim sisteminin yüklenmesiyle ilgilidir. Super block da bir block uzunlu8undad9r ve
DOS'un BPB alan9na kar/9l9k gelir. Yani kritik format bilgileri burada tutulur. Örne8in toplam
block say9s9, bir block'un kaç sektörden olu/tu8u vb.. i-node list n block uzunlu8undad9r ve i-node
elemanlar9ndan olu/ur. i-node elemanlar9n9n unix sisteminde unix sistemine de8i/ebilir. i-node
elemanlar9n9n her biri bir dosyaya ili/kindir. i-node elemanlar9n9n her birinin içerisinde dosyan9n
güvenlik bilgileri, dosyan9n disk üzerinde hangi blocklarda oldu8u vb. bilgiler bulunur. i-node list
bölgesinin uzunlu8u de8i/tirilemez. Yani dosya sistemindeki dosyalar9n belli bir say9s9 olmak
zorundad9r. Dosyalar9n isimleri yani directory bilgileri data bölgesinde s9radan bir dosyaym9/ gibi
tutulur. Bir directory dosyas9 dosya bilgi elemanlar9nda olu/ur. Dosya bilgi elemanlar9 dosya
isimlerinden(14 byte) ve i-node numaralar9ndan(2 byte) olu/ur. i-node numaras9 o dosyaya ili/kin
bilgilerin i-node list bölgesi içerindeki hangi i-node eleman9nda oldu8unu gösterir.

isim(14 byte) i-node numaras9(2 byte)


|--------------| |--|

Root directory'e ili/kin dosya bilgileri s9f9r9nc9 i-node eleman9nda tutulmaktad9r. Alt
dizinler normal bir dosyaym9/ gibi organize edilirler.

44
i-node Elemanlar9n9n Yap9s9
___________________
| | Bir dosyan9n uzunlu8u 10 bloktan küçük ya da e/it ise
| -------- | dosyan9n parçalar9n9n hangi bloklarda oldu8u do8rudan
| -------- | "10 direct block pointer" ile belirlenen bloklarda aran9r
| ---------| Bir blok numaras9 ganellikle 4 byte uzunlu8undad9r.
|__________________| 1 block = 2 sektör(1024 byte) oldu8una göre 1 blok,256
| |Link no. blo8un numaras9n9 tutabilir. Dosyan9n uzunlu8u 10-256.
|__________________| blok aras9nda ise "single block pointer" ile belirtilen
| |Size blokta, dosyan9n hangi blokta oldu8unu belirten bilgiler
|__________________| vard9r.
|__________________| E8er dosya 256 bloktan daha büyükse ve 65536 bloktan
|__________________| küçük ya da e/it ise "double block pointer" in gösterdi8i
|__________________|10 direct blok içerisinde dosya parçalar9n9n hangi bloklarda
|__________________| block oldu8una ili/kin bloklar9n hangileri oldu8unu anlatan
|__________________| pointer bilgiler vard9r. Bu sistemin en büyük dezavantaj9 tahsis
|__________________| edilme potansiyelinde olan bo/(free) bloklar9n
|__________________| saptanamamas9d9r. Bo/ blok(free block) listesini tutan
|__________________| özel bloklar vard9r. ilk n tane bo/ blok kolay eri/ilsin
|__________________| diye süper blokta tutulmaktad9r. Her blo8un son bo/ blok
|__________________| eleman9 bir sonraki bo/ blok bilgilerinin tutuldu8u
| | Single bilgileri gösterir. UNIX tabanl9 sistemlerde i-node
| | block numaras9n9 veren ve i-node bilgilerinin elde edilmesini
| | pointer sa8layan özel sistem fonksiyonlar9 vard9r. UNIX
|__________________| sistemlerinde de directory içerisinde dosya bulmaya
| | yarayan findfirst ve findnext gibi sistem fonksiyonlar9
| | Double vard9r.
| | block
|__________________|pointer
| |
| | Triple
| | block
|__________________| pointer
| DATA |
|__________________|
| DATA |
|__________________|
| DATA |
|__________________|
.............

45
.............
.............
.............

D SK BÖLGE TABLOSU (DISC PARTITION TABLE)

Bir hard disk de8i/ik i/letim sistemlerinin yüklenmesine olanak verecek /ekilde organize
edilmi/tir. Disk üzerinde ard9/9l sektörlerden olu/mu/ ve her bir tanesi farkl9 dosya sistemleri ile
organize edilen bölgeler olu/turulabilir. Bu bölgelere 'partition' denir. Söz konusu bu disk
bölgelerine ili/kin bilgiler, ismine disk bölge tablosu denilen bir tablo ile tutulurlar. Disk bölge
tablosu içerisinde bölgelerin hangi kafa-iz-sektör dilimlerinde ba/lad989, hangi kafa- iz- sektör
dilimlerinde bitti8i, kaç sektör uzunlu8unda bitti8i gibi bilgiler vard9r.

Disk bölge tablosu 4 bölgenin yerini tutacak /ekilde 4 elemanl9d9r. Her bir giri/ 16 byte
uzunlu8undad9r. Disk bölge tablosu her hard-diskin 0. yüz 0. iz ve 1. sektöründedir. Bu sektörün
1beH (Decimal 446) offsetinden ba/lar. Yani disk bölge tablosu diskin ilk sektörünün son
16 * 4 + 2 byte'l9k bölgesindedir. Son 2 byte disk bölge tablosunun geçerli olup olmad989n9
gösteren kontrol byte'lar9d9r. Bu byte'lar9n 55 AA biçiminde olmas9 gerekir. Fdisk program9
asl9nda bu 64 byte uzunlu8undaki bölge üzerinde i/lemler yapar. Hard-diskin ilk sektörüne MBR
(Master Boot Record) denir. Her disk bölgesinin ilk sektörü o dosya sisteminin boot sektörü
olmak zorundad9r.

D SK BÖLME TABLOSUNUN FORMATI

OFFSET UZUNLUK ANLAMI


0(0) BYTE Bölge durumu:burada ilgili partian9n aktif olup olmad989 bilgisi vard9r.
Buradaki bilgi ya 00h yada 80h durumundad9r.4 bölgeden yaln9zca biri
80h de8erine sahiptir. 80h bülgenin aktif oldu8unu gösterir. Aktif bölge
hangi bölgenin default i/letim sistemine sahip oldu8unu anlat9r
1(1) BYTE Ba/lang9ç kafa numaras9 ilgili bölgenin hangi yüzden ba/lad989n9
gösterir.
2(2) word Ba/lang9ç sektör ve track
4(4) byte Bölge türü o bölgedeki i/letim sisteminin hangisi oldu8unu belirtir.
5(5) byte Biti/ kafa numaras9
6(6) word Biti/ sektör ve track
8(8) dword Ba/lang9ç mant9ksal sektör no
c(12) dword Bölgedeki toplam sektör say9s9

hangi disk bölgesinin aktif oldu8unu tespit eden ve onun boot sektörünü yükleyip çal9/t9ran
program MBR sektöründe bulunmaktad9r. yani bios taki program kontrolu MBR içindeki
programa b9rak9r. MBR daki ise kontrolu aktif bölgenin boot sektörüne b9rakmaktad9r. bir tak9m
bölge yönetim programlar9 MBR yerine yüklenmi/ olabilir. bu durumda aç9l9/ s9ras9nda hangi

46
i/letim sisteminin yüklenece8i sorulur; MBR daki yeni program ilgili bölgedeki i/letim sisteminin
yüklenmesini sa8lar.

BA LANGIÇ VE B T SEKTÖR VE TRACK B LG S N N HESAPLANMASI

C C S S S S S S C C C C C C C C

n byte n+1 byte

E8er bölge türü 5 ise bu bölgenin ayr9 bir disk alan9 gibi de8erlendirelece8i anlam9 ç9kar buna
extended partian denir di8erlerine primary partian denir extended partian ayr9 disk gibi ele al9n9r
extended partian9n da ilk sektöründe yine bir disk bölge tablosu vard9r. Ancak extended partiana
ili/kin bölge tablosunda iki giri/ vard9r.

!!!!!!!!!! KEND KEND N ÇAOIRAN FONKSIYONLAR !!!!!!!!!

RECURS VE FUNCT ONS

Bir fonksiyon hatta main bile kendini ça89rabilir. tabii bu ça89rma i/leminin belli bir say9s9
olmal9d9r. e8er bir fonksiyon sürekli kendini ça89r9rsa stack ta/mas9 olu/ur ve sistemin bütünlü8ü
bozulur. bir fonksiyonun ne kadart say9da kendini ça89rabilece8i çal9/9lan sistemdeki mikro
i/lemci, i/letim sistemi, fonksy9n içindeki yerel de8i/kenlerin taoplam uzunlu8u gibi faktörlere
ba8l9d9r. kendi kendini ça89ran bir fonksiyondaki yerel de8i/kenler ne kadar fazla yer kaplarsa
kendi kendini ça89rma say9s9 o kadar azal9r. böyle fonksiyonlar9n tasar9m9nda büyük yerel
dizilerin kullan9lmas9 tavsiye edilmez.

KEND KEND N ÇAOIRAN FONKSIYONLARIN FAYDALARI


Yaz9l9mda kullan9lan algoritmalar kendi kendini ça89rma aç9s9ndan 3 bölümde incelenebilir.

1- Kenci kendini ça89rmayan fonk larla kullan9lan algoritmalar: algoritmalar9n ço8u bu türdendir.

2- hem kendi kendini ça89ran hemde ça89rmayan fonklarla sa8lanabilen algoritmalar: bu tür
algoritmalar9n iki yaz9m biçimide oalbilir.

3- yaln9zca kendi kendini ça89ran fonksiyonlarla ça89r9labilen algoritmalar: bu tür algoritmalar9n


kendi kendini ça89rmayan fonksiyonlarla tasar9m9 imkans9z veya imkans9z denecek kadar zordur.

47
/*---------fakt.c-------------*/
/*--recursive de8il--*/
long factorial (int n)

{
long i;
long f = 1;

for (i = 1; i <= n; ++i)


f *=i;

return f;
}

main (void)
{
printf("%ld\n", factorial(8));
}
/*-------------------------------*/

Örnek:Faktoriyel algoritmas9n9n kendi kendini ça89ran bir algoritmayloa tasar9m9.


bir fonksiyon kendini ça89r9nca yerel de8i/kenler tekrar yarat9l9rlar.

/*-------fakt_rek.c--------------*/
/*---------recursive------------*/
long factorial (int n)

{
long temp;

if (n == 0)
return 1;
temp = n * factorial (n-1);
return temp;
}

main (void)
{
printf("%ld\n", factorial(8));
}
/*--------------------------------*/

Örnek:Bir say9n9n tam üssünü alan fonksiyon tasar9m9.

48
/*-----------pow_rek.c------------*/
/*recursive*/
long rpow(double a, int b)
{
if (b == 0)
return 1;
return a * rpow(a, b - 1);
}

main (void)
{
printf("%ld", rpow(2,8));
}
/*---------------------------------*/

Örnek:Bir diziyi s9raya dizen recursive bir fonksiyonun tasar9m9.(seçerek s9ralama yöntemiyle)

Böyle bir tasar9mda dizinin ba/lang9ç adresi ve uzunlu8u fonksiyona parametre olarak
verilir. Fonksiyon dizinin en büyük eleman9n9 bularak sonundaki elemanla yer de8i/tirir ve kendi
kedisini bir eksik uzunluk ile ça89r9r. Uzunluk 1 oldu8unda i/lem bitirilir.

/*-----------rsort.c----------------*/
void rsort(int *p, int n)
{
int i, max, indis;

if (n == 1)
return;
max = p[0];
indis = 0;
for (i = 1; i < n; ++i)
if(max < p[i]){
max = p[i];
indis = i;
}
p[indis] = p[n-1];
p[n-1] = max;
rsort(p, n-1);
}

main(void)
{
int s[5] = {4, 2, 8, 6, 7};
int i;

49
clrscr();
rsort(s, 5);
for (i = 0;i < 5; ++i)
printf("%d\n", s[i]);
}
/*-----------------------------------*/

Örnek:Sadece putchar fonksiyonu kullanarak int bir de8erin ekrana yaz9lmas9.

/*---------printd.c-----------*/
/*---------print_re.c---------*/

Örnek:Bir karakter dizisini ters yüz eden fonksiyonun recursive olarak tasar9m9.

/*----------swapelem.c-------------*/
#include <string.h>
#include <stdio.h>

void swapelem(char *str, int l, int r)


{
char temp;

if (l >= r)
return;
temp = str[l];
str[l] = str[r];
str[r] = temp;
swapelem(str, l + 1, r - 1);
}

void mystrrev(char *str)


{
swapelem(str, 0, strlen(str) - 1);
}

void main(void)
{
char *text = "Merhaba Dünya";

puts(text);
mystrrev(text);
puts(text);
}
/*----------------------------------*/

50
Dizin Arama /lemleri(Directory Search And Traversing)

findfirst fonksiyonunun üçüncü parametresi dizin içerisinde hangi özellikteki dosyalar9n


aranaca89n9 gösterir. Özellikler dos.h içerisinde yaln9zca bir bit'i 1 olan sembolik sabitler
biçiminde tan9mlanm9/t9r.

FA_RDONLY
FA_HIDDEN
FA_SYSTEM
FA_LABEL
FA_DIREC
FA_ARCH

Bu sembolik sabitler bit OR i/lemine sokulur. Örne8in


#define FA_ALL (FA_DIREC | FA_ARCH | FA_HIDDEN | FA_SYSTEM)

ifadesi sayesinde FA_ALL kullan9larak tüm attribute'lar için arama yap9labilir.

Örnek:Recursive olarak dizin dosyalar9 listelenmesi


/*--------------dirsearc.c------------------*/
#include <stdio.h>
#include <dos.h>
#include <dir.h>

void main(void)
{
struct ffblk X;
int result;

result = findfirst("c:/*.*", &X, FA_DIREC);


while(!result){
if(X.ff_attrib & FA_DIREC)
printf("%s\n", X.ff_name);
result = findnext(&X);
}
}
/*-------------------------------------------*/

Örne8imizdeki walk_tree fonksiyonu kendi kendini ça89rarak bütün dizinleri


dola/maktad9r. walk_tree fonksiyonu bir dizin dosyas9 buldu8unda global pth dizisini o dizini
belirtecek biçimde günceller ve kendini ça89r9r.

/*-------------dirlist.c------------------*/
#include <stdio.h>

51
#include <dir.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>

/*Symbolic Constants*/

#define MAXPATH 80

/*Function Prototype*/

void walk_tree(void);
void disp_dir(const char *str);
void next_path(const char *str);
void prev_path(void);
void dirtree(int drive);

/*Global Variables*/

char pth[MAXPATH] = "C:/*.*";

/*Functions*/

void next_path(const char *str)


{
*(pth + strlen(pth) - 3) = '\0';
strcat(pth, str);
strcat(pth, "/*.*");
}

void prev_path(void)
{
char *str = pth;
int n;

n = strlen(pth);
str += n -5;
while(*str != '/')
--str;
*str = '\0';
strcat(str, "/*.*");
}

void disp_dir(const char *str)


{

52
/*int num = 0;*/
int i/*, len*/;

/* while (str[num])
++num;*/
for(i = 0; i < /*num*/ strlen(str) - 4; ++i)
putchar(str[i]);
putchar('\n');
}

void dirtree(int drive)


{
pth[0] = drive + 'A';
walk_tree();
}

void walk_tree(void)
{
struct ffblk fdirec;
int result;

result = findfirst(pth, &fdirec, FA_DIREC | FA_SYSTEM | FA_HIDDEN);


while(!result) {
if (!strcmp(fdirec.ff_name, ".")) {
result = findnext(&fdirec);
result = findnext(&fdirec);
continue;
}
if(fdirec.ff_attrib & FA_DIREC){
next_path(fdirec.ff_name);
disp_dir(pth);
walk_tree();
}
result = findnext(&fdirec);
}
prev_path();
}
#if 1

void main (void)


{
dirtree(2);
}
#endif
/*-----------------------------------*/

53
Örnek:sector per cluster büyüklü8ü yüzünden kullan9lamayan yeri bulan program9n tasarlanmas9.

/*-------------tsize.c---------------*/
#include <stdio.h>
#include <dir.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>

/*Symbolic Constants*/

#define MAXPATH 80

/*Function Prototype*/

void walk_tree(void);
void next_path(const char *str);
void prev_path(void);
long GetAllocSize(int drive);

/*Global Variables*/

char pth[MAXPATH] = "C:/*.*";

long size = 0;

/*Functions*/

void next_path(const char *str)


{
*(pth + strlen(pth) - 3) = '\0';
strcat(pth, str);
strcat(pth, "/*.*");
}

void prev_path(void)
{
char *str = pth;
int n;

n = strlen(pth);
str += n -5;
while(*str != '/')

54
--str;
*str = '\0';
strcat(str, "/*.*");
}

long GetAllocSize(int drive)


{
pth[0] = drive + 'A';
walk_tree();
return size;
}

void walk_tree(void)
{
struct ffblk fdirec;
int result;

result = findfirst(pth, &fdirec, FA_DIREC | FA_SYSTEM | FA_HIDDEN);


while(!result) {
if (!strcmp(fdirec.ff_name, ".")) {
result = findnext(&fdirec);
result = findnext(&fdirec);
continue;
}
if(fdirec.ff_attrib & FA_DIREC){
next_path(fdirec.ff_name);
walk_tree();
}
else
size += fdirec.ff_fsize % (16 * 512);
result = findnext(&fdirec);
}
prev_path();
}
#if 1

void main (void)


{
printf("%ld\n", GetAllocSize(2));
}
#endif
/*---------------------------------------*/

Çok /lemli Sistemlerde Kaynak Payla/9m9

55
Çok i/lemli(multi-processing) sistemlerde n tane program(process) zaman payla/9ml9
olarak de8i/tirmeli bir biçimde çal9/t9r9lmaktad9r. Genellikle i/letim sistemlerinde dönerli
çizelgeleme (round rolling scheduling) sistemi kullan9l9r. Bu sistemde her bir program s9ras9yla
belli bir süre(quantum) çal9/t9r9l9r. Baz9 sistemlerde(örne8in WINDOWS 95/98/NT) ayn9
zamanda bir öncelik derecesi sistemi de kullan9l9r. Bu sisteme göre öncelik derecesi yüksek
olanlar tam olarak bitirildikten sonra di8erlerine çizelgeleme uygulan9r. Tabii i/letim sistemi
klavye, mouse gibi d9/sal birimleri kullanmak isteyen programlar9 bu istekler kar/9lanana kadar
çizelgeleme d9/9 b9rak9rlar. Bu duruma bloke edilme(process blocking) denir. D9/sal olay
gerçekle/ti8inde i/letim sistemi tekrar program9 çizelgelemeye devam eder.
Çok i/lemli sistemlerde bir program9n çal9/t9r9lma süresi doldu8unda di8er bir program
çal9/t9r9l9r. Bu i/leme görevler aras9 geçi/(task switch) i/lemi denir. Bir program payla/9lan bir
kayna89 kullanmaya ba/lad989nda bir görevler aras9 geçi/ durumu olu/ursa ba/ka bir program da
bu kayna8a eri/ti8inde problemli bir durum ortaya ç9kar. Çünkü önceki program bir tak9m
i/lemlere ba/lam9/ olabilir, oysa geçilen program yeni ba/tan bir tak9m i/lemleri ba/latm9/
olabilir. Program9n çal9/ma s9ras9 eski programa geldi8inde bu program9n olu/turdu8u eski
de8erler kaybolaca89ndan sistem çöker. Sistemin çökmemesi için payla/9lan kayna89n b9rak9lana
kadar tek program taraf9ndan kullan9lmas9 sa8lanmal9d9r.
Payla/9lan bir kayna89 kullanan koda kritik kod(critical section) denir. Kritik kodlara
giri/ler ve bu kodlardan ç9k9/lar i/letim sisteminin özel fonksiyonlar9 ça89r9larak belirtilmelidir.
E8er bir program kritik bir koda girdiyse ve ba/ka bir program da ayn9 kayna8a ula/mak istemi/se
o program i/letim sistemi taraf9ndan çizelgeleme d9/9 b9rak9l9r. lk program kritik kodu
bitirdi8inde di8er program çizelgeleme dahil edilerek kritik koda sokulur. Kritik kod yaratma
i/lemine semafor ya da seri hale getirme i/lemi denir.

HATA AYIKLAMA VE ASSERT MAKROSUNUN KULLANIMI

BUG NED R??

Bir kodun baz9 durumlarda hatal9 çal9/mas9na yol açan olaylar. Bir program9n yanl9/
çal9/mas9na yol açan gizli yaz9l9m hatalar9d9r. Bug lar program9n sat9r say9s9n9n artmas9 ile do8ru
orant9l9 bir /ekilde artarlar. Bir programda bug olup olmad989 büyük firmalarda içsel test
bölümlerince test edilir testin son a/amas9 gerçek kullan9m testi(beta) testi a/amas9d9r. buglar9n
ay9klanmas9 ve tespit edilmesi için özel yaz9l9mlara gereksinim duyulabilir. Bir program9n hatas9z
olmas9n9 sa8laman9n en önemli yolu program9 hatas9z olarak yazmaya çal9/makt9r. Hatas9z
program yazmak için al9nacak ilk önlem uyar9 mesajlar9n9 gözden geçirmektir. Çünkü uyar9
mesajlar9n9n %95'i programc9n9n9 gerçekten yapm9/ oldu8u hatalar9 bildirmektedir. derleyicilerin
uyar9 mesajlar9n9n baz9lar9 kurulum s9ras9nda default olarak pasif duruma getirilmi/tir. Bunlar9n
hepsinin aktive edilmesi hata yakalama aç9s9ndan önemlidir. Uyar9 mesajlar9 ya da uyar9y9
gerektiren durumlar standart olarak belirlenmemi/tir ama error gerektiren durumlar dilin kurallar9
ile ilgili oldu8u için standardize edilmi/tir.

BUGLARIN PROGRAMIN YAZILIMI SIRASINDA TESP T ED LMES

Bir program9 yazarken hatalar9n tespit edilmesinin en iyi yolu bir ipucunun elde
edilmesidir. Bu ipucunun sa8lanmas9 için program içinde hata yap9lma olas9l989 olan tüm kodlara

56
if kontrolleri yerle/tirilir. if deyimi içerisine bir mesaj yaz9larak program sonland9r9labilir. Bu
mesaj bir ipucu niteli8indedir. Buradan hareketle bug'a yol açan kod bulunabilir. Her türlü hata
olas9l989 içeren kodlara kontrol yerle/tirmek iyi bir çözümdür. Ancak gereksiz kontroller program9
büyütür ve yava/lat9r. Yap9lacak en iyi /ey program deneme(debug) ve gerçek (release)
versiyonlar9na ay9rmakt9r. Deneme versiyonu kontrollü ve yava/ çal9/an verisyondur, ancak
hatalar bu sayede tespit edilebilir. Oysa release versiyon kontrollerin silinmesi ile elde edilmi/
versiyondur, sat9lcak olan da release versiyonu sat9lacakt9r. /te en önemli nokta tek bir kod
üzerinde bu kontrollerin eklenip ç9kart9lmas9na olanak sa8layacak bir yöntem belirlemektir.
Özetle program deneme versiyonu ile geli/tirilip test edilir gerçek versiyonu ile sat9l9r. Bu i/lemin
de pratik bir biçimde yap9lmas9 gerekir.

DEBUG KONTROLLER NEREYE VE HANG DURUMLARDA YERLE T R LMEL D R??

1- Gösterici parametresi alan fonksiyonlarda geçirilen adresin NULL gösterici olup olmad989n9n
testi. Yani gösterici parametresi alan tüm fonksiyonlar9n blok ba/lar9nda bu durum test
edilmelidir.

2- S9n9r de8erlerinin test edilmesi için konulan de8erler.

3- Verify i/lemlerinde kullan9labilir. Olmas9 kesin gözüyle bak9lan durumlar9n test edilmesine
yönelik kontrollerin konulmas9.

Hata kontrolü problemi tespit ederse problemin kaynak kod içerisinde nerede oldu8unu da
belirtmesi gerekir. Örne8in kursoru konumland9ran pos fonksiyonu binlerce yerde ça89r9lm9/
olabilir, bu fonksiyona yanl9/ parametre geçilmesinden dolay9 tespit edilen hatan9n yeri
belirlenmelidir. Yerle/tirilecek kontrollerin say9s9 istenildi8i kadar çok olabilir, ancak gereksiz
kontrollerin yerle/tirilmesi do8ru de8ildir.

abort ve exit Fonksiyonlar9

exit fonksiyonu bir tak9m i/lemleri geri alarak(program9n yüklenmesi s9ras9nda yap9lm9/
baz9 i/lemler) programdan ç9kmak amac9yla kullan9l9r. Bu fonksiyonla programdan ç9kmak için
program9n bütünlü8ünün bozulmam9/ olmas9 gerekir. Oysa abort fonksiyonu geri alma i/lemlerini
yapmadan ani bir biçimde ç9k9/9 sa8lar. Yani program9n bütünlü8ü bozulduu8unda bir tak9m
i/lemlerin geri al9nmas9na bile olanak kalmam9/sa abort fonksiyonu tercih edilmi/tir. Her iki
fonksiyonun prototipi de stdlib.h 'tad9r. abort fonksiyonu parametresizdir ve program9
sonland9r9rken ekrana "Abnormal program termination" yaz9s9n9 yazar. Program9n deneme
sürümündeki hata yakalama kodlar9ndan ç9k9/ abort fonksiyonuyla yap9lmal9d9r.

assert Makrosu

assert isimli makro ANSI standartlar9nda tan9mlanm9/ olan ve bildirimi assert.h içerisinde
olan program9n deneme sürümünde kontrol yerle/tirmesini sa8layan bir makrodur. Bu makro
yerine programc9n9n iste8i do8rultusunda çe/itli makrolar da yaz9labilir.

57
Standart assert Makrosunun Kullan9lmas9

assert makrosu bir kar/9l/t9rma ifadesiyle ça89r9lmad9r. Örnek:


assert(p != NULL);
Bu makroyla program içerisine ön i/leci taraf9ndan bir kontrol kodu yerle/tirilir. assert ifadesi
olmas9 gereken iddiay9 anlatmal9d9r. E8er bu iddia geçersizse yani assert ifadesinin say9sal de8eri
0'sa kontrol kodu taraf9ndan ekrana "Assertion failed" yaz9s9 bas9larak abort fonksiyonu ile
program sonland9r9l9r. E8er assert.h dosyas9ndan önce NDEBUG ifadesi define edilmi/se assert
makrosu koddan tamamen ç9kart9l9r. Bu durumda deneme sürümünde bolbol assert kullan9l9r
ancak NDEBUG sebmbolik sabiti define edilmez. Program9n bug's9z çal9/t989na emin olduktan
sonra NDEBUG sabiti define edilerek program dahil edilir. Bu i/lemle bütün assert kontrolleri
koddan ç9kar9lm9/ olur.

/*----------assert.c----------*/
#include <stdio.h>
#include <assert.h>

void myputs(const char *str)


{
assert(str != NULL);
while(*str != '\0'){
putchar(*str);
++str;
}
putchar('\n');
}

void main(void)
{
char s[] = "Ankara";
char *p;

p = strchr(s ,'x');
myputs(p);
}
/*----------------------------*/

assert ile yakalanan nokta bug'9n olu/tu8u nokta de8ildir. Bug'9n olumsuzluklara yol açt989
noktalardan biridir. Bu noktadan hareketle bug'9n yeri tespit edilmelidir.

ASSERT MAKROSUNUN YAZILMASI

Assert makrosunun ASSERT biçiminde tekrar yazmay9 deneyelim. yazaca89m9z bu versiyonda


DEGUB isimli sembolik sabit define edilmemi/ ise ASSERT ifadeleri/ koddan ç9kart9l9r.

58
edilmi/se koda eklenir (orjinal assert i/lemlerinde NDEBUG sembolik sabiti define edilmni/ ise
assert ifadeleri koddan ç9kart9lmaktad9r).
1. versiyon:

#ifdef DEBUG
#define ASSERT(f) \
if (f) { } \
else { \
printf("Assert failed\n");\
abort(); \
}
#else
#define ASSERT(f)

#define DEBUG
#include "myassert.h"

void fonk (const char *p)


{
ASSERT (p != NULL); /*kontrol olay9*/
}

if (p != NULL) {}
else {
printf("Assertion failed...\n");
abort();
}

2.versiyon:
hata yakaland989nda verilecek mesaj ve abort fonksiyonunun ça89r9lma kodu ba/ka bir fonksiyon
içerisine yaz9labilir. böylece her ça89rmada mesaj stringi için tekrar tekrar koda eklenmez.

#ifdef DEBUG
void _Assert (void)
{
printf("Assertion failed...\n");
abort();
}
#endif

#ifdef DEBUG
#define ASSERT(f) \
if (f) { } \
else \

59
_Assert();
#else
#define ASSERT(f)
#endif

3. versiyon:
Bu assert i/lemlerini daha etkin hale getirmek için hatan9n yakaland989 dosya isminin ve sat9r
numaras9n9n da rapor edilmesi gerekir.

SOnuç Assert i/lemleri ön i/lemci komutlar9 ile koda eklenip ç9kart9lmaktad9r. Orjinal Assert
makrosu Standart bir biçimde tüm C derleyicilerinde bulunurlar. do8rudan bu makro
kullan9labilir.

PORT KAVRAMI VE LEMC LER


/lemci nedir???

/lemci programlanabilen yani komut çal9/t9rabilen elektronik devrelerdir. i/lemciler bnu günkü
teknoloji ile entegre biçiminde üretilirler. /lemciler Çe/itli uçlara sahiptir. i/lemcilere komut
gönderilmesi elektriksel i/aretlerle yap9l9r. say9sal bilgisayarlarda kullan9lan i/lemciler. ikilik
sistemde çal9/9rlar. /lemcinin bir ucuna iletilen gerilim seviyesi say9sal olarak 0 veya 1 biçiminde
alg9lan9r. ören8in 5 volt civar9nda bir gerilim 1, 0 civar9nda bir gerilim ise 0 biçiminde
yorumlan9r. i/lemciyi programlamak yada komut göndermek demek i/lemcinin n tane ucuna
elektrikdsel i/aretler uygulamak demektir. i/lemci bu n uçtan ald989 de8erleri say9sal olarak
yorumlayarak ne yapmas9 gerektir8ini anlar. i/lemcinin i/lemi yapmas9 için belli bir zamana
ihtayaç9 vard9r. bu zaman sonras9nda elde edilen de8erler i/lemcinin m tane ucundan okunabilir.
tabi m tane uctan okunan de8erler m bit say9 biçiminde yorumlanmal9d9r. bir i/lemciye komutla
rve komutun parametreleri 8-16-32 bit topluluklar halinde gönderilebilir. böyle i/lemcilere 8-16-
32 bit i/lemciler denir. bir bilgisayar sisteminde kendi yerel bölgesinde sorumlu pek çok i/lemci
vard9r. bu i/lemcilere komutlar9 merkezi bir i/lemci gönderir. böyle i/lemcilere de CPU denir.
tabi cpu da programlanabikir bir i/lemcidir. onun hangi i/lemcileri programlamas9 gerekti8ine
sonucta programc9 karar verir. cpu ile ram ve i/lemciler ik grup uç ile ba8lanm9/lard9r. Veri yolu
denilen bir grup uç i/lemcilere ve ram e bilgi göndermek yada onlardan bilgi almak için
kullan9l9r, adres yolu denilen bir grup uç ise istenilen bir i/lemciyi seçmek yada ramden bir
kutucu8u seçmek amac9 ile kullan9l9r. bir i/lemcinin port numaras9 o i/lemcinin seçilmesini
sa8layan bir say9d9r. bire i/lmecinin n tane port numaras9 olabilir. bütün port numaralar9 çe/itli
i/lemciler taraf9ndan payla/t9r9lm9/t9r. örne8in bir port bir bilgi gönderildi8inde o port numaras9
hangi i/lemciye ba8l9 ise bilgi o i/lemciye gönderilmi/ olur. bir i/lemciyi programlayabilmek için
/unlar9 bilme gerekir.

1- i/lemcinin port numaras9n9


2- i/lemcinin hangi komutlara kar/9 ne yapaca89n9
3- bu i/lemlerin programlama içinden nas9l yap9laca89

60
Bir cpu nun en fazla kaç portsa bilgi gönderebilece8i tasar9mda tespit edilir. örne8in intel
i/lemcileri en fazla 65536 porta eri/ebilir. klasik bir at mimarisinde ilk 4096 port
kullan9lmaktad9r. yani i/lemcilerin port numaralar9 000-3FF aras9ndad9r. bir i/lemcinin port
numaralar9 eski sistemde elektriksel ba8lant9larla yani de8i/tirilemez bir biçimde belirleniyordu.
oysa son y9llarda geli/tirilen pnp teknolojisi ile i/lemcilerin port numaras9 da d9/ar9dan yaz9l9m
yolu ile de8i/tirilebilmektedir. bu sistem mimariye yeni bir kart yada i/lemci eklenmesinde
olu/acak çat9/malar9 gidermek amaçl9 dü/ünülmü/tür.

Portlara De8er Gönderilmesi ve Portlardan De8er Al9nmas9

Asl9nda portlara bilgi gönderip portlardan bilgi alma i/lemi OUT ve IN makine
komutlar9yla yap9l9r. Tabii bu komutlar9 kullanabilmek için sembolik makine dilini bilmek
gerekir. Ancak bunun yerine prototipleri dos.h içerisinde bulunan bir grup fonksiyondan da
faydalan9labilir. Bu fonksiyonlar 8 bit ve 16 bit i/lemciler için dü/ünülmü/tür.

1- /lemcilere 1 Byte Bilgi Gönderen Fonksiyonlar

void outportb(int portadr, unsigned char value);


int outp(int portid, int value); (makro)

Bu fonksiyonlar9n i/levleri tamamen ayn9d9r. Birinci parametreleri bilginin gönderilece8i


port numaras9, ikinci parametresi ise gönderilecek de8erdir.

2- /lemcilerden 1 Byte Bilgi Okuyan Fonksiyonlar

unsigned char inportb(int portadr);


int inp(int portid); (makro)

Bu fonksiyonlar parametresiyle belirtilen porttan bilgiyi okuyarak geri dönü/ de8eri olarak
bildirirler.

3-Portlara 2 Byte Bilgi Gönderen ve Okuyan Fonksiyonlar

void outport(int portadr, int value);


unsigned inport(int portadr);

Portlar9n Kullan9lmas9na li/kin Bir Örnek

Bir i/lemcinin port numaralar9 i/lemci üretildi8inde göreli olarak belirtilir. Onlara gerçek
numaralar9 tasar9mc9 vermektedir. Birinci 8259 20H ve 21H portlar9n9 kullanmaktad9r. 8259'un
21H portuna 1 byte bilgi gönderilince bu bilgi 8259'un interrupt mask register denilen bir
register'9na yaz9l9r. 8259 interrupt mask register içerisindeki 1 olan bitlere ili/kin uçlardan gelen
kesmeleri görmezlikten gelir. 21H portu hem okunabilir hem yaz9labilir bir porttur.

Zamanlay9c9 kesmesini devre d9/9 b9rakmak için yap9lacak i/lemler:

61
Bunun için önce interrupt mask register okunur(Yani 21H portu okunacak), sonra 8254 0
numaral9 uca ba8l9 oldu8una göre di8er bitlere dokunulmadan 0 numaral9 bit 1 yap9l9r(1 ile OR
i/lemi) ve elde edilen de8er geri yaz9l9r.

UYARI: Çok i/lemli i/letim sistemlerinde(Win, Unix vesaire) koruma mekanizmas9


uygulanmaktad9r. Koruma mekanizmas9 gere8i normnal programc9lar portlara eri/ip onlar9
programlayamazlar.

------outp.c-------
#include <dos.h>
#include <stdio.h>

void main(void)
{
char x;

x = inp(0x21);
x = x | 1;
outp(0x21, x);
}

PC'LERDE ZAMANLAMA LEMLER

PC mimarisinde zamanlama konusuyla ilgili iki i/lemci bulunmaktad9r.


1-8254 PIT(programmable interval timer)
2-RTC(real time clock)

8254 PIT LEMC S

Bu i/lemci kendi içersinde 3 ayr9 darbe üretebilen sayaca sahiptir. Bu üç ayr9 sayaç
mimaride çe/itli amaçlarla kullan9l9r. Örne8in sayaçlardan birisi 8259 kesme denetleyicisi
i/lemcisine ba8l9d9r ve saniyede 18,2 kere darbe üreterek 8H donan9m kesmesinin ça89r9lmas9na
yol açar. 8254'ün 3 ba89ms9z sayac9n9n da darbe üretme frekans9n9n tespit edilmesinde kullan9lan
bir yazmac9(register) vard9r. Programlama s9ras9nda bu yazmaca 16 bit uzunlu8unda bir say9
yerle/tirilir. /lemcinin herbir saat darbesinde bu yazmaç içerisindeki say9 bir azalt9l9r. Bu say9
s9f9rlan9nca darbe üretilir ve ilk say9 tekrar yazmaç içerisine yerle/tirilir. PC mimarisinde 8254
i/lemcisinin kristal frekans9 ..........(tam de8er gelecek). 8H kesmesi için kullan9lan sayaca ili/kin
yazmaç de8eri en büyük de8er olan 65535'tir. Bu durumda 8H kesmesinin olu/ma frekans9
....../65535 = .......'d9r. Bu durumda 8254 i/lemcisi programlanarak 8H kesmesinin ça89r9lma h9z9
artt9r9labilir ama azalt9lamaz. CPU çal9/ma frekans9ndan ba89ms9z gecikme sa8layacak bir
fonksiyon bu i/lemcinin programlanmas9yla yaz9labilir. Tabii böyle bir fonksiyon windows ve
unix gibi sistemler alt9nda kullan9lamaz(bu i/letim sistemleri bu i/lemciden görevler aras9 geçi/
mekanizmas9 için faydalan9rlar ve koruma mekanizmas9 içinde bu i/lemciye eri/im

62
engellenmektedir). Yani böyle bir fonksiyon sadece DOS alt9nda yaz9labilir. Do8al olarak
istenirse ayr9 bir kart biçiminde ba/ka bir 8254 i/lemcisi sisteme eklenebilir.

RTC LEMC S

Bu i/lemci tamamen bir saatin yapt989 i/lemleri yapmak amac9yla tasarlanm9/t9r. O anda
bulunulan tarih ve zaman bilgisi RTC i/lemcisine sorularak elde edilebilir. RTC i/lemcisi
AT'lerle birlikte mimariye kat9lm9/t9r ve bilgisayar kapat9lsa bile bir pil taraf9ndan beslenerek
çal9/maya devam eder. Bu i/lemcinin ayn9 zamanda küçük bir RAM bölgesi vard9r. Setup bilgileri
bu bölgede tutulur. Bu i/lemci tarih bilgisine ili/kin y9l bilgisini 4 digit halinde tutmaktad9r.

C'de Tarih ve Zaman Bilgisinin Elde Edilmesi

En temel yöntem time ve localtime fonksiyonlar9n9n kullan9mas9d9r. time fonksiyonu 01-


01-1970'den itibaren geçen saniye say9s9n9 verir. localtime fonksiyonu bu de8eri alarak bunu tarih
ve zaman bilgisine dönü/türür. Ancak bu fonksiyonlar tarihe ili/kin y9l bilgisini 2 digit olarak
verirler. Sonuç olarak tarihe ili/kin y9l bilgisinin 4 digit olarak elde edilmesi için C'de RTC
i/lemcisinin okunmas9 gerekir(di8er programlama dillerinde kimi fonksiyonlar yada komutlar
RTC i/lemcisni okuyarak y9l bilgisini 4 digit olarak zaten verirler). RTC i/lemcisi ile
ili/ki kurmak için 2 yöntem kullan9labilir:
1-Do8rudan i/lemcinin port numaralar9 kullan9larak eri/ilebilir.Ancak bunun için RTC'nin
programlanmas9n9 bilmek gerekir.
2-1A BIOS kesmesinin çe/itli kesmeleri RTC i/lemcisini programlayarak zaten temel i/lemleri
yapmaktad9r. Yani bu kesme ça89r9larak i/lemler yürütülebilir.

1AH Kesmesinin Fonksiyonlar9

Bu kesmenin 4 önemli fonksiyonu vard9r.


F:2 Get time
F:3 Set time
F:4 Get date
F:5 Set date
Bu fonsiyonlar BCD(binary coded decimal) say9 sistemini kullanmakatd9r.

BCD Say9 Sistemi

Onluk sistemde yaz9lm9/ olan her bir digit'e 4 bit kar/9l9k dü/ürülürse o onluk say9 BCD
sisteminde ifade edilmi/ olur.
1913 == 0001 1001 0001 0011
1001 001 == 91

1AH F:2
Parametreler AH=>2

63
Geri dönü/ de8eri CH=>saat, CL=>dakika, DH=>saniye(BCD yorumu)
1AH F:3
Parametreler AH=>3, CH=>saat, CL=dakika, DH=>saniye(BCD)
1AH F:4
Parametreleri AH=>4
Geri dönü/ de8eri CH=>yüzy9l - 1, CL=>y9l, DH=>ay, DL=>gün(BCD)
1AH F:5
Parametreler AH=>5, CH=>yüzy9l - 1, CL=>y9l, DH=>ay, DL=>gün(BCD)

Bu fonksiyonlar e8er RTC bulunmad989ndan dolay9 ba/ar9s9zl98a u8rarsa cflag elaman9 1


olmaktad9r.

PC'LERDE HABERLE ME

SAYISAL HABERLE MEN N TEMELLER

Haberle/me temel olarak gönderici taraf9n hatta bir gerilim uygulamas9 al9c9 taraf9n da bu
gerilime bakarak hangi bitin gönderildi8ini tespit etmesi esas9na dayan9r. Yani haberle/mede
bilgiler bitlerine ayr9/t9r9l9r, bit bit iletilir. Haberle/mede bir gönderici bir de al9c9 taraf söz
konusudur. E8er tek yönlü bir haberle/me sistemi kullan9lacaksa iki hat yeterlidir. (Hatlarsan biri
toprak gerilim iki uca uygulanacakt9r) E8er çift yönlü bir haberle/me isteniyorsa yani iki taraf9n
da hem göndermesi hem almas9 söz konusuysa hat say9s9 üçe ç9kart9lmal9d9r. Gönderme ve alma
durumlar9na göre haberle/me sistemleri bir kaç gruba ayr9l9r.

Simplex: Tek tarafl9 haberle/me


Half Dublex: ki tarafl9 ama gönderme ve alma i/lemi ayn9 anda yap9lamaz.
Full Dublex: Her iki taraf da gönderip alma i/lemini e/ zamanl9 yapabilir.

t an9nda 1 bit ya da n bitlik bir bilginin hatta b9rak9lmas9 durumuna göre haberle/me seri
haberle/me ve paralel haberle/me olarak iki bölüme ayr9labilir. Paralel haberle/me için daha fazla
hat gerekir ve uygulamada tercih edilmemektedir. Seri ya da paralel haberle/menin prensipleri
aras9nda bir farkl9l9k yoktur. (Paralel haberle/meye byte seviyesinde seri haberle/me de denir)

Haberle/menin Problemleri

1-)E/ zamanl9l9k problemi(senkronizasyon)

64
Gönderici ve al9c9 taraf9n e/it h9zlarda i/lemlerini yapmas9 gerekir. En önemli problem
gönderici beklemeye ba/lad989nda al9c9n9n bu beklemeyi tespit etmesidir. Gönderen taraf9n
byte'lar aras9nda hiçbir bekleme olmadan bütün bitleri e/ zamanl9 göndermesi durumuna senkron
seri haberle/me sistemi denir. Byte'lar aras9nda rast gele bekleme zamanlar9 olabilir ancak byte'lar
e/it zaman aral9klar9yla gönderilebiliyorsa bu haberle/me sistemine asenkron seri haberle/me
sistemi denir. Uygulamada hemen her zaman asenkron seri haberle/me sistemi kullan9l9r.
2-)Al9c9 taraf9n do8ru bilgiyi al9p almad989 bir biçimde test edilmelidir.
E8er al9c9 taraf bilgiyi ald9ysa hiç olmazsa bilginin yanl9/ al9nd989n9n bilinmesi gerekir.
3-)Mesafe sorunu
Gönderici ve al9c9 taraf birbirinden çok uzaksa bilgi telefon haberle/me sistemiyle (telefon
tellerinden modem arac9l989yla) gönderilip al9nabilir.

Bilgisayardaki Haberle/me Portlar9

PC'lerde ismine seri ve paralel port denilen iki grup haberle/me portu bulunur. Paralel
portlar 25 pinli bilgisayar taraf9 di/i olan konnektörlerden olu/ur. Seri portlar 9 ya da 25 pinli
olabilirler. Bilgisayar taraf9 erkek biçimindeki konnektörlerden olu/ur. Normal olarak PC'ler en
fazla 4 seri 4 paralel portu desteklemektedirler. Sat9n al9nd989nda genelde iki seri bir paralel portu
bulunur. Fakat özel kartlarla bu say9 fazlala/t9r9labilir.

Paralel Portlar

Pinlerin simleri ve Anlamlar9

Pin isimleri bilgisayar printer haberle/mesi dü/ünülerek konulmu/tur. Tabii paralel port
yaln9zca printer haberle/mesinde de8il daha pek çok konuda kullan9labilir. Bu durumda isimlerin
bizim için ciddi bir anlam9 yoktur.

1: STROPE
2: D0
3: D1
4: D2
5: D3
6: D4

65
7: D5
8: D6
9: D7
10: ACK
11: BUSY
12: PE
13: SLCT
14: AUTOFEED
15: ERROR
16: INIT
17: SLCT IN
18-25: GND(Toprak)

Bizim için paralel port 25 pinden olu/mu/ bir devre olarak de8erlendirilebilir. Paralel
portun baz9 pinlerine programlama yoluyla 5 Volt ya da 0 Volt gerilim uygulanabilir. Yine paralel
portun baz9 pinlerindeki olu/turulmu/ olan gerilimler okunabilir. Paralel portun uçlar9na bilgi
göndererek bu porta tak9lan çe/itli cihazlar tak9labilir. Paralel portun ç9k9/lar9 TTL seviyesindedir.
Yani do8rudan logic devreler sürülebilir. Paralel portun 2-9 nolu uçlar9na yaln9zca i/aret
gönderilebilir. Yani bu uçlardan okuma yap9lamaz. (Baz9 eski paralel portlarda bu uçlar çift yönlü
çal9/abilmektedir) Paralel portun yaln9zca 5 ucundan okuma yap9labilir. Bu pinler 10,11,12,13,15
nolu pinlerdir. Di8er pinler okuma ya da yazma amaçl9 kullan9lamazlar. Sonuç olarak 8 bit
gönderme 5 bit okuma yap9labilir. Paralel portun uçlar9 paralel port i/lemcisi denilen özel bir
i/lemciye ba8l9d9r.

Paralel Port /lemcisinin Kullan9m9

Bu .i/lemcinin 3 tane 8 bitlik register'9 vard9r. Bu register'lara DATA, STATUS,


COMMAND register'lar9 denir. Bu 3 register'9n da birer port adresi vard9r. Bu portlar9n adresleri
normal olarak BIOS haberle/me alan9nda yazmaktad9r. Bunlar9n adresleri

0040:0008 => LPT1


0040:000A => LPT2
0040:000C => LPT3
0040:000E => LPT4

Ancak sistemlerin çok büyük ço8unlu8unda taban adresler /u biçimdedir.

LPT1 => 378H


LPT2 => 278H
LPT3 => 3BCH

Bu durumda paralel port i/lemcisinin register’lar9 taban port adresine göre /u biçimdedir.

Taban + 0 = Data register


Taban + 1 = Status register

66
Taban + 2 = Command register

Örne8in LPT1 için:

Data register için 378H,


Status register için 379H,
Command register için ise 37AH'ta bulunur.

Data Register

Bu register'9n LPT1 için port numaras9 378H, LPT2 için port numaras9 278H't9r.Bu
register yaln9zca yazma amaçl9 kullan9labilir. Okuma amaçl9 kullan9lamaz.

outp(0x378, 0xFC); /*LPT1'in data register'9na 0xFC bilgisi gönderilmesi*/

Data register'a bir bilgi yaz9ld989nda yaz9lan bilginin bitleri paralel portun D0 ve D7 uçlar9
aras9nda gerilim seviyesi olarak görünür. Bu uçlar 2-9 numaral9 uçlard9r. Örne8in paralel portun 2
ve 3 numaral9 pinlerinde 5 Volt olu/turabilmek için data register'a 3 de8erinin yaz9lmas9 laz9md9r.
(3 = 0011)

Led yak9p söndürme:(led.c)

Status Register

Bu register LPT1 için 379H, LPT2 için 279H port adreslerindedir. Yaln9zca okunabilen
bir register'd9r. Bu register'dan okunan bilgiler 10, 11, 12, 13, 15 nolu uçlar9n gerilim seviyelerini

67
göstermektedir. 7 numaral9 bitten elde edilen de8er 11 numaral9 pinin tersidir. Yani bu bit 1
olarak okunmu/sa 11 numaral9 pin 0 Volta çekilmi/tir.

Örnek:13 nolu pin ile 25 nolu pin k9sa devresinde okuma.....(read.c)

Command Register

LPT1 için 37A LPT2 için port adresleri 27A'd9r. Bu register belli bir olay meydana
geldi8inde ya da belli durumlarda kullan9l9r. Yani okuma ya da yazma amaçl9 kullan9lamaz.
Normal olarak write-only bir register'd9r. Ancak bu register'a bilgi yaz9ld989nda paralel port
i/lemcisi çe/itli amaçlarla programlan9r. Yani burada yaz9lan de8erler i/lemciyi programlamak
amac9yla kullan9lmaktad9r.

Bilgisayarlar Aras9 Bilgi Aktar9m9

ki bilgisayar aras9 paralel portlar kullan9larak bir bilgi aktar9m9 yap9lacaksa ismine laplink
denilen bir kablo haz9rlanmas9 gerekir. Laplink kablosu ba8lant9 /emas9:

2:D0
3:D1
4:D2
5:D3
6:D4
15:error
13:SLCT
12:PE
10:ACK
11:BUSY
25:GND

Mademki paralel portun 5 ucu alma 8 ucu gönderme için kullan9l9yor, o halde bilgi
transferi de olsa olsa bit-bit yap9labilir. Yani bir byte kar/9 tarafa iki hamlede gönderilebilir.
Laplink kablosunda gönderen taraf9n 4 data ucu alan taraf9n 4 al9c9 ucuna kar/9l9kl9 ba8lan9r.
Gönderen taraf bir byte’l9k bilgiyi 4 bit 4 bit ay9rarak gönderir. 4 bit bilgi göndermek için
gönderici taraf 4 biti data register'a yazar, al9c9 taraf status register'9 okuyarak bu 4 biti elde eder.
Tabi bu i/lemin bir biçimde e/ zamanl9 olarak yap9lmas9 gerekir. Bu e/ zamanl9l989 sa8lamak için
be/inci uç kullan9lmaktad9r.

68
Ba/lang9ç durumu: Al9c9 taraf 1’de bekliyor.
1.ad9m: Gönderen 4 biti hatta b9rak9yor; hatt9 s9f9ra çekiyor. Bu s9rada al9c9 taraf döngüde 1
oldu8u müddetçe bekliyor.
2.ad9m: Gönderen hat 0’da oldu8u sürece bekliyor. Al9c9 gönder demek için hatt9 1’e çekiyor ve
al9c9 1 oldu8u müddetçe bekliyor.

E/ zamanl9l9k için kullan9lan 6-11 ba8lant9s9 ters i/aretlidir. Tabii bu ba8lant9da 6-11 ve
11-6 olmak üzere çift tarafl9d9r.

Transfer Program9 Hakk9nda Aç9klama

Programda sendchr ve receive_chr olmak üzere iki fonksiyon yaz9lm9/t9r. Sendchr 1 byte
uzunlu8unda bilgiyi 4 bitlik iki parçaya ay9rarak kar/9 tarafa gönderir. Receive_chr e/ zamanl9l9k
belirlemelerine göre bunu al9r. Tabii bu fonksiyonlar9n tek ba/lar9na kullan9lmas9 sonsuz
beklemeye yol açar. Yani bir bilgisayar sendchr ile bir byte bilgi göndermi/se i/lemin devam
etmesi için kar/9
taraf9n receive_chr ise bunu almas9 gerekir. Örne8imizdeki sendchr ve receive_chr fonksiyonlar9
ayr9 birer fonksiyon olarak tasarlanm9/t9r. Bu fonksiyonlar dosya transferinin ötesinde endüstriyel
uygulamalarda PC’lerin ucuz haberle/mesini sa8lamak amac9yla kullan9labilir. Paralel laplink
kablosu en fazla 3-4 metre uzunlu8unda olmal9d9r. Örnek programda gönderen ve alan iki ayr9
program vard9r. Gönderen taraf önce dosya ismi ve uzunlu8unu gönderir. Alan taraf dosya ismini
ald9ktan sonra yazma modunda dosyay9 açar. Dosya uzunlu8u alan taraf9n i/lemini bitirmesi için
gereklidir.

Paralel portlar hakk9nda adresler


http://dragon.hearts.ac.uk/data/datasheets/parallel.html
http://www.geocities.com/SiliconValley/Bay/8302/parallel.htm

/*-----------sendrece.c------------*/
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include <stdlib.h>

#define LPT1DATA 0x378


#define LPT1STAT 0x379

typedef unsigned char BYTE;

int receive_char(void)
{
BYTE dpos;
BYTE rchar;

do {

69
dpos = inp(LPT1STAT);
} while((dpos >> 7) == 1);
dpos = inp(LPT1STAT);
dpos = (dpos << 1) >> 4;
rchar = dpos;
outp(LPT1DATA, 0x0);
do {
dpos = inp(LPT1STAT);
} while((dpos >> 7) == 0);
dpos = inp(LPT1STAT);
dpos = (dpos << 1) >> 4;
rchar |= dpos << 4;
outp(LPT1DATA, 0xFF);
return rchar;
}

void sendchar(char ch)


{
BYTE dpos;

do {
dpos = inp(LPT1STAT);
} while((dpos >> 7) == 1);/*wait until the receiver is ready*/
dpos = ch & 0x0F;
dpos |= 0x10;
outp(LPT1DATA, dpos);/*send lower 4 bit to receiver*/
do {
dpos = inp(LPT1STAT);
} while((dpos >> 7) == 0);/*wait until the receiver is ready*/
dpos = ch >> 4;
dpos &= 0x0F;
outp(LPT1DATA, dpos);/*send upper 4 bit to receiver*/
}

#ifdef RECEIVE

void main(void)
{
FILE *fp;
char fname[20];
char flen[20];
BYTE ch;
long len;
long n;
int i;

70
outp(LPT1DATA, 0xFF);
i = 0; /*Get file name*/
do {
ch = receive_char();
fname[i++] = ch;
} while(ch != '\0');
i = 0; /*get file length*/
do {
ch = receive_char();
flen[i++] = ch;
} while(ch != '\0');
len = atol(flen);
printf("Dosya: %s Uzunluk: %ld\n", fname, len);
if ((fp = fopen(fname, "w+b")) == NULL) {
printf("Cannot open file..!");
exit(1);
}
for (n = 0; n < len; ++n) { /*get file info*/
ch = receive_char();
fputc(ch, fp);
}
printf("Dosya aktar9ld9..\n");
fclose(fp);
}

#endif

#ifdef SEND

void main(int argc, char *argv[])


{
FILE *fp;
char flen[30];
BYTE ch;
long n;
long len;
int i;

if (argc != 2){
printf("wrong number of arguments..\n");
exit(1);
}
if ((fp = fopen(argv[1], "r+b")) == NULL) {
printf("Cannot open file..\n");

71
exit(1);
}
fseek(fp, 0, 2);/*get file size*/
len = ftell(fp);
ltoa(len, flen, 10);
rewind(fp);
outp(LPT1DATA, 0);
i = 0;
do { /*send file name*/
sendchar(argv[1][i++]);
} while(argv[1][l++] != '\0');
for (n = 0; n < len; ++n) { /*send file info*/
ch = fgetc(fp);
sendchar(ch);
}
fclose(fp);
}

#endif

Küçük Chat Program9n9n Aç9klamas9


Bu programda da sendchar ve receive_char fonksiyonlar9 kullan9lm9/t9r. Gönderen taraf
klavyede bir tu/a basar. Bas9lan tu/ sendchar fonk ile yollan9r, kar/9 taraf bunu receive_char
fonksiyonu ile al9r ve ekranda görüntüler. Örnek program tek dosya halinde verilmi/tir. ki tane
main #ifdef SEND ve #ifdef RECEIVE ön i/lemci bloklar9na al9nm9/t9r.

/*----------chat.c------------*/
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include <stdlib.h>

#define LPT1DATA 0x378


#define LPT1STAT 0x379

typedef unsigned char BYTE;

int receive_char(void)
{
BYTE dpos;
BYTE rchar;

do {
dpos = inp(LPT1STAT);

72
} while((dpos >> 7) == 1);
dpos = inp(LPT1STAT);
dpos = (dpos << 1) >> 4;
rchar = dpos;
outp(LPT1DATA, 0x0);
do {
dpos = inp(LPT1STAT);
} while((dpos >> 7) == 0);
dpos = inp(LPT1STAT);
dpos = (dpos << 1) >> 4;
rchar |= dpos << 4;
outp(LPT1DATA, 0xFF);
return rchar;
}

void sendchar(char ch)


{
BYTE dpos;

do {
dpos = inp(LPT1STAT);
} while((dpos >> 7) == 1);/*wait until the receiver is ready*/
dpos = ch & 0x0F;
dpos |= 0x10;
outp(LPT1DATA, dpos);/*send lower 4 bit to receiver*/
do {
dpos = inp(LPT1STAT);
} while((dpos >> 7) == 0);/*wait until the receiver is ready*/
dpos = ch >> 4;
dpos &= 0x0F;
outp(LPT1DATA, dpos);/*send upper 4 bit to receiver*/
}

#ifdef RECEIVE

void main(void)
{
BYTE n;

outp(LPT1DATA, 0xFF);
do {
n = receive_char();
if (n == '\r')
putchar('\n');
else

73
putchar(n);
} while(n != 'q');
}
#endif

#ifdef SEND

void main(void)
{
BYTE ch;

outp(LPT1DATA, 0);
for(;;){
ch = getch();
if (ch == '\r');
putchar('\n');
else
putchar(ch);
sendchar(ch);
if (ch == 'q')
break;
}
}

#endif

Paralel Port ve IRQ

Paralel portun 10 nolu ACK ucu IRQ olu/turmak için kullan9labilmektedir. E8er 10
numaral9 uç 0 Volta çekilirse (bu uç yaln9zca okunabilir ve default olarak 1’dir.) 8259 yoluyla 7
numaral9 IRQ ça89r9l9r. Bu IRQ 0F numaral9 kesme kodunun ça89r9lmas9na yol açar. Bu durumda
transfer i/lemi /öyle de yap9labilir. Paralel porta bilgi geldi8inde al9c9 taraf için kesme ça89r9l9r,
kesme kodu da alma uçlar9n9 okuyarak bilgiyi al9r. Bu i/lemde dikkat edilecek iki durum vard9r:
1-)Normal olarak paralel port i/lemcisi 8259’u uyararak kesme olu/mas9na yol açmaz. Bunu
mümkün hale getirmek için paralel port i/lemcisinin command register'9n9n 4 numaral9 biti1
yap9lmal9d9r.
2-)IRQ olu/tuktan sonra bir daha kesmenin gelebilmesi için kesme kodunun kesme
denetleyicisine 20H de8erini göndermesi gerekir. (Yani 20H portuna 20H de8erinin gönderilmesi
gerekir.)
3-)Ba/lang9ç konumunda 0F numaral9 kesme 8259 taraf9ndan pasif hale sokulmu/ olabilir. Bunu
aktif hale getirebilmek için 21H portuna 7 numaral9 bitin 1 yap9lmas9n9 sa8layacak bir de8er
gönderilmelidir.

Paralel Portun Yetmedi8i Durumlarda Ç9k9/ Elde Etmenin Yöntemleri

74
Bu tür durumlarda özel kartlar kullan9labilir. çinde 8255 i/lemcinin bulundu8u pek çok
basit kart piyasada bulunmaktad9r. Bir 8255 i/lemcisi ile 3*8 giri/ ya da ç9k9/ ucu elde edilebilir.
Piyasada sat9lan 3, 4, 5... kadar 8255 i/lemcisi bulunmaktad9r.

Asenkron Seri Haberle/menin Özellikleri

Asenkron seri haberle/me uygulamada en fazla kullan9lan haberle/me yöntemidir. Bu


haberle/mede bytelar aras9 bekleme zaman9 rastgele olabilir. Ancak bytelar9n bitlewri e/it h9zda
gönderilip al9n9r. H9z saniyede gönderilen bit say9s9 ile ölçülür.(bps, baud). En çok kullan9lan
haberle/me h9zlar9: 1200, 2400, 4800, 9600, 19200, 38400... En önemli iki sorun e/ zamanl9l989n
sa8lanmas9 ve bilgi gönderilmeyen zaman aral989n9n saptanmas9d9r. E/ zamanl9l9k kararl9 çal9/an
i/lemcilerle kolayl9kla sa8lanabilir. Bilginin gönderilmedi8i durumda hat 1’de beklemektedir.
Al9c9 taraf bilginin kodlanmaya ba/lad989n9 hatt9n 0’a çekilmesinden anlar. Bundan sonra al9c9
taraf belirlenen h9zda hatt9 örneklemeye ba/lar(hatta bakar) ve data bitlerini elde eder. Bilginin
gönderilmeye ba/lad989n9 anlatan, hatt9n 0’a çekilmesiyle olu/an ilk 0 biti data bitlerine dahil
de8ildir. Buna start bit denir. Start bit her zaman logic 0 olmak zorundad9r. Data bitleri
gönderildikten sonra ileti/imin döngüsel olarak devam edebilmesi için hatt9n tekrar 1 durumuna
çekilmesi gerekir. Data bitlerinden sonra hatt9n 1’e çekilmesine yarayan logic 1 seviyeli bit’e stop
bit denir. Stop bit start bit gibi mutlaka bulunmak zorundad9r. Bu durumda 8 bitlik bir transfer
için asl9nda en az 10 bit gönderilmektedir. Bps cinsinden verilen h9z de8eri içerisine bu bitler de
dahildir. Stop bit say9s9 1 yada 2 olarak belirlene blinir. 2. Stop bit asl9nda gerekli de8ildir ancak
bytlar9n beklemesiz pe/i s9ra gönerildi8i durumlarda 2 stop bit sistemi kullan9l9rsa al9c9 tarafa
daha fazla zaman verilmi/ olur böylece ileti/im butür durumlarda dahada sa8lamla/t9r9l9rç.
Uygulamada 2 stop bit fazla kullan9lmaz. Bir byte l9k bilginin gönderilmesi sonucunda alan
taraf9n bu bilgiyi do8ru al9p almad989 tespit edile bilinir. Seri haberle/mede bunun için parit
yöntemi denilen bir yöntem kullan9la bilinir. Tabi ilti/imde böyle bir hata yakalama yönteminin
kullan9l9p kullan9lmayaca89 isteye ba8l9d9r. Parity yöntemi kullan9lacaksa data bitlerinden sonra
ismine parity biti denilen bir bit daha gönderilir. Parity yöntemi tek ve çift olmak üzere ikiye
ayr9l9r. Çift parity yöntemi gönderilen data bitleri içerisindeki 1 olan bitlerin say9s9n9 çift yapacak
biçimde bit parity biti gönderme durumudur. Örne8in data bitleri içerisinde 3 tane 1 varsa ve çift
parity yöntemi kullan9l9yorsa parity biti olarak 1 gönderilir. Tek parity yöntemi bunun tam
tersidir. Data bitlerindeki 1’lerin say9s9n9 tek yapacak biçimde parity biti gönderilmesi
durumudur. Bu yönteme göre al9c9 taraf önce data bitlerini al9r, hangi parity bitinin gelmesi
gerekti8ini hesaplar. E8er bir uyu/mazl9k varsa al9nan byte de8erinin yanl9/ oldu8unu anlar. Tabii
parity yöntemi hatalar9 kesinlikle bulabilecek bir yöntem de8ildir. Örne8in iki bit bozulmu/sa
böyle bir hatay9 bulamaz. leti/imde parity kontrolünün yap9l9p yap9lmayaca89n9n yap9lacaksa tek
ya da çift mi yap9laca89 ortakla/a tespit edilmelidir. Bu durumda 1 byte’l9k bilginin gönderilmesi
s9ras9nda s9ras9yla /u bitler gönderilmektedir: Start bit, data bitleri, parity biti, stop bitleri. Asl9nda
data bitleri 8 bit olmak zorunda de8ildir. Gönderilecek bilginin türüne göre 5, 6, 7 bit de olabilir.
Sonuç olarak bir ileti/imde iki taraf9nda /unlar9 kesin olarak bilmesi gerekir:
1. Kaç data biti kullan9lacak
2. Stop bitlerinin say9s9
3. Parity yönteminin kullan9l9p kullan9lmayaca89

75
UART /lemcileri

Bir bytel9k bilginin bitlerine ayr9larak tespit edilen parametreler do8ultusunda


gönderilmesi ismine UART(universal asynchronous receiver and transmitter) denilen bir i/lemci
sayesinde yap9lmaktad9r. UART i/lemcisi pek çok firma taraf9ndan ayn9 özelliklere sahip olacak
biçimde üretilmi/tir(National 15560, Intel 8250). UART i/lemcisi kabaca /öyle kullan9l9r:
1. Önce data bitlerinin say9s9, stop bitlerinin say9s9, parity kullan9lma durumu, örnekleme h9z9
tespit edilerek i/lemci bu parametreler do8rultusunda programlan9r.
2. Bilgi UART i/lemcisine 1 byte /eklinde gönderilir. /lemci bunu bitlerine ay9r9p kar/9 tarafa
belirlenen parametreler do8rultusunda kodlar.
3. UART i/lemcisi kar/9 taraftan bit bit gelen bilgiyi alarak bunu byte bilgisine dönü/türür ve
saklar.

/lemci 28 pin’e sahiptir. Bu uçlardan 3’ü ileti/imde as9l önemli görevi üstlenir. Bu uçlar99 RXD,
TXD, GND uçlar9d9r. ki UART i/lemecisi kar/9l9kl9 olarak /öyle ba8lanabilir.
RXD

TXD

GND

UART i/lemcileri full dublex çal9/acak /ekilde tasarlanm9/t9r.

Seri Port Kullan9m9

Seri port 9 ya da 25 pinli olarak bilgisayarlarda bulunmaktad9r. Bilgisayar taraf9 erkek


konnektör biçimindedir. Zaten 25 pinli konnnektörlerin de yaln9zca 9 ucu ba8l9d9r. Seri portlara
UART i/lemcisi ba8l9d9r. Yani seri portlar9n uçlar9 UART i/lemcisiyle aymn9d9r. UART’9n
ç9k9/lar9 TTL seviyesindedir. Ancak seri porta verilmeden önce bir RS232 dönü/türücü
devresinden geçirilir. RS232 gerilim seviyeleri TTL gibi de8ildir. +- 15 V civar9ndad9r. RS232
dönü/türücüsü çift yönlüdür.

Seri Port Pinlerinin simlendirilmesi ve Anlamland9r9lmas9

9 pin:

o5 o4 o3 o2 o1

76
o9 o8 o7 o6

Seri port ve UART pinlerinin isimleri temel olarak modem haberle/mesi temel al9narak
verilmi/tir.
1=>CD(Carrier detect)
2=>RXD(Receive data)
3=>TXD(Transmit data)
4=>DTR(Data terminalk ready)
5=>GND(Ground)
6=>DSR(Data set ready)
7=>RTS(Request to send)
8=>CTS(Clear to send)
9=> RI(Ring indicator)

Seri porttan bilgi aktaran bir lap link kablosu en ekonomik olarak 3 uçlu olabilir.
RXD TXD
TXD RXD
GND GND

UART /lemcisinin Programlanmas9

UART i/lemcisinin programlanmas9n9n 3 yolu vard9r:


1. C derleyicilerinin kütüphanelerinde programlayan, bilgi gönderen ve alan çe/itli fonksiyonlar
vard9r. O fonksiyonlar9n kullan9lmas9 ö8renilir ve ça89r9l9r.
2. BIOS içerisinde(EPROM’da) UART i/lemcisini programlayan çe/itli kesme kodlar9 vard9r.
Bu kesmeler ça89r9larak i/lemler yürütülebilir. Bu i/lem için 14H BIOS kesmesinin
fonksiyonlar9 kullan9lmaktad9r.
3. Do8rudan UART i/lmecisinin portlar9na bilgi göndererek en a/a89 seviyeden programlama
i/lemini gerçekle/tirmek. (Zaten 14H kesmesi de bu biçimde i/lemleri yürütmektedir.)

UART /lemcisinin A/a89 Seviyeli Programlanmas9

UART i/lemcisinin içerisinde haberle/me portlar9na ba8l9 çe/itli register’lar vard9r. Bu


portlara bilgi gönderildi8inde bilgi register’lara yaz9l9r. Benzer biçimde portlar okundu8unda
asl9nda o register’lar9n içerisindeki bilgi okunmaktad9r. UART i/lemcisinin programlama yaz9l9m
yoluyla eri/ilebilen 10 tane register’9 vard9r. Register’lar9n birer port numaras9 bulunur. Seri
portlara ba8l9 UART i/lemcilerinin taban port adresleri BIOS haberle/me alan9 içerisinde
yazmaktad9r. Ancak çok büyük olas9l9kla taban port adresleri /öyledir:
COM1=>3F8
COM2=>2F8
COM3=>3E8
COM4=>2E8

Bir Byte Bilginin Gönderilmesi /lemi

77
Bir byte’l9k bilgi UART i/lemcisinin THR register’9na gönderilir. /lemci bu gönderilme
i/leminden sonra otomatik olarak bu bilgiyi bitlerine ay9rarak TXD ucundan kodlayacakt9r. Ancak
gönderici taraf çok h9zl9 bir biçimde bilgileri THR içerisine yazarsa problemli bir durum ortaya
ç9kar. Yani THR register’9 UART taraf9ndan bo/alt9ld9ktan sonra tekrar bilgi gönderilmektedir.

Bir Byte Bilginin Al9nmas9 /lemi

UART bit bit elde etti8i bilgiyi byte’a dönü/türerek RBR register’9n9n içerisne yazar. Yani
bilginin al9nabilmesi için RBR register’9n9n okunmas9 gerekir. Tabii programc9 RBR register’9n9
yaln9zca yeni bir bilgi geldi8inde okumal9d9r. O halde UART yeni bir bilgi geldi8ini bir biçimde
haberdar eder.

LSR REGISTERI (line status register)

Bu register genel olarak 8250’nin içinde bulundu8u durum hakk9nda bilgi


vermektedir. Bu register’9n her bir biti bir durum hakk9nda bilgi verir. Bitlerin anlamlar9:

7 6 5 4 3 2 1 0
Xxxxxx TEMT THRE BI FE PE OE DR

DR biti: Bu bit bir ise RBR register9na gelen bilgi yerle/tirilmi/tir dolay9s9 ile bu register9n
okunup bilginin al9nmas9 gerekllidir. Bu durumda bilgi alma i/i için sürekli LSR portu okunur
e8er DR biti 1 ise RBR register’9 okunarak bilgi elde edilir.

----------------------lsr-dr.c------------------------
#define BASE 0x3F8 /* Com1 */
#define LSR (BASE + 5) /* LSR port numaras9 */

void fonk(void)
{
int x;
char ch;

do {
x = inp(LSR);
} while (!(x & 1));
ch = inp(RBR);
}
--------------------------------------------------------

78
LSR register’9 her okundu8unda içerisindeki bitler otomatik olarak s9f9rlan9r. Yani programc9n9n
s9f9r9lamas9na gerek kalmaz.

OE biti (overrun error): Bu bit 1 ise /öyle bir olay gerçekler/mi/tir. 8250’ye bir bilgi gelmi/ ve
RBR de tutulmu/tur ancak okunamadan yeni gelen bir bilgi eskisini bozmu/tur. Bu overrun error
olarak adlan9r.

PE biti (parity error): Bu bit 1 ise bilgi parity hatas9ndan dolay9 yanl9/ al9nm9/t9r.

FE biti (framing error): Start bit data bitleri ve parity ve stop bitlerinin hepsine birlikte “frame”
denmektedir. Start bitten sonra data ve parity bitleri al9n9r ve bundan sonra stop bit için hat 1’e
çekilmelidir. Hat 1’e çekilmemi/se stop bit al9namam9/t9r. Dolay9s9 ile frame bozuktur o zaman
bu bit 1 olur.

BI biti (brake 9ntterupt): Haberle/mede hat koparsa UART sürekli s9f9r de8erini okur i/te start bit
data bitleri parity ve stop bitl/eri uzunlu8u kadar süre s9f9r okunmu/ ise UART durumdan
/üphelenerek bu biti bir yapar. Yani bu bit özellikle hat kopmas9 gibi durumlar9 tespit etmek
amac9yla kullan9l9r.

THRE biti (transmitter holding register empty): Bilgi gönderirken önceki bilginin THR
register9ndan al9nm9/ oldu8unu garantilemek gerekir. E8er UART THR register’9ndaki bilgiyi
alm9/sa bu bit 1’ler. Yani yeni bir bilgi THR register’9na yazabiliriz.

----------------------lsr-thre.c--------------------------
#define BASE 0x3F8 /* Com1 */
#define LSR (BASE + 5) /* LSR port numaras9 */

void fonk(void)
{
int x;
char ch;

do {
x = inp(LSR);
} while (!(x >> 5) & 1));
outp(THR, ch);
}
-----------------------------------------------------------

TEMT biti (transmitter empty): THRE biti bilginin yanl9zca THR register’9ndan al9nd989n9 anlat9r.
Bu bilgi al9nd9ktan sonra bitlere ayr9/t9t9l9p gönderilecektir. Oysa bu bitin bir olmas9 ayn9
zamanda thr register’9 içindeki bilginin al9narak gönderilmi/ oldu8unu anlat9r. Yani bu bit bir ise
THR ve TSR register’lar9n9n her ikisi birden bo/tur.

79
UART‘IN HIZININ AYARLANMASI

UART’9n h9z9n9n ayarlanmas9 için iki registere’a bilgi gönderilmesi gerekir. Bunlar DLL ( divisor
Latch Least) ve DLM (divisor latch most) . UART i/lemcisinin uçlar9na ba8ülanan kristal
frekenas9 PC sistemlerinde 1843200 hertz dir.
A/a89daki denklemden elde edilen 16 bitlik de8erin yüksek anlaml9 byte’9 DLM dü/ük olan9 DLL
içine yerle/tirilir.
16 bit register de8eri = 1843200 / (16 * baud rate)
bu denklemden Pc sistemleri için UART 9n en yüksek ve en dü/ük çal9/ma h9zlar9 tespit edilebilir.
En yüksek h9z DLM=00 DLL=01 ile 115200 dür. En dü/ük h9z ise DLM=FF DLL=FF iken
yakl/9k 1 dir

En çok kullan9lan h9zlar9 DLL ve DLM de8erleri:

HIZ DLM DLL


2400 00 30
4800 00 18
9600 00 0C
19200 00 06
38400 00 03
57600 00 02
115200 00 01

DATA STOP VE PARITY LEMLER N N AYARLANMASI


Bu i/lemler için LCR register9 kullan9ll9r. Bu registerda 8 bittir. Ve belirlemeler bu bitleri set
ederek yap9l9r.

Dü/ük anlaml9 iki bit data bitlerinin say9s9n9 olu/turmak için kullan9l9r.
00 5 bit
01 6 bit
10 7 bit
11 8 bit

7 6 5 (sabit parity) 4 3 (Parity kontrol) 2 (Stop bit) 1 0


Sürekli 0 s.parity yok 0 tek 1 yap9lacak 0 1stopbit \\\\\\\\\\\ \\\\\\\\
s9f9rd9r. 1 s.parity var 1 çift 2 yap9lmayacak 1 2stopbit \\\\\\\\\

4nolu bit tek mi yoksa çift mi parity yönteminin kullan9laca89n9 belirlemede i/e yarar.
Yap9lmayacaksa bu bitin anlam9 yoktur.
5nolu bit bir ise parity biti olarak sürekli bir yada s9f9r gönderilir. Buna sabit parity yöntemi denir.

80
7 NOLU B T N ANLAMI: Bu bit baz9 registerlar9n kulland989 ortak port numaralar9n9 ayr9/t9rmak
amac9 ile kullan9l9r.e8er BASE+0 portuna bilgi gönderiliyorsa bu bilgi THR DLL register9na
gönderiliyordur. /te LCR nin 7 nolu biti s9f9r ise THR bir ise dll register9na gönderilecektir.
Benzer bir biçimde base +1 portu hem okunabilir hem yaz9labilitr bir porttur. Ve görünü/te bu
porta DLM ve IER registerlar9n9n her ikisi birden ba8l9d9r. /te LCR register9n9n 7 nolu biti bir ise
DLM 0 ise IEM register9n9n kullan9m9 söz konusudur.

SER PORT v IRQ

Seri port yoluyla donan9m kesmenin ça89r9lmas9 sa8lanabilir. COM1 ve COM3 için IRQ 4
ça89r9l9r. IRQ 4’ün kesme numaras9 0CH’t9r. COM2 ve COM4 için IRQ 3 ça89r9l9r. IRQ 3’ün
kesme numaras9 0BH’t9r. Yani birinci 8259’un 4 numaral9 ucu COM1 portuna ba8l9 olan
UART’a 3 numaral9 ucu ise COM2 portuna ba8l9 olan UART’a(8250) ba8l9d9r. Uygulamada pek
çok seri port haberle/mesi kesme sistemiyle yap9lmaktad9r. Yani seri portlara ba8l9 olan birimler
UART i/lemcisini uyar9rlar, UART i/lemcisi ise 8259 i/lemcisine kesme iste8ini bildirir. Sonuç
olarak kesme d9/sal birim taraf9ndan ça89rt9lm9/ olur. Örne8in mouse devresi böyle bir kesme
mekanizmas9yla çal9/9r. Yani mouse seri porta periyodik olarak IRQ iste8i gönderir, kesme kodu
da mouse okunu hareket ettirir. UART i/lemcisinin kesme ça89rmas9 bir tak9m olaylar9n
gerçekle/mesine ba8l9d9r. Hangi olaylar gerçekle/ti8inde kesme ça89r9laca89 IER register’9na
de8ere ya9larak belirlenir. IER register’9n9n dü/ük anlaml9 4 biti kullan9l9r, di8erleri de 0’d9r.
0 Numaral9 Bit:
Bu bit 1 ise RBR register’9na yeni bir bilgi geldi8inde kesme ça89r9l9r.
1 Numaral9 Bit:
Bu bit 1 ise THR register’9 bo/al9nca kesme ça89r9l9r.
2 Numaral9 Bit:
Bu bir 1 ise UART i/lemcisinin durumu de8i/ince kesme ça89r9l9r. Yani LSR
register’9ndaki bitlerin durumu de8i/mi/se kesme ça89r9l9r.
3 Numaral9 Bit:
Bu bit 1 ise MSR register’9ndaki herhagi bir bit konum de8i/tirmi/se ça89r9l9r.

Bu bitlerin hepsi 1 yap9l9rsa kesme pek çok sebepten dolay9 gelmi/ olabilir. /te kesme
kodu kesmenin nedenini IIR(interrupt identification register) register’9na bakarak anlar. Bu
register’9n 1 ve 2 numaral9 bitleri kesmenin nedenini aç9klar.

00 MSR de8i/mesi nedeniyle


01 THR bo/almas9 nedeniyle
10 RBR’ye bilgi gelmesi nedeniyle
11 Hata nedeniyle

DOSYALARIN SER PORT KULLANILARAK TRANSFER ED LMES

Gönderen taraf dosyan9n karakterleri h9zl9 bir biçimde yaz9yorsa fakat alan taraf yava/ ise
bilgiyi do8ru bir biçimde alamayacakt9r (alan taraf overrun error durumuyla kar/9la/9r). Yani
gönderen h9zl9 alan yava/sa sorun olu/acakt9r. Bu tür senkronizasyon problemleri ba/ka
sebeplerden de ortaya ç9kabilir. Bu durumda bir transfer protokolü kullanmak gerekir. Kullan9lan

81
en basit transfer protokolü z-modem protokolüdür. Bu protokole göre gönderen taraf alan taraftan
onay bekler. Onay bekleme durumu alan taraf9n gönderen tarafa bir karakter göndermesi
i/lemidir. Böylece iki sistem birbirinden farkl9 h9zlarda bile olsa yaz9l9m yoluyla senkronizasyon
sa8lanm9/ olur. k9sa mesafe bilgisayar haberle/mesi için senkronizasyonu donan9m yoluyla
sa8lamak da mümkündür. Özellikle RTS/CTS uçlar9 kar/9l9kl9 ba8lanarak donan9m yoluyla
senkronizasyon sa8lanabilir.

MODEMLER HAKKINDA KISA B LG LER

Modemler seri porta ba8lanarak çal9/t9r9l9rlar. çsel ve di/sal olmak üzere iki tür modem
vard9r. D9/sal modemler bir seri kablo ile bilgisayara ba8lan9rlar. Oysa içsel modemler geni/letme
yuvalar9na tak9l9rlar. çsel modemler yine kendi içersinde seri porta sahiptirler. Yaz9l9mda
kullan9m farkl9l9klar9 yoktur. Yani aç9kça seri porta ba8lanm9/ olmasalar da ba8lanm9/
varsay9larak programlamal9d9rlar. Modemler say9sal bilgiyi normal telefon haberle/mesine
çevirerek uzak ileti/imi sa8larlar. Mademki modem UART i/lemcisiyle bilgisayara ba8lanm9/t9r.
O halde modeme bilgi göndermek için asl9nda bilgi UART i/lemcisine gönderilir. Benzer
biçimde modem bilgiyi elde etti8inde UART i/lemcisine kendisi yazar, biz de i/lemciden bilgiyi
al9r9z.

MODEM N PROGRAMLANMASI

Modemin programlanmas9 ve kullan9lmas9 yüksek seviyeli komutlarla yap9l9r. Bir


numaray9 arama, aramaya cevap verme, bilgi gönderme ve bilgi alma i/lemleri yaz9 biçiminde
komutlarla yürütülür. Bu türe standart komutlara AT komutlar9 denir. Ba/l9ca AT komutlar9
/unlard9r(bütün komutlar9n ba/9 AT ile ba/lar daha sonraki karakter komutun ne oldu8unu
aç9klar):

Komut /levi
ATA Aramaya yan9t verir(answer). Telefon çald989 zaman telefonun çald989 tespit edilince
ba8lant9n9n kurulmas9 için bu komut gönderilir.
ATD Arama komutu(dial). Kar/9 taraf9 aramak için kullan9l9r.
ATZ Modemi reset etmek amac9yla kullan9l9r.

MODEM N ÇALI MA MODLARI

Bir modemin 3 modu vard9:


1. Command mode Modem reset edildi8inde command moddad9r. Bu mode’da
modeme AT komutlar9 gönderilebilir. Örne8in bu modda arama
yap9labilir, aramaya cevap verilebilir. Ba8lant9 yap9ld9ktan sonra
modem otomatik olarak online moda geçer.

82
2. Online mode Bu modda modeme bir bilgi gönderildi8inde modem bunu
komut olarak kabul etmez, kar/9 tarafa gönderir. Yine bu modda
modemden al9nan bilgi kar/9 taraf9n gönderdi8i bilgidir.
Haberle/me bittikten sonra modem yine command moda
geçirilir ve sonra ba8lant9 kesilir. Online moddan online-
command moduna geçi/ yap9labilir.
3. Online-command mode Bu modda ba8lant9 kesilmez ancak modem AT komutlar9n9
alma moduna geçer.

Command Online
mode mode

Online
command
mode

Modemin command modda iki durumu vard9r. Echo mode denilen modda modeme her
gönderilen komut kar/9l989nda modem önce gönderilen komutun kendisini yollar. Sonra komut
kar/9l989nda yap9lan i/lemi anlatan küçük bir cevap yaz9s9 gönderir. Echo mode kapat9l9rsa modem
gönderilen komutu bir daha göndermez. Yaln9zca cevap yaz9s9n9 gönderir.

bioscom FONKS YONUNUN KULANIMI

Seri porta bilgi gönderip almak için a/a89 seviyeli programlama yerine do8rudan 14H
kesmesi ça89r9labilir ya da Borland derleyicilerinde bioscom isimli fonksiyon kullan9labilir.
Prototipi bios.h içerisindedir.

int bioscom(int cmd, char abyte, int port);

cmd 0 veya _COM_INIT


cmd 3 veya _COM_STATUS
cmd 1 veya _COM_STATUS
cmd 2 veya _COM_RECEIVE

Önce com portu cmd 0 ile initialize etmek gerekir. Üçüncü parametre com port numaras9n9
göstermektedir. 0 ise com1, 1 ise com2. kinci parametre e8er com port set edilecekse set

83
de8erlerini al9r. E8er bilgi gönderilecekse gönderilcek bilgiyi temsil eder. E8er bilgi al9nacaksa
ikinci parametrenin hiçbir önemi yoktur. Örne8in:

bioscom(_COM_INIT, _COM_CHR8 | Com portu 9600, noparity, 8 data biti ve 1


_COM_STOP1 | _COM_NOPARITY | stop bitine set eder.
_COM_9600, 0);
bisocom(_COM_SEND, ‘x’, 0); x karakterini com1 portuna gönderir
y = bioscom(_COM_RECEIVE, 0, 0); Com portundan bilgi al9r ve y’ye aktar9r.
State = bioscom(_COM_STATUS, 0, 0); UART’9n LSR ve MSR register de8erleri
al9n9r.

Örnek:Bir string’i com porta gönderen program.

/*-------------bioscom.c----------------*/
void writecomstr(const char * str)
{
char stat;

while(*str != '\0'){
do {
stat = bioscom(_COM_STATUS, 0, 0);
}while(!((stat >> 14) & 1));
bioscom(_COM_SEND, *str, 0);
++str;
}
}

void main(void)
{
writecomstr("ATD2883520\r");/*com port'a modem için dial komutu numaras9 yollar*/
}
/*-----------------------------------------*/

Ancak comporta bilgi göndermenin en kolay yolu önce com portu bioscom fonksiyonu ile set
etmek, daha sonra fprintf gibi dosya fonksiyonlar9yla FILE adresi yerine stdaux vererek
kullanmakt9r. Örne8in:

fprintf(stdaux,”ATD2883520\r”);

AT komutlar9 gönderildikten sonra komutun bitti8ini göstermek için ‘\r’ karakterini


göndermek gerekir.

LER DÜZEY EKRAN LEMLER

Standart Text Mode

84
80x25 çözünürlü8e sahip text moda standart text mode denir. Standart text mode
neredeyse bütün bilgisayarlar taraf9ndan desteklenmektedir. Bu bölümdeki yaln9zca standart text
mode’u içermektedir. Standart text mode’a ili/kin 3 tane video mode vard9r. Bunlar 2, 3, 7 ekran
modlar9d9r. 2 ve 7 numaral9 modlar mono modlard9r, 3 renkli text moddur. Mono modlarda renk
gözükmez. Renkli modda her karakter matrisinin /ekil ve zemin rengi söz konusudur. 16 /ekil 8
zemin rengi vard9r ve bu renkler önceden tan9mlanm9/t9r. Zemin renkleri /ekil renklerinin ilk 8
tanesidir. Yani ayn9 anda en fazla 16 renk görülebilir. Yüksek say9da renk ancak grafik modda
elde edilebilir.

Standart Text Mode’da Ekran Belle8inin Organizasyonu

Bugün kullan9lan VGA grafik kartlar9n9n üzerinde ismine ekran belle8i denilen bir RAM
bölgesi vard9r. Ekran belle8i DOS bölgesinin bitiminden ba/lar(A0000) ve 1 MB adres alan9
içerisindedir. Yani bu RAM bölgesi ekran kart9n9n üzerinde olmas9na kar/9n sanki normal simm
bloklar9n9n içerisindeymi/ gibi i/lem görür. Bu bölgeye uzak göstericilerle eri/ebiliriz. Ekran
belle8i A0000 adresinden ba/lamas9na kar/9n renkli standart text mode’da belle8in aktif olan
bölgesi B8000’dan, renksiz text mode’da ise B0000’dan ba/lar. Ekran kart9 ekran belle8inin aktif
bölgesindeki bilgileri monitöre belirlenen bir h9zda gönderir. Monitörde bnu bilgileri ekran9n
belirlenen bölgesine basar. Yani ekranda bir bilginin ç9kmas9n9 sa8lamak için tek yap9lacak /ey
bilgiyi bu ekran belle8ine yazmakt9r. Bilgi buraya yaz9ld9ktan sonra ekran kart9 taraf9ndan
monitöre yollan9r ve monitör taraf9ndan gösterilir. PC’lerde hangi programlama dili söz konusu
olursa olsun sonuçta ekrana yazma yapan fonksiyonlar ya da komutlar bilgiyi ekran belle8ine
yazmak zorundad9rlar. Ekran belle8indeki her iki byte ekrandaki bir matrisel hücreyi temsil eder.
Ekran belle8inin aktif bölgesini gösterecek bir gösterici tan9mlanabilir. Renkli text mode için bu
göstericinin içerisine segmen ve offset olarak /u de8erler yerle/tirilmelidir. scrp ekran belle8inin
aktif bölgesini gösteriyor olsun.

char far *scrp = (char far *)0xB8000000;

Bu göstericinin (row,col) hücresini göstermesi için yap9lmas9 gereken:

scrp = scrp + row * 160 + col * 2;

Bu iki byte’9n birinci byte’9 ekran9n belirlenen bölgesinde ç9kacak ascii karakterini, ikinci byte’9
ise rengini belirlemekte kullan9l9r. Örne8in a/a89daki fonksiyon ekran9n istenilen bölgesine
isenilen karakteri basar.

/*------------ekran1.c-----------------*/
void _writec(int row, int col, char ch)
{
char far *scrp = (char far *)0xB8000000;

scrp += row * 160 + col * 2;


*scrp = ch;

85
}

void main(void)
{
_writec(10, 10, ‘x’);
}
/*----------------------------------*/

Renk Bilgisinin Olu/turulmas9

Dü/ük anlaml9 4 bit /ekil daha sonraki 3 bit zemin ve en yüksek anlaml9 bit ise yan9p
sönme bilgisini içerir.

B Z Z Z

Renkler:

BLACK 0x0
BLUE 0x1
GREEN 0x2
CYAN 0x3
RED 0x4
MAGENTA 0x5
BROWN 0x6
WHITE 0x7
GRAY 0x8
LBLUE 0x9
LGREEN 0xA
LCYAN 0xB
LRED 0xC
LMAGENTA 0xD
YELLOW 0xE
LWHITE 0xF

/*------------ekran2.c----------------*/
void _writec(int row, int col, char ch, int color)
{
char far *scrp = (char far *)0xB8000000;

scrp += row * 160 + col * 2;


*scrp++ = ch;
*scrp = color;
}

void main(void)

86
{
clrscr();
_writec(10, 10, 'x', 0x1F);
}
/*---------------------------------------*/

conio Kütüphanesinin Kullan9m9

Prototipleri conio.h içerisinde bulunan ve temel ekran i/lmelerini yapan bir grup
fonksiyon vard9r. Bu fonksiyonlar borland derleyicilerine özgüdür ve yaln9zca DOS alt9nda
kullan9labilir.

textattr, textbackground, textcolor Fonksiyonlar

Bu fonksiyonlar cprintf ile yaz9lan yaz9n9n rengini belirlemekte kullan9l9rlar. cprintf


fonksiyonu burada belirlenmi/ olan renklere bakarak yazma i/lemini yapar ve kullan9m9 printf
fonksiyonunun ayn9s9d9r.
textattr fonksiyonunun tek parametresi vard9r. Bu parametre /ekil zemin ve blink bilgisini
içerir.
textbackground /ekil rengine dokunmadan sadece zemin rengini de8i/tirmede kullan9l9r.
textcolor yaln9zca /ekil rengini de8i/tirmek amac9yla kullan9l9r.

Renk fadesinin Düzenli Bir Biçimde Yap9lmas9

ekil ve zemin renkleri düzenli bir biçimde sembolik sabit olarak belirlenirse bit OR
i/lemiyle renkler kolayl9kla belirlenebilir. Örne8in /ekil renkleri ve zemin renkleri /öyle
tasarlanabilir.

0x01 0x0
0x02 0x10
0x03 0x20
.. ..
0x0F 0x70

Bu durumda a/a89daki gibi bir kullan9m çok kullan9/l9 olur.

BLUE_ | WHITE /* zemin rengi mavi /ekil rengi beyaz */

Ekran belle8i ile daha düzenli çal9/abilmek için ekran belle8indeki her hücre bilgisi bir
yap9yla temsil edilebilir.

/*-----------ekran3.c-------------*/

87
typedef struct _CHR{
char chr;
char attr;
}CHR;

void _writec(int row, int col, int ch)


{
CHR far *scrp = (CHR far *)0xB8000000;

scrp += row * 80 + col;


scrp -> chr = ch;
}

void main(void)
{
_writec(10, 20, 'y');
}
/*----------------------------------*/

Kütüphane Olu/turma

Sürekli yinelenen i/lemlerin kolay yap9lmas9n9 sa8lamak için çe/itli fonksiyonlar9 yazmak
ve biriktirmek gerekir. Bu fonksiyonlar9n birbirlerini ça89rmas9yla yüksek seviyeli i/lemler basit
birkaç fonksiyona indirgenebilir. Böylece büyük projeler önceden olu/turulmu/ kütüphaneler
olu/turularak kolayca haz9rlanabilir. Kütüphane olu/turma i/lemleri için disk üzerinde iyi bir
organizasyon olu/turulmal9d9r. Bir kütüphane içindeki fonksiyonlar9 düzenli bir
dokümantasyonunun yap9lmas9 gerekir. Yani fonsiyonlar9n parametrelerinin ne anlamlara geldi8i,
amaçlar9n9n ne oldu8u, geri dönü/ de8erlerinin ne oldu8u aç9kça dokümante edilmelidir.
Bir kütüphane içerisinde 3 seviye fonksiyon bulunmal9d9r.
1-)A/a89 seviyeli fonksiyonlar
2-)Orta seviyeli fonksiyonlar
3-)Yüksek seviyeli fonksiyonlar

A/a89 seviyeli fonksiyonlar en temel i/lemleri yapan fonksiyon grubunu olu/turur. Orta
seviyeli fonksiyonlar a/a89 seviyeli fonksiyonlar9 kullanarak orta seviyeli i/lemler yaparlar.
Yüksek seviyeli fonksiyonlar kullan9c9n9n ça89rd989 çok yüksek seviyeli i/lemleri yapan
fonksiyonlard9r.

Kütüphane Dosyalar9n9n Tasarlanmas9

Kütüphane dosyalar9 C ve H uzant9l9 olmak üzere iki /ekilde tasarlanmal9d9r. C uzant9l9


dosya içerisinde fonksiyon tan9mlamalar9 bulunur. H uzant9l9 dosya içerisinde ise genel olarak
nesne yaratmayan bildirimler yerle/tirilir. Yani sembolik sabitler, yap9, birlik, bit alan9
bildirimleri, typedef bildirimleri, fonksiyon prototipleri gibi bildirimler bulunmal9d9r. Bu H
uzant9l9 dosya C uzant9l9 dosya içerisinden include edilir. Art9k istenirse bu dosya derlenerek LIB

88
uzant9l9 dosyalar9n içerisine kat9labilir. Burada olu/turulan H uzant9l9 dosya yaln9zca bu
kütüphaneyi derlemek amac9yla de8il bu kütüphanenin kullan9ld989 durumlarda da include
edilmelidir.

Scroll /lemleri

Dikdörtgensel bir bölge içerisindeki tüm karakterlerin sa8a sola yukar9 a/a89
kayd9r9lmas9na scroll i/lemi denir. Scroll i/lemleri 10H kesmesinin 6 ve 7 numaral9
fonksiyonlar9yla yapt9r9l9r.

AH 6, 7 (6 a/a89, 7 yukar9)
AL 1 CH row1
CL col1
BH 7 DH row2
DL col2

Mademki scroll_up ve scroll_down fonksiyonlar9 tüm ekran için kullan9l9r, o halde yaz9m
i/lemini kolayla/t9rmak için iki makro tasarlanabilir.

#define scrup() scroll_up(0, 0, 24, 79)


#define scrdown() scroll_down(0, 0, 24, 79)

Ekran9n Silinmesi

Int 10H F:6

AH 6
AL 0
BH 7
CH row1
CL col1
DH row2
DL col2

Bu fonksiyon belirli bir dikdörtgensel bölgenin içini silmekte kullan9l9r. Ekran


kütüphanesinde clear isimli makro clearscr fonksiyonunu ça89rarak tüm ekran9 silmektedir.

#define clear() clearscr(0, 0, 24, 79)

Cursor’un Yerinin Tespiti

Cursor’un bulundu8u sat9r ve sütunun numaras9n9 almak için 10H kesmesinin 3 numaral9
fonksiyonu kullan9l9r. Geri dönü/ de8eri

89
DH sat9r no
DL sütun no

getcur Fonksiyonu

getcur fonksiyonu cursor’un konumunu tek parça int biçiminde al9r. Öyleki yüksek
anlaml9 byte de8eri sat9r, dü/ük anlaml9 byte de8eri sütun belirtir.

setcur Fonksiyonu

getcur ile al9nan de8er setcur ile konumland9r9labilir.

row = getrow(); cpos = getcur();


col = getcol(); ....
.... .....
.... ...
pos(row, col); setcur(cpos);

Sayfa Kavram9

80x25 text mode’da bir ekranl9k görüntü 80 * 25 * 2 = 4000 byte ile temsil edilir. 4000
bilgisayar için iyi bir say9 de8ildir. Ekran belle8indeki herbir 4096 byte bilgiye bir sayfa denir.
Default sayfa s9f9rd9r. Ama bir kesme ile bir sayfa aktif hale geitirilebilir. Bir sayfan9n aktif hale
getirilmesi ile ekran belle8inin aktif bölgesi de8i/tirilmi/ olur. Toplam sayfa say9s9 ekran kart9na
ve özellikle de kart üzerindeki bellek miktar9na ba8l9 olarak de8i/ir. Birden fazla ekran sayfas9n9n
kullan9lmas9 yayg9n bir özellik de8ildir. Donan9msal olarak sayfa de8i/tirmek için int 10H
kesmesinin 5 numaral9 fonksiyonu kullan9l9r.

AL sayfa numaras9

Her sayfan9n ayr9 bir cursor’u vard9r. Aktif sayfay9 donan9msal olarak de8i/tiren
set_active_page fonksiyonu tan9mlanm9/t9r. Sayfan9n donan9msal olarak de8i/tirilmesi pagemno
global de8i/kenini etkilemedi8i için birçok fonksiyon yanl9/(ba/ka bir sayfa için) çal9/9r. Bunun
için change_active_page fonksiyonu tasarlanm9/t9r. Bu fonksiyon önce donan9msal de8i/iklik
yapar, daha sonra pageno global de8i/keninin de8erini de8i/tirir. Yani biz kütüphane içerisinde
change_active_page fonksiyonunu ça89rmal9y9z.

Cursur’un Boyunun De8i/tirilmesi

Cursor 0-13’lük bir dikdörtgenin herhangi bir kesiti olabilir.

0
1
2
3

90
4
5
6
7
8
9
10
11
12
13

Cursor’un boyu iki de8i/kenle tespit edilir: min ve max. Normal cursor durumunda min = 12,
max = 13, maximum cursor durumunda ise min = 0, max = 13’tür. Cursor’un boyunun
dei/tirilmesi int 10H kesmesibnin 1 nolu fonksiyonu ile yap9l9r.
AH 1
CH min
CL max

Kütüphanede set_cursor_size fonksiyonu bu i/i yapar. /lemleri kolayla/t9rmak için iki makro
yaz9lm9/t9r.

#define maxcur() set_cursor_size(0, 13)


#define normcur() set_cursor_size(12, 13)

Klavye /lemleri

getkb() ve keypressed() fonksiyonlar9 getch() ve kbhit() fonksiyonlar9n9n kar/9l989


say9labilir.
Ekran Belle8i le Do8rudan Çal9/an A/a89 Seviyeli Fonksiyonlar9n Tasar9m9

Ekran belle8inde herbir hücreyi temsil eden bir yap9 belirlemek i/leri kolayla/t9r9r. Global
bir de8i/kende ekran belle8inin ba/lang9ç adresi tutulur.

typedef struct _CHR {


char chr;
char attr;
} CHR;

char far *vp = (char far *)0xb8000000;

initvideo() fonksiyonu

Mademki ekran belle8inin aktif bölgesi mono ve renkli modlar için farkl9d9r. O halde
sistemin otomatik olarak çal9/abilmesi için global vp de8i/keninin set edilmesi gerekir. Bu
fonksiyon önce o andaki video modu al9r, e8er bu video mod 2 ve 7 numaral9 modlardan bir

91
tanesi ise ekran belle8inin ba/lan9ç adresini 0xb0000000 adresine de8ilse 0xb8000000 adresine
set eder. Bu kütüphaneyi kullanan her türlü kod ba/lang9çta initvideo fonksiyonunu ça89rmal9d9r.

Buradaki temel fonksiyonlar genellikle row ve col parametresi al9rlar. Genellikle her
fonksiyon global vp de8erini sayfa numaras9 ile birle/tirerek aktif bölgeyi yerel bir scrp
göstericisine al9r.

CHR far *scrp = (CHR far *)(vp + pageno * PGSIZE);

Fonsiyon isimlendirmesinde baz9 isimler _ ile ba/lat9lm9/t9r. Bu isimli fonksiyonlar renk


bilgisini dikkate almazlar.

Temel Ekran Fonksiyonlar9n9n /levleri

_writec stenen bir ekran bölgesine tek bir karakteri renk bilgisine kar9/madan basar.
writec Yukar9daki fonksiyon gibidir anck renk bilgisini de kullan9r.
_writes Belirlenen ekran bölgesine renk bilgisini dikkate almadan bir yaz9y9 basar
writes Yukar9dai fonksiyon gibidir ancak renk bilgisini de kullan9r.
_fillc Belirlenen ekran bölgesinden itibaren renk bilgisini dikkate almadan belirlenen
bir karaketeri n defa basar.
fillc Yukar9daki fonksiyon gibidir ancak renk bilgisini de kullan9r.
_vfillc Ekran9n belirlenen bir bölgesinden ba/layarak belirlenen bir karakteri dü/ey
olarak renk bilgisini dikkate almadan basar.
vfillc Yukar9daki fonksiyon gibidir ancak renk bilgisini de kullan9r.
_writens Bir yaz9y9 belirlenen bir bölgeden ba/layarak n defa renk bilgisini dikkate almdan
basar.
writens Yukar9daki fonksiyon gibidir ancak renk bilgisini de kullan9r.
_frame Bu fonksiyon rengi dikkate almadan sol üst ve sa8 alt kö/egenleriyle belirtilen
çerçeveyi çizer
frame Yukar9daki fonksiyon gibidir ancak renk bilgisini de kullan9r.
_framed _frame gibidir ama çift çizgili çerçeve çizer.
framed frame gibidir ama çift çizgili çerçeve çizer.
Çerçeve Çizimler

Çerçeve yaln9zca dikdörtgensel bir çizim belirtir. Oysa pencere kavram9 bölgesel bir
kavramd9r. Çerçeve çizmek için özel çerçeve karakterleri kullan9l9r. Bütün çerçeve karakterlerinin
çift çizgili olanlar9 da vard9r. Çerçeve çizmek için writec, fillc ve vfillc fonksiyonlar9 kullan9l9r.
Önce kö/e karakterleri writec fonksiyonlar9yla yerle/tirirlir. Sonra fillc ile yatay çizgiler, vfillc ile
dikey çizgiler yerle/tirilir.

setwnd Fonksiyonu

wnd isimli gösterici Window türünden dinamik olarak büyütülen bir dizinin ba/lang9ç
adresini tutar.

92
chwnd Fonksiyonu

Bu fonksiyon bir pencere aç9ksa kapat9r, kapal9ysa açar. E8er pencere aç9l9yorsa arka plan
bilgi setwnd taraf9ndan tahsis edilmi/ olan blo8a yaz9l9r, kapat9l9yorsa bu bilgi ekrana geri bas9l9r.
Ancak pencere kapan9rken dikket edilmesi gereken bir durum vard9r. Pencere aç9kken bir tak9m
görüntüsel de8i/iklikler yap9lm9/ olabilir. Arka plan bilgiyi ekrana basmadan önce de8i/tirilmi/
olan pencere bilgisinin saklanmas9 gerekir. Saklama i/leminden sonra arka plan bilgi bas9l9r.
Art9k yeni bilgi arka plan bilgi olacakt9r ve ilgili de8i/iklikler yap9l9r. Fonksiyona setwnd’den
al9nan handle de8eri parametre olarak geçirilir. Pencere aç9ksa kapat9l9r, kapal9ysa aç9l9r. Tabii bu
pencere sisteminde son aç9lan pencere ilk kapat9lmak zorundad9r. Herhangi bir pencerenin
kapat9laca89 durumda daha de8i/ik bir organizasyon yap9lmal9d9r.

freewnd Fonksiyonu

Bir pencere art9k kullan9lmayacaksa freewnd fonksiyonu ile serbest b9rak9lmal9d9r. Çünkü
bu fonksiyon arka plan bilgi için tahsis edilmi/ alan9 free fonksiyonu ile serbest b9rak9r.

clearwnd Fonksiyonu

Bu fonksiyon program9 bitirirken sadece 1 kez ça89r9lmal9d9r. Çünkü dinamik olarak


büyütülen Window dizisini serbest b9rakmakta kullan9l9r.

Pencere Sisteminin Geli/tirilmesi Konusundan Tavsiyeler

- Bir pencere aç9ld9ktan sonra pencerenin içerisine bir/eyler yazmak için her defas9nda
koordinat dönü/ümü yapmak gerekir. Oysa bu i/lem bir grup fonksiyon taraf9ndan otomatik
olarak da yap9labilir. Örne8in ekrana bilgi yazan bütün fonksiyonlar9n W versiyonlar9 olur. Bu
fonksiyon kullan9ld989nda hangi pencere aktifse onun sol üst kö/egeni 0, 0 kabul edilir. Aktif
pencerenin otomatik olarak bulunmas9 yani örne8in bir pencere kapat9ld9ktan sonra hangi
pencerenin aktif olaca89n9n bilinece8i stack algritmas9 ile mümkün olabilir. Tabii bu i/lemler
manuel olarak da bir fonksiyon ça89r9larak yap9labilir. Örne8in void set_active_window(int
handle);
- Olu/turdu8umuz pencere sisteminde son aç9lan pencere ilk kapat9lmak zorundad9r. Oysa
de8i/ik bir düzenlemeyle herhangi bir pencerenin kapat9lmas9 sa8lanabilir.

Klavye Kullan9m9

1980 y9l9nda piyasaya sürülen ilk PC’lerde 83 tu/lu klavye kullan9l9yordu. Bu klavyeye PC
klavyesi denilmektedir. Daha sonra bu klavye sistemine bir tu/ daha eklenmi/tir ve 84 tu/lu
yap9lm9/t9r. Ancak 1985 y9llar9ndan sonra klavyede çok ciddi bir de8i/iklik yap9lm9/t9r ve
101/102 tu/ sistemine geçilmi/tir. Yap9lan de8i/iklik hem tu/lar9n yerleriyle hem de say9lar9yla
ilgilidir. Ok tu/lar9, home, end gibi özel tu/lardan birer tane daha eklenmi/tir. Son y9llarda
özellikle WINDOWS i/letim sistemi için klavyeye birkaç tu/ daha eklenmi/tir. Ancak bu tu/lar
WINDOWS d9/9nda kullan9lmamaktad9r.

93
Klavye Devresi

Klavyenin mekanik k9sm9 birbirini kesen matrisel bir ba8lant9 sistemine oturtulmu/tur. Bir
tu/a bas9ld989nda yatay ve dü/ey eksenlerdeki yollar k9sa devre yap9l9r. Böylece elektriksel olarak
hangi tu/a bas9ld989 anla/9l9r. Bu matris biçimindeki yap9n9n yatay ve dikey uçlar9 ismine klavye
i/lemcisi denilen özel bir i/lemciye ba8l9d9r. Bu i/lemci Intel 8048 ya da türevi bir i/lemci(Holtek
HT6547D) olabilir. Klavye i/lemcisi bas9lan tu/un kaç numaral9 tu/ oldu8unu tespit eder ve bunu
bit bit kodlayarak iletir. Keyboard i/lemcisine göre her tu/un bir s9ra nosu vard9r. Bu say9ya
klavye tarama kodu(keyboard scan code) denir. Bas9lan tu/un klavye tarama kodu klavye
i/lemcisinden bit bit okunarak al9nabilir. Bas9lan tu/un bilgisi seri haberle/me yoluyla bit bit
i/lemcinin data ve clock uçlar9 kullan9larak al9nabilir. Clock ucu normalde logic 1 seviyesindedir.
Bir tu/a bas9ld989nda i/lemci hangi tu/a bas9ld989n9 anlar ve clock ucunu 0’a çekerek bas9lan tu/un
klavey tarama kodunu vermeye ba/lar. Bilgiyi alacak ki/i clock ucuna bakarak data hatt9n9
örneklemelidir. Tu/a bas9ld989nda i/lemci yaln9zca klavye tarama(KTK) kodu yollar. /lemci
tu/tan elin çekildi8ini de anlar. Bunu bildirmek için önce bir F0 sonra da tu/a ili/kin KTK
de8erini yollar. KTK bilgisi de 1 byte uzunlu8unda bir bilgidir. Numlock capslock gibi tu/lara
bas9ld989nda i/lemci normal olarak bu tu/lar9n 9/9klar9n9 yakmaz. Bu 9/9klar9n yakt9r9lmas9 bu
i/lemcinin d9/ar9dan programlanmas9yla yap9l9r. Yani i/lemci hem bilgi göndermekte hem de bilgi
alarak programlanmaktad9r.

Klavye bilgisayar ba8lant9s9nda 5 uçlu bir konnektör kullan9l9r. Bu uçlar:

1
2

3
4
5

1. Clock
2. Data
3. Reset
4. Ground
5. +5V

Klavyeden gönderilen bilgi bu konnektör yoluyla ismine klavye i/lemcisi denilen bir i/lemci
taraf9ndan elde edilir. Klavye i/lemcisi olarak Intel 8042 gibi i/lemciler kullan9lmaktad9r. Klavye
denetleyicisi klavye tarama kodunu ismine sistem tarama kodu(system scan code) denen ba/ka bir
tarama koduna çevirir. Klavye denetleyicisi 8259 kesme denetleyicisine ba8l9d9r. Bir tu/a
bas9ld989nda ve çekildi8inde 1 numaral9 IRQ’nun ça89r9lmas9na yol açar. Bu IRQ sayesinde 9
numaral9 kesme kodu çal9/t9r9lmaktad9r. Klavye denetleyicisinin iki tane register’9 vard9r. Bu
register’lar do8rudan 60H ve 64H portlar9na ba8l9d9r. 60H portuna DATA portu denir. E8er bu
porta ba8l9 register okunursa son bas9lan ya da b9rak9lan tu/a ili/kin sistem tarama kodu elde
edilir. Sistem tarama kodu klavye tarama kodundan farkl9d9r. Tu/tan el çekildi8inde çekilme
i/lemini anlatmak için F0 byte’9 gönderilmez, sistem tarama kodunun en yüksek anlaml9 biti

94
1’lenir. Bir tu/a bas9ld989nda tu/a ili/kin sistem tarama kodu klavey denetleyicisi taraf9ndan
denetlkenir ve IRQ 1 ça89r9l9r.

/*-----klavye.c-----*/
#include <stdio.h>
#include <dos.h>
#include <conio.h>

void main(void)
{
char ch;

for(;;) {
printf("%02X\r", inp(0x60));
if (kbhit()) {
ch = getch();
if (ch == 'q')
break;
}
}
}
/*-----------------------*/

IRQ 1 (9H kesmesi) Ne Yapar?

Kesme kodu 60H portunu okuyarak bas9lan tu/un bilgisini al9r ve bunu ismine klavye
tampon bölgesi denilen bir bölgeye dönü/türerek yazar. Kesme kodunun klavye tampon bölgesine
yerle/tirdi8i tarama koduna geni/letilmi/ tarama kodu(extended scan code) denir. Geni/letilmi/
tarama kodu sistem tarama kodundan ctrl ve alt tu/lar9n9n kullan9m9 aç9s9ndan farkl9d9r. Ctlr ve alt
tu/una ba/ka bir tu/la beraber bas9ld989nda asl9nda bunlar9n iki ayr9 sistem tarama kodu oldu8u
halde tek bir kod olarak birle/tirilmektedir. Yani örne8in ctrl+c tu/lar9na bas9ld989nda sanki tek
bir tu/a bas9lm9/ gibi tek bir geni/letilmi/ tarama kodu yaz9l9r.

Tarama kodu çevirme özeti: Klavye içerisindeki klavye i/lemcisi d9/ar9ya klavye tarama kodunu
verir. Klavye denetleyicisi bunu sistem tarama koduna çevirir ve 60H portundaki register’a yazar.
9H kesme kodu bunu geni/letilmi/ tarama koduna çevirir ve klavye tampon bölgesine yazar.

Programlama dillerindeki bütün klavyeden tu/ alan fonksiyonlar tu/ bilgisini nihai yer olan klave
tampon bölgesinden almaktad9r.

Klavye Tampon Bölgesi(keyboard buffer)

Klavye tampon bölgesi 0000:041E bölgesinde bulunmaktad9r. Bu tampon bölge en fazla


15 tu/un bilgisini tutan döngüsel bir yap9dad9r. Klavye buffer9’n9n durumunu ismine head ve tail
pointer denilen iki pointer gösterir. Bu iki pointer ayn9 de8erdeyse tampon bölge bo/tur. Bir tu/a

95

Head pointer
Tail pointer
bas9ld989nda 9H kesme kodu tu/ bilgisini tampon bölgeye yerle/tirir ve tail pointer’9 ilerletir. u
anda tamponda 1 karakter vard9r.

Klavye tampon bölgesindeki herbir giri/ 2 byte uzunlu8undad9r. Bu iki byte’9n dü/ük anlaml9
byte’9 bas9lan tu/un ASCII kodunu yüksek anlaml9 bye’9 geni/letilmi/ tarama kodunu tutar. Özel
tu/lar9n ASCII kodu 0’d9r. Onlkar ancak geni/letilmi/ tarama koduyla te/his edilebilirler. Klavye
tampon bölgesinde bulunan bilgiler 16H kesmesinin fonksiyonlar9yla al9nabilirler. Yani
programc9 klavye tampon bölgesinin yap9s9n9 bilmek zorunda de8ildir. Çünkü buradan bilgiyi
16H kesmesinin fonksiyonlar9n9 ça89rarak alabilir. Programlama dillerindeki klavyeye ili/kin tüm
fonksiyonlar asl9nda 16H kesmesini ça89rarak bu bilgiyi tampon bölgeden al9rlar. Örne8in getch
gibi bir fonksiyon 16H kesmesini ça89rmaktad9r. Ancak geni/letilmi/ tarama kodunu
vermemektedir.

16H Kesmesinin Baz9 Fonksiyonlar9

Tamponda bulunan tu/a ili/kin ASCII ve geni/letilmi/ tarama kodunun al9nmas9

INT 16H
F:0 ve F:10H

Geri dönü/ de8eri:

AX
AH Tarama kodu
AL ASCII kodu

Bu kesmeyi kullanarak ASCII ve geni/letilmi/ tarama kodunu alan bir C fonksiyonu


yaz9labilir.

/*-----klavye2.c-----*/
#include <stdio.h>
#include <dos.h>

int getkb(void)
{
union REGS regs;

regs.h.ah = 0x0;
int86(0x16, &regs, &regs);
return regs.x.ax;

96
}

void main(void)
{
int ch;

while((ch = getkb()) != 0x011b)


printf("%04x\n", ch);
}
/*----------------------*/

Tabii bu kesme e8er tampon bölge bo/sa doluncaya kadar bekler. Yani 16H kesme kodu
a/a89daki gibi çal9/9r:

16H()
{
while(tampon bo/)
;
return tampondaki_bilgiler;
}

Tamponun bo/ oldu8unu varsayal9m. 16H döngü içerisinde tampona bakarak bekler.bir tu/a
bas9ld989nda program9n ak9/9 donan9mn kesmesiyle kesme koduna geçer. Kesme kodu tamponu
doldurur. Kesme kodunun ç9k9/9nda döngüsel durum tampon doldu8u için sonlan9r. Bütün özel
tu/lar9n ASCII ve scan kodlar9 birlikte “scr.h” header dosyas9nda tan9mlanm9/t9r. Sembolik sabit
isimlendirilmesinde KP ile ba/layan grup sa8 taraftaki tu/ grubudur. Örne8in KP8 yukar9 ok tu/u,
KP2 a/a89 ok tu/udur.

/*-----klavye3.c-----*/

Klavyeden String Alan Geli/mi/ Fonksiyonlar

Standart C’de kulland989m9z gets() ve scanf() fonksiyonlar9 ciddi projelerde


kullan9lmayacak kadar ilkeldir. Bu fonksiyonlar hiçbir özel tu/ için özel davran9/ göstermezler.
Örne8in insert ve delete tu/lar9na duyarl9 de8ildirler. gets() fonklsiyonu yerine çok daha geli/mi/
getstr() fonksiyonu yaz9lacakt9r.

getsr() Fonksiyonundan Beklenilenler

- n karakter alma gibi bir s9n9r belirleme durumu olmal9d9r. stense bile daha fazla karakter
al9namamal9d9r.
- DEL, INS, HOME, END gibi tu/lara uygun davran9/lar9 göstermelidir.
- stenilen bir tu/a bas9ld989nda ver giri/ alan9ndan ç9k9lmas9 gerekir.

97
getstr() Fonksiyonunun Parametreleri

getstr(void *str, int count, int (*exfunc)(int), const char *init);

- Fonksiyonun birinci parametresi edit alan9 içerisindeki bilginin yerle/tirilece8i adresi belirtir.
- kinci parametre en fazla kaç karakter okunaca89n9 beliritir.
- Üçüncü parametre edit alan9n9n terk etmek için kullan9lacak tu/un belirlenece8i fonksiyonu
ça89r9r. Bu fonksiyon getstr() içerisinden bas9lan tu/ parametresiyle ça89r9l9r. E8er fonksiyon 0
d9/9 bir de8ere geri dönerse edit alan9 terk edilir, 0 de8eriyle dönerse terk edilmez. Fonksiyon
/öyle tasarlanabilir.

int exfunc(int ch)


{
switch(ch) {
case CR:
case CTRL_C:
return 1;
}
return 0;
}

- Dördüncü parametre edit alan9na girildi8inde ç9kacak yaz9y9 belirlemede kullan9l9r. E8er bu
parametre NULL ise hiçbir yaz9 ç9kart9lmaz.

Fonksiyon hangi tu/ nedeniyle edit alan9ndan ç9klm9/sa ona geri döner.

Fonksiyonun Tasar9m9

Algoritman9n çekirde8i döngü içerisinde getkb() fonksiyonuyla bir tu/ al9nmas9, bu tu/un
switch içerisinde hangi tu/ oldu8unun belirlenmesi ve uygun i/lemleri yap9lmas9 i/lemlerine
dayan9r. Edit penceresi cursor neredeyse orada aç9l9r.

Fonksiyonda Kullan9lan Yerel De8i/kenler

row, col O anda cursor’un bulundu8u hücrenin koordinat bilgilerini tutar.


col_init Edit alan9n9n ba/lang9ç kolon bilgisini tutar.
nchr O anda edit alan9nda girilmi/ toplam karakterlerin say9s9n9 belirtir.

98
n Cursor’un bulundu8u sütun bilgisini edit alan9n9n ba/9ndan itibaren belirten
bir orijinde tutar.

updatenchr() lk giri/te edit aln9nda bulunan toplam karakterlerin say9s9na geri döner.
getnscr() Edit alan9n9n içerisindeki bilginin elde edilmesi için kullan9l9r.

Bütün tu/ kontrollerinde e8er gerekliyse n, col, nchr de8i/kenleri güncellenmelidir. E8er bas9lan
tu/ özel bir tu/ de8ilse switch de8iminin default k9sm9na gelinirlir. Bu durmda bas9lan tu/ edit
alan9n9n sonuna eklenir.

Kod Organizasyonu

getstr() fonksiyonu iki dosya halinde yaz9lm9/t9r(getstr.h ve getstr.c). Getstr.h içerisinde


fonksiyon parametreleri ve sembolik sabitler vard9r. Getstr.c içerisinde ise getstr() ve ilgili di8er
fonksiyonlar9n tan9mlamalar9 bulunur. getstr() fonksiyonu yaz9l9rken scr.c modülündeki
fonksiyonlar kullan9lmaktad9r. Bunu sa8lamak için bir project dosyas9 olu/turulur. Project
dosyas9n9n içerisine scr.c ve getstr.c dosyalr9 konulur.

Kütüphane Olu/turma

Uzant9s9 .lib olan dosyalara kütüphane dosyalar9 denir. Kütüphane dosyalar9 obj
modüllerden olu/ur. Obj modüller derlenmi/ fonksiyonlardan olu/ur. Örne8in n tane fonksiyon
kütüphane içerisine yerle/tirilecekse:

1. n tane fonksiyon bir kaynak dosya içerisine yaz9l9r. Bu kaynak dosya x.c olsun.
2. Bu dosya derlenerek obj modül elde edilir. X.obj olu/tu.
3. Bu obj modül lib dosyan9n içerisine yerle/tirilir.

Bir kütüphaneye obj modül eklemek ya da ç9karmak için

TLIB.EXE(Borland)
LIB.EXE(Microsoft)
ARC(Unix tabanl9)

Kullan9m9:

Tlib <.lib name> +/- <.obj name>

Örnek:

Tlib a.lib + b.obj /*b.obj’u a.lib’e dahil eder*/


Tlib a – b /*a.lib içerisinden b.obj dosyas9 ç9kar9l9r*/
Tlib a,con /*a.lib içerisindeki tüm obj modülleri ve fonksiyonlar9 ekrana listeler*/
Tlib a,b /*a.lib içerisindeki tüm obj modülleri ve fonksiyonlar9 b.lst dosyas9na yazar*/

99
lgili lib dosyas9 yoksa yarat9r. Lib dosyalar9 link a/amas9nda aran9r. stenilen bir .lib
dosyas9na linker’9n bakmas9 için o lib dosyas9n9n project dosyas9na dahil edilmesi gerekir. Tabii
derleme a/amas9nda kütüphanede bulunan fonksiyonlar9 prototipleri için header dosyalar9n9n
include edilmesi gerekir.

String Fonksiyonlar9n9n Geli/tirilmesi

1. Scroll içeren bir version’u yaz9labilir. Yani fonksiyondaki count edit alan9n9n uzunlu8unu
belirtir, ancak count say9s9ndan daha fazla karakter giri/i yap9labilir.
2. Tarih alan tam say9 ve gerçek say9 alan özel getstr() fonksiyonlar9 yaz9labilir.
3. Ve nihayet bütün bu fonksiyonlar tek bir fonksiyon içerisine entegre edilebilirler.

100

You might also like