From b969c28cd4f3cb98e4cc2dc12b249888a084fd2d Mon Sep 17 00:00:00 2001 From: mooinglemur Date: Thu, 14 Mar 2024 20:33:18 -0700 Subject: [PATCH] [DOS/FAT32] enable selection of auto_tx and the fast write loop via U0>B (#306) * [DOS/FAT32] enable selection of auto_tx and the fast write loop via U0>B * we are not using the rest of the byte, but we should also avoid setting extraneous bits in it * handle initialization --- dos/functions.s | 4 +- fat32/fat32.s | 5 ++- fat32/main.s | 3 ++ fat32/regs.inc | 2 +- fat32/sdcard.s | 117 +++++++++++++++++++++++++++++------------------- inc/fat32.inc | 1 + 6 files changed, 82 insertions(+), 50 deletions(-) diff --git a/dos/functions.s b/dos/functions.s index b1bf45b6..543b8401 100644 --- a/dos/functions.s +++ b/dos/functions.s @@ -1095,10 +1095,10 @@ test_rom_checksum: ;--------------------------------------------------------------- ; set_fast_serial ; -; In: a fast serial (0/1) +; In: a fast serial (0/1/2/3) ;--------------------------------------------------------------- set_fast_serial: - ; do nothing + fat32_call sdcard_set_fast_mode lda #0 rts diff --git a/fat32/fat32.s b/fat32/fat32.s index e394b04c..2cf5cf93 100644 --- a/fat32/fat32.s +++ b/fat32/fat32.s @@ -9,7 +9,7 @@ .include "sdcard.inc" .include "text_input.inc" -.import sector_buffer, sector_buffer_end, sector_lba +.import sector_buffer, sector_buffer_end, sector_lba, sdcard_set_fast_mode .import filename_char_ucs2_to_internal, filename_char_internal_to_ucs2 .import filename_cp437_to_internal, filename_char_internal_to_cp437 @@ -1246,6 +1246,9 @@ fat32_init: ; No time set up sta fat32_time_year + lda #0 ; default to slow/traditional SD accesses + jsr sdcard_set_fast_mode + sec rts diff --git a/fat32/main.s b/fat32/main.s index 50ec7b5a..f2243fbe 100644 --- a/fat32/main.s +++ b/fat32/main.s @@ -54,6 +54,7 @@ .import sdcard_init .import sdcard_check_alive +.import sdcard_set_fast_mode .import fat32_set_time @@ -103,3 +104,5 @@ jmp sdcard_init ; $C069 jmp sdcard_check_alive ; $C06C + + jmp sdcard_set_fast_mode ; $C06F diff --git a/fat32/regs.inc b/fat32/regs.inc index 4d462e25..e4764684 100644 --- a/fat32/regs.inc +++ b/fat32/regs.inc @@ -54,5 +54,5 @@ ERRNO_OUT_OF_RESOURCES = 12 SPI_CTRL_SELECT_SDCARD = $01 SPI_CTRL_SELECT_MASK = $01 SPI_CTRL_SLOWCLK = $02 -SPI_CTRL_AUTOTX = $08 +SPI_CTRL_AUTOTX = $04 SPI_CTRL_BUSY = $80 diff --git a/fat32/sdcard.s b/fat32/sdcard.s index 02d3a5e4..f153d0dc 100755 --- a/fat32/sdcard.s +++ b/fat32/sdcard.s @@ -6,7 +6,7 @@ .include "lib.inc" .include "sdcard.inc" - .export sector_buffer, sector_buffer_end, sector_lba + .export sector_buffer, sector_buffer_end, sector_lba, sdcard_set_fast_mode .bss cmd_idx = sdcard_param @@ -22,14 +22,11 @@ sdcard_param: sector_lba: .res 4 ; dword (part of sdcard_param) - LBA of sector to read/write .res 1 +sd_fast: + .res 1 ; Bitmask: WR------ where R = auto_tx and W = fast writes timeout_cnt: .byte 0 -; XXX disabled for now; on real hardware, this returns -; XXX all 0xFE bytes with all tested SD cards -;FAST_READ=1 -;FAST_WRITE=1 - .code ;----------------------------------------------------------------------------- @@ -329,8 +326,39 @@ sdcard_read_sector: clc rts -.ifdef FAST_READ -@start: ; Enable auto-tx mode +@start: + bit sd_fast + bvs @fast + +@slow: + ; Read 512 bytes of sector data + ldx #$FF + ldy #0 +@3: stx SPI_DATA ; 4 +@4: bit SPI_CTRL ; 4 + bmi @4 ; 2 + 1 if branch + + lda SPI_DATA ; 4 + sta sector_buffer + 0, y + iny + bne @3 + + ; Y already 0 at this point +@5: stx SPI_DATA ; 4 +@6: bit SPI_CTRL ; 4 + bmi @6 ; 2 + 1 if branch + lda SPI_DATA ; 4 + sta sector_buffer + 256, y + iny + bne @5 + + ; Read CRC bytes + jsr spi_read + jsr spi_read + + jmp @after +@fast: + ; Enable auto-tx mode lda SPI_CTRL ora #SPI_CTRL_AUTOTX sta SPI_CTRL @@ -341,7 +369,7 @@ sdcard_read_sector: ; Efficiently read first 256 bytes (hide SPI transfer time) ldy #0 ; 2 -@3: lda SPI_DATA ; 4 +@3f: lda SPI_DATA ; 4 sta sector_buffer + 0, y ; 5 lda SPI_DATA ; 4 sta sector_buffer + 1, y ; 5 @@ -361,10 +389,10 @@ sdcard_read_sector: clc ; 2 adc #8 ; 2 tay ; 2 - bne @3 ; 2+1 + bne @3f ; 2+1 ; Efficiently read second 256 bytes (hide SPI transfer time) -@4: lda SPI_DATA ; 4 +@4f: lda SPI_DATA ; 4 sta sector_buffer + 256 + 0, y ; 5 lda SPI_DATA ; 4 sta sector_buffer + 256 + 1, y ; 5 @@ -384,7 +412,7 @@ sdcard_read_sector: clc ; 2 adc #8 ; 2 tay ; 2 - bne @4 ; 2+1 + bne @4f ; 2+1 ; Disable auto-tx mode lda SPI_CTRL @@ -393,33 +421,7 @@ sdcard_read_sector: ; Next read is now already done (first CRC byte), read second CRC byte jsr spi_read - -.else -@start: ; Read 512 bytes of sector data - ldx #$FF - ldy #0 -@3: stx SPI_DATA ; 4 -@4: bit SPI_CTRL ; 4 - bmi @4 ; 2 + 1 if branch - - lda SPI_DATA ; 4 - sta sector_buffer + 0, y - iny - bne @3 - - ; Y already 0 at this point -@5: stx SPI_DATA ; 4 -@6: bit SPI_CTRL ; 4 - bmi @6 ; 2 + 1 if branch - lda SPI_DATA ; 4 - sta sector_buffer + 256, y - iny - bne @5 - - ; Read CRC bytes - jsr spi_read - jsr spi_read -.endif +@after: ; Success jsr deselect sec @@ -448,22 +450,24 @@ sdcard_write_sector: lda #$FE jsr spi_write -.ifdef FAST_WRITE + bit sd_fast + bpl @slow ; Send 512 bytes of sector data ; NOTE: Direct access of SPI registers to speed up. ; Make sure 9 CPU clock cycles take longer than 640 ns (eg. CPU max 14MHz) ldy #0 -@1: lda sector_buffer, y ; 4 +@1f: lda sector_buffer, y ; 4 sta SPI_DATA ; 4 iny ; 2 - bne @1 ; 2 + 1 + bne @1f ; 2 + 1 ; Y already 0 at this point -@2: lda sector_buffer + 256, y ; 4 +@2f: lda sector_buffer + 256, y ; 4 sta SPI_DATA ; 4 iny ; 2 - bne @2 ; 2 + 1 -.else + bne @2f ; 2 + 1 + bra @after +@slow: ; Send 512 bytes of sector data ldy #0 @1: lda sector_buffer, y ; 4 @@ -476,7 +480,7 @@ sdcard_write_sector: spi_write_macro iny ; 2 bne @2 ; 2 + 1 -.endif +@after: ; Dummy CRC lda #0 jsr spi_write @@ -558,3 +562,24 @@ sdcard_check_alive: jsr deselect plp rts + +;----------------------------------------------------------------------------- +; sdcard_set_fast_mode +; +; .A = 0: fast mode off +; .A = 1: fast reads +; .A = 2: fast writes +; .A = 3: fast reads and writes +;----------------------------------------------------------------------------- +sdcard_set_fast_mode: + pha + lda #$c0 + trb sd_fast + pla + and #3 + lsr + ror + ror + tsb sd_fast + sec + rts diff --git a/inc/fat32.inc b/inc/fat32.inc index 8af3e2be..115413b5 100644 --- a/inc/fat32.inc +++ b/inc/fat32.inc @@ -43,3 +43,4 @@ fat32_set_time = $C066 sdcard_init = $C069 sdcard_check_alive = $C06C +sdcard_set_fast_mode = $C06F