Sie sind auf Seite 1von 53

; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ** rdless ; ** ;

RCS Header $Id: FPRF24.TXT Last Revised, 26/08/2008 Floating point routine library file needed by RFLvlMeter.asm program, made by extracting from various Microchip Technology floating point library and function files, including FP24.A16 (Rev 2.7 1996/10/07 13:50:29 by F.J.Testa) FP32.A16 (Rev 2.8 1996/10/07 13:50:59 by F.J.Testa) MATH16.MAC (Rev 1.3 1996/10/05 19:52:32 by F.J.Testa) EXP1024.A16 (Rev 1.3 1997/02/25 14:27:16 by F.J.Testa) RND3224.A16 (Rev 1.1 1996/08/22 00:51:17 by F.J.Testa) FLOOR24.A16 (Rev 1.3 1996/10/09 13:23:39 by F.J.Testa) MATH16.INC (Rev 2.4 1997/02/11 16:58:49 by F.J.Testa) FXM46.a16 (Rev 2.3 1996/10/16 14:23:23 by F.J.Testa) FXD26.a16 (Rev 2.3 1996/10/16 14:23:57 by F.J.Testa) FLOAT_ASCII (by Rick Evans, in AN670) ************************************************************************ org h'400' ; make the include routines start at 0400h, rega

; of the length of the main program... ************************************************************************ THIS FIRST SECTION COMES FROM FP24.A16...

; Unary operations: both input and output are in AEXP,AARG ; ; Binary operations: input in AEXP,AARG and BEXP,BARG with output in AEXP, AARG ; ; All routines return WREG = 0x00 for successful completion, and WREG = 0x FF ; for an error condition specified in FPFLAGS. ; ; ************************************************************************ ************* ; ************************************************************************ ************* ; ; 24 bit floating point representation ; ; EXPONENT 8 bit biased exponent ; It is important to note that the use of biased exponents produces ; a unique representation of a floating point 0, given by ; EXP = HIGHBYTE = LOWBYTE = 0x00, with 0 being the only ; number with EXP = 0. ; ; HIGHBYTE 8 bit most significant byte of fraction in sign-magnitud e representation, ; with SIGN = MSB, implicit MSB = 1 and radix point to the right of MSB ; ; LOWBYTE 8 bit least significant byte of sign-magnitude fraction ; ; EXPONENT HIGHBYTE LOWBYTE ; ; xxxxxxxx S.xxxxxxx xxxxxxxx ;

; ; ; ;

RADIX POINT

; ************************************************************************ ***************** ; ************************************************************************ ***************** ; ; ; ; ; ; ; ; ; ; Integer to float conversion Input: 16 bit 2's complement integer right justified in AARGB0, AARGB1 Use: CALL FLO1624 or CALL FLO24

Output: 24 bit floating point number in AEXP, AARGB0, AARGB1 Result: AARG <-- FLOAT( AARG ) Max Timing: Min Timing: PM: 11+26 = 37 11+72 = 83 clks 11+77 = 88 clks 7+14 = 21 clks 7+18 = 25 clks SAT = 0 SAT = 1 AARG = 0 DM: 6

;--------------------------------------------------------------------------------------------FLO1624 FLO24 d add bias MOVLW MOVWF MOVF MOVWF BTFSS GOTO COMF MSB in SIGN COMF INCF BTFSC INCF AARGB0,F AARGB1,F _Z AARGB0,F D'15'+EXPBIAS EXP AARGB0,W SIGN AARGB0,MSB NRM2424 AARGB1,F ; initialize exponent an

; test sign ; if < 0, negate and set

;******************************************************************************* *************** ; ; 1, ; ; ; Normalization routine Input: 24 bit unnormalized floating point number in AEXP, AARGB0, AARGB with sign in SIGN,MSB and other bits zero. Use: CALL NRM2424 or CALL NRM24

Output: 24 bit normalized floating point number in AEXP, AARGB0, AARGB1

; ; ; ; ; ;

Result: AARG <-- NORMALIZE( AARG ) Max Timing: Min Timing: PM: 26 10+6+7*7+7 = 72 clks SAT = 0 10+6+7*7+1+11 = 77 clks SAT = 1 14 clks 5+9+4 = 18 clks AARG = 0 DM: 6

;--------------------------------------------------------------------------------------------NRM2424 NRM24 CLRF nt MOVF BTFSS GOTO MOVF move MOVWF BTFSC 0 GOTO CLRF BSF NORM2424 MOVF SUBWF BTFSS BTFSS GOTO BCF NORM2424A n done and RLF DECFSZ GOTO GOTO FIXSIGN24 positive RETLW RES024 CLRF CLRF CLRF CLRF RETLW 0 AARGB0 AARGB1 AARGB2 EXP 0 ; result equals zero ; clear extended byte BTFSS BCF AARGB0,F EXP,F NORM2424A SETFUN24 SIGN,MSB AARGB0,MSB ; decrement EXP BTFSC GOTO RLF RES024 AARGB1 TEMP,3 TEMP,W EXP,F _Z _C SETFUN24 _C AARGB0,MSB FIXSIGN24 AARGB1,F ; clear carry bit ; if MSB=1, normalizatio ; otherwise, shift left AARGB0 _Z ; if highbyte=0, result= AARGB0,W _Z NORM2424 AARGB1,W ; test if highbyte=0 ; if so, shift 8 bits by TEMP ; clear exponent decreme

; underflow if EXP=0 ; clear explicit MSB if

;******************************************************************************* *************** ;******************************************************************************* *************** ; ; AARGB2 ; ; ; ; ; ; ; ; ; Use: CALL FLO2424 Integer to float conversion Input: 24 bit 2's complement integer right justified in AARGB0, AARGB1,

Output: 24 bit floating point number in AEXP, AARGB0, AARGB1 Result: AARG <-- FLOAT( AARG ) Max Timing: 14+94 = 108 clks 14+103 = 117 clks 14+109 = 123 clks 6+28 = 34 clks 6+22 = 28 clks RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG = 0 DM: 7

Min Timing: PM: 14+51 = 65

;--------------------------------------------------------------------------------------------FLO2424 d add bias MOVLW MOVWF CLRF BTFSS GOTO COMF MSB in SIGN COMF COMF INCF BTFSC INCF BTFSC INCF BSF AARGB1,F AARGB0,F AARGB2,F _Z AARGB1,F _Z AARGB0,F SIGN,MSB D'23'+EXPBIAS EXP SIGN AARGB0,MSB NRM3224 AARGB2,F ; initialize exponent an

; test sign ; if < 0, negate and set

;******************************************************************************* *************** ; ; 1, ; ; ; ; Normalization routine Input: 32 bit unnormalized floating point number in AEXP, AARGB0, AARGB AARGB2, with sign in SIGN,MSB Use: CALL NRM3224

Output: 24 bit normalized floating point number in AEXP, AARGB0, AARGB1 Result: AARG <-- NORMALIZE( AARG )

; ; ; ; ; ;

Max Timing:

21+6+7*8+7+4 = 94 clks RND = 0 21+6+7*8+20+4 = 103 clks RND = 1, SAT = 0 21+6+7*8+19+11 = 109 clks RND = 1, SAT = 1 22+6 = 28 clks 5+9+4+4 = 22 clks AARG = 0 DM: 7

Min Timing: PM: 51

;--------------------------------------------------------------------------------------------NRM3224 nt CLRF MOVF BTFSS GOTO MOVF move MOVWF MOVF MOVWF CLRF BSF 8 MOVF BTFSS GOTO MOVF move MOVWF CLRF BCF 8 BSF MOVF 0 BTFSC GOTO NORM3224 MOVF SUBWF BTFSS BTFSS GOTO BCF NORM3224A n done and RLF RLF DECFSZ GOTO GOTO AARGB1,F AARGB0,F EXP,F NORM3224A SETFUN24 ; decrement EXP BTFSC GOTO RLF _Z RES024 TEMP,W EXP,F _Z _C SETFUN24 _C AARGB0,MSB NRMRND3224 AARGB2,F ; clear carry bit ; if MSB=1, normalizatio ; otherwise, shift left TEMP,4 AARGB0,W ; if highbyte=0, result= AARGB0 AARGB1 TEMP,3 ; increase decrement by AARGB0,W _Z NORM3224 AARGB1,W ; test if highbyte=0 ; if so, shift 8 bits by AARGB0 AARGB2,W AARGB1 AARGB2 TEMP,3 TEMP AARGB0,W _Z NORM3224 AARGB1,W ; clear exponent decreme ; test if highbyte=0 ; if so, shift 8 bits by

; increase decrement by

; underflow if EXP=0

NRMRND3224

BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSS

FPFLAGS,RND AARGB1,LSB FIXSIGN24 AARGB2,MSB FIXSIGN24 AARGB1,F _Z AARGB0,F _Z FIXSIGN24 AARGB0,F AARGB1,F EXP,F _Z SETFOV24 FIXSIGN24

; round if next bit is s

et

; has rounding caused car ; if so, right shift ; check for overflow

ryout? GOTO RRF RRF INCF BTFSC GOTO GOTO

;******************************************************************************* *************** ;******************************************************************************* *************** ; ; ; ; ; ; ; ; ; ; Float to integer conversion (needed by EXP1024) Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 Use: CALL INT2416 or CALL INT24

Output: 16 bit 2's complement integer right justified in AARGB0, AARGB1 Result: AARG <-- INT( AARG ) Max Timing: 29+6*6+5+13 = 83 clks 29+6*6+5+19 = 89 clks 29+6*6+5+22 = 92 clks 18+5+7 = 30 clks DM: 6 RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

Min Timing: PM: 63

