Makine Dilinin Püf Noktaları

Hepinize merhaba. Uzun bir süredir devam eden ve şimdilik bitmeye hiç de niyeti olmayan bir Püf Noktaları bölümünde birlikteyiz yine. Bu sayıda, her zaman olduğu gibi, normal olarak bir C64'ün yapamayacağı işlerden birini seçtim. Ama hatırlatmakta fayda var: Benim burada anlattığım programlar, yaptıkları işi en hızlı ve en etkili şekilde yapan programlar olmayabilirler. Bu köşede asıl yapmaya çalıştığım, C64'ün, belli bazı gruplar dışında kimsenin bilmesine izin verilmeyen yeteneklerinden sizleri haberdar etmek ve bu yetenekleri kullanmak için ne gibi bir mantık izleyebileceğinizi anlatmak. Neyse çenem düştü gene. Biz en iyisi asıl konumuza dönelim. Aslında bu ay seçtiğim iki konu var. Bunlardan birincisi, ABUR-CUBUR köşesine girmesi gereken bir program ve size bir teknik açıklamaya değil, hayatınızı kolaylaştırmaya yönelik.

Piyasada bulabileceğiniz bazı kartuşları kullanıyorsanız (EXPERT gibi), ekrana yazdığınız scroll text'leri veya ekranda bulunan datalarını belleğin bir köşesine zahmetsizce atabilirsiniz. Ama diyelim ki bu kartuşlardan edinmek istemiyorsunuz veya kartuşunuz bozuldu. Ekrana yazılanları belleğe nasıl transfer edersiniz? Ekranı doldurmadan önce, bu transferi yapacak bir makine dili programı yazarsınız, sonra yazılarınızla ekranı doldurursunuz, yazılar bitince de, ekranı yukarı kaydırmayacak bir yerden SYS komutuyla, ekranı transfer edersiniz. Bu her zaman yapabileceğiniz kolay bir işlem. Peki, tam yirmi beş satırlık bir ekranı transfer etmek isterseniz ne yaparsınız? Ekranın herhangi bir yerine SYS yazamayacağınız (kayan yazıların ortasından SYS'nizin geçmesini istemezsiniz değil mi?) için, değişik yöntemler aramanız gerekecektir. İlk bakışta benim aklıma tek yol gelmişti, fakat bu yazıyı yazarken, daha az teknik olan, fakat yine de işe yarayabilecek bir yöntem geldi aklıma. Önce bir yöntemi anlatayım, sonra ötekini anlatırım. Birinci sistemde, her zaman yaptığınız gibi, transfer işlemini yapacak bir makine dili programı yazın. Sonra BASIC'e dönüp şu satırı girin:

1 INPUT A$:SYS programbaşı

RUN dedikten sonra ekranı temizleyip yazacaklarınızı yazın ve ekran dolunca da RETURN'e basın. Makine dili programınız otomatik olarak çalışacaktır. Ama bu sistemi denemediğim için, bazı hatalar çıkabilir. En iyisi, kısa bir örnekle deneyin bu sistemi. İşe yararsa ve sizin de kolayınıza gelirse bu sistemle ekran transfer edersiniz. Eğer BASIC kullanmak istemiyorsanız (Ekrandaki yazıları BASIC alanına transfer edeceksiniz özellikle) bilgisayarınızın değişik bir özelliğinden yararlanmanız gerekir: NMI'lar. Bildiğiniz gibi NMI, Non Maskable Interrupt, yani engellenmez interrupt'lardır. Diğer bilgisayarlarda, bu interrupt'ı kullanmak için, mutlaka donanım kullanmanız gerekmektedir, fakat C64'te RESTORE tuşuna basmanız bir NMI oluşmasını sağlar. Eğer Programcının El Kitabı'nı dikkatlice okuduysanız, $0318-$0319 adreslerinde NMI vektörlerinin bulunduğunu fark etmişsinizdir. Yani, bu vektörleri programınızı gösterecek şekilde ayarlarsanız, RESTORE'a basıldığında istediğiniz işi yapabilirsiniz. Tabii bu arada programınızdan sağ salim çıkmayı da başarmak da sizi oldukça zorlayacaktır. Her şeyden önce, programı RTS değil, RTI ile terk etmeniz gereklidir. NMI, herhangi bir anda bilgisayarın işini baktırıp kendi işini göreceği için, programınızda kullandığınız tüm register'ların ilk durumlarını saklamanız gereklidir. Bu işin tam olarak nasıl yapıldığını aşağıdaki programda görebilirsiniz.

