/*
 * fir.dsp -- ADSP-2191 FIR filter adapted for open21xx assembler.
 * Based on Analog Devices application note.
 */
	.section/PM program0;
	.global _start;
_start:
	/* Setup DAGs */
	i0 = 0x0100;	/* delay line */
	i1 = 0x0200;	/* input samples */
	i2 = 0x0300;	/* output */
	i4 = 0x0400;	/* coefficients (PM) */
	l0 = 31;	/* circular buffer length */
	l4 = 31;
	m0 = 1;
	m1 = 1;
	m3 = -1;
	m4 = 1;

	/* FIR kernel */
	mr = 0, mx0 = dm(i1,m1), my0 = pm(i4,m4);
	dm(i0,m3) = mx0;
	cntr = 40;
	do _mult_acc until ce;

	/* Inner loop: 30 taps (unrolled) */
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);
	mr=mr+mx0*my0(ss), mx0=dm(i0,m3), my0=pm(i4,m4);

	/* Last tap + output chain */
	mr=mr+mx0*my0(ss), mx0=dm(i0,m1), my0=pm(i4,m4);
	sr=ashift mr2 (hi), mx0=dm(i1,m1);
	sr=sr or lshift mr1 (lo), dm(i0,m3) = mx0;
_mult_acc:
	mr = 0, dm(i2,m1) = sr0;
	rts (db);
	mx0 = dm(i0,m1);
	mx0 = dm(i1,m3);

_halt:
	jump _halt;
