
	.def	LogoStartHigh	$e003
	.def	LogoStartLow	$0e68

	.def	ResetLevel1	32
	
	.org	0	;reset
	
	nop
	nop
	cli
	
	br	userStart ;only for debugging
	nop
	nop
	nop
	nop
		
	.incdir	"F:\git\goldmomo_endlos\assembler_files\ucore\"
	.include "include\ucore_ctrl.i"	
	.include "boot_level_subHeader.s"
	
;boot level 1 start	
	
	;
	
	gpci	r7,2		;next 4 + X
	br	setupVideo
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;copy logo
	
	movei	r0,LogoStartLow
	movei	r1,LogoStartHigh
	moveih	r0,>LogoStartLow
	moveih	r1,>LogoStartHigh
	
	movei	r3,0
	movei	r2,0
	moveih	r3,$f0		;sram base
	
	gpci	r7,2		;next 4 + X
	br	extCopy8
	movei	r4,$33		;delay slot
	nop			;delay slot
	moveih	r4,$9e		;delay slot
	nop			;delay slot
	
	;init sd
	
reInitSDCard	
	gpci	r7,2		;
	br	initSDCard	
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot

	cmpeqi	r0,0
	brtc	reInitSDCard
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;search bootblock
	
	movei	r2,0
	movei	r3,0		;start block
	
