more work on SD card support
This commit is contained in:
1 parent
37c193788c
commit
5704a8d4cd
13 files changed
+429
-389
No files matched your search
@@ -35,6 +35,8 @@ SRCDIR_BASIC = $(SRCDIR_COMMON) \
|
|||||||
|
|
||||||
SRCDIR_DOS_M65 = $(SRCDIR_COMMON) \
|
SRCDIR_DOS_M65 = $(SRCDIR_COMMON) \
|
||||||
src/dos_m65 \
|
src/dos_m65 \
|
||||||
|
# src/dos_m65/cmdrdos \
|
||||||
|
src/dos_m65/sdcard
|
||||||
|
|
||||||
SRCDIR_KERNAL = $(SRCDIR_COMMON) \
|
SRCDIR_KERNAL = $(SRCDIR_COMMON) \
|
||||||
src/kernal \
|
src/kernal \
|
||||||
|
|||||||
@@ -94,6 +94,8 @@
|
|||||||
|
|
||||||
; --- Built-in DOS configuration
|
; --- Built-in DOS configuration
|
||||||
|
|
||||||
|
;; #CONFIG# CMDRDOS NO ; do not change, DOS is not implemented yet
|
||||||
|
|
||||||
;; #CONFIG# UNIT_SDCARD 0 ; do not change, DOS is not implemented yet
|
;; #CONFIG# UNIT_SDCARD 0 ; do not change, DOS is not implemented yet
|
||||||
;; #CONFIG# UNIT_FLOPPY 0 ; do not change, DOS is not implemented yet
|
;; #CONFIG# UNIT_FLOPPY 0 ; do not change, DOS is not implemented yet
|
||||||
;; #CONFIG# UNIT_RAMDISK 0 ; do not change, DOS is not implemented yet
|
;; #CONFIG# UNIT_RAMDISK 0 ; do not change, DOS is not implemented yet
|
||||||
|
|||||||
@@ -241,6 +241,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; Check that internal DOS configuration is correct
|
||||||
|
|
||||||
|
!ifdef CONFIG_CMDRDOS { !ifndef CONFIG_MB_M65 {
|
||||||
|
!error "CONFIG_CMDRDOS requires CONFIG_MB_M65"
|
||||||
|
} }
|
||||||
|
|
||||||
|
|
||||||
; Check that startup banner configuration is correct
|
; Check that startup banner configuration is correct
|
||||||
|
|
||||||
!set counter = 0
|
!set counter = 0
|
||||||
@@ -415,6 +422,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; Handle non-LGPL3 code
|
||||||
|
|
||||||
|
!ifdef CONFIG_CMDRDOS { !set HAS_NOLGPL3_WARN = 1 }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; Determine if we need space-savings in BASIC code
|
; Determine if we need space-savings in BASIC code
|
||||||
|
|
||||||
!ifndef CONFIG_MB_M65 {
|
!ifndef CONFIG_MB_M65 {
|
||||||
|
|||||||
@@ -59,9 +59,18 @@ INITMSG_end:
|
|||||||
|
|
||||||
jsr initmsg_bytes_free
|
jsr initmsg_bytes_free
|
||||||
|
|
||||||
|
!ifdef HAS_NOLGPL3_WARN {
|
||||||
|
|
||||||
|
lda #<str_nonlgpl3_warn
|
||||||
|
ldy #>str_nonlgpl3_warn
|
||||||
|
jmp STROUT
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
ldx #$09
|
ldx #$09
|
||||||
ldy #$00
|
ldy #$00
|
||||||
jmp plot_set
|
jmp plot_set
|
||||||
|
}
|
||||||
|
|
||||||
INITMSG_main_banner:
|
INITMSG_main_banner:
|
||||||
|
|
||||||
@@ -99,3 +108,16 @@ INITMSG_revision:
|
|||||||
lda #<rom_revision_basic_string
|
lda #<rom_revision_basic_string
|
||||||
ldy #>rom_revision_basic_string
|
ldy #>rom_revision_basic_string
|
||||||
jmp STROUT
|
jmp STROUT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
!ifdef HAS_NOLGPL3_WARN {
|
||||||
|
|
||||||
|
str_nonlgpl3_warn:
|
||||||
|
|
||||||
|
!byte $0D, $0D, $0D, $0D
|
||||||
|
!pet "build contains non-lgpl3 code"
|
||||||
|
!byte $0D
|
||||||
|
!pet " *** do not distribute ***"
|
||||||
|
!byte $0D, $0D, $00
|
||||||
|
}
|
||||||
@@ -106,3 +106,5 @@ initmsg_real:
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
!ifdef HAS_NOLGPL3_WARN { !error "HAS_NOLGPL3_WARN not implemented"
|
||||||
@@ -2,17 +2,41 @@
|
|||||||
; Memory locations for the DOS
|
; Memory locations for the DOS
|
||||||
;
|
;
|
||||||
|
|
||||||
|
; NOTES:
|
||||||
|
; - DOS zeropage is mirrored at $8000
|
||||||
|
; - starting from $8000, 16KB RAM is available (starting from $10000 in C65 address space)
|
||||||
|
; - additional 16KB RAM is reserved for DOS too ($14000-$17FFF), and can be banked-in if needed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
; Page 0
|
; Page 0
|
||||||
;
|
;
|
||||||
|
|
||||||
!addr MAGICSTR = $00 ; magic string; if not matching, DOS considered non-functional
|
!addr MAGICSTR = $00 ; magic string; if not matching, DOS considered non-functional
|
||||||
|
|
||||||
!addr UNIT_SDCARD = $05
|
; General DOS configuration
|
||||||
!addr UNIT_FLOPPY = $06
|
|
||||||
!addr UNIT_RAMDISK = $07
|
|
||||||
|
|
||||||
; NOTES:
|
!addr UNIT_SDCARD = $05
|
||||||
; - DOS zeropage is mirrored at $8000
|
!addr UNIT_FLOPPY = $06
|
||||||
; - starting from $8000, 16KB RAM is available (starting from $10000 in C65 address space)
|
!addr UNIT_RAMDISK = $07
|
||||||
; - additional 16KB RAM is reserved for DOS too ($14000-$17FFF), and can be banked-in if needed
|
|
||||||
|
; SD/SDHC card variables
|
||||||
|
|
||||||
|
!addr CARD_INIT_DONE = $08 ; $80 - init done, $00 - init not done
|
||||||
|
!addr CARD_IS_SDHC = $09 ; $00 = SD, $80 = SDHC
|
||||||
|
!addr CARD_SIZE = $0A ; 4 bytes
|
||||||
|
!addr CARD_SECNUM = $0E ; 4 bytes - sector number
|
||||||
|
|
||||||
|
!addr CARD_TMP_STEP = $12 ; 4 bytes
|
||||||
|
!addr CARD_TMP_RETRIES = $16 ; 1 byte
|
||||||
|
|
||||||
|
!addr CARD_BUFPNT = $FC ; 4 bytes - pointer to hardware sector buffer XXX replace copy routines with DMAgic
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; High memory
|
||||||
|
;
|
||||||
|
|
||||||
|
!addr CARD_BUF = $8100 ; 512 bytes, up to $82FF - buffer for reading/writing data
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
!ifndef HAS_NOLGPL3_WARN {
|
||||||
|
!error "No LGPL3 incompatible warning issued"
|
||||||
|
}
|
||||||
@@ -26,6 +26,9 @@ dos_INIT:
|
|||||||
lda #CONFIG_UNIT_RAMDISK
|
lda #CONFIG_UNIT_RAMDISK
|
||||||
sta UNIT_RAMDISK
|
sta UNIT_RAMDISK
|
||||||
|
|
||||||
; XXX initialize drivers, etc.
|
; Mark SD card as not initialized
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
sta CARD_INIT_DONE
|
||||||
|
|
||||||
rts
|
rts
|
||||||
@@ -1,380 +0,0 @@
|
|||||||
|
|
||||||
;
|
|
||||||
; MEGA65 SD/SDHC card support
|
|
||||||
;
|
|
||||||
|
|
||||||
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; Permanent values XXX addresses are temporary
|
|
||||||
|
|
||||||
!addr CARD_IS_SDHC = $80 ; $00 = SD, $80 = SDHC
|
|
||||||
!addr CARD_SIZE = $81 ; 4 bytes
|
|
||||||
!addr CARD_SECNUM = $85 ; 4 bytes - sector number
|
|
||||||
!addr CARD_BUFPNT = $89 ; 4 bytes - pointer to hardware sector buffer
|
|
||||||
|
|
||||||
|
|
||||||
; Temporary data XXX addresses are temporary
|
|
||||||
|
|
||||||
!addr TMP_STEP = $8D ; 4 bytes
|
|
||||||
!addr TMP_RETRIES = $8E ; 1 byte
|
|
||||||
|
|
||||||
!addr CARD_BUF = $8100 ; 512 bytes, up to $82FF
|
|
||||||
|
|
||||||
|
|
||||||
; External entry points:
|
|
||||||
; - m65_sdcard_init
|
|
||||||
; - m65_sdcard_readsector
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m65_sdcard_init:
|
|
||||||
|
|
||||||
; Initialize most important variables
|
|
||||||
|
|
||||||
lda #$00
|
|
||||||
sta CARD_IS_SDHC
|
|
||||||
|
|
||||||
lda #SD_SECBUF_0
|
|
||||||
sta CARD_BUFPNT+0
|
|
||||||
lda #SD_SECBUF_1
|
|
||||||
sta CARD_BUFPNT+1
|
|
||||||
lda #SD_SECBUF_2
|
|
||||||
sta CARD_BUFPNT+2
|
|
||||||
lda #SD_SECBUF_3
|
|
||||||
sta CARD_BUFPNT+3
|
|
||||||
|
|
||||||
; Reset the card
|
|
||||||
|
|
||||||
jsr m65_sdcard_reset
|
|
||||||
|
|
||||||
; Try to read first sector to see if card is operable
|
|
||||||
|
|
||||||
lda #$00
|
|
||||||
sta SD_ADDR+0
|
|
||||||
sta SD_ADDR+1
|
|
||||||
sta SD_ADDR+2
|
|
||||||
sta SD_ADDR+3
|
|
||||||
|
|
||||||
jsr m65_sdcard_read
|
|
||||||
bcc m65_sdcard_init_operable
|
|
||||||
|
|
||||||
; XXX if we are here, mark card as not operable and quit
|
|
||||||
|
|
||||||
m65_sdcard_init_operable:
|
|
||||||
|
|
||||||
; Work out if this is SD or SDHC card - SD cards can't read at non-sector aligned addresses
|
|
||||||
|
|
||||||
lda #$02
|
|
||||||
sta SD_ADDR+0
|
|
||||||
lda #$00
|
|
||||||
sta SD_ADDR+1
|
|
||||||
sta SD_ADDR+2
|
|
||||||
sta SD_ADDR+3
|
|
||||||
|
|
||||||
jsr m65_sdcard_read
|
|
||||||
|
|
||||||
lda SD_CTL
|
|
||||||
beq m65_sdcard_init_sdsc
|
|
||||||
|
|
||||||
; FALLTROUGH
|
|
||||||
|
|
||||||
m65_sdcard_init_sdhc:
|
|
||||||
|
|
||||||
lda #$80
|
|
||||||
sta CARD_IS_SDHC
|
|
||||||
|
|
||||||
bra m65_sdcard_init_getsize
|
|
||||||
|
|
||||||
m65_sdcard_init_sdsc:
|
|
||||||
|
|
||||||
lda #$00
|
|
||||||
sta CARD_IS_SDHC
|
|
||||||
lda #$40 ; use byte addressing
|
|
||||||
sta SD_CTL
|
|
||||||
|
|
||||||
; FALLTROUGH
|
|
||||||
|
|
||||||
m65_sdcard_init_getsize:
|
|
||||||
|
|
||||||
; Work out size of SD card in a safe way
|
|
||||||
; (binary search of sector numbers is NOT safe for some reason.
|
|
||||||
; It frequently reports bigger than the size of the card)
|
|
||||||
|
|
||||||
lda #$00
|
|
||||||
sta CARD_SECNUM+0
|
|
||||||
sta CARD_SECNUM+1
|
|
||||||
sta CARD_SECNUM+2
|
|
||||||
sta CARD_SECNUM+3
|
|
||||||
|
|
||||||
; step = 16*2048
|
|
||||||
|
|
||||||
sta TMP_STEP+0
|
|
||||||
sta TMP_STEP+2
|
|
||||||
sta TMP_STEP+3
|
|
||||||
lda #$08
|
|
||||||
sta TMP_STEP+1
|
|
||||||
|
|
||||||
; XXX finish the implementation
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; -------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m65_sdcard_readsector: ; XXX reads sector CARD_SECNUM
|
|
||||||
|
|
||||||
; Set read address, depending on card type
|
|
||||||
|
|
||||||
bit CARD_IS_SDHC
|
|
||||||
bpl m65_sdcard_readsector_sdsc
|
|
||||||
|
|
||||||
m65_sdcard_readsector_sdhc:
|
|
||||||
|
|
||||||
lda CARD_SECNUM+0
|
|
||||||
sta SD_ADDR+0
|
|
||||||
lda CARD_SECNUM+1
|
|
||||||
sta SD_ADDR+1
|
|
||||||
lda CARD_SECNUM+2
|
|
||||||
sta SD_ADDR+2
|
|
||||||
lda CARD_SECNUM+3
|
|
||||||
sta SD_ADDR+3
|
|
||||||
|
|
||||||
bra m65_sdcard_readsector_read
|
|
||||||
|
|
||||||
m65_sdcard_readsector_sdsc: ; multiply sector number by 512
|
|
||||||
|
|
||||||
lda #$00
|
|
||||||
sta SD_ADDR+0
|
|
||||||
clc
|
|
||||||
lda CARD_SECNUM+0
|
|
||||||
rol
|
|
||||||
sta SD_ADDR+1
|
|
||||||
lda CARD_SECNUM+1
|
|
||||||
rol
|
|
||||||
sta SD_ADDR+2
|
|
||||||
lda CARD_SECNUM+2
|
|
||||||
rol
|
|
||||||
sta SD_ADDR+3
|
|
||||||
bcs m65_sdcard_readsector_fail ; branch if sector number too large for SD card
|
|
||||||
lda CARD_SECNUM+3
|
|
||||||
bne m65_sdcard_readsector_fail ; branch if sector number too large for SD card
|
|
||||||
|
|
||||||
; FALLTROUGH
|
|
||||||
|
|
||||||
m65_sdcard_readsector_read:
|
|
||||||
|
|
||||||
; Set number of retries
|
|
||||||
|
|
||||||
lda #$0A
|
|
||||||
sta TMP_RETRIES
|
|
||||||
|
|
||||||
; FALLTROUGH
|
|
||||||
|
|
||||||
m65_sdcard_readsector_try_loop:
|
|
||||||
|
|
||||||
; Wait till card is ready
|
|
||||||
|
|
||||||
jsr m65_sdcard_readsector_wait
|
|
||||||
bcs m65_sdcard_readsector_fail
|
|
||||||
|
|
||||||
; Read command
|
|
||||||
|
|
||||||
lda #$02
|
|
||||||
sta SD_CTL
|
|
||||||
|
|
||||||
; Wait for command completion
|
|
||||||
|
|
||||||
jsr m65_sdcard_readsector_wait
|
|
||||||
bcs m65_sdcard_readsector_fail
|
|
||||||
|
|
||||||
|
|
||||||
lda SD_CTL
|
|
||||||
and #$67
|
|
||||||
bne m65_sdcard_readsector_copy_data
|
|
||||||
|
|
||||||
jsr m65_sdcard_reset
|
|
||||||
dec TMP_RETRIES
|
|
||||||
bne m65_sdcard_readsector_try_loop
|
|
||||||
|
|
||||||
; FALLTROUGH
|
|
||||||
|
|
||||||
m65_sdcard_readsector_fail:
|
|
||||||
|
|
||||||
sec
|
|
||||||
rts
|
|
||||||
|
|
||||||
m65_sdcard_readsector_copy_data:
|
|
||||||
|
|
||||||
; XXX this should be a separate routine
|
|
||||||
; XXX use DMAgic for this
|
|
||||||
|
|
||||||
phz
|
|
||||||
phx
|
|
||||||
|
|
||||||
ldx #$00
|
|
||||||
ldz #$00
|
|
||||||
|
|
||||||
@RL1:
|
|
||||||
lda [CARD_BUFPNT],z
|
|
||||||
sta CARD_BUF,x
|
|
||||||
inc CARD_BUFPNT+1
|
|
||||||
lda [CARD_BUFPNT],z
|
|
||||||
sta CARD_BUF+$100,x
|
|
||||||
dec CARD_BUFPNT+1
|
|
||||||
|
|
||||||
inz
|
|
||||||
inx
|
|
||||||
bne @RL1
|
|
||||||
|
|
||||||
; Restore registers and quit
|
|
||||||
|
|
||||||
plx
|
|
||||||
plz
|
|
||||||
|
|
||||||
clc
|
|
||||||
rts
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; -------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
m65_sdcard_readsector_wait:
|
|
||||||
|
|
||||||
; Wait till card is ready
|
|
||||||
|
|
||||||
lda SD_CTL
|
|
||||||
; Sometimes we see this result, i.e., sdcard.vhdl thinks it is done,
|
|
||||||
; but sdcardio.vhdl thinks not. This means a read error.
|
|
||||||
cmp #$01
|
|
||||||
beq m65_sdcard_readsector_wait_fail
|
|
||||||
tax
|
|
||||||
and #$40
|
|
||||||
bne m65_sdcard_readsector_wait_fail
|
|
||||||
txa
|
|
||||||
and #$03
|
|
||||||
bne m65_sdcard_readsector_wait
|
|
||||||
|
|
||||||
clc
|
|
||||||
rts
|
|
||||||
|
|
||||||
m65_sdcard_readsector_wait_fail:
|
|
||||||
|
|
||||||
sec
|
|
||||||
rts
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; -------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m65_sdcard_read:
|
|
||||||
|
|
||||||
; Trigger read
|
|
||||||
|
|
||||||
lda #$02
|
|
||||||
sta SD_CTL
|
|
||||||
|
|
||||||
; Wait for result
|
|
||||||
|
|
||||||
ldx #90
|
|
||||||
@1:
|
|
||||||
jsr m65_sdcard_wait_16000_usec
|
|
||||||
lda SD_CTL
|
|
||||||
and #$03
|
|
||||||
beq @2
|
|
||||||
dex
|
|
||||||
bne @1
|
|
||||||
|
|
||||||
; Read failed
|
|
||||||
|
|
||||||
sec
|
|
||||||
rts
|
|
||||||
@2:
|
|
||||||
;; Success
|
|
||||||
|
|
||||||
clc
|
|
||||||
rts
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; -------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m65_sdcard_reset:
|
|
||||||
|
|
||||||
ldx #$40
|
|
||||||
stx SD_CTL
|
|
||||||
ldy #$00
|
|
||||||
sty SD_CTL
|
|
||||||
iny ; $01
|
|
||||||
sty SD_CTL
|
|
||||||
|
|
||||||
; Wait till SD card resets
|
|
||||||
@3:
|
|
||||||
lda SD_CTL
|
|
||||||
and #$03
|
|
||||||
bne @3
|
|
||||||
|
|
||||||
; For SDHC card set appropriate mode
|
|
||||||
|
|
||||||
bit CARD_IS_SDHC
|
|
||||||
bpl @4
|
|
||||||
inx ; $41
|
|
||||||
stx SD_CTL
|
|
||||||
@4:
|
|
||||||
rts
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; -------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
m65_sdcard_wait_16000_usec:
|
|
||||||
|
|
||||||
; Uses VIC-II raster register; wait time is not exactly precise, but should be
|
|
||||||
; a good approximation
|
|
||||||
|
|
||||||
phx
|
|
||||||
pha
|
|
||||||
|
|
||||||
ldx #$FF
|
|
||||||
|
|
||||||
; XXX wait below is same as in KKERNAL, wait_x_lines - consider importing and reusing
|
|
||||||
lda VIC_RASTER
|
|
||||||
@w1:
|
|
||||||
cmp VIC_RASTER
|
|
||||||
beq @w1
|
|
||||||
lda VIC_RASTER
|
|
||||||
dex
|
|
||||||
bne @w1
|
|
||||||
|
|
||||||
pla
|
|
||||||
plx
|
|
||||||
|
|
||||||
rts
|
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
|
||||||
|
;
|
||||||
|
; Initialize memory card, determine it's type and size
|
||||||
|
;
|
||||||
|
|
||||||
|
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; XXX finish the routine
|
||||||
|
|
||||||
|
|
||||||
|
sdcard_init:
|
||||||
|
|
||||||
|
; Initialize most important variables
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
sta CARD_IS_SDHC
|
||||||
|
|
||||||
|
lda #SD_SECBUF_0
|
||||||
|
sta CARD_BUFPNT+0
|
||||||
|
lda #SD_SECBUF_1
|
||||||
|
sta CARD_BUFPNT+1
|
||||||
|
lda #SD_SECBUF_2
|
||||||
|
sta CARD_BUFPNT+2
|
||||||
|
lda #SD_SECBUF_3
|
||||||
|
sta CARD_BUFPNT+3
|
||||||
|
|
||||||
|
; Reset the card
|
||||||
|
|
||||||
|
jsr sdcard_reset
|
||||||
|
|
||||||
|
; Try to read first sector to see if card is operable
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
sta SD_ADDR+0
|
||||||
|
sta SD_ADDR+1
|
||||||
|
sta SD_ADDR+2
|
||||||
|
sta SD_ADDR+3
|
||||||
|
|
||||||
|
jsr sdcard_init_read
|
||||||
|
bcc sdcard_init_operable
|
||||||
|
|
||||||
|
; XXX if we are here, mark card as not operable and quit
|
||||||
|
|
||||||
|
sdcard_init_operable:
|
||||||
|
|
||||||
|
; Work out if this is SD or SDHC card - SD cards can't read at non-sector aligned addresses
|
||||||
|
|
||||||
|
lda #$02
|
||||||
|
sta SD_ADDR+0
|
||||||
|
lda #$00
|
||||||
|
sta SD_ADDR+1
|
||||||
|
sta SD_ADDR+2
|
||||||
|
sta SD_ADDR+3
|
||||||
|
|
||||||
|
jsr sdcard_init_read
|
||||||
|
|
||||||
|
lda SD_CTL
|
||||||
|
beq sdcard_init_sdsc
|
||||||
|
|
||||||
|
; FALLTROUGH
|
||||||
|
|
||||||
|
sdcard_init_sdhc:
|
||||||
|
|
||||||
|
lda #$80
|
||||||
|
sta CARD_IS_SDHC
|
||||||
|
|
||||||
|
bra sdcard_init_getsize
|
||||||
|
|
||||||
|
sdcard_init_sdsc:
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
sta CARD_IS_SDHC
|
||||||
|
lda #$40 ; use byte addressing
|
||||||
|
sta SD_CTL
|
||||||
|
|
||||||
|
; FALLTROUGH
|
||||||
|
|
||||||
|
sdcard_init_getsize:
|
||||||
|
|
||||||
|
; Work out size of SD card in a safe way
|
||||||
|
; (binary search of sector numbers is NOT safe for some reason.
|
||||||
|
; It frequently reports bigger than the size of the card)
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
sta CARD_SECNUM+0
|
||||||
|
sta CARD_SECNUM+1
|
||||||
|
sta CARD_SECNUM+2
|
||||||
|
sta CARD_SECNUM+3
|
||||||
|
|
||||||
|
; step = 16*2048
|
||||||
|
|
||||||
|
sta CARD_TMP_STEP+0
|
||||||
|
sta CARD_TMP_STEP+2
|
||||||
|
sta CARD_TMP_STEP+3
|
||||||
|
lda #$08
|
||||||
|
sta CARD_TMP_STEP+1
|
||||||
|
|
||||||
|
; XXX finish the implementation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; Helper routines
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
sdcard_init_read:
|
||||||
|
|
||||||
|
; Trigger read
|
||||||
|
|
||||||
|
lda #$02
|
||||||
|
sta SD_CTL
|
||||||
|
|
||||||
|
; Wait for result
|
||||||
|
|
||||||
|
ldx #90
|
||||||
|
@1:
|
||||||
|
jsr sdcard_wait_16000_usec
|
||||||
|
lda SD_CTL
|
||||||
|
and #$03
|
||||||
|
beq @2
|
||||||
|
dex
|
||||||
|
bne @1
|
||||||
|
|
||||||
|
; Read failed
|
||||||
|
|
||||||
|
sec
|
||||||
|
rts
|
||||||
|
@2:
|
||||||
|
;; Success
|
||||||
|
|
||||||
|
clc
|
||||||
|
rts
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
|
||||||
|
;
|
||||||
|
; Reads the sector from the SD card
|
||||||
|
;
|
||||||
|
|
||||||
|
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
|
||||||
|
|
||||||
|
|
||||||
|
; XXX provide documentation
|
||||||
|
|
||||||
|
|
||||||
|
sdcard_readsector:
|
||||||
|
|
||||||
|
; XXX check if card initialized and operable
|
||||||
|
|
||||||
|
; Set read address, depending on card type
|
||||||
|
|
||||||
|
bit CARD_IS_SDHC
|
||||||
|
bpl sdcard_readsector_sdsc
|
||||||
|
|
||||||
|
sdcard_readsector_sdhc:
|
||||||
|
|
||||||
|
lda CARD_SECNUM+0
|
||||||
|
sta SD_ADDR+0
|
||||||
|
lda CARD_SECNUM+1
|
||||||
|
sta SD_ADDR+1
|
||||||
|
lda CARD_SECNUM+2
|
||||||
|
sta SD_ADDR+2
|
||||||
|
lda CARD_SECNUM+3
|
||||||
|
sta SD_ADDR+3
|
||||||
|
|
||||||
|
bra sdcard_readsector_read
|
||||||
|
|
||||||
|
sdcard_readsector_sdsc: ; multiply sector number by 512
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
sta SD_ADDR+0
|
||||||
|
clc
|
||||||
|
lda CARD_SECNUM+0
|
||||||
|
rol
|
||||||
|
sta SD_ADDR+1
|
||||||
|
lda CARD_SECNUM+1
|
||||||
|
rol
|
||||||
|
sta SD_ADDR+2
|
||||||
|
lda CARD_SECNUM+2
|
||||||
|
rol
|
||||||
|
sta SD_ADDR+3
|
||||||
|
bcs sdcard_readsector_fail ; branch if sector number too large for SD card
|
||||||
|
lda CARD_SECNUM+3
|
||||||
|
bne sdcard_readsector_fail ; branch if sector number too large for SD card
|
||||||
|
|
||||||
|
; FALLTROUGH
|
||||||
|
|
||||||
|
sdcard_readsector_read:
|
||||||
|
|
||||||
|
; Set number of retries
|
||||||
|
|
||||||
|
lda #$0A
|
||||||
|
sta CARD_TMP_RETRIES
|
||||||
|
|
||||||
|
; FALLTROUGH
|
||||||
|
|
||||||
|
sdcard_readsector_try_loop:
|
||||||
|
|
||||||
|
; Wait till card is ready
|
||||||
|
|
||||||
|
jsr sdcard_readsector_wait
|
||||||
|
bcs sdcard_readsector_fail
|
||||||
|
|
||||||
|
; Read command
|
||||||
|
|
||||||
|
lda #$02
|
||||||
|
sta SD_CTL
|
||||||
|
|
||||||
|
; Wait for command completion
|
||||||
|
|
||||||
|
jsr sdcard_readsector_wait
|
||||||
|
bcs sdcard_readsector_fail
|
||||||
|
|
||||||
|
|
||||||
|
lda SD_CTL
|
||||||
|
and #$67
|
||||||
|
bne sdcard_readsector_copy_data
|
||||||
|
|
||||||
|
jsr sdcard_reset
|
||||||
|
dec CARD_TMP_RETRIES
|
||||||
|
bne sdcard_readsector_try_loop
|
||||||
|
|
||||||
|
; FALLTROUGH
|
||||||
|
|
||||||
|
sdcard_readsector_fail:
|
||||||
|
|
||||||
|
sec
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; Helper routines
|
||||||
|
;
|
||||||
|
|
||||||
|
sdcard_readsector_copy_data:
|
||||||
|
|
||||||
|
; XXX this should be a separate routine
|
||||||
|
; XXX use DMAgic for this
|
||||||
|
|
||||||
|
phz
|
||||||
|
phx
|
||||||
|
|
||||||
|
ldx #$00
|
||||||
|
ldz #$00
|
||||||
|
|
||||||
|
@1:
|
||||||
|
lda [CARD_BUFPNT],z
|
||||||
|
sta CARD_BUF,x
|
||||||
|
inc CARD_BUFPNT+1
|
||||||
|
lda [CARD_BUFPNT],z
|
||||||
|
sta CARD_BUF+$100,x
|
||||||
|
dec CARD_BUFPNT+1
|
||||||
|
|
||||||
|
inz
|
||||||
|
inx
|
||||||
|
bne @1
|
||||||
|
|
||||||
|
; Restore registers and quit
|
||||||
|
|
||||||
|
plx
|
||||||
|
plz
|
||||||
|
|
||||||
|
clc
|
||||||
|
rts
|
||||||
|
|
||||||
|
sdcard_readsector_wait:
|
||||||
|
|
||||||
|
; Wait till card is ready
|
||||||
|
|
||||||
|
lda SD_CTL
|
||||||
|
; Sometimes we see this result, i.e., sdcard.vhdl thinks it is done,
|
||||||
|
; but sdcardio.vhdl thinks not. This means a read error.
|
||||||
|
cmp #$01
|
||||||
|
beq sdcard_readsector_wait_fail
|
||||||
|
tax
|
||||||
|
and #$40
|
||||||
|
bne sdcard_readsector_wait_fail
|
||||||
|
txa
|
||||||
|
and #$03
|
||||||
|
bne sdcard_readsector_wait
|
||||||
|
|
||||||
|
clc
|
||||||
|
rts
|
||||||
|
|
||||||
|
sdcard_readsector_wait_fail:
|
||||||
|
|
||||||
|
sec
|
||||||
|
rts
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
;
|
||||||
|
; Resets the SD card
|
||||||
|
;
|
||||||
|
|
||||||
|
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sdcard_reset:
|
||||||
|
|
||||||
|
ldx #$40
|
||||||
|
stx SD_CTL
|
||||||
|
ldy #$00
|
||||||
|
sty SD_CTL
|
||||||
|
iny ; $01
|
||||||
|
sty SD_CTL
|
||||||
|
|
||||||
|
; Wait till SD card resets
|
||||||
|
@1:
|
||||||
|
lda SD_CTL
|
||||||
|
and #$03
|
||||||
|
bne @1
|
||||||
|
|
||||||
|
; For SDHC card set appropriate mode
|
||||||
|
|
||||||
|
bit CARD_IS_SDHC
|
||||||
|
bpl @2
|
||||||
|
inx ; $41
|
||||||
|
stx SD_CTL
|
||||||
|
@2:
|
||||||
|
rts
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sdcard_wait_16000_usec:
|
||||||
|
|
||||||
|
; Uses VIC-II raster register; wait time is not exactly precise, but should be
|
||||||
|
; a good approximation
|
||||||
|
|
||||||
|
phx
|
||||||
|
pha
|
||||||
|
|
||||||
|
ldx #$FF
|
||||||
|
|
||||||
|
; XXX wait below is same as in KKERNAL, wait_x_lines - consider importing and reusing
|
||||||
|
lda VIC_RASTER
|
||||||
|
@1:
|
||||||
|
cmp VIC_RASTER
|
||||||
|
beq @1
|
||||||
|
lda VIC_RASTER
|
||||||
|
dex
|
||||||
|
bne @1
|
||||||
|
|
||||||
|
pla
|
||||||
|
plx
|
||||||
|
|
||||||
|
rts
|
||||||
Reference in new issue
Block a user