Hi! Ich habe mal anhand der auf Bitte melde dich an, um diesen Link zu sehen. veröffentlichten Programmier-Dokumentation versucht, ein paar Daten von meiner SD-Karte auszulesen. Im Prinzip habe ich erstmal nichts anderes gemacht, als die in der Anleitung beschriebenen Routinen zum Initialsieren und anschließenden Auslesen der Karte zu einem lauffähigen Programm zusammengefügt und mittels ACME kompiliert.
Leider hängt sich das Programm bei mir in einer Endlosschleife auf, und zwar in der Subroutine "waitformmcdata". Hier sollte mir der SPI nach einem übermittelten Blocklesekommando ("CMD17") eigentlich mit $FE antworten. Diese Antwort bleibt aber leider aus; ich bekomme nur $FF. Als Indikator für diese Endlosschleife habe ich mal die Rahmenfarbe rotieren lassen.
Habe ich etwa noch was übersehen? Oder liegt es vielleicht an meiner SD-Karte? ![]()
Ich hänge mal den Sourcecode und das ausführbare Programm an. Wenn alles klappt, sollten 512 Bytes von der Karte direkt sichtbar in den Bildschirmspeicher ab $0400 geschrieben werden. Wenn der Rahmen nicht mehr aufhört zu flackern, wartet das Programm noch auf das OK-Signal von der Karte (so wie bei mir
).
CU
Kratznagel
!to "mmcread.prg"
memptr = $fb
*= $0800
!byte $00,$0c,$08,$0a,$00,$9e,$34,$30,$39,$36,$00,$00,$00,$00
*= $1000
jsr .initmmc64
jsr .resetmmc64
jsr .initwaitmmc64
;Enable 8Mhz mode
lda $df11
ora #%00000100
sta $df11
jsr .blockreadcmd
jsr .waitformmcdata
jsr .blockread
rts
;-----------------------------------------------------------------------------------
; Initialize a flash card plugged into the MMC64
;-----------------------------------------------------------------------------------
.initmmc64
lda $df11 ;get contents of MMC64 control register
and #%10111011 ;set 250khz & write trigger mode
ora #%00000010 ;disable card select
sta $df11 ;update control register
ldx #$0a ;initialize counter (10*8 pulses)
ldy #$ff ;initialize value to be written (bits must be all high)
.mmcinitloop
sty $df10 ;send 8 pulses to the card
.busywait
lda $df12 ;we catch the status register
and #$01 ;all bits shiftet out?
bne .busywait ;nope, so wait
dex ;decrement counter
bne .mmcinitloop ;until 80 pulses sent
lda $df11 ;pull card chip select line down for SPI communication
and #%11111101
sta $df11
rts
;-----------------------------------------------------------------------------------
;Reset the flash card
;-----------------------------------------------------------------------------------
.resetmmc64
ldy #$09 ;we send 8 command bytes to the card
.mmc64resetloop
lda .resetcmd-1,y ;grab command byte
sta $df10 ;and fire it to the card
.resetbusy
lda $df12 ;we check the busy bit
and #$01 ;to ensure that the transfer is safe
bne .resetbusy
dey ;decrease command counter
bne .mmc64resetloop ;until the entire command has been sent
lda $df10 ;now we check the card response
and #$01 ;did it accept the command ?
bne .mmcresponded ;ok, everything is fine !
lda $df12 ;is there a card at all ?
and #$08
beq .resetmmc64 ;yup, so we just resend the command
.mmcresponded
rts
.resetcmd
!byte $ff,$ff,$95,$00,$00,$00,$00,$40,$ff ;CMD0
;-----------------------------------------------------------------------------------
;check if card has left initialization
;-----------------------------------------------------------------------------------
.initwaitmmc64
ldy #$09 ;we send 8 command bytes to the card
.initwaitloop
lda .initwaitcmd-1,y ;grab command byte
sta $df10 ;and fire it to the card
.initwaitbusy
lda $df12 ;we check the busy bit
and #$01 ;to ensure that the transfer is safe
bne .initwaitbusy
dey ;decrease command counter
bne .initwaitloop ;until entire command has been sent
lda $df10 ;did the card left its init state?
and #$01
bne .initwaitmmc64 ;no, so we resend the command to check it again
rts
.initwaitcmd
!byte $ff,$ff,$ff,$00,$00,$00,$00,$41,$ff ;CMD1
;-----------------------------------------------------------------------------------
;Block read command - set up a 512 byte transfer from $00000100 to $000002ff of the
;SD Card into C64 memory
;-----------------------------------------------------------------------------------
.blockreadcmd
ldy #$09
.blockreadcmdloop
lda .blockrcmd-1,y
sta $df10
dey
bne .blockreadcmdloop
rts
.blockrcmd
!byte $ff,$ff,$ff,$00,$01,$00,$00,$51,$ff ;CMD17
;-----------------------------------------------------------------------------------
;Wait until card is ready
;-----------------------------------------------------------------------------------
.waitformmcdata
inc $d020 ;rotate border color
lda #$ff
sta $df10 ;write all high bits
lda $df10 ;to give the possibility to respond
cmp #$fe ;has it started?
bne .waitformmcdata ;nop, so we continue waiting
rts
;-----------------------------------------------------------------------------------
; Transfer 512 bytes from card into memory
;-----------------------------------------------------------------------------------
.blockread
lda #$00 ;init
sta memptr ;pointer
lda #$04 ;to
sta memptr+1 ;$0400
lda $df11 ;set MMC64 into read trigger mode
ora #%01000000 ;which means every read triggers a SPI transfer
sta $df11
lda $df10 ;we have to start with one dummy read here
ldx #$02 ;set up counters
ldy #$00
.sectorcopyloop
lda $df10 ;get data byte from card
sta (memptr),y ;store it into memory ( memptr has to be initialized)
iny ;have we copied 256 bytes ?
bne .sectorcopyloop ;nope, so go on!
inc memptr+1 ;increase memory pointer for next 256 bytes
dex ;have we copied 512 bytes ?
bne .sectorcopyloop
lda $df10 ;we have to end the data transfer with one dummy read
lda $df11 ;now we put the hardware back into write trigger mode again
and #%10111111
sta $df11
rts
Alles anzeigen