;****************************************************************
;  EECS 452 Digital Signal Processing Design Laboratory         *
;  Delay Audio Effect				                      *
;  File : delay.asm                                             *
;  Author : Eric Veit, Kevin Ziemer, Rob Wolfbrandt, Raghav Mani & Kurt Metzger *
;                                                               *
;  This program takes in an audio signal, and adds a certain    *;  a certain amount of delay, based on knob settings            *
;****************************************************************
 
         page    132,60
         opt      mex
         
         ; Allocate the Y memory between top of on-chip memory
         ; and the bottom of the off chip memory so that it
         ; won't accidentally be used.
                  SECTION    X_FILL 
GAP_BOT  EQU    $800        
         org    x:GAP_BOT
x_fill   ds     $10000-GAP_BOT
         ENDSEC

         SECTION    Y_FILL 
GAP_BOT  EQU    $800        
         org    y:GAP_BOT
y_fill   ds     $10000-GAP_BOT
         ENDSEC

;============================================================================
; Our Delay Buffer Allocated:
;============================================================================

         ; The RTFFT section contains the main code

         SECTION    RTFFT

         nolist
         include  'ioequ.asm'       ; define I/0 equates
         include  'intequ.asm'      ; define interrupt equates
         include  'v_init.asm'      ; read interrupt vector initialization
         include  'ada_equ.asm'     ; read CODEC support definitions
         list

;****************************************************************************
; the following EQUates will define the operatonal parameters
;   of the codec.  Please refer to the ADA_EQU.ASM source file
;   for a description of the parameters selections available.  The
;   variables defined by the EQUates are sent to the  codec via 
;   the transmit buffer, TX_BUFF.
;
;   Since the parameters are defined in ADA_EQU.ASM, these lines must
;   follow the include statement.
;****************************************************************************

TONE_OUTPUT     EQU     HEADPHONE_EN+LINEOUT_EN+(0*LEFT_ATTN)+(0*RIGHT_ATTN)   
TONE_INPUT      EQU     MIC_IN_SELECT+(15*MONITOR_ATTN)


B_SIZE         EQU     512     ; Define the size of the FFT here!!!!


; Declare relative storage prior to defining absolute storage

        org    x:               ; first assign x memory

stack    ds    40       ; allocate the stack

IR_FLAGS        ds      1       ; interrupt flags
IRA             EQU     0       ; SW 2 pressed
IRD             EQU     1       ; SW 3 pressed
LASTTIME        ds      1

ENCOUNT1        ds      1
ENCOUNT2        ds      1
ENCOUNT3        ds      1
ENCOUNT4        ds      1

DELAY_VAR		equ	1800

;---------------------Memory allocation--------------------------
;============================================================================
; Our Delay Buffer Allocated:
;============================================================================
	   org 	x:$10000			;Starting off chip memory
buffer	equ	*
buff 	   dsm 	27000			;setting up sample buffer circular
;============================================================================


        org     x:B_SIZE            
        
LSIZE   EQU     B_SIZE+128     ; need extra room for smaller transforms
l_inp   dsm     LSIZE           ; left channel input sample buffer
l_out   dsm     LSIZE           ; left channel output value buffer


;----------------------------------------------------------------
;   Interrupt vectors

        org P:0

        jmp     START                   ; reset comes here

        org p:I_IRQA                    ; IRQA .. EVM SW2 pressed

        jsr     EVM_SW2                 ; call sw2 interrupt handler

        org p:I_IRQD                    ; IRQD .. EVM SW3 pressed

        jsr     EVM_SW3                 ; call sw3 interrupt handler

        org p:I_TIM2C

        jsr     >TIMER2C
        
                                                                
;---------------------Program start address----------------------

        org     p:$100

START
        ori     #3,mr                   ; disable interrupts
        movep   #$040004,x:M_PCTL       ; PLL = 5 x 16.9344Mhz = 84.672MHz

                                        ; set up ext memory wait state counts
        movep   #012422,x:M_BCR         ; load bus control register
                                        ; 00002 area 0 wait state for SRAM
                                        ; 00001 area 1 wait states
                                        ; 001   area 2 wait states
                                        ; 001   area 3 wait states
                                        ; 00001 default wait states
                                        ; 000   state, lock, request
                                        
                                        ; set use of external SRAM
