Files
super6502/sw/test_code/sd_controller_test/main.s
2024-07-20 21:40:26 -07:00

171 lines
3.6 KiB
ArmAsm

.export _init, _nmi_int, _irq_int
.include "zeropage.inc"
.autoimport
.segment "VECTORS"
.addr _nmi_int ; NMI vector
.addr _init ; Reset vector
.addr _irq_int ; IRQ/BRK vector
SD_CONTROLLER = $e000
SD_CMD = SD_CONTROLLER
SD_ARG = SD_CONTROLLER + $4
SD_DATA = SD_ARG
SD_FIFO_0 = SD_CONTROLLER + $8
SD_FIFO_2 = SD_CONTROLLER + $C
SD_PHY = SD_CONTROLLER + $10
SD_PHY_CLKDIV = SD_PHY
SD_PHY_CLKCTRL = SD_PHY + $1
SD_PHY_SAMP_VOLT = SD_PHY + $2
SD_PHY_BLKSIZ = SD_PHY + $3
SD_DMA_BASE = SD_CONTROLLER + $28
SD_DMA_STAT_CTRL = SD_CONTROLLER + $2C
SDIOCLK_100KHZ = $FC
SPEED_512B = $09
.zeropage
rca: .res 4
.code
_nmi_int:
_irq_int:
_init:
ldx #$ff
txs
cld
lda #<(__STACKSTART__ + __STACKSIZE__)
sta sp
lda #>(__STACKSTART__ + __STACKSIZE__)
sta sp+1
stz SD_PHY_CLKCTRL
stz SD_PHY_SAMP_VOLT
lda #SPEED_512B
sta SD_PHY_BLKSIZ
lda #SDIOCLK_100KHZ
sta SD_PHY_CLKDIV
@wait_clk: lda SD_PHY_CLKDIV
cmp #SDIOCLK_100KHZ
bne @wait_clk
; send_goidle();
jsr send_goidle
; send_r1(8, 0x1aa);
lda #$0
sta sreg+1
lda #$0
sta sreg
ldx #$01
lda #$aa
jsr pusheax
lda #$08
jsr send_r1
@acmd41:
; send_r1(55, 0x00);
lda #$0
sta sreg+1
lda #$0
sta sreg
ldx #$00
lda #$00
jsr pusheax
lda #55
jsr send_r1
; send_r1(41, 0x4000ff80);
lda #$40
sta sreg+1
lda #$0
sta sreg
ldx #$ff
lda #$80
jsr pusheax
lda #41
jsr send_r1
lda sreg+1
bpl @acmd41
; cmd 11
; cmd 2
; cmd 3
@end:
bra @end
wait_busy: lda SD_CMD+$1
bit #$40
bne wait_busy
rts
; No arguments, no response
; sends cmd0
; also clears removed and error flags?
send_goidle:
stz SD_ARG+$3
stz SD_ARG+$2
stz SD_ARG+$1
stz SD_ARG
stz SD_CMD+$3
lda #$04
sta SD_CMD+$2
lda #$80
sta SD_CMD+$1
lda #$40
sta SD_CMD
jsr wait_busy
rts
; Command in A
; Arg on stack as 32 bits
; returns the response in eax
; (How can we signal a failure then?)
send_r1:
pha ; push command to stack
jsr popeax
PHA
stx SD_ARG+$1
lda sreg
sta SD_ARG+$2
lda sreg+1
sta SD_ARG+$3
pla
sta SD_ARG ; lsb has to be the last written.
lda #$81 ; This also clears error flag (only for acmd41?)
sta SD_CMD+$1
pla
ora #$40
sta SD_CMD
jsr wait_busy
lda SD_DATA + $3
sta sreg+1
lda SD_DATA + $2
sta sreg
ldx SD_DATA + $1
lda SD_DATA
rts