;*******************************************************************************
; C H A M E L E O N   DSP Assembler file                                       *
;*******************************************************************************
; Copyright (C) 2001-2003 Soundart                                             *
; www.soundart-hot.com                                                         *
; support@soundart-hot.com                                                     *
;*******************************************************************************
; Modified by Aleix Riera
; aleix@fjarre.com
; www.fjarre.com/~aleix
;*******************************************************************************
;
; MODULE: DelayR (only RIGHT audio (Y))
;	This module implements an interpolating delay with feedback. It uses 
;	fractional delay size from 0 to 1.0
;
;	The code is based in the file units.asm from the 56000 assembly code
;	once part of HMSL, the Forth based Hierarchical Music Specification Language.
;	HMSL was developed by Phil Burk, Larry Polansky and David Rosenboom
;
;	NOTE: New modification: The audio thru is blocked
;
; ARGUMENTS:
;	(X)   = InAddr		- Input buffer (Y)
;	(X+1) = OutAddr		- Output buffer (Y)
;	(X+2) = DelayAddr	- Delay buffer address (X)
;	(X+3) = MaxLength	- MaxLength in words of the delay buffer
;	(X+4) = Index		- Index inside the delay buffer
;	(X+5) = Level		- Send level of the input signal to the module
;	(X+6) = DelaySize	- Fractional delay size (1.0 = size of the delay buffer)
;	(X+7) = Feedback	- Level of the signal to be sent to the input again
;
;******************************************************************************
module_delay_R:

	define	R_In			'R5'
	;define	R_Out			'R5'
	define	R_Table1		'R6'
	define	N_Table1		'N6'
	define	R_Table2		'R7'
	define	N_Table2		'N7'

;===============================CODE=====================================

	MOVE	X:(R_X)+,R_In
	;MOVE	X:(R_X)+,R_Out
	MOVE	X:(R_X)+,N4
	MOVE	X:(R_X)+,R_Table1		; R_Table = first position of the delay buffer
	MOVE	X:(R_X)+,Y0			; MaxLength of delay buffer
	MOVE	X:(R_X)+,B			; next integer index in delay buffer

	MOVE	R_Table1,R_Table2

	
	.LOOP	#BUFFER_SIZE
	;----------------------------------------------------------------
	  MOVE	X:(R_X)+,X0	Y:(R_In),Y1	; Y1 = input sample
	  MPY	X0,Y1,A		X:(R_X)+,X1	; A = input_level * input_sample
	  					; X1 = FRACTIONAL tap delay
	  MAC	X1,Y0,B		B,N2		; B = FP tap offset
	  CMP	Y0,B		Y0,N1
	  SUB	Y0,B	IFGE
	  MOVE	#>$1,X1
	  ADD	X1,B		B1,N_Table1	; N_Table = Int tap offset
	  CMP	Y0,B
	  SUB	Y0,B	IFGE
	  MOVE	A,Y1
	  MOVE	B1,N_Table2
	  MOVE	B0,B1				; B1 = save fraction, clip off higher bits
	  LSR	B				; convert to 0-1 range,
	  NOP
	  MOVE	X:(R_Table1+N_Table1),X0	; X0 = delayed sample from table
	  TFR	X0,A		B1,X1		; X1 = interpolating fraction
	  MAC	-X1,X0,A	N2,N_Table1	; -frac*s[n]
	  MOVE	X:(R_Table2+N_Table2),Y0	; get next sample
	  MAC	X1,Y0,A		X:(R_X)-,X1 	; A= frac*s[n+1] - frac*s[n], X1 = feedback level
	  					; samp = s[n] + frac*s[n+1] - frac*s[n]
	  MOVE	Y:(R_In)+,Y0			; Y0 = input
	  ;ADD	Y0,A		A,X0		; A = input + delayed
	  ;added by me
	  MOVE	A,X0
	  ;added by me				; X0 = delayed
	  MPY	X0,X1,B		#>$1,X1		; B = delayed*feedbackLevel
	  ADD	Y1,B		(R_X)-		; B = scaled_input + delayed*feedback
	  ;;by me
	  MOVE	R_X,N5
	  MOVE	N4,R_X
	  ;;by me
	  ;MOVE	A,Y:(R_Out)+			; save output
	  NOP
	  NOP
	  NOP
	  MOVE	A,Y:(R_X)+
	  MOVE	R_X,N4
	  MOVE	N5,R_X
	  
	  MOVE	B,X:(R_Table1+N_Table1)		; save sample + feedback into delay line
	  MOVE	N2,B
	  SUB	X1,B		N1,Y0
	  ADD	Y0,B	IFLT
	;----------------------------------------------------------------
	.ENDL

	NOP
	MOVE	B,X:(R_X-1)		; save updated sample position
	LUA	(R_X+3),R_X

;===============================CODE=====================================

	undef	R_In
	;undef	R_Out
	undef	R_Table1
	undef	R_Table2
	undef	N_Table1
	undef	N_Table2

	RTS