
	.incdir	"F:\git\goldmomo_endlos\assembler_files\ucore\hcore\"
	.include	"include/uctrl_port.i"
	.incdir	"F:\git\goldmomo_endlos\assembler_files\ucore\"
	.include	"include/ucore_ctrl.i"

;*********************************************************************
;* start
;*********************************************************************	
	
	.def	spLast		$d4000000
	.def	stackSize	1048576	;4 MegaByte per core
	
	.def	screenWidth	360
	.def	screenHeight	225
	
	org	hcoreStartPc
	
	nop
	nop
	nop
	nop
	
startHCore

	move	hold,stackSize
	moveh	hold,last,>>stackSize
	or	r0,last,0
	nop
	
	gssr	hold,0			;get core number
	fead	last,r0	
	nop
	mul	r0			;stackOffset = core number (0..n) * stackSize
	
	;set stack offset
	
	move	hold,spLast
	moveh	hold,last,>>spLast
	sub	r127,last,r0		;stackPointer (r127) = spLast - stackOffset
	
	;set other cores (not core 0) to sleep
	
	gssr	hold,0
	cmpeq	last,0
	br.tc	stop
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	
	;setup video
	
	gpc	r126,2
	br	setupVideo
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	;
	
	move	r16,0
	
loop	
	;wait vblank

	gpc	r126,2
	;br	waitBlank
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	;switch frames
	
	gpc	r126,2
	br	switchFrames
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot	
	
	;clear screen
	
	move	hold,drawFrame
	moveh	hold,last,>>drawFrame
	ld	r1,last,0		;dest
	
	move	hold,2531;10125		;count
	or	r2,last,0
	gpc	r126,2
	br 	fill8
	move	r0,$fff			;value          ;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	
	;draw test char
		

;******************************
;*
;* drawString
;*
;* r0 = source (752bit width)
;* r1 = dest
;* r2 = dest width
;* r3 = color
;* r4 = x start
;* r5 = y start
;* r6 = drawFunction
;* r7 = text address
;*	

	;push data to stack
	
	sub	r127,r127,12
	nop
	nop
	st	r16,r127,0		;counter
	add	r16,r16,1		;add counter
	
	gssr	hold,4		;cache hit cnt
	st	last,r127,2
	gssr	hold,5		;fetch stall cnt
	st	last,r127,4
	gssr	hold,6		;score stall cnt
	st	last,r127,6
	gssr	hold,7		;execute stall cnt
	st	last,r127,8
	gssr	hold,8		;dispatch merge stall cnt
	st	last,r127,10

	;

	move	hold,font1Bit		
        moveh	hold,last,>>font1Bit  
        add	r0,last,0		;src
        
	move	hold,drawFrame
	moveh	hold,last,>>drawFrame
	ld	r1,last,0		;dest
	
        move	r2,720			;dest width
        move	hold,$ffff		
        moveh	hold,last,$ffff	
        or	r3,last,0		;color
	
	move	r4,10			;x
	move	r5,9			;y
	
	move	hold,drawChar		
        moveh	hold,last,>>drawChar  
        add	r6,last,0		;draw function
	
	move	hold,testString		
        moveh	hold,last,>>testString  
        add	r7,last,0		;text address
	
	gpc	r126,2
	br	drawString	
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	;restore stack
	
	add r127,r127,12

	;
	
	br	loop
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
stop	br	stop
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
;******************************
;*
;* fill8 (8 longs)
;*	
;* r0 = value
;* r1 = address
;* r2 = count
;*
	
fill8
	nop

fill8Loop
	nop
	sub	r2,r2,1
	st	r0,r1,0
	st	r0,r1,2
	st	r0,r1,4
	st	r0,r1,6
	st	r0,r1,8
	cmpeq	r2,0
	br.tc	fill8Loop
	st	r0,r1,10	;delay slot
	st	r0,r1,12	;delay slot
	st	r0,r1,14	;delay slot
	add	r1,r1,16	;delay slot

	jmp	r126,0
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot	
	
;******************************
;*
;* drawString
;*
;* r0 = source (752bit width)
;* r1 = dest
;* r2 = dest width
;* r3 = color
;* r4 = x start
;* r5 = y start
;* r6 = drawFunction
;* r7 = text address
;*	

drawString

	.def	drawStringStackUse	16

	;prolog

	sub	r127,r127,drawStringStackUse	;sp-
	nop
	nop
	st	r16,r127,0	
	st	r17,r127,2	
	st	r18,r127,4
	st	r19,r127,6
	st	r20,r127,8
	st	r21,r127,10
	st	r22,r127,12	
	st	r126,r127,14
	
	;
	
	or	r16,r0,r0			;store source
	or	r17,r1,r1			;store dest
	or	r18,r2,r2			;store width
	or	r19,r3,r3			;store color
	or	r20,r6,r6			;store draw function
	or	r21,r7,r7			;store text address
	
	add	r22,r127,drawStringStackUse	;stack last
	
	;x & y is pixelwise
	
	fead	r2,r5		;	y * width
	add	r4,r4,r4	;x*2
	mul	hold		;
	add	r17,last,r17	;dest+=
	add	r17,last,r4	;dest+=x
	
	;char loop
	
