Bu kod neden calismaz????

29 replies · 15,892 views

Bu kod neden calismaz????
!to "merhabadunya.prg"
*=$c000
start:
jsr clrscr
ldx #<text1
ldy #>text1
jsr print
ldy #$40
jsr delay
ldx #<text2
ldy #>text2
jsr print
ldy #$40
jsr delay
ldx #<text3
ldy #>text3
jsr print
end:
jmp end
screen=$0400
print:
stx print+1
sty print+2
ldx #0
printloop:
lda $0000,x
sta screen,x
ldy #$40
jsr delay
inx
cpx #40
bne printloop
rts
delay:
ldx #0
delayloop:
dex
bne delayloop
dey
bne delayloop
rts
clrscr:
ldx #0
lda #$20
clrscrloop:
sta $0400,x
sta $0500,x
sta $0600,x
sta $0700,x
inx
bne clrscrloop
rts
text1:
!scr "MERHABA DUNYA"
text2:
!scr "ISTE GELIYORUM"
text3:
!scr "BANGIR BANGIR"
bu kod ekrani temizliyor ekrana bir "/" karakteri biede ici dolu kutu basiyor ve duruyor nedendir bulamadim acikcasi???*
Bu kod neden calismaz????
işte bu yüzden çalışmaz 🙂
print altrutininde x registerinin değerini delay rutinine girmeden önce saklamalısın. Çünkü delay rutinindede ldx #0 var ve delay rutini bitince yine x=0 oluyor. geri dönüşte print alt rutinindeki inx komutuyla, aslında delay rutininden geri dönüşteki x registeri değerini 1 arttırıyorsun. yani x registeri hep 0 ve 1 değerlerini alıyor. dolayısı ile printloop'a bne yaptığında x registerinde herzaman 1 oluyor. Bu yüzden text teki diğer karakterleri hiç bir zaman okuyamıyorsun ve yazdıramıyorsun.
diğer bir hata ise
print: stx print+1
sty print+2
komutları ile aslında yukardaki stx komutuna ait parametreleri değiştiriyorsun. doğrusu
stx printloop+1
sty printloop+2
şeklinde olmalıydı
bu yüzden sen ilk okuma sırasında $0000 sonra $0001 nolu adreslerin içindeki değeri ekrana basmış oluyorsun
print:
stx print+1
sty print+2
ldx #0
printloop:
lda $0000,x
sta screen,x
ldy #$40
jsr delay
inx
cpx #40
bne printloop
rts
delay:
ldx #0
delayloop:
dex
bne delayloop
dey
bne delayloop
rts
Bu kod neden calismaz????
OK simdi daha bi duzenli ama birkac sorun daha var...
bangir bangir dan sonra C karakteri basiyor ekranin sonunda kadar,kodun bu parcasini alip baska bi yerde test ettim eger karakter sayisi kadar dongu verirsem basmiyor ama karakter sayisindan fazla dongu verirse
ornegin 13 karakterlik yazim var
cpx #40 dersem kalan kismina C karakteri basiyor.
ama cpx 13 dersem probşem yok????
Burdaki C karakteri bir garip bi C onuda soliim bildigimiz C degil 🙂
Delay dongusune girmeden x degerini saklamayi ise kafamda cozemedim 🙁
Bu kod neden calismaz????
bu arada yeni başlayanlar için bir-iki bilgi vereyim.
ekranı silmek için
jsr $e544 komutu kullanılabilir.
eğer ekranı sildikten sonra farklı bir renk ile yazı yazdırmak için
lda #renk
jsr $e536 komutları kullanılabilir.
program içinde 1 mili saniye gecikme yapmak için
jsr $eeb3 komutu işinizi görür.
gecikme süresini uzatmak için
ldx #---
delay jsr $eeb3
dex
bne delay
komutlarını kullanbilirsiniz.
Bu kod neden calismaz????
Originally posted by Bakkada@Oct 2 2005, 04:31 PM
OK simdi daha bi duzenli ama birkac sorun daha var...
bangir bangir dan sonra C karakteri basiyor ekranin sonunda kadar,kodun bu parcasini alip baska bi yerde test ettim eger karakter sayisi kadar dongu verirsem basmiyor ama karakter sayisindan fazla dongu verirse
ornegin 13 karakterlik yazim var
cpx #40 dersem kalan kismina C karakteri basiyor.
ama cpx 13 dersem probşem yok????
Burdaki C karakteri bir garip bi C onuda soliim bildigimiz C degil 🙂
Delay dongusune girmeden x degerini saklamayi ise kafamda cozemedim 🙁
[post=2119]Quoted post[/post]