searchBootBlockLoop	
	
	movei	r1,$0a
	movei	r0,$00
	moveih	r1,$f0		;r1:r0 = $f00a 0000 (dest start)
	
	gpci	r7,2		;
	br	sdCardReadBlocks	
	movei	r4,0		;1 blk		delay slot (
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r0,0		;fail?
	brtc	reInitSDCard	;init again
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;test block goldmomo?
	
	movei	r1,$0a
	movei	r0,$08
	movei	r5,goldmomoEndlos
	moveih	r1,$f0		;r1:r0 = $f00a 0008 (dest start)
	moveih	r5,>goldmomoEndlos

	gpci	r7,2		;
	br	extCmp		;cmp with goldmomo endlos sentinel
	movei	r6,7		;cnt-1 delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r0,0		;
	brtc	checkMbr		;not goldmomo block -> check mbr
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot

	;block 0
	
loadAndExecute	
	
	;store start block (r2:r3)
	
	movei	r6,startBlock
	nop
	moveih	r6,>startBlock
	nop
	st	r6,r2
	addi	r6,1
	nop
	st	r6,r3
	
	;load into sram
	
	movei	r1,$0a
	movei	r0,$00
	moveih	r1,$f0		;r1:r0 = $f00a 0000 (dest start)
	
	gpci	r7,2		;r3:r2 = start block
	br	sdCardReadBlocks	
	movei	r4,63		;64 blks delay slot 
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r0,0		;fail?
	brtc	reInitSDCard	;init again
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;copy data to iram and execute
	;source 	ext r6:r5
	;destination	int r3
	;count-1	r4
	
	movei	r6,$0a
	movei	r5,ResetLevel1
	movei	r3,ResetLevel1	;dest start
	movei	r4,$df
	moveih	r6,$f0		;r1:r0 = $f00a 0020 (source start)
	moveih	r4,$3f		;8192-32-1
		
	br	copyToIramAndExecute
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
;******************************	
	
checkMbr

	movei	r1,$0a
	movei	r0,$e3
	moveih	r1,$f0		;r1:r0 = $f00a 00e3 (mbr -> start block)
	
	nop
	
	esadr	r1,r0
	erqldi	1		;low
	erqldi	0		;high
	eld	r3		;
	eld	r2
	swp	r3,r3
	swp	r2,r2		;endian ...
	
	br	searchBootBlockLoop
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
;******************************
;* extCmp
;*
;* r1:r0	ext address
;* r5 		internal address
;* r6 		cnt-1
;*
;* return
;*
;* r0 = 0 (data equal)
;*

extCmp

	push	r2
	push	r3
	push	r4
	
	;
	
extCmpLoop

	rqldi	r5,0
	nop
	nop
	ld	r2	;s1
	
	esadr	r1,r0
	erqldi	0
	eld	r3	;s2
	nop
	
	cmpeq	r2,r3
	brtc	extCmpLoopNotEqual
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	

	subi	r6,1
	brts	extCmpLoop
	addi	r0,1		;delay slot
	addtqi	r1,r1,0		;delay slot
	addi	r5,1		;delay slot
	nop			;delay slot
	
	;equal
	
	movei	r0,0
	
	;epilog

extCmpLoopEpilog
	
	rqpop	
	rqpop	
	rqpop
	pop	r4
	pop	r3
	pop	r2
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot

extCmpLoopNotEqual
	addqi	r0,r6,1
	br	extCmpLoopEpilog
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
;******************************
;* extCopy8
;*
;* r1:r0 source
;* r3:r2	dest
;* r4 count - 1 (8 words per count)
;* 
		
extCopy8	

	push	r5
	push	r6
	
extCopy8Loop
	esadr	r1,r0
	erqldi	0
	erqldi	1
	erqldi	2
	erqldi	3
	erqldi	4
	erqldi	5
	erqldi	6
	erqldi	7
	
	esadr	r3,r2
	eld	r5
	eld	r6
	est	r5,0
	est	r6,1
	eld	r5
	eld	r6
	est	r5,2
	est	r6,3
	eld	r5
	eld	r6
	est	r5,4
	est	r6,5
	eld	r5
	eld	r6
	est	r5,6
	est	r6,7
	

	subi	r4,1
	brts	extCopy8Loop
	addi	r0,8		;delay slot
	addtqi	r1,r1,0		;delay slot
	addi	r2,8		;delay slot
	addtqi	r3,r3,0		;delay slot
	
	rqpop
	rqpop
	jmpi	r7,0
	pop	r6	;delay slot
	pop	r7     	;delay slot
	nop		;delay slot
	nop		;delay slot	
	
	
;******************************
;*
;* setupVideo
;*

setupVideo

	
	movei	r0,videoDefault		;source
	movei	r1,UcTimer2Ctrl		;dest-1
	moveih	r0,>videoDefault
	moveih	r1,>UcTimer2Ctrl			
	movei	r2,26			;27-1
	
setupVideoLoop

	rqldi	r0,0
	addi	r0,1
	addi	r1,1
	ld	r3
	subi	r2,1
	brts	setupVideoLoop
	st	r1,r3	;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
		
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot	
	
videoDefault		;AD NAME					NEW				DEFAULT
	
	word	$0001	;10 VIDEO_ON					1				1 (ON)
	word	$0097	;11 HSYNC (D = 11 .. 0)				152-1				152-1
	word	$017f	;12 HSTART (D = 11 .. 0)			384-1				384-1
	word	$017d	;13 HMEMSTART (D = 11 .. 0)			382-1				382-1
	word	$071f	;14 HSTOP (D = 11 .. 0)				1824-1				1824-1
	word	$076f	;15 HTOTAL (D = 11 .. 0)			1904-1				1904-1
	word	$0002	;16 VSYNC (D = 10 .. 0)				3-1				3-1
	word	$001e	;17 VSTART (D = 10 .. 0)			31-1				31-1
	word	$03a2	;18 VSTOP  (D = 10 .. 0)			931-1				931-1
	word	$03a3	;19 VTOTAL  (D = 10 .. 0)			932-1				932-1
	word	$0000	;1a LC ADDER LOW				$0000				$0000
	word	$0080	;1b LC ADDER HIGH				$0080				$0040	
	word	$0000	;1c LC ADDER LATCH				X				X
	word	$0000	;1d LC START (10 .. 0) Pixeloffset		$0000				$0000	
	word	$0000	;1e						X				X
	word	$0000	;1f						X				X
	word	$0008	;20 HLOADSTART 					8				8
	word	$0170	;21 HLOADSTOP					360+8				180+8
	word	$001e	;22 VLOADSTART 					31-1				31-1
	word	$03a2	;23 VLOADSTOP 					931-1				931-1
	word	$0002	;24 VLOADNEXT					2				4
	word	$0000	;25 MEM_STARTADR_store low			$0000				$0000
	word	$f000	;26 MEM_STARTADR_store high			$f000				$f000
	word	$0000	;27 MEM_LINEOFFSET_store low			$0000				$0000
	word	$0000	;28 MEM_LINEOFFSET_store high			$0000				$0000
	word	$0002	;29 MEM_MODE_store 				2				2 (X1R5G5B5X1R5G5B5)
	word	$0000	;2a LATCH MEM_STARTADR/LINEOFFSET/MODE		X				X

	
;******************************
;*
;* sdCardReadBlocks
;*
;* r1:r0 = destination address 
;* r3:r2 = startblock
;* r4	 = block count - 1
;*	
;* return
;*
;* r0	 = 0 (load ok)
;*
;* scratch r0,r1
;*

sdCardReadBlocks

	;prolog

	push	r2
	push	r3
	push	r4
	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
	
	;wait upto fifos are empty
	
	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
	
	movei	r4,0
	nop
	add	r4,r4,r0
	nop
	add	r4,r4,r1
	nop
	add	r4,r4,r2
	nop
	add	r4,r4,r3
	nop
	
	cmpeqi	r4,0		;sum of fifos not zero then loop again
	brtc	waitSdFifoLoad	;
	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
	
	;epilog

	movei	r0,0	;finish successfull
	
sdCardReadBlocksFinish
	
	rqpop	
	rqpop	
	rqpop
	pop	r7
	pop	r6
	pop	r5
	
	rqpop	
	rqpop	
	rqpop
	pop	r4
	pop	r3
	pop	r2
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
sdCardReadBlocksError

	;celanup stack
	
	rqpop
	rqpop
	rqpop
	br	sdCardReadBlocksFinish
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	.def	cmdToReciveWait	9	
	
;******************************
;*
;* initSDCard
;*
;* return r0 
;*  
;* r0 = 0 (init success)
;*      1 - 2 	= CMD55, ACMD41 recive error
;*	3	= bringutp timeout (ACMD41) -> no sd card
;*	4	= reading CID fails
;*	5	= reading RCA fails
;*	6	= reading CSD fails
;*
	
initSDCard

	push	r7

	gpci	r7,2
	br 	sleep
	movei	r0,9		;10ms		delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
			
	;change clk to ~400khz
	
	movei	r5,$08
	movei	r6,$00
	moveih	r5,$00
	moveih	r6,$A0		;sd card base + $8
	
	nop
	
	esadr	r6,r5
	
	movei	r0,$ff		;clk msk	
	movei	r1,$00		;clk down cmp
	movei	r2,$00		;clk up cmp
	movei	r3,$80		;clk write cmp
	movei	r4,$bf		;clk read cmp
	
	moveih	r0,$01
	moveih	r2,$01
	moveih	r4,$01
	
	est	r0,0
	est	r1,1
	est	r2,2
	est	r3,3
	est	r4,4	
	
	;store clk
	
	movei	r5,$00
	movei	r6,$00
	moveih	r5,$00
	movei	r0,0
	moveih	r6,$A0		;sd card base 
	moveih	r0,$08		;write clk
	
	esadr	r6,r5
	est	r0,0
	
	;sleep
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;------------------- CMD0 reset -> no respons

	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	movei	r0,0		;cmd0		delay slot
	movei	r1,0		;arg low	delay slot
	movei	r2,0		;arg high	delay slot
	movei	r3,0		;48 bit		delay slot
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;2ms		delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;------------------- CMD8 reset -> ignore response

	movei	r3,0		;48 bit		
	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	movei	r0,8		;cmd0		delay slot
	movei	r1,$aa		;arg low	delay slot
	movei	r2,0		;arg high	delay slot
	moveih	r1,1		;2.7-3.6V		delay slot
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;2ms		delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;------------------- loop bingup while busy
	
	movei	r7,$ff	;max 256 times
	nop
	
bringupSDBusy	

	push	r7
	
	;--
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;10ms		delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;------------------- CMD55 (switch to app) -> check respons
	
	;send
	
	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	movei	r0,55		;cmd55		delay slot
	movei	r1,0		;arg low	delay slot
	movei	r2,0		;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	initSDCardErrorUnpop
	movei	r1,$01		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;------------------- ACMD41 (bringup) -> check respons
	
	;--
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;10ms		delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;send
	
	movei	r0,41		;cmd41		
	movei	r1,0		;arg low	
	movei	r2,$ff		;VALL	arg high
	moveih	r1,0		;arg low	
	moveih	r2,$40		;HCS	arg high		
	movei	r3,0		;48 bit		
	
	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;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) ]
	;r2 = recived arg low
	;r3 = recived arg high
	
	movei	r7,3
	nop
	and	r2,r0,r7	;error / time out
	nop
	cmpeqi	r2,0
	brtc	initSDCardErrorUnpop
	movei	r1,$02		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;
	
	rqpop
	nop
	nop
	pop	r7	;busy count
	
	;test busy flag
	
	extri	r3,15		;MSB in high result
	brts	bringupSDFinished	;not busy
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;its busy so try again
	
	subi	r7,1
	brts	bringupSDBusy
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	br	initSDCardError
	movei	r1,$03		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
		