Programdan da gördüğünüz gibi, ilk olarak $0318-$0319 adreslerine programımızın adresini alçak-yüksek bayt (low-high byte) formatında veriyoruz ($02ab için $AB, $02 gibi) ve BASIC'e dönüyoruz. Herhangi bir anda RESTORE'a basıldığında, $800B'de bulunan programımıza sıçranıyor. İlk olarak, programda kullanılan Y, A register'larını yığına kaydediyoruz, sonra $0400-$07FE arasını $4000'e transfer ediyoruz ve yığında bulunan değerleri register'lara aktarıp, BASIC'e dönüyoruz. Basit, değil mi? Bu ayın asıl konusu, C64'e ekran başlangıç satırını unutturmak. Aslında çok zeki gibi görünen C64'ünüz bir miktar aptaldır. Ufak bazı hileler kullanarak, border sınırına geldiğini unutturup ekranın alt ve üst kısımlarını açtırabilir (Gelecek sayılardan birinde bunu da açıklayacağım, sabırsızlanmayın.), ekranın başlangıç yerini unutturabilir, ilk satırı 12. satırda, ikinci satırı 20. satırda gösterebiliriz. Ufak birer tasarım hatası olan bu tür boşlukları bulursanız, azıcık da yaratıcılığınızı kullanırsanız, dehşet demo teknikleri üretebilirsiniz. Bu sayıda açıklayacağım rutinin neden çalıştığını anlayabilmeniz için; rutini anlatmadan önce, C64'ün karakterleri ekrana nasıl bastığı hakkında bir miktar ön bilgi vermem gerekiyor. Bildiğiniz gibi, C64'ün karakter ekranı, her biri 40 karakterden oluşan 25 satırdan meydana gelir ve normal olarak $0400 (1024) adresinden başlayarak 1000 bayt işgal eder.

