/********************************************************************/
// sd card
/********************************************************************/
#define	dspi_dtar0	0x0c
#define	dspi_dsr	0x2c	
#define	dspi_dtfr	0x34	
#define	dspi_drfr	0x38

.text	
sd_test:
		lea			MCF_PSC0_PSCTB_8BIT,a6
		move.l  	#'SD-C',(a6)
		move.l  	#'ard ',(a6)

		move.l		#__Bas_base,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			warte_1ms
		move.l		#0xc00d3c00,(a0)			// 8 bit 4MHz clocken cs off
		bsr			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			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		#'SDHC',(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		#'Ver1',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		#'32GB',(a6)
		bra			sd_ok
sd_16G:
		lsl.l		#1,d1
		bcc			sd_8G
		move.l		#'16GB',(a6)
		bra			sd_ok
sd_8G:
		lsl.l		#1,d1
		bcc			sd_4G
		move.l		#' 8GB',(a6)
		bra			sd_ok
sd_4G:
		lsl.l		#1,d1
		bcc			sd_2G
		move.l		#' 4GB',(a6)
		bra			sd_ok
sd_2G:
		lsl.l		#1,d1
		bcc			sd_1G
		move.l		#' 2GB',(a6)
		bra			sd_ok
sd_1G:
		lsl.l		#1,d1
		bcc			sd_512M
		move.l		#' 1GB',(a6)
		bra			sd_ok
sd_512M:
		lsl.l		#1,d1
		bcc			sd_256M
		move.b		#'5',(a6)
		move.l		#'12MB',(a6)
		bra			sd_ok
sd_256M:
		lsl.l		#1,d1
		bcc			sd_128M
		move.b		#'2',(a6)
		move.l		#'56MB',(a6)
		bra			sd_ok
sd_128M:
		lsl.l		#1,d1
		bcc			sd_64M
		move.b		#'1',(a6)
		move.l		#'28MB',(a6)
		bra			sd_ok
sd_64M:
		lsl.l		#1,d1
		bcc			sd_32M
		move.l		#'64MB',(a6)
		bra			sd_ok
sd_32M:
		lsl.l		#1,d1
		bcc			sd_16M
		move.l		#'32MB',(a6)
		bra			sd_ok
sd_16M:
		lsl.l		#1,d1
		bcc			sd_8M
		move.l		#'16MB',(a6)
		bra			sd_ok
sd_8M:
		move.l		#'<9MB',(a6)
sd_ok:		
		move.l  	#' OK!',(a6)
		move.l		#0x0a0d,(a6)
		halt
		halt
		rts
// subs ende -------------------------------
sd_V1:
		move.l  #'non!',(a6)
		move.l	#0x0a0d,(a6)
		halt
		halt
		rts
sd_error:
		move.l  #'Erro',(a6)
		move.l  #'r!',(a6)
		move.l	#0x0a0d,(a6)
		halt
		halt
		rts
sd_not:
		move.l  #'non!',(a6)
		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
/******************************************/
