$NOMOD51
NAME LSQRT
/**********************************************************************************************
* uint32 lsqrt(uint32 value1)
* 32位整数开平方
用 途 :中颖SH79/88/89F51系列MCU
作 者 :许意义
21ic ID :LAOXU
中颖论坛 : bbs.21ic.com
日 期 : 2011-10-11
**********************************************************************************************/
?PR?_LSQRT?LSQRT SEGMENT CODE
?DT?_LSQRT?LSQRT SEGMENT DATA OVERLAYABLE
EXTRN CODE (_ISQRT)
EXTRN CODE (?C?ULCMP)
EXTRN CODE (?C?ULSHR)
PUBLIC _LSQRT
RSEG ?DT?_LSQRT?LSQRT
?_LSQRT?BYTE:
x?040: DS 4
ORG 4
xr?041: DS 4
ORG 8
q2?042: DS 4
;xr?043: DS 4 ---> DPL:DPH:DPL1:DPH1
DPL1 EQU 84H
DPH1 EQU 85H
RSEG ?PR?_LSQRT?LSQRT
_LSQRT: MOV A,R4
ORL A,R5
JNZ LSQRT_1 // 16位整数开平方
LJMP _ISQRT
LSQRT_1: MOV x?040+03H,R7 // 32位整数开平方
MOV x?040+02H,R6
MOV x?040+01H,R5
MOV x?040,R4
; { unsigned long xr, xr1;
; unsigned long q2;
; xr = 0;
CLR A
MOV xr?041+03H,A
MOV xr?041+02H,A
MOV xr?041+01H,A
MOV xr?041,A
; R4>40H, q2 = 0x40000000; R4>10H, q2 = 0x10000000; R4>04H, q2 = 0x4000000; R4>01H, q2 = 0x1000000;
; R5>40H, q2 = 0x400000; R5>10H, q2 = 0x100000; R5>04H, q2 = 0x40000; R5>01H, q2 = 0x10000;
MOV q2?042+03H,A
MOV q2?042+02H,A
MOV q2?042+01H,A
MOV q2?042,A
MOV R0,#x?040
MOV R1,#q2?042
MOV R2,#2
MOV A,#40H
LSQRT_10: CJNE @R0,#40H,$+3
JNC LSQRT_2
CJNE @R0,#10H,$+3
JNC LSQRT_3
CJNE @R0,#04H,$+3
JNC LSQRT_4
CJNE @R0,#01H,$+3
JNC LSQRT_5
INC R0
INC R1
DJNZ R2,LSQRT_10
DEC R1
LSQRT_5: RR A
RR A
LSQRT_4: RR A
RR A
LSQRT_3: RR A
RR A
LSQRT_2: MOV @R1,A
; do{ xr1 = xr + q2;
LSQRT_6: MOV A,xr?041+03H
ADD A,q2?042+03H
MOV DPH1,A
MOV A,xr?041+02H
ADDC A,q2?042+02H
MOV DPL1,A
MOV A,xr?041+01H
ADDC A,q2?042+01H
MOV DPH,A
MOV A,xr?041
ADDC A,q2?042
MOV DPL,A
; if(xr1 <= x)
MOV R7,x?040+03H
MOV R6,x?040+02H
MOV R5,x?040+01H
MOV R4,x?040
MOV R3,DPH1
MOV R2,DPL1
MOV R1,DPH
MOV R0,A
SETB C
LCALL ?C?ULCMP
JNC LSQRT_7
; { x -= xr1;
CLR C
MOV A,x?040+03H
SUBB A,DPH1
MOV x?040+03H,A
MOV A,x?040+02H
SUBB A,DPL1
MOV x?040+02H,A
MOV A,x?040+01H
SUBB A,DPH
MOV x?040+01H,A
MOV A,x?040
SUBB A,DPL
MOV x?040,A
; xr = (xr >> 1) + q2;
MOV R7,xr?041+03H
MOV R6,xr?041+02H
MOV R5,xr?041+01H
MOV R4,xr?041
MOV R0,#01H
LCALL ?C?ULSHR
MOV A,R7
ADD A,q2?042+03H
MOV xr?041+03H,A
MOV A,R6
ADDC A,q2?042+02H
MOV xr?041+02H,A
MOV A,R5
ADDC A,q2?042+01H
MOV xr?041+01H,A
MOV A,R4
ADDC A,q2?042
MOV xr?041,A
; }
SJMP LSQRT_8
; else { xr >>= 1;
LSQRT_7: MOV R7,xr?041+03H
MOV R6,xr?041+02H
MOV R5,xr?041+01H
MOV R4,xr?041
MOV R0,#01H
LCALL ?C?ULSHR
MOV xr?041+03H,R7
MOV xr?041+02H,R6
MOV xr?041+01H,R5
MOV xr?041,R4
; }
; }while(q2 >>= 2);
LSQRT_8: MOV R7,q2?042+03H
MOV R6,q2?042+02H
MOV R5,q2?042+01H
MOV R4,q2?042
MOV R1,#02H
MOV R0,#02H
LCALL ?C?ULSHR
MOV q2?042+03H,R7
MOV q2?042+02H,R6
MOV q2?042+01H,R5
MOV q2?042,R4
MOV A,R4
ORL A,R5
ORL A,R6
ORL A,R7
JZ $ + 5H
LJMP LSQRT_6
; if(xr < x)
MOV R7,x?040+03H
MOV R6,x?040+02H
MOV R5,x?040+01H
MOV R4,x?040
MOV R3,xr?041+03H
MOV R2,xr?041+02H
MOV R1,xr?041+01H
MOV R0,xr?041
CLR C
LCALL ?C?ULCMP
JNC LSQRT_9
; { return(xr + 1);
MOV A,xr?041+03H
ADD A,#01H
MOV R7,A
CLR A
ADDC A,xr?041+02H
MOV R6,A
CLR A
ADDC A,xr?041+01H
MOV R5,A
CLR A
ADDC A,xr?041
MOV R4,A
RET
; }
; else { return(xr);
LSQRT_9: MOV R7,xr?041+03H
MOV R6,xr?041+02H
MOV R5,xr?041+01H
MOV R4,xr?041
; }
; }
RET
; END OF _LSQRT
END