;*********************************************************************
;*
;* PS2KeyToAscii (need PS2Process before)
;* 
;* return
;*
;* r0 = ascii value (0 if no key) 
;*

PS2KeyToAscii

	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r7
	
	;clean up valid keys
	
	movei	r0,mPSNormalKeys	;keys current
	movei	r1,rawKeyMask		;ascii mask
	movei	r2,mCleanNormalKeys	;destination
	moveih	r0,>mPSNormalKeys
	moveih	r1,>rawKeyMask
	moveih	r2,>mCleanNormalKeys	
	movei	r3,8			;9 words -1
	
keyToAsciiAndLoop

	rqldi	r0,0
	rqldi	r1,0
	addi	r0,1
	ld	r4
	ld	r5
	addi	r1,1
	and	r4,r4,r5

	subi	r3,1
	brts	keyToAsciiAndLoop
	st	r2,r4	;delay slot
	nop		;delay slot
	addi	r2,1	;delay slot
	nop		;delay slot
	
	;find first key
	
	movei	r2,mCleanNormalKeys	;source to find
	movei	r3,$0			;counter for bits
	movei	r4,8			;9 words
	moveih	r2,>mCleanNormalKeys	
	nop
	
keyToAsciiFindFirst

	rqldi	r2,0
	addi	r2,1
	nop
	ld	r0	;word
	nop
	bffo	r1,r0	;r1 is value of first bit (t=true if found)
	brts	keyToAsciiFoundFirst
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	subi	r4,1	
	brts	keyToAsciiFindFirst
	addi	r3,16	;next word		delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
		
keyToAsciiFoundFirst
	
	;search value in keytable
	
	gpci	r7,2
	br	binSearch
	add	r0,r1,r3			;bit count + word count * 16	(16*(9*16) = 160 means not found!)	delay slot
	movei	r2,rawToAsciiTable		;									delay slot
	movei	r1,rawToAsciiTableLength	;length									delay slot
	moveih	r2,>rawToAsciiTable		;									delay slot
	
	movei	r1,$ff
	or	r4,r0,r0		;save bit pos
	moveih	r1,$ff		;
	
	;test found
	
	nop
	
	cmpeq	r1,r5	;$ffff means no found 
	brts	keyToAsciiInvalidKey
	movei	r0,0	;invalid value	delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;remove this key from ps2 buffer
	
	gpci	r7,2
	br	PS2ClearKey		;fixme
	or	r0,r4,r4		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;is shift enabled (could be optimized with direct access)
	
	gpci	r7,2
	br	PS2TestKey
	movei	r0,18	;Left Shift?	delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	gpci	r7,2
	br	PS2TestKey
	or	r2,r0,r0	;store last value	delay slot
	movei	r0,89		;Right Shift?	delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	movei	r1,asciiTable
	or	r2,r2,r0	;left or right pressed r2 = 1 else 0
	moveih	r1,>asciiTable
	muli	r2,8		;shift rigt offset
	add	r1,r1,r5
	nop
	rqldi	r1,0
	nop
	nop
	ld	r0		;value
	nop
	lsr	r0,r0,r2	
	nop
	moveih	r0,0		;clear uppervalue

keyToAsciiInvalidKey	
	
	rqpop
	rqpop
	rqpop
	pop	r7
	pop	r5
	pop	r4
	
	rqpop
	rqpop
	rqpop
	pop	r3
	pop	r2
	pop	r1
	
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
mCleanNormalKeys
	
	.space	9	;16 * 9 = 144 bit	