Retrojen Forum
Dijital Sanat => Kodlama => Konuyu başlatan: wizofwor - 28 Aralık 2013, 11:00:18
-
Diyelim ki oyunumu bitirdim. En son iş ekrana puan yazmaya geldi. İki baytlık bir alanda skoru tutuyorum. Bunu ekrana basmak için pratik bir yöntem var mı?
Aklıma gelen ilk çözüm skoru bodoslama sürekli 10'a bölerek decimal'e çevirmek. Sonra'da ekrana basılacak karakter kodlarını hesaplamak.
Biraz daha pratik olabileceğini düşündüğüm çözüm. Skor için 4-5 baytlık alan ayırarak hafızada decimal değeri saklamak. (Toplama yaparken sonucu 9 ile karşılaştırıp, 9'dan büyükse bir sonraki byte'ı arttırmak vs..)
Dip not: C64 özelinde bu iş için kernel rutinleri vardır diye tahmin ediyorum. Belki de enayilik mi ediyorum ama kernel rutinlerini kullanmak istemiyorum.
-
Evet bu gayet can sıkıcı bir problemdir. Başa çıkmak için benim önereceğim iki yol var:
- 6510'un BCD modunu kullanmak. Bu modda toplama çıkarma vs ondalık düzende çalışır. o zaman her nibble da bir basamağa denk geleceği için kolayca ekrana basılabilir
- Eger normal hexadecimal kullanacaksan o zaman birkaç tablo ile skor yazdırılabilir. Bu bahsettiğin 10'a bölme işleminden daha hızlı olur. Ancak skor eğer bir bayttan daha büyük olabilecekse o zaman tablo metodu gümler (çok belleğe malolmaya başlar veya karmaşıklaşır) o durumda art arda bölme metodu daha yavaş ama daha dayanıklı ve esnek bir çözüm olur.
- mutlaka Basic ROM'da bir yerlerde de kullanılabilecek şeyler vardır. Ben bilmiyorum.
-
- mutlaka Basic ROM'da bir yerlerde de kullanılabilecek şeyler vardır. Ben bilmiyorum.
Basic Romda $BDCD adresi senin işini görür.
LDA Lo-byte
LDX Hi-byte
JSR $BDCD
...
0-65535 arasını yazdırabilirsin.
-
Skoru onluk sistemde değil de oyunda beklenen maksimum skorun basamak sayısı kadar byte bilgisi olarak kaydetsen ve ekranda skoru yazılacağı adreslere POKE X,48+n gibi her basamağı yazdırsan en pratik olacak sanki. 48+N dan kasıt, ASCII değeri olarak 48="0", 49="1"... gibi.
Dediğin gibi, her basamak için INX ile o byte'ı arttırıp 9 a gelince sıfırlayıp diğer basamağa geçmek gibi bir işlem.
Böylece oyun sonunda yazdırmak değil de oyun esnasında ekranda skoru görüntüleyecek bir bölgede sürekli güncellemek de mümkün.
-
10'a bölme? 10000,1000,100 ve 10 çıkartarak saymaca :D
25213 olsun rakam:
a=0
(25213-10000) >0 a++ geriye 15213
15213-10000>0 a++ kaldı 5213
(5213-10000) >0 ? değil, [a=2], ilk decimal haneyi bulduk. a'yı bir yere kaydedip, 10000'i geri ekleyip 1000'liklere geçelim:
a=0
(5213-1000) >0? doğru a++
...
şeklinde sıra sıra 10k,1k,100 ve 10 çıkartarak tüm haneleri bulmaca.
Tabii z80'de 16 bit registerler var, bir de SBC komutu var. Bu iş kolay oluyor 3-4 komutla çıkıyor. 6502'de de çok zor olacağını sanmıyorum.
z80'de çok kabaca şöyle olur:
ld hl, <hiscore> ;2 byte'lık hi score 0-65535 arasında
ld bc, <string adresi> ;bu adrese 5 byte'lık bir char string oluşturacak
ld de,10000
call hanebul
ld de,1000
call hanebul
ld de,100
call hanebul
ld de,10
call hanebul
hanebul:
xor a ;a=0
haneloop:
or a ;C flag reset
sbc hl,de ; hl-de
jr c, sonrakihane ; <0?
inc a ;a++
jr haneloop ;loop
sonrakihane:
add 48 ;ascii tablosuna göre "0"=dec 48 (c64'ünkü farklıydı sanırım)
ld bc,a ;char'ı ram'e yaz
inc bc ; indeksi ilerlet
adc hl,de ;son çıkarılan rakamı geri ekle
ret ;bu hane bitti, sonraki haneye geçelim
bu işlem sonucunda "string adresi" lokasyonunda 5 byte boyunca decimal gibi görünen string çıkacak, bunları bir şekilde yazdıracaksın işte. :)
kafadan yazdım, çalışmıyordur büyük ihtimal, ama fikir verecektir.
edit: kod denemesi eklendi, wizofwor bahane edilerek z80 pratik edildi :D
-
Olayı 10-15 satır kodla çözüvermişsin. Etkilenmedim desem yalan olur. Tuşları vs. sağlam speccy nasıl buluruz. Piyasası nedir?
-
Dediğin gibi, her basamak için INX ile o byte'ı arttırıp 9 a gelince sıfırlayıp diğer basamağa geçmek gibi bir işlem.
Böylece oyun sonunda yazdırmak değil de oyun esnasında ekranda skoru görüntüleyecek bir bölgede sürekli güncellemek de mümkün.
Sanırım oradaki sorun birden fazla değerde skor işlemi için ciddi loop tutulmak zorunda kalır. Yani diyelim ki, skora 553 eklemek için gerçekten de 553 iteration gerekiyor. Senin yöntem sadece 1 puan kazanmaca varsa pratik olabilir.
Olayı 10-15 satır kodla çözüvermişsin. Etkilenmedim desem yalan olur. Tuşları vs. sağlam speccy nasıl buluruz. Piyasası nedir?
Ahem, efendim latife ediyorsunuz. Ama 16bit register işi gerçektende kıyak.
Bu soru ciddi ise, piyasada iki çeşit speccy var: 1.Sağlam speccy, 2. arızalı-sağlam speccy :) Görüldüğü üzere bozuk speccy diye birşey yoktur :)
Sağlam ya da arızalı-sağlam, ederi 50-75 lira arasındadır. Yakında enflasyon hortlayabileceği için fiyatın yükselme trendine girdiğini tahmin ediyorum.
Sorunsuz bir speccy isterseniz +2 gri model tercih edilmelidir, tuşları asla bozulmaz, çok dayanıklıdır, o da aynı fiyattadır.
-
Tabi ki haklısın, her skor artımı için bir hareket gerekiyor önerimde.
-
konu hortlatma durumu...
Bugün tesadüfen buna denk geldim:
https://groups.google.com/forum/#!topic/comp.sys.apple2.programmer/NpfRXsf2T0s
Steve Wozniak'ın appleII için yazdığı binary->decimal çeviricisi. Normalde birsürü vardır ama bir woz kodu olduğu için buraya koymak şarttı.
BCD kullanımı, nightlord'un önerdiği şey. Derginin kendisini de aradım ama ilgili sayıyı bulamadım malesef.
şurada bazı sayıları var:
ftp://ftp.apple.asimov.net/pub/apple_II/documentation/magazines/apple_orchard
*
HEX0 EQU 0 BINARY ARGUMENT (LOW BYTE)
HEX1 EQU 1
DEC0 EQU 2 (LOW BYTE)
DEC1 EQU 3 DECIMAL RESULT
DEC2 EQU 4 (HIGH BYTE)
*
ORG $300
OBJ $6300
*
HEXDEC LDA #0
STA DEC0 CLEAR RESULT (EXCEPT HIGH BYTE).
STA DEC1
SED SET 6502 DECIMAL MODE.
LDY #16 PREPARE FOR 16 BITS.
LOOP ASL HEX0
ROL HEX1 SHIFT BIT OUT OF BINARY ARGUMENT.
LDA DEC0
ADC DEC0
STA DEC0 DOUBLE DECIMAL RESULT.
LDA DEC1 (PLUS CARRY)
ADC DEC1
STA DEC1
ROL DEC2 SHIFT IN LAST BIT.
DEY REPEAT 16 TIMES/
BNE LOOP
CLD ;CLEAR DECIMAL MODE.
RTS RETURN.
SYM
--- END ASSEMBLY ---