1- ekrana basacağın yazıların uzunluğu aynı ise cpx #uzunluk olmalı, eğer uzunlukları farklı ise eşitlemek için kısa olan yazılara boşluk eklemen gerekir.
2- Eğer programında o an için kullandığın bir register başka bir alt rutinde farklı bir değer ile yükleniyorsa, registerin önceki değerini kullanılmayan bir adrese kopyalarsın. alt rutinden çıkmadan yani rts komutundan hemen önce registere daha önce kopyaladığın değeri geri yüklersin ve rts ile alt rutinden çıkarsın. veya alt rutinden geri döndükten sonra -jsr komutundan sonra kopyaladığın değeri geri okursun. böylece alt rutine gitmeden önceki asıl değeri kaybetmemiş olursun.
Buna göre senin rutininde
ldx #0
printloop:
lda $0000,x
sta screen,x
stx sakla
ldy #$40
jsr delay
ldx sakla
inx
cpx #40
bne printloop
rts
yukarıdaki sakla yerine programa zarar vermeyecek herhangi bir adresi kullanabilirsin.
Bu kod neden calismaz????
ben şu kullanımı tavsiye ederim
screen = $0400
ldx #$00
loop lda text,x
beq out
sta screen,x
inx
bne loop
out rts
text !scr "deneme 123"
!byte 0
Gerçi bu maksimum 255 karakterlik bir text için çalışır ama olsun, şimdilik anlaman için yeterli. Text'in bittiği yerden bir sonraki byte'ı 0 yapıyoruz ve 0'a geldiyse trasferi sona erdir şeklinde kontrol ediyoruz.
Bu kod neden calismaz????
ben ayni yerlerde tax ve txa komutu kullanmayi denedim tabi olmadi 🙂
Main CPU Jam error 😛
Hmmm yavas yavas oturuo anniorum simdi....
SU programi bi bastan yazip calistiriim bakiiim
Bu kod neden calismaz????
Originally posted by Bakkada@Oct 2 2005, 05:10 PM
ben ayni yerlerde tax ve txa komutu kullanmayi denedim tabi olmadi 🙂
Main CPU Jam error 😛
Hmmm yavas yavas oturuo anniorum simdi....
SU programi bi bastan yazip calistiriim bakiiim
[post=2125]Quoted post[/post]


Daha gelmemiş olabilirsiniz o konuya, tutorialları takip etmiyorum ancak bu tür durumlarda stack kullanımı çok pratiktir. Örnek olarak X'deki değeri geçici olarak saklamak istiyorsan.
txa
pha
..
..
..
..
pla
tax
şeklinde stack'i kullanabilirsin. Stack yalnızca (illegal opcode kullanmadan) accumulator ile çalışır. Bunun dışında zeropage de güzel bir çözüm olabilir.
stx $fb
..
..
..
ldx $fb
mesela...
Stack konusuna gelmediyseniz ben daha fazla kafanı karıştırmiim. zeropage'e gelince bunlar $0000-$00ff arası hafıza adresleridir. Bu adreslerin kullanımı hafızada daha az yer kapladığı ve daha az cycle yediği için tercih edilir. Ancak $00-$ff arası tüm adresleri dilediğin gibi kullanamazsın, bazıları özel adreslerdir. Bunun için programcının el kitabı ya da Hades'in dökümanlarındaki hafıza tablolarını kurcalamanı tavsiye ederim. Bu arada elbette ki özel adres olsa da kullanmanda sakınca olmayan adresler mevcuttur. Örnek olarak RS232 üzerinden hiçbir işlem yapmayacağını varsayarak $f7, $f8, $f9, $fa adreslerini dilediğin gibi kullanabilirsin, her ne kadar normalde boş adresler olmasalar da. $fb-$fe aralığındaki adresler de zaten freedir. Ben genellikle bu adresleri kullanmayı tercih ediyorum.
Bu kod neden calismaz????
hah şöyle...
nihayet soru cevap başladı. inşallah devamı gelir.
ekrana yazı basma ile ilgili olarak bir rutinde ben yazayım. hem kısa hem hesaplı ....
lda #<text
ldy #>text
jsr $ab1e
rts
text .text "deneme 1-2-3"
.byte 0
ek bilgi : text uzunluğu max. 255 byte olabilir. ve text'in sonunda MUTLAKA 0 byte ı olmalıdır.
(çocukları gönderdim küçük odaya. 1-2 saat code kasabilirim 🙂🙂)
Bu kod neden calismaz????
bakkada, ekrana text basma konusunda yeterince bilgi edindiysen küçük bir ipucu da ben vereyim. diyelim ki uzun bir yazının 40 karakterlik, yani 1 satırlık kısmını ekrana basıyorsun. satırı ekrana bastıktan sonra text'i aldığın adresi her seferinde 1 arttırıp tekrar basarak basit bir scrolltext yapabilirsin.
Bu kod neden calismaz????
!to "yazdir.prg"
*=$C000
start:
jsr clrscr
ldy #$c0
jsr delay
ldx #<text1
ldy #>text1
screen=$0400
jsr print
ldy #$c0
jsr delay
ldx #<text2
ldy #>text2
jsr print
ldy #$c0
jsr delay
ldx #<text3
ldy #>text3
jsr print
end:
jmp end
clrscr:
ldx #0
lda #$20
clrscrloop:
sta $0400,x
sta $0500,x
sta $0600,x
sta $0700,x
inx
bne clrscrloop
rts
delay:
ldx #0
delayloop:
dex
bne delayloop
dey
bne delayloop
rts
print:
stx printloop + 1
sty printloop + 2
ldx #0
printloop:
lda $0000,x
sta screen,x
stx $0097
ldy #$c0
jsr delay
ldx $0097
inx
cpx #14
bne printloop
rts
text1:
!scr "merhaba dunya "
text2:
!scr "iste geliyorum"
text3:
!scr "gumbur gumbur "
Calisanini yazdim sonunda;MAP64'den temp data area buldum. $0097 adresiymis,oraya al-ver mantigi uyguladim calisti.Yalniz aklima takildi simdi ben her cumleyi farkli satira basmak istiyorum 🙂
Yani screeni herseferinde farkli bir degere atamak istiyorum;
TEXT1 : screen'e
text2 : screen+40
text 3 : screen+80 'e gitsin...
jsr print komutundan once screen=$0400;screen=screen+40 denedim ama olmadi 🙂
Belki de ogrendiklerimiz ile simdilik bu kadarini yapabiliyoruzdur 🙂
Kasmaya devam yardim icin tesekkurler...
Gene sorucam kacamassiniz 😛
Bu kod neden calismaz????
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.
Son bir dipnot. Varsayılan ekran adresi $0400-$07e8 arasındadır. Dolayısıyla ekranı
ldx #0
lda #$20
clrscrloop:
sta $0400,x
sta $0500,x
sta $0600,x
sta $0700,x
inx
bne clrscrloop
rts
yerine
ldx #0
lda #$20
clrscrloop:
sta $0400,x
sta $0500,x
sta $0600,x
sta $06e8,x
inx
bne clrscrloop
rts
şeklinde silersen $07e8-$07ff arasını doldurmamış olursun. Bu aralıkta spriteların hafıza konumları gibi bazı önemli bilgiler mevcuttur. Bunun için yukarda düzelttiğim gibi kullanmanı tavsiye ederim.
Bu kod neden calismaz????
putscr opcode'mudur??
Bu kod neden calismaz????
Originally posted by Bakkada@Oct 3 2005, 10:37 AM
putscr opcode'mudur??
[post=2139]Quoted post[/post]


