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

;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
Wrong umlauts? - Assume file is ANSI (CP1252) encoded