;******************************
;*
;* sdCardReadBlocks
;*
;* r1:r0 = destination address 
;* r3:r2 = startblock
;* r4	 = block count - 1
;*	
;* return
;*
;* r0	 = 0 (load ok)
;*

sdCardReadBlocks

	;prolog

	push	r5
	push	r6
	push	r7
	
	;setup burst address
	
	movei	r5,$10
	movei	r6,$00
	moveih	r5,$00
	moveih	r6,$A0		;sd card base + $10
	nop
	
	esadr	r6,r5
	
	movei	r5,2		;enable burst
	
	est	r0,2		;low
	est	r1,3		;high
	est	r5,0		;enable burst (push total fifo out)
	
	; r3:r2 = startblock , r4	 = block count - 1
	
blockLoop

	push	r2
	push	r3
	push	r4
	
	;display to 7seg (debug)

	; gpci	r7,2		;next 4 + X
	; br	longToHexMap
	; or	r1,r2,r2	;delay slot
	; or	r0,r3,r3	;delay slot
	; nop			;delay slot
	; nop			;delay slot
		
	; gpci	r7,2		;next 4 + X
	; br	drawHex
	; nop			;delay slot
	; nop			;delay slot
	; nop			;delay slot
	; nop			;delay slot
	
	;---> block loop (r3:r2 = current block)
	
	;reset reciver
	
	movei	r5,$10
	movei	r6,$00
	moveih	r5,$00
	moveih	r6,$A0		;sd card base + $15
	movei	r0,3		;reset reciver , burst enable
	
	esadr	r6,r5
	est	r0,0
	
	;is sdhc (no -> current block * 512)
	
	movei	r0,sdCardIsSDHC
	nop
	moveih	r0,>sdCardIsSDHC
	nop
	rqldi	r0,0
	nop
	nop
	ld	r0
	nop
	cmpeqi	r0,0
	brtc	sdhcBlkCalcContinue	;is sdhc so in blocks
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;r3:r2 * 512
	
	;r3                  r2
	;aaaa aaaa bbbb bbbb cccc cccc dddd dddd
	;bbbb bbbc cccc cccd dddd ddd0 0000 0000 
	
	moveih	r3,0		;r3 = 0000 0000 bbbb bbbb *1
	or	r0,r2,r2	;r0 = cccc cccc dddd dddd *2
	moveih	r2,0		;r2 = dddd dddd 0000 0000 *3
	swp	r3,r3		;r3 = bbbb bbbb 0000 0000 *4
	swp	r2,r2		;r2 = dddd dddd cccc cccc *5
	add	r3,r3,r3	;r3 = bbbb bbb0 0000 0000 *6	
	lsri	r0,7		;r0 = 0000 000c cccc cccd *7
	add	r2,r2,r2	;r2 = dddd ddd0 0000 0000 *8
	or	r3,r3,r0	;r3 = bbbb bbbc cccc cccd *9
		
sdhcBlkCalcContinue

	;send single block read (CMD17)
			
	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	movei	r0,17		;cmd		delay slot
	or	r1,r2,r2	;r1 arg low 	delay slot
	or	r2,r3,r3	;r2 arg high 	delay slot
	movei	r3,0		;48 bit		delay slot
	
	;recive
	
	gpci	r7,2		;next 4 + X
	br	sdCardReciveCmd
	movei	r1,$ff		;			delay slot
	nop			;			delay slot
	moveih	r1,$ff		;65536 = timeout 	delay slot
	nop			;			delay slot
	
	;test recive result [ r0 = status (4 = ok | 2 = error | 1 = timeout) ]
	
	movei	r7,3
	nop
	and	r2,r0,r7	;error / time out
	nop
	cmpeqi	r2,0
	brtc	sdCardReadBlocksError
	movei	r0,1		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop	

	;wait for transfer finish
	
	movei	r5,$10
	movei	r6,$00
	moveih	r5,$00
	moveih	r6,$A0		;sd card base + $10
	nop
	
	esadr	r6,r5
	
waitSdReadFinish	
	erqldi	0
	eld	r0
	nop
	cmpeqi	r0,$f
	brtc	waitSdReadFinish
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;check fifos <8192-512
	
	movei	r5,$15
	movei	r6,$00
	moveih	r5,$00
	moveih	r6,$A0		;sd card base + $15
	nop
	
	esadr	r6,r5
	
waitSdFifoLoad	
	
	erqldi	0
	erqldi	1
	erqldi	2
	erqldi	3
	eld	r0
	eld	r1
	eld	r2
	eld	r3
	
	cmplo	r0,r1		;r0<r1	
	movets	r1,r1,r0	;d = r1 else r0
	
	cmplo	r2,r3		;r2<r3	
	movets	r3,r3,r2	;d = r3 else r2
	
	nop
	
	cmplo	r1,r3		;r1<r3	
	movets	r3,r3,r1
	
	movei	r0,0
	nop
	moveih	r0,$1c
	nop
	
	;r3 is biggest fifo load
	cmplo	r3,r0	;r3 < 8192-1024
	brtc	waitSdFifoLoad	;not then wait again
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;<---
	
	rqpop
	rqpop
	rqpop
	pop	r4
	pop	r3
	pop	r2
	
	subi	r4,1
	brts	blockLoop
	addi	r2,1	;next block delay slot	
	addtqi	r3,r3,0	;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;wait for empty recive fifos, bustransfer finished (IMPLEMENT ME)
	
	;epilog

	movei	r0,0	;finish successfull
	
