TEYP TURBOLARI

Hepinize merhaba, 64'çüler! Bu sayıda da, teyp turbosu yaratmanın inceliklerini açıklamaya devam ediyoruz. Hatırlayacağınız gibi, geçen sayıda ekranı kapatmaya ihtiyaç duymadan yükleme yapabilen basit bir turbo programını satır satır incelemiştik. Aslında bu turbonun tek özelliği açık ekranla yükleme yapabilmek değil, fakat diğer özelliklerinin kullanılması gelecek sayıdan başlayarak anlatacağım. Bu sayıda daha öncelikli bir konu olan turbo korumalarından söz etmek istiyorum. Şu anda piyasada bulunan birçok turbo kolay yollarla kırılamayacak kadar iyi korunmuştur. Fakat bu turbolar -belki de nasıl çalıştığı anlaşılmasın diye- pek piyasaya dağıtılmaz. Yani kendi programınızı korumak için tamamen kendinize güvenmek zorundasınız. Ama yeterince kaynak kitabınız yoksa, basit kırma yöntemlerini engellemek için bile bol miktarda ter dökmeniz gerekir. Bu sebeple, “Teyp Turboları” yazısında, turbo koruma yöntemlerine de değinmek istedim. Aslında, bu konu biraz “modası geçmiş” bulunabilir. Çünkü herkesin elinde dolaşan kırıcı kartuşlar, ne yazık ki program kopyalanmasını çok kolay hale getirdi. Fakat, günlerce uğraşarak yarattığınız bir turbonun meraklı bir programcı tarafından iki saniyede kırılmasını görmektense, bu yazıya birkaç dakikanızı ayırmayı tercih edeceğinize eminim. Şu anda çoğu turbo düşmanının, program kırmak için kullandığı standarda yakın sistemler vardır. Her kırıcı ilk olarak şu komutları verip programı yüklemeyi dener:

POKE 43,0
POKE 44,192
POKE 2048,255

