Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DOS/FAT32] enable selection of auto_tx and the fast write loop via U0>B #306

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions dos/functions.s
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
5 changes: 4 additions & 1 deletion fat32/fat32.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
3 changes: 3 additions & 0 deletions fat32/main.s
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@

.import sdcard_init
.import sdcard_check_alive
.import sdcard_set_fast_mode

.import fat32_set_time

Expand Down Expand Up @@ -103,3 +104,5 @@

jmp sdcard_init ; $C069
jmp sdcard_check_alive ; $C06C

jmp sdcard_set_fast_mode ; $C06F
2 changes: 1 addition & 1 deletion fat32/regs.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
117 changes: 71 additions & 46 deletions fat32/sdcard.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

;-----------------------------------------------------------------------------
Expand Down Expand Up @@ -329,8 +326,39 @@ sdcard_read_sector:
clc
rts

.ifdef FAST_READ
@start: ; Enable auto-tx mode
@start:
bit sd_fast
bvs @fast
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: since fast is hoped to eventually be the default, perhaps the branch should go to slow and fast should be a cycle faster?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The branch would be too far to jump over the fast routine, so nothing would be saved here.


@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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something for possible consideration: there could be a situation where for some reason the user's system cannot tolerate fast read or write (e.g. the system is overclocked or we enable a slower SPI bus to a Wi-Fi peripheral). It might be good to have a hard override that prevents setting fast reads or writes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you see this working?

For now, the variable gets initialized to 0 at boot (with the most recent push) and the user has to explicitly change it.

pha
lda #$c0
trb sd_fast
pla
and #3
lsr
ror
ror
tsb sd_fast
sec
rts
1 change: 1 addition & 0 deletions inc/fat32.inc
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ fat32_set_time = $C066
sdcard_init = $C069
sdcard_check_alive = $C06C

sdcard_set_fast_mode = $C06F
Loading