/**
	\file chacha20Asm.s
	
*/
#include <vstypes.h>


#ifdef ASM

#if 0

	.sect data_y,const_y
	.export _chacha20QuarterRollConst
_chacha20QuarterRollConst:
	.word 0,12,12-32,8,8-32,7,7-32

	.sect code,Chacha20QuarterRoll8
	.export _Chacha20QuarterRoll8
_Chacha20QuarterRoll8:
	ldx (i6)+1,null
	stx i0,(I6)+1;	sty i1,(I6)
	stx i2,(I6)+1;	sty i3,(I6)
	stx le,(I6)+1;	sty ls,(I6)
	stx lr0,(I6)+1;	sty lc,(I6)
	stx a0,(I6)+1;	sty a1,(I6)
	stx b0,(I6)+1;	sty b1,(I6)
	stx c0,(I6)+1;	sty c1,(I6)
	stx d0,(I6)+1;	sty d1,(I6)

	.import _chachaWorkP
	ldc _chachaWorkP,i7
	ldc _chacha20QuarterRollConst,i5

	ldc 8-1,ls
	ldx (i5)+1,null; ldy (i7)+3,i0
	ldx (i0)+1,a0;	ldy (i7)-2,i3
	loop ls,$9-1
	ldx (i3)+1,d0

	ldx (i0)-1,a1;	ldy (i7)+1,i1
	ldx (i1)+1,b0
	ldx (i1),b1;	ldy (i7)+2,i2
	add a,b,a;	ldx (i3),d1

	xor d,a,d;	ldx (i2)+1,c0
	stx a0,(i0);	sty d1,(i6)
	add d0,null,d1;	ldy (i6),d0;	ldx (i2),c1

	add c,d,c;	ldy (i5)-1,a0
	xor b,c,b;	ldy (i5)+2,b2
	ashl b,a0,c;	stx c0,(i6);	sty c1,(i6)
	ldy (i5)+1,a0
	ashl b,a0,b;	ldx (i0),a0
	xor b,c,b;	ldy (i5)-3,c0
	add a,b,a
	xor d,a,d;	stx a0,(i0)+1

	ldy (i5)+4,d2;	stx a1,(i0)
	ashl d,c0,c;	ldy (i5)+1,a0
	ashl d,a0,d;	ldy (i7)+3,i0
	xor d,c,d;	ldx (i6),c0;	ldy (i6),c1
	
	add c,d,c;	ldy (i5)-5,a0
	xor b,c,b;	stx c1,(i2)-1
	stx d1,(i3)-1;	ldy (i5)+6,b2
	ashl b,a0,d;	stx d0,(i3);	ldy (i5),c1
	ldx (i0)+1,a0;	ldy (i7)-2,i3
	ashl b,c1,b;	stx c0,(i2)
	xor b,d,b;	ldx (i3)+1,d0

	stx b1,(i1)-1;	ldy (i5)-5,null
	stx b0,(i1)

$9:
	ldx (I6)-1,null
	ldx (I6)-1,d0;	ldy (I6),d1
	ldx (I6)-1,c0;	ldy (I6),c1
	ldx (I6)-1,b0;	ldy (I6),b1
	ldx (I6)-1,a0;	ldy (I6),a1
	ldx (I6)-1,lr0;	ldy (I6),lc
	ldx (I6)-1,le;	ldy (I6),ls
	ldx (I6)-1,i2;	ldy (I6),i3
	jr
	ldx (I6)-1,i0;	ldy (I6),i1

#else

/*
	void Chacha20QuarterRoll8N(register __c0 s_int16 n);
*/

.sect data_y,const_y
	.import _chachaWorkP
	.export _chacha20QuarterRollConst
_chacha20QuarterRollConst:
	.word 0,12,12-32,8,8-32,7,7-32,_chachaWorkP,8-1

.sect code,Chacha20QuarterRoll8N
	.export _Chacha20QuarterRoll8N
_Chacha20QuarterRoll8N:
	ldx (i6)+1,null
	stx i0,(I6)+1;	sty i1,(I6)
	stx i2,(I6)+1;	sty i3,(I6)
	stx le,(I6)+1;	sty ls,(I6)
	stx lr0,(I6)+1;	sty lc,(I6)
	stx a0,(I6)+1;	sty a1,(I6)
	stx b0,(I6)+1;	sty b1,(I6)
	stx i4,(I6)+1;	sty c1,(I6)
	stx d0,(I6)+1;	sty d1,(I6)

	ldc _chacha20QuarterRollConst+7,i5

	mv i6,i4
	j $8
	stx c0,(i6)+1

$1:	// Outer loop start
	loop ls,$8-1
	ldx (i3)+1,d0

$2:	// Inner loop start
	ldx (i0)-1,a1;	ldy (i7)+1,i1
	ldx (i1)+1,b0;	ldy (i5)-6,null
	ldx (i1),b1;	ldy (i7)+2,i2
	add a,b,a;	ldx (i3),d1

	xor d,a,d;	ldx (i2)+1,c0
	stx a0,(i0);	sty d1,(i6)
	add d0,null,d1;	ldy (i6),d0;	ldx (i2),c1

	add c,d,c;	ldy (i5)-1,a0
	xor b,c,b;	ldy (i5)+2,b2
	ashl b,a0,c;	stx c0,(i6);	sty c1,(i6)
	ldy (i5)+1,a0
	ashl b,a0,b;	ldx (i0),a0
	xor b,c,b;	ldy (i5)-3,c0
	add a,b,a
	xor d,a,d;	stx a0,(i0)+1

	ldy (i5)+4,d2;	stx a1,(i0)
	ashl d,c0,c;	ldy (i5)+1,a0
	ashl d,a0,d;	ldy (i7)+3,i0
	xor d,c,d;	ldx (i6),c0;	ldy (i6),c1
	
	add c,d,c;	ldy (i5)-5,a0
	xor b,c,b;	stx c1,(i2)-1
	stx d1,(i3)-1;	ldy (i5)+6,b2
	ashl b,a0,d;	stx d0,(i3);	ldy (i5),c1
	ldx (i0)+1,a0;	ldy (i7)-2,i3
	ashl b,c1,b;	stx c0,(i2)
	xor b,d,b;	ldx (i3)+1,d0

	stx b1,(i1)-1;	ldy (i5)+1,null
	stx b0,(i1)
	// Inner loop end	