Bu komutlardan ilk ikisi, normalde $0801 (2049) adresinde bulunan BASIC programının başka bir adreste bulunduğuna inandırmaktadır bilgisayarınızı, (Örnekte 49152). Son komut ise neden bilgisayara eklendiğini hiçbir zaman anlayamadığım bir özellikten yararlanmak için kullanılır: Eğer BASIC başlangıç adresinin bir eksiğinde 0'dan farklı bir değer varsa, RUN komutu programınızı çalıştırmaz. Neyse ki bu adreslerin işlevlerini sadece kırıcılar değil, biz de biliyoruz. Böylece, turbomuz çalışmaya başlamadan önce bu adreslerin değerini normale çevirirsek acemi kırıcıların işini bozmuş oluruz. (Biz bu adreslerin düzeltilmesi işini Kernal'a bırakacağız gene de.) Biraz daha deneyimli programcılar, klavyeden girilen, veya program satırlarında bulunan komutların Kernal'a $0073 (115) adresinde bulunan bir kısa programcıkla iletildiğini bilirler. Tabi ki bu bölüm RAM'de yer için, üzerinde yapılacak ufak bir değişiklikle, klavyeden girilen komutları işletime sokup, BASIC'e ait olanları ciddiye almaması sağlanabilir. Dergimizin ilk sayılarında yayınlanan bir program bu işi yapmaktaydı zaten. Ama, bu numarayı da öğrendiğimize göre, bu programın artık işe yaramayacağı açıktır. Turbobaşında Kernal'da bulunan başka bir rutine sıçrayarak bu yöntemi kullanmayı deneyenleri de hayal kırıklığına uğratabiliriz. Bütün bunlara rağmen, turbo koruma programımızın gücü üç-dört adresin değerini düzeltmekten gelmiyor. Bu turbonun asıl özelliği, en zor şartlarda dahi bu adresleri düzeltmesini sağlayacak olan kısmı çalıştırabilmesi. Normalde, oto-run programların kullandığı adresler, yeterince etkin bir şekilde Turbonuzun çalışmasını sağlayamazlar (Bu geçen sayıda verdiğimiz turbo için de geçerli). Çünkü, programı kasede kaydetmeden önce, bellekteki asıl yerine kopyalama zorunluluğu vardır ve yeterince güçlü adresler, belirlenen adrese, kasede kayıt yapılmadan önce sıçranılmasını sağlar. Fakat, C-64 KERNAL'ını yeterince inceleyenler bilirler ki, bir programı yükleneceği adrese taşımadan da kasede veya diske kaydedebilirsiniz. Fakat böyle bir rutin yazmanın bedeli, Jsr $FFD8 komutuyla yapabileceğiniz işi çok daha fazla komutla yapmaktır. Hatta “Press Record & Play on tape” mesajını yazdıracak rutin olan $F838 adresine bile sizin sıçramanız gerekecektir. Bu rutin için kullanmanız gereken iki ayrı adres daha vardır: $F76A ve $F67C, $F76A adresi, program adının, başlangıç ve bitiş adreslerinin ve yüklenecek olan data tipinin (Basic, Makine dili, vb.) bulunduğu kayıt başlığını (header) kasede kaydeder (program yüklenmeden önce başlık kısmı yüklenir ve sadece datalardan oluşan ikinci kısmın nereye yükleneceği gibi bilgiler buradan elde edilir). $F67C adresindeki rutin de başlık kısmını kaydetmeden, belirtilen alanı kasede kaydeder. Başlık ve data kısımlarını ayrı ayrı kasede kaydedebildiğimize göre, programın $02A7 adresine yükleneceğini bildirdikten sonra, $CD40 adresindeki programı ve koruma kısmını kasede kaydedebiliriz. Bu sayede, programınızın kayıt öncesi çalışma ihtimali tamamen ortadan kalkacaktır. Bu kayıt işlemini yapan rutin aşağıda gördüğünüz gibidir:

5 LDA #$01
5 CC35 TAX
 CC36 TAY
., CC37 JSR $FEFBA
., CC3A LDA #$10
CC3CLDX #SDA
., CC3E LDY #$CD
., CC40 JSR $FEFBD
5 CC43 LDA #$A7
3 CC45 LDY #$02
., CC47 STA $Cİ
., CC49 STA $C2
 CC4B LDA #$56
LDY #$04
., CC4AF STA $AE
., ÖC51 STA $AF
CC53 JSR $F838
.,CC56 LDA #$03
., CC58 JSR $F7GA
., CC5B LDA #$40
., LDY #$CD
CC5F STA $CI
,,CC61 STY $C2
., CC65 LDY #$CE
. CC67 STA $AE
., CC69 STY $AF
., CC6GB JSR $F67C

