;*********************************************************************
;* ps2
;*********************************************************************	

;*********************************************************************
;*
;* PS2Reset
;*	
;* trash r0
;*
	
PS2Reset

	push	r1
	push	r2
	
	movei	r2,mPSNormalKeys
	movei	r1,17
	moveih	r2,>mPSNormalKeys
	movei	r0,0
	
	;clear all keys
	
PS2ResetLoop
	subi	r1,1
	brts	PS2ResetLoop
	st	r2,r0	;delay slot
	addi	r2,1	;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;reset state
	
	movei	r2,mPS2State
	movei	r1,ePS2StateWait
	moveih	r2,>mPS2State
	nop
	st	r2,r1
	
	;epilog
	
	rqpop
	rqpop
	jmpi	r7,0	
	pop	r2	;delay slot
	pop	r1	;delay slot
	nop		;delay slot
	nop		;delay slot
	
;*********************************************************************
;*
;* PS2Process
;*		
	
PS2Process	

	;prolog

	push	r0
	push	r1	
	push	r2
	push	r3
	push	r4
	push	r7
	

	;
	
	movei	r2,UcPs2PortACtrl
	movei	r3,mPS2State
	moveih	r2,>UcPs2PortACtrl	
	movei	r4,mLastKey
	
	;check ps2 input

	rqldi	r2,0
	moveih	r3,>mPS2State
	movei	r4,>mLastKey
	ld	r0	;ps2 data
	
	rqldi	r3,0
	nop
	nop
	ld	r1	;state
	
	extri	r0,8	;data in available
	brtc	PS2ProcessFinish
	nop		;delay slot
	nop		;delay slot
	moveih	r7,$1	;100 = accept data 		delay slot
	moveih	r0,0	;clear upper data of result	delay slot
	
	st	r2,r7	;write ps2 - accept data
	st	r4,r0	;store last key
		
	;error check
	
	cmpeqi	r0,$00	;key board error
	brts	PS2Reset
	movei	r7,PS2ProcessFinish		;delay slot
	nop					;delay slot
	moveih	r7,>PS2ProcessFinish		;delay slot
	nop					;delay slot
	
	;state check
	
	cmpeqi	r1,ePS2StateWait
	brts	PS2StateWait
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	cmpeqi	r1,ePS2StateWaitBreak		
	brts	PS2StateWaitBreak	
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	cmpeqi	r1,ePS2StateWaitExtended	
	brts	PS2StateWaitExtended	
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	cmpeqi	r1,ePS2StateWaitExtendedBreak	
	brts	PS2StateWaitExtendedBreak	
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
PS2ProcessFinish	
	
	rqpop
	rqpop
	rqpop
	poparqp	r7
	poparqp	r4
	poparqp	r3
	pop	r2
	pop	r1
	pop	r0
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
;*********************************************************************
;*
;* PS2TestKey
;*	
;* r0 = number to test
;* 
;* return
;*
;* r0 = 0 = not pressed / 1 = pressed
;*	

PS2TestKey

	push	r1
	push	r2

	movei	r1,$f
	movei	r2,mPSNormalKeys
	and	r1,r0,r1	;bit pos
	moveih	r2,>mPSNormalKeys
	lsri	r0,4		;word pos
	nop
	add	r2,r2,r0
	nop
	rqldi	r2,0
	nop
	nop
	ld	r2
	movei	r0,1
	lsr	r2,r2,r1	
	nop
	and	r0,r2,r0

	rqpop	
	rqpop	
	jmpi	r7,0
	pop	r2	;delay slot
	pop	r1	;delay slot
	nop		;delay slot
	nop		;delay slot
	
;*********************************************************************
;*
;* PS2ClearKey
;*	
;* r0 = number to clear
;* 
;* 	

PS2ClearKey

	push	r1
	push	r2
	push	r7

	gpci	r7,2
	br	PSSetKey
	movei	r2,0		;reset				delay slot
	movei	r1,1		;delay slot
	cmploi	r2,160		;delay slot
	movets	r1,r2,r1	;<160 not extended (0) else 1	delay slot
	
	rqpop
	rqpop
	rqpop
	pop	r7
	pop	r2
	pop	r1
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot

