;*******************************************************************************
; C H A M E L E O N   DSP Assembler file                                       *
;*******************************************************************************
;Aleix Riera
;www.fjarre.com/~aleix
;aleix@fjarre.com
;*******************************************************************************
;
; MODULE: 4MIXER for Delay
;	It mixes 4 IN's to 1 OUT, controlling only volumes.
;
;	OUTleft[i] =	IN1[i]*Vol1[i] +
;	 		IN2[i]*Vol2[i] +
;			IN3[i]*Vol3[i] +
;			IN4[i]*Vol4[i] +
;
;	OUTright[i] =	IN1[i]*Vol1[i] +
;	 		IN2[i]*Vol2[i] +
;			IN3[i]*Vol3[i] +
;			IN4[i]*Vol4[i] +
;
; ARGUMENTS:
;
;	(X)=	OutLAddr	- Output Stereobuffer (L)
;
;	(X+1) = InLAddr	1	- Input Stereobuffer (L)
;	(X+2) = Vol 1		- Volume
;	(X+3) = InRAddr	2	- Input Stereobuffer (L)
;	(X+4) = Vol 2		- Volume
;	(X+5) = InLAddr	3	- Input Stereobuffer (L)
;	(X+6) = Vol 3		- Volume
;	(X+7) = InLAddr	4	- Input Stereobuffer (L)
;	(X+8) = Vol 4		- Volume
;
;******************************************************************************
module_4mixerD:
	define	R_OutL		'R1'
	define	R_OutR		'R5'
	define	R_InLi		'R2'
	define	R_InRi		'R6'

;===============================CODE=====================================

	MOVE 		X:(R_X),R_OutL
	MOVE		X:(R_X),R_OutR
	
	;Clear output buffer to accumulate the In's
	CLR	A
	REP	#BUFFER_SIZE
		MOVE		A,X:(R_OutL)+	A,Y:(R_OutR)+

	MOVE		X:(R_X),R_OutL
	MOVE		X:(R_X)+,R_OutR

	;for each channel (1 to 4): We will repeat code for 4 times
	;CHANNEL 0
		MOVE		X:(R_X),R_InLi
		MOVE		X:(R_X)+,R_InRi
		MOVE		X:(R_X)+,X1
		
		MOVE				Y:(R_OutR),Y1
		MOVE		X:(R_InLi)+,X0
		MPY	X0,X1,A			Y:(R_InRi)+,Y0
		MPY	Y0,X1,B X:(R_OutL),X0
		ADD	X0,A
		ADD	Y1,B	X:(R_InLi)+,X0	Y:(R_InRi)+,Y0
		.LOOP	#BUFFER_SIZE
		;----------------------------------------------------------------
		MPY	X0,X1,A	A,X:(R_OutL)+
		MPY	Y0,X1,B	X:(R_OutL),X0	B,Y:(R_OutR)+
		ADD	X0,A			Y:(R_OutR),Y1
		ADD	Y1,B	X:(R_InLi)+,X0	Y:(R_InRi)+,Y0
		;----------------------------------------------------------------
		.ENDL
	;END CHANNEL 0

	MOVE	X:(R_X-3),R_OutL
	MOVE	X:(R_X-3),R_OutR

	;CHANNEL 1
		MOVE		X:(R_X),R_InLi
		MOVE		X:(R_X)+,R_InRi
		MOVE		X:(R_X)+,X1
		
		MOVE				Y:(R_OutR),Y1
		MOVE		X:(R_InLi)+,X0
		MPY	X0,X1,A			Y:(R_InRi)+,Y0
		MPY	Y0,X1,B X:(R_OutL),X0
		ADD	X0,A
		ADD	Y1,B	X:(R_InLi)+,X0	Y:(R_InRi)+,Y0
		.LOOP	#BUFFER_SIZE
		;----------------------------------------------------------------
		MPY	X0,X1,A	A,X:(R_OutL)+
		MPY	Y0,X1,B	X:(R_OutL),X0	B,Y:(R_OutR)+
		ADD	X0,A			Y:(R_OutR),Y1
		ADD	Y1,B	X:(R_InLi)+,X0	Y:(R_InRi)+,Y0
		;----------------------------------------------------------------
		.ENDL
	;;END CHANNEL 1

	MOVE	X:(R_X-5),R_OutL
	MOVE	X:(R_X-5),R_OutR

	;CHANNEL 2
		MOVE		X:(R_X),R_InLi
		MOVE		X:(R_X)+,R_InRi
		MOVE		X:(R_X)+,X1
		
		MOVE				Y:(R_OutR),Y1
		MOVE		X:(R_InLi)+,X0
		MPY	X0,X1,A			Y:(R_InRi)+,Y0
		MPY	Y0,X1,B X:(R_OutL),X0
		ADD	X0,A
		ADD	Y1,B	X:(R_InLi)+,X0	Y:(R_InRi)+,Y0
		.LOOP	#BUFFER_SIZE
		;----------------------------------------------------------------
		MPY	X0,X1,A	A,X:(R_OutL)+
		MPY	Y0,X1,B	X:(R_OutL),X0	B,Y:(R_OutR)+
		ADD	X0,A			Y:(R_OutR),Y1
		ADD	Y1,B	X:(R_InLi)+,X0	Y:(R_InRi)+,Y0
		;----------------------------------------------------------------
		.ENDL
	;END CHANNEL 2

	MOVE	X:(R_X-7),R_OutL
	MOVE	X:(R_X-7),R_OutR

	;CHANNEL 3
		MOVE		X:(R_X),R_InLi
		MOVE		X:(R_X)+,R_InRi
		MOVE		X:(R_X)+,X1
		
		MOVE				Y:(R_OutR),Y1
		MOVE		X:(R_InLi)+,X0
		MPY	X0,X1,A			Y:(R_InRi)+,Y0
		MPY	Y0,X1,B X:(R_OutL),X0
		ADD	X0,A
		ADD	Y1,B	X:(R_InLi)+,X0	Y:(R_InRi)+,Y0
		.LOOP	#BUFFER_SIZE
		;----------------------------------------------------------------
		MPY	X0,X1,A	A,X:(R_OutL)+
		MPY	Y0,X1,B	X:(R_OutL),X0	B,Y:(R_OutR)+
		ADD	X0,A			Y:(R_OutR),Y1
		ADD	Y1,B	X:(R_InLi)+,X0	Y:(R_InRi)+,Y0
		;----------------------------------------------------------------
		.ENDL
	;END CHANNEL 3

;===============================CODE=====================================

	undef	R_OutL
	undef	R_OutR
	undef	R_InLi
	undef	R_InRi
	
	RTS