yok yanlış anlaşılmış. Burda boşluklar ve tablar ile ilgili sorun yaşıyoruz tabii ki. putscr yalnızca bir label yani etiket. onun yerine "hede" de diyebilirsin, tabii ki ilerdeki tüm "putscr"ler yerine hede demek kaydıyla 🙂
turbo assembler, acme gibi şeylerden uzaklaşacak olursak şöyle anlatabilirim olayı. Programımız $c000'dan başlıyor diyelim ve sta $0400,x de $c036 adresinde yer alıyor
.c000 78 sei
.c001 a9 00 lda #$00
.c003 8d 20 d0 sta $d020
.c006 8d 21 d0 sta $d021
...
...
...
...
.c036 9d 00 04 sta $0400,x
...
...
şeklinde gidiyorsa hafıza adreslerinde $0400'ü 40'ar 40'ar (hex sistemde $28) arttırmak için
lda $c037
clc
adc #$28
sta $c037
lda $c038
adc #$00
sta $c038
demek gerekiyor. Yani sta $0400,x'in bulunduğu adresin bir sonrasındaki adres $0400'ün "00" bölümü onu da takip eden adres "04" kısmını birer byteda tutuyor ve biz doğrudan onları arttırıyoruz. Tabii bir de bunun için pointer kullanmak mantıklı ancak şimdi bir de ona girersem hiç çıkamayız işin içinden. Yine de Nightlord'un tutoriallarında yer alıyor olabilir. sta ($##),y olayı.
Bu kod neden calismaz????
Arkadaslar,Nightlordun dokumani no:4'u okudugumda bazi seyleri anliyamadim.Anlayamadiklarim 16 ve 24 bitlik toplama islemleri.
Su kodu yazdigimda
lda #1
clc
adc #2
sta $0400
bu kod ekranin sol ust kosesine "B" karakterini basiyor;yanilmiyorsam "2" b harfine denk geldigi icin boyle oluyor peki matematik toplama yapip ekranin herhangi bir yerine atamiyor muyuz?Yada ASM 'de toplama islemini ekrana bastirip ne mi yapicas 🙂
ama su kodu yazdigimda
lda #<1
clc
adc #<1
sta #<$00
lda #>1
adc #>1
sta #<$97
bu kod calismio.Biliorum biraz salak bi kod aslinda ama neden calismadigini bulamadim.Sanirim adresleme mantigi ile ilgili bi problem war...
16bitlik toplama ve akabinde 24 bitlik toplmama konusunda sorunlarim war mantik olarak anladim ama kod yazmaya gelince calisan kod yazamiyorum....
Hmmmm salak hissettim kendimi bir an 😠