;*********************************************************************
;*
;* PS2StateWait
;*
;* r0 = ps2 data
;* r1 = state
;* r3 = state address

PS2StateWait

	cmpeqi	r0,$f0				;$f0 -> next state = break;
	brts	PS2ProcessFinish
	movei	r1,ePS2StateWaitBreak		;delay slot
	nop					;delay slot
	st	r3,r1				;delay slot
	nop					;delay slot
	
	cmpeqi	r0,$e0				;$e0 -> next state = wait extended;
	brts	PS2ProcessFinish
	movei	r1,ePS2StateWaitExtended	;delay slot
	nop					;delay slot
	st	r3,r1				;delay slot
	nop					;delay slot
	
	cmpeqi	r0,$e1				;$e1 -> next state = wait extended;
	brts	PS2ProcessFinish
	movei	r1,ePS2StateWaitExtended	;delay slot
	nop					;delay slot
	st	r3,r1				;delay slot
	nop					;delay slot
	
	gpci	r7,2		;next 4 + X
	br	PSSetKey
	nop					;delay slot
	movei	r1,0				;not extended	delay slot
	movei	r2,1				;set		delay slot
	nop					;delay slot
	
	br	PS2ProcessFinish
	movei	r1,ePS2StateWait		;else -> next state = wait		;delay slot
	nop					;delay slot
	st	r3,r1				;delay slot
	nop					;delay slot
	
;*********************************************************************
;*
;* PS2StateWaitBreak
;*
;* r0 = ps2 data
;* r1 = state
;* r3 = state address
	
PS2StateWaitBreak	
	
	gpci	r7,2		;next 4 + X
	br	PSSetKey
	nop					;delay slot
	movei	r1,0				;not extended	delay slot
	movei	r2,0				;clear		delay slot
	nop					;delay slot

	br	PS2ProcessFinish
	movei	r1,ePS2StateWait		;next state = wait	;delay slot
	nop					;delay slot
	st	r3,r1				;delay slot
	nop					;delay slot
	
;*********************************************************************
;*
;* PS2StateWait
;*
;* r0 = ps2 data
;* r1 = state
;* r3 = state address

PS2StateWaitExtended

	cmpeqi	r0,$f0				;$f0 -> next state = break extended;
	brts	PS2ProcessFinish
	movei	r1,ePS2StateWaitExtendedBreak		;delay slot
	nop					;delay slot
	st	r3,r1				;delay slot
	nop					;delay slot
		
	gpci	r7,2		;next 4 + X
	br	PSSetKey
	nop					;delay slot
	movei	r1,1				;extended	delay slot
	movei	r2,1				;set		delay slot
	nop					;delay slot
	
	br	PS2ProcessFinish
	movei	r1,ePS2StateWait		;else -> next state = wait	;delay slot
	nop					;delay slot
	st	r3,r1				;delay slot
	nop					;delay slot	
	
;*********************************************************************
;*
;* PS2StateWaitBreak
;*
;* r0 = ps2 data
;* r1 = state
;* r3 = state address
	
PS2StateWaitExtendedBreak	

	gpci	r7,2		;next 4 + X
	br	PSSetKey
	nop					;delay slot
	movei	r1,1				;extended	delay slot
	movei	r2,0				;clear		delay slot
	nop					;delay slot
	
	br	PS2ProcessFinish
	movei	r1,ePS2StateWait		;next state = wait	;delay slot
	nop					;delay slot
	st	r3,r1				;delay slot
	nop					;delay slot
	
	
;*********************************************************************
;*
;* PSSetResetKey
;*	
;* r0 = data
;* r1 = 1 = extended
;* r2 = 1 = set / 0 = reset	
;*
	
