;Quadratwurzel für ATmega
;h#s 01/06
#ifndef SQRT4_I90
#define SQRT4_I90
;Quelle: 32-bit-Zahl (optional 24bit)
;Ziel: 16-bit-Zahl
;Natürlich nur vorzeichenlos!
; r17:r16=sqrt4(r5:r4:r3:r2)
;ifdef SQRT3 (alternativ, bisschen schneller)
; r17:r16=sqrt3(r4:r3:r2)
;Der Wurzelrest ist in R1:R0
;Es wird stets abgerundet! Ist der Wurzelrest größer als die
;Wurzel, sollte aufgerundet werden.
.include "makros.i90"
#ifdef SQRT3
sqrt3:
;PE: R4:R3:R2 = Ausgangswert (24bit)
;PA: R17:R16 = Wurzel (12bit)
; R1:R0 = Wurzelrest (13bit)
;VR: R0-R4, R16-R17
;Ta: 280 (17,5 µs @ 16 MHz)
# define SQRTLOOP 12
#else
sqrt4:
;Der Wertebereich des Radikanden (32bit) darf nicht ausgereizt werden:
;PE: R5:R4:R3:R2 = Ausgangswert (30bit)
;PA: R17:R16 = Wurzel (15bit)
; R1:R0 = Wurzelrest (16bit)
;VR: R0-R5, R16-R17
# define SQRTLOOP 16
#endif
;Doppelwurzel=0
clr r16
clr r17
;Akku löschen
clr r0
clr r1
push r18
ldi r18,SQRTLOOP ;Für jedes Ergebnis-Bit eine Runde
sqrt_zieh:
;Doppelwurzel "verdoppeln"
sec
rolw r17,r16 ;[xxxxx1 -> xxxxx01]
cbr r16,2
;Zwei Bits aus Radikand in Akku schieben
lslw r3,r2
rol r4
#ifndef SQRT3
rol r5
#endif
rolw r1,r0
lslw r3,r2
rol r4
#ifndef SQRT3
rol r5
#endif
rolw r1,r0
#ifndef SQRT3
brcs sqrt_sub
#endif
;Akku mit Doppelwurzel vergleichen
cp r0,r16
cpc r1,r17
brcs sqrt_okay
;Doppelwurzel vom Akku abziehen
sqrt_sub:
sub r0,r16
sbc r1,r17
;Doppelwurzel+=2
sbr r16,2 ;[xxxxx01 -> xxxxx11]
sqrt_okay:
;nächste Runde
djnz r18,sqrt_zieh
;Doppelwurzel halbieren
lsrw r17,r16
;fertig
pop r18
ret
#undef SQRTLOOP
#endif//SQRT4_I90
Detected encoding: ANSI (CP1252) | 4
|
|