$8:
	ldx (i4),c0;	ldy (i5)+1,i7
	add c0,ones,c0;	ldy (i7)+3,i0
	stx c0,(i4);	ldy (i5)-1,ls
	jnc $1
	ldx (i0)+1,a0;	ldy (i7)-2,i3
	
	// Outer loop end
$9:
	ldx (I6)-2,null
	ldx (I6)-1,d0;	ldy (I6),d1
	ldx (I6)-1,i4;	ldy (I6),c1
	ldx (I6)-1,b0;	ldy (I6),b1
	ldx (I6)-1,a0;	ldy (I6),a1
	ldx (I6)-1,lr0;	ldy (I6),lc
	ldx (I6)-1,le;	ldy (I6),ls
	ldx (I6)-1,i2;	ldy (I6),i3
	jr
	ldx (I6)-1,i0;	ldy (I6),i1

#endif



/*
	void Chacha20Sum32NXY(register __i0 u_int32 *d, register __i2 u_int32 __mem_y *s, register __a0 s_int16 n);
*/
	.sect code,Chacha20Sum32NXY
	.export _Chacha20Sum32NXY
_Chacha20Sum32NXY:
	add a0,ones,a0;	ldx (i6)+1,null
	stx c0,(I6)+1;	sty c1,(I6)
	stx le,(I6)+1;	sty ls,(I6)
	stx a1,(I6)+1;	sty lc,(I6)
	stx d0,(I6)+1;	sty d1,(I6)
	stx i1,(I6)+1;	sty i3,(I6)

	jns $9
	stx b0,(I6);	sty b1,(I6)

	ldc 8,c0
	mv a0,ls
	ldc 3,i1
	ldc -1,i3

	ldx (i0)+1,a0;	ldy (i2)+1,b0
	ldx (i0)+1,a1;	ldy (i2)+2,b1
	loop ls,$9-1
	add a,b,b

	and d1,null,d1; mv b0,d0
	ashl d,c0,d;	ldx (i0)-2,a0
	or d0,d1,b0;	mv b1,d0
	and d1,null,d1;	stx b0,(i0)*;	ldy (i2)*,b1
	ashl d,c0,d;	ldy (i2)+3,b0
	or d0,d1,c1;	ldx (i0)-2,a1
	add a,b,b;	stx c1,(i0)+3

$9:
	ldx (I6)-1,b0;	ldy (I6),b1
	ldx (I6)-1,i1;	ldy (I6),i3
	ldx (I6)-1,d0;	ldy (I6),d1
	ldx (I6)-1,a1;	ldy (I6),lc
	ldx (I6)-1,le;	ldy (I6),ls
	jr
	ldx (I6)-1,c0;	ldy (I6),c1




/*
void Chacha20XOR16(register __i0 unsigned u_int16 *d, register __i2 u_int32 *s);
*/
	.sect code,Chacha20XOR16
	.export _Chacha20XOR16
_Chacha20XOR16:
	ldx (i6)+1,null
	stx lc,(I6)+1;	sty a1,(I6)
	stx le,(I6)+1;	sty ls,(I6)
	
	ldc 32-1,ls
	loop ls,$9-1
	ldx (i2)+1,a0;	sty a0,(I6)

	ldx (i0),a1
	xor a0,a1,a1;	ldx (i2)+1,a0
	stx a1,(i0)+1

$9:
	ldy (I6)-1,a0
	ldx (I6)-1,le;	ldy (I6),ls
	jr
	ldx (I6)-1,lc;	ldy (I6),a1


#endif /* ASM */




	.end



#if 0
	/********* EVERYTHING FROM NOW ON IS PURELY DECORATIONAL!!! **********/

/*
	void Generic(void) - 2018 edition
*/
	.sect code,Generic
	.export _Generic
_Generic:
	ldx (i6)+1,null
	stx i0,(I6)+1;	sty i1,(I6)
	stx i2,(I6)+1;	sty i3,(I6)
	stx le,(I6)+1;	sty ls,(I6)
	stx lr0,(I6)+1;	sty lc,(I6)
	stx a0,(I6)+1;	sty a1,(I6)
	stx b0,(I6)+1;	sty b1,(I6)
	stx c0,(I6)+1;	sty c1,(I6)
	stx d0,(I6)+1;	sty d1,(I6)
	stx i4,(I6)

	ldx (I6)-1,i4
	ldx (I6)-1,d0;	ldy (I6),d1
	ldx (I6)-1,c0;	ldy (I6),c1
	ldx (I6)-1,b0;	ldy (I6),b1
	ldx (I6)-1,a0;	ldy (I6),a1
	ldx (I6)-1,lr0;	ldy (I6),lc
	ldx (I6)-1,le;	ldy (I6),ls
	ldx (I6)-1,i2;	ldy (I6),i3
	jr
	ldx (I6)-1,i0;	ldy (I6),i1
#endif
