finished code to calculate number of blocks in CBDOS

This commit is contained in:
FeralChild64 committed 2021-02-16 21:47:26 +01:00
1 parent 9466b5cca5
commit 1e0f1eeb92
7 files changed
+89 -670

No files matched your search

-93
View File
@@ -1,93 +0,0 @@
;
; Various helper routines for SD card support
;
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
;
; Sets read/write address
;
; Input: CARD_SECNUM, CARD_IS_SDHC
; Output: Carry set = error
; Preserves: .X, .Y, .Z
;
sdcard_set_addr:
bit CARD_IS_SDHC
bpl sdcard_set_addr_sdsc
sdcard_set_addr_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
; FALLTROUGH
sdcard_set_addr_done:
clc
rts
sdcard_set_addr_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_helper_fail ; branch if sector number too large for SD card
lda CARD_SECNUM+3
beq sdcard_set_addr_done ; do not branch if sector number too large for SD card
; FALLTROUGH
sdcard_helper_fail:
sec
rts
;
; Wait till card is ready
;
; Input: none
; Output: Carry set = error
; Preserves: .Y, .Z
sdcard_wait_ready:
; XXX if card does not get ready, try to reset it
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_helper_fail
tax
and #$40
bne sdcard_helper_fail
txa
and #$03
bne sdcard_wait_ready
clc
rts
-243
View File
@@ -1,243 +0,0 @@
;
; 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_BUFPNT1+0
sta CARD_BUFPNT2+0
lda #SD_SECBUF_1
sta CARD_BUFPNT1+1
inc
sta CARD_BUFPNT2+1
lda #SD_SECBUF_2
sta CARD_BUFPNT1+2
sta CARD_BUFPNT2+2
lda #SD_SECBUF_3
sta CARD_BUFPNT1+3
sta CARD_BUFPNT2+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
bcs sdcard_init_getsize_fail ; if failure, mark card as not operable and quit
; 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 #CARD_CMD_SDHC_OFF ; $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)
; step (and first sector) = 16*2048
sta CARD_TMP_STEP+0
sta CARD_SECNUM+0
sta CARD_TMP_STEP+2
sta CARD_SECNUM+2
sta CARD_TMP_STEP+3
sta CARD_SECNUM+3
lda #$08
sta CARD_TMP_STEP+1
sta CARD_SECNUM+1
; FALLTROUGH
sdcard_init_getsize_read:
; Try to read sector
jsr sdcard_readsector
bcc sdcard_init_getsize_next ; XXX original code checks PEEK(sd_ctl)&0x63;...
; Failed to read - restore card state and sector number
jsr sdcard_reset
sec
lda CARD_SECNUM+0
sbc CARD_TMP_STEP+0
sta CARD_SECNUM+0
lda CARD_SECNUM+1
sbc CARD_TMP_STEP+1
sta CARD_SECNUM+1
lda CARD_SECNUM+2
sbc CARD_TMP_STEP+2
sta CARD_SECNUM+2
lda CARD_SECNUM+3
sbc CARD_TMP_STEP+3
sta CARD_SECNUM+3
; Divide step by 2, skip bytes which are always 0
clc
; ror CARD_TMP_STEP+3
; ror CARD_TMP_STEP+2
ror CARD_TMP_STEP+1
ror CARD_TMP_STEP+0
; FALLTROUGH
sdcard_init_getsize_next:
; Increment sector number by step
clc
lda CARD_SECNUM+0
adc CARD_TMP_STEP+0
sta CARD_SECNUM+0
lda CARD_SECNUM+1
adc CARD_TMP_STEP+1
sta CARD_SECNUM+1
lda CARD_SECNUM+2
adc CARD_TMP_STEP+2
sta CARD_SECNUM+2
lda CARD_SECNUM+3
adc CARD_TMP_STEP+3
sta CARD_SECNUM+3
; If sector number is 0 - report failure
lda CARD_SECNUM+0
ora CARD_SECNUM+1
ora CARD_SECNUM+2
ora CARD_SECNUM+3
beq sdcard_init_getsize_fail
; If step is 0 - this is the end, we know maximum size
lda CARD_TMP_STEP+0
ora CARD_TMP_STEP+1
ora CARD_TMP_STEP+2
ora CARD_TMP_STEP+3
beq sdcard_init_getsize_done
; Check sector number, should be below $10:$00:$00:$00
lda CARD_SECNUM+3
and #$F0
bne sdcard_init_getsize_read
; It is not - report maximum size
lda #$FF
sta CARD_SECNUM+0
sta CARD_SECNUM+1
sta CARD_SECNUM+2
lda #$0F
sta CARD_SECNUM+3
; FALLTROUGH
sdcard_init_getsize_done:
; Return sector number as maximum readable sector
lda CARD_SECNUM+0
sta CARD_SIZE+0
lda CARD_SECNUM+1
sta CARD_SIZE+1
lda CARD_SECNUM+2
sta CARD_SIZE+2
lda CARD_SECNUM+3
sta CARD_SIZE+3
clc
rts
sdcard_init_getsize_fail:
; XXX mark card as inoperable
sec
rts
;
; Helper routines
;
sdcard_init_read:
; Trigger read
lda #CARD_CMD_READ ; $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
-97
View File
@@ -1,97 +0,0 @@
;
; 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
jsr sdcard_set_addr
bcs sdcard_readsector_fail
; 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_wait_ready
bcs sdcard_readsector_fail
; Read command
lda #CARD_CMD_READ ; $02
sta SD_CTL
; Wait for command completion
jsr sdcard_wait_ready
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 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
-32
View File
@@ -1,32 +0,0 @@
;
; Resets the SD card
;
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
sdcard_reset:
ldx #CARD_CMD_SDHC_OFF ; $40
stx SD_CTL
ldy #CARD_CMD_RESET ; $00
sty SD_CTL
ldy #CARD_CMD_END_RESET ; $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
ldx #CARD_CMD_SDHC_ON ; $41
stx SD_CTL
@2:
rts
-26
View File
@@ -1,26 +0,0 @@
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
-175
View File
@@ -1,175 +0,0 @@
;
; Writes the sector to the SD card
;
; Based on https://github.com/MEGA65/mega65-libc/blob/master/cc65/src/sdcard.c
; XXX finish, provide documentation
sdcard_writesector:
; XXX check if card initialized and operable
lda SD_CTL
and #$03
bne sdcard_writesector ; XXX add a timer here
; End reset XXX is this needed? should this be done for sector reading too?
lda #CARD_CMD_END_RESET ; $01
sta SD_CTL
; Set write address
jsr sdcard_set_addr
bcs sdcard_writesector_fail
; FALLTROUGH
sdcard_writesector_write:
; Set number of retries
lda #$0A
sta CARD_TMP_RETRIES
; FALLTROUGH
sdcard_writesector_try_loop:
jsr sdcard_writesector_copy_data
; Wait till card is ready
jsr sdcard_wait_ready
bcs sdcard_writesector_fail
; Write command
lda #CARD_CMD_WRITE ; $03
sta SD_CTL
; Wait for command completion
jsr sdcard_wait_ready
bcs sdcard_writesector_fail
; Check result
lda SD_CTL
and #$67
bne sdcard_writesector_verify
; Write failed - retry
jsr sdcard_reset
dec CARD_TMP_RETRIES
bne sdcard_writesector_try_loop
; FALLTROUGH
sdcard_writesector_fail:
sec
rts
sdcard_writesector_verify:
; There is a bug in the SD controller; you have to read between writes,
; or it gets really upset
@1:
lda SD_CTL
and #$03
bne @1
lda #CARD_CMD_READ ; $02
sta SD_CTL
@2:
lda SD_CTL
and #$03
beq @2
@3: ; XXX deduplicate this ppart
lda SD_CTL
and #$03
bne @3
; FALLTROUGH
sdcard_writesector_verify_loop:
; Compare buffers
phx
phz
ldx #$00
ldz #$00
lda [CARD_BUFPNT1],z
cmp CARD_BUF, x
bne sdcard_writesector_verify_fail
lda [CARD_BUFPNT2],z
cmp CARD_BUF+$100, x
bne sdcard_writesector_verify_fail
inz
inx
bne sdcard_writesector_verify_loop
; FALLTROUGH
sdcard_writesector_verify_success:
plz
plx
clc
rts
sdcard_writesector_verify_fail:
plz
plx
sec
rts
;
; Helper routines
;
sdcard_writesector_copy_data:
; XXX use DMAgic for this
phz
phx
ldx #$00
ldz #$00
@1:
lda CARD_BUF,x
sta [CARD_BUFPNT1],z
lda CARD_BUF+$100,x
sta [CARD_BUFPNT2],z
inz
inx
bne @1
; Restore registers and quit
plx
plz
clc
rts
+89 -4
View File
@@ -7,13 +7,75 @@ util_dir_filesize_bytes: ; preserves .X
; Convert file size in bytes (32-bit value) to blocks, afterwards
; continue processing in 'util_dir_filesize_blocks'
; XXX temporary - calculate size in 254-byte blocks
lda PAR_FSIZE_BYTES+1
sta PAR_FSIZE_BLOCKS+0
; Start from handling some large values
lda PAR_FSIZE_BYTES+3
+bne util_dir_filesize_max ; file over 16MB size
lda PAR_FSIZE_BYTES+2
inc
+beq util_dir_filesize_max ; file over 8MB size
; Set initial size as 0 blocks
lda #$00
sta PAR_FSIZE_BLOCKS+0
sta PAR_FSIZE_BLOCKS+1
; Calculate number of blocks
ldy #$03
@lp:
lda PAR_FSIZE_BYTES+2
cmp util_dir_cmptab_hi,y
bcc @lp_next
bne @lp_adc_sbc
lda PAR_FSIZE_BYTES+1
cmp util_dir_cmptab_mi,y
bcc @lp_next
bne @lp_adc_sbc
lda PAR_FSIZE_BYTES+0
cmp util_dir_cmptab_lo,y
bcc @lp_next
@lp_adc_sbc:
clc
lda PAR_FSIZE_BLOCKS+0
adc util_dir_addtab_lo,y
sta PAR_FSIZE_BLOCKS+0
lda PAR_FSIZE_BLOCKS+1
adc util_dir_addtab_hi,y
sta PAR_FSIZE_BLOCKS+1
sec
lda PAR_FSIZE_BYTES+0
sbc util_dir_cmptab_lo, y
sta PAR_FSIZE_BYTES+0
lda PAR_FSIZE_BYTES+1
sbc util_dir_cmptab_mi, y
sta PAR_FSIZE_BYTES+1
lda PAR_FSIZE_BYTES+2
sbc util_dir_cmptab_hi, y
sta PAR_FSIZE_BYTES+2
bra @lp
@lp_next:
dey
bpl @lp
; Correct for bytes not filling in the whole block
lda PAR_FSIZE_BYTES+0
beq util_dir_filesize_blocks
inc PAR_FSIZE_BLOCKS+0
bne util_dir_filesize_blocks
inc PAR_FSIZE_BLOCKS+1
; FALLTROUGH
util_dir_filesize_blocks: ; preserves .X
@@ -95,3 +157,26 @@ util_dir_filesize_4: ; file size needs 4 digits
ldy #$00
rts
; Tables for calculating blocks from bytes
util_dir_addtab_hi:
!byte $00, $00 ; 2 next bytes same as in 'lo' table
util_dir_addtab_lo:
!byte $01, $10, $00, $00
util_dir_cmptab_hi:
!byte ^(254), ^(254 * 16), ^(254 * 16 * 16), ^(254 * 16 * 16 * 16), ^(254 * 16 * 16 * 16 * 16)
util_dir_cmptab_mi:
!byte >(254), >(254 * 16), >(254 * 16 * 16), >(254 * 16 * 16 * 16), >(254 * 16 * 16 * 16 * 16)
util_dir_cmptab_lo:
!byte <(254), <(254 * 16), <(254 * 16 * 16), <(254 * 16 * 16 * 16), <(254 * 16 * 16 * 16 * 16)