Originally posted by myriac@Oct 6 2005, 04:37 PM
* = $c000
jsr clear_screen
ldy #$40
jsr delay
ldx # < text1
ldy # > text1
jsr copy_text
ldy #$80
jsr delay
ldx # < text2
ldy # > text2
jsr copy_text
ldy #$c0
jsr delay
ldx # < text3
ldy # > text3
jsr copy_text
end:
jmp end
clear_screen:
ldx #0
lda #20
cs_loop:
sta $0400,x
sta $0500,x
sta $0600,x
sta $0700,x
inx
bne cs_loop
rts
screen = $0400 + (12*40)
copy_text:
stx ct_loop + 1
sty ct_loop + 2
ldx #0
ct_loop:
lda $0000,x
sta screen,x
inx
cpx #40
bne ct_loop
rts
delay:
ldx #0
d_loop:
dex
bne d_loop
dey
bne d_loop
rts
text1:
!scr "merhaba dunya "
text2:
!scr "iste geliyorum "
text3:
!scr "bangir bangir "
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,
[post=2198]Quoted post[/post]
[/b]
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ı
$0400
$0428
$0450
$0478
$04a0
$04c8
$04f0
$0518
$0540
..
..
..
$07c0
şeklinde devam eder.
bir de şu alıntı işine yarayabilir, pointerları da kapsıyor çünkü.
= $0801
!byte $0b, $08, $00, $00, $9e, $32, $30, $36, $31, $00, $00, $00
!to "test.prg"
stradr1 = $0400
stradr2 = $0428
stradr4 = $0478
* = $080d
lda #$01
jsr $e536
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
[/b]
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.
Bunları bir oku önce gerisini tekrar tartışırız.
Originally posted by myriac@Oct 7 2005, 09:49 PM
!byte $0b, $08, $00, $00, $9e, $32, $30, $36, $31, $00, $00, $00
lda #$01
jsr $e536
jmp *
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)
[post=2222]Quoted post[/post]
[/b]
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;
!byte $0b, $08, $00, $00, $9e, $32, $30, $36, $31, $00, $00, $00
Bak byteların içersinde geçiyor 2061...
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/ (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/ (http://www.ffd2.com/fridge/chacking/) (EN)
Nightlord da o konuya gelmediyse henüz yakında gelecektir. Bkz:
http://nightlord.dr2.net/ (http://nightlord.dr2.net/) (TR)