Programdan da anladığınız gibi, ilk olarak normal kayıt yapacakmış gibi SETLES ($FFBA) ve SETNAM ($FFBD) adreslerine sıçrayarak, kaydın kasede yapılacağını ve $CDDA adresinden başlayan $10 baytlık bir başlık bulunacağını bilgisayara bildiriyoruz. Dikkat ettiyseniz, bu turboda geçen sefer yaptığımız gibi programın yarısını başlığa eklemedik (uzunluğu $10'dan fazla vererek). Bunun sebebi, başlık kısmında bir korumamızın bulunmamasıdır. Yani FOUND yazısından sonra basılırsa, programın en önemli yarısı ortaya çıkacaktır. Bunun yerine, $0351'deki parçayı da $02A7'den başlayan parçayla birlikte kaydediyoruz. Fakat bunu yapmak için yüklenen IRQ interrupt vektörünün $EA31'i değil, $F92C'yi göstermesini sağlamamız gereklidir. Aksi takdirde, programımızın $0316'dan sonrası yüklenmeyecektir. Buradan sonra, normal bir SAVE işlemi için gereken işlemlerden sapmalar başlıyor. İlk olarak, $C1-$C2 adresine, kaydedilen program yüklenirken, hangi adresten başlayacağını alçak-yüksek bayt (low-high: $02A7 yazmak için, $C1'e $A7, $C2'ye $02 değerleri verilir) formatında yazıyoruz. Yüklenecek programın bitiş adresini de yine aynı formatı kullanarak $AE-$AF adreslerine yazıyoruz. Bundan sonra, $EF038 adresine sıçrayarak, RECORD ve PLAY'e basılmasını bekliyoruz. Başlık kısmını kaydetmeden önce yüklenecek olan data tipinin makine dili programı olduğunu, akümülatör'e (A registeri) $03 değerini yükleyerek belirtiyoruz. Artık $F76A adresine sıçrayabiliriz. Böylece başlık kısmını kasede kaydetmiş olduk. Şimdi de kaydedilecek data kısmının belleğin neresinde olduğunu bilgisayara bildirmemiz gerekiyor. Bunun için de datanın şu anda bellekte başladığı yer olan $CD48'i $C1-$C2 adreslerine demin yaptığımız gibi yerleştiriyoruz. adreslerine de son baytın adresini verdikten sonra, $F67C adresine sıçrayarak data kısmını da kasede kaydediyoruz. Artık turbosuz kısmın (yükleyici; loader) kaydı tamamen yapıldı. Turbolu kısmın nasıl kaydedildiğini geçen sayıda detaylı olarak anlatmıştım. Fakat güvenliğiniz açısından, turbonun başında aranan $40 serisinin ve ondan sonra gelen $5A baytının değerlerini değiştirmeyi unutmayın (yükleyicide de aynı değerleri değiştirin!!). DİKKAT: $40'ın yerine içinde yalnızca tek bir bit bulunduran bir bayt yazın ($01, $80, $20 gibi). Bu sayede, eskiden yaptığınız korumasız turboların yükleyicileriyle (loader'larıyla) korunmuş programınızın yüklenmesini engellersiniz.

., CCE6 LDY #$40
€CE8 LDA #S04 ;Bu Baytı değiştirin
CCEAJSR $CCF6
€CEDDEY
CCEE BNE
LDA #$91 ;Bu Baytı Değiştirin
» CCF2 JSR
CCESIRTS
x CMP #$04 ;CCE9'dakiyle aynı
., CE03 BNE $CEOE
CMP #$04 ;CCE9'dakiyle aynı
CEİ7 BEÇ
CE19 CMP #$91 ,CCF1'dekiyle
., CEİB BEÇ $CE24

Peki hangi adreslerin değerini değiştirerek, bilgisayarınızın ısrarla programınızı çalıştırmasını sağlarsınız? Bunu yapmak için genelde $0300'dan başlayıp, $0334'e kadar süren, içinde çok hayati rutinlerin adreslerini bulunduran yerlerden yararlanırsınız. Bu adresler ve yaptıkları işler şöyledir: $0302-$0303: BASIC warm start. READY yazıldıktan sonra kullanıcıdan komut alan ve imleci ekrana çıkaran rutinin başlangıç adresi. Genelde sadece bu adres kullanılır.

$0306-$0307: BASIC LIST. LIST komutunun rutininin başlangıç adresi burada bulunur. Kullanmak pek de gerekli değildir. $0316-$0317: BRK interrupt vektörü. Bir BRK komutuyla karşılaşılırsa sıçranacak adres burada saklanır.

$0318-$0319: NMI interrupt vektörü. NMI interrupt'ı oluşturulduğunda (mesela RESTORE tuşuna basıldığında) sıçranacak adres burada saklanır.

Buradan sonra gelecek olan KERNAL vektörlerinin hepsinin bizim rutini göstermesi şart değildir. Fakat kırıcının gözünden kaçan bir vektör bile kullanıldığı zaman yükleyicinize sıçrayacağı için, kırıcıya zor anlar yaşatacaktır. $031A-$031B: KERNAL OPEN vektörü. $031C-$031D: KERNAL CLOSE vektörü. $0320-$0321: KERNAL CHKOUT vektörü. $0322-$0323: KERNAL CLRCHN vektörü. $0326-$0327: KERNAL CHROUT vektörü. Bu adresi her zaman kullanmanızı öneririm. Çünkü bilgisayarınız ekrana herhangi bir şey yazmak istediğinde bu vektörün gösterdiği yere sıçrayacaktır. $0328-$0329: KERNAL STOP vektörü. Bu vektörü kesinlikle kullanmayın. LOAD işlemi sırasında durmadan bu vektörün gösterdiği adrese sıçranır. Eğer değiştirirseniz, yükleme tamamlanmaz. $032C-$032D: KERNAL CLALL vektörü. $0330-$0331: KERNAL LOAD vektörü. $0330-$0332: KERNAL SAVE vektörü,

KERNAL LOAD

Bu bölgenin nasıl düzenlendiğini aşağıda görebilirsiniz:

Bu vektörlerin gösterdiği adreste bulunan rutinlerin neler yaptığını size anlatmayacağım, çünkü konumuzun biraz dışında. Merak eden arkadaşlar gerekli bilgiyi “Programcının El Kitabı” adlı Teleteknik yayınında bulabilirler. Buraya kadar, bir yükleyiciyi nasıl kendiliğinden çalışabilir ve kolay kolay çalışması engellenemez hale getireceğinizi anlattım. Buradan sonra da, yükleyicinizin başına ne tür korumalar koyabileceğinizi anlatmaya çalışacağım. Yükleyicimizin uzun olması sebebiyle, hem ilk parçanın çalışması için bozduğumuz adresleri düzeltmeye, hem de yüklenecek olan programı korumaya pek yerimiz kalmıyordu. Bu sebeple, yükleyicinin bazı parçalarını ekranın başı olan $0400 adresine yerleştirmeye karar verdim. $0400'de bulunan program parçası şöyledir:

43-44 adreslerini KERNAL rutinleri kullanarak düzelteceğimi söylemiştim, ama bu rutinin 43-44 için gereken değerleri $0281, $0282 adreslerinden okuduğunu belirtmemiştim. Gerçekten de çoğu kişi bu adreslerin kullanılabileceğinden haberdar değildir ve KERNAL kullanarak 43-44'ü düzelttiğini sanır. Fakat $0282'ye 255 değerini veren bir kişi kolaylıkla bu korumayı atlatabilir. Bu sebeple öncelikle bu adreslere almaları gereken değerleri vermemiz gerekir. KERNAL'da ilk kullandığımız rutin $E3BF adresinden başlıyor. Bu rutin, 43-44, 2048 adreslerini düzeltiyor ve $0073'de bulunan rutini normal haline çeviriyor. İkinci sıçradığımız adres olan $E453, daha çok önceden bozduğumuz adresleri temizlemeye yönelik çalışıyor. Bu arada, yığını da temizleyerek, bilgisayarın yüklemeye girişimden önce nerede kaldığını unutmasını sağlıyor. Daha sonra, basit kartuşları engelleyebilecek bir adrese sıçrıyoruz. $FD02 adresinden döndükten sonra, sıfır bayrağı (zero flag) temizse (reset) problem yok demektir. Ama eğer sıfır bayrağı kalkmışsa (set) $8004 adresinde CBM80 yazılı demektir (birileri RESET yapıldığı zaman kendi rutinini çalıştırmak istiyor diyebiliriz). BNE komutumuz, RESET'in engellenmediği durumlarda $041D'ye atlanmasını sağlar. RESET engelini farkedip, $FD50 adresine sıçradığımızda, $0200-$0400 bölgesi olduğu gibi temizleniyor ve bilgisayar kilitleniyor. $041D'den sonrasında, geçen sayıda anlattığımız işlemler yapılarak turbo çalışmaya hazır hale getiriliyor. Bu kısımda daha birçok değişik zorluk çıkarabilecek yeriniz var. Yapabileceğiniz hinliklerden bir kaçını burada sıralayım:

1) Engelleyemediğiniz kartuşlara suikast düzenleyebilirsiniz. Yani, belleği birbirini tutmayan, ilgisiz bir sürü sayıyla doldurabilirsiniz ($0801- $FFF7 arasını doğal olarak). Bu sayede hem bellekte olabilecek bir program parçacığını yok edersiniz, hem de tüm korumaları atlatan kartuşların, kayıt sırasında programı fazla sıkıştıramamasını sağlarsınız.

2) NMI vektörünü bir RTI'yı gösterecek şekilde ayarladıktan sonra, yapay olarak bir NMI yaratırsınız. Bu sayede EXPERT kartuşunun daha ileri gitmesini engellersiniz. Bunu yapabilmek için, $DD0E'ye $11 verdikten sonra sırasıyla $DD0E'ye ve $DD0D'ye $83 değerini girmeniz gereklidir. Bunlardan başka, engelleyebildiğiniz tüm kartuşları engelleyin. (Bu arada eğer arkadaşlarınızla kartuş engelleme sistemlerinizi paylaşmak isterseniz, dergimize kullandığınız yöntemleri açıklayan bir mektup yollayın.) Neyse, konuyu fazla dağıttık. Gene rutinin açıklanmasına dönelim. $0400'de işimiz bittikten sonra