;--------------------------------------------------------------------------------------------INT2416 INT24 MOVF BTFSC RETLW MOVF MOVWF BSF MOVLW SUBWF BTFSS EXP,W _Z 0x00 AARGB0,W SIGN AARGB0,MSB EXPBIAS+D'15' EXP,F EXP,MSB ; test for zero argument

; save sign in SIGN ; make MSB explicit ; remove bias from EXP

GOTO COMF INCF MOVLW = 8 SUBWF BTFSS GOTO MOVWF RLF unding MOVF MOVWF CLRF MOVLW = 8 SUBWF BTFSS GOTO MOVWF RLF unding CLRF MOVF BTFSS BCF GOTO TSHIFT2416 = 0 MOVF BTFSC GOTO SHIFT2416 BCF RRF RRF DECFSZ GOTO BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSC GOTO INT2416OK e BTFSS RETLW COMF COMF INCF

SETIOV16 EXP,F EXP,F 8 EXP,W _C TSHIFT2416 EXP AARGB1,F AARGB0,W AARGB1 AARGB0 8 EXP,W _C TSHIFT2416 EXP AARGB1,F AARGB1 EXP,W _Z _C SHIFT2416OK EXP,W _Z SHIFT2416OK _C AARGB0,F AARGB1,F EXP,F SHIFT2416 FPFLAGS,RND AARGB1,LSB INT2416OK _C INT2416OK AARGB1,F _Z AARGB0,F AARGB0,MSB SETIOV16 SIGN,MSB 0 AARGB1,F AARGB0,F AARGB1,F ; test for overflow ; if sign bit set, negat ; right shift by EXP ; shift completed if EXP ; do byte shift if EXP > ; do byte shift if EXP >

; rotate next bit for ro

; rotate next bit for ro

SHIFT2416OK

; round if next bit is s

et

BTFSC INCF RETLW SETIOV16 lag REG CLRF o's BTFSS ger MOVLW MOVWF MOVWF RLF RRF RETLW REG BSF BTFSS RETLW

_Z AARGB0,F 0 FPFLAGS,IOV FPFLAGS,SAT 0xFF AARGB0 SIGN,MSB 0xFF AARGB0 AARGB1 SIGN,F AARGB0,F 0xFF ; set integer overflow f ; test for saturation ; return error code in W ; saturate to largest tw ; complement 16 bit inte ; SIGN = 0, 0x 7F FF ; SIGN = 1, 0x 80 00 ; return error code in W

;******************************************************************************* *************** ;******************************************************************************* *************** ; ; ; ; AARGB2 ; ; ; ; ; ; Result: AARG <-- INT( AARG ) Max Timing: 41+6*7+6+16 = 105 clks 41+6*7+6+24 = 113 clks 41+6*7+6+26 = 115 clks 5 clks DM: 6 RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 Float to integer conversion Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 Use: CALL INT2424

Output: 24 bit 2's complement integer right justified in AARGB0, AARGB1,

Min Timing: PM: 82

;--------------------------------------------------------------------------------------------INT2424 CLRF MOVF BTFSC RETLW MOVF MOVWF BSF MOVLW AARGB2 EXP,W _Z 0x00 AARGB0,W SIGN AARGB0,MSB EXPBIAS+D'23' ; test for zero argument

; save sign in SIGN ; make MSB explicit ; remove bias from EXP

SUBWF BTFSS GOTO COMF INCF MOVLW = 8 SUBWF BTFSS GOTO MOVWF RLF unding MOVF MOVWF MOVF MOVWF CLRF MOVLW if EXP >= 8 SUBWF BTFSS GOTO MOVWF RLF unding MOVF MOVWF CLRF MOVLW if EXP >= 8 SUBWF BTFSS GOTO MOVWF RLF unding CLRF MOVF BTFSS BCF GOTO TSHIFT2424 = 0 MOVF BTFSC GOTO SHIFT2424 BCF RRF RRF RRF DECFSZ GOTO BTFSC BTFSS

EXP,F EXP,MSB SETIOV24 EXP,F EXP,F 8 EXP,W _C TSHIFT2424 EXP AARGB2,F AARGB1,W AARGB2 AARGB0,W AARGB1 AARGB0 8 EXP,W _C TSHIFT2424 EXP AARGB2,F AARGB1,W AARGB2 AARGB1 8 EXP,W _C TSHIFT2424 EXP AARGB2,F AARGB2 EXP,W _Z _C SHIFT2424OK EXP,W _Z SHIFT2424OK _C AARGB0,F AARGB1,F AARGB2,F EXP,F SHIFT2424 FPFLAGS,RND AARGB2,LSB ; right shift by EXP ; shift completed if EXP ; do another byte shift ; do another byte shift ; do byte shift if EXP >

; rotate next bit for ro

; rotate next bit for ro

; rotate next bit for ro

SHIFT2424OK

GOTO BTFSS GOTO INCF BTFSC INCF BTFSC INCF BTFSC GOTO INT2424OK e BTFSS RETLW COMF COMF COMF INCF BTFSC INCF BTFSC INCF RETLW IRES024 zero CLRF CLRF CLRF RETLW SETIOV24 lag REG CLRF o's BTFSS ger MOVLW MOVWF MOVWF MOVWF RLF RRF RETLW REG BSF BTFSS RETLW

INT2424OK _C INT2424OK AARGB2,F _Z AARGB1,F _Z AARGB0,F AARGB0,MSB SETIOV24 SIGN,MSB 0 AARGB0,F AARGB1,F AARGB2,F AARGB2,F _Z AARGB1,F _Z AARGB0,F 0 AARGB0 AARGB1 AARGB2 0 FPFLAGS,IOV FPFLAGS,SAT 0xFF AARGB0 SIGN,MSB 0xFF AARGB0 AARGB1 AARGB2 SIGN,F AARGB0,F 0xFF

; test for overflow ; if sign bit set, negat

; integer result equals

; set integer overflow f ; test for saturation ; return error code in W ; saturate to largest tw ; complement 24 bit inte ; SIGN = 0, 0x 7F FF FF ; SIGN = 1, 0x 80 00 00

; return error code in W

;******************************************************************************* *************** ;******************************************************************************* *************** ; ; ; ; Floating Point Multiply Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 24 bit floating point number in BEXP, BARGB0, BARGB1 Use: CALL FPM24

; ; ; ; ; ; ; ;

Output: 24 bit floating point product in AEXP, AARGB0, AARGB1 Result: AARG <-- AARG * BARG Max Timing: 25+15*16+15+18 = 298 clks 25+15*16+15+29 = 309 clks 25+15*16+15+33 = 313 clks 6+5 = 11 clks 24+15*11+14+15 = 218 clks DM: 11 RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG * BARG = 0

Min Timing: PM: 80

;--------------------------------------------------------------------------------------------FPM24 s MOVF BTFSS MOVF BTFSC GOTO M24BNE0 MOVF XORWF MOVWF MOVF ADDWF MOVLW BTFSS GOTO SUBWF BTFSC GOTO flag GOTO MTUN24 SUBWF BTFSS GOTO MOVF MOVWF MOVF MOVWF BSF plicit BSF BCF CLRF product CLRF MOVLW MOVWF MLOOP24 BTFSS AARGB1 D'16' TEMP AARGB3,LSB ; initialize counter ; test next bit BARGB0,MSB _C AARGB0 ; clear initial partial MOK24 EXP,F _C SETFUN24 AARGB0,W AARGB2 AARGB1,W AARGB3 AARGB2,MSB AEXP,W _Z BEXP,W _Z RES024 AARGB0,W BARGB0,W SIGN BEXP,W EXP,F EXPBIAS-1 _C MTUN24 EXP,F _C SETFOV24 ; test for zero argument

; save sign in SIGN

; set multiply overflow

MOK24 ; move result to AARG ; make argument MSB's ex

GOTO MADD24 MOVF ADDWF MOVF BTFSC INCFSZ ADDWF RRF RRF RRF RRF BCF DECFSZ GOTO BTFSC ation GOTO RLF RLF RLF DECF MROUND24 BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSS rryout? GOTO RRF RRF INCF BTFSC GOTO MUL24OK positive RETLW SETFOV24 erflag REG MOVLW MOVWF oating MOVWF BSF BTFSS RETLW BTFSS BCF

MNOADD24 BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F AARGB0,F AARGB1,F AARGB2,F AARGB3,F _C TEMP,F MLOOP24 AARGB0,MSB MROUND24 AARGB2,F AARGB1,F AARGB0,F EXP,F FPFLAGS,RND AARGB1,LSB MUL24OK AARGB2,MSB MUL24OK AARGB1,F _Z AARGB0,F _Z MUL24OK AARGB0,F AARGB1,F EXP,F _Z SETFOV24 SIGN,MSB AARGB0,MSB 0 FPFLAGS,FOV FPFLAGS,SAT 0xFF 0xFF AEXP AARGB0 ; set floating point und ; test for saturation ; return error code in W ; has rounding caused ca ; if so, right shift ; check for overflow ; check for postnormaliz

MNOADD24

; round if next bit is s

et

; clear explicit MSB if

; saturate to largest fl ; point number = 0x FF 7

F FF MOVWF sign bit RLF RRF RETLW REG ;******************************************************************************* *************** ;******************************************************************************* *************** ; ; ; ; ; ; ; ; ; ; ; Floating Point Divide Input: 24 bit floating point dividend in AEXP, AARGB0, AARGB1 24 bit floating point divisor in BEXP, BARGB0, BARGB1 Use: CALL FPD24 SIGN,F AARGB0,F 0xFF ; return error code in W AARGB1 ; modulo the appropriate