textLoop
	
	ld	r4,r21,0	;load word
	add	r21,r21,2	;next address
	
	cmpeq	r4,37		;%
	br.ts	textProcessCmd
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	cmpeq	r4,0		;end
	br.ts	textLoopEnd
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	;no cmd and not end so draw char
	
	gpc	r126,2
	br	textDrawChar
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	br	textLoop
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	
textLoopEnd	
	
	;epilog
	
	ld	r16,r127,0	;
	ld	r17,r127,2	;
	ld	r18,r127,4
	ld	r19,r127,6
	ld	r20,r127,8	
	ld	r21,r127,10	
	ld	r22,r127,12	
	ld	r126,r127,14
	
	nop	
	jmp	r126,0
	add	r127,r127,drawStringStackUse	;delay slot
	nop					;delay slot
	nop					;delay slot
	nop					;delay slot
	
; 
; r4 = char
;

textDrawChar

	sub	r127,r127,2	;sp--
	nop
	nop
	st	r126,r127,0	;store lr

	;draw
	
	sub	hold,r4,32	;char offset
	and	r4,last,$ff	;secure and
	gpc	r126,2
	jmp	r20,0		;draw function
	or	r0,r16,r16	;source       delay slot
	or	r1,r17,r17	;dest         delay slot
	or	r2,r18,r18	;width        delay slot
	or	r3,r19,r19	;color        delay slot
	
	;
	
	ld	r126,r127,0	;get lr
	add	r127,r127,2	;sp++
	
	jmp	r126,0
	add	r17,r17,16	;destination + 8 pixel
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
; r22 = stack	
	
textProcessCmd

	ld	r4,r21,0	;load cmd
	add	r21,r21,2
	
	cmpeq	r0,120	;x -> hex		
	br	textProcessCmdHex
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	br	textLoop	;unknown
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
;	
	
textProcessCmdHex

	ld	r9,r22,0	;value from stack
	add	r22,r22,2	;goto next (up)
	
	move	r10,7
	
textProcessCmdHexLoop

	lsr	r4,r9,28	;use upper 4 bit	;delay slot
	gpc	r126,2	
	br	textDrawChar
	cmple	r4,9                                    ;delay slot
	add.ts	r4,r4,48	;16+32  0..9            ;delay slot
	add.tc	r4,r4,55	;23+32  A..F            ;delay slot
	nop						;delay slot

	cmpeq	r10,0
	br.tc	textProcessCmdHexLoop
	sub	r10,r10,1	;delay slot
	lsl	r9,r9,4		;delay slot
	nop			;delay slot
	nop			;delay slot
	
	br	textLoop	;go back
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	
;******************************
;*
;* drawChar
;*
;* r0 = source (752bit width)
;* r1 = dest
;* r2 = dest width
;* r3 = color
;* r4 = char offset
;*

drawChar

	move	hold,$8000
	or	r8,last,0	;shift mask
	
	and	hold,r4,1	;even/odd
	cmpeq	last,0
	lsr.tc	r8,r8,8		;shift mask >> 8 if odd
	
	lsr	hold,r4,1	;offset / 2
	add	r0,last,r0	;to source address
	nop	
	move	r4,15
lineLoop

	ldw	r5,r0,0		;load 16 bit
	or	r7,r8,r8	;reset msk
	move	r6,7
	nop
	
; pixelLoop	
	; and	hold,r5,r7	;
	; cmpeq	last,0
	; st.tc	r3,r1,0		;color to dest if bit set

	; cmpeq	r6,0
	; br.tc	pixelLoop
	; lsr	r7,r7,1 ;delay slot
	; sub	r6,r6,1	;delay slot
	; add     r1,r1,2 ;delay slot
	; nop             ;delay slot
	
	lsr	hold,r7,0
	and	hold,last,r5
	cmpeq	last,0
	st.tc	r3,r1,0		;color to dest if bit set
	
	lsr	hold,r7,1
	and	hold,last,r5
	cmpeq	last,0
	st.tc	r3,r1,2		;color to dest if bit set
	
	lsr	hold,r7,2
	and	hold,last,r5
	cmpeq	last,0
	st.tc	r3,r1,4		;color to dest if bit set
	
	lsr	hold,r7,3
	and	hold,last,r5
	cmpeq	last,0
	st.tc	r3,r1,6		;color to dest if bit set
	
	lsr	hold,r7,4
	and	hold,last,r5
	cmpeq	last,0
	st.tc	r3,r1,8		;color to dest if bit set
	
	lsr	hold,r7,5
	and	hold,last,r5
	cmpeq	last,0
	st.tc	r3,r1,10	;color to dest if bit set
	
	lsr	hold,r7,6
	and	hold,last,r5
	cmpeq	last,0
	st.tc	r3,r1,12	;color to dest if bit set
	
	lsr	hold,r7,7
	and	hold,last,r5
	cmpeq	last,0
	st.tc	r3,r1,14	;color to dest if bit set
	
	cmpeq	r4,0
	br.tc	lineLoop
	nop
	;sub	r1,r1,16	;delay slot
	add	r0,r0,47	;delay slot
	sub	r4,r4,1		;delay slot
	add	r1,r1,r2     	;delay slot
	             	
	;epilog
		
	jmp	r126,0
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
;******************************
;*
;* setupVideo
;*