SRAM    equ     $010000                 ; starting address of 32 KW SRAM
        movep   #$010931,x:M_AAR0       ; load address atribute register 0
                                        ; 01   static ram access
                                        ; 0    polarity
                                        ; 0    program space enable
                                        ; 1    x address space enable
                                        ; 1    y address space enable
                                        ; 0    address multiplexing
                                        ; 0    packing enable
                                        ; 1001 Number of address bit to compare
                                        ; 0000 0001 0000  addr to compare
                                        ; described in EVM manual pps 4-7, 4-8
        movep   #$000A05,X:M_IPRC       ; IRQA/IRQD/SSI level 1 interrupts. edge sensitive
        bset    #M_MS,omr

        movec   #0,SP                   ; clear stack pointer
        move    #0,SC                   ; clear stack counter
        movep   #$0,x:M_TCSR0           ; turn LED off

        move    #stack,r6               ; initialize stack pointer
        move    #-1,m6                  ; linear addressing for stack

        movep   #>$1,x:M_HPCR           ; enable GPIO B input to CPU
        movep   #>$1,x:M_HDDR

; --- INIT THE CODEC ---

        jsr     ada_init                ; jump subroutine to initialize the codec
        
        move    #l_inp,x0               ; address of left channel input buffer
        move    #LSIZE,x1               ; size of the buffer
        jsr     get_l_init              ; initialize left input support
        move    #l_out,x0               ; address of left channel output buffer
        move    #LSIZE,x1               ; size of the buffer
        jsr     put_l_init              ; initialize left output support
        
        move    #TONE_OUTPUT,y1         ; headphones, line out, mute spkr, no attn.
        move    y1,x:DA_DATA+2
        move    #TONE_INPUT,y1          ; no input gain, monitor mute
        move    y1,x:DA_DATA+3
       

; ---- INIT THE KNOBS ---------

        move    #>5,x0
        move    x0,x:ENCOUNT1           ; initialize counters
        move    x0,x:ENCOUNT2
        move    x0,x:ENCOUNT3
        move    x0,x:ENCOUNT4
        
        movep   x:M_HDR,x0              ; read switch states
        move    x0,x:LASTTIME           ; initialize LASTTIME       
        movep   #200000,x:M_TCPR2       ; set clock tic rate
        movep   #0,x:M_TLR2             ; start counting from 0
        movep   #$205,x:M_TCSR2

	  movep	x:M_IPRP,a1			
	  move	#>$100,x0
	  or		x0,a
	  movep	a,x:M_IPRP			; Sets the appropriate Inturrupts

        andi    #$FC,mr                 ; enable interrupts 
                                                               
;---------------------Main program loop--------------------------

;============================================================================
; Our Code goes here
;============================================================================
	  move #buffer,r4			;starting out with first sample
	  move #0,n4			;making sure offset register is set to 0
	  move #26999,m4  
loop
            jsr get_l_val            	; returns value in a
		move a,x:(r4)		
		move x:(r4)-,x0			; x0=new sample
		move	x:ENCOUNT1,x1		; X1 = position of the first knob (delay time)
		move	#>DELAY_VAR,y1
		mpy	y1,x1,a
		asl	#23,a,a			; a1 = offset
		move	a,n4
		move x:(r4+n4),a			; gets delayed audio
		move a,y0				;y0 contains delayed sample
		move x:ENCOUNT2,x1		; x1=position of second knob (delay amplitude)
		mpy #0.0333,x1,b			;0.0333 =.5/16
		and #0,b
		asl #23,b,b
		move b,x1				;x1=scaling coefficient
		clr a					;clear accumulator
		mac x1,y0,a
		mac #0.5,x0,a 
            move a,x0
            jsr put_l_val
            jmp loop
;============================================================================

TIMER2C                                 ; timer 2 compare interrupt support
        move    x0,x:(r6)+
        move    x1,x:(r6)+
        move    a0,x:(r6)+
        move    a1,x:(r6)+
        move    a2,x:(r6)+
	  move    m0,x:(r6)+
	  move    n0,x:(r6)+
        move    r0,x:(r6)+

        movep   x:M_HDR,x0              ; get switches this time
        move    x:LASTTIME,a            ; get switches last time
        eor     x0,a1                   ; look for changes
        and     #>$5500,a               ; retain A bits only
        tst     a                       ; 0 = no changes
        jeq     testend
        move    a,x1                    ; save changes
        brclr   #8,a1,set_limits_1           ; branch if sw1 not change
        move    x:ENCOUNT1,r0
		  move	#$FFFF,m0
        move    x0,a1                   ; get switch states
        lsl     a                       ; shift A into B position
        eor     x0,a1                   ; checking direction
        brset   #9,a1,sw1up
        move    (r0)-
        move    r0,x:ENCOUNT1
        jmp     set_limits_1