Bilgisayarınız, belli raster satırlarına geldiğinde ($D011 register'ının değeriyle oynamadıysanız, $33, $3B, $43, $4B, ... raster satırlarında) o anda işletilmekte olan komutla işi biter bitmez kontrolü eline alır ve $0400'den bulunduğu satırın kırk katı kadar ileride bulunan kırk baytı okur (satırın 0. satır olduğunu kabul ederek tabii ki). Yani, $33 raster satırına gelindiğinde $0400-$0427 baytları okunur ve karakterleri gösteren devreye iletilir. Tabii ki bu işi yapmak için neredeyse tüm satır boyunca sizin komutlarınızın işletime girmesini engeller. Yazıda ne hakkında konuştuğumu anlatmaya çalışırken satırlar harcamaktansa, şu andan itibaren bu raster satırlarına DMA (Direct Memory Access — doğrudan bellek erişimi) satırları diyeceğim. DMA satırlarına bu adın verilmesinin sebebi, bu satırlarda bilgisayarınızın, makine dili komutlarınızı kısa bir süre için bir kenara bırakıp, doğrudan bellekten değer okumasıdır. İleride daha gelişmiş rutinleri (FLI, veya flex rutinleri gibi) açıklarken bu konunun daha detaylı kısımlarını inceleyeceğim. Bu konuyu bu sayıda daha fazla deşebilecek kadar yerimiz yok ne yazık ki. Zaten bu sayıyı ilgilendiren kısım, $D011 adresinin ilk üç bitiyle ilgili. Eğer, adresinin ilk üç bitinin değerleriyle oynarsanız, ekran normalde başladığı yerden daha aşağıda görünecektir. Fakat bu işlemi genelde tüm ekranı içerecek şekilde yaptığınızdan, çoğunuz bu satır kaydırma işleminin yalnızca DMA satırlarının yerini değiştirdiğini bilmez. Yani bu özelliği kullanarak bir satırı ortasından ayıramazsınız. Bunu yapacak (daha doğrusu yapması gereken) rutini hazırladığınızda, ilk satırın bir yerden tekrar gösterildiğini göreceksiniz (şanslıysanız... Çok daha garip şeyler olabilir). Sizin yapmaya çalıştığınız şey, 2. pikselden sonrasını 3 piksel aşağı kaydırmak olsun. $34 (ikinci piksel bu satırda bulunur) raster satırında $D011 adresine $1B-$43-$1E değerini vermeniz gerekir. Ama bu rutini çalıştırdığınızda yaptığınız tek iş, DMA satırını $33'den $36'ya almak olur. Sonuç olarak C64'ünüz normalde $33'de gösterilmeye başlanan satırı henüz göstermediğini sanır ve $36'ya geldiğinde bu satırı tekrar göstermeye girişir. Yani ekranda bir buçuk tane birinci satır elde edersiniz. Eğer aynı şeyi 5. satırın bulunduğu yerde yapmaya kalkarsanız, elde edeceğiniz şey yarım beşinci satır ve yeniden başlayan ekran değil, bir buçuk beşinci satır olacaktır. Fakat, DMA satırından bir önce, DMA satırının yerini değiştirirseniz ($D011'in değeriyle oynayarak), örneğin $42 raster satırından DMA satırını $45'e alırsanız, $43'de yeni bir satır gösterilmeye başlanmayacak, $45'e kadar olan bölge boş bırakılacaktır. Aslında tam olarak “boş bırakılacaktır” da diyemeyiz çünkü $3FFF adresinin değeri, burada siyah renkle gösterilir (ne demek istediğimi anlamaya çalışmaktansa deneyin ve görün). Yaratıcılığınızı kullanırsanız burada da çok iyi bir demo'luk malzeme görebilirsiniz. Fakat şu anda size bu konuda hiç bir şey söyleyemeyeceğim. Düşünün ve ne yapabileceğinizi bulun... Bizim ekranı kaydırmamız da tam olarak yukarıda anlattığım rutinin mantığını kullanıyor. Yani ilk DMA satırından bir önce ($32 raster satırından) başlayarak, DMA satırını normalden bir aşağı satırda gösteriyor. Daha sonraki satırda da girerek DMA satırını bir aşağı daha alıyor ve bu işlem, kaç satır kaydırmak istiyorsanız o kadar devam ettiriliyor. Sonuçta, ekranımız istediğimiz kadar piksel aşağıdan başlayabiliyor. İsterseniz bu konuyu kafanıza iyice yerleştirmek için, bu sayfada bir yerlerde bulabileceğiniz program listesine bir göz atın. Daha sonra, programın açıklamasını okuyun. Aslında program $C000 adresinden başlıyor, fakat zaten hepinizin bildiği (en azından bu yazıyı takip edenlerinizin) IRQ giriş rutinini yazmaya gerek yok. Fakat rutini incelediğinizde, bu kısımda $FE'ye 1 değerini verdiğimi görünce şaşırmayın diye söylüyorum: $FE, ekranın kaç piksel aşağı kaydırılacağını tutan adrestir ve ilk IRQ sırasında ekranın garip bir yere gitmemesi için bu değeri en başta ayarlamanız şarttır. Gelelim rutinin kendisine. İlk olarak, $FE'nin 0 olup olmadığı kontrol ediliyor ve değeri sıfır ise ekran hiç kaydırılmadan rutinin sonuna sıçranıyor. Eğer bu kontrolü yapmazsak, $FE'yi azaltarak 0'a ulaştırmaya çalışan rutinimiz, $FF bayt kaydırmayı deneyecekti ekranı. Bu kontrolü X register'ında yaparak, $FE'nin değerini doğrudan sayıcımıza almış da oluyoruz. Buradan sonra yaptıklarımız, demin anlattığım gibi bilgisayarınızı hep bir alt satırda olduğuna inandırmak için gerekli. Bir alt satırda olduğunu söyleyen değeri $D011'e yerleştirdikten sonra, bu değeri bir artırıp, ikinci satırı beklememiz gerekir. Fakat böyle bir sayıcı zaten bilgisayarınızda bulunuyor. Evet doğru tahmin ettiniz. RASTER satırını gösteren $D012'de bir sayacımız bulunuyor. Eğer bu adresin değerinin ilk üç bitini yazarsak istediğimiz işi yaptırmış oluruz. Eğer bir monitör programı yardımıyla $D011'in değerini alırsanız $1B olduğunu görürsünüz. İlk üç biti dışında $18 değeri bulunur $D011'de (25 satır-karakter ekranı olduğunu belirtmek için). Biz de $D012'den aldığımız ilk üç biti (AND üç biti izole ediyoruz) $18 ile OR'luyoruz. Fakat, $D011'i ekranın en solundan başka yerlerde değiştirmeye kalkışırsak sonucu tam bir felaket olacağı için (kontrolsüz yapıldığı zaman özellikle), yeni satır gelene kadar bekliyoruz (eski satırın değeri