$02A7'de bulunan programa da sıçrıyoruz. Burada bulunan program ise şöyle:

Ne yazık ki $0300'ü tamamen düzeltecek bir rutin bulmaya vaktim yok. Bu sebeple, geri kalan değerleri kendim düzeltiyorum. İlk başta kullandığımız rutin ($E453) yalnızca $030B'ye kadar olan adreslerin yerini normale çeviriyordu. $0324'den sonrasının değerleri $FD30 adresinden bulunabildiği için, bu değerleri $0314'e taşımakta zorlanmazsınız sanırım. Daha sonra sıçrayarak hem ekranı, hem de koruma programımızı bellekten temizliyoruz. Böylece bu aşamadan sonra programa müdahale edecek kişiler, ne tür korumalar kullandığımızı asla öğrenemeyecekler. Daha sonra da bildiğimiz şekilde programın yüklenmesini sağlıyoruz. Burada son bir şey daha söylemek istiyorum: Programınızın koruma kısmında elinizden geldiği kadar çok standart dışı komut kullanın. Mesela $F4 kodlu bir komutu monitör programınız büyük bir ihtimalle “227” şeklinde gösterecektir. Fakat program içinde bu komutla karşılaşıldığında 2 bayt süren bir NOP olarak işlem yapılır. Herhangi bir programda birden fazla bayttan oluşan (örneğin Jsr $E453) bir komutun başına $F4 $A9 baytlarını eklerseniz, programın büyük bir kısmı saçma sapan bir şekilde görünecektir. Fakat işleyişinde herhangi bir değişme olmayacaktır. Bu tür standart dışı komutların tam listesini 15. sayımızın Döküm Eki'nde bulabilirsiniz. Gelecek sayımızda, turbomuzun asıl önemli özelliği olan interrupt yükleme'den nasıl faydalanabileceğimizi anlatacağım. Fakat, bu aydan sonra, tekrar turbonun korunmamış halini kullanacağım. Çünkü, korunmuş bir programı incelemek sizin için oldukça zor olabilir (özellikle yeterli destek programınız yoksa). Daha sonra, bu yazıda gösterdiğim yöntemleri kullanarak turbonuzu istediğiniz gibi kullanabilirsiniz. Gelecek aya kadar hoşçakalın. 19

Vedat Hallaç