;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
|
|