Output: 24 bit floating point quotient in AEXP, AARGB0, AARGB1 Result: AARG <-- AARG / BARG Max Timing: 32+13+15*26+25+12 = 472 clks 32+13+15*26+25+34 = 494 clks 32+13+15*26+25+38 = 498 clks 7+5 = 12 clks DM: 11 RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

Min Timing: PM: 120

;--------------------------------------------------------------------------------------------FPD24 o MOVF BTFSC GOTO MOVF BTFSC GOTO D24BNE0 MOVF XORWF MOVWF BSF BSF TALIGN24 CLRF MOVF MOVWF MOVF MOVWF MOVF SUBWF MOVF BEXP,W _Z SETFDZ24 AEXP,W _Z RES024 AARGB0,W BARGB0,W SIGN AARGB0,MSB BARGB0,MSB TEMP AARGB0,W AARGB2 AARGB1,W AARGB3 BARGB1,W AARGB3, f BARGB0,W ; clear align increment ; test for alignment ; test for divide by zer

; save sign in SIGN ; make argument MSB's ex

plicit

BTFSS INCFSZ SUBWF CLRF CLRF BTFSS GOTO BCF RRF RRF RRF MOVLW MOVWF DALIGN24OK MOVF SUBWF BTFSS GOTO MOVLW ADDWF ADDWF BTFSC GOTO GOTO MOVLW ADDWF ADDWF BTFSS GOTO MOVLW MOVWF RLF RLF RLF RLF RLF MOVF SUBWF MOVF BTFSS INCFSZ SUBWF RLF IORWF BTFSS GOTO BSF GOTO

_C BARGB0,W AARGB2, f AARGB2 AARGB3 _C DALIGN24OK _C AARGB0,F AARGB1,F AARGB2,F 0x01 TEMP BEXP,W EXP,F _C ALTB24 EXPBIAS-1 TEMP,W EXP,F _C SETFOV24 DARGOK24 EXPBIAS-1 TEMP,W EXP,F _C SETFUN24 D'16' TEMPB1 AARGB3,F AARGB2,F AARGB1,F AARGB0,F TEMP,F BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F BARGB0,W TEMP,F TEMP,LSB DREST24 AARGB3,LSB DOK24 ; test for restore ; align if necessary

; save align increment ; compare AEXP and BEXP

AGEB24

; set overflow flag

ALTB24

; set underflow flag ; initialize counter ; left shift

DARGOK24 DLOOP24

; subtract

DREST24

MOVF ADDWF MOVF BTFSC INCF ADDWF BCF DECFSZ GOTO BTFSC BTFSS GOTO BCF RLF RLF RLF MOVF SUBWF MOVF BTFSS INCFSZ SUBWF RLF IORWF ANDLW ADDWF BTFSC INCF BTFSS

BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F AARGB3,LSB TEMPB1,F DLOOP24 FPFLAGS,RND AARGB3,LSB DIV24OK _C AARGB1,F AARGB0,F TEMP,F BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F BARGB0,W TEMP,W 0x01 AARGB3,F _C AARGB2,F _Z DIV24OK AARGB2,F AARGB3,F EXP,F _Z SETFOV24 SIGN,MSB AARGB2,MSB AARGB2,W AARGB0 AARGB3,W AARGB1 0 FPFLAGS,FUN FPFLAGS,SAT 0xFF

; restore if necessary

DOK24 DROUND24

; compute next significa ; for rounding ; subtract

nt bit

; test if rounding cause

d carryout GOTO RRF RRF INCF BTFSC GOTO DIV24OK positive MOVF MOVWF MOVF MOVWF RETLW SETFUN24 erflag BSF BTFSS RETLW ; move result to AARG BTFSS BCF

; test for overflow

; clear explicit MSB if

; set floating point und ; test for saturation ; return error code in W

REG MOVLW loating MOVWF 0 00 CLRF sign bit CLRF RLF RRF RETLW REG SETFDZ24 g BSF RETLW FPFLAGS,FDZ 0xFF ; set divide by zero fla AARGB1 SIGN,F AARGB0,F 0xFF AARGB0 ; modulo the appropriate AEXP ; point number = 0x 01 0 0x01 ; saturate to smallest f

; return error code in W

;******************************************************************************* *************** ;******************************************************************************* *************** ; ; ; ; ; ; ; ; ; ; ; Floating Point Subtract Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 24 bit floating point number in BEXP, BARGB0, BARGB1 Use: CALL FPS24

Output: 24 bit floating point sum in AEXP, AARGB0, AARGB1 Result: AARG <-- AARG - BARG Max Timing: 2+197 = 199 clks 2+208 = 210 clks 2+213 = 215 clks 2+12 = 14 clks DM: 11 RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

Min Timing: PM: 2+112 = 114

;--------------------------------------------------------------------------------------------FPS24 MOVLW XORWF 0x80 BARGB0,F

;******************************************************************************* *************** ; ; ; ; ; Floating Point Add Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 24 bit floating point number in BEXP, BARGB0, BARGB1 Use: CALL FPA24

Output: 24 bit floating point sum in AEXP, AARGB0, AARGB1

; ; ; ; ; ;

Result: AARG <-- AARG - BARG Max Timing: 25+28+6*6+5+31+72 = 197 clks 25+28+6*6+5+42+72 = 208 clks 25+28+6*6+5+42+77 = 213 clks 8+4 = 12 clks DM: 11 RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

Min Timing: PM: 112

;--------------------------------------------------------------------------------------------FPA24 in TEMP MOVF XORWF MOVWF CLRF CLRF MOVF XP SUBWF BTFSS GOTO MOVF P MOVWF nd BARG MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF USEA24 0 MOVF BTFSC RETLW MOVF MOVWF BSF BSF AEXP,W BEXP AARGB4,W AEXP BARGB0,W AARGB4 AARGB0,W BARGB0 AARGB4,W AARGB0 BARGB1,W AARGB4 AARGB1,W BARGB1 AARGB4,W AARGB1 BEXP,W _Z 0x00 AARGB0,W SIGN AARGB0,MSB BARGB0,MSB ; save sign in SIGN ; make MSB's explicit ; return AARG if BARG = AARGB4 ; therefore, swap AARG a BEXP,W _C USEA24 BEXP,W ; use BARG if AEXP < BEX AARGB0,W BARGB0,W TEMP AARGB2 BARGB2 AEXP,W ; clear extended byte ; use AARG if AEXP >= BE ; exclusive or of signs

MOVF BEXP SUBWF MOVWF BTFSC GOTO MOVLW SUBWF BTFSS shift GOTO MOVWF MOVF tion MOVWF MOVF MOVWF CLRF MOVLW SUBWF BTFSS relative to AARG GOTO MOVF MOVWF RETLW ALIGNB24 P = 0 MOVF BTFSC GOTO ALOOPB24 BCF RRF RRF RRF DECFSZ GOTO BTFSS GOTO COMF COMF COMF INCF BTFSC INCF BTFSC INCF AOK24 MOVF ADDWF MOVF BTFSC INCFSZ ADDWF

BEXP,W AEXP,W BEXP _Z ALIGNED24 8 BEXP,W _C ALIGNB24 BEXP BARGB1,W BARGB2 BARGB0,W BARGB1 BARGB0 8 BEXP,W _C ALIGNB24 SIGN,W AARGB0 0x00 BEXP,W _Z ALIGNED24 _C BARGB0,F BARGB1,F BARGB2,F BEXP,F ALOOPB24 TEMP,MSB AOK24 BARGB2,F BARGB1,F BARGB0,F BARGB2,F _Z BARGB1,F _Z BARGB0,F BARGB2,W AARGB2,F BARGB1,W _C BARGB1,W AARGB1,F

; compute shift count in

; if BEXP >= 8, do byte

; keep for postnormaliza

; if BEXP >= 8, BARG = 0

; already aligned if BEX

; right shift by BEXP

ALIGNED24 te

; negate if signs opposi

MOVF BTFSC INCFSZ ADDWF BTFSC GOTO BTFSS GOTO RRF ent EXP RRF RRF INCFSZ GOTO GOTO ACOMP24 BTFSC GOTO COMF COMF t and COMF INCF BTFSC INCF BTFSC INCF MOVLW XORWF GOTO

BARGB0,W _C BARGB0,W AARGB0,F TEMP,MSB ACOMP24 _C NRMRND3224 AARGB0,F AARGB1,F AARGB2,F AEXP,F NRMRND3224 SETFOV24 _C NRM3224 AARGB2,F AARGB1,F AARGB0,F AARGB2,F _Z AARGB1,F _Z AARGB0,F 0x80 SIGN,F NRM24 ; normalize and fix sign ; negate, toggle sign bi ; then normalize ; shift right and increm

;******************************************************************************* *************** org h'800' to ; simplify page crossings... ; ************************************************************************ **************** ; THIS NEXT SECTION COMES FROM FP32.A16 ; (TO GET FPA32 -- called by EXP1024, POL24, also ; FPM32 -- needed by POL24 macro & FLOAT_ASCII, also ; INT3232 -- needed by FLOAT_ASCII, also ; SETFUN32 -- needed by NORM4032, also ; SETFOV32 -- needed by NRM4032) ; ; ; ; ; PIC16 32 BIT FLOATING POINT LIBRARY Floating Point Add Input: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 32 bit floating point number in BEXP, BARGB0, BARGB1, BARGB2 Use: CALL FPA32 ; we make the remaining routines start at 0800h,

; ; ; ; ; ; ;

Output: 32 bit floating point sum in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG <-- AARG - BARG Max Timing: 31+41+6*7+6+41+90 = 251 clks 31+41+6*7+6+55+90 = 265 clks 31+41+6*7+6+55+96 = 271 clks 8+4 = 12 clks DM: 14 RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

Min Timing: PM: 146

