 	
;*********************************************************************
;* macros
;*********************************************************************	
	
	.macro	stop
	stop@	br	stop@
		nop
		nop
		nop
		nop
	.endmacro
	
	.macro	rgbMul(rInOut,multi,temp1,temp2,temp3)
		move	temp2,$ff
		lsl	hold,rInOut,8
		lsr	rInOut,last,8
		lsr	temp1,last,16		;temp1  = 0000 00RR
		and	temp3,rInOut,temp2	;temp3  = 0000 00BB
		lsr	hold,rInOut,8		;hold   = 0000 RRGG
		and	temp2,last,temp2	;temp2  = 0000 00GG
		
		;process
		
		fead		temp1,multi		
		fead		temp2,multi	
		mul_fead	temp1,temp3,multi	;r * c
		mul		temp2		;g * c
		mul		temp3		;b * c
		
		;
		
		lsr	temp1,temp1,8
		lsr	temp2,temp2,8
		lsr	temp3,temp3,8
			
		;assemble
		
		lsl	temp1,temp1,16	;00RR 0000
		lsl	hold,temp2,8	;0000 GG00
		or	hold,last,temp3	;0000 GGBB
		or	rInOut,last,temp1	;00RR GGBB
	.endmacro
	
;*********************************************************************
;* init
;*********************************************************************		
	
	org	hcoreStartPc
	
	.def	spLast		$d4000000
	.def	stackSize	1048576	;4 MegaByte per core
	
startHCore

	move	hold,stackSize
	moveh	hold,last,>>stackSize
	or	r0,last,0
	gssr	hold,0			;get core number		
	fead	last,r0	
	nop
	mul	r0			;stackOffset = core number (0..n) * stackSize

	;r125 as counter for debug ctrl
	
	move	r125,0
	
	;set stack offset
	
	move	hold,spLast
	moveh	hold,last,>>spLast
	sub	r127,last,r0		;stackPointer (r127) = spLast - stackOffset	
	
	;let only core 0 run, others are in idle state
	
	gssr	hold,0			;get core number
	cmpeq	last,0			;core 0?
	br.ts	startHCore0
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	;other cores goto sleep
	
	gpc	r126,0	;gpc doesnt accept negative values (fix me)
	nop
	nop
	nop
	idle	
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
;*********************************************************************
;* start hcore 0
;*********************************************************************		
	
startHCore0	

	move	r31,32		;counter

loop

	;prepare parallel execution
	
	sub	r127,r127,2	
	nop				;
	st	r31,r127,0		;store counter on stack
	
	spa	r127,0			;hand_over_address = sp
	
	move	hold,parallelFunction
	moveh	hold,last,>>parallelFunction
	or	r0,last,0
	spa	last,1			;jump_address	   = parallelFunction
	
	gssr	hold,1			;get total core in system
	spa	last,2			;max_cores 	   = use max
	
	gpc	r126,2			;return address
	
	rake			;allocate and jump parrallel
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot

	add	r127,r127,2	;stack pop
	add	hold,r31,15	;counter ++
	and	r31,last,$ff	;&0xff
	
	
	br	loop
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	.def	totalPixelCount		324000		;720*450
	
	;----------------------------------------------------------------------------
	;- parallel
	;----------------------------------------------------------------------------
	
parallelFunction

	;prolog

	sub	r127,r127,2
	nop
	st	r126,r127,0	;store LR

	;debug counter
	
	add	r125,r125,1
	
	;

	gpa	r0,0		;hand_over_address
	gpa	r1,2		;max_cores working here
	gpa	r2,3		;core number of THIS working cores
		
	rqld	r0,0		;hand over address is stack from core 0
	ld	r15		;get factor
	
	;
	
	move	r17,r1				;pixelOffset / max_cores in this function
	gpc	r126,2
	br	div1to8
	move	hold,totalPixelCount		;delay slot
	moveh	hold,last,>>totalPixelCount	;delay slot
	or	r16,last,0			;delay slot
	nop	;delay slot
	
	;r18 = pixel to draw
	fead	r18,r2		;r18 = offset in pixels = r18 * core number
	move	r20,1		;counter
	mul	hold		;offset in pixels
	lsl	r19,last,1	;r19 = offset in longs = offset in pixel *2

	;.execm	stop
	
	move	hold,testPic
	moveh	hold,last,>>testPic
	add	r0,last,r19		;source+offset
	
	move	hold,frame
	moveh	hold,last,>>frame
	add	r1,last,r19		;dest+offset
	
	;draw loop	
	
	rqld	r0,0	;prerequest
	
drawLoop	

	
	ld	r2
	cmpeq	r20,r18
	rqld.tc	r0,2	;request next 
	
	.execm	rgbMul(r2,r15,r100,r101,r102)
	nop
	
	st	r2,r1,0
		
	cmpeq	r20,r18
	br.tc	drawLoop
	add	r20,r20,1	;counter ++	delay slot
	add	r0,r0,2         ;source++       delay slot
	add	r1,r1,2         ;dest++         delay slot
	nop                     ;               delay slot
	
	;epilog
	
	rqld	r127,0
	add	r127,r127,2	
	ld	r126		;get lr
	
	nop
	
	jmp	r126,0		;return
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	
	
;******************************
;*
;* div1to8
;*
;* r16	 = divident
;* r17	 = divider
;* r18	 = result
;*

div1to8
	cmpeq	r17,1
	move.ts	r18,r16
	jmp.ts	r126,0			;return if 17 = 1 
	sub	hold,r17,2		;-2 (0..1) skiped in table	delay slot
	lsl	r17,last,2		;divider * 4 (ever 4 word)	delay slot	
	move	hold,divTable		;				delay slot	
	moveh	hold,last,>>divTable	;divtable			delay slot
	add	hold,last,r17		;				
	
	rqld	last,0		;factor
	rqld	last,2		;shift
	ld	hold
	fead	last,r16
	nop
	mulh	r17		;factor * divident
	
	jmp	r126,0		;return
	ld	r16		;shift	delay slot
	nop			;	delay slot
	lsr	r18,r17,r16	;	delay slot
	nop			;	delay slot
	
divTable
	.data	$80000000,0	;2
        .data	$aaaaaaab,1	;3
        .data	$80000000,1	;4
        .data	$cccccccd,2	;5
        .data	$aaaaaaab,2	;6
        .data	$92492493,2	;7 small error at 3E+9++
        .data	$80000000,2	;8
	