Y'de bulunuyor. Ve biz $D012'nin değeri Y'ye eşit olduğu sürece beklemede kalıyoruz.) ve ilk iş olarak demin hesapladığımız değeri $D011'e yazarak DMA satırını bir aşağı alıyoruz. Aslında bu program, benim tembelliğimden dolayı tam olarak çalışmıyor. Yani 1 satır kaydırılması gerekirken, beş-altı satır kaydırıyor. Çünkü $D012'nin değerini doğrudan doğruya ele aldığımızda, DMA sadece bir satır kaymıyor. İlk olarak $38 gibi kontrolsüz (ve şu anda hesaplamaya üşendiğim) bir raster satırından başlıyor ekran. Oysa, $D012 değerine CLC ADC $07 komutlarıyla 7 eklesek ve AND, OR işlemlerini daha sonra yapsak, ilk DMA satırı tam olarak $34 raster satırına denk gelecekti ve bir satır kaydırmak istediğinizde, ekran bir satır kayacaktı. Program çoktan baskıya gittiği için bu hatayı düzeltmeyi size bırakıyorum. Programımıza geri dönelim. Bu $D012'yi $D011'e taşıma işlemi $FE'de belirtilen kadar satır yapıldıktan sonra, ekranın 9. satırını sabit bir noktaya getirecek olan rutine giriş raster satırını belirliyoruz. Oynayan satır sayısı sekiz olduğuna göre, 88 - 64 = $40'ı $FE'nin değerine ekliyor, bu değeri de interrupt'a giriş raster satırı olan $2E'ye ekliyoruz. Bu hesapla yaptığımız iş $FE'de belirtilen miktar kadar kaymış olan ekranın sekizinci satırının son pikselinin, raster satırı olarak yerini belirlemek. Bu sayede, bu noktadan başlayarak, dokuzuncu satırı belirli bir noktaya kadar kaydırabiliriz, ama önce ikinci interrupt'un programına bir bakın...

Dokuzuncu satırı 46 piksel + 64 piksel (sekiz karakter satırının uzunluğu) aşağıda sabitlemek için, $FE'yi 46'dan çıkarıyoruz ve dokuzuncu satırın daha kaç piksel aşağı kaydırılması gerektiğini buluyoruz. Sonra, aynı satırda yaptığımız işlemleri tekrarlayarak, dokuzuncu satırı 100. raster satırına indiriyoruz. Son olarak da $C100'den başlayan sinüs tablomuzdan yeni değeri okuyup $FE adresine yazıyoruz ve interrupt vektörlerini, ilk interrupt rutinini gösterecek şekilde ayarlıyoruz. İyi de neden programı iki ayrı interrupt'a ayırdık? Yani arada sadece sekiz satırın geçmesini beklesek daha kolay olmaz mıydı? Eh, aslında daha kolay olurdu, fakat tam 64 raster satırı çöpe atmış olurduk. Oysa iki ayrı interrupt haline getirince, aradaki 64 raster satırını müzik çalarak, ekranın altında yazı kaydırarak, v.b. değerlendirebiliriz. Son bir şey daha: Bu programı kullandığınızda, ekrandaki satırların yerinin değiştiğini sakın unutmayın. Ekranda artık yirminci veya yirmi-