setupVideo

	move	r3,0
	move	hold,video320x225x32
	moveh	hold,last,>>video320x225x32	
	or	r0,last,0			;source data
	move	hold,UcVideoRHCountWVideoOn	;dest start
	or	r1,last,0
	
	
setupVideoLoop
	
	ldw	r2,r0,r3			;get data[r3]
	.execm	ucpSetParam(0,r1)		;param 0 = address ($8010 ++)
	.execm	ucpSetParam(1,r2)		;param 1 = value
	.execm	ucpCall(upfCallSubUCtrlWrite)	;set uctrl register
	cmpeq	r3,26
	br.tc	setupVideoLoop
	add	r3,r3,1
	add	r1,r1,1
	nop	;delay slot
	nop	;delay slot
	
	jmp	r126,0
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
video320x225x32	
		
	word	$00010097
	word	$017f017d
	word	$071f076f
	word	$0002001e
	word	$03a203a3
	word	$00000040
	word	$00000000
	word	$00000000
	word	$00080170
	word	$001e03a2
	word	$00040000
	word	$d0000000
	word	$00000000
	word	$00000000
	
;******************************
;*
;* waitBlank
;*	

waitBlank

	;emulator test

	.execm	ucpSetParam(0,UuLedR)	;param 0 = UuLedr / isEmu
	.execm	ucpCallReturn(t0,upfCallSubUCtrlRead)	;get uctrl register
	nop
	
	and	hold,t0,1
	cmpeq	last,0			
	br.tc	waitBlankEnd		;t0 <> 0 (emulator) -> waitBlankEnd 
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;sw test

	.execm	ucpSetParam(0,UcRSwichtWLedG)	;param 0 = UcRSwichtWLedG 
	.execm	ucpCallReturn(t0,upfCallSubUCtrlRead)	;get uctrl register
	nop
	
	and	hold,t0,1
	cmpeq	last,1			
	br.ts	waitBlankEnd		;t0(0) == 1 (SW0 is set) -> waitBlankEnd 
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
		
	move	hold,UcVideoHITVCOUNT
	or	t0,last,0		;hitv count
	move	t1,930			;line
	
	.execm	ucpSetParam(0,t0)		;param 0 = address (hitv count)
	.execm	ucpSetParam(1,t1)		;param 1 = 930
	.execm	ucpCall(upfCallSubUCtrlWrite)	;set uctrl register
	
	move	hold,UcVideoRPVcountHit
	or	t0,last,0		;vcount hit adr
	
	.execm	ucpSetParam(0,t0)		;param 0 = address (vcount hit)
	
waitBlankLoop

	.execm	ucpCallReturn(t0,upfCallSubUCtrlRead)	;set uctrl register
	nop
	and	hold,t0,1
	cmpeq	last,1		;vcount hit?
	br.tc	waitBlankLoop	;no do again
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
waitBlankEnd

	jmp	r126,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
;******************************
;*
;* switchFrames
;*	

switchFrames

	move	hold,displayFrame
	moveh	hold,last,>>displayFrame
	or	t0,last,0
	
	move	hold,drawFrame
	moveh	hold,last,>>drawFrame
	or	t1,last,0
	nop
	
	ld	t2,t0,0
	ld	t3,t1,0
	
	;t2 = display
	;t3 = draw
	
	move	hold,UcVideoMEMStartAdrLow
	or	t4,last,0
	move	hold,UcVideoMEMStartAdrHigh
	or	t5,last,0
	
	or	t6,t3,t3	;low
		
	.execm	ucpSetParam(0,t4)		;param 0 = address (start address low)
	.execm	ucpSetParam(1,t6)		;param 1 = value
	.execm	ucpCall(upfCallSubUCtrlWrite)	;set uctrl register
	
	lsr	t6,t6,16	;high
	move	hold,UcVideoMEMLatch
	or	t4,last,0
	
	.execm	ucpSetParam(0,t5)		;param 0 = address (start address high)
	.execm	ucpSetParam(1,t6)		;param 1 = value
	.execm	ucpCall(upfCallSubUCtrlWrite)	;set uctrl register
	
	.execm	ucpSetParam(0,t4)		;param 0 = address (latch out)
	.execm	ucpCallReturn(t4,upfCallSubUCtrlWrite)	;set uctrl register
	
	nop
	fead	t4,t4	;sync
	
	jmp	r126,0
	st	t3,t0,0	;delay slot
	st	t2,t1,0	;delay slot
	nop		;delay slot
	nop		;delay slot
	
displayFrame	word	frame0
drawFrame	word	frame1	

testString	
	.stringz	"Test cnt %x"
	