SX Microcontroller DSP Math Method

8bit 16 step Averageing filter by Andrew Warren

    ; Written by Andrew Warren [fastfwd at ix.netcom.com].
    ;
    ;       (NEW - AVE) + 16*AVE
    ; AVE = --------------------
    ;               16

NEW	equ	[ANY FILE REGISTER]	;HOLDS NEW SAMPLE [0-255].
AVE	equ	[ANY FILE REGISTER[	;HOLDS THE AVERAGE [0-255].
AVFRAC	equ	[ANY FILE REGISTER]	;HOLDS THE FRACTIONAL PART
                                          ;OF THE AVERAGE [0-15].
TEMP	equ	[ANY FILE REGISTER]	;TEMPORARY STORAGE.

    FILTER:

	mov	W, #00001111B	;MASK OFF ALL BUT THE FRACTIONAL
	and	AVFRAC, W	;PART OF THE OLD AVERAGE
                                    ;(AVFRAC'S HI-NIBBLE CAN
                                    ;CONTAIN GARBAGE).

	mov	W, AVE	;NEW = NEW - AVE.
	sub	NEW, W	;CARRY = 0 IF THE DIFFERENCE IS
                                    ;NEGATIVE, CARRY = 1 IF POSITIVE.

	mov	W, <>AVE;HI-NIBBLE OF W = MIDDLE NIBBLE
                                    ;OF 16*AVE.

	mov	TEMP, W	;LO-NIBBLE OF TEMP = HI-NIBBLE
                                    ;OF 16*AVE (LO-NIBBLE OF 16*AVE
                                    ;IS ALWAYS 0000).

    ; NEW CONTAINS (NEW - AVE) AND [TEMP:W] HOLDS 16*AVE.
    ; ADD THEM TOGETHER.

	sb	C	;IF (NEW - AVE) WAS NEGATIVE,
	dec	TEMP	;ADJUST THE HI-NIBBLE OF 16*AVE.

	and	W, #11110000B	;W = LO-BYTE OF 16*AVE.
	or	W, AVFRAC	;(INCLUDE AVE'S FRACTIONAL
                                    ;PART).

	add	W, NEW	;W = LO-BYTE OF
                                    ;((NEW-AVE) + 16*AVE).
                                    ;CARRY = 1 IF SUM > 255,
                                    ;CARRY = 0 OTHERWISE.

	mov	AVFRAC, W	;LO-NIBBLE OF AVFRAC =
                                    ;FRACTIONAL PART OF FINAL
                                    ;RESULT.  HI-NIBBLE = GARBAGE.

	and	W, #11110000B	;W = (LO-NIBBLE OF
                                    ;((15*AVE+NEW)/16)) * 16.

	mov	AVE, W	;AVE = (LO-NIBBLE OF
                                    ;((15*AVE+NEW)/16)) * 16.

	swap	AVE	;AVE = LO-NIBBLE OF
                                    ;((15*AVE+NEW)/16).

    ; AVE'S LO-NIBBLE CONTAINS THE LO-NIBBLE OF THE FINAL RESULT.
    ; AVE'S HI-NIBBLE = 0000.

	snb	C	;LO-NIBBLE OF TEMP =
	inc	TEMP	;HI-NIBBLE OF ((15*AVE+NEW)/16).

	mov	W, <>TEMP	;HI-NIBBLE OF W = HI-NIBBLE OF
	and	W, #11110000B	;((15*AVE+NEW)/16).
                                    ;LO-NIBBLE OF W = 0000.

    ; W'S HI-NIBBLE CONTAINS THE HI-NIBBLE OF THE FINAL RESULT.
    ; LO-NIBBLE = 0000.

	or	AVE, W	;COMBINE THE HI- AND LO-NIBBLES
                                    ;AND STORE THE FINAL RESULT IN
                                    ;AVE.

    ; AVE CONTAINS THE NEW AVERAGE.

    See?  That wasn't too hard; just 20 words of program space and
    20 instruction cycles...  And not a single floating-point
    operation anywhere in there.