bringupSDFinished	

	;r3 = bit 14 = 1 then SDHC
	
	movei	r0,sdCardIsSDHC
	movei	r4,0
	moveih	r0,>sdCardIsSDHC
	movei	r5,1
	
	extri	r3,14	;sdhc?
	movets	r4,r5,r4
	nop
	st	r0,r4	;save for reader
	
	;card is ready now
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait	;delay slot
	nop				;delay slot
	nop				;delay slot
	nop				;delay slot
	
	;------------------- CMD2 (get CID) -> check respons
	
	;send
	
	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	movei	r0,2		;cmd2		delay slot
	movei	r1,0		;arg low	delay slot
	movei	r2,0		;arg high	delay slot
	movei	r3,1		;136 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	initSDCardError
	movei	r1,$04		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
		
	;get relative address
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait	;delay slot
	nop				;delay slot
	nop				;delay slot
	nop				;delay slot
	
	;------------------- CMD3 (get RCA) -> check respons
	
	;send
	
	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	movei	r0,3		;cmd3		delay slot
	movei	r1,0		;arg low	delay slot
	movei	r2,0		;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	initSDCardError
	movei	r1,$05		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;r3 = high 16 bit is RCA
	
	movei	r0,sdCardRCA
	nop
	moveih	r0,>sdCardRCA
	nop
	st	r0,r3	;store rca
		
	;get CSD
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;delay slot
	nop					;delay slot
	nop					;delay slot
	nop					;delay slot
	
	;------------------- CMD9 (get CSD) -> check respons (need CSD?)
	
	movei	r0,sdCardRCA
	nop
	moveih	r0,>sdCardRCA
	nop
	rqldi	r0,0
	nop
	nop
	ld	r2	;arg high	
	
	;send
	
	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	movei	r0,9		;cmd9		delay slot
	movei	r1,0		;arg low	delay slot
	nop			;arg high	delay slot
	movei	r3,1		;136 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	initSDCardError
	movei	r1,$06		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;------------------- CMD7 (select card) -> check respons
	
	;sleep
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;send
	
	movei	r0,sdCardRCA
	nop
	moveih	r0,>sdCardRCA
	nop
	rqldi	r0,0
	nop
	nop
	ld	r2	;arg high	
	
	
	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	movei	r0,7		;cmd3		delay slot
	movei	r1,0		;arg low	delay slot
	nop			;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	initSDCardError
	movei	r1,$07		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;------------------- CMD16 (select block length) -> check respons
	
	;sleep
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;send
		
	movei	r1,0	
		
	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	movei	r0,16		;cmd		delay slot
	moveih	r1,$2		;arg low	delay slot
	movei	r2,0		;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	initSDCardError
	movei	r1,$08		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			
	
	;------------------- CMD55 with rca (to app) -> check respons
	
	;sleep
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	movei	r0,sdCardRCA
	nop
	moveih	r0,>sdCardRCA
	nop
	rqldi	r0,0
	nop
	nop
	ld	r2	;arg high	
	
	;send
		
	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	movei	r0,55		;cmd		delay slot
	movei	r1,0		;arg low	delay slot
	nop			;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	initSDCardError
	movei	r1,$09		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot	
	
	;------------------- ACMD6 (set bus width) -> check respons
	
	;sleep
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;send
		
	gpci	r7,2		;next 4 + X
	br	sdCardSendCmd	
	movei	r0,6		;cmd		delay slot
	movei	r1,2		;arg low (4bit)	delay slot
	movei	r2,0		;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	initSDCardError
	movei	r1,$0A		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot	
	
	;sleep
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
		
	;change clk to 25MHz
	
	movei	r5,$08
	movei	r6,$00
	moveih	r5,$00
	moveih	r6,$A0		;sd card base + $8
	
	nop
	
	esadr	r6,r5
	
	movei	r0,$03		;clk msk	
	movei	r1,$00		;clk down cmp
	movei	r2,$02		;clk up cmp
	movei	r3,$01		;clk write cmp
	movei	r4,$01		;clk read cmp
	
	est	r0,0
	est	r1,1
	est	r2,2
	est	r3,3
	est	r4,4	
	
	;store clk
	
	movei	r5,$00
	movei	r6,$00
	moveih	r5,$00
	movei	r0,0
	moveih	r6,$A0		;sd card base 
	moveih	r0,$08		;write clk
	
	esadr	r6,r5
	est	r0,0
	
	;sleep
	
	gpci	r7,2
	br 	sleep
	movei	r0,cmdToReciveWait		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
		
	;init ok	
		
	movei	r0,0
	
initSDCardError

	rqpop
	nop
	nop
	pop	r7
	nop
	
	jmpi	r7,0	
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
initSDCardErrorUnpop
	;remove	r7 from stack
	
	rqpop
	br	initSDCardError
	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
	
;******************************
;*
;* sleep
;*	
;* r0 = (cnt in ms) -1	
;*
;*

sleep

	push	r1
	
sleepLoopOut
	
	movei	r1,$4c
	nop
	moveih	r1,$45
	nop
	
sleepLoopIn
	subi	r1,1
	brts	sleepLoopIn
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	subi	r0,1
	brts	sleepLoopOut
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	rqpop	
	jmpi	r7,0	
	nop		;delay slot
	pop	r1	;delay slot
	nop		;delay slot
	nop		;delay slot

;---------------
; longToHexMap
;
; r0 = high value
; r1 = low value
; r7 = rpc
; 	

longToHexMap

	push	r0
	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7
	
	
	movei	r2,hexMap
	movei	r7,hex7seg
	movei	r5,$f		;msk
	moveih	r2,>hexMap	;8 h
	moveih	r7,>hex7seg
	
	movei	r6,1

highLow
	
	or	r3,r0,r0
	or	r4,r0,r0
	lsri	r3,12
	lsri	r4,8
	and	r3,r3,r5
	and	r4,r4,r5
	
	add	r3,r3,r7
	add	r4,r4,r7
	rqldi	r3,0
	rqldi	r4,0
	nop
	ld	r3
	ld	r4
	nop
	
	st	r2,r3		;8;4
	addi	r2,1		
	nop
	st	r2,r4		;7;3
	addi	r2,1
	
	or	r3,r0,r0
	and	r4,r0,r5
	lsri	r3,4
	nop
	and	r3,r3,r5
	nop
	
	add	r3,r3,r7
	add	r4,r4,r7
	rqldi	r3,0
	rqldi	r4,0
	nop
	ld	r3
	ld	r4
	nop
	
	st	r2,r3		;6;2
	addi	r2,1		
	nop
	st	r2,r4		;5;1
	addi	r2,1
	
	or	r0,r1,r1	;next 4 digits
	subi	r6,1
	brts	highLow
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	rqpop	
	rqpop	
	rqpop	
	pop	r7
	pop	r6
	pop	r5
	
	rqpop	
	rqpop	
	rqpop	
	pop	r4
	pop	r3
	pop	r2
	
	rqpop	
	rqpop	
	nop
	pop	r1
	pop	r0
	
	jmpi	r7,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
		
 ;--     0
 ;--    ###
 ;--  5 # # 1
 ;--    #6#
 ;--  4 # # 2
 ;--    ###
 ;--     3	

