440 lines
8.7 KiB
ArmAsm
440 lines
8.7 KiB
ArmAsm
/********************************************************************/
|
|
// sd card
|
|
/********************************************************************/
|
|
#define dspi_dtar0 0x0c
|
|
#define dspi_dsr 0x2c
|
|
#define dspi_dtfr 0x34
|
|
#define dspi_drfr 0x38
|
|
|
|
#define LONGASC(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | (d))
|
|
|
|
#define MCF_PAD_PAR_DSPI (__MBAR+0xA50)
|
|
#define MCF_PSC0_PSCTB_8BIT (__MBAR+0x860C)
|
|
#define MCF_DSPI_DMCR (__MBAR+0x8A00)
|
|
#define MCF_SLT0_SCNT (__MBAR + 0x908)
|
|
|
|
.text
|
|
|
|
warte_10ms:
|
|
move.l d0,-(sp)
|
|
move.l MCF_SLT0_SCNT,d0
|
|
sub.l #1320000,d0
|
|
warte_d6:
|
|
cmp.l MCF_SLT0_SCNT,d0
|
|
bcs warte_d6
|
|
move.l (sp)+,d0
|
|
rts
|
|
|
|
warte_1ms:
|
|
move.l d0,-(sp)
|
|
move.l MCF_SLT0_SCNT,d0
|
|
sub.l #132000,d0
|
|
warte_d5:
|
|
cmp.l MCF_SLT0_SCNT,d0
|
|
bcs warte_d5
|
|
move.l (sp)+,d0
|
|
rts
|
|
|
|
.global sd_idle
|
|
.global sd_init
|
|
|
|
sd_init:
|
|
lea MCF_PSC0_PSCTB_8BIT,a6
|
|
move.l #LONGASC('S', 'D', '-', 'C'),(a6)
|
|
move.l #LONGASC('a', 'r', 'd', ' '),(a6)
|
|
|
|
move.l buffer,a5 // basis addresse (diesen bereich brauchen wir nicht mehr!)
|
|
move.l #0x1fffffff,d0 // normal dspi
|
|
move.l d0,MCF_PAD_PAR_DSPI
|
|
lea MCF_DSPI_DMCR,a0
|
|
move.l #0x800d3c00,(a0) // 8 bit cs5 on
|
|
move.l #0x38558897,d0
|
|
move.l d0,dspi_dtar0(a0) // 400kHz
|
|
move.l #0x082000ff,d4 // tx vorbesetzen
|
|
mov3q.l #-1,dspi_dsr(a0)
|
|
|
|
bsr.l warte_1ms
|
|
move.l #0xc00d3c00,(a0) // 8 bit 4MHz clocken cs off
|
|
bsr.l warte_10ms
|
|
move.l #0x800d3c00,(a0) // 8 bit 4MHz normal cs on
|
|
bsr sd_com
|
|
bsr sd_com
|
|
bsr sd_com
|
|
bsr sd_com
|
|
bsr sd_com
|
|
bsr sd_com
|
|
bsr sd_com
|
|
bsr sd_com
|
|
bsr sd_com
|
|
bsr sd_com
|
|
move.l #0x802d3c00,(a0) // 8 bit 4MHz normal cs off
|
|
clr.b d4
|
|
bsr sd_com
|
|
bsr sd_com
|
|
move.l #0x800d3c00,(a0) // 8 bit 4MHz normal cs on
|
|
move.b #0xff,d4
|
|
bsr sd_com
|
|
bsr sd_com
|
|
move.l #0x802d3c00,(a0) // 8 bit 4MHz normal cs off
|
|
bsr.l warte_10ms
|
|
|
|
// sd idle
|
|
move.l #100,d6 // 100 versuche
|
|
move.l #10,d3 // 10 versuche
|
|
sd_idle:
|
|
move.b #0xff,d4 // receive byt
|
|
bsr sd_com
|
|
move.b #0x40,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #0x95,d4
|
|
bsr sd_com
|
|
|
|
move.b #0xff,d4 // receive byt
|
|
bsr sd_com
|
|
cmp.b #0x01,d5
|
|
beq idle_end
|
|
bsr sd_com
|
|
cmp.b #0x01,d5
|
|
beq idle_end
|
|
bsr sd_com
|
|
cmp.b #0x01,d5
|
|
beq idle_end
|
|
bsr sd_com
|
|
cmp.b #0x01,d5
|
|
beq idle_end
|
|
bsr sd_com
|
|
cmp.b #0x01,d5
|
|
beq idle_end
|
|
bsr sd_com
|
|
cmp.b #0x01,d5
|
|
beq idle_end
|
|
subq.l #1,d6
|
|
beq sd_not
|
|
bra sd_idle
|
|
idle_end:
|
|
// cdm 8
|
|
read_ic:
|
|
move.b #0xff,d4 // receive byt
|
|
bsr sd_com
|
|
move.b #0x48,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #0x01,d4
|
|
bsr sd_com
|
|
move.b #0xaa,d4
|
|
bsr sd_com
|
|
move.b #0x87,d4
|
|
bsr sd_com
|
|
|
|
bsr sd_get_status
|
|
cmp.b #5,d5
|
|
beq sd_v1
|
|
cmp.b #1,d5
|
|
bne read_ic
|
|
|
|
move.b #0xff,d4
|
|
bsr sd_com
|
|
move.b d5,d0
|
|
bsr sd_com
|
|
move.b d5,d1
|
|
bsr sd_com
|
|
move.b d5,d2
|
|
bsr sd_com
|
|
cmp.b #0xaa,d5
|
|
bne sd_testd3
|
|
move.l #LONGASC('S', 'D', 'H', 'C'),(a6)
|
|
move.b #' ',(a6)
|
|
sd_v1:
|
|
|
|
// cdm 58
|
|
read_ocr:
|
|
move.b #0xff,d4 // receive byt
|
|
bsr sd_com
|
|
move.b #0x7a,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #0x00,d4
|
|
bsr sd_com
|
|
move.b #0x00,d4
|
|
bsr sd_com
|
|
move.b #0x01,d4
|
|
bsr sd_com
|
|
|
|
bsr sd_get_status
|
|
move.l #LONGASC('V', 'e', 'r', '1'),d6
|
|
cmp.b #5,d5
|
|
beq read_ocr
|
|
cmp.b #1,d5
|
|
bne read_ocr
|
|
|
|
move.b #0xff,d4
|
|
bsr sd_com
|
|
move.b d5,d0
|
|
bsr sd_com
|
|
move.b d5,d1
|
|
bsr sd_com
|
|
move.b d5,d2
|
|
bsr sd_com
|
|
|
|
// acdm 41
|
|
move.l #20000,d6 // 20000 versuche ready can bis 1 sec gehen
|
|
wait_of_aktiv:
|
|
move.b #0xff,d4 // receive byt
|
|
bsr sd_com
|
|
move.b #0x77,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #0x95,d4
|
|
bsr sd_com
|
|
|
|
bsr sd_get_status
|
|
cmp.b #0x05,d5
|
|
beq wait_of_aktiv
|
|
|
|
wait_of_aktiv2:
|
|
move.b #0xff,d4 // receive byt
|
|
bsr sd_com
|
|
move.b #0x69,d4
|
|
bsr sd_com
|
|
move.b #0x40,d4
|
|
bsr sd_com
|
|
move.b #0x00,d4
|
|
bsr sd_com
|
|
move.b #0x00,d4
|
|
bsr sd_com
|
|
move.b #0x00,d4
|
|
bsr sd_com
|
|
move.b #0x95,d4
|
|
bsr sd_com
|
|
|
|
bsr sd_get_status
|
|
tst.b d5
|
|
beq sd_init_ok
|
|
cmp.b #0x05,d5
|
|
beq wait_of_aktiv2
|
|
subq.l #1,d6
|
|
bne wait_of_aktiv
|
|
sd_testd3:
|
|
subq.l #1,d3
|
|
bne sd_idle
|
|
bra sd_error
|
|
|
|
sd_init_ok:
|
|
// cdm 10
|
|
read_cid:
|
|
move.b #0xff,d4 // receive byt
|
|
bsr sd_com
|
|
move.b #0x4a,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #0x00,d4
|
|
bsr sd_com
|
|
move.b #0x00,d4
|
|
bsr sd_com
|
|
move.b #0x95,d4
|
|
bsr sd_com
|
|
|
|
move.l a5,a4 // adresse setzen
|
|
bsr sd_rcv_info
|
|
|
|
// name ausgeben
|
|
lea 1(a5),a4
|
|
moveq #7,d7
|
|
sd_nam_loop:
|
|
move.b (a4)+,(a6)
|
|
subq.l #1,d7
|
|
bne sd_nam_loop
|
|
move.b #' ',(a6)
|
|
|
|
// cdm 9
|
|
read_csd:
|
|
move.b #0xff,d4 // receive byt
|
|
bsr sd_com
|
|
move.b #0x49,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #00,d4
|
|
bsr sd_com
|
|
move.b #0x00,d4
|
|
bsr sd_com
|
|
move.b #0x00,d4
|
|
bsr sd_com
|
|
move.b #0x01,d4
|
|
bsr sd_com
|
|
|
|
move.l a5,a4 // adresse setzen
|
|
bsr sd_rcv_info
|
|
|
|
mvz.b (a5),d0
|
|
lsr.l #6,d0
|
|
|
|
bne sd_csd2 // format v2
|
|
move.l 6(a5),d1
|
|
moveq #14,d0 // bit 73..62 c_size
|
|
lsr.l d0,d1 // bits extrahieren
|
|
and.l #0xfff,d1 // 12 bits
|
|
addq.l #1,d1
|
|
mvz.w 9(a5),d0
|
|
lsr.l #7,d0 // bits 49..47
|
|
and.l #0x7,d0 // 3 bits
|
|
moveq.l #8,d2 // x256 (dif v1 v2)
|
|
sub.l d0,d2
|
|
lsr.l d2,d1
|
|
bra sd_print_size
|
|
sd_csd2:
|
|
mvz.w 8(a5),d1
|
|
addq.l #1,d1
|
|
sd_print_size:
|
|
swap d1
|
|
lsl.l #1,d1
|
|
bcc sd_16G
|
|
move.l #LONGASC('3', '2', 'G', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_16G:
|
|
lsl.l #1,d1
|
|
bcc sd_8G
|
|
move.l #LONGASC('1', '6', 'G', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_8G:
|
|
lsl.l #1,d1
|
|
bcc sd_4G
|
|
move.l #LONGASC(' ', '4', 'G', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_4G:
|
|
lsl.l #1,d1
|
|
bcc sd_2G
|
|
move.l #LONGASC(' ', '4', 'G', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_2G:
|
|
lsl.l #1,d1
|
|
bcc sd_1G
|
|
move.l #LONGASC(' ', '2', 'G', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_1G:
|
|
lsl.l #1,d1
|
|
bcc sd_512M
|
|
move.l #LONGASC(' ', '1', 'G', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_512M:
|
|
lsl.l #1,d1
|
|
bcc sd_256M
|
|
move.b #'5',(a6)
|
|
move.l #LONGASC('1', '2', 'M', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_256M:
|
|
lsl.l #1,d1
|
|
bcc sd_128M
|
|
move.b #'2',(a6)
|
|
move.l #LONGASC('5', '6', 'M', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_128M:
|
|
lsl.l #1,d1
|
|
bcc sd_64M
|
|
move.b #'1',(a6)
|
|
move.l #LONGASC('2', '8', 'M', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_64M:
|
|
lsl.l #1,d1
|
|
bcc sd_32M
|
|
move.l #LONGASC('6', '4', 'M', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_32M:
|
|
lsl.l #1,d1
|
|
bcc sd_16M
|
|
move.l #LONGASC('3', '2', 'M', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_16M:
|
|
lsl.l #1,d1
|
|
bcc sd_8M
|
|
move.l #LONGASC('1', '6', 'M', 'B'),(a6)
|
|
bra sd_ok
|
|
sd_8M:
|
|
move.l #LONGASC('<', '9', 'M', 'B'),(a6)
|
|
sd_ok:
|
|
move.l #LONGASC(' ', 'O', 'K', '!'),(a6)
|
|
move.l #0x0a0d,(a6)
|
|
//halt
|
|
//halt
|
|
rts
|
|
// subs ende -------------------------------
|
|
sd_V1:
|
|
move.l #LONGASC('n', 'o', 'n', '!'),(a6)
|
|
move.l #0x0a0d,(a6)
|
|
//halt
|
|
//halt
|
|
rts
|
|
sd_error:
|
|
move.l #LONGASC('E', 'r', 'r', 'o'),(a0)
|
|
move.l #LONGASC('r', '!', '', ''), (a0)
|
|
move.l #0x0a0d,(a6)
|
|
halt
|
|
halt
|
|
rts
|
|
sd_not:
|
|
move.l #LONGASC('n', 'o', 'n', '!'),(a0)
|
|
move.l #0x0a0d,(a6)
|
|
halt
|
|
halt
|
|
rts
|
|
|
|
// status holen -------------------------------
|
|
sd_get_status:
|
|
move.b #0xff,d4
|
|
bsr sd_com
|
|
cmp.b #0xff,d5
|
|
beq sd_get_status
|
|
rts
|
|
// byt senden und holen ---------------------
|
|
sd_com:
|
|
move.l d4,dspi_dtfr(a0)
|
|
wait_auf_complett:
|
|
btst.b #7,dspi_dsr(a0)
|
|
beq wait_auf_complett
|
|
move.l dspi_drfr(a0),d5
|
|
mov3q.l #-1,dspi_dsr(a0) // clr status register
|
|
rts
|
|
|
|
// daten holen ----------------------------
|
|
sd_rcv_info:
|
|
moveq #18,d3 // 16 byts + 2 byts crc
|
|
move.b #0xff,d4
|
|
sd_rcv_rb_w:
|
|
bsr sd_get_status
|
|
cmp.b #0xfe,d5 // daten bereit?
|
|
bne sd_rcv_rb_w // nein->
|
|
sd_rcv_rd_rb:
|
|
bsr sd_com
|
|
move.b d5,(a4)+
|
|
subq.l #1,d3
|
|
bne sd_rcv_rd_rb
|
|
rts
|
|
/******************************************/
|
|
|
|
.data
|
|
buffer: dc.l 0, 0, 0, 0, 0, 0, 0, 0
|