PSSetKey

	push	r0
	push	r3
	push	r4
	push	r5
	
	movei	r5,mPSExtendedKeys
	movei	r4,mPSNormalKeys
	moveih	r5,>mPSExtendedKeys
	moveih	r4,>mPSNormalKeys
	movei	r3,$f
	cmpeqi	r1,0			;0 = normal offset else extended
	movets	r5,r4,r5		;r5 = src / dest address
	
	and	r3,r0,r3		;r3 = low 0..15 	(bit pos)
	lsri	r0,4			;r0 = higher data	(word pos)
	
	nop
	add	r5,r5,r0		;add word offset
	nop
	rqldi	r5,0			;get word
	nop
	nop
	ld	r0
	nop
	or	r4,r0,r0		;r4
	bset	r0,r3			;r0 |=  1<<bitpos 
	bclr	r4,r3			;r4 &~= 1<<bitpos
	cmpeqi	r2,0			;0 = reset else set
	movets	r0,r4,r0
	nop
	st	r5,r0			;store back
		
	rqpop
	rqpop
	rqpop
	pop	r5
	pop	r4
	pop	r3
	
	rqpop
	jmpi	r7,0	
	nop		;delay slot
	pop	r0	;delay slot
	nop		;delay slot
	nop		;delay slot
		
	;data
	
	.def	ePS2StateWait			0
	.def	ePS2StateWaitBreak		1
	.def	ePS2StateWaitExtended		2
	.def	ePS2StateWaitExtendedBreak	3
	
	
mPS2State	word	ePS2StateWait		
		
mPSNormalKeys	
	.space	9	;16 * 9 = 144 bit
	
mPSExtendedKeys	
	.space	9	;16 * 8 = 144 bit
	
mLastKey	word	0	
	
;*********************************************************************
;* info
;*********************************************************************
	
	;Key		Hex Value (e0 is extended)
	
	;F9		1
	;F5             3
	;F3             4
	;F1             5
	;F2             6
	;F12            7
	;F10            9
	;L ALT          11
	;L SHFT         12
	;L CTRL         14
	;Q              15
	;1              16
	;C              21
	;X              22
	;D              23
	;E              24
	;4              25
	;3              26
	;SPACE          29
	;N              31
	;B              32
	;H              33
	;G              34
	;Y              35
	;6              36
	;K              42
	;I              43
	;O              44
	;0              45
	;9              46
	;'              52
	;[              54
	;=              55
	;CAPS           58
	;R SHFT         59
	;BKSP           66
	;KP 1           69
	;KP 0           70
	;KP .           71
	;KP 2           72
	;KP 5           73
	;KP 6           74
	;KP 8           75
	;ESC            76
	;NUM            77
	;F11            78
	;KP +           79
	;F7             83
	;F8             0A
	;F6             0B
	;F4             0C
	;TAB            0D
	;`              0E
	;Z              1A
	;S              1B
	;A              1C
	;W              1D
	;2              1E
	;V              2A
	;F              2B
	;T              2C
	;R              2D
	;5              2E
	;M              3A
	;J              3B
	;U              3C
	;L              4B
	;;              4C
	;P              4D
	;-              4e
	;ENTER          5A
	;]              5B
	;\              5D
	;KP 4           6B
	;KP 7           6C
	;KP 3           7A
	;KP -           7B
	;KP *           7C
	;KP 9           7D
	;WWW Search     E0, 10
	;Previous Track E0, 15
	;WWW Favorites  E0, 18
	;WWW Refresh    E0, 20
	;Volume Down    E0, 21
	;Mute           E0, 23
	;WWW Stop       E0, 28
	;Calculator     E0, 2B
	;WWW Forward    E0, 30
	;Volume Up      E0, 32
	;Play/Pause     E0, 34
	;Power          E0, 37
	;WWW Back       E0, 38
	;WWW Home       E0, 3A
	;Stop           E0, 3B
	;Sleep          E0, 3F
	;My Computer    E0, 40
	;E-Mail         E0, 48
	;Next Track     E0, 4D
	;Media Select   E0, 50
	;Wake           E0, 5E
	;R ALT          E0,11
	;PRNT           E0,12, E0,7C 
	;R CTRL         E0,14
	;L GUI          E0,1F
	;R GUI          E0,27
	;APPS           E0,2F
	;KP /           E0,4A
	;KP EN          E0,5A
	;END            E0,69
	;L ARROW        E0,6B
	;HOME           E0,6C
	;INSERT         E0,70
	;DELETE         E0,71
	;D ARROW        E0,72
	;R ARROW        E0,74
	;U ARROW        E0,75
	;PG DN          E0,7A
	;PG UP          E0,7D
	;PAUSE          E1,14,77, E1,F0,14, F0,77
	