hex7seg			
	
	word	%00111111 ; 0		
	word	%00000110 ; 1			
	word	%01011011 ; 2		
	word	%01001111 ; 3		
	word	%01100110 ; 4		
	word	%01101101 ; 5		
	word	%01111101 ; 6		
	word	%00000111 ; 7		
	word	%01111111 ; 8		
	word	%01101111 ; 9		
	word	%01110111 ; A		
	word	%01111100 ; b		
	word	%00111001 ; C		
	word	%01011110 ; d		
	word	%01111001 ; E		
	word	%01110001 ; F	
	
;---------------
; drawHex
; 
; r7 = rpc
;
; scratch r0,r1
; 

drawHex	

	push	r0
	push	r1
	push	r2
	push	r3
	push	r4

	movei	r0,hexMap
	movei	r1,Uc7SegHex76
	moveih	r0,>hexMap
	moveih	r1,>Uc7SegHex76		;r1 = (hex7:hex6)
	
	movei	r2,0

drawHexLoop

	rqldi	r0,0
	rqldi	r0,1
	addi	r0,2		
	ld	r3		;hex n
	ld	r4		;hex n + 1
	swp	r3,r3
	nop
	or	r4,r4,r3
	nop
	st	r1,r4
	subi	r1,1

	cmpeqi	r2,6
	brtc	drawHexLoop
	addi	r2,2		;delay slot (t is not used so hazard can ignored)
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	rqpop	
	rqpop	
	rqpop	
	pop	r4
	pop	r3
	pop	r2
	
	rqpop	
	rqpop	
	nop
	pop	r1
	pop	r0
	
	jmpi	r7,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
hexMap	word	$10	;h0
	word	$11
	word	0
	word	0
	word	0
	word	0
	word	0
	word	0	;h7	
	
		
;** ident string

goldmomoEndlos	
	.stringb	"goldmomo_endlos"
