AMİGA VE C
Retro bilgisayarLLER
CENKER ÖZKURT C yolculuğumuz devam ediyor. Bu ay da aynı şekilde yeni örneklerimiz ile yazımızı sürdürüyoruz. Hatırlayacağınız gibi, geçen ay Menudesign adı altında bir örnek program üzerinde çalışmıştık. Bu örnek ile kendi utility program arşivimizi hazırlayabiliyor ve çalıştırabiliyorduk. Bu örneğimizin en büyük faydası, bizlerin de artık kendi utility programlarımızı hazırlayabileceğimizi görmüş olmamız. Yeni örneklerimize geçmeden önce, Compile ve Link işlemleri için kullanabileceğimiz parametre listesini vermek istiyorum. Bu parametreler ile programımızın hafıza modelini, hangi hafıza bölgesinde bulunacağını, assembler listesini isteyip istemediğimizi belirtebiliyoruz. Bu sayede, örneğin programımızın assembler listesini incelememiz mümkün olabiliyor. Dikkat edin; Assembler listesi dedim!! Dikkat!! Dikkat!!.. Buradan da anlaşılacağı gibi, C derleyicimiz aynı zamanda bir assembler derleyicisidir. Yazmış olduğumuz C programı, Compile vasıtasıyla assembler'a çevrilir. Fakat siz bu assembler listesini göremezsiniz. Görebilmeniz için aşağıda vermiş olduğum parametre listesini kullanmanız gerekiyor,
Compiler Parametreleri:
assemble etmeden uzantısı .asm olan dosyayı yarat -c link etmeden uzantısı .o olan dosyayı yarat -s uyarı mesajlarını yazmadan compile et -t C source cümlelerini assembler listesine at -e geniş code'lü hafıza modelini kullan -d geniş data'lı hafıza modelini kullan -i integer ve sabitleri 32 bit'lik long'a çevir
Link Parametreleri:
ihtiyaç olan module'ü name.lib'te ara -l(edb) — code, data ya da bss'leri chip hafızaya yükle -f(edb) — code, data ya da bss'leri fast hafızaya yükle
Compiler ve Linker parametreleri ayrı ayrı verilmiştir. Örneğin bir programımızın assembler listesini görmek istersek, compile sırasında;
cc -a prog.c
yazmalıyız. Bu sayede Compile programı C programının assembler listesini çıkaracaktır. İstersek bu liste üzerinde değişiklik yaparak yeniden compile edebiliriz. Gelecek ay bu konu üzerinde daha geniş olarak duracağız ve C programlarımızda assembler programlarımızı çağırmayı öğreneceğiz. Yukarıdaki parametreler Aztec C Versiyon 3.6 içindir. Elinde versiyon 5.0'ı olanlar bu parametreleri şu şekilde kullana-
a prog.c
Bu konudaki geniş bilgiyi disketinizdeki döküman dosyalarından öğrenebilirsiniz.
Link işlemleri sırasında, programımızı istediğimiz hafıza bölgesine (Chip ya da Fast) atabiliriz. Bu işlem özellikle assembler programları yazdığımızda işimize yarayacaktır. Şimdi bu ayki örneklerimize geçebiliriz. İlk örneğimiz, joystick ya da joystick portlarımızı kontrol için. Programı çalıştırdıktan sonra joystick'imizi hareket ettirerek hangi yönün sağlam ya da bozuk olduğunu öğrenmemiz mümkün. Programımız tamamı aşağıda olduğu gibi:
#define PORT 2
short *joy-Üxdff00842*PORT;
char *cia-0xbfe00l;
Amain()
/
while(1) |
if(*joy&2) printf("SOL");
printf("SAG");
1) printf("ASAGI");
primf("YUKARI");
if(1*cia&64*PORT)) printf("ATES");
|
)
İlk satırdaki önişlemci komutu ile, PORT macro sabitini belirliyoruz. Burada 2 sayısı 2. portu kullanacağımızı belirtiyor. Aynı şekilde 1. portu da kontrol etmemiz mümkün. Diğer satırda *joy değişkeni short tipinde tanımlanıyor. Aynı zamanda bu değişkeni pointer olarak tanımlayarak joystick portunu görüntülemesini de sağlıyoruz. Portu görmemizi sağlayan adres, hex olarak 0xdff008+2*PORT'dir. short tipindeki değişkenler, 2 byte'lık bir yer kaplamaktadır. Bu adres de aynı şekilde bize 16 bitlik bir sayı ile geri döneceğinden, biz de short olarak tanımladık. Tanımlarken short yerine WORD tipi yazmanız da mümkün. Çünkü short ve WORD tamamen aynı özelliklere sahiptir. Fakat WORD tipi kullanırken, programınızın başına #include <exec/types.h> yazmanız gerekir. WORD bu dosya içerisinde short olarak define edilmektedir. İkinci satırda 'fire' tuşunu kontrol için *cia değişkenini 0xbfe001 adresini görüntüleyecek şekilde tanımlıyoruz. Sonraki satırlarda ana programa girerek *while* komutu ile sonsuz bir döngüye giriyoruz. Döngü içerisinde *if* satırları ile joy değişkeninin bit durumunu kontrol ediyoruz. Örneğin joystick'i sola çekerek 0xdff008+2*PORT adresinin 2. bit'inin '1' olup olmadığını öğrenerek durumu ekrana yazıyoruz. Diğer satırlarda da aynı şekilde bu adreslerin bit durumlarını kontrol ederek döngüye devam ediyoruz. Döngüden çıkmak için klasik hareket *Ctrl-C* yapıyoruz. Bu ayki ikinci örneğimiz günün tarihini ve saati öğrenmemizi sağlayan kısa bir program. Bu iş için iki komut kullanıyoruz. Komutlar Aztec firmasının hazırlamış olduğu kütüphanede mevcut. İlk komut timer'dan zamana karşılık bir değer okuyor. Timer bilgisayarımızın içerisinde devamlı çalışan bir sayıcı olarak çalışıyor. Daha sonra biz bu değeri okuyarak 26 byte'lık bir diziye çeviriyoruz. Diziyi ekrana yazarak sonucu görüyoruz.
main()
(
long *tloc;
long *clock;
P* Timer'dan zamana karsilik bir deger okur */
timeltloc);
/* Bu degeri 26 karakterlik ASCTI ye cevirir */
clock);
|
Diğer programımız ikinci örneğimizin daha gelişmişi. Program çalıştıktan sonra bir window açarak tarih, saat ve hafıza durumunu görüntülüyor. Ayrıca programı AmigaDos'tan run komutu ile MultiTask olarak çalıştırmak mümkün. Şimdi programımıza bir göz atalım;
STATUS (c)9.1.1992 by CENKER OZKURT */
#include <stdio.h>
#include <exec/exec.h>
#include <exec/execbase.h>
#include <graphics/gfxbase.h>
#include <intuition/intuitionbase.h>
#include <exec/memory.h>
struct NewWindow windef — |
200, 0, 440, 22,
WINDOWCLOSEİWINDOWDRAG ,
NULL, NULL,
NULL,
NULL, NULL, 0, 0, 0, 0,
WBENCHSCREEN
k
struct GfxBase *GfxBase;
struct İntuitionBase *IntuitionBase;
struct Window *win;
struct RastPort *rp;
main()
long *tloc;
long *clock;
long c1241;
char *msg;
char
int ChipFree,FastFree;
IntuitionBase — OpenLibrary ("intuition.library", 0);
GixBase — OpenLibrary (“graphics,library", 0);
win — Open Window (&windef);
SetTaskPri(FindTask((char *) ;
SetWindowTitles( win, "STATUS(c)1992 by Cenker OZKURT",0);
while(1) |
if (msg — GetMsg (win -> UserPort)) |
ReplyMsg (msg);
CloseWindow(win);
CloseLibrary(GfxBase);
Closelibrary(IntuitionBase);
return;
|
time(tloc);
clockzetimeltloc);
strncpy(e,clock,24);
ChipFree —
FastFree
sprintf(a,"9os CHIP-9od
Movef(rp,23,18);
Text(rp,a,strlen(a));
|
|
Programın ilk satırlarında #include önişlem komutları ile gerekli olan makrolar ve fonksiyonlar tanımlanıyor. Struct satırlarında kullanılan yapılar belirleniyor. main() fonksiyonu içerisinde Intuition ve Graphics Library'leri açılıyor, OpenWindow() ile window'umuz hazırlanıyor ve SetTaskPri() ile çalışmaya başlayan programın task'lar arasındaki öncelik sırası belirleniyor. -128 en düşük değeri belirtiyor. Öncelik sırası -128 ile +127 arasında ayarlanabilir. Sonraki satırda aynı şekilde sonsuz döngüye giriş: GetMsg() fonksiyonu ile window'dan mesaj gelip gelmediğini kontrol ediyoruz. Window'u kapama mesajı geldiğinde 'if' bloklarına girerek programdan çıkıyoruz. Aksi takdirde alt satırlara geçilerek tarih, zaman ve hafıza durumunu öğreniyor ve window'a yazıyoruz. Bu ayki üçüncü ve son programımız da C'de kayan yıldızlar! Birçok demoda karşımıza çıkan bu yıldızları ben de C'de sizler için hazırladım. Programımız çalıştıktan sonra ekranın ortasından bize doğru yıldızlar kayacaktır. Programımızın bazı avantajları da bulunmakta. Bunların başında kayan yıldızların hızını ve sayısını ayarlamak geliyor. Bununla birlikte yıldızların hangi noktadan bize doğru geleceğini belirleyebiliyoruz. Programın mantık kısmını anlamayı size bırakıyorum. Eğer bunu anlayabilirseniz yıldızları tersine sizden uzaklaştırabilirsiniz. Şimdi programımızı inceleyebiliriz:
We TDI
Programming by Cenker OZKURT */
#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gfxbase.h>
#define NSTARS 30
struct IntuitionBase *IntuitionBase;
struct GixBase *GfxBase;
struct NewScreen serdef — |
0, 0, 320, 256,
1, /* #planes */
<A, -1,
NULL,
CUSTOMSCREEN,
NULL, NULL, NULL, NULL
Kk
struct windef — |
0, 0, 320, 256,
A, A1,
CLOSEWINDOW,
WINDOWCLOSE,
NULL, NULL, NULL, NULL, NULL,
0, 0, 0, 0,
CUSTOMSCREEN
k
struct Window *win;
struct Screen
struct RastPort *rp;
int xİNSTARSI), yINSTARSI), zİNSTARSI;
int xo|NSTARSI, windef.Screen — ser;
if z OpenWindow (&windef))) |
long seed: printf painted
closestuffO;
|
— -> RastPort);
int magic, in
register int i, İz:
CUCET GENBANO),
inc-6;
openstuff ():
SetRast(rp, OL);
-> ViewPort), OL, OL, OL, ÖL);
SetRGBA (&(ser -> ViewPort), IL, ISL, I5L, 15L);
for i<NSTARS: i4-4) point(i); int result — 90 ma
" Tong *DateStampı
while(1) |
for i<NSTARS: | ç if (seed — OL) |
if ((zli) — ine) <- DateStamp (datevec);
© bü, Seed > (WORD)
İ PA
* mazic / 128: A > 0x800000001 ((seed << 1)»
YÜ) * iy yi 128;
- SiğAPen (Tp, Ol 0x1D872B4İL);
WritePixel (rp, yoli)); else seed <<
if (xs <0 İl ys >255) |
pointli): return (result):
|
else |
SetAPen (rp, İD); | Program açıklamamıza geçelim. İlk olarak #include dosyaları
WritePiygl Gr ve struct satırları işleniyor. Aradaki,
xoli) xs: erir
#define NSTARS 30
if (msg = GetMsg (win -> UserPort)) satırı ile yıldız sayısını 30 tane olarak belirliyoruz. Bu sayı ile ReplyMsg (msg); oynamanız mümkün. Diğer satırlarda Screen ve Window yapıları break; belirlenerek tek plane'lik bir ekran açılıyor. Tek plane'lik bir ekranda 2 adet rengimiz mevcut. Taban rengini siyah, yazı rengimizi ise beyaz olarak main() içerisindeki SetRGB4() fonksiyonları ile tanımlıyoruz. Diğer satırlarda ise yıldız koordinatlarını ve ivmelenmek için integer olarak değişkenler kullanıyoruz. Kullanılacak olan değişkenler de tanımlandıktan sonra closeStuff() ile bütün ekran ve pencereler hazırlanıyor. register int i;
açılan window'un, çerçeve rengini zemin renk olarak se-
SetRGBA4A (&(ser > ViewPort), OL, OL, OL, OL);
SetRGB4 (&(ser > ViewPort), 1L, I5L, 15L);
di Yukarıdaki satırlarda da zemin ve kalem rengi paletten seçiliyor. printf ("Intuition open failed."); Sayıların yanındaki karakteri, değerin LONG olarak değerlendirileceğini belirtiyor. "(long) 1" ile "1L" arasında bir fark yok. Her iki yazım şekli de tip değişimini sağlıyor. Diğer satırlarda yıldızlar belirlenerek bize doğru kaymaya başlıyorlar. Yıldız sayısını azalttığımızda hız biraz daha artacaktır. Window'umuzun sol üst köşesini kliklediğimizde programımız sona erecektir. Program içerisindeki rnd() fonksiyonunu, rastgele sayı üretmek için kullanıyoruz. rnd(100) verdiğimizde, fonksiyon -100 ile 100
if (!(GfxBase = OpenLibrary ("graphics.library", 0))) arasında bir sayı ile geri dönecektir. Bu alt rutini siz de kendi printf ("Can't open screen \n"); programlarınızda rahatlıkla kullanabilirsiniz. closestuff(); Programlarımız bu aylık da bu kadar. Gelecek ay C'de assembler rütinlerinin nasıl kullanıldığını sizlere göstereceğim. Şimdilik hepinize iyi AMIGA DÜNYASI 26