HEXADECIMAL VE ASCII MEMORY DUMP
Retro bilgisayar;=======================================================================================;
; hexadecimal ve ascii memory dump programı
;
; C64 TÜRKİYE dergisi sayı 8 için hazırlanmıştır
;
; 10-05-2005 / ismail "hades" şahin
;
; hades@amigaturk.com
www.c64turkiye.com www.amigaturk.com c64turkiye@amigaturk.com ;
;=======================================================================================;
*=$0801
prg
.word nextline
.word 2005
.byte $9e
.text "2061"
.byte 0
nextline
.word 0
start etiketli yere kadar olan kısımda LIST komutuyla göreceğiniz 2005 SYS2061
satırını oluşturuyoruz.
start
lda
#$0d
;yeşil renk kodu
jsr
$e536
dex
stx
$d020
stx
$d021
stx
$fb
stx
$fc
Yukarıdaki bölümde karakter rengi yeşil olacak şekilde ekranı siliyoruz ve ekran silindikten sonra X registerinin değerini 1 azaltarak "0" yapıyoruz. Bu değeri $D020 ve $D021 adreslerine vererek ekran renklerini siyah yapıyoruz. Ayrıca daha sonra kullanacağımız $FB ve $FC adreslerini sıfırlıyoruz. lda #<text1 ldy #>text1 jsr $ab1e lda #$3a jsr $ffd2 lda #$24 jsr $ffd2
Önce ekrana biraz yazı yazıyoruz sonra ":" ve "$" karakterlerini basıyoruz. adres_gir jsr hex_byte_in sta $fc ;high bayt jsr hex_byte_in sta $fb ;low bayt
Bu bölümde ilk önce adresin HIGH baytını klavyeden girip $FC adresine saklıyoruz.
Sonrada LOW baytını girip $FB adresinde saklıyoruz.
ldy
#$00
ldx
#$06
clc
jsr
$fff0
Yukarıdaki komutlarla kursörün yerini belirliyoruz. Y registerine kursörü koyacağımız yerin sütun değerini, X registerine ise satır değerini vererek Kernal Rom’daki PLOT rutinine sıçrıyoruz.
C64 TÜRKİYE #8 5
lda
#<text2
ldy
#>text2
jsr
$ab1e
lda
#<text3
ldy
#>text3
jsr
$ab1e
Ekrana birşeyler yazdırıyoruz ve asıl bölüme geçiyoruz.
dumper
lda
#$10
sta
line
Ekranda bir seferde kaç satır gösterileceğini ayarlıyoruz.
line_dump
lda
#$20
jsr
$ffd2
lda
$fc
jsr
mem_to_scr
lda
$fb
jsr
mem_to_scr
lda
#$3a
jsr
$ffd2
lda
#$20
jsr
$ffd2
Önce bir adet "boşluk" basıyoruz. Programın başında girdiğimiz adresin önce HIGH
baytını, sonrada LOW baytını hex olarak ekrana yazdırıyoruz. Son olarak ":" ve "boşluk"
karakterlerini basıyoruz
one_line_dump
ldy
#$00
loop1
lda
($fb),y
sta
temp_scr,y
jsr
mem_to_scr
lda
#$20
jsr
$ffd2
iny
cpy
#$08
bne
loop1
Bu bölümde bir satıra hex dump yapıyoruz. Y registerini sıfırlayıp bayt sayacı olarak kullanıyoruz. LDA komutuyla hafızadan o anki baytı alıyoruz ve geçici olarak saklıyoruz. Hafızadan okuduğumuz baytı JSR komutuyla HEX formatlı olarak ekrana yazdırıyoruz. Ekrana bir baytı yazdırdıktan sonra bir adet "boşluk" basıyoruz. Y registerini (bayt sayacı) 1 arttırıp 8 ile karşılaştırıyoruz. 8 olmadıysa hafızadaki bir sonraki bayt için LOOP1 etiketli yere sıçrıyoruz. 8 olduysa program aşağıdan devam ediyor. ascii ldy #$00 ascii_dump lda temp_scr,y cmp #$20 bcc no_ascii cmp #$60 bcs no_ascii .byte $2c no_ascii lda #$2e jsr $ffd2 iny cpy #$08 bne ascii_dump
Burada ise daha önce hafızadan okuyup geçici olarak sakladığımız baytların varsa ascii karşılığını ekrana yazdırıyoruz. İlk olarak Y registerini sayaç olarak kullanmak üzere sıfırlıyoruz. Sakladığımız ilk baytı alıyoruz. Önce "boşluk" karakterinden küçük olup olmadığını kontrol ediyoruz. Eğer küçükse "no_ascii" yazan yere gidiyoruz ve ekrana
C64 TÜRKİYE #8 6 "." karakterini basıyoruz. Eğer okunan bayt "boşluk" karakterinden büyükse bu sefer (Å) karakterinden büyük olup olmadığını kontrol ediyoruz. Eğer büyükse yine "no_ascii" yazan yere gidiyoruz. Eğer küçükse yani okunan bayt $20-$60 arasındaysa ekrana basıyoruz. Fakat burada $2C bayt'ı bilgisayarı kandırmak için kullanıyoruz. $2C değeri "BIT" komutunun kodu olup kullandığı parametre 2 baytlıktır. Bu parametreler ise "no_ascii" yazan yerdeki "LDA #$2E" komutunun baytlarıdır. Dolayısıyla "BIT $A92E" gibi bir komut yazmış oluyoruz. Bu durumda komut sırası .... BCS NO_ASCII - BIT $A92E - JSR $FFD2 şeklinde olmaktadır. Dolayısıyla Aküdeki değer değişmemiş olmakta ve bu değerin ASCII karşılığını yazdırmış oluyoruz. Normalde "no_ascii" yazan yere gelindiğinde Aküye $2E değeri yüklenmektedir ve $2E'nin ascii karşılığı "." karakteridir. Bu nedenle hafızadan okunan baytların ascii karakter karşılığı yoksa "." basılmaktadır. Bu işlemleri 8 defa tekrarlıyoruz ve sonra program aşağıdan devam ediyor. new_line lda #$0d jsr $ffd2
Yukarıdaki iki komutla bir alt satıra geçiyoruz.
mem_setup
lda
$fb
clc
adc
#$08
sta
$fb
bcc
no_inc_fc
inc
$fc
no_inc_fc
dec
line
bne
line_dump
Bu bölümde ilk olarak hafızadan okuyacağımız yeni yerin adresini hesaplıyoruz. $FB adresinde okuma yaptığımız adresin LOW baytı bulunmaktadır. Bu adresteki değeri 8 ile toplayıp geri yazıyoruz. (Her seferinde 8 bayt okuduğumuz için 8 ile topluyoruz). Toplama sonucunda elde biti varsa (yani sonuç 255'ten büyükse -"C" biti "1" ise-) bu sefer $FC adresindeki HIGH baytı bir arttırıyoruz. Eğer elde biti "0" ise yani sonuç 255 veya küçükse "no_inc_fc" yazan yere gidiyoruz. Burada ise daha önce tanımlamış olduğumuz ekranda bir seferde gösterilecek satır sayısını bir azaltıyoruz. “0” olmadıysa “line_dump” yazan yere gidip ekranda 16 satır gösterilinceye kadar işlemleri tekrarlıyoruz. f_keys jsr $ffe4 cmp #$85 ;F1 - Sonraki sayfa beq next_page cmp #$86 ;F3 - Önceki sayfa beq old_pages cmp #$87 ;F5 - Yeni adres beq restart cmp #$88 ;F7 - Çıkış bne f_keys jmp $a474 ;Basic'e geri dön restart jmp start next_page .byte $2c old_pages dec $fc ldy #$00 ldx #$08 clc jsr $fff0 jmp dumper
Burası ekranda 16 satır yani 16*8=128 bayt dump edildikten sonra basılması gereken "F(onksiyon)" tuşlarının kontrol edildiği bölümdür. Önce bir JSR komutuyla tuşları okuyoruz ve "F" tuşları olup olmadığını kontrol ediyoruz. "F1" ile "next_page" yazan yere gidiyoruz. Daha önce bahsettiğimiz şekilde "BIT" komutuyla bilgisayarı kandırıyoruz ve kursörün yerini belirleyip dump etme işine tekrar başlıyoruz. "F3" ile daha önceki sayfayı ekrana getiriyoruz. Bunun için o anki hafıza adresinin HIGH baytının tutulduğu $FC adresinin değerini 1 azalttıktan sonra kursörün yerini belirliyoruz ve başa dönüyoruz. "F5" ile farklı bir adresi dump etmek için programın en başına zıplıyoruz. "F7" ile programdan çıkıyoruz.
Burası altrutinlerin olduğu bölümdür.
hex_byte_in
jsr
hex_key_in
;high nibble
jsr
key_to_mem
asl
asl
asl
asl
sta
$fb
jsr
hex_key_in
;low nibble
jsr
key_to_mem
ora
$fb
sta
$fb
rts
Klavyeden bir baytlık hex sayı girme ve bu sayıyı hafızaya saklama bölümüdür. Önce
klavyeden hex karakter girilen alt rutine gidiyoruz. Geri dönüşte aküde bulunan tuş değe-
rinin sayısal karşılığını almak için bir başka alt rutine gidiyoruz. Buradan geri dönüşte
ise elimizdeki sayıyı 4 kez sola kaydırıp high nibble olarak $FB adresine saklıyoruz.Aynı
alt rutinlere bir kez daha uğruyoruz ve daha önce high nibble olarak sakladığımız değerle
R işlemi yaptıktan sonra aynı adrese yazıyoruz.
O
hex_key_in
jsr
$ffe4
ldx
#$00
control
cmp
key_table,x
bne
next
jsr
$ffd2
rts
next
inx
cpx
#$10
bne
control
jmp
hex_key_in
Bu kısımda klavyeden sadece hex sistem tuşlarına basılıp basılmadığını kontrol edi-
yoruz. Önce klavye taranıyor. Tarama sonunda Aküdeki değeri bir sayaca göre tablodaki
değerle karşılaştırıyoruz. Eğer karşılaştırma sonucunda basılan tuş tabloda varsa karak-
ter ekrana basılıyor ve rutinden çıkılıyor. Yoksa klavye tekrar taranıyor.
key_to_mem
ldx
#$00
loop0
cmp
key_table,x
beq
val_read
inx
cpx
#$10
bne
loop0
val_read
lda
val_table,x
rts
Bu kısımda basılan tuşa göre hafızaya alınacak sayı elde ediliyor. Aküdeki değer
bir tablo ile karşılaştırılıyor. Karşılaştırma sonucu eşitlik varsa, kullanılan sayacın
değeri kullanılarak başka bir tablodan hafızaya yazılacak değer okunuyor ve rutinden
çıkılıyor.
mem_to_scr
pha
lsr
lsr
lsr
lsr
jsr
convert
pla
and
#$0f
convert
tax
lda
key_table,x
jsr
$ffd2
rts
Geldik son alt rutine. Burada yapılan iş hafızadan okunan bir baytı hex olarak ekrana yazdırmak. İlk olarak hafızadan okunan bayt daha sonra tekrar kullanılmak üzere yığına atılıyor. Sonra HIGH nibble değerini ekrana yazdırmak için 4 kez sağa kaydırılıyor. Elde edilen değer sayaç olarak kullanılarak, sayaca göre tablodan okunan değer ekrana yazdırılıyor. Daha sonra yığındaki değer geri alınarak $0F sayısı ile AND işlemi yapılıyor. Böylece LOW nibble elde ediliyor. Sayaç işlemleri bir kez daha yapılıp hafızadaki bir sayı hex olarak ekrana yazdırılmış oluyor.
key_table
.text "0123456789abcdef"
;basılması gereken tuş tablosu
val_table
.byte 0,1,2,3,4,5,6,7,8,9
;tuşlara göre sayısal değerler
.byte 10,11,12,13,14,15
line
.byte 16
;ekrana basılacak satır sayısı
text1
.text " c64 turkiye hex-ascii dump program"
.byte $0d
.text " 10-may-2005 code: hades of ascraeus"
.byte $0d,$0d
.text "f1:next f3:prev. f5:new f7:exit"
.byte 13,13
text2
.text " adres"
.byte 0
text3
.text " hexadecimal memory dump ascii "
.byte $0d
.text " ===== ======================= ========"
.byte $0d,0
temp_scr
.byte 0,0,0,0,0,0,0,0
;geçici saklama bölgesi
.end

