diff --git a/src/aliases/,aliases_hardware_m65.s b/src/aliases/,aliases_hardware_m65.s index ad72e0e2..b05afa32 100644 --- a/src/aliases/,aliases_hardware_m65.s +++ b/src/aliases/,aliases_hardware_m65.s @@ -32,6 +32,12 @@ !addr C65_EXTKEYS_PR = $D607 !addr C65_EXTKEYS_DDR = $D608 + ; SD card + + !addr SD_CTL = $D680 + !addr SD_ADDR = $D681 ; 4 bytes + !addr SD_ERRCODE = $D6DA + ; DMAgic !addr DMA_ADDRLSBTRIG = $D700 diff --git a/src/dos_m65/m65_sdcard.s b/src/dos_m65/m65_sdcard.s index c27b2f7b..b6e6735a 100644 --- a/src/dos_m65/m65_sdcard.s +++ b/src/dos_m65/m65_sdcard.s @@ -18,33 +18,21 @@ !addr TMP_STEP = $89 ; 4 bytes -; Hardware - -!addr SD_CTL = $D680 -!addr SD_ADDR = $D681 ; 4 bytes -!addr SD_ERRCODE = $D6DA - - -; XXX SD_SECTORBUF = 0xffd6e00L; +; XXX hardware address SD_SECTORBUF = 0xffd6e00L; -m65_sdcard_init: ; to be called during DOS initialization +m65_sdcard_init: lda #$00 sta CARD_IS_SDHC jsr m65_sdcard_reset - ; FALLTROUGH - -m65_sdcard_init_gettype: - - ; First work out if this is SD or SDHC card - ; SD cards can't read at non-sector aligned addresses + ; Try to read first sector to see if card is operable lda #$00 sta SD_ADDR+0 @@ -52,22 +40,67 @@ m65_sdcard_init_gettype: sta SD_ADDR+2 sta SD_ADDR+3 - ; Trigger read + 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_CTL - - ; XXX + 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_getsize: +m65_sdcard_init_sdhc: - ; Put $00200000 to TMP_STEP and TMP_SECNUM + lda #$80 + sta CARD_IS_SDHC - ; XXX this should probably be initialized in a loop + ; Prepare data for determining card size - put $00200000 to TMP_STEP and TMP_SECNUM + + ; SDHC claims 32GB limit, and reading from beyond that might cause + ; trouble. However, 32bits x 512byte sectors = 16TB addressable. + ; It thus seems that the top byte of the address may not be safe to use, + ; or at least the top few bits. + + ; XXX this should be initialized to 0 in a loop + + lda #$00 + sta TMP_SECNUM+0 + sta TMP_STEP+0 + sta TMP_SECNUM+1 + sta TMP_STEP+1 + sta TMP_SECNUM+2 + sta TMP_STEP+2 + + lda #$02 + sta TMP_SECNUM+3 + sta TMP_STEP+3 + + bra m65_sdcard_init_getsize + +m65_sdcard_init_sdsc: + + lda #$00 + sta CARD_IS_SDHC + lda #$40 ; use byte addressing + sta SD_CTL + + ; Prepare data for determining card size - put $00200000 to TMP_STEP and TMP_SECNUM + + ; XXX this should be initialized to 0 in a loop lda #$00 sta TMP_SECNUM+0 @@ -81,7 +114,55 @@ m65_sdcard_init_getsize: sta TMP_SECNUM+2 sta TMP_STEP+2 - ;; XXX finish + ; 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) + + ; XXX finish + + + + + + + + + + + + + +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 @@ -97,16 +178,42 @@ m65_sdcard_reset: sty SD_CTL ; Wait till SD card resets -@1: +@3: lda SD_CTL and #$03 - bne @1 + bne @3 ; For SDHC card set appropriate mode bit CARD_IS_SDHC - bpl @2 + bpl @4 inx ; $41 stx SD_CTL -@2: +@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 diff --git a/src/kernal/iec/iec_wait1ms.s b/src/kernal/iec/iec_wait1ms.s index 435d9dba..4412d0f4 100644 --- a/src/kernal/iec/iec_wait1ms.s +++ b/src/kernal/iec/iec_wait1ms.s @@ -23,7 +23,7 @@ iec_wait1ms: ; FALLTROUGH -wait_x_bars: ; additional entry point for delayy in screen and tape support +wait_x_bars: ; additional entry point for delay in screen and tape support ; has to preserve .Y and put .X to 0 lda VIC_RASTER