.include	"m128Adef.inc"
.DEVICE		ATmega128A
;частота кварца 16.000 MHz
.equ    	CPU_CLOCK	= 16000000

;Регистры общего назначения
.def		sqr0		= r8
.def		sqr1		= r9
.def		sqr2		= r10
.def		sqr3		= r11

.def		mask0		= r12
.def		mask1		= r13
.def		mask2		= r14
.def		mask3		= r15

.def		temp0 		= r16
.def		temp1 		= r17
.def		temp2 		= r18
.def		temp3 		= r19

.def		src0		= r26
.def		src1		= r27
.def		src2		= r28
.def		src3		= r29

	    .DSEG
        .org	0x100

InputNum:		.byte	0x04		; Входное число     (L...H)
OutputSqr:		.byte	0x02		; Рассчитанное значение квадратного корня из числа в "InputNum" (L...H)

		.CSEG
		.org	0
		cli
		ldi		temp0,	0x80
		out		MCUCSR,	temp0
		;запуск WDT с периодом 1 секунды 
        ldi     temp0,	0x0F
        out     WDTCR,	temp0
		wdr
   		;инициализация стека на конец SRAM
		ldi		temp0,	high(RAMEND)
		out		SPH,	temp0
		ldi		temp0,	low(RAMEND) 
		out		SPL,	temp0		
		clr		temp0


mnlooptest:		rcall	SquareRoot32to16x16
				rjmp	mnlooptest


;****************************************************************
;  //объявление функции с одним параметром - без знаковое целое 4  байта
;  unsigned short isqrt( unsigned long ul) { 
;  // объявление переменной - без знаковое целое 4  байта;  
;  unsigned long sqr = 0;   
;  // объявление переменной - без знаковое целое 4  байта
;  unsigned long temp;     
;  // объявление переменной   - без знаковое целое 4  байта. 
;  //В переменную записывается значение 0x40000000
;  unsigned long mask = 0x40000000; 
;  do{         //  цикл с пост условием (проверка произойдет после выполнения тела цикла)
;    temp = sqr | mask;  // побитное "или"  между  sqr и mask, результат записывается в temp
;    sqr >>= 1;          // сдвиг переменной sqr на 1 бит вправо
;    if( temp <= ul ){   // условный оператор если temp меньше равно  ul
;      sqr |= mask;      //  побитное "или"  между  sqr и mask, результат записывается в sqr
;      ul -= temp;       //  вычисляется разница между  ul и temp результат записывается в ul
;    }
;  }while( mask >>= 2 ); // Сдвинуть mask  на два бита в право, результат записать в mask,  выполнять цикл пока mask > 0.
;  if( sqr < ul && sqr < 0xFFFF ) ++sqr; // округление результата  (если sqr меньше ul "и" sqr меньше 0xFFFF в sqr записывается sqr+1)
;  return (unsigned short)sqr;           // возвращение результата работы функции, тип переменной приводится к без знаковое целое 1  байт

SquareRoot32to16x16:
		lds		src0,	InputNum	
		lds		src1,	InputNum+1	
		lds		src2,	InputNum+2	
		lds		src3,	InputNum+3	
		;
		clr		mask0				;  unsigned long mask = 0x40000000; 
		clr		mask1
		clr		mask2
		ldi		temp0,	0x40
		mov		mask3,	temp0
		;
		clr		sqr0				;  unsigned long sqr = 0;   
		clr		sqr1
		clr		sqr2
		clr		sqr3
		
_sr32loop:
			movw	temp0,	sqr0		;temp = sqr | mask; 
			movw	temp2,	sqr2
			or   temp0, mask0
			or   temp1, mask1
			or   temp2, mask2
			or   temp3, mask3
			lsr		sqr3	;sqr >>= 1; 
			ror		sqr2
			ror		sqr1
			ror		sqr0
			;
			cp		src0,	temp0		;if( temp <= ul )
			cpc		src1,	temp1
			cpc		src2,	temp2
			cpc		src3,	temp3
			; Если С=0, то условие выполнено
			brcs	_sr32_skipif		; пропустить, если С=1
				;							{
				or		sqr0,	mask0	; sqr |= mask
				or		sqr1,	mask1
				or		sqr2,	mask2
				or		sqr3,	mask3
				;
				sub		src0,	temp0 	; ul -= temp; 
				sbc		src1,	temp1
				sbc		src2,	temp2
				sbc		src3,	temp3
				;							}
_sr32_skipif:
			lsr		mask3		;( mask >>= 2 )
			ror		mask2
			ror		mask1
			ror		mask0
			;
			lsr		mask3
			ror		mask2
			ror		mask1
			ror		mask0
			;
			mov		temp0,	mask0   ; mask=0?
			or		temp0,	mask1
			or		temp0,	mask2
			or		temp0,	mask3
			;
			brne	_sr32loop		;while( mask=0 )
		;
		sts		OutputSqr,	sqr0
		sts		(OutputSqr+1), sqr1
		ret


  