;--------------------------------------------------------------------------------------------FPA32 MOVF AARGB0,W ; exclusive or of signs in TEMP XORWF BARGB0,W MOVWF TEMP CLRF CLRF MOVF XP SUBWF BTFSS GOTO MOVF P MOVWF nd BARG MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF USEA32 0 MOVF AEXP,W BEXP AARGB5,W AEXP BARGB0,W AARGB5 AARGB0,W BARGB0 AARGB5,W AARGB0 BARGB1,W AARGB5 AARGB1,W BARGB1 AARGB5,W AARGB1 BARGB2,W AARGB5 AARGB2,W BARGB2 AARGB5,W AARGB2 BEXP,W ; return AARG if BARG = AARGB5 ; therefore, swap AARG a BEXP,W _C USEA32 BEXP,W ; use BARG if AEXP < BEX AARGB3 BARGB3 AEXP,W ; clear extended byte ; use AARG if AEXP >= BE

BTFSC RETLW MOVF MOVWF BSF BSF MOVF BEXP SUBWF MOVWF BTFSC GOTO MOVLW SUBWF BTFSS shift GOTO MOVWF MOVF tion MOVWF MOVF MOVWF MOVF MOVWF CLRF MOVLW SUBWF BTFSS shift GOTO MOVWF MOVF tion MOVWF MOVF MOVWF CLRF MOVLW SUBWF BTFSS relative to AARG GOTO MOVF MOVWF RETLW ALIGNB32 P = 0 MOVF BTFSC GOTO ALOOPB32 BCF RRF RRF

_Z 0x00 AARGB0,W SIGN AARGB0,MSB BARGB0,MSB BEXP,W AEXP,W BEXP _Z ALIGNED32 8 BEXP,W _C ALIGNB32 BEXP BARGB2,W BARGB3 BARGB1,W BARGB2 BARGB0,W BARGB1 BARGB0 8 BEXP,W _C ALIGNB32 BEXP BARGB2,W BARGB3 BARGB1,W BARGB2 BARGB1 8 BEXP,W _C ALIGNB32 SIGN,W AARGB0 0x00 BEXP,W _Z ALIGNED32 _C BARGB0,F BARGB1,F ; right shift by BEXP ; already aligned if BEX ; save sign in SIGN ; make MSB's explicit ; compute shift count in

; if BEXP >= 8, do byte

; keep for postnormaliza

; if BEXP >= 8, do byte

; keep for postnormaliza

; if BEXP >= 8, BARG = 0

RRF RRF DECFSZ GOTO ALIGNED32 te BTFSS GOTO COMF COMF COMF COMF INCF BTFSC INCF BTFSC INCF BTFSC INCF AOK32 MOVF ADDWF MOVF BTFSC INCFSZ ADDWF MOVF BTFSC INCFSZ ADDWF MOVF BTFSC INCFSZ ADDWF BTFSC GOTO BTFSS GOTO RRF nt EXP RRF RRF RRF INCFSZ GOTO GOTO ACOMP32 BTFSC GOTO COMF COMF t and COMF COMF INCF

BARGB2,F BARGB3,F BEXP,F ALOOPB32 TEMP,MSB AOK32 BARGB3,F BARGB2,F BARGB1,F BARGB0,F BARGB3,F _Z BARGB2,F _Z BARGB1,F _Z BARGB0,F BARGB3,W AARGB3,F BARGB2,W _C BARGB2,W AARGB2,F BARGB1,W _C BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F TEMP,MSB ACOMP32 _C NRMRND4032 AARGB0,F AARGB1,F AARGB2,F AARGB3,F AEXP,F NRMRND4032 SETFOV32 _C NRM4032 AARGB3,F AARGB2,F AARGB1,F AARGB0,F AARGB3,F ; normalize and fix sign ; negate, toggle sign bi ; then normalize ; shift right and increme ; negate if signs opposi

BTFSC INCF BTFSC INCF BTFSC INCF MOVLW XORWF NRM32 nt CLRF MOVF BTFSS GOTO MOVF move MOVWF MOVF MOVWF CLRF BSF 8 MOVF BTFSS GOTO MOVF move MOVWF CLRF BCF 8 BSF MOVF 0 BTFSC GOTO NORM3232 MOVF SUBWF BTFSS BTFSS GOTO BCF NORM3232A n done and RLF RLF DECFSZ GOTO GOTO FIXSIGN32 BTFSS BTFSC GOTO RLF

_Z AARGB2,F _Z AARGB1,F _Z AARGB0,F 0x80 SIGN,F TEMP AARGB0,W _Z NORM3232 AARGB1,W AARGB0 AARGB2,W AARGB1 AARGB2 TEMP,3 AARGB0,W _Z NORM3232 AARGB1,W AARGB0 AARGB1 TEMP,3 TEMP,4 AARGB0,W _Z RES032 TEMP,W EXP,F _Z _C SETFUN32 _C AARGB0,MSB FIXSIGN32 AARGB2,F AARGB1,F AARGB0,F EXP,F NORM3232A SETFUN32 SIGN,MSB ; clear carry bit ; if MSB=1, normalizatio ; otherwise, shift left ; decrement EXP ; if highbyte=0, result= ; clear exponent decreme ; test if highbyte=0 ; if so, shift 8 bits by

; increase decrement by ; test if highbyte=0 ; if so, shift 8 bits by

; increase decrement by

; underflow if EXP=0

BCF positive RETLW RES032 CLRF CLRF CLRF CLRF CLRF RETLW BSF BTFSS RETLW REG MOVLW loating MOVWF 0 00 00 CLRF sign bit CLRF CLRF RLF RRF RETLW REG

AARGB0,MSB 0 AARGB0 AARGB1 AARGB2 AARGB3 EXP 0 FPFLAGS,FUN FPFLAGS,SAT 0xFF 0x01 AEXP AARGB0 AARGB1 AARGB2 SIGN,F AARGB0,F 0xFF

; clear explicit MSB if

; result equals zero

SETFUN32 erflag

; set floating point und ; test for saturation ; return error code in W ; saturate to smallest f ; point number = 0x 01 0 ; modulo the appropriate

; return error code in W

;******************************************************************************* *************** ; ; 1, ; ; ; AARGB2, ; ; ; ; ; ; ; ; AARGB3 Result: AARG <-- NORMALIZE( AARG ) Max Timing: 38+6*9+12+8 = 112 clks RND = 0 38+6*9+12+24 = 128 clks RND = 1, SAT = 0 38+6*9+12+31 = 135 clks RND = 1, SAT = 1 33+6 = 39 clks 5+9+8 = 22 clks AARG = 0 DM: 8 Normalization routine (needed by FPA32) Input: 40 bit unnormalized floating point number in AEXP, AARGB0, AARGB AARGB2, AARGB3 with sign in SIGN,MSB Use: CALL NRM4032

Output: 32 bit normalized floating point number in AEXP, AARGB0, AARGB1,

Min Timing: PM: 66

;--------------------------------------------------------------------------------------------NRM4032 CLRF TEMP ; clear exponent decreme nt

MOVF BTFSS GOTO MOVF move MOVWF MOVF MOVWF MOVF MOVWF CLRF BSF 8 MOVF BTFSS GOTO MOVF move MOVWF MOVF MOVWF CLRF BCF 8 BSF MOVF BTFSS GOTO MOVF move MOVWF CLRF BSF 8 MOVF 0 BTFSC GOTO NORM4032 MOVF SUBWF BTFSS BTFSS GOTO BCF NORM4032A n done and RLF RLF RLF DECFSZ GOTO BTFSC GOTO RLF

AARGB0,W _Z NORM4032 AARGB1,W AARGB0 AARGB2,W AARGB1 AARGB3,W AARGB2 AARGB3 TEMP,3 AARGB0,W _Z NORM4032 AARGB1,W AARGB0 AARGB2,W AARGB1 AARGB2 TEMP,3 TEMP,4 AARGB0,W _Z NORM4032 AARGB1,W AARGB0 AARGB1 TEMP,3 AARGB0,W _Z RES032 TEMP,W EXP,F _Z _C SETFUN32 _C AARGB0,MSB NRMRND4032 AARGB3,F AARGB2,F AARGB1,F AARGB0,F EXP,F NORM4032A

; test if highbyte=0 ; if so, shift 8 bits by

; increase decrement by ; test if highbyte=0 ; if so, shift 8 bits by

; increase decrement by

; test if highbyte=0 ; if so, shift 8 bits by

; increase decrement by ; if highbyte=0, result=

; clear carry bit ; if MSB=1, normalizatio ; otherwise, shift left ; decrement EXP

GOTO NRMRND4032 BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSC INCF BTFSS rryout? GOTO RRF RRF RRF INCF BTFSC GOTO GOTO SETFOV32 erflag REG MOVLW MOVWF oating MOVWF F FF FF MOVWF sign bit MOVWF RLF RRF RETLW REG BSF BTFSS RETLW

SETFUN32 FPFLAGS,RND AARGB2,LSB FIXSIGN32 AARGB3,MSB FIXSIGN32 AARGB2,F _Z AARGB1,F _Z AARGB0,F _Z FIXSIGN32 AARGB0,F AARGB1,F AARGB2,F EXP,F _Z SETFOV32 FIXSIGN32 FPFLAGS,FOV FPFLAGS,SAT 0xFF 0xFF AEXP AARGB0 AARGB1 AARGB2 SIGN,F AARGB0,F 0xFF

; underflow if EXP=0

; round if next bit is s

et

; has rounding caused ca ; if so, right shift

; check for overflow

; set floating point und ; test for saturation ; return error code in W

; saturate to largest fl ; point number = 0x FF 7 ; modulo the appropriate

