diff --git a/hw/super6502_fpga/src/sim/Makefile b/hw/super6502_fpga/src/sim/Makefile index 68ce51d..e1930d4 100644 --- a/hw/super6502_fpga/src/sim/Makefile +++ b/hw/super6502_fpga/src/sim/Makefile @@ -9,6 +9,7 @@ INCLUDE=include/sdram_controller_define.vh TB_NAME=sim_top COPY_FILES=addr_map.mem init_hex.mem +SD_IMAGE=sd_image.bin FLAGS=-DSIM -DRTL_SIM -DVERILATOR -DSDIO_AXI @@ -17,9 +18,12 @@ all: waves waves: $(TB_NAME) ./$(TB_NAME) -fst -$(TB_NAME): $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) $(COPY_FILES) +$(TB_NAME): $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) $(COPY_FILES) $(SD_IMAGE) iverilog -g2005-sv $(FLAGS) -s $@ -o $@ $(INCLUDE) $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) -I ../../ +$(SD_IMAGE): + dd if=/dev/urandom bs=1 count=65536 of=$(SD_IMAGE) + # I feel like this should also realize that the outside files are newer... .PHONY: $(COPY_FILES) $(COPY_FILES): ../../$@ diff --git a/hw/super6502_fpga/src/sim/hvl/sim_top.sv b/hw/super6502_fpga/src/sim/hvl/sim_top.sv index 4abf8e6..35db4bb 100644 --- a/hw/super6502_fpga/src/sim/hvl/sim_top.sv +++ b/hw/super6502_fpga/src/sim/hvl/sim_top.sv @@ -180,7 +180,8 @@ IOBUF dat_buf ( ); mdl_sdio #( - .LGMEMSZ(16) + .LGMEMSZ(16), + .MEMFILE("sd_image.bin") ) u_sd_card_emu ( .sd_clk(o_sd_clk), .sd_cmd(w_sd_cmd), diff --git a/hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi b/hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi index f10a377..d91f6a7 160000 --- a/hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi +++ b/hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi @@ -1 +1 @@ -Subproject commit f10a377dcec804bb8cba6d9a2239d3693044a1d5 +Subproject commit d91f6a77fac91a85cd0d1b96bb0d2c472ae35f23 diff --git a/sw/test_code/sd_controller_test/link.ld b/sw/test_code/sd_controller_test/link.ld index 974a662..da9724e 100644 --- a/sw/test_code/sd_controller_test/link.ld +++ b/sw/test_code/sd_controller_test/link.ld @@ -1,6 +1,7 @@ MEMORY { RAM: start = $0000, size = $200; + SDRAM: start = $200, size = $de00; ROM: start = $F000, size = $1000, file = %O; } diff --git a/sw/test_code/sd_controller_test/main.s b/sw/test_code/sd_controller_test/main.s index d2d8005..480057a 100644 --- a/sw/test_code/sd_controller_test/main.s +++ b/sw/test_code/sd_controller_test/main.s @@ -16,7 +16,7 @@ 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_FIFO_1 = SD_CONTROLLER + $C SD_PHY = SD_CONTROLLER + $10 @@ -25,12 +25,12 @@ 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 +SD_DMA_BASE = SD_CONTROLLER + $14 +SD_DMA_BASE2 = SD_CONTROLLER + $18 +SD_DMA_LEN = SD_CONTROLLER + $1C SDIOCLK_100KHZ = $FC +SDIOCLK_25MHZ = $03 SPEED_512B = $09 .zeropage @@ -102,9 +102,94 @@ _init: lda sreg+1 bpl @acmd41 - ; cmd 11 - ; cmd 2 - ; cmd 3 + ; send_r2(2, 0x00); + stz sreg+1 + stz sreg + ldx #$00 + lda #$00 + jsr pusheax + lda #2 + jsr send_r2 + + lda SD_FIFO_0 + lda SD_FIFO_0 + lda SD_FIFO_0 + lda SD_FIFO_0 + + ; send_r1(3, 0x00); + stz sreg+1 + stz sreg + ldx #$00 + lda #$00 + jsr pusheax + lda #3 + jsr send_r1 + + lda #$30 + sta SD_PHY_CLKCTRL + stz SD_PHY_SAMP_VOLT + lda #SPEED_512B + sta SD_PHY_BLKSIZ + lda #SDIOCLK_25MHZ + sta SD_PHY_CLKDIV + +@wait_clk2: lda SD_PHY_CLKDIV + cmp #SDIOCLK_25MHZ + bne @wait_clk2 + + ; The upper 16 bits are the RCA, but they are already in sreg + ; The lower 16 are don't cares, so we can leave them. + + jsr pusheax + lda #7 + jsr send_r1b + + ; Now we need to DMA the first sector into memory, say at $1000 + ; The example code reads multiple, but we can probably just read 1 (cmd17) + ; write to address $1000 + ; dma length is 1 + stz SD_DMA_BASE+$3 + stz SD_DMA_BASE+$2 + lda #$10 + sta SD_DMA_BASE+$1 + stz SD_DMA_BASE + + stz SD_DMA_LEN + $3 + stz SD_DMA_LEN + $2 + stz SD_DMA_LEN + $1 + lda #$01 + sta SD_DMA_LEN + + ; address 0 + stz sreg+1 + stz sreg + ldx #$00 + lda #$00 + jsr pusheax + lda #18 + jsr send_dma + + ; Try reading again just to make sure it works. + stz SD_DMA_BASE+$3 + stz SD_DMA_BASE+$2 + lda #$12 + sta SD_DMA_BASE+$1 + stz SD_DMA_BASE + + stz SD_DMA_LEN + $3 + stz SD_DMA_LEN + $2 + stz SD_DMA_LEN + $1 + lda #$01 + sta SD_DMA_LEN + + ; address 0 + stz sreg+1 + stz sreg + ldx #$00 + lda #$02 + jsr pusheax + lda #18 + jsr send_dma @end: @@ -142,8 +227,23 @@ send_goidle: ; 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 +send_r1: stz tmp1 + inc tmp1 + bra send + +send_r1b: stz tmp1 + inc tmp1 + inc tmp1 + inc tmp1 + bra send + +send_dma: pha + lda #$20 + sta tmp1 + pla + bra send + +send: pha ; push command to stack jsr popeax PHA stx SD_ARG+$1 @@ -153,7 +253,8 @@ send_r1: 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?) + lda #$80 ; This also clears error flag (only for acmd41?) + ora tmp1 sta SD_CMD+$1 pla ora #$40 @@ -168,4 +269,29 @@ send_r1: ldx SD_DATA + $1 lda SD_DATA + rts + +; Command in A +; Arg on stack as 32 bits +; returns the response in eax +; (How can we signal a failure then?) +send_r2: + 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 #$82 ; This also clears error flag (only for acmd41?) + sta SD_CMD+$1 + pla + ora #$40 + sta SD_CMD + + jsr wait_busy + rts \ No newline at end of file