Source file: /~heha/Mikrocontroller/avr-inc.zip/muladd2.i90

;Multiplikation + Addition für ATmega
;bspw. für digitale Regler, Signalverarbeitung usw.
;h#s 01/06
#ifndef MULADD2_I90
#define MULADD2_I90

;Quelle: 2 16-bit-Zahlen
;Ziel: 40-bit-Akkumulator
;Vorzeichenbehaftete und vorzeichenlose Version

;	clr5				;Akku nullsetzen
;	clr4				;32 bit des Akkus null setzen
;	clrr5r4r3			;R5,R4,R3 null setzen
;	clrr5r4				;R5,R4 null setzen
;	Muladdu2u2(r17:r16,r19:r18)	;2 vorzeichenlose Argumente
;	Muladds2s2(r17:r16,r19:r18)	;2 vorzeichenbehaftete Argumente
;Der Akkumulator ist R6:R5:R4:R3:R2 (5 Bytes)
;und durch seine Größe einigermaßen überlaufsicher.
;Mit dem Symbol NOS2S2 wird die vzb. Variante ausgeklammert.

.include "makros.i90"

clr5:
;Nullsetzen des 40-bit-Akkus, zur Vorbereitung von MulAdd
	clr	r6
clr4:
	clr	r2
clrr5r4r3:
	clr	r3
clrr5r4:
	clr	r4
	clr	r5
	ret

Muladdu2u2:
;Multiplizieren, addieren, Begrenzen bei 40 bit unwahrscheinlich
;PE: r17:r16 = vzl. Faktor 1
;    r18:r19 = vzl. Faktor 2
;    r6:r5:r4:r3:r2 = Summand
;    ZERO = 0
;PA: r6:r5:r4:r3:r2 = Produkt + Summand
;VR: r0-r7
	mul	r16,r18		;Low-Teile
	add	r2,r0
	adc	r3,r1
	in	r7,SREG		;CY retten
	mul	r17,r19		;High-Teile
	out	SREG,r7		;CY wiederherstellen
	adc	r4,r0
	adc	r5,r1
	adc	r6,ZERO
	mul	r17,r18		;High*Low
	add	r3,r0
	adc	r4,r1
	adc	r5,ZERO
	adc	r6,ZERO
	mul	r16,r19		;Low*High
	add	r3,r0
	adc	r4,r1
	adc	r5,ZERO
	adc	r6,ZERO
	ret

#ifndef NOS2S2
	
MulAdds2s2:
;Multiplizieren, addieren, Begrenzen bei 40 bit unwahrscheinlich
;PE: r17:r16 = vzb. Faktor 1 (wird zerstört)
;    r18:r19 = vzb. Faktor 2 (bleibt erhalten)
;    r6:r5:r4:r3:r2 = Summand
;    YH = 0!
;PA: r6:r5:r4:r3:r2 = Produkt + Summand
;VR: r0-r7, r16-r17
	subi	r17,0x80
	subi	r19,0x80
;vzl. multiplizieren (a+8000h)(b+8000h)
	rcall	MulAddu2u2
;Ergebnis korrigieren
	clr	r0
	subi	r19,0x80	;"b" zurückwandeln
	add	r16,r18
	adc	r17,r19		;"a+8000h+b"
	sbrc	r19,7
	 clc
	ror	r17
	ror	r16
	ror	r0		;()*8000h
	sub	r3,r0
	sbc	r4,r16
	sbc	r5,r17		;subtrahieren
	sbc	r6,ZERO
	ret
;Der Berechnungstrick, ohne Konvertierung zu vzl. Zahlen:
;(a+8000h)(b+8000h) = a*b + a*8000h + b*8000h + 40000000h
;		    = a*b +(a+8000h + b)*8000h
;also:
;a*b = (a+8000h)(b+8000h) - (a+8000h+b)*8000h

#endif//NOS2S2
#endif//MULADD2_I90
Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded