;*******************************************************************************
; C H A M E L E O N   DSP Assembler file                                       *
;*******************************************************************************
; Copyright (C) 2001-2002 Soundart                                             *
; www.soundart-hot.com                                                         *
; support@soundart-hot.com                                                     *
;*******************************************************************************
; Modified by Aleix Riera
; aleix@fjarre.com
; www.fjarre.com/~aleix
;*******************************************************************************
;
; MODULE: Osc2: ONLY 1 SAMPLE / BUFFER_SIZE
;	Linear interpolated wavetable oscillator with fixed amplitude and 
;	frequency (see doc/dsp/appnotes/APR1.pdf from the Motorola application
;	notes to understand the direct table look-up with linear interpolation).
;
;	This code is based in the file osci.asm from the musickit source code.
;	MusicKit is a set of classes and object templates used in NeXT computers
;	(which include a DSP56002 chip) to build applications for music composition,
;	synthesis and performance (author: Julius Smith, James A. Moorer.
; 	Copyright 1990 NeXT Computer, Inc. All rights reserved).
;
; NOTE: The ouput signal is NOT filtered to ensure a bandlimited spectrum, thus
;	if the wavetable contains sudden sample transitions (as the sawtooth or
;	the square waveform), the output signal will be aliased.
;
; ARGUMENTS:
;	(X)   = TableAddr	- Wavetable address (X)
;	(X+1) = TableMask	- Wavetable length - 1
;	(X+2) = Out		- Output sample (Y)
;	(X+3) = Amplitude	- Oscillator amplitude
;	(X+4) = INT(Inc)	- Phase increment
;	(X+5) = FRAC(Inc)	-
;	(X+6) = INT(Phase)	- Current phase
;	(X+7) = FRAC(Phase)	-
;
;******************************************************************************
module_osc:
	define	R_Table1		'R1'
	define	N_Table1		'N1'
	define	R_Table2		'R6'
	define	N_Table2		'N6'
	define	R_Out			'R5'
	define	R_Tmp			'R2'

;===============================CODE=====================================

	MOVE 	X:(R_X)+,R_Table1		;(X)   = TableAddr (X)
	MOVE	X:(R_X)+,X0			;(X+1) = TableMask
	MOVE	X:(R_X)+,R_Out			;(X+2) = OutAddr (Y)
	CLR	A		R_X,R_Tmp
	MOVE	X:(R_X)+,X1			;(X+3) = Amplitude
	MOVE	X:(R_X)+,Y1			;(X+4) = INT(Inc)
	MOVE	X:(R_X)+,Y0			;(X+5) = FRAC(Inc)

	MOVE	X:(R_X)+,A1			;(X+6) = INT(Phase)
	MOVE	X:(R_X)-,A0			;(X+7) = FRAC(Phase)
	MOVE	R_Table1,R_Table2

	AND	X0,A		#>1,B
	ADD	A,B
	MOVE	A0,X1

	;.LOOP	#BUFFER_SIZE
	;----------------------------------------------------------------
	  AND	X0,B		A1,N_Table1
	  NOP
	  TFR	X1,B		B1,N_Table2
	  LSR	B
	  NOP
	  MOVE	B1,X1
	  MOVE	X:(R_Table2+N_Table2),B
	  MOVE	X:(R_Table1+N_Table1),Y1
	  SUB	Y1,B
	  NOP
	  TFR	Y1,B		B,Y1
	  MACR	X1,Y1,B		X:(R_Tmp)+,X1
	  NOP
	  MOVE	B,Y1
	  MPYR	Y1,X1,B		X:(R_Tmp)+,Y1
	  MOVE	X:(R_Tmp)-,Y0
	  ADD	Y,A		(R_Tmp)-
	  AND	X0,A		#>1,B		B,Y1
	  MOVE	Y1,Y:(R_Out)+
	  ADD	A,B		A0,X1
	;----------------------------------------------------------------
	;.ENDL

	MOVE	A1,X:(R_X)+
	MOVE	A0,X:(R_X)+

;===============================CODE=====================================

	undef	R_Table1
	undef	N_Table1
	undef	R_Table2
	undef	N_Table2
	undef	R_Out
	undef	R_Tmp

	RTS