sw1up   move    (r0)+
        move    r0,x:ENCOUNT1    

;-------------------------------------------------------------------
; This following section successfully sets the limits of the nobs to be
; 0 <= knob <= 15
set_limits_1
	move	x:ENCOUNT1,r0
	brclr	#23,r0,pos_cot_1
	move	#0,r0
	move	r0,x:ENCOUNT1
	jmp	within_lim1
pos_cot_1
	brclr	#4,r0,within_lim1
	move	#>15,r0
	move	r0,x:ENCOUNT1
within_lim1
;-------------------------------------------------------------------
   
testsw2
        move    x1,a                    ; get changes back
        brclr   #10,a1,testsw3
        move    x:ENCOUNT2,r0
	  move	#$FFFF,m0
        move    x0,a1                   ; get switch states
        lsl     a                       ; shift A into B position
        eor     x0,a1                   ; checking direction
        brset   #11,a1,sw2up
        move    (r0)-
        move    r0,x:ENCOUNT2
        jmp     set_limits_2
sw2up   move    (r0)+
        move    r0,x:ENCOUNT2

;-------------------------------------------------------------------
; This following section successfully sets the limits of the nobs to be
; 0 <= knob <= 15
set_limits_2
	move	x:ENCOUNT2,r0
	brclr	#23,r0,pos_cot_2
	move	#0,r0
	move	r0,x:ENCOUNT2
	jmp	within_lim2
pos_cot_2
	brclr	#4,r0,within_lim2
	move	#>15,r0
	move	r0,x:ENCOUNT2
within_lim2
;-------------------------------------------------------------------

testsw3
        move    x1,a                    ; get changes back
        brclr   #12,a1,testsw4
        move    x:ENCOUNT3,r0
	  move	#$FFFF,m0
        move    x0,a1                   ; get switch states
        lsl     a                       ; shift A into B position
        eor     x0,a1                   ; checking direction
        brset   #13,a1,sw3up
        move    (r0)-
        move    r0,x:ENCOUNT3
        jmp     set_limits_3
sw3up   move    (r0)+
        move    r0,x:ENCOUNT3

;-------------------------------------------------------------------
; This following section successfully sets the limits of the nobs to be
; 0 <= knob <= 15
set_limits_3
	move	x:ENCOUNT3,r0
	brclr	#23,r0,pos_cot_3
	move	#0,r0
	move	r0,x:ENCOUNT3
	jmp	within_lim3
pos_cot_3
	brclr	#4,r0,within_lim3
	move	#>15,r0
	move	r0,x:ENCOUNT3
within_lim3
;-------------------------------------------------------------------


testsw4
        move    x1,a                    ; get changes back
        brclr   #14,a1,testend
        move    x:ENCOUNT4,r0
	  move	#$FFFF,m0
        move    x0,a1                   ; get switch states
        lsl     a                       ; shift A into B position
        eor     x0,a1                   ; checking direction
        brset   #15,a1,sw4up
        move    (r0)-
        move    r0,x:ENCOUNT4
        jmp     set_limits_4
sw4up   move    (r0)+
        move    r0,x:ENCOUNT4  

;-------------------------------------------------------------------
; This following section successfully sets the limits of the nobs to be
; 0 <= knob <= 15
set_limits_4
	move	x:ENCOUNT4,r0
	brclr	#23,r0,pos_cot_4
	move	#0,r0
	move	r0,x:ENCOUNT4
	jmp	within_lim4
pos_cot_4
	brclr	#4,r0,within_lim4
	move	#>15,r0
	move	r0,x:ENCOUNT4
within_lim4
;-------------------------------------------------------------------
     
testend
        move    x0,x:LASTTIME
	  move    x:-(r6),r0
	  move    x:-(r6),n0
	  move    x:-(r6),m0
        move    x:-(r6),a2
        move    x:-(r6),a1
        move    x:-(r6),a0
        move    x:-(r6),x1
        move    x:-(r6),x0
        rti




; EVM switches 2 and 3 interrupt support

EVM_SW2                                 ; switch 2 pressed interrupt support
        bset    #IRA,x:>IR_FLAGS
        rti

EVM_SW3
        bset    #IRD,x:>IR_FLAGS        ; switch 3 pressed interrupt support
        rti

        ENDSEC