; return error code in W

;******************************************************************************* *************** ;******************************************************************************* *************** ; ; ; ; ; ; Floating Point Multiply (needed by POL24 macro) Input: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 32 bit floating point number in BEXP, BARGB0, BARGB1, BARGB2 Use: CALL FPM32

Output: 32 bit floating point product in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG <-- AARG * BARG

; ; ; ; ; ;

Max Timing:

26+23*22+21+21 = 574 clks 26+23*22+21+35 = 588 clks 26+23*22+21+38 = 591 clks 6+6 = 12 clks 24+23*11+21+17 = 315 clks

RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG * BARG = 0 DM: 14

Min Timing: PM: 94

;--------------------------------------------------------------------------------------------FPM32 s MOVF BTFSS MOVF BTFSC GOTO M32BNE0 MOVF XORWF MOVWF MOVF ADDWF MOVLW BTFSS GOTO SUBWF BTFSC GOTO flag GOTO MTUN32 SUBWF BTFSS GOTO MOVF MOVWF MOVF MOVWF MOVF MOVWF BSF BSF BCF CLRF product CLRF CLRF MOVLW MOVWF MLOOP32 BTFSS GOTO AARGB1 AARGB2 D'24' TEMP AARGB5,LSB MNOADD32 MOK32 EXP,F _C SETFUN32 AARGB0,W AARGB3 AARGB1,W AARGB4 AARGB2,W AARGB5 AARGB3,MSB BARGB0,MSB _C AARGB0 AEXP,W _Z BEXP,W _Z RES032 AARGB0,W BARGB0,W SIGN BEXP,W EXP,F EXPBIAS-1 _C MTUN32 EXP,F _C SETFOV32 ; test for zero argument

; save sign in SIGN

; set multiply overflow

MOK32

; make argument MSB's ex

plicit ; clear initial partial

; initialize counter ; test next bit

MADD32

MOVF ADDWF MOVF BTFSC INCFSZ ADDWF MOVF BTFSC INCFSZ ADDWF

BARGB2,W AARGB2,F BARGB1,W _C BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F AARGB0,F AARGB1,F AARGB2,F AARGB3,F AARGB4,F AARGB5,F _C TEMP,F MLOOP32 AARGB0,MSB MROUND32 AARGB3,F AARGB2,F AARGB1,F AARGB0,F EXP,F FPFLAGS,RND AARGB2,LSB MUL32OK AARGB3,MSB MUL32OK AARGB2,F _Z AARGB1,F _Z AARGB0,F _Z MUL32OK AARGB0,F AARGB1,F AARGB2,F EXP,F _Z SETFOV32 SIGN,MSB AARGB0,MSB 0 FPFLAGS,IOV FPFLAGS,SAT 0xFF ; set integer overflow flag ; test for saturation ; return error code in WREG ; has rounding caused ca ; if so, right shift ; check for postnormali

MNOADD32

RRF RRF RRF RRF RRF RRF BCF DECFSZ GOTO BTFSC

zation GOTO RLF RLF RLF RLF DECF MROUND32 BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSC INCF BTFSS rryout? GOTO RRF RRF RRF INCF BTFSC GOTO MUL32OK positive RETLW SETIOV3224 BSF BTFSS RETLW BTFSS BCF

; check for overflow

; clear explicit MSB if

CLRF o's

AARGB0

; saturate to largest tw

BTFSS SIGN,MSB ; complement 24 bit integer MOVLW 0xFF MOVWF AARGB0 ; SIGN = 0, 0x 7F FF FF MOVWF AARGB1 ; SIGN = 1, 0x 80 00 00 MOVWF AARGB2 RLF SIGN,F RRF AARGB0,F RETLW 0xFF ; return error code in WREG ; **************************************************************************** *************** ; ************************************************************************ ******************* ; Float to integer conversion ; ; ; AARGB2, ; ; ; ; ; ; ; AARGB3 Result: AARG <-- INT( AARG ) Max Timing: 54+6*8+7+21 = 130 clks 54+6*8+7+29 = 137 clks 54+6*8+7+29 = 137 clks 5 clks DM: 7 RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 Input: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 Use: CALL INT3232

Output: 32 bit 2's complement integer right justified in AARGB0, AARGB1,

Min Timing: PM: 102

;--------------------------------------------------------------------------------------------INT3232 CLRF MOVF BTFSC RETLW MOVF MOVWF BSF MOVLW SUBWF BTFSS GOTO COMF INCF MOVLW = 8 SUBWF BTFSS GOTO EXP,W _C TSHIFT3232 AARGB3 EXP,W _Z 0x00 AARGB0,W SIGN AARGB0,MSB EXPBIAS+D'31' EXP,F EXP,MSB SETIOV32 EXP,F EXP,F 8 ; test for zero argument

; save sign in SIGN ; make MSB explicit ; remove bias from EXP

; do byte shift if EXP >

MOVWF RLF unding MOVF MOVWF MOVF MOVWF MOVF MOVWF CLRF MOVLW if EXP >= 8 SUBWF BTFSS GOTO MOVWF RLF unding MOVF MOVWF MOVF MOVWF CLRF MOVLW if EXP >= 8 SUBWF BTFSS GOTO MOVWF RLF unding MOVF MOVWF CLRF MOVLW if EXP >= 8 SUBWF BTFSS GOTO MOVWF RLF unding CLRF MOVF BTFSS BCF GOTO TSHIFT3232 = 0 MOVF BTFSC GOTO SHIFT3232 BCF RRF RRF RRF

EXP AARGB3,F AARGB2,W AARGB3 AARGB1,W AARGB2 AARGB0,W AARGB1 AARGB0 8 EXP,W _C TSHIFT3232 EXP AARGB3,F AARGB2,W AARGB3 AARGB1,W AARGB2 AARGB1 8 EXP,W _C TSHIFT3232 EXP AARGB3,F AARGB2,W AARGB3 AARGB2 8 EXP,W _C TSHIFT3232 EXP AARGB3,F AARGB3 EXP,W _Z _C SHIFT3232OK EXP,W _Z SHIFT3232OK _C AARGB0,F AARGB1,F AARGB2,F

; rotate next bit for ro

; do another byte shift

; rotate next bit for ro

; do another byte shift

; rotate next bit for ro

; do another byte shift

; rotate next bit for ro

; shift completed if EXP

; right shift by EXP

RRF DECFSZ GOTO SHIFT3232OK BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSC INCF BTFSC INCF BTFSC GOTO BTFSS RETLW COMF COMF COMF COMF INCF BTFSC INCF BTFSC INCF BTFSC INCF RETLW IRES032 zero CLRF CLRF CLRF CLRF RETLW SETIOV32 lag REG CLRF o's BTFSS ger MOVLW MOVWF FF MOVWF 00 MOVWF MOVWF RLF BSF BTFSS RETLW

AARGB3,F EXP,F SHIFT3232 FPFLAGS,RND AARGB3,LSB INT3232OK _C INT3232OK AARGB3,F _Z AARGB2,F _Z AARGB1,F _Z AARGB0,F AARGB0,MSB SETIOV3224 SIGN,MSB 0 AARGB0,F AARGB1,F AARGB2,F AARGB3,F AARGB3,F _Z AARGB2,F _Z AARGB1,F _Z AARGB0,F 0 AARGB0 AARGB1 AARGB2 AARGB3 0 FPFLAGS,IOV FPFLAGS,SAT 0xFF AARGB0 SIGN,MSB 0xFF AARGB0 AARGB1 AARGB2 AARGB3 SIGN,F ; set integer overflow f ; test for saturation ; return error code in W ; saturate to largest tw ; complement 32 bit inte ; SIGN = 0, 0x 7F FF FF ; SIGN = 1, 0x 80 00 00 ; integer result equals

; test for overflow ; if sign bit set, negat

INT3232OK e

RRF RETLW ; ; ; ; ; COF, ; ; ; ; ; ; d ; t ; ; t ; POL24

AARGB0,F 0xFF

; return error code in WREG

*********************************************************************** *********************************************************************** THIS SECTION COMES FROM MATH16.MAC (for POL24 macro, needed by EXP1024) POL24 macro COF,N,ROUND

32 bit evaluation of polynomial of degree N, PN(AARG), with coefficients and where AARG is assumed have been be saved in DARG when N>1. The result is in AARG. ROUND ROUND ROUND ROUND = = = = 0 1 2 3 no rounding rounding is rounding is rounding is is enabled; can be previously enabled enabled enabled then disabled before last add assumed disabled then enabled before last ad

ROUND = 4 ROUND = 5

rounding is assumed enabled and then disabled before las add if DARGB3,RND is clear rounding is assumed disabled and then enabled before las add if DARGB3,RND is set

macro local variable if

COF,N,ROUND i,j i = N, j = 0 ROUND == 1 BSF ROUND == 2 FPFLAGS,RND

endif MOVLW MOVWF while MOVLW MOVWF variable endw BSF PCLATH,3 BCF PCLATH,4 CALL variable MOVLW MOVWF variable while j = 0 j <= 2 FPM32 j <= 2 COF#v(i)#v(j) BARGB#v(j) j = j + 1 COF#v(i) BEXP

i = i - 1 COF#v(i) BEXP

MOVLW MOVWF variable endw BSF PCLATH,3 BCF PCLATH,4 CALL variable while

COF#v(i)#v(j) BARGB#v(j) j = j + 1

FPA32

i = i - 1 i >= 0 MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF BSF PCLATH,3 BCF PCLATH,4 CALL MOVLW MOVWF DEXP,W BEXP DARGB0,W BARGB0 DARGB1,W BARGB1 DARGB2,W BARGB2 FPM32 COF#v(i) BEXP j = 0 j <= 2 MOVLW MOVWF COF#v(i)#v(j) BARGB#v(j) j = j + 1

