Home     Contact     Projects     Experiments     Circuits     Theory     BLOG     PIC Tutorials     Time for Science     RSS     Terms of services     Privacy policy  
   
 Home      Projects     Experiments     Circuits     Theory     BLOG     PIC Tutorials     Time for Science   



All about PIC microcontrollers

Within these pages, you can find many useful pieces of code mostly in assembly for the Microchip PIC micro controller family. A lot of people have spend many hours trying to put the bits and bytes together. If the code is NOT written by a member of the PCB Heaven community, then a link will be added above the code with the original website that this code was found.
Because the code is copied to our servers, you should know that:

  • The responsible web master of the website that the code is taken, has been informed and he has agreed to copy the code
  • All emails from the above contact have been kept as records but due to personal privacy cannot be shown in public.
  • The author of the code is always clearly indicated above the code. In some cases the author is unknown. If you happen to be the author of the code or you know the person who wrote it, please inform us by email and it will be added ASAP.

We would personally like to send the credits to all the people that managed to write some very interesting code and publish it, and special thanx to the people that originally hosted those code snippets and gave us the permission to copy them.


View code
24 bit floating point
Author: Nikolai Golovchenko
This code was originally located @ http://www.piclist.com


Follow this link to go back

;**********************************************************************
;By Nikolai Golovchenko
;24 BIT FLOATING POINT SQARE ROOT
;
;Input:
; AARGB0 - high byte with sign bit
; AARGB1 - low byte
; AEXP - exponent 2^(AEXP - 127)
;Output:
; AARGB0-1, AEXP - 24 bit floating point
;Temporary:
; BARGB0-1, BEXP - temporary for result
; TEMPB0-1
; LOOPCOUNT - counter
;
;ROM: 85 instructions
;RAM: 9 bytes
;
;Timing (includes call and return)
;6 cycles best case
;2+3+18+8*26-1+8*21-1+7+2= 406 cycles worst case
;**********************************************************************
;NOTES: 1)Square root is taken on absolute value of the number
; (sign bit is ignored)
; 2)Rounding not implemented yet
;**********************************************************************
FPSQRT24
;Normalize input
;1)Check for zero input - if zero then exit
;2)Change sign to 1 and use sign bit as explicit MSB
;3)Divide BEXP = BEXP / 2
;4)If AEXP can be divided by 2 (AEXP<0>=1) then
;BARGB1 = 1, AARGB<0-1> << 1 and find 15 more bits
;5)Else find 16 more bits

movf AEXP, w ;if zero input then return
btfsc 0x03, 2
retlw 0x00

clrf BARGB0 ;set up all used
clrf BARGB1 ;temporary registers
clrf TEMPB0 ;
clrf TEMPB1 ;

bsf AARGB0, 7 ;make MSB explicit and ignore mantissa sign

;sqrt(2^E*M)=2^(E/2)*sqrt(M)
;we will align mantissa point above MSb. This is
;equivalent to division by 2. Or,
;sqrt(2^E*M)=sqrt(M/2)*2^((E+1)/2)
;new exponent is (E+1)/2
;new mantissa is M/2 (not changed, just new point position)

;divide (bexp+1) by 2. bexp is (eb + 127), where eb=-126..128!
;eb/2 is rounded to minus infinity!
movwf BEXP ;copy aexp to bexp
decf BEXP, f ;ensure required round mode
bcf 0x03, 0 ;divide by 2
rrf BEXP, f ;
movlw 0x40 ;correct bias after division
addwf BEXP, f ;

;if (E+1)/2 result has a remainder, then multiply mantissa by 2
;(left shift)
btfss AEXP, 0
goto FPSQRT24a
rlf AARGB1, f ;(carry was zero)
rlf AARGB0, f
bsf BARGB1, 0 ;set first bit of current result
;and discard MSb of mantissa (we
;used it already by setting first bit)
FPSQRT24a

;First find 8 bits of result. This will shift AARGB0 - AARGB1 to TEMPB1
;Then only zeros will be fed instead of AARGB0
movlw 0x08 ;loop counter
movwf LOOPCOUNT ;
FPSQRT24b
movlw 0x40 ;substract test bit from
subwf AARGB0, f ;current lowest byte.
;it works also exactly
;like 0xC0 addition for the
;addition branch.
movf BARGB1, w ;load accumulator with
;current result LSB

btfsc TEMPB0, 7
goto FPSQRT24b_add

btfss 0x03, 0
incfsz BARGB1, w
subwf TEMPB1, f
movlw 0x01
btfss 0x03, 0
subwf TEMPB0, f
goto FPSQRT24b_next

FPSQRT24b_add
btfsc 0x03, 0
incfsz BARGB1, w
addwf TEMPB1, f
movlw 0x01
btfsc 0x03, 0
addwf TEMPB0, f

FPSQRT24b_next
rlf BARGB1, f ;shift result into result bytes
rlf BARGB0, f

rlf AARGB1, f ;Shift out next two bits of input
rlf AARGB0, f ;
rlf TEMPB1, f ;
rlf TEMPB0, f ;
rlf AARGB1, f ;
rlf AARGB0, f ;
rlf TEMPB1, f ;
rlf TEMPB0, f ;

decfsz LOOPCOUNT, f ;repeat untill 8 bits will be found
goto FPSQRT24b

;Find other 7 or 8 bits. Only zeros are fed instead of AARGB0
;Repeat untill MSb of result gets set
FPSQRT24d
btfsc BARGB1, 0 ;if Temp sign is positive, than jump to subtraction
goto FPSQRT24d_sub ;(previous result bit is inverted sign bit,
;Tempb0.7 can not be used instead, because
;it may overflow)

;after LSBs addition (0x00 + 0xC0 = 0xC0) C=0,
;so we just continue adding higher bytes,
;keeping in mind that LSB=0xC0 and C=0
movf BARGB1, w
addwf TEMPB1, f
movf BARGB0, w
btfsc 0x03, 0
incfsz BARGB0, w
addwf TEMPB0, f
goto FPSQRT24d_next

FPSQRT24d_sub

bcf 0x03, 0 ;simulate borrow (0x00 - 0x40 = 0xC0, C=0)
incfsz BARGB1, w
subwf TEMPB1, f
movf BARGB0, w
btfss 0x03, 0
incfsz BARGB0, w
subwf TEMPB0, f

FPSQRT24d_next
rlf BARGB1, f ;shift result into result bytes
rlf BARGB0, f

bsf 0x03, 0 ;Shift out next two bits of input
rlf TEMPB1, f ;(set carry before each shift to
rlf TEMPB0, f ;simulate 0xC0 value)
bsf 0x03, 0 ;
rlf TEMPB1, f ;
rlf TEMPB0, f ;

btfss BARGB0, 7 ;repeat untill all 16 bits will be found
goto FPSQRT24d

;flag C, TEMPB1 - TEMPB0 contain current input that may be used to find 17th bit for rounding

;Copy BARG to AARG
movf BEXP, w
movwf AEXP
movf BARGB0, w
movwf AARGB0
movf BARGB1, w
movwf AARGB1
bcf AARGB0, 7 ;clear sign bit (overwrites explicit MSB, which is always one)

retlw 0x00

Follow this link to go back






delicious
digg
reddit this Reddit this
Faves



 HOT in heaven!