birinci satırınız yok. Onların yerini alan diğer satırlarda işlem yaparak ekranın altındaki efektleri (kayan yazı, sallanan logolar, v.b.) elde edersiniz. Eh, C64'ünüzü dolandırmak oldukça kolaymış değil mi? Bu yazıdan sonra hâlâ kafanızda soru işaretleri kaldıysa, Ek'inde bulacağınız programı yazın ve üzerinde oynayarak, neyin ne olduğunu anlamaya çalışın. Buna rağmen kafanıza takılan yerler olursa, dergiye benim adıma mektup yollayarak sorularınızı belirtmekten çekinmeyin. Şimdiye kadar oldukça çok interrupt tekniğini ele aldık. (Ekranda sekiz'den fazla sprite göstermeye çalışan arkadaş, mektubunu aldım, fakat şu anda o konuya giremeyecek kadar başlarındayız yazının. Bir süre sonra MULTIPLEXER'ların (ekranda sekiz'den fazla sprite gösterme rutinine verilen ad) mantığını da açıklayacağım. İlgine teşekkürler.) Fakat şu anda bile konu seçiminde zorlamaya başladım. Eğer öğrenmek istediğiniz intro teknikleri varsa, yapılan efekti açık bir şekilde anlatan (mümkünse programın kendisini de gönderin) bir mektup yollayın dergiye, gelecek sayılarda bu istek konularına da yer vereceğim. Gelecek sayıya kadar hoşçakalın.

Modem Nedir?

Biz iki arkadaşız ve ikimizde de Commodore 64 var. Modem kullanmak istiyoruz fakat bazı sorularımız var, eğer yardımcı olursanız çok seviniriz. Sorularımız kısaca şöyle: 1- Modem Commodore'un neresine bağlanıyor? 2- Ben oyunu yüklerken arkadaşımda da yükleniyor mu? 3- Bir Modem sistemi ne kadar tutar? 4- Özel bir kabloya ihtiyaç var mı? 5- Bende bir Destek 64 kartuşu var ama bir türlü makine diliyle yazılan programları yazamıyorum. Nasıl kullanmam gerek?

Sayın Modem kullanıcıları, Mektupta isminiz geçmediği için sizlere bu şekilde hitap etmem gerek. Gelelim Modem problemlerinize: 1- Modem genellikle Commodore'unuzun USER PORT'una bağlanır, fakat bazı modelleri değişik sistemlerle çalıştıklarından dolayı farklı portlara bağlanabilir. 2- Modem kullanırken iki tarafından da aynı anda program yüklemesi olası değildir, Modemler telefonlar arası program ve data alış-veriş işlemlerinde kullanılır. Arkadaşınızla modem aracılığıyla haberleşebilir veya birbirinize program yollayabilirsiniz. Hatta modem ile modem hattı bulunan Commodore kulüplerine üye olarak oradan da program alabilirsiniz. 3- Modem fiyatları hakkında pek fikrim yok; fakat Türkiye'de sadece bir-iki model bulunuyor. Bunların fiyatları için ise üreten ya da satan firmaya telefon etmeniz gerekmekte. 4- Modemler telefon aracılığıyla çalıştığından dolayı ekstra kabloya ihtiyaç yoktur. 5- Destek 64 kartuşunuzda monitör programı bulunmuyorsa makine dili programları yazamazsınız. Bunun için bir monitör programı edinmelisiniz. Dergimizdeki programlar içinse M.D.E. kullanmalısınız. Önümüzdeki sayılarımızdan birinde bu konuyu detaylı olarak inceleyeceğiz. Dergimizi takip etmeye devam edin.

Program Kopyalamak

Size sormak istediğim birkaç sorum var. 1- Disketten kasede ya da kasetten diskete program çekilebilir mi? 2- C-64'ün hafızası artırılabilir mi? Artarsa ne kadar? 3- Bir disketten diğerine kopya yapmaya yarayan “TURBO COPY” programını nasıl temin edebilirim? 4- Derginizde açıklamaları yapılan oyunların çoğu AMIGA için, Bu programların C-64 versiyonu var mı? Ömer Faruk Anlı

Sayın Ömer Faruk Anlı, Disketten kasede program çekmek için ne yapabileceğinizi soruyorsunuz, bu demektir ki dergimizi yeterince detaylı okumuyorsunuz. Daha geçtiğimiz sayı başlayan TURBO-LAR adlı bölüm sadece bu konu üzerinedir. Commodore'un hafıza arttırımına gelince, Commodore'unuzun 64 K olan hafızasına en fazla 512 K daha eklenebiliyor. Fakat bunun için gerekli kartuş henüz Türkiye'de bulunmuyor. Ya dışarıdan getirtmeniz ya da gelmesini beklemeniz gerekiyor. TURBO COPY programı içinse yetkili bayilere başvurmalısınız. Aynı program olmasa bile başka bir kopya programı aynı işi görecektir. Dergimizde açıklamaları yayınlanan oyunlar ise genellikle AMIGA'da çözülüyor ve yazılıyor ve genelde çoğunun Commodore 64 versiyonu mevcut, bunları öğrenmek içinse program satan yetkili bayilere başvurmalısınız.

Döküm Eki

Derginizi ilgiyle okuyor ve bütün programları yazıyorum fakat bazı problemlerim var; 1- Döküm ekinizdeki altı veya üstü çizili harfler ne anlama geliyor? 2- “JUNGLE” oyununun açıklamasının tamamını tekrar açıklar mısınız? 3- Benim ve 15 arkadaşımın disk sürücüsü yok, biraz da teyp ile yüklenebilen oyunlar yayınlar mısınız? 4- Tanıttığınız oyunların AMIGA ya da C-64 oyunu olup olmadığını belirtebilirseniz seviniriz.

Edirne, C-64 sınıfı adına Selçuk İslamoğlu Sayın Selçuk İslamoğlu, Dergimizi ilgiyle izlemenize sevindik, bu arada programları yazmanız da çok iyi. Eğer bu programlarla ilgileniyorsanız bir de Program Döküm Eki'nde yer almakta. Sorularınıza gelince: 1- Döküm ekinde yer alan altı çizik karakterler SHIFT ile, üstü çizili olanlar ise COMMODORE ile birlikte basılmalıdır. Tabii abone olursanız bunlara ihtiyaç kalmıyor. 2- İstediğinizi yerine getirmek maalesef mümkün değil. Tek yapabileceğiniz o açıklamanın yer aldığı eski sayıyı elde etmek olacaktır. 3- Kasette çalışan oyunlar için pek fazla bir şey yapamayacağız, çünkü bize açıklama getiren yazarlarımız genelde AMIGA kullanıyor. Fakat yayınlanan oyunların çoğunun C-64 kaset versiyonları mevcut. 4- Tanıttığımız oyunlarda genellikle hangi bilgisayar olduğu belirtilir fakat yukarıda da belirttiğim gibi birçok oyun artık birkaç versiyonda piyasaya çıkıyor ve değişik bilgisayarlarda aynı oyunu bulmak mümkün.

Basic ve Makine Dili

Ben BASIC dilinden anlamama karşın Makine Dili hakkında en ufak bir bilgim yok. Makine dilinde programları aynen yazıp RUN ediyorum fakat bilgisayar hata veriyor. Bunlara satır no'su verdim sonuç yine aynı. Bu konuda yardımlarınızı bekliyorum, ya da bir kitap ismi yazarsanız çok memnun olurum.

Onur Berkup

Sayın Onur Berkup, İlk olarak makine dilinin BASIC ile hemen hemen hiç benzeşmediğini söylemeliyim. Bu tür programları yazmak için ya bir ASSEMBLER ya da bir assembler programına ihtiyacınız var, çünkü bu tür programlar bir editör programı olmadan yazılamazlar. Bazı assembler programları bir BASIC editörü gibi çalıştığında satır numaraları ile yazabiliyorsunuz. Fakat bu türlerini pek tavsiye edemeyeceğim. Öğrenmek için ise genelde yabancı dilde yazılı kitaplar mevcut. Bu tür kitapları bulmak oldukça kolay. MACHINE CODE öğreten programlar için yabancı yayın satan kitapçılara uğramanızı tavsiye ederim.