variable while

variable endw if i == 0 if BCF endif if BSF endif if BTFSS BCF

ROUND == 2 FPFLAGS,RND

ROUND == 3 FPFLAGS,RND

ROUND == 4 DARGB3,RND FPFLAGS,RND

endif if BTFSC BSF endif endif BSF PCLATH,3 BCF PCLATH,4 CALL variable endw endm ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; EXP1024 MOVLW )/(2*LOG(10)) SUBWF EXP,W 0x64 ; test for x < 2**(-24 ****************************************************************** ****************************************************************** THIS NEXT SECTION IS FROM EXP1024.A16 (ALL OF IT, IN FACT) Evaluate exp10(x) Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 Use: CALL EXP1024 FPA32 ROUND == 5 DARGB3,RND FPFLAGS,RND

i = i - 1

Output: 24 bit floating point number in AEXP, AARGB0, AARGB1 Result: AARG <-- EXP10( AARG ) Testing on [MINLOG10,MAXLOG10] from 10000 trials: Timing: 2043 Error: -0x75 min 2561 min 0x77 max mean 2328.7 clks max -0.95 mean 40.34 rms nsb

-----------------------------------------------------------------------This approximation of the base 10 exponential function is based upon the expansion exp10(x) = 10**x = 2**(x/log10(2)) = 2**z * 2**n x/log10(2) = z + n, where 0 <= z < 1 and n is an integer, evaluated during range reduction. Segmented third degree minimax polynomial approximations are used to estimate 2**z on the intervals [0,.25], [.25,.5], [.5,.75] and [.75,1].

MOVWF BTFSC GOTO BTFSC GOTO TPEXP1024 MOVF SUBLW BTFSS GOTO BTFSS GOTO MOVF SUBLW BTFSS GOTO BTFSS GOTO MOVF SUBLW BTFSS GOTO GOTO DOMERR24 BSF RETLW TNEXP1024 MOVF SUBLW BTFSS GOTO BTFSS GOTO MOVF SUBLW BTFSS GOTO BTFSS GOTO MOVF SUBLW BTFSS GOTO EXP1024ARGOK MOVF MOVWF BCF BSF PCLATH,3 1 BCF PCLATH,4 CALL

TEMPB0 TEMPB0,MSB EXP1024ONE AARGB0,MSB TNEXP1024 AEXP,W MAXLOG1024EXP _C DOMERR24 _Z EXP1024ARGOK AARGB0,W MAXLOG1024B0 _C DOMERR24 _Z EXP1024ARGOK AARGB1,W MAXLOG1024B1 _C DOMERR24 EXP1024ARGOK FPFLAGS,DOM 0xFF AEXP,W MINLOG1024EXP _C DOMERR24 _Z EXP1024ARGOK AARGB0,W MINLOG1024B0 _C DOMERR24 _Z EXP1024ARGOK AARGB1,W MINLOG1024B1 _C DOMERR24 FPFLAGS,W DARGB3 FPFLAGS,RND

; return 10**x = 1

; domain error

; save rounding flag ; disable rounding ; make sure we will stay in page ; when we call RREXP1024

RREXP1024

MOVLW SUBWF BTFSS GOTO EXP1024H BTFSS GOTO POL24 on [.75,1] MOVF ADDWF RETLW EXP1024HL on [.5,.75] POL24 MOVF ADDWF RETLW EXP1024L MOVLW SUBWF BTFSS GOTO POL24 on [.25,.5] MOVF ADDWF RETLW EXP1024LL on [0,.25] EXP1024OK MOVF ADDWF BTFSS RETLW BSF GOTO EXP1024ONE MOVLW MOVWF CLRF CLRF CLRF RETLW POL24

0x7E AEXP,W _Z EXP1024L AARGB0,MSB-1 EXP1024HL EXP24HH,3,0 EARGB3,W AEXP,F 0x00 EXP24HL,3,0 EARGB3,W AEXP,F 0x00 0x7D AEXP,W _Z EXP1024LL EXP24LH,3,0 EARGB3,W AEXP,F 0x00 EXP24LL,3,0 ; minimax approximation ; minimax approximation ; minimax approximation ; minimax approximation

EARGB3,W AEXP,F DARGB3,RND 0x00 FPFLAGS,RND RND3224 EXPBIAS AEXP AARGB0 AARGB1 AARGB2 0x00 ; restore rounding flag ; return e**x = 1.0

; ; ;

************************************************************* Range reduction routine for the exponential function x/log10(2) = z + n

RREXP1024 MOVF MOVWF BSF MOVF MOVWF MOVF MOVWF MOVLW 9489 MOVWF MOVLW MOVWF MOVLW MOVWF BSF PCLATH,3 1 BCF PCLATH,4 CALL INCF INCF BTFSC GOTO RLF RLF RLF RLF DECF RREXP1024YOK BTFSS BCF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF BSF PCLATH,3 age 1 BCF PCLATH,4 CALL MOVF MOVWF MOVF MOVWF MOVF MOVWF BCF PCLATH,3 BCF PCLATH,4 CALL FLOOR24 AEXP,W DEXP AARGB0,W DARGB0 AARGB1,W DARGB1 ; save k in DARG DARGB0,MSB AARGB0,MSB AEXP,W BEXP AARGB0,W BARGB0 AARGB1,W BARGB1 AARGB2,W BARGB2 ; save y in BARG FXM2416U AEXP,F AEXP,F AARGB0,MSB RREXP1024YOK AARGB3,F AARGB2,F AARGB1,F AARGB0,F AEXP,F ; when we call FXM2416U ; x * (1/log10(2)) AARGB0 0x9A AARGB1 0x78 AARGB2 ; make sure we will stay in page AARGB0,W DARGB0 AARGB0,MSB AARGB0,W BARGB0 AARGB1,W BARGB1 0xD4 ; 1/log10(2) = 3.3219280

; make sure we stay in p

; prepare to swing down to page 0 INT2416 ; k = [ x * (1/ln2) ]

MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF CLRF MOVLW XORWF BSF PCLATH,3 BCF PCLATH,4 CALL MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF ; ;

AARGB1,W EARGB3 DEXP,W AEXP DARGB0,W AARGB0 DARGB1,W AARGB1 AARGB2 0x80 AARGB0,F

; save k in EARG

; make sure we'll stay in page1 ; when we call FPA32 FPA32 AEXP,W DEXP AARGB0,W DARGB0 AARGB1,W DARGB1 AARGB2,W DARGB2 ; save y in DARG

RETLW 0x00 ------------------------------------------------------------------third degree minimax polynomial coefficients for 2**(x) on [.75,1] EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU 0x7E 0x7D 0xB4 0x54 0x7E 0x3B 0xC4 0x97 0x7C 0x31 0xE9 0x3C 0x7B 0x50 0x65 0xDC ; EXP24HH0 = .99103284632

EXP24HH0 EXP24HH00 EXP24HH01 EXP24HH02 EXP24HH1 EXP24HH10 EXP24HH11 EXP24HH12 EXP24HH2 EXP24HH20 EXP24HH21 EXP24HH22 EXP24HH3 EXP24HH30 EXP24HH31 EXP24HH32 ;

; EXP24HH1 = .73346850266

; EXP24HH2 = .17374128273

; EXP24HH3 = .10175678143

third degree minimax polynomial coefficients for 2**(x) on [.5,.75] EQU EQU EQU EQU EQU EQU EQU 0x7E 0x7F 0x7E 0x08 0x7E 0x34 0xB3 ; EXP24HL0 = .99801686089

EXP24HL0 EXP24HL00 EXP24HL01 EXP24HL02 EXP24HL1 EXP24HL10 EXP24HL11

; EXP24HL1 = .70586404164

EXP24HL12 EXP24HL2 EXP24HL20 EXP24HL21 EXP24HL22 EXP24HL3 EXP24HL30 EXP24HL31 EXP24HL32 ;

EQU EQU EQU EQU EQU EQU EQU EQU EQU

0x81 0x7C 0x57 0x51 0xF7 0x7B 0x2F 0x3D 0xB5 ; EXP24HL2 = .21027360637

; EXP24HL3 = .85566912730E-1

third degree minimax polynomial coefficients for 2**(x) on [.25,.5] EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU 0x7E 0x7F 0xF2 0x7D 0x7E 0x32 0x09 0x98 0x7C 0x6C 0x52 0x61 0x7B 0x13 0x5C 0x0C ; EXP24LH0 = .99979384559

EXP24LH0 EXP24LH00 EXP24LH01 EXP24LH02 EXP24LH1 EXP24LH10 EXP24LH11 EXP24LH12 EXP24LH2 EXP24LH20 EXP24LH21 EXP24LH22 EXP24LH3 EXP24LH30 EXP24LH31 EXP24LH32 ;

; EXP24LH1 = .69545887384

; EXP24LH2 = .23078300446

; EXP24LH3 = .71952910179E-1

third degree minimax polynomial coefficients for 2**(x) on [0,.25] EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU 0x7E 0x7F 0xFF 0xFB 0x7E 0x31 0x74 0xA1 0x7C 0x75 0x30 0xA0 0x7A 0x77 0xD4 0x08 ; EXP24LL0 = .99999970657

EXP24LL0 EXP24LL00 EXP24LL01 EXP24LL02 EXP24LL1 EXP24LL10 EXP24LL11 EXP24LL12 EXP24LL2 EXP24LL20 EXP24LL21 EXP24LL22 EXP24LL3 EXP24LL30 EXP24LL31 EXP24LL32 ; ; ;

; EXP24LL1 = .69318585159

; EXP24LL2 = .23944330933

; EXP24LL3 = .60504944237E-1

******************************************************************* ******************************************************************* THIS NEXT SECTION COMES FROM FROM FLOOR24.A16 (needed by EXP1024)

; ; ; ; ; ; ; ; ; ; ; ; FLOOR24

Evaluate floor(x) Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 Use: CALL FLOOR24

Output: 24 bit floating point number in AEXP, AARGB0, AARGB1 Result: AARG <-- FLOOR( AARG ) Testing on [-MAXNUM,MAXNUM] from 100000 trials: min Timing: 37 min Error: 0x00 max 55 max 0x00 mean 42.7 mean 0.0 clks rms 0.0 nsb

----------------------------------------------------------------------floor(x) evaluates the largest integer, as a float, not greater than x. CLRF MOVF BTFSC RETLW MOVF MOVWF MOVF MOVWF MOVLW AARGB2 AEXP,W _Z 0x00 AARGB0,W AARGB3 AARGB1,W AARGB4 EXPBIAS AEXP,W TEMPB1 TEMPB1,MSB FLOOR24ZERO 0x10-1 TEMPB0 TEMPB1 TEMPB1,LSB+3 FLOOR24MASKH 0x07 TEMPB0,F LOW FLOOR24MASKTABLE TEMPB0,F HIGH FLOOR24MASKTABLE _C 0x01 PCLATH TEMPB0,W ; divide by eight ; save number of zero bi ; test for zero argument

; save mantissa

; computed unbiased expo

nent SUBWF MOVWF BTFSC GOTO SUBLW MOVWF ts in TEMPB0 MOVWF BTFSC GOTO FLOOR24MASKL MOVLW pointer ANDWF MOVLW ADDWF MOVLW BTFSC ADDLW MOVWF INCF ; get remainder for mask

CALL ANDWF BTFSS n RETLW MOVWF MOVF SUBWF BTFSS GOTO RETLW FLOOR24RNDL COMF MOVWF INCF ADDWF BTFSC INCF BTFSS rryout? RETLW RRF RRF INCFSZ RETLW BCF PCLATH,4 BCF PCLATH,3 GOTO FLOOR24MASKH MOVLW pointer ANDWF MOVLW ADDWF MOVLW BTFSC ADDLW MOVWF INCF CALL ANDWF CLRF BTFSS n RETLW MOVWF MOVF SUBWF BTFSS GOTO MOVF SUBWF BTFSS GOTO

FLOOR24MASKTABLE AARGB1,F AARGB0,MSB 0x00 AARGB7 AARGB4,W AARGB1,W _Z FLOOR24RNDL 0x00 AARGB7,W TEMPB1 TEMPB1,W AARGB1,F _Z AARGB0, F _Z 0x00 AARGB0,F AARGB1,F AEXP,F 0x00 SETFOV24 0x07 TEMPB0,F LOW FLOOR24MASKTABLE TEMPB0,F HIGH FLOOR24MASKTABLE _C 0x01 PCLATH TEMPB0,W FLOOR24MASKTABLE AARGB0,F AARGB1 AARGB0,MSB 0x00 AARGB7 AARGB4,W AARGB1,W _Z FLOOR24RNDH AARGB3,W AARGB0,W _Z FLOOR24RNDH

; access table for mask ; if negative, round dow

; has rounding caused ca

; check for overflow ; prepare to go back to page 0

; get remainder for mask

; access table for mask ; if negative, round dow

RETLW FLOOR24RNDH COMF MOVWF INCF ADDWF BTFSS rryout? RETLW RRF RRF INCFSZ RETLW BCF PCLATH,3 BCF PCLATH,4 GOTO FLOOR24ZERO BTFSC GOTO CLRF CLRF CLRF RETLW FLOOR24MINUSONE MOVLW MOVWF MOVLW MOVWF CLRF RETLW ; ; ;

0x00 AARGB7,W TEMPB1 TEMPB1,W AARGB0,F _C 0x00 AARGB0,F AARGB1,F AEXP,F 0x00 ; prepare to swing back to page 0 SETFOV24 AARGB0,MSB FLOOR24MINUSONE AEXP AARGB0 AARGB1 0x00 0x7F AEXP 0x80 AARGB0 AARGB1 0x00 ; check for overflow

; has rounding caused ca

---------------------------------------------------------------------table for least significant byte requiring masking, using pointer from the remainder of the number of zero bits divided by eight. PCL 0xFF 0xFE 0xFC 0xF8 0xF0 0xE0 0xC0 0x80 0x00

FLOOR24MASKTABLE MOVWF RETLW RETLW RETLW RETLW RETLW RETLW RETLW RETLW RETLW ; ; ; ; ;

*********************************************************************** *********************************************************************** THIS NEXT SECTION COMES FROM RND3224.A16 (RND3224 needed by EXP1024) Nearest neighbor rounding Input: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2

; ; ; ; ; ; ; ; ; RND3224

Use:

CALL

RND3224

Output: 24 bit floating point number in AEXP, AARGB0, AARGB1 Result: AARG <-- RND( AARG ) Testing on [MINNUM,MAXNUM] from 10000 trials: min Timing: 3 min Error: 0 max 17 max 0 mean clks mean 0 nsb

--------------------------------------------------------------------BTFSS RETLW BSF MOVLW ANDWF BTFSC RRF AARGB2,MSB 0x00 _C 0x7F AARGB2,W _Z AARGB1,W AARGB0,W SIGN AARGB0,MSB _Z _C AARGB1,F _Z AARGB0,F ; round ; select even if NSB = 0 ; is NSB < 0x80? ; set carry for rounding

x80 MOVF MOVWF BSF BCF BTFSC INCF BTFSC INCF BTFSS GOTO RRF INCF ) GOTO RND3224OK BCF PCLATH,4 BCF PCLATH,3 SETFOV24 BTFSS BCF tive RETLW ; ; ; ; 0x00 *************************************************************** *************************************************************** THIS NEXT SECTION COMES FROM MATH16.INC FILE SIGN,MSB AARGB0,MSB ; clear sign bit if posi ; but if Z=0 go to RND3223OK ; going to SETFOV24, so prepare ; for just back to page 0 ; save sign ; make MSB explicit

