{___________________________________________________________________________ direc.ASM ADSP-21020 Directional Audio Simulator Operation: * Records speeech from left and right channel while flag0 is pressed * Plays back when flag0 is released * Press Reset to clear the buffer * Each Press of IRQ2 will switch between three states: (0) Normal Play and Record (1) Time Reverse the sample (2) Frequency Reverse the sample (mirror) To assemble this demo from scratch use the following commands: asm21k loop ld21k -a ezlab21k loop spl21k -a ezlab21k -ram -dm -pm -f B loop Author: 14-Feb-91, SLC Analog Devices Inc. DSP Division ____________________________________________________________________________} { ADSP-21020 System Register bit definitions } #include "def21020.h" {___________________________________________________________________________} .SEGMENT/DM dm_sram; .VAR buffer[10]; {do not declare all 32k so it will load faster } .ENDSEG; .SEGMENT/DM hip_regs; .PORT in_audio_l; { ADSP-2111 HDR0 = mic input } .PORT in_audio_r; { ADSP-2111 HDR1 } .PORT out_audio_l; { ADSP-2111 HDR2 = speaker output } .PORT out_audio_r; { ADSP-2111 HDR3 } .PORT control_0; { ADSP-2111 HDR4 } .PORT control_1; { ADSP-2111 HDR5 } .ENDSEG; .SEGMENT/DM dac_a; .PORT dac_a; .ENDSEG; .SEGMENT/DM dac_b; .PORT dac_b; .ENDSEG; .SEGMENT/DM adc_b; .PORT adc_b; .ENDSEG; {___________________________________________________________________________} .SEGMENT/PM rst_svc; { Reset Vector } call init_21k; jump main; .ENDSEG; {___________________________________________________________________________} .SEGMENT/PM irq2_svc; { Push Button Interrupt } jump irq2_asserted; .ENDSEG; {___________________________________________________________________________} .SEGMENT/PM irq3_svc; { Audio I/O Interrupt } jump irq3_asserted (db); bit set mode1 SRD1L|SRD1H|SRRFL|SRRFH; { use all secondary registers} nop; .ENDSEG; {___________________________________________________________________________} .SEGMENT/PM tmzh_svc; { Timer Interrupt } jump timer_hi_prior; .ENDSEG; {___________________________________________________________________________} .SEGMENT/PM pm_sram; main: r0=0x00000100; { data to circulate through LEDs} ustat2 = 0; { starting state = 0 } bit set imask IRQ3I; bit set mode1 IRPTEN; { enable global int.} bit set mode2 TIMEN; { timer on! } bit set mode1 SRD1L|SRD1H|SRRFL|SRRFH; nop; b0=buffer; { b0 is start of buffer } l0=1; { length starts at one } bit clr mode1 SRD1L|SRD1H|SRRFL|SRRFH; nop; wait: r0 = dm(adc_b); { get value from knob } dm(adc_b) = r0; { start next conversion } r1 = lshift r0 by -27; { scale down r0 to 0-32 } r8 = pass r1; { zero the floating point } r0 = 16; comp(r8,r0); if EQ jump center; if GT jump greater; if LT jump less; nop; nop; center: bit set astat FLG2|FLG3; { if at center light 2 and 3 } m0 = 0; { no delay } jump wait; nop; nop; greater: bit set astat FLG2; bit clr astat FLG3; r6=1; { delay is on left channel } r0 = 16; r7 = r8 - r0; { scale down to 0-16 } m0 = 3; jump wait; nop; nop; less: bit set astat FLG3; bit clr astat FLG2; r6 = 0; { delay is on right } r0 = 16; r7 = r0 - r8; m0 = 12; jump wait; nop; nop; {___________________________initialize the chip___________________________} init_21k: pmwait =0x00001c21; { pmwtstates=0,sw.wtstates only} dmwait =0x0070a421; { bank2_dmwtstates=1,sw.wtstates only} tperiod =0x004c4640; { timer interrupt at 5 Hz } tcount = tperiod; irptl =0; bit set mode2 0x10; nop; read cache 0; bit clr mode2 0x10;{clr cache} {irq2&3 enable, timer enable high priority} bit set imask TMZHI|IRQ2I; {irq2&3 edge sens, flag 1&2&3 outputs} bit set mode2 IRQ2E|IRQ3E|FLG1O|FLG2O|FLG3O; bit clr astat FLG1|FLG2|FLG3; { clear flag LEDs } rts; {__________________________Timer Interrupt__________________________________} timer_hi_prior: pop sts; { get ASTAT from stack, pushed there by IRQ } bit tgl astat FLG1; push sts; { restore stack so effect happens after rti } r3=dm(adc_b); { Read last ADC-B input } dm(adc_b)=r3; { write to ADC-B to start conversion } dm(dac_b)=r3; { output DAC-B value } rti; {__________________________IRQ2 Interrupt Vector____________________________} { Switch between 3 states and display the state on Flag 2 and 3 } irq2_asserted: { Change State } r0=ustat2; { get current state } r0=r0+1; { Increment state } r1=3; comp(r0,r1); if eq r0=r0 xor r0; { clear if going back to state 0 } ustat2=r0; { Reverse state for display on LEDs} r1=lshift r0 by -1; r0=bclr r0 by 1; r1=r1 or lshift r0 by 1; pop sts; { get ASTAT from stack, pushed there by IRQ } bit clr astat FLG2|FLG3; r0=astat; r0=r0 or lshift r1 by 21; astat=r0; push sts; { restore stack so effect happens after rti } rti; {__________________________IRQ3 Interrupt Vector____________________________} irq3_asserted: r4=dm(in_audio_l); { get AD1849 left channel } if not flag0_in jump playback; nop; nop; record: dm(i0,1)=r4; { store one sample } r4=l0; r4=r4+1; { increment length } r5=32767; { max buffer size } r4=clip r4 by r5; l0=r4; { new length for circular buffer} rti; playback: nop; i1 = i0; nop; nop; r4=dm(m0,i1); { get undelayed sample } r3=dm(i0,0); { get delayed sample } r8=dm(i0,1); { increment } dm(out_audio_l)=r4; { output AD1849 value } dm(out_audio_r)=r3; pop sts; { for rev 0 silicon anomaly } push sts; rti; .ENDSEG;