sdCardReadBlocksFinish
	
	rqpop	
	rqpop	
	rqpop
	pop	r7
	pop	r6
	pop	r5
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
sdCardReadBlocksError

	;cleanup stack
	
	rqpop
	rqpop
	rqpop
	br	sdCardReadBlocksFinish
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot	
	
;******************************
;*
;* sdCardSendCmd
;*
;* r0 = cmd
;* r1 = arg low
;* r2 = arg high
;* r3 = 0 -> set reciver to 48bit / 1 -> set reciver to 136 bit
;*
;*

sdCardSendCmd

	push	r5
	push	r6
	
	movei	r5,$00
	movei	r6,$00
	moveih	r5,$00
	moveih	r6,$A0		;sd card base
	
	moveih	r0,2		;reset $0002 CMDX
	
	swp	r3,r3		;r3 = 000x 0000
	esadr	r6,r5
	muli	r3,4		
	
	;reset first (reset read after write)
	
	est	r0,0		;reset	
	
	;
		
	moveih	r0,1		;start $0001 CMDX 
	est	r1,3		;low argument 
	or	r0,r0,r3	;add reciver mode
	est	r2,2		;high argument 
	est	r0,0		;cmd + start
	
	est	r0,7		;write sync (to wait for real startup)
	est	r0,7
	est	r0,7
	
	rqpop	
	rqpop
	jmpi	r7,0	
	pop	r6	;delay slot
	pop	r5	;delay slot
	nop		;delay slot
	nop		;delay slot
	
		
;******************************
;*
;* sdCardReciveCmd
;*
;* r1 = timeout count -1
;*
;* return
;*
;* r0 = status (4 = ok | 2 = error | 1 = timeout)
;* r1 = recived cmd						
;* r2 = recived arg low
;* r3 = recived arg high
;* r4 = expected crc, recived crc
;* r5 = ptr to 8 words (full data recived if mode is 136 bit)
;*


sdCardReciveCmd
		
	push	r6
	
	movei	r5,$00
	movei	r6,$00
	moveih	r5,$00
	moveih	r6,$A0		;sd card base	
	
	nop
	
	esadr	r6,r5
	
	
;wait for respons
	
sdCardReciveCmdRead

	erqldi	0	;status
	movei	r4,6	;110
	eld	r0	;RO RE SP (Recive Ok, Recive Error, Send in Progress)
	nop
	and	r2,r0,r4
	nop
	cmpeqi	r2,0	;if not 'not' ok or error retry
	brtc	sdCardReciveCmdFinish
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot	
	
	subi	r1,1	
	brts	sdCardReciveCmdRead
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot

	;timeout
	
	addi	r0,1	;set timeout in status
	
sdCardReciveCmdEpilog	
	
	rqpop	
	jmpi	r7,0	
	movei	r5,sdCardReciveCmdFullDataBuffer		;delay slot		
	pop	r6						;delay slot
	moveih	r5,>sdCardReciveCmdFullDataBuffer		;delay slot		
	nop							;delay slot
	
sdCardReciveCmdFinish

;* r1 = recived cmd
;* r2 = recived arg low
;* r3 = recived arg high
;* r4 = expected crc, recived crc
;* r5 = ptr to 8 words (full data recived if mode is 136 bit)

	;get 48 bit values
	
	;erqldi	3	;cmd
	erqldi	3	;arg low
	erqldi	2	;arg high
	erqldi	1	;ecrc crc
	
	or	r1,r0,r0
	nop
	lsri	r1,8
	
	movei	r5,$02
	movei	r6,$00
	moveih	r5,$00
	moveih	r6,$A0		;sd card base + 2
	
	;eld	r1
	eld	r2
	eld	r3
	eld	r4
	
	esadr	r6,r5		;base for 136bit mode
	
	movei	r5,sdCardReciveCmdFullDataBuffer
	erqldi	0
	moveih	r5,>sdCardReciveCmdFullDataBuffer
	erqldi	1
	erqldi	2
	erqldi	3
	erqldi	4
	erqldi	5
	erqldi	6
	erqldi	7
	
	push	r7
	movei	r7,7
	
sdCardReciveCmdReadLongArg
		
	eld	r6	;127 .. 112
	subi	r7,1
	brts	sdCardReciveCmdReadLongArg
	st	r5,r6	;delay slot
	addi	r5,1	;delay slot			
	nop		;delay slot
	nop		;delay slot
	
	
	rqpop
	br	sdCardReciveCmdEpilog
	nop							;delay slot
	pop	r7						;delay slot
	nop							;delay slot
	nop							;delay slot
	
sdCardReciveCmdFullDataBuffer

	.space	8
	