_Z ; has rounding caused carryout? RND3224OK RRF AARGB0,F ; if so, right shift AARGB1,F EXP,F ; test for floating point overflow BTFSS _Z ; if Z=1, go to SETFOV24 (page 0

GOTO RND3224OK

; ;

24 BIT FLOATING POINT CONSTANTS Maximum argument to EXP1024 equ equ equ 0x84 0x1A 0x21 ; 38.531839445 = log10(2**128)

MAXLOG1024EXP MAXLOG1024B0 MAXLOG1024B1 ;

Minimum argument to EXP1024 equ equ equ 0x84 0x97 0xB8 ; -37.9297794537 = log10(2**-126)

MINLOG1024EXP MINLOG1024B0 MINLOG1024B1 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;

****************************************************************** ****************************************************************** THIS NEXT SECTION COMES FROM FXM46.A16 (for the FXM2416U routine, needed by EXP1024) Note that the original version of FXM2416U in turn used the macro UMUL2416L (also in FXM46.A16), but only once. This version incorporates that macro code, 'unrolled'... 24x16 Bit Unsigned Fixed Point Multiply 24x16 -> 40 Input: 24 bit unsigned fixed point multiplicand in AARGB0 16 bit unsigned fixed point multiplier in BARGB0 Use: CALL FXM2416U

Output: 40 bit unsigned fixed point product in AARGB0 Result: AARG <-- AARG x BARG Max Timing: Min Timing: 8+324+2 = 334 clks 8+102 = 110 clks

PM: 8+61+1 = 70 DM: 12 ----------------------------------------------------------------CLRF AARGB3 CLRF AARGB4 MOVF AARGB0,W MOVWF TEMPB0 MOVF AARGB1,W MOVWF TEMPB1 MOVF AARGB2,W MOVWF TEMPB2 MOVLW MOVWF 0x08 LOOPCOUNT BARGB1, F _C ; clear partial product

FXM2416U

; (this is the start of the ; code from the UMUL2416L macro)

LOOPUM2416A RRF BTFSC

GOTO ALUM2416NAP DECFSZ LOOPCOUNT, F GOTO LOOPUM2416A MOVWF LOOPUM2416B RRF BTFSC GOTO DECFSZ GOTO CLRF CLRF CLRF RETLW BLUM2416NAP BCF GOTO ALUM2416NAP BCF GOTO ALOOPUM2416 RRF BTFSS GOTO MOVF ADDWF MOVF BTFSC INCFSZ ADDWF MOVF BTFSC INCFSZ ADDWF ALUM2416NA RRF RRF RRF RRF DECFSZ GOTO MOVLW MOVWF BLOOPUM2416 RRF BTFSS GOTO MOVF ADDWF MOVF BTFSC BARGB0, F _C BLUM2416NA TEMPB2,W AARGB2, F TEMPB1,W _C AARGB0, F AARGB1, F AARGB2, F AARGB3, F LOOPCOUNT, F ALOOPUM2416 0x08 LOOPCOUNT BARGB1, F _C ALUM2416NA TEMPB2,W AARGB2, F TEMPB1,W _C TEMPB1,W AARGB1, F TEMPB0,W _C TEMPB0,W AARGB0, F _C ALUM2416NA _C BLUM2416NA BARGB0, F _C BLUM2416NAP LOOPCOUNT, F LOOPUM2416B AARGB0 AARGB1 AARGB2 0x00 LOOPCOUNT

INCFSZ ADDWF MOVF BTFSC INCFSZ ADDWF BLUM2416NA RRF RRF RRF RRF RRF DECFSZ GOTO macro code RETLW AARGB0, F AARGB1, F AARGB2, F

TEMPB1,W AARGB1, F TEMPB0,W _C TEMPB0,W AARGB0, F

AARGB3, F AARGB4, F LOOPCOUNT, F BLOOPUM2416 0x00

; this is the end of the

;******************************************************************************* *************** ;******************************************************************************* *************** ; THIS NEXT SECTION COMES FROM FXD26.A16 (for FXD3216U, needed by float_as cii) ; note also that UDIV3216L macro is needed by FXD3216U ; ; 32/16 PIC16 FIXED POINT DIVIDE ROUTINES ; ; Input: fixed point arguments in AARG and BARG ; ; Output: quotient AARG/BARG followed by remainder in REM ; ; All timings are worst case cycle counts ; ; It is useful to note that the additional unsigned routines requiring a n on-power of two ; argument can be called in a signed divide application where it is known that the ; respective argument is nonnegative, thereby offering some improvement in ; performance. ; ; Routine Clocks Function ; ; FXD3216S 595 32 bit/16 bit -> 32.16 signed fixed point divide ; ; FXD3216U 703 32 bit/16 bit -> 32.16 unsigned fixed point divide <-- * * ; ; FXD3115U 541 31 bit/15 bit -> 31.15 unsigned fixed point divide ; ;******************************************************************************* *************** ; ; ; Max Timing: Min Timing: PM: 240 16+6*22+21+21+6*22+21+21+6*22+21+21+6*22+21+8 = 699 clks 16+6*21+20+20+6*21+20+20+6*21+20+20+6*21+20+3 = 663 clks DM: 9

UDIV3216L

macro CLRF RLF RLF MOVF SUBWF MOVF BTFSS INCFSZ SUBWF CLRW BTFSS MOVLW SUBWF RLF MOVLW MOVWF

TEMP AARGB0,W REMB1, F BARGB1,W REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F AARGB0, F 7 LOOPCOUNT AARGB0,W REMB1, F REMB0, F TEMP, F BARGB1,W AARGB0,LSB UADD26LA REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F UOK26LA REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F AARGB0, F

LOOPU3216A

RLF RLF RLF RLF MOVF BTFSS GOTO SUBWF MOVF BTFSS INCFSZ SUBWF CLRW BTFSS MOVLW SUBWF GOTO

UADD26LA

ADDWF MOVF BTFSC INCFSZ ADDWF CLRW BTFSC MOVLW ADDWF

UOK26LA RLF DECFSZ GOTO RLF RLF RLF RLF MOVF

LOOPCOUNT, F LOOPU3216A AARGB1,W REMB1, F REMB0, F TEMP, F BARGB1,W

BTFSS GOTO SUBWF MOVF BTFSS INCFSZ SUBWF CLRW BTFSS MOVLW SUBWF GOTO UADD26L8 ADDWF MOVF BTFSC INCFSZ ADDWF CLRW BTFSC MOVLW ADDWF

AARGB0,LSB UADD26L8 REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F UOK26L8 REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F AARGB1, F

UOK26L8 RLF MOVLW MOVWF LOOPU3216B RLF RLF RLF RLF MOVF BTFSS GOTO SUBWF MOVF BTFSS INCFSZ SUBWF CLRW BTFSS MOVLW SUBWF GOTO UADD26LB ADDWF MOVF BTFSC INCFSZ ADDWF CLRW BTFSC MOVLW ADDWF

7 LOOPCOUNT AARGB1,W REMB1, F REMB0, F TEMP, F BARGB1,W AARGB1,LSB UADD26LB REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F UOK26LB REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F AARGB1, F

UOK26LB RLF

DECFSZ GOTO RLF RLF RLF RLF MOVF BTFSS GOTO SUBWF MOVF BTFSS INCFSZ SUBWF CLRW BTFSS MOVLW SUBWF GOTO UADD26L16 ADDWF MOVF BTFSC INCFSZ ADDWF CLRW BTFSC MOVLW ADDWF RLF MOVLW MOVWF LOOPU3216C RLF RLF RLF RLF MOVF BTFSS GOTO SUBWF MOVF BTFSS INCFSZ SUBWF CLRW BTFSS MOVLW SUBWF GOTO UADD26LC ADDWF MOVF BTFSC INCFSZ

LOOPCOUNT, F LOOPU3216B AARGB2,W REMB1, F REMB0, F TEMP, F BARGB1,W AARGB1,LSB UADD26L16 REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F UOK26L16 REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F AARGB2, F 7 LOOPCOUNT AARGB2,W REMB1, F REMB0, F TEMP, F BARGB1,W AARGB2,LSB UADD26LC REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F UOK26LC REMB1, F BARGB0,W _C BARGB0,W

UOK26L16

ADDWF CLRW BTFSC MOVLW ADDWF UOK26LC RLF DECFSZ GOTO RLF RLF RLF RLF MOVF BTFSS GOTO SUBWF MOVF BTFSS INCFSZ SUBWF CLRW BTFSS MOVLW SUBWF GOTO UADD26L24 ADDWF MOVF BTFSC INCFSZ ADDWF CLRW BTFSC MOVLW ADDWF RLF MOVLW MOVWF LOOPU3216D RLF RLF RLF RLF MOVF BTFSS GOTO SUBWF MOVF BTFSS INCFSZ SUBWF CLRW BTFSS

REMB0, F _C 1 TEMP, F AARGB2, F LOOPCOUNT, F LOOPU3216C AARGB3,W REMB1, F REMB0, F TEMP, F BARGB1,W AARGB2,LSB UADD26L24 REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F UOK26L24 REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F AARGB3, F 7 LOOPCOUNT AARGB3,W REMB1, F REMB0, F TEMP, F BARGB1,W AARGB3,LSB UADD26LD REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C

UOK26L24

MOVLW SUBWF GOTO UADD26LD ADDWF MOVF BTFSC INCFSZ ADDWF CLRW BTFSC MOVLW ADDWF

1 TEMP, F UOK26LD REMB1, F BARGB0,W _C BARGB0,W REMB0, F _C 1 TEMP, F AARGB3, F

UOK26LD RLF DECFSZ GOTO BTFSC GOTO MOVF ADDWF MOVF BTFSC INCFSZ ADDWF UOK26L endm

LOOPCOUNT, F LOOPU3216D AARGB3,LSB UOK26L BARGB1,W REMB1, F BARGB0,W _C BARGB0,W REMB0, F

;******************************************************************************* *************** ;******************************************************************************* *************** ; ; RGB3 ; ; ; RGB3 ; ; ; ; ; FXD3216U 32/16 Bit Unsigned Fixed Point Divide 32/16 -> 32.16 Input: 32 bit unsigned fixed point dividend in AARGB0, AARGB1,AARGB2,AA 16 bit unsigned fixed point divisor in BARGB0, BARGB1 Use: CALL FXD3216U

Output: 32 bit unsigned fixed point quotient in AARGB0, AARGB1,AARGB2,AA 16 bit unsigned fixed point remainder in REMB0, REMB1 Result: AARG, REM <-- AARG / BARG Max Timing: Max Timing: 2+699+2 = 703 clks 2+663+2 = 667 clks DM: 9 REMB0 REMB1

PM: 2+240+1 = 243 CLRF CLRF UDIV3216L

RETLW

0x00

;**************************************************************************** ;**************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; THIS SECTION IS TAKEN FROM FLOAT_ASCII.INC (most of it, in fact) to provide Floating Point to ASCII conversion (from AN670) INPUT: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 OUTPUT: ones, tenths, hundredths, thousandths, tenthous (ASCII digit in each) USED: INDF,FSR,AARG,BARG,REMB,digit_count PROCEDURE: The floating point number in AARG is multiplied by 1000 (or 100) Then the product is divided by 10 three times. After each divide, the remainder is kept. After each digit is obtained, 30H is added to it to make it an ASCII representation of that number. Then, the ASCII value is stored in register RAM at the locations specified in the "cblock." Note: The ASCII decimal point is not generated by this routine. You must output the decimal point in the correct decimal position for your application. For this example, the decimal point is after the first digit: ones.

; Note also: in this version, the initial BARG setup with the multiplier ; (10kd, 1kd or 100d) has been moved into the calling prog ram. ; ;**************************************************************************** last_digit set tenthous SIG_FIG equ 5 ;set SIG_FIG equal to the number of ;significant figures in your decimal number ;for example: ones, tenths,hundredths, ;thousandths - requires 4 sig figs ; make sure we will stay in page1 ; when we call FPM32 ;AARG = AARG * BARG (where BARG = 1000d ; also make sure we will stay in page1 ; when we call INT3232 ;AARG <-- INT( AARG ) ;pointer = address of smallest d ;load counter with the number of ;significant figures in the decimal number ;Make the divisor 10.

float_ascii BSF PCLATH,3 BCF PCLATH,4 call FPM32 or 100d) BSF PCLATH,3 BCF PCLATH,4 call INT3232 movlw movwf igit movlw movwf flo_asclp clrf SIG_FIG digit_count BARGB0 last_digit FSR

movlw d'10' movwf BARGB1 BSF PCLATH,3 BCF PCLATH,4 call FXD3216U movf movwf movlw addwf decf REMB1,w INDF 0x30 INDF,f FSR,f

; make sure we will stay in page1 ; when we call FXD3216U ;divide (32 bit fixed) / 10 (to get remainder) ;put remainder in w register ;put number into appropriate digit position ;add 30h to decimal number to convert to ASCII ;move pointer to next digit ; loop back to continue, if not done

decfsz digit_count,f goto flo_asclp return

; ************************************************************************ ***********

Das könnte Ihnen auch gefallen