lütfen birisi aklımı açsın :
3. chapter' ın bu kısmına kada bilgilerimi tazeledim,
defalarca okudum, danışmayacam dedim kimseye ama işte yazıyorum
1) 16 bitlik text1 yada text 2,3 etiketini 2 baytlık registerlara bölüp argüman olarak x ve y diye belirtip sora dallanıyoruz mantığını kavrayamıyorum,
2) soa copy_text e dallandığımız yerde
stx ct_loop + 1
sty ct_loop + 2
satırlarında x ve y kndini nerelere nasıl yazıyor ? (şayet böyleyse, stx in bu kullanımı kafamı karışırdı)
3) cpxle döngü neden kırka kadar sayıyor ?
kısacası halihazırda varolan text1: text2: text3: etiketlri varken argüman geçirerek bu yazıları ekrana yazdırmayı bi türlü çözemedim.
lütfen acemiye bi yardım kimse gülmesin
c64 asm yi tekrar öğrenmyi çok istiyorum :(
Saygılrımla,
skate
6th October 2005, 18:06
Originally posted by myriac@Oct 6 2005, 04:37 PM
* = $c000
lütfen birisi aklımı açsın :
3. chapter' ın bu kısmına kada bilgilerimi tazeledim,
defalarca okudum, danışmayacam dedim kimseye ama işte yazıyorum
1) 16 bitlik text1 yada text 2,3 etiketini 2 baytlık registerlara bölüp argüman olarak x ve y diye belirtip sora dallanıyoruz mantığını kavrayamıyorum,
2) soa copy_text e dallandığımız yerde
stx ct_loop + 1
sty ct_loop + 2
satırlarında x ve y kndini nerelere nasıl yazıyor ? (şayet böyleyse, stx in bu kullanımı kafamı karışırdı)
3) cpxle döngü neden kırka kadar sayıyor ?
kısacası halihazırda varolan text1: text2: text3: etiketlri varken argüman geçirerek bu yazıları ekrana yazdırmayı bi türlü çözemedim.
lütfen acemiye bi yardım kimse gülmesin
c64 asm yi tekrar öğrenmyi çok istiyorum :(
Saygılrımla,
Quoted post
2 bytelık register diye birşey yok 6510'da. Tüm olay 8 bit yani 1 byte. Ancak hafıza erişimi için kullanılan adresler 16 bit. Bu 16 biti high byte ve low byte diye ikiye ayırıyoruz. Aslında bu konuyu daha önce açıkladım copy&paste yapiim.
screen = $0400
dedikten sonra bunu screen = screen + 40 şeklinde değiştiremezsin ne yazık ki. Bunun için şunu yapman lazım.
screen = $0400
..
..
..
putscr sta screen,x
..
..
..
lda putscr+1
clc
adc #40
sta putscr+1
lda putscr+2
adc #0
sta putscr+2
..
..
..
Burda putscr adresi hafızada şu şekilde duruyor
sta $0400,x
Bu da hex codelar ile
9d 00 04
şeklinde yazılır.
9d -> sta $####,x
00 -> $0400'ün low byte'ı
04 -> $0400'ün high byte'ı
Bu durumda bizim arttırmamız gereken yer $0400'ün low byte'ı yani putscr+1
Peki ya $f0'dan sonra ne olacak? $f0 + $28 = $18 yani $0418 olur. Ancak toplamada carry flag denen bir "elde" bayrağı vardır ki adc'den önceki "clc" komutunun amacı bu bayrağı temizlemek. Çünkü o temizlenmezse toplamanın sonucu bir fazla çıkar. Örnek olarak
lda #0
adc #40
dediğimizde sonuç 40 ya da 41'dir. Tamamen carry flag'e bağlı. Ancak
lda #0
clc
adc #40
kesinlikle 40'dır. Çünkü carry flag'i temizliyoruz. Takip eden
lda putscr+2
adc #0
sta putscr+2
kısmında ise eğer bir önceki toplamada sonuç 255'i geçmediyse putscr+2 yani başlangıçta $04 olan değer değişmez. Ancak eğer sınır aşıldıysa yani $f0+$28 işleminden sonra sonuç $05 olacaktır. Bu sayede satır numaraları
lda #<satir1
sta $fa
lda #>satir1
sta $fb
lda #<stradr1
sta $fc
lda #>stradr1
sta $fd
jsr satirbas
lda #<satir2
sta $fa
lda #>satir2
sta $fb
lda #<stradr2
sta $fc
lda #>stradr2
sta $fd
jsr satirbas
lda #<satir4
sta $fa
lda #>satir4
sta $fb
lda #<stradr4
sta $fc
lda #>stradr4
sta $fd
jsr satirbas
jmp *
satirbas
ldy #$00
loop
lda ($fa),y
beq out
sta ($fc),y
iny
cpy #$28
bne loop
out
rts
satir1 !scr "bu satir ekranin en ustunde yer alacak"
!byte 0
satir2 !scr "bu ise ikinci satir olacak"
!byte 0
satir4 !scr "bu satir dorduncu satir olarak basilacak"
!byte 0
Daha pratik yöntemler var ama bu sanırım senin için "pointer kullanımı" açısından en anlaşılanı olacaktır.
lda ($fa),y
gibi bir kulanım şunu yapar. $fa adresindeki byteı low byte ve $fb adresindeki byteı high byte olarak alır ve o adrese y değerini ekleyerek o değeri accumulator'e aktarır.
sta ($fc),y
ise aynı şekilde $fc ve $fd'den aldığı hafıza adresine y ekler ve o adrese accumulator'ün değerini yazar.
diyelimki $fa, $fb, $fc ve $fd'nin değerleri şu şekilde olsun;
$fa = $30
$fb = $08
$fc = $00
$fd = $04
ve y registerında da 5 değeri olduğunu varsayalım. Bu durumda
lda ($fa),y
sta ($fc),y
demek olur ki
lda $0835
sta $0405
Bir de cpx ile döngü neden 40'a kadar sayıyor diye sormuşsun. Çünkü 64'de ekranın bir satırı 40 karakterdir ve daha fazlasını trasfer edersen ya alt satıra geçer ya da en alt satırsa ekran adresinden dışarı taşma yapar.
şu programda sadece text1' in içeriğini yazması gerekmezmi ?,
MERHABA DUNYA (cpx #13 yaparsam)
kırk karaktere kadar da diğer bazı sembolleri basması
(cpx # 40 olursa).çünkü text2 ve text3 etiketlerine REM attığımda ekran şöle oluyor :
MERHABA DUNYA@@@@@@@@@@@@@@@@@@@@ (cpx#40 iken)
toplam 40 karakter
halbuki program yukarıdaki halinde 12. satıra 40 karakter yerleştiriyor ama, text2 ve text 3 üde neden ?
yani tüm etiketler aktif ,program run ettiğimde ekran 12. satırın başından itibaren şöyle :
MERHABA DUNYA ISTE GELIYORUM BANGIR BANG
toplam 40
nasıl text2 ve text 3üde alıyor ?
halbuki kodda
ldx # < text1
ldy # > text1
jsr copy_text
sadece bunlar var..
skate
7th October 2005, 09:31
@myriac: evet çok güzel bir noktaya gelmişsin ve hemen hemen herşeyi anlamışsın. Tek bir nokta kalmış, labelların (etiketlerin) sanal yaratıklar ve sadece basit referans kaynakları olduğunu tam anlamamışsın.
Yazılan herşey yazıldığı sırayla hafızaya alınır. Kısacası "rts" den sonra gelen;
satırları "rts"nin bulunduğu hafıza adresinden itibaren byte byte hafızaya yerleşir. Örnek olarak "rts" $c050 adresinde yer alıyor diyelim. Bu durumda rts'den sonraki adresler şu şekilde sıralanacaktır.
$c051 -> m
$c052 -> e
$c053 -> r
$c054 -> h
$c055 -> a
$c056 -> b
$c057 -> a
$c058 -> *
$c059 -> d
$c05a -> u
$c05b -> n
$c05c -> y
$c05d -> a
$c05e ->
$c05f -> i
$c060 -> s
$c061 -> t
$c062 -> e
$c063 -> *
$c064 -> g
$c065 -> e
$c066 -> l
$c067 -> i
$c068 -> y
$c069 -> o
$c06a -> r
$c06b -> u
$c06c -> m
$c06d ->
$c06e -> b
$c06f -> a
$c070 -> n
$c071 -> g
$c072 -> i
$c073 -> r
$c074 ->
$c075 -> b
$c076 -> a
$c077 -> n
$c078 -> g
$c079 -> i
$c07a -> r
Şimdi text1, text2 ve text3'ün ne olduğuna gelelim.
text1 = $c051
text2 = $c05f
text3 = $c06e
yani hafıza adreslerini tutuyor o labbellar yalnızca. Sen
Bu işlemi yaptığında "lda $0000,x" satırı "lda $c051,x" olarak değişecektir. Bu da ne demek? $c051'den itibaren kopyala demek. Yani o "text2" nedir bilmez ve "text2"ye gelince de herhangi bir sebepten durmaz. Ancak baştaki satırları
ldx # < text2
ldy # > text2
şeklinde değiştirecek olursan ordan itibaren okuyup ekrana basmaya başlar. Bu program belki de labellar açısından biraz kafa karıştırıcı ancak benim gönderdiğim örnekte birden fazla labelın farklı satırlara nasıl bazıldığını görebilirsin, bir daha incele istersen.
incelememi istediğin örneğinde;
bana sadece bu satırlarla ilgili açıklama değilde, ipucu verir misin ?
birde "pointers & c64" ilgili kaynak gösterebilir misin ? (yerli yabancı farketmez)
Quoted post
En üstteki satır basicden;
0 sys 2061
satırının bytelara dökülmüş hali. PC'de COM dosyaları $0100 adresinden execute edilirler örneğin. c64'de ise execution biraz farklı çalışan bir sistemdir. RUN denildiği zaman $0801'den itibaren yazılmış olan BASIC codeları çalışır. Eğer programımız Assembler ile yazılmışsa (ki bu durumda öyle) ona SYS ile jump ederiz. Kısacası o başlangıçtaki bytelar bir tür Autostart işlemi için bulunuyorlar. Aksi taktirde code'u yükleyip RUN dediğinde code çalışmazdı. Sen kendin SYS xxxx şeklinde kodun başladığı satıra giderdin. Code $080d'den başlıyorsa bunun decimal karşılığı olan 2061 bizim başlangıç satırımızdır. Dikkat edecek olursan;
jsr $e544 ekranı temizler. jsr $e536'da aynı işi yapar ancak ek olarak accumulator'deki değeri renk değeri olarak kabul ederek ekranı temizler. Bu yüzden
lda #$01
jsr $e536
dediğimizde tüm ekran 1'in renk kodu olduğu beyaz renk ile temizlenir. Kısacası bundan sonra ekrana yazdırdığımız yazılar beyaz olarak yazılacaktır.
* karakteri adres belirtir. örnek olarak;
* = $080d
diyoruz biliyorsun.
c000 jmp $c005
c003 lda #$02
c005 sta $d020
gibi bir kod olduğunu varsayalım. Bunu ACME'de satır numarası kullanmadan.
jmp *+5
lda #$02
sta $d020
şeklinde yazabiliriz örneğin. Yani "*" bulunduğun yer anlamına gelir. *+3, *-7 gibi kullanımlar mümkümdür. Örnek olarak;
ldy #$03
dey
bne *-1
dersen hafızaya şu şekilde yerleşecektir.
c000 ldy #$03
c002 dey
c003 bne $c002
bu bağlamda;
jmp *
demek
c000 jmp $c000
yani sonsuza dek kendine git, programdan çıkma demek. Ekrana birşeyler yazdırdıktan sonra "ready." yazısı yazılanları bozacağı için "rts" ile programdan çıkmak yerine programı kilitlemeyi uygun buldum.
Gelelim son soruna. Tahmin ediyorum Hades'in c64 Türkiye'de açıklanmıştır.
http://www29.websamba.com/c64turkiye/ (TR)
Yoksa bile C=Hacking Magazine'de "yok yok" olduğuna göre o da vardır :)
Bkz: http://www.ffd2.com/fridge/chacking/ (EN)
Nightlord da o konuya gelmediyse henüz yakında gelecektir. Bkz:
http://nightlord.dr2.net/ (TR)
nightlord
9th October 2005, 00:43
selam myriac
butun sorularini skate hali hazirda cevaplamis zaten. su an sen yeni bir soru sorana kadar benim de soyleyebilecegim baska bisey yok. fakat cpx #40 bolumuyle ilgili bi aciklama yapmam lazim.
aslinda kodda text1 2 ve 3 mesajlarinda tirnak isaretlerinin arasinda toplam 40 karakter olacak sekilde bosluklari ayarlamistim. fakat blog bi sekilde webde spaceleri temizliyor (ard arda gelen n tane bosluk karakteri bir bosluk karakterine indirgeniyor) bu yuzden sen yalniz text1 bastirmaya calisirken elindeki programda 40 karakterlik bolgeye diger iki mesaj da sigiyor. ayni sebepten normalde oralarda bosluk var.
ne yaptiysam sitemde bbcode ile code modifierini calistiramadim. bu yanlis anlama buradan geliyor.
yakinda kursta gecen kodlari .a64 uzantili dosyalar olarak koyacagim siteye boylece fixed width font kullanan bi editorler acinca daha okunakli seyler goreceksiniz.
lda #<satir1
sta $fa
lda #>satir1
sta $fb
lda #<stradr1
sta $fc
lda #>stradr1
sta $fd
jsr satirbas
satirbas
ldy #$00
loop
lda ($fa),y
beq out
sta ($fc),y
iny
cpy #$28
bne loop
out
rts
satir1 !scr "bu satir ekranin en ustunde yer alacak"
!byte 0
aslına bakarsanız sizlere karşı bu defa yazılı düşünme gereğini hissettim:
bir özet yapacak olursam :
yukarıdaki örnekte;
stradr1 = $0400
stradr2 = $0428
stradr4 = $0478
öncelikle bu üç satırla, videomatrixte karakterlerin basılacağı satır numaraları hex adres tanımları olarak atandı.
en alttaki satir1 etiketinin 2 byte 'lık hex adresi
lda #<satir1
sta $fa
lda #>satir1
sta $fb
koduyla;
küçük byte aküye sonra fa adresine
büyük byte aküye sonra fb adresine yazıldı.
ve ;
lda #<stradr1
sta $fc
lda #>stradr1
sta $fd
koduyla satır adresleri
küçük byte aküye sonra fc adresine
büyük byte aküye sonra fd adresine yazıldı.
ve jsr satirbas
burada y register ındaki 00 değeri indexli olarak lda (fa),y kullanımından doğan ardışık adreslere indexli olarak eklenip aküye atıldı.beq satırı out etiketine henüz gitmiyor çünkü sanırım y deki değer 28 değil.(AMA ŞUNU ANLAMADAIM BEQ kendinden önce gelen son satıra göre işlem yapmıyormu ? yani beq burda hangi karşılaştırmaya ait dallanma sağlıyor ?) ve sta ($fc),y satırıyla fc,fd ye yazılmış olan stradr1 in adres değeri yerinden itibaren aküdeki değeriyle basıldı. y 1 artırıldı 28 e eşit olasaya kada döngü döndü.
anlatımım biraz karışık olabilir, ama beq satırı haricinde anladım (mı) sanırım. :)
satir1 !scr "bu satir ekranin en ustunde yer alacak"
!byte 0
birde burada "!byte 0" napıyor onu anlamadım.ve son sorum fa,fb,fc,fd, adresleri c-64 te null' mı? fe,ff de böylemi ? başka böle boş adresler var mı?
bu arada izmir hatay b.evler de oturuyorum.
saygılarımla,
skate
9th October 2005, 20:53
"cmp" komutu olmadan "beq" sıfıra eşitse anlamına gelir. ordaki "!byte 0" da oraya gelince "beq"nun tetiklenmesi için var.
lda #$00
beq $c030
rts
bu kod "rts"ye gelmeden $c030 adresine gider
lda #$0a
beq $c030
rts
bu ise "rts"ye gider çünkü değer 0'dan farklı.
lda #$0c
cmp #$0c
beq $c030
rts
burda ise $0c ise $c030'a git demiş oluyoruz ki ytine $c030'a gider
lda #$00
cmp #$0c
beq $c030
rts
burda ise $00, $0c'ye eşit olmadığı için "rts"ye ulaşır kod.
beq "eşitse" anlamına gelir. tersi "bne"dir yani "eşit değilse"...
şimdi çıkmam lazım evden, daha sonra detayını anlatırım.
nightlord
9th October 2005, 21:24
BEQ 'o anda status registerdeki zero flag 1 ise dallan' anlamina gelir
BNE de 'o anda status registerdeki zero flag 0 ise dallan' anlamina gelir
bazi komutlarin yaptiklari islemlerin sonucu olarak status registerdeki flagler etkilenirler. kursun birinci bolumunde ve yine sitede bilgisayar mimarisine giris bolumunde status registeri hakkinda yazilanlara tekrar goz atmak isteyebilirsin. bu etkilenme yalnizca zero flag de degil carry overflow ve negative flaglerinde de olabilir. ancak her komut her flagi etkilemeyebilir. bazi komutlar hicbir flagi etkilemeyebilir
herhangi bir registere yukleme komutu (lda ldx ldy) status registerdaki zero flagi etkiler. yuklenen deger 0 ise zero flag 1 olur. 0'dan farkli ise zero flag 0 olur.
keza adc sbc lsr asl and ora eor gibi aritmetik ve mantiksal islemler (yani ALU tarafindan yapilan islemler) de status register flaglerini etkiler. bu islemlerden sonra sonuc 0 ciktigi zamanlarda zero flag 1 olur.
yine karsilastirma komutlari olan cmp cpx ve cpy de status register flaglerini etkiler. bu uc komut aslinda karsilastirilan iki deger arasinda cikarma islemi yapar fakat sonucu saklamaz. ama status registerdaki flagler sanki bir cikarma islemi yapilmiscasina etkilenir.
dolayisiyla mesela
lda #10
cmp #10
dedigimizde 10 - 10 islemi 0 oldugu icin zero flag 1 olur. ancak sonuc saklanmaz. yani bu satirlardan sonra A'sa hala 10 kalacaktir 0 degil.
bundan sonra kullanilacak beq komutu bu yuzden esitlik halinde dallanma yapar.
ben aslinda henuz indirect indexed adresleme modunu henuz anlatmadim (lda (xx),y) . bir ara insallah konu oraya gelecek :) bu yazdigin programdaki temel mantik okunulan yazinin degisken uzunlukta olmasina izin vermesi. yani onceki programdaki cpx #40 gibi sabit uzunlukta karakter kopyalamak yerine bu program karakterleri saymadan kopyaliyor. ancak her kopyaladigi karakter 0 mi diye kontrol ediyor. cunku buradaki tasarimda 0 baytina ozel bi anlam yuklenmis. 'kopyalamayi durdur' anlamina geliyor. dolayisiyla textin bittigi yere bir adet ilave 0 bayti koyarsak, programimiz 0a kadarki karakterleri kopyalayip 0'i gorunce duruyor. boylece degisik uzunluklarda text mesajlarini mesaj 0 ile bitmek kosuluyla bu programa verebiliyoruz. iste !byte 0 komutu mesajin harflerinin bellege dizildigi adreslerin en sonuna bir adet 0 degeri yerlestiriyor. bununla ilgili olarak dun koydugum acme ve etiketler konusuna bakmak isteyebilirsin.
BEQ komutu da programda kopyalanan karakterler A'ya okunup ekrana gonderilmeden once 0 degeri okunmus mu diye bakmak icin kullanilmis. yani BEQ komutu once hangi komutlarin calistigini bilmiyor. o anda status registerdaki zero flage bakiyor. ama once calisan komutlar da ayni flagi etkiledikleri icin program calisiyor. fakat bu komutlarin illa cmp cpx cpy olmasi gerekmiyor. status registeri etkileyen baska komutlar da amacimiza gore beq'dan once kullanilabilir.
skate
10th October 2005, 11:15
Galiba henüz tutoriallarda gelinmeyen konulara atladım. Eğitimi iyice karıştırmiim. Sustum :)
myriac
10th October 2005, 21:03
:) , skate harikaydı yaa....
ve de nightlord ; "acme ve etiketler" konusunu açman muhteşem,