Math
Math
AN544
Math Utility Routines
These routines have been optimized wherever possible
with a compromise between speed, RAM utilization, and
code size. Some routines (multiplication and division)
are provided in two forms, one optimized for speed and
the other optimized for code size.
INTRODUCTION
This application note provides some utility math routines
for Microchip's second generation of high performance
8-bit microcontroller, the PIC17C42. Three assembly
language modules are provided, namely ARITH.ASM,
BCD.ASM and FXPDIV.ASM. Currently in each file the
following subroutines are implemented:
ARITH.ASM
DOUBLE PRECISION
MULTIPLICATION
BCD.ASM
8-bit binary to 2 digit BCD conversion
16-bit binary to 5 digit BCD conversion
5-bit BCD to 16-bit binary conversion
2 digit BCD addition
FXPDIV.ASM.
The routines that are implementing in this source file are
shown in Table 3.
As more routines are available, they will be added to the
library. The latest routines may be obtained either
through Microchip's bulletin board or by contacting your
nearest Microchip sales office for a copy on a MS-DOS
floppy.
Comments
Program Memory
Instruction Cycles
Scratch RAM
W Register
mpy8x8_F
speed efficient
36
36
used
mpy8x8_S
code efficient
13
69
used
DS00544C-page 1
4-63
4
3
Math Routines
DOUBLE PRECISION DIVISION
The data memory organization is explained in the comment section of the code. Faster execution and code
space saving can be achieved by setting "MODE_FAST
equ TRUE". However, setting MODE_FAST variable to
TRUE restricts that operands and the 32-bit result be in
data RAM locations 0x18 and 0x1F (in this mode,
MOVFP and MOVPF instructions may be used to transfer data to/from any RAM location to addresses less than
0x1F). If MODE_FAST is set to FALSE, there will be no
restriction on the location of the data RAM values used
in this subroutine. However, the code will be slightly
slower and occupies more program memory.
Comments
D_mpyF
Speed Efficient,
Signed Arithmetic
D_mpyF
Program Memory
Instruction Cycles
Scratch RAM
W Register
204
183
used
Speed Efficient,
Unsigned Arithmetic
179
176
used
D_mpyS
Code Efficient,
Signed Arithmetic
52
254
used
D_mpyS
Code Efficient,
Unsigned Arithmetic
21
242
used
Max Cycles
Min. Cycles
Program Memory
16 / 8 Signed
146
135
146
Data Memory
5
16 / 8 Unsigned
196
156
195
16 / 7 Unsigned
130
130
129
15 / 7 Unsigned
125
125
124
16 / 16 Unsigned
214
187
241
16 / 16 Unsigned
244
180
243
16 / 15 Unsigned
197
182
216
16 / 15 Unsigned
191
177
218
32 / 16 Unsigned
414
363
476
32 / 16 Unsigned
485
459
608
32 / 15 Unsigned
390
359
451
31 / 15 Unsigned
383
353
442
DS00544C-page 2
4-64
Math Routines
DOUBLE PRECISION ADDITION AND
SUBTRACTION
Two routines are provided. One performs a 2's complement addition and the other one performs a 2's complement subtraction of two 16-bit binary numbers. These
subroutines are located in ARITH.ASM and printed in
the listing file ARITH.LST. The performance specs are
shown in Table 4.
f(Y) = Y2 - N = 0
Equation 1:
(Y - Y0)2f" f(Y0)
2!
+ ....
(X - Y0)2f" f(Y0)
2!
+ .... = 0
f(Y0) + (X - Y0)f'(Y0) = 0
X = Y + f(Y0)
Therefore,
i.e.,
'f(Y0)
Program Memory
Instruction Cycles
Scratch RAM
W Register
Dadd
used
Dsub
used
Program Memory
Negate
Instruction Cycles
7
Scratch RAM
0
W Register
unused
NegateAlt
used
NegMac
used
AltNegMac
unused
11
11
used
DS00544C-page 3
4-65
Math Routines
case in most of the real world signals). Although this
routine is provided as a tool to implement a PID algorithm for motor control, it can be used as a general
purpose subroutine. This routine uses the so called
3-Point formula to compute the differential of a
sequence of numbers.
Equation 3:
N
Xn-1
2
The routine "Sqrt" in ARITH.ASM implements the above
equation. Equation 3 requires that at first an initial
approximation for the root is known. The better the initial
approximation, the faster the convergence rate would
be. In the "Sqrt" routine, the initial approximation root is
set as N/2. This routine calls the double precision
division routine (D_divS).
The above equation can be approximated using the 3Point formula as given below:
3-Point Formula:
1
f'(t) = df(t)
=
dt
BCD ROUTINES
Three routines are provided for general purpose BCD
arithmetic:
a.
b.
c.
BCD addition
NUMERICAL DIFFERENTIATION
This routine performs numerical differentiation of a sequence of data if the input sequence is assumed to be
piecewise linear with no discontinuances (this is the
Program Memory
Instruction Cycles
Scratch RAM
W Register
Sqrt
22
3300 (approx.)
used
Comments
Program Memory
W Register
BCDtoB
BCD to Binary
30
112
used
B2_BCD_Looped
32
750
used
B2_BCD_Straight
44
572
used
BinBCD
10
62
unused
BCDAdd
BCD addition
used
DS00544C-page 4
4-66
Math Routines
NUMERICAL INTEGRATION
This routine performs numerical integration using Simpson's
Three-Eighths Rule. This is a third order approximation for
the function, whose integral is to be computed at a given
point. Although this routine is provided as a tool to
implement a PID algorithm for motor control, it can be used
as a general purpose subroutine. Given a function f(t), its
integral over a range t0 to t3 is represented as:
t3
f(t)dt. This function is approximated as follows:
t0
4
3
FIGURE 1
15 14 13 12
.......
TABLE 8: DIFFERENTIATION
Name
Comments
Program Memory
Diff
Numerical Differentiation
34
Instruction Cycles
365
Scratch RAM
10
W Register
used
TABLE 9: INTEGRATION
Name
Comments
Program Memory
Integrate
Numerical Integration
39
Instruction Cycles
370
Scratch RAM
12
W Register
used
DS00544C-page 5
4-67
Math Routines
FIGURE 2 - AUTOCORELATION OF THE DATA POINTS GENERATED BY THE RANDOM NUMBER
GENERATOR
Autocorrelation of Data from Random Number Generator
1.20
1.00
0.80
Magnitude 0.60
0.40
0.20
0.00
1
11
21
31 41
51 61
71 81
Sample Number
Comments
Program Memory
Instruction Cycles
Scratch RAM
W Register
Pseudo Random
12
12
used
21
452
used
Number Generator
Gauss
Gaussian Random
Number Generator
100
80
Relative 60
Amplitude
40
20
113
97
81
65
49
33
17
0
Samples
DS00544C-page 6
4-68
Math Routines
APPENDIX A: GENERAL PURPOSE MATH ROUTINES
LISTING FILE OF ARITH.ASM
MPASM B0.54
PAGE 1
General Purpose Math Routines For PIC17C42 : Ver 1.0
0001
#define PAGE
EJECT
TITLE
General Purpose Math Routines For PIC17C42 : Ver 1.0
LIST
P=17C42, C=120, T=ON, L=0, R=DEC
;
include 17c42.h
;
;*******************************************************************
;
Define RAM Locations necessary For the ARITH.ASM
;
RAM locations should be defined before calling the library math
; routines
;*******************************************************************
;
0001
MODE_FAST
equ
TRUE
0000
SIGNED
equ
FALSE
;
;*******************************************************************
;
if MODE_FAST
CBLOCK 0x18
0018 0004
ACCaLO, ACCaHI, ACCbLO, ACCbHI
; Ram Locations for Arithmetic
001C 0004
ACCcLO, ACCcHI, ACCdLO, ACCdHI
;
Routines
ENDC
else
CBLOCK 0x20
ACCaLO, ACCaHI, ACCbLO, ACCbHI
ACCcLO, ACCcHI, ACCdLO, ACCdHI
ENDC
endif
;
CBLOCK
0020 0004
tempLo, tempHi, count, sign
ENDC
CBLOCK
0024 0002
NumLo, NumHi
0026 0001
iterCnt
ENDC
;
CBLOCK
; RAM locations for Diff routine
0027 0003
XnLo, XnHi, Xn_1_Lo
002A 0003
Xn_1_Hi, Xn_2_Lo, Xn_2_Hi
002D 0002
DiffKLo, DiffKHi
; DiffK = h = Step Size
002F 0002
DiffLo, DiffHi
ENDC
;
CBLOCK
; RAM Locations for Integrate
0031 0004
X0Lo, X0Hi, X1Lo, X1Hi
; Routine
0035 0004
X2Lo, X2Hi, X3Lo, X3Hi
0039 0002
IntgKLo, IntgKHi
; INTEGRATE CONST = 3*h/8
003B 0002
IntgLo, IntgHi
ENDC
;
;*******************************************************************
;
0018
mulcnd equ
ACCaLO
0019
mulplr equ
ACCaHI
001A
L_byte
equ
ACCbLO
001B
H_byte
equ
ACCbHI
;
000A
_LUPCNT equ
10
; Set Desired Number of iterations
001E
SqrtLo
equ
ACCdLO
; for Square Root Routine(NEWTON Iterations)
001F
SqrtHi
equ
ACCdHI
;
; Define RAM locations for the Random Number Generators
DS00544C-page 7
4-69
4
3
Math Routines
;
RandLo
RandHi
GaussHi
GaussLo
GaussTmp
;
0018
0019
001B
001A
0020
0000 E02D
0001 E036
0002 E02D
0003 E03B
0004 E02D
0005 E050
0006 E02D
0007 E065
0008 E02D
0009 E119
000A E02D
000B E138
000C
000D
000E
000F
0010
B0F3
0125
B0F6
0124
E27D
0011
0012
0013
0014
0015
B0FF
0119
B0FF
0118
E293
0016
0017
0018
0019
001A
B0FF
0119
B0FF
0118
E2B8
001B
001C
001D
001E
B0FF
010D
B05F
010E
001F
0020
0021
0022
B030
0119
B045
0118
0023 C028
equ
equ
equ
equ
equ
ACCaLO
ACCaHI
ACCbHI
ACCbLO
tempLo
ORG
0x0000
;*******************************************************************
;
Math Routines Test Program
;*******************************************************************
;
;
Load constant values to ACCa & ACCb for testing
;
main
call
loadAB
; result of adding ACCb+ACCa->ACCb
call
D_add
; Here Accb = 81FE
;
call
loadAB
; result of subtracting ACCb - ACCa->ACCb
call
D_sub
; Here Accb = 7E00
;
call
loadAB
; result of multiplying ACCb*ACCa >(ACCd,ACCc)
call
D_mpyS
; Here (ACCd,ACCc) = 00FF 7E01
;
call
loadAB
; result of multiplying ACCb*ACCa->(ACCd,ACCc)
call
D_mpyF
; Here (ACCd,ACCc) = 00FF 7E01
;
call
loadAB
; result of multiplying ACCb/ACCa->(ACCd,ACCc)
call
D_divS
; Here (ACCd,ACCc) = 0040 003f
;
call
loadAB
; result of multiplying ACCb/ACCa->(ACCd,ACCc)
call
D_divF
; Here (ACCd,ACCc) = 0040 003f
;
movlw
0xf3
movwf
NumHi
movlw
0xf6
; Set input test number = 62454
movwf
NumLo
; = F3F6h
call
Sqrt
; result = 00F9h = 249 (in SqrtLo)
;
; exact sqrt(62454) = 249.9
;
movlw
0xff
movwf
mulplr
; multiplier (in mulplr) = 0FF
movlw
0xff
; multiplicand(W Reg )
= 0FF
movwf
mulcnd
call
mpy8x8_F
; The result 0FF*0FF = FE01 is in locations
;
; H_byte & L_byte
movlw
0xff
movwf
mulplr
; multiplier (in mulplr) = 0FF
movlw
0xff
; multiplicand(W Reg )
= 0FF
movwf
mulcnd
call
mpy8x8_S
; The result 0FF*0FF = FE01 is in
;
; H_byte & L_byte
;
Test The Random Number Generators
;
Capture data into trace buffer by TABLE WRITES to a
;
dummy Program Memory location
;
movlw
0xff
movwf
tblptrl
movlw
0x5f
movwf
tblptrh
;
movlw
0x30
movwf
RandHi
movlw
0x45
movwf
RandLo
;
goto
GaussPoint
;
DS00544C-page 8
4-70
Math Routines
0024
0025
0026
0027
E311
A418
AE19
C024
0028
0029
002A
002B
E31E
A41A
AE1B
C028
002C C02C
002D
002E
002F
0030
B001
0119
B0FF
0118
0031
0032
0033
0034
0035
B07F
011B
B0FF
011A
0002
RandPoint
call
Random16
tlwt
_LOW,RandLo
; only for data capture
tablwt
_HIGH,0,RandHi
; using PICMASTER
goto
RandPoint
;
GaussPoint
call
Gauss
tlwt
_LOW,GaussLo
; only for data capture
tablwt _HIGH,0,GaussHi
; using PICMASTER
goto
GaussPoint
;
self
goto
self
; End Of Test Routines
;
loadAB
movlw
0x01
movwf
ACCaHI
movlw
0xff
; loads ACCa = 01FF
movwf
ACCaLO
;
movlw
0x7f
movwf
ACCbHI
movlw
0xFF
; loads ACCb = 7FFF
movwf
ACCbLO
return
;
;*******************************************************************
;
Double Precision Arithmetic Routines
;
;
Routines : Addition, Subtraction, Multiplication ,Division
;
Square Root
;
;
NOTE : MODE_FAST must first be set to either
;
TRUE or FALSE
;
; MODE_FAST determines the RAM address locations of ACCa thru ACCd
;
; If MODE_FAST is set TRUE, data transfers can be done efficiently
; using MOVFP & MOVPF instructions instead of indirectly moving
; at first to W Reg and then to the desired RAM locations
;
;
The speed increase using this way of locating ACCa to
;
ACCd will result in a saving of about 20 Cycles/filter stage
;
In this case ( a 2 stage filter), it is faster by 40 Cycles
;
; If due to other constraints, ACCa thru ACCd cannot be set at
; address 0x18 to 0x1f, then the user is required to set
; MODE_FAST to FALSE
;
;*******************************************************************
;
Double Precision Addition
;
;
Addition : ACCb(16 bits) + ACCa(16 bits) -> ACCb(16 bits)
;
(a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits )
;
(b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits )
;
(c) CALL D_add
;
(d) The result is in location ACCbLO & ACCbHI ( 16 bits )
;
;
Performance :
;
Program Memory : 4 (excluding call & return)
;
Clock Cycles
: 4 (excluding call & return)
;
W Register
: Used
;
Scratch RAM
: 0
;
;*******************************************************************;
;
D_add
DS00544C-page 9
4-71
4
3
Math Routines
0036
0037
0038
0039
003A
6018
0F1A
6019
111B
0002
003B
003C
003D
003E
003F
6018
051A
6019
031B
0002
0040
0041
0042
0043
0044
0045
0046
0047
6000
8D04
2D00
8504
6000
2900
0300
0002
0048
0049
004A
004B
004C
004D
004E
004F
1300
8D04
1500
8504
9A04
0700
1300
0002
movfp
addwf
movfp
addwfc
return
ACCaLO,wreg
ACCbLO
ACCaHI,wreg
ACCbHI
;addwf lsb
;addwf msb with carry
;
;*******************************************************************
;
DS00544C-page 10
4-72
Math Routines
;
;
Performance :
;
Program Memory :
21 (UNSIGNED)
;
52 (SIGNED)
;
Clock Cycles
:
242 (UNSIGNED :excluding CALL & RETURN)
;
:
254 (SIGNED :excluding CALL & RETURN)
;
Scratch RAM
:
1 (used only if SIGNED arithmetic)
;
;
Note : The above timing is the worst case timing, when the
;
register ACCb = FFFF. The speed may be improved if
;
the register ACCb contains a number ( out of the two
;
numbers ) with less number of 1s.
;
;
Double Precision Multiply ( 16x16 -> 32 )
;
( ACCb*ACCa -> ACCb,ACCc ) : 32 bit output with high word
; in ACCd ( ACCdHI,ACCdLO ) and low word in ACCc ( ACCcHI,ACCcLO ).
;********************************************************************
;
D_mpyS
;results in ACCd(16 msbs) and ACCc(16
;
if
CALL
endif
;
0050 2922
0051 8422
0052 5A20
0053 5B21
0054 291F
0055 291E
0056
0057
0058
0059
005A
005B
005C
005D
1921
1920
9004
C05E
6018
0F1E
6019
111F
005E
005F
0060
0061
0062
0063
191F
191E
191D
191C
1722
C056
SIGNED
S_SIGN
clrf
bsf
4
3
count
count,4
; set count = 16
;
if MODE_FAST
movpf
ACCbLO,tempLo
movpf
ACCbHI,tempHi
else
movfp
ACCbLO,wreg
movwf
tempLo
movfp
ACCbHI,wreg
movwf
tempHi
endif
clrf
ACCdHI
clrf
ACCdLO
;
;
shift right and addwf 16 times
;
mpyLoop
rrcf
tempHi
rrcf
tempLo
btfss
_carry
goto
NoAdd
; LSB is 0, so no need to addwf
movfp
ACCaLO,wreg
addwf
ACCdLO
;addwf lsb
movfp
ACCaHI,wreg
addwfc ACCdHI
;addwf msb
NoAdd
rrcf
ACCdHI
rrcf
ACCdLO
rrcf
ACCcHI
rrcf
ACCcLO
decfsz count
goto
mpyLoop
;
if SIGNED
btfss
sign,MSB
return
comf
ACCcLO
incf
ACCcLO
btfsc
_z
decf
ACCcHI
comf
ACCcHI
btfsc
_z
decf
ACCdLO
DS00544C-page 11
4-73
Math Routines
comf
btfsc
decf
comf
return
ACCdLO
_z
ACCdHI
ACCdHI
else
0064 0002
return
endif
;
; Assemble this section only if Signed Arithmetic Needed
;
if
SIGNED
;
S_SIGN
movfp
ACCaHI,wreg
xorwf
ACCbHI,w
movwf
sign
; MSB of sign determines whether signed
btfss
ACCbHI,MSB
; if MSB set go & negate ACCb
goto
chek_A
comf
ACCbLO
incf
ACCbLO
btfsc
_z
; negate ACCb
decf
ACCbHI
comf
ACCbHI
;
chek_A
btfss
ACCaHI,MSB
; if MSB set go & negate ACCa
return
comf
ACCaLO
incf
ACCaLO
btfsc
_z
; negate ACCa
decf
ACCaHI
comf
ACCaHI
return
;
endif
;
;*******************************************************************
;
Double Precision Multiplication
;
;
( Optimized for Speed : straight Line Code )
;
;
Multiplication : ACCb(16 bits) * ACCa(16 bits) -> ACCd,ACCc ( 32 bits )
;
(a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits )
;
(b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits )
;
(c) CALL D_mpy
;
(d) The 32 bit result is in location ( ACCdHI,ACCdLO,ACCdHI,ACCdLO )
;
;
Performance :
;
Program Memory :
179 (UNSIGNED)
;
204 (SIGNED)
;
Clock Cycles
:
176 (UNSIGNED :excluding CALL & RETURN)
;
:
183 (SIGNED :excluding CALL & RETURN)
;
;
Note : The above timing is the worst case timing, when the
;
register ACCb = FFFF. The speed may be improved if
;
the register ACCb contains a number ( out of the two
;
numbers ) with less number of 1s.
;
;
The performance specs are for Unsigned arithmetic ( i.e,
;
with SIGNED equ FALSE ).
;
;
Upon return from subroutine, the input registers
DS00544C-page 12
4-74
Math Routines
;
;
;**********************************************************
;
Multiplication Macro
;**********************************************************
;
mulMac MACRO
variable i
i = 0
if SIGNED
.while i < 15
else
.while i < 16
endif
.if i < 8
btfss
ACCbLO,i
; test low byte
.else
btfss
ACCbHI,i-8
; test high byte
.fi
goto
NoAdd#v(i)
; LSB is 0, so no need to addwf
movfp
ACCaLO,wreg
addwf
ACCdLO
;addwf lsb
movfp
ACCaHI,wreg
addwfc ACCdHI
;addwf msb
NoAdd#v(i)
rrcf
ACCdHI
rrcf
ACCdLO
rrcf
ACCcHI
rrcf
ACCcLO
bcf
_carry
i = i+1
.endw
if SIGNED
rrcf
ACCdHI
rrcf
ACCdLO
rrcf
ACCcHI
rrcf
ACCcLO
bcf
_carry
endif
;
ENDM
;
;***************************************************************
;
Double Precision Negate Macros
;***************************************************************
AltNegMac
MACRO
fileRegLo,fileRegHi
movfp
fileRegLo,wreg
negw
fileRegLo
movfp
fileRegHi,wreg
clrf
fileRegHi
subwfb fileRegHi
ENDM
;
negMac MACRO
fileRegLo, fileRegHi
comf
fileRegLo
; negate FileReg ( -FileReg -> FileReg )
incf
fileRegLo
btfsc
_z
decf
fileRegHi
comf
fileRegHi
ENDM
;
NegMac32
MACRO
x3,x2,x1,x0
movfp
x3,wreg
negw
x3
movfp
x2,wreg
clrf
x2
DS00544C-page 13
4-75
4
3
Math Routines
subwfb
movfp
clrf
subwfb
movfp
clrf
subwfb
0065 291F
0066 291E
0067 8804
0000
0000
0068 901A
x2
x1,wreg
x1
x1
x0,wreg
x0
x0
ENDM
;
;*******************************************************************;
;
Double Precision Multiply ( 16x16 -> 32 )
;
( ACCb*ACCa -> ACCb,ACCc ) : 32 bit output with high word
; in ACCd ( ACCdHI,ACCdLO ) and low word in ACCc ( ACCcHI,ACCcLO ).
;
D_mpyF
;results in ACCd(16 msbs) and ACCc(16
;
if
SIGNED
;
movfp
ACCaHI,wreg
xorwf
ACCbHI,w
movwf
sign
btfss
ACCbHI,MSB
; if MSB set go & negate ACCb
goto
chek_A_MSB_MPY
;
negMac ACCbLO,ACCbHI
;
chek_A_MSB_MPY
btfss
ACCaHI,MSB
; if MSB set go & negate ACCa
goto
continue_MPY
negMac ACCaLO,ACCaHI
;
endif
;
continue_MPY
clrf
ACCdHI
clrf
ACCdLO
bcf
carry
;
;
use the mulMac macro 16 times
;
mulMac
variable i
i = 0
if SIGNED
.while i < 15
else
.while i < 16
endif
.if i < 8
btfss
ACCbLO,i
; test low byte
.else
btfss
ACCbHI,i-8
; test high byte
.fi
goto
NoAdd#v(i)
; LSB is 0, so no need to addwf
movfp
ACCaLO,wreg
addwf
ACCdLO
;addwf lsb
movfp
ACCaHI,wreg
addwfc ACCdHI
;addwf msb
NoAdd#v(i)
rrcf
ACCdHI
rrcf
ACCdLO
rrcf
ACCcHI
rrcf
ACCcLO
bcf
_carry
i = i+1
.endw
.if i < 8
btfss
ACCbLO,i
; test low byte
.else
DS00544C-page 14
4-76
Math Routines
btfss
ACCbHI,i-8
.fi
0069
006A
006B
006C
006D
C06E
6018
0F1E
6019
111F
goto
movfp
addwf
movfp
addwfc
NoAdd0
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
NoAdd0
006E
006F
0070
0071
0072
0001
191F
191E
191D
191C
8804
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
.if i < 8
btfss
ACCbLO,i
; test low byte
.else
btfss
ACCbHI,i-8
; test high byte
0073 911A
.fi
0074
0075
0076
0077
0078
C079
6018
0F1E
6019
111F
goto
movfp
addwf
movfp
addwfc
NoAdd1
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
NoAdd1
0079
007A
007B
007C
007D
0002
191F
191E
191D
191C
8804
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
.if i < 8
btfss
ACCbLO,i
; test low byte
.else
btfss
ACCbHI,i-8
; test high byte
007E 921A
.fi
007F
0080
0081
0082
0083
C084
6018
0F1E
6019
111F
goto
movfp
addwf
movfp
addwfc
NoAdd2
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
NoAdd2
0084
0085
0086
0087
0088
0003
191F
191E
191D
191C
8804
0089 931A
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
.if i < 8
btfss
ACCbLO,i
; test low byte
.else
btfss
ACCbHI,i-8
; test high byte
.fi
008A
008B
008C
008D
008E
C08F
6018
0F1E
6019
111F
goto
movfp
addwf
movfp
addwfc
NoAdd3
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
DS00544C-page 15
4-77
4
3
Math Routines
008F
0090
0091
0092
0093
0004
191F
191E
191D
191C
8804
0094 941A
0095
0096
0097
0098
0099
C09A
6018
0F1E
6019
111F
009A
009B
009C
009D
009E
0005
191F
191E
191D
191C
8804
009F 951A
00A0
00A1
00A2
00A3
00A4
C0A5
6018
0F1E
6019
111F
00A5
00A6
00A7
00A8
00A9
0006
191F
191E
191D
191C
8804
00AA 961A
00AB
00AC
00AD
00AE
00AF
C0B0
6018
0F1E
6019
111F
00B0
00B1
00B2
00B3
00B4
0007
191F
191E
191D
191C
8804
00B5 971A
00B6
00B7
00B8
00B9
00BA
C0BB
6018
0F1E
6019
111F
NoAdd3
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
addwfc
NoAdd4
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
addwfc
NoAdd5
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
addwfc
NoAdd6
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
addwfc
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
ACCbLO,i
ACCbHI,i-8
NoAdd4
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
ACCbLO,i
ACCbHI,i-8
NoAdd5
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
ACCbLO,i
ACCbHI,i-8
NoAdd6
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
ACCbLO,i
ACCbHI,i-8
NoAdd7
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
DS00544C-page 16
4-78
Math Routines
00BB
00BC
00BD
00BE
00BF
0008
191F
191E
191D
191C
8804
00C0 901B
00C1
00C2
00C3
00C4
00C5
C0C6
6018
0F1E
6019
111F
00C6
00C7
00C8
00C9
00CA
0009
191F
191E
191D
191C
8804
00CB 911B
00CC
00CD
00CE
00CF
00D0
C0D1
6018
0F1E
6019
111F
00D1
00D2
00D3
00D4
00D5
000A
191F
191E
191D
191C
8804
00D6 921B
00D7
00D8
00D9
00DA
00DB
C0DC
6018
0F1E
6019
111F
00DC
00DD
00DE
00DF
00E0
000B
191F
191E
191D
191C
8804
00E1 931B
00E2
00E3
00E4
00E5
C0E7
6018
0F1E
6019
NoAdd7
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
addwfc
NoAdd8
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
addwfc
NoAdd9
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
addwfc
NoAdd10
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
ACCbLO,i
ACCbHI,i-8
NoAdd8
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
4
3
ACCbLO,i
ACCbHI,i-8
NoAdd9
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
ACCbLO,i
ACCbHI,i-8
NoAdd10
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
ACCbLO,i
ACCbHI,i-8
NoAdd11
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
;addwf lsb
DS00544C-page 17
4-79
Math Routines
00E6 111F
00E7
00E8
00E9
00EA
00EB
000C
191F
191E
191D
191C
8804
00EC 941B
00ED
00EE
00EF
00F0
00F1
C0F2
6018
0F1E
6019
111F
00F2
00F3
00F4
00F5
00F6
000D
191F
191E
191D
191C
8804
00F7 951B
00F8
00F9
00FA
00FB
00FC
C0FD
6018
0F1E
6019
111F
00FD
00FE
00FF
0100
0101
191F
191E
191D
191C
8804
0102 961B
0103
0104
0105
0106
0107
C108
6018
0F1E
6019
111F
0108
0109
010A
010B
010C
000F
191F
191E
191D
191C
8804
010D 971B
010E
010F
0110
0111
C113
6018
0F1E
6019
addwfc
NoAdd11
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
addwfc
NoAdd12
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
addwfc
NoAdd13
rrcf
rrcf
rrcf
rrcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
addwfc
NoAdd14
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
.if i < 8
btfss
.else
btfss
.fi
goto
movfp
addwf
movfp
ACCdHI
;addwf msb
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
ACCbLO,i
ACCbHI,i-8
NoAdd12
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
ACCbLO,i
ACCbHI,i-8
NoAdd13
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
ACCdHI
ACCdLO
ACCcHI
ACCcLO
ACCbLO,i
ACCbHI,i-8
NoAdd14
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
ACCdHI
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
ACCbLO,i
ACCbHI,i-8
NoAdd15
ACCaLO,wreg
ACCdLO
ACCaHI,wreg
DS00544C-page 18
4-80
Math Routines
0112 111F
0113
0114
0115
0116
0117
0010
addwfc
NoAdd15
rrcf
rrcf
rrcf
rrcf
bcf
i = i+1
if SIGNED
rrcf
rrcf
rrcf
rrcf
bcf
endif
191F
191E
191D
191C
8804
ACCdHI
;addwf msb
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
ACCdHI
ACCdLO
ACCcHI
ACCcLO
_carry
;
;
0118 0002
if SIGNED
btfss
sign,MSB
; negate (ACCc,ACCd)
return
NegMac32 ACCcHI,ACCcLO,ACCdHI, ACCdLO
return
else
return
endif
;
;*******************************************************************
;
Double Precision Division
;
;
( Optimized for Code : Looped Code )
;
;*******************************************************************;
;
Division : ACCb(16 bits) / ACCa(16 bits) -> ACCb(16 bits) with
;
Remainder in ACCc (16 bits)
;
(a) Load the Denominator in location ACCaHI & ACCaLO ( 16 bits )
;
(b) Load the Numerator in location ACCbHI & ACCbLO ( 16 bits )
;
(c) CALL D_div
;
(d) The 16 bit result is in location ACCbHI & ACCbLO
;
(e) The 16 bit Remainder is in locations ACCcHI & ACCcLO
;
;
Performance :
;
Program Memory :
31 (UNSIGNED)
;
39 (SIGNED)
;
Clock Cycles
: 300 (UNSIGNED : excluding CALL & RETURN)
;
: 312 (SIGNED : excluding CALL & RETURN)
;
;
NOTE :
;
The performance specs are for Unsigned arithmetic ( i.e,
;
with SIGNED equ FALSE ).
;
;*******************************************************************
;
Double Precision Divide ( 16/16 -> 16 )
;
;
( ACCb/ACCa -> ACCb with remainder in ACCc ):16 bit output
; with Quotiont in ACCb(ACCbHI,ACCbLO)and Remainder in ACCc (ACCcHI,ACCcLO).
;
;
B/A = (Q) + (R)/A
;
or
B = A*Q + R
;
;
where
B :
Numerator
;
A :
Denominator
;
Q :
Quotiont (Integer Result)
;
R :
Remainder
;
;
Note : Check for ZERO Denominator or Numerator is not performed
;
A ZERO Denominator will produce incorrect results
;
; SIGNED Arithmetic :
; In case of signed arithmetic, if either
DS00544C-page 19
4-81
4
3
Math Routines
0119 8404
011A 8504
011B
011C
011D
011E
011F
0120
2922
8422
291D
291C
291E
291F
0121
0122
0123
0124
0125
0126
0127
0128
0129
012A
012B
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C12C
6018
041C
012C 9004
012D C133
012E
012F
0130
0131
0132
6018
051C
6019
031D
8004
0133
0134
0135
0136
1B1E
1B1F
1722
C121
0137 0002
SIGNED
CALL
S_SIGN
endif
;
clrf
count
bsf
count,4
clrf
ACCcHI
clrf
ACCcLO
clrf
ACCdLO
clrf
ACCdHI
;
; Looped code
;
divLoop
bcf
_carry
rlcf
ACCbLO
rlcf
ACCbHI
rlcf
ACCcLO
rlcf
ACCcHI
movfp
ACCaHI,wreg
subwf
ACCcHI,w
btfss
_z
goto
notz
movfp
ACCaLO,wreg
subwf
ACCcLO,w
notz
btfss
_carry
goto
nosub
subca
movfp
ACCaLO,wreg
subwf
ACCcLO
movfp
ACCaHI,wreg
subwfb
ACCcHI
bsf
_carry
nosub
rlcf
ACCdLO
rlcf
ACCdHI
decfsz
count
goto
divLoop
; set count = 16
;check if a>c
;
if SIGNED
btfss
sign,MSB
return
movlw
ACCcLO
movwf
fsr0
call
negate
movlw
ACCdLO
movwf
fsr0
call
negate
return
else
return
endif
;
;*******************************************************************
;
Double Precision Division
DS00544C-page 20
4-82
Math Routines
;
;
( Optimized for Speed : straight Line Code )
;
;*******************************************************************;
;
Division : ACCb(16 bits) / ACCa(16 bits) -> ACCb(16 bits) with
;
Remainder in ACCc (16 bits)
;
;
(a) Load the Denominator in location ACCaHI & ACCaLO ( 16 bits )
;
(b) Load the Numerator in location ACCbHI & ACCbLO ( 16 bits )
;
(c) CALL D_div
;
(d) The 16 bit result is in location ACCbHI & ACCbLO
;
(e) The 16 bit Remainder is in locations ACCcHI & ACCcLO
;
;
B/A = (Q) + (R)/A
;
or
B = A*Q + R
;
;
where
B :
Numerator
;
A :
Denominator
;
Q :
Quotiont (Integer Result)
;
R :
Remainder
;
;
Note : Check for ZERO Denominator or Numerator is not performed
;
A ZERO Denominator will produce incorrect results
;
;
SIGNED Arithmetic :
;
In case of signed arithmetic, if either
; numerator or denominator is negative, then both Q & R are
; represented as negative numbers
;
-(B/A) = -(Q) + (-R)/A
;
or
-B = (-Q)*A + (-R)
;
;
Performance :
;
Program Memory
: 325 (UNSIGNED)
;
354 (SIGNED)
;
Clock Cycles
: 250 (UNSIGNED : excluding CALL & RETURN)
;
: 260 (SIGNED : excluding CALL & RETURN)
;
;*******************************************************************;
;
division macro
;
divMac MACRO
variable i
i = 0
.while i < 16
;
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
notz#v(i) btfss
goto
subca#v(i) movfp
subwf
movfp
subwfb
bsf
nosub#v(i) rlcf
rlcf
i=i+1
.endw
;
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz#v(i)
ACCaLO,wreg
ACCcLO,w
_carry
nosub#v(i)
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
;check if a>c
DS00544C-page 21
4-83
4
3
Math Routines
0138
0139
013A
013B
291D
291C
291E
291F
0000
ENDM
;
;*******************************************************************
;
Double Precision Divide ( 16/16 -> 16 )
;
;
( ACCb/ACCa -> ACCb with remainder in ACCc ) : 16 bit output
;
with Quotiont in ACCb (ACCbHI,ACCbLO) and Remainder in ACCc
ACCcHI,ACCcLO).
;
;
NOTE: Before calling this routine, the user should make sure that
;
the Numerator(ACCb) is greater than Denominator(ACCa). If
;
the case is not true, the user should scale either Numerator
;
or Denominator or both such that Numerator is greater than
;
the Denominator.
;
;
;*******************************************************************
;
D_divF
;
if
SIGNED
movfp
ACCaHI,wreg
xorwf
ACCbHI,w
movwf
sign
btfss
ACCbHI,MSB
; if MSB set go & negate ACCb
goto
chek_A_MSB_DIV
;
negMac ACCbLO,ACCbHI
;
chek_A_MSB_DIV
btfss
ACCaHI,MSB
; if MSB set go & negate ACCa
goto
continue_DIV
negMac ACCaLO,ACCaHI
endif
;
continue_DIV
clrf
ACCcHI
clrf
ACCcLO
clrf
ACCdLO
clrf
ACCdHI
;
; straight line code : using the macro divMac
;
divMac
variable i
0000
i = 0
.while i < 16
;
bcf
_carry
rlcf
ACCbLO
rlcf
ACCbHI
rlcf
ACCcLO
rlcf
ACCcHI
movfp
ACCaHI,wreg
subwf
ACCcHI,w
;check if a>c
btfss
_z
goto
notz#v(i)
movfp
ACCaLO,wreg
subwf
ACCcLO,w
;if msb equal then check lsb
notz#v(i)
btfss
_carry
;carry set if c>a
goto
nosub#v(i)
; if c < a
subca#v(i) movfp
ACCaLO,wreg
;c-a into c
subwf
ACCcLO
movfp
ACCaHI,wreg
subwfb
ACCcHI
bsf
_carry
;shift a 1 into d (result)
nosub#v(i) rlcf
ACCdLO
rlcf
ACCdHI
DS00544C-page 22
4-84
Math Routines
i=i+1
.endw
;
013C
013D
013E
013F
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
014A
014B
014C
014D
014E
014F
0001
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C147
6018
041C
9004
C14E
6018
051C
6019
031D
8004
1B1E
1B1F
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
015A
015B
015C
015D
015E
015F
0160
0161
0162
0163
0002
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C15B
6018
041C
9004
C162
6018
051C
6019
031D
8004
1B1E
1B1F
0164
0165
0166
0167
0168
0169
016A
016B
016C
016D
016E
016F
0170
0171
0172
0173
0174
0175
0176
0177
0003
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C16F
6018
041C
9004
C176
6018
051C
6019
031D
8004
1B1E
1B1F
notz0
subca0
nosub0
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
;check if a>c
_z
notz0
ACCaLO,wreg
ACCcLO,w
;if msb equal then check lsb
_carry
;carry set if c>a
nosub0
; if c < a
ACCaLO,wreg
;c-a into c
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
;shift a 1 into d (result)
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz1
ACCaLO,wreg
ACCcLO,w
_carry
nosub1
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz2
ACCaLO,wreg
ACCcLO,w
_carry
nosub2
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
i = i+1
;
notz1
subca1
nosub1
;check if a>c
i = i+1
;
notz2
subca2
nosub2
;check if a>c
i = i+1
DS00544C-page 23
4-85
Math Routines
;
0178
0179
017A
017B
017C
017D
017E
017F
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
018A
018B
0004
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C183
6018
041C
9004
C18A
6018
051C
6019
031D
8004
1B1E
1B1F
018C
018D
018E
018F
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
019A
019B
019C
019D
019E
019F
0005
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C197
6018
041C
9004
C19E
6018
051C
6019
031D
8004
1B1E
1B1F
01A0
01A1
01A2
01A3
01A4
01A5
01A6
01A7
01A8
01A9
01AA
01AB
01AC
01AD
01AE
01AF
01B0
01B1
01B2
01B3
0006
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C1AB
6018
041C
9004
C1B2
6018
051C
6019
031D
8004
1B1E
1B1F
notz3
subca3
nosub3
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz3
ACCaLO,wreg
ACCcLO,w
_carry
nosub3
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz4
ACCaLO,wreg
ACCcLO,w
_carry
nosub4
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz5
ACCaLO,wreg
ACCcLO,w
_carry
nosub5
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
_carry
;check if a>c
i = i+1
;
notz4
subca4
nosub4
;check if a>c
i = i+1
;
notz5
subca5
nosub5
;check if a>c
i = i+1
;
01B4 8804
DS00544C-page 24
4-86
Math Routines
01B5
01B6
01B7
01B8
01B9
01BA
01BB
01BC
01BD
01BE
01BF
01C0
01C1
01C2
01C3
01C4
01C5
01C6
01C7
0007
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C1BF
6018
041C
9004
C1C6
6018
051C
6019
031D
8004
1B1E
1B1F
01C8
01C9
01CA
01CB
01CC
01CD
01CE
01CF
01D0
01D1
01D2
01D3
01D4
01D5
01D6
01D7
01D8
01D9
01DA
01DB
0008
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C1D3
6018
041C
9004
C1DA
6018
051C
6019
031D
8004
1B1E
1B1F
01DC
01DD
01DE
01DF
01E0
01E1
01E2
01E3
01E4
01E5
01E6
01E7
01E8
01E9
01EA
01EB
01EC
01ED
01EE
01EF
0009
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C1E7
6018
041C
9004
C1EE
6018
051C
6019
031D
8004
1B1E
1B1F
notz6
subca6
nosub6
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz6
ACCaLO,wreg
ACCcLO,w
_carry
nosub6
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz7
ACCaLO,wreg
ACCcLO,w
_carry
nosub7
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz8
ACCaLO,wreg
ACCcLO,w
_carry
nosub8
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
_carry
ACCbLO
;check if a>c
i = i+1
;
notz7
subca7
nosub7
4
3
;check if a>c
i = i+1
;
notz8
subca8
nosub8
;check if a>c
i = i+1
;
01F0 8804
01F1 1B1A
DS00544C-page 25
4-87
Math Routines
01F2
01F3
01F4
01F5
01F6
01F7
01F8
01F9
01FA
01FB
01FC
01FD
01FE
01FF
0200
0201
0202
0203
000A
1B1B
1B1C
1B1D
6019
041D
9204
C1FB
6018
041C
9004
C202
6018
051C
6019
031D
8004
1B1E
1B1F
0204
0205
0206
0207
0208
0209
020A
020B
020C
020D
020E
020F
0210
0211
0212
0213
0214
0215
0216
0217
000B
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C20F
6018
041C
9004
C216
6018
051C
6019
031D
8004
1B1E
1B1F
0218
0219
021A
021B
021C
021D
021E
021F
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
022A
022B
000C
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C223
6018
041C
9004
C22A
6018
051C
6019
031D
8004
1B1E
1B1F
022C
022D
022E
022F
0230
8804
1B1A
1B1B
1B1C
1B1D
notz9
subca9
nosub9
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz9
ACCaLO,wreg
ACCcLO,w
_carry
nosub9
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz10
ACCaLO,wreg
ACCcLO,w
_carry
nosub10
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz11
ACCaLO,wreg
ACCcLO,w
_carry
nosub11
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
;check if a>c
i = i+1
;
notz10
subca10
nosub10
;check if a>c
i = i+1
;
notz11
subca11
nosub11
;check if a>c
i = i+1
;
DS00544C-page 26
4-88
Math Routines
0231
0232
0233
0234
0235
0236
0237
0238
0239
023A
023B
023C
023D
023E
023F
000D
6019
041D
9204
C237
6018
041C
9004
C23E
6018
051C
6019
031D
8004
1B1E
1B1F
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
024A
024B
024C
024D
024E
024F
0250
0251
0252
0253
000E
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C24B
6018
041C
9004
C252
6018
051C
6019
031D
8004
1B1E
1B1F
0254
0255
0256
0257
0258
0259
025A
025B
025C
025D
025E
025F
0260
0261
0262
0263
0264
0265
0266
0267
000F
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
9204
C25F
6018
041C
9004
C266
6018
051C
6019
031D
8004
1B1E
1B1F
0268
0269
026A
026B
026C
026D
026E
8804
1B1A
1B1B
1B1C
1B1D
6019
041D
notz12
subca12
nosub12
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
ACCaHI,wreg
ACCcHI,w
_z
notz12
ACCaLO,wreg
ACCcLO,w
_carry
nosub12
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz13
ACCaLO,wreg
ACCcLO,w
_carry
nosub13
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
_z
notz14
ACCaLO,wreg
ACCcLO,w
_carry
nosub14
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
bcf
rlcf
rlcf
rlcf
rlcf
movfp
subwf
_carry
ACCbLO
ACCbHI
ACCcLO
ACCcHI
ACCaHI,wreg
ACCcHI,w
;check if a>c
i = i+1
;
notz13
subca13
nosub13
;check if a>c
i = i+1
;
notz14
subca14
nosub14
;check if a>c
i = i+1
;
;check if a>c
DS00544C-page 27
4-89
Math Routines
026F
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
027A
027B
0010
9204
C273
6018
041C
9004
C27A
6018
051C
6019
031D
8004
1B1E
1B1F
027C 027C
notz15
subca15
nosub15
btfss
goto
movfp
subwf
btfss
goto
movfp
subwf
movfp
subwfb
bsf
rlcf
rlcf
_z
notz15
ACCaLO,wreg
ACCcLO,w
_carry
nosub15
ACCaLO,wreg
ACCcLO
ACCaHI,wreg
ACCcHI
_carry
ACCdLO
ACCdHI
btfss
return
negMac
negMac
return
else
return
sign,MSB
i = i+1
;
;
if SIGNED
027C 0002
; negate (ACCc,ACCd)
ACCcLO,ACCcHI
ACCdLO,ACCdHI
endif
;
;*******************************************************************
;
;
Square Root By Newton Raphson Method
;
;
This routine computes the square root of a 16 bit number(with
; low byte in NumLo & high byte in NumHi ). After loading NumLo &
; NumHi with the desired number whose square root is to be computed,
; branch to location Sqrt ( by GOTO Sqrt ). CALL Sqrt cannot
; be issued because the Sqrt function makes calls to Math routines
; and the stack is completely used up.
;
The result = sqrt(NumHi,NumLo) is returned in location SqrtLo.
; The total number of iterations is set to ten. If more iterations
; are desired, change LupCnt equ .10 to the desired value. Also,
; the initial guess value of the square root is given set as
; input/2 ( in subroutine init ). The user may modify this scheme
; if a better initial approximation value is known. A good initial
; guess will help the algorithm converge at a faster rate and thus
; less number of iterations required.
;
Two utility math routines are used by this program : D_divS
; and D_add. These two routines are listed as seperate routines
; under double precision Division and double precision addition
; respectively.
;
; Note : If square root of an 8 bit number is desired, it is probably
; better to have a table look scheme rather than using numerical
; methods.
;
This method is computationally quite intensive and
; slow, but very accurate and the convergence rate is high
;
;
Performance :
;
Program Memory : 22 (excluding D_divS subroutine)
;
Clock Cycles : 3000 (approximately,with 10 iterations)
;
;
The #of cycles depends on Number of Iterations Selected.
; In a lot of cases 5 or less iterations may be sufficient
;
;
;*******************************************************************
;
Newton-Raphson Method
;*************************************************************
027D E28B
Sqrt
call
SqrtInit
DS00544C-page 28
4-90
Math Routines
027E 7A24
027F 7B25
0280 E119
0281
0282
0283
0284
nextIter
if MODE_FAST
movfp
NumLo,ACCbLO
movfp
NumHi,ACCbHI
else
movfp
NumLo,wreg
movwf
ACCbLO
movfp
NumHi,wreg
movwf
ACCbHI
endif
;
call
D_divS
601E
0F18
601F
1119
0285 8804
0286 1919
0287 1918
movfp
addwf
movfp
addwfc
ACCdLO,wreg
ACCaLO
ACCdHI,wreg
ACCaHI
bcf
rrcf
rrcf
_carry
ACCaHI
ACCaLO
decfsz
goto
return
iterCnt
nextIter
;
0288 1726
0289 C27E
028A 0002
028B B00A
028C 0126
028D 7925
028E 7824
028F
0290
0291
0292
8804
1919
1918
0002
; End Sqrt
;
SqrtInit
movlw
_LUPCNT
movwf
iterCnt
; set number of iterations
if MODE_FAST
movfp
NumHi,ACCaHI
movfp
NumLo,ACCaLO
else
movfp
NumHi,wreg
movwf
ACCaHI
movfp
NumLo,wreg
; set initial guess root = NUM/2
movwf
ACCaLO
endif
bcf
_carry
rrcf
ACCaHI
rrcf
ACCaLO
; set initial sqrt = Num/2
return
;
;*******************************************************************
;
8x8 Software Multiplier
;
( Fast Version : Straight Line Code )
;
;
The 16 bit result is stored in 2 bytes
;
; Before calling the subroutine mpy , the multiplier should
; be loaded in location mulplr , and the multiplicand in
; mulcnd . The 16 bit result is stored in locations
; H_byte & L_byte.
;
;
Performance :
;
Program Memory : 36 words
;
# of cycles
: 36
(excluding call & return)
;
Scratch RAM
:
0 locations
;
W Register
: Used
;
; This routine is optimized for speed efficiency ( straight line code
)
; For code efficiency, refer to mult8x8S.asm ( looped code )
;*******************************************************************
;
Define a macro for adding & right shifting
;
multiply
MACRO
variable i
;
i = 0
DS00544C-page 29
4-91
4
3
Math Routines
.while i < 8
btfsc
addwf
rrcf
rrcf
i = i+1 ;
.endw
ENDM
mulplr,i
H_byte
H_byte
L_byte
; End of macro
;
;
mpy8x8_F
0293
0294
0295
0296
291B
291A
6018
8804
clrf
clrf
movfp
bcf
H_byte
L_byte
mulcnd,wreg
_carry
;
0000
0000
0297
0298
0299
029A
0001
029B
029C
029D
029E
0002
029F
02A0
02A1
02A2
0003
02A3
02A4
02A5
02A6
0004
02A7
02A8
02A9
02AA
0005
02AB
02AC
02AD
02AE
0006
02AF
02B0
02B1
02B2
0007
9819
0F1B
191B
191A
02B3
02B4
02B5
02B6
0008
9F19
0F1B
191B
191A
9919
0F1B
191B
191A
9A19
0F1B
191B
191A
9B19
0F1B
191B
191A
9C19
0F1B
191B
191A
9D19
0F1B
191B
191A
9E19
0F1B
191B
191A
multiply
variable i
i = 0
.while i < 8
btfsc
addwf
rrcf
rrcf
i = i+1
.endw
btfsc
addwf
rrcf
rrcf
i = i+1
btfsc
addwf
rrcf
rrcf
i = i+1
btfsc
addwf
rrcf
rrcf
i = i+1
btfsc
addwf
rrcf
rrcf
i = i+1
btfsc
addwf
rrcf
rrcf
i = i+1
btfsc
addwf
rrcf
rrcf
i = i+1
btfsc
addwf
rrcf
rrcf
i = i+1
btfsc
addwf
rrcf
rrcf
i = i+1
mulplr,i
H_byte
H_byte
L_byte
;
mulplr,i
H_byte
H_byte
L_byte
;
mulplr,i
H_byte
H_byte
L_byte
;
mulplr,i
H_byte
H_byte
L_byte
;
mulplr,i
H_byte
H_byte
L_byte
;
mulplr,i
H_byte
H_byte
L_byte
;
mulplr,i
H_byte
H_byte
L_byte
;
mulplr,i
H_byte
H_byte
L_byte
;
mulplr,i
H_byte
H_byte
L_byte
;
;
return
DS00544C-page 30
4-92
Math Routines
02B8
02B9
02BA
02BB
02BC
02BD
291B
291A
2922
8322
6018
8804
02BE
02BF
02C0
02C1
02C2
02C3
02C4
9819
0F1B
191B
191A
2119
1722
C2BE
02C5 0002
;
;*******************************************************************
;
8x8 Software Multiplier
;
( Code Efficient : Looped Code )
;
;
The 16 bit result is stored in 2 bytes
;
; Before calling the subroutine mpy , the multiplier should
; be loaded in location mulplr , and the multiplicand in
; mulcnd . The 16 bit result is stored in locations
; H_byte & L_byte.
;
;
Performance :
;
Program Memory : 13 words (excluding call & return)
;
# of cycles
: 69
(excluding call & return)
;
Scratch RAM
: 1 byte
;
W Register
: Used
;
; This routine is optimized for code efficiency ( looped code )
; For time efficiency code refer to mult8x8F.asm (straight line code)
;*******************************************************************
;
mpy8x8_S
clrf
H_byte
clrf
L_byte
clrf
count
bsf
count,3
; set count = 8
movfp
mulcnd,wreg
bcf
_carry
; Clear the carry bit in the status Reg.
loop
btfsc
mulplr,0
addwf
H_byte
rrcf
H_byte
rrcf
L_byte
rrncf
mulplr
decfsz
count
goto
loop
;
return
;
;*******************************************************************
;
Numerical Differenciation
;
;
The so called Three-Point Formula is implemented to
; differenciate a sequence of points (uniformly sampled).
;
The eqn implemented is :
;
f(Xn) = [ f(Xn - 2h) - 4*f(Xn - h) + 3*f(Xn)]*0.5/h
;
where Xn is the present sample and h is the step size.
;
;
The above formula may be rewritten as :
;
;
f(Xn) = [ 0.5*f(Xn -2) - 2*f(Xn - 1) + 0.5*3*f(Xn)]*1/DiffK
; where DiffK = h = Step Size
;
;
This differenciation routine can be used very effectively
; in the computation of the differential component part in
; a PID Loop calculation in Motor Control Applications
;
;
Double precision arithmetic is used throught
; The present sample value is assumed to be in locations
; (XnHi, XnLo). The past two values are assumed to be in locations
; (Xn_1_Hi, Xn_1_Lo) & (Xn_2_Hi, Xn_2_Lo).
;
The output value is located in DiffHi & DiffLo. No overflow
; checking mechanism is implemented. If the values are limited
; to 12 bits, then the user need not worry about overflows
;
; It is users responsibility to update the past values with the
; present values before calling this routine.
; After computation, the present value Xn is not moved to Xn_1
DS00544C-page 31
4-93
4
3
Math Routines
02C6
02C7
02C8
02C9
02CA
02CB
602B
0E27
011A
602C
1028
011B
02CC
02CD
02CE
02CF
02D0
02D1
02D2
02D3
6027
0F1A
6028
111B
6027
0F1A
6028
111B
02D4 8804
02D5 191B
02D6 191A
; because the user may want these values to be intact for other
; computations ( say numerical integration)
;
Also it is users responsibility to set past 2 values
; (Xn_1 & Xn_2) values to be zero on initialization.
;
;*******************************************************************
;
Diff
movfp
Xn_2_Lo,wreg
addwf
XnLo,w
movwf
ACCbLO
movfp
Xn_2_Hi,wreg
addwfc
XnHi,w
movwf
ACCbHI
; Y = f(Xn-2) + f(Xn)
;
movfp
XnLo,wreg
addwf
ACCbLO
movfp
XnHi,wreg
addwfc
ACCbHI
movfp
XnLo,wreg
addwf
ACCbLO
movfp
XnHi,wreg
addwfc
ACCbHI
; Y = f(Xn-2) + 3*f(Xn)
;
bcf
_carry
rrcf
ACCbHI
rrcf
ACCbLO
; Y = 0.5*[ f(Xn-2) + 3*f(Xn) ]
;
02D7
02D8
02D9
02DA
02DB
02DC
02DD
02DE
6029
051A
602A
031B
6029
051A
602A
031B
movfp
subwf
movfp
subwfb
movfp
subwf
movfp
subwfb
Xn_1_Lo,wreg
ACCbLO
Xn_1_Hi,wreg
ACCbHI
Xn_1_Lo,wreg
ACCbLO
Xn_1_Hi,wreg
ACCbHI
movfp
movwf
movfp
movwf
DiffKLo,wreg
ACCaLO
DiffKHi,wreg
ACCaHI
call
movfp
movwf
movfp
movwf
D_divS
ACCbLO,wreg
DiffLo
ACCbHI,wreg
DiffHi
;
02DF
02E0
02E1
02E2
602D
0118
602E
0119
02E3
02E4
02E5
02E6
02E7
E119
601A
012F
601B
0130
; result = Y/h
;
02E8 0002
return
;
;*******************************************************************
;
;
Numerical Integration
;
;
;
Simpsons Three-Eighths Rule is implemented
;
;
Y(n) = [ f(X0) + 3*f(X1) + 3*f(X2) + f(X3)]*3*h/8
;
; where h is the step size and the integral is over the
; range X0 to X3
;
The above equation can be rewritten as
;
;
Y(n) = [ f(X0) + 3*f(X1) + 3*f(X2) + f(X3)]*IntgK
;
;
where IntgK = 3*h/8 (in locations (IntgKHi, IntgKHi)
;
;
This Integration routine can be used very effectively
DS00544C-page 32
4-94
Math Routines
02E9
02EA
02EB
02EC
02ED
02EE
6031
0E37
011A
6032
1038
011B
02EF
02F0
02F1
02F2
02F3
02F4
02F5
02F6
02F7
02F8
02F9
02FA
6033
0F1A
6034
111B
6033
0F1A
6034
111B
6033
0F1A
6034
111B
02FB
02FC
02FD
02FE
02FF
0300
0301
0302
0303
0304
0305
0306
6035
0F1A
6036
111B
6035
0F1A
6036
111B
6035
0F1A
6036
111B
0307
0308
0309
030A
6039
0118
603A
0119
030B
030C
030D
030E
030F
E050
601E
013B
601F
013C
0310 0002
DS00544C-page 33
4-95
4
3
Math Routines
0311 1A19
0312 0C19
0313 1B00
0314
0315
0316
0317
0318
0319
031A
031B
031C
031D
1D19
1C18
2300
0C19
1D19
B501
1B18
0D18
1B19
0002
031E
031F
0320
0321
0322
2922
8522
291A
291B
2920
0323
0324
0325
0326
0327
0328
E311
6018
0F1A
6019
111B
2900
;*******************************************************************
;
;
Random Number Generator
;
; This routine generates a 16 Bit Pseudo Sequence Random Generator
; It is based on Linear shift register feedback. The sequence
; is generated by (Q15 xorwf Q14 xorwf Q12 xorwf Q3 )
;
;
The 16 bit random number is in location RandHi(high byte)
; & RandLo (low byte)
;
;
Before calling this routine, make sure the initial values
; of RandHi & RandLo are NOT ZERO
;
A good chiose of initial random number is 0x3045
;*******************************************************************
;
Random16
rlcf
RandHi,w
xorwf
RandHi,w
rlcf
wreg
; carry bit = xorwf(Q15,14)
;
swapf
RandHi
swapf
RandLo,w
rlncf
wreg
xorwf
RandHi,w
; LSB = xorwf(Q12,Q3)
swapf
RandHi
andlw
0x01
rlcf
RandLo
xorwf
RandLo
rlcf
RandHi
return
;
;*******************************************************************
;
Gaussian Noise Generator
;
; This routine generates a 16 Bit Gaussian distributed random
; points. This routine calls the routine Random16, which
; generates a psuedo random noise sequence. Gaussian noise
; is computed using the CENTRAL LIMIT THEOREM.
;
The Central Limit Theorem states that the average weighted
; sum of uncorelated samples tends to have a Gaussian distribution
; For practical purposes, the sum could be over a sample size
; of 32 Random numbers. Better results could result if a larger
; sample size is desired. For faster results, a sum over 16 samples
; would also be adequate ( say, for applications like Speech synthesis,
; channel simulations, etc).
;
;
The 16 bit Gaussian distributed point is in locations
; GaussHi & GaussLo
;
;
Before calling this routine, the initial seed of Random
; number should be NON ZERO ( refer to notes on Random16 routine
;
;*******************************************************************
;
Gauss
clrf
count
bsf
count,5
; set Sample size = 32
clrf
GaussLo
clrf
GaussHi
clrf
GaussTmp
;
NextGauss
call
Random16
; get a random value
movfp
RandLo,wreg
addwf
GaussLo
movfp
RandHi,wreg
addwfc GaussHi
clrf
wreg
DS00544C-page 34
4-96
Math Routines
0329 1120
032A 1722
032B C323
addwfc
decfsz
goto
GaussTmp
count
NextGauss
;
032C B005
032D
032E
032F
0330
0331
movlw
GaussDiv16
rrcf
rrcf
rrcf
decfsz
goto
;
return
;
1920
191B
191A
1700
C32D
0332 0002
5
GaussTmp
GaussHi
GaussLo
wreg
GaussDiv16
END
Errors
:
Warnings :
; weghted average
; divide by 32
; End Of arith.asm
0
0
4
3
DS00544C-page 35
4-97
Math Routines
APPENDIX B : BCD ARITHMETIC ROUTINES
LISTING FILE OF BCD.ASM
MPASM B0.54
0001
PAGE
#define PAGE
EJECT
;TITLE
BCD Arithmetic Routines : Ver 1.0
;*******************************************************************
;
BCD Arithmetic Routines
;*******************************************************************
0020
0022
0025
0026
0002
0003
0001
0002
0026
0026
0027
0000 2B21
0001 2B20
0002 E01F
LIST
P=17C42, C=80, L=0, R=DEC
include 17c42.h
CBLOCK
0x20
Lbyte, Hbyte
R2, R1, R0
;must maintain R2, R1, R0 sequence
count
Num1, Num2
ENDC
;
BCD
equ
Num1
Htemp
equ
Num1
Ltemp
equ
Num2
;
ORG
0x0000
;**********************************************************
;
BCD Arithmetic Test Program
;**********************************************************
;
main
setf
Hbyte
setf
Lbyte
;
; 16 bit binary num = 0xfff
call
B2_BCD_Looped
; after conversion the Deci
;
0003 2B21
0004 2B20
0005 E03F
Hbyte
Lbyte
B2_BCD_Straight
movlw
movwf
movlw
movwf
movlw
movwf
0x06
R0
0x55
R1
0x35
R2
call
BCDtoB
movlw
movwf
movlw
movwf
0x99
Num1
0x99
Num2
call
BCDAdd
movlw
call
0x63
BinBCD
;
0006
0007
0008
0009
000A
000B
B006
0124
B055
0123
B035
0122
;
000C E082
;
000D
000E
000F
0010
B099
0126
B099
0127
;
0011 E093
;
;
0012 B063
0013 E015
0014 C014
;
;
self
goto
self
;
;**********************************************************
;
Binary To BCD Conversion Routine (8 bit)
DS00544C-page 36
4-98
Math Routines
0015 2926
0016
0017
0018
0019
001A
B1F6
9004
C01B
1526
C016
001B
001C
001D
001E
B10A
1D26
0926
0002
001F 8404
0020 8504
0021
0022
0023
0024
0025
0026
8804
2925
8425
2924
2923
2922
0027
0028
0029
002A
002B
1B20
1B21
1B22
1B23
1B24
002C 2725
002D 0002
002E B022
002F 0101
0030 E036
0031 1501
0032 E036
;
;
This routine converts the 8 bit binary number in th
; to a 2 digit BCD number in location BCD( compacted BCD Co
;
The least significant digit is returned in location
; the most significant digit is returned in location MSD.
;
;
Performance :
;
Program Memory : 10
;
Clock Cycles
: 62 (worst case when W =
;
( i.e max Decimal nu
;**********************************************************
;
BinBCD
clrf
BCD
again
addlw
-10
btfss
_carry
goto
swapBCD
incf
BCD
goto
again
swapBCD
addlw
10
swapf
BCD
iorwf
BCD
return
;
;**********************************************************
;
Binary To BCD Conversion Routine (16 Bit)
;
(LOOPED Version)
;
;
This routine converts a 16 Bit binary Number to a 5
; BCD Number.
;
;
The 16 bit binary number is input in locations Hbyt
; Lbyte with the high byte in Hbyte.
;
The 5 digit BCD number is returned in R0, R1 and R2
; containing the MSD in its right most nibble.
;
;
Performance :
;
Program Memory : 32
;
Clock Cycles
: 750
;
;**********************************************************
;
B2_BCD_Looped
bsf
_fs0
bsf
_fs1
; set fsr0 for no auto inc
;
bcf
_carry
clrf
count
bsf
count,4
; set count = 16
clrf
R0
clrf
R1
clrf
R2
loop16a
rlcf
Lbyte
rlcf
Hbyte
rlcf
R2
rlcf
R1
rlcf
R0
;
dcfsnz
count
return
adjDEC
movlw
R2
; load R2 as indirect addr
movwf
fsr0
call
adjBCD
;
incf
fsr0
call
adjBCD
4
3
DS00544C-page 37
4-99
Math Routines
;
0033 1501
0034 E036
incf
call
fsr0
adjBCD
;
0035 C027
0036
0037
0038
0039
003A
003B
003C
003D
003E
6000
B103
9B00
0100
6000
B130
9F00
0100
0002
003F 8404
0040 8504
0041
0042
0043
0044
0045
0046
8804
2925
8425
2924
2923
2922
0047
0048
0049
004A
004B
1B20
1B21
1B22
1B23
1B24
004C
004D
004E
004F
2725
0002
B022
0101
0050
0051
0052
0053
0054
0055
0056
0057
6000
B103
9B00
0100
6000
B130
9F00
0100
0058 1501
0059 6000
goto
loop16a
;
adjBCD
movfp
indf0,wreg
addlw
0x03
btfsc
wreg,3
; test if result > 7
movwf
indf0
movfp
indf0,wreg
addlw
0x30
btfsc
wreg,7
; test if result > 7
movwf
indf0
; save as MSD
return
;
;**********************************************************
;
Binary To BCD Conversion Routine (16 Bit)
;
(Partial Straight Line Version)
;
;
This routine converts a 16 Bit binary Number to a 5
; BCD Number.
;
;
The 16 bit binary number is input in locations Hbyt
; Lbyte with the high byte in Hbyte.
;
The 5 digit BCD number is returned in R0, R1 and R2
; containing the MSD in its right most nibble.
;
;
Performance :
;
Program Memory : 44
;
Clock Cycles
: 572
;
;**********************************************************
;
B2_BCD_Straight
bsf
_fs0
bsf
_fs1
; set fsr0 for no auto inc
;
bcf
_carry
clrf
count
bsf
count,4
; set count = 16
clrf
R0
clrf
R1
clrf
R2
loop16b
rlcf
Lbyte
rlcf
Hbyte
rlcf
R2
rlcf
R1
rlcf
R0
;
dcfsnz
count
return
; DONE
movlw
R2
; load R2 as indirect addr
movwf
fsr0
; adjustBCD
movfp
indf0,wreg
addlw
0x03
btfsc
wreg,3
; test if result > 7
movwf
indf0
movfp
indf0,wreg
addlw
0x30
btfsc
wreg,7
; test if result > 7
movwf
indf0
; save as MSD
;
incf
fsr0
; adjustBCD
movfp
indf0,wreg
DS00544C-page 38
4-100
Math Routines
005A
005B
005C
005D
005E
005F
0060
B103
9B00
0100
6000
B130
9F00
0100
addlw
btfsc
movwf
movfp
addlw
btfsc
movwf
0x03
wreg,3
indf0
indf0,wreg
0x30
wreg,7
indf0
;
0061 1501
0062
0063
0064
0065
0066
0067
0068
0069
6000
B103
9B00
0100
6000
B130
9F00
0100
006A C047
006B
006C
006D
006E
B50F
0F20
9804
1521
006F
0070
0071
0072
0073
8804
1A20
0127
1A21
0126
0074
0075
0076
0077
0078
0079
007A
007B
007C
8804
1B20
1B21
8804
1B20
1B21
8804
1B20
1B21
007D
007E
007F
0080
6027
0F20
6026
1121
incf
fsr0
; adjustBCD
movfp
indf0,wreg
addlw
0x03
btfsc
wreg,3
; test if result > 7
movwf
indf0
movfp
indf0,wreg
addlw
0x30
btfsc
wreg,7
; test if result > 7
movwf
indf0
; save as MSD
;
goto
loop16b
;
;**********************************************************
;
BCD To Binary Conversion
;
;
This routine converts a 5 digit BCD number to a 16
; number.
;
The input 5 digit BCD numbers are asumed to be in l
; R0, R1 & R2 with R0 containing the MSD in its right most
;
;
The 16 bit binary number is output in registers Hby
; ( high byte & low byte repectively ).
;
;
The method used for conversion is :
;
input number X = abcde ( the 5 digit BCD nu
;
X = (R0,R1,R2) = abcde = 10[10[10[10a+b]+c]+d]+e
;
;
Performance :
;
Program Memory : 30
;
Clock Cycles
: 112
;
;**********************************************************
;
mpy10b
andlw
addwf
btfsc
incf
mpy10a
bcf
rlcf
movwf
rlcf
movwf
;
bcf
rlcf
rlcf
bcf
rlcf
rlcf
bcf
rlcf
rlcf
;
movfp
addwf
movfp
addwfc
0x0f
Lbyte
_carry
Hbyte
_carry
Lbyte,w
Ltemp
Hbyte,w
Htemp
; multiply by 2
_carry
Lbyte
Hbyte
_carry
Lbyte
Hbyte
_carry
Lbyte
Hbyte
; multiply by 2
; (Htemp,Ltemp) = 2*N
; multiply by 2
; multiply by 2
; (Hbyte,Lbyte) = 8*N
Ltemp,wreg
Lbyte
Htemp,wreg
Hbyte
DS00544C-page 39
4-101
4
3
Math Routines
0081 0002
0082
0083
0084
0085
0086
return
;
;
BCDtoB
clrf
movfp
andlw
movwf
call
;
swapf
call
;
movfp
call
2921
6024
B50F
0120
E06F
0087 1C23
0088 E06B
0089 6023
008A E06B
; (Hbyte,Lbyte) = 10*N
Hbyte
R0,wreg
0x0f
Lbyte
mpy10a
; result = 10a+b
R1,w
mpy10b
; result = 10[10a+b]
R1,wreg
mpy10b
; result = 10[10[10a+b]+c]
swapf
call
R2,w
mpy10b
; result = 10[10[10[10a+b]+
movfp
andlw
addwf
btfsc
incf
R2,wreg
0x0f
Lbyte
_carry
Hbyte
;
008B 1C22
008C E06B
;
008D
008E
008F
0090
0091
6022
B50F
0F20
9804
1521
0092 0002
return
; BCD to binary conversion
;
;**********************************************************
;
;
Unsigned BCD Addition
;
;
This routine performs a 2 Digit Unsigned BCD Additi
; It is assumed that the two BCD numbers to be added are in
; locations Num1 & Num2. The result is the sum of Num1+Num2
; and is stored in location Num2 and the overflow carry is
; in location Num1
;
;
Performance :
;
Program Memory :
5
;
Clock Cycles
:
5
;
;**********************************************************
;
BCDAdd
movfp
Num1,wreg
addwf
Num2,w
; perform binary addition
0093 6026
0094 0E27
0095
0096
0097
0098
; result = 10[10[10[10a+b]
2F27
2926
1B26
0002
daw
clrf
rlcf
return
Num2
Num1
Num1
;
;**********************************************************
;
END
Errors
:
Warnings :
0
0
DS00544C-page 40
4-102
Math Routines
APPENDIX C: FXPDIV.ASM
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
DS00544C-page 41
4-103
4
3
Math Routines
SADD26#v(i)
SOK26#v(i)
SADD268
SOK268
SADD26#v(i)
SOK26#v(i)
SADD2616
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
BARG+B0,WREG
REM+B0
SOK26#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B0
RLCF
i = 9
while i < 16
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
ACC+B1
SOK2616 RLCF
SADD26#v(i)
i = 17
while i < 24
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ACC+B1,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B0,LSB
SADD268
REM+B1
BARG+B0,WREG
REM+B0
SOK268
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B1,LSB
SADD26#v(i)
REM+B1
BARG+B0,WREG
REM+B0
SOK26#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1
ACC+B2,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B1,LSB
SADD2616
REM+B1
BARG+B0,WREG
REM+B0
SOK2616
REM+B1
BARG+B0,WREG
REM+B0
ACC+B2
ACC+B2,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B2,LSB
SADD26#v(i)
REM+B1
BARG+B0,WREG
REM+B0
SOK26#v(i)
REM+B1
BARG+B0,WREG
DS00544C-page 42
4-104
Math Routines
SOK26#v(i)
SADD2624
SOK2624
SADD26#v(i)
SOK26#v(i)
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i = 25
while i < 32
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
BTFSC
GOTO
MOVFP
ADDWF
MOVFP
ADDWFC
REM+B0
ACC+B2
ACC+B3,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B2,LSB
SADD2624
REM+B1
BARG+B0,WREG
REM+B0
SOK2624
REM+B1
BARG+B0,WREG
REM+B0
ACC+B3
ACC+B3,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B3,LSB
SADD26#v(i)
REM+B1
BARG+B0,WREG
REM+B0
SOK26#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B3
4
3
ACC+B3,LSB
SOK26
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
SOK26
endm
UDIV3216 macro
;
restore = 15/20 clks, nonrestore = 11/14 clks
;
Max Timing: 16*15+1+16*20 = 561 clks
;
Min Timing: 16*11+1+16*14 = 401 clks
;
PM: 16*15+1+16*20 = 561
DM: 9
variable
i
i = 0
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
BTFSC
_C
GOTO
UOK26#v(i)
MOVFP
BARG+B1,WREG
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
BCF
_C
UOK26#v(i)
RLCF
ACC+B0
i=i+1
endw
DS00544C-page 43
4-105
Math Routines
UOK26#v(i)
UOK26#v(i)
UOK26#v(i)
i = 8
while i < 16
RLCF
RLCF
RLCF
MOVFP
SUBWF
MOVFP
SUBWFB
BTFSC
GOTO
MOVFP
ADDWF
MOVFP
ADDWFC
BCF
RLCF
i=i+1
endw
CLRF
i = 16
while i < 24
RLCF
RLCF
RLCF
RLCF
MOVFP
SUBWF
MOVFP
SUBWFB
CLRF
SUBWFB
BTFSC
GOTO
MOVFP
ADDWF
MOVFP
ADDWFC
CLRF
ADDWFC
BCF
RLCF
i=i+1
endw
i = 24
while i < 32
RLCF
RLCF
RLCF
RLCF
MOVFP
SUBWF
MOVFP
SUBWFB
CLRF
SUBWFB
BTFSC
GOTO
MOVFP
ADDWF
MOVFP
ADDWFC
CLRF
ADDWFC
BCF
RLCF
i=i+1
endw
endm
ACC+B1,W
REM+B1
REM+B0
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
_C
UOK26#v(i)
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
_C
ACC+B1
TEMP
ACC+B2,W
REM+B1
REM+B0
TEMP
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
_C
UOK26#v(i)
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
_C
ACC+B2
ACC+B3,W
REM+B1
REM+B0
TEMP
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
_C
UOK26#v(i)
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
_C
ACC+B3
DS00544C-page 44
4-106
Math Routines
NDIV3216
macro
;
Max Timing:
10+31*15+6 = 481 clks
;
Min Timing: 10+31*14+6 = 450 clks
;
PM: 10+31*19+6 = 605
DM: 9
variable i
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
CLRF
TEMP,W
SUBWFB
TEMP
RLCF
ACC+B0
i = 1
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
RLCF
TEMP
MOVFP
BARG+B1,WREG
BTFSS
ACC+B0,LSB
GOTO
NADD26#v(i)
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
CLRF
WREG
SUBWFB
TEMP
GOTO
NOK26#v(i)
NADD26#v(i)
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
CLRF
WREG
ADDWFC
TEMP
NOK26#v(i)
RLCF
ACC+B0
i=i+1
endw
RLCF
ACC+B1,W
RLCF
REM+B1
RLCF
REM+B0
RLCF
TEMP
MOVFP
BARG+B1,WREG
BTFSS
ACC+B0,LSB
GOTO
NADD268
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
CLRF
WREG
SUBWFB
TEMP
GOTO
NOK268
NADD268
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
CLRF
WREG
ADDWFC
TEMP
NOK268
RLCF
ACC+B1
i = 9
while i < 16
RLCF
ACC+B1,W
RLCF
REM+B1
RLCF
REM+B0
RLCF
TEMP
MOVFP
BARG+B1,WREG
BTFSS
ACC+B1,LSB
GOTO
NADD26#v(i)
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
4
3
DS00544C-page 45
4-107
Math Routines
NADD26#v(i)
NOK26#v(i)
NADD2616
NOK2616
NADD26#v(i)
NOK26#v(i)
NADD2624
CLRF
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
CLRF
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
CLRF
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
CLRF
ADDWFC
RLCF
i = 17
while i < 24
RLCF
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
CLRF
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
CLRF
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
CLRF
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
WREG
TEMP
NOK26#v(i)
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
ACC+B1
ACC+B2,W
REM+B1
REM+B0
TEMP
BARG+B1,WREG
ACC+B1,LSB
NADD2616
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
NOK2616
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
ACC+B2
ACC+B2,W
REM+B1
REM+B0
TEMP
BARG+B1,WREG
ACC+B2,LSB
NADD26#v(i)
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
NOK26#v(i)
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
ACC+B2
ACC+B3,W
REM+B1
REM+B0
TEMP
BARG+B1,WREG
ACC+B2,LSB
NADD2624
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
NOK2624
REM+B1
BARG+B0,WREG
REM+B0
DS00544C-page 46
4-108
Math Routines
NOK2624
NADD26#v(i)
NOK26#v(i)
CLRF
ADDWFC
RLCF
i = 25
while i < 32
RLCF
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
CLRF
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
CLRF
ADDWFC
RLCF
i=i+1
endw
BTFSC
GOTO
MOVFP
ADDWF
MOVFP
ADDWFC
WREG
TEMP
ACC+B3
ACC+B3,W
REM+B1
REM+B0
TEMP
BARG+B1,WREG
ACC+B3,LSB
NADD26#v(i)
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
NOK26#v(i)
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
ACC+B3
4
3
ACC+B3,LSB
NOK26
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
NOK26
endm
UDIV3215
macro
;
Max Timing:
8+31*12+6 = 386 clks
;
Min Timing:
8+31*11+6 = 355 clks
;
PM: 8+31*14+6 = 448
DM: 8
variable i
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
RLCF
ACC+B0
i = 1
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
BTFSS
ACC+B0,LSB
GOTO
UADD25#v(i)
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
GOTO
UOK25#v(i)
UADD25#v(i)
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
UOK25#v(i)
RLCF
ACC+B0
i=i+1
endw
RLCF
ACC+B1,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
DS00544C-page 47
4-109
Math Routines
UADD258
UOK258
UADD25#v(i)
UOK25#v(i)
UADD2516
UOK2516
UADD25#v(i)
UOK25#v(i)
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i = 9
while i < 16
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i = 17
while i < 24
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
ACC+B0,LSB
UADD258
REM+B1
BARG+B0,WREG
REM+B0
UOK258
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1
ACC+B1,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B1,LSB
UADD25#v(i)
REM+B1
BARG+B0,WREG
REM+B0
UOK25#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1
ACC+B2,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B1,LSB
UADD2516
REM+B1
BARG+B0,WREG
REM+B0
UOK2516
REM+B1
BARG+B0,WREG
REM+B0
ACC+B2
ACC+B2,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B2,LSB
UADD25#v(i)
REM+B1
BARG+B0,WREG
REM+B0
UOK25#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B2
ACC+B3,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B2,LSB
UADD2524
REM+B1
BARG+B0,WREG
REM+B0
DS00544C-page 48
4-110
Math Routines
UADD2524
UOK2524
UADD25#v(i)
UOK25#v(i)
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i = 25
while i < 32
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
BTFSC
GOTO
MOVFP
ADDWF
MOVFP
ADDWFC
UOK2524
REM+B1
BARG+B0,WREG
REM+B0
ACC+B3
ACC+B3,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B3,LSB
UADD25#v(i)
REM+B1
BARG+B0,WREG
REM+B0
UOK25#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B3
ACC+B3,LSB
UOK25
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
UOK25
endm
UDIV3115
macro
;
Max Timing:
5+8+30*12+6 = 379 clks
;
Min Timing:
5+8+30*11+6 = 349 clks
;
PM: 5+8+30*14+6 = 439
DM: 8
variable i
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
RLCF
ACC+B0
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
RLCF
ACC+B0
i = 2
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
BTFSS
ACC+B0,LSB
GOTO
UADD15#v(i)
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
GOTO
UOK15#v(i)
UADD15#v(i)
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
UOK15#v(i)
RLCF
ACC+B0
i=i+1
endw
RLCF
ACC+B1,W
RLCF
REM+B1
DS00544C-page 49
4-111
Math Routines
UADD158
UOK158
UADD15#v(i)
UOK15#v(i)
UADD1516
UOK1516
UADD15#v(i)
UOK15#v(i)
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i = 9
while i < 16
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i = 17
while i < 24
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
REM+B0
BARG+B1,WREG
ACC+B0,LSB
UADD158
REM+B1
BARG+B0,WREG
REM+B0
UOK158
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1
ACC+B1,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B1,LSB
UADD15#v(i)
REM+B1
BARG+B0,WREG
REM+B0
UOK15#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1
ACC+B2,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B1,LSB
UADD1516
REM+B1
BARG+B0,WREG
REM+B0
UOK1516
REM+B1
BARG+B0,WREG
REM+B0
ACC+B2
ACC+B2,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B2,LSB
UADD15#v(i)
REM+B1
BARG+B0,WREG
REM+B0
UOK15#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B2
ACC+B3,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B2,LSB
UADD1524
REM+B1
DS00544C-page 50
4-112
Math Routines
UADD1524
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
UOK1524 RLCF
UADD15#v(i)
UOK15#v(i)
i = 25
while i < 32
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
BTFSC
GOTO
MOVFP
ADDWF
MOVFP
ADDWFC
BARG+B0,WREG
REM+B0
UOK1524
REM+B1
BARG+B0,WREG
REM+B0
ACC+B3
ACC+B3,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B3,LSB
UADD15#v(i)
REM+B1
BARG+B0,WREG
REM+B0
UOK15#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B3
4
3
ACC+B3,LSB
UOK15
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
UOK15
endm
;**********************************************************************************************
;**********************************************************************************************
;
16/16 Bit Division Macros
SDIV1616
macro
;
Max Timing:
5+8+14*12+6 = 187 clks
;
Min Timing:
5+8+14*11+6 = 173 clks
;
PM: 5+8+14*14+6 = 215
DM: 6
variable i
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
RLCF
ACC+B0
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
RLCF
ACC+B0
i = 2
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
BTFSS
ACC+B0,LSB
GOTO
SADD66#v(i)
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
GOTO
SOK66#v(i)
SADD66#v(i)
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
DS00544C-page 51
4-113
Math Routines
SOK66#v(i)
SADD668
SOK668
SADD66#v(i)
SOK66#v(i)
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i = 9
while i < 16
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
BTFSC
GOTO
MOVFP
ADDWF
MOVFP
ADDWFC
ACC+B0
ACC+B1,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B0,LSB
SADD668
REM+B1
BARG+B0,WREG
REM+B0
SOK668
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1
ACC+B1,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B1,LSB
SADD66#v(i)
REM+B1
BARG+B0,WREG
REM+B0
SOK66#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1
ACC+B1,LSB
SOK66
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
SOK66
endm
UDIV1616 macro
;
restore = 15 clks, nonrestore = 11 clks
;
Max Timing: 8*15+8*15 = 240 clks
;
Min Timing: 8*11+8*11 = 176 clks
;
PM: 8*15+8*15 = 240
DM: 6
variable
i
i = 0
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
BTFSC
_C
GOTO
UOK66#v(i)
MOVFP
BARG+B1,WREG
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
BCF
_C
UOK66#v(i)
RLCF
ACC+B0
i=i+1
endw
i = 8
DS00544C-page 52
4-114
Math Routines
while i < 16
RLCF
ACC+B1,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
BTFSC
_C
GOTO
UOK66#v(i)
MOVFP
BARG+B1,WREG
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
BCF
_C
UOK66#v(i)
RLCF
ACC+B1
i=i+1
endw
endm
NDIV1616
macro
;
Max Timing:
9+15*15+6 = 240 clks
;
Min Timing:
9+15*14+6 = 225 clks
;
PM: 9+15*19+6 = 300
DM: 7
variable i
RLCF
ACC+B0,W
RLCF
REM+B1
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
CLRF
TEMP,W
SUBWFB
TEMP
RLCF
ACC+B0
i = 1
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
RLCF
TEMP
MOVFP
BARG+B1,WREG
BTFSS
ACC+B0,LSB
GOTO
NADD66#v(i)
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
CLRF
WREG
SUBWFB
TEMP
GOTO
NOK66#v(i)
NADD66#v(i)
NOK66#v(i)
ADDWF
MOVFP
ADDWFC
CLRF
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
CLRF
SUBWFB
4
3
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
ACC+B0
ACC+B1,W
REM+B1
REM+B0
TEMP
BARG+B1,WREG
ACC+B0,LSB
NADD668
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
DS00544C-page 53
4-115
Math Routines
NADD668
NOK668
NADD66#v(i)
NOK66#v(i)
GOTO
ADDWF
MOVFP
ADDWFC
CLRF
ADDWFC
RLCF
i = 9
while i < 16
RLCF
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
CLRF
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
CLRF
ADDWFC
RLCF
i=i+1
endw
BTFSC
GOTO
MOVFP
ADDWF
MOVFP
ADDWFC
NOK668
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
ACC+B1
ACC+B1,W
REM+B1
REM+B0
TEMP
BARG+B1,WREG
ACC+B1,LSB
NADD66#v(i)
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
NOK66#v(i)
REM+B1
BARG+B0,WREG
REM+B0
WREG
TEMP
ACC+B1
ACC+B1,LSB
NOK66
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
NOK66
endm
UDIV1615
macro
;
Max Timing:
7+15*12+6 = 193 clks
;
Min Timing:
7+15*11+6 = 178 clks
;
PM: 7+15*14+6 = 213
DM: 6
variable i
RLCF
ACC+B0,W
RLCF
REM+B1
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
RLCF
ACC+B0
i = 1
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
BTFSS
ACC+B0,LSB
GOTO
UADD65#v(i)
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
GOTO
UOK65#v(i)
UADD65#v(i)
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
UOK65#v(i)
RLCF
ACC+B0
i=i+1
endw
RLCF
ACC+B1,W
DS00544C-page 54
4-116
Math Routines
UADD658
UOK658
UADD65#v(i)
UOK65#v(i)
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i = 9
while i < 16
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
BTFSC
GOTO
MOVFP
ADDWF
MOVFP
ADDWFC
REM+B1
REM+B0
BARG+B1,WREG
ACC+B0,LSB
UADD658
REM+B1
BARG+B0,WREG
REM+B0
UOK658
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1
ACC+B1,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B1,LSB
UADD65#v(i)
REM+B1
BARG+B0,WREG
REM+B0
UOK65#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1
4
3
ACC+B1,LSB
UOK65
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
UOK65
endm
UDIV1515
macro
;
Max Timing:
5+8+14*12+6 = 187 clks
;
Min Timing:
5+8+14*11+6 = 173 clks
;
PM: 5+8+14*14+6 = 215
DM: 6
variable i
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
RLCF
ACC+B0
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
ADDWF
REM+B1
MOVFP
BARG+B0,WREG
ADDWFC
REM+B0
RLCF
ACC+B0
i = 2
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
BTFSS
ACC+B0,LSB
GOTO
UADD55#v(i)
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
GOTO
UOK55#v(i)
DS00544C-page 55
4-117
Math Routines
UADD55#v(i)
UOK55#v(i)
UADD558
UOK558
UADD55#v(i)
UOK55#v(i)
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
REM+B1
BARG+B0,WREG
REM+B0
ACC+B0
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i = 9
while i < 16
RLCF
RLCF
RLCF
MOVFP
REM+B1
BARG+B0,WREG
REM+B0
UOK558
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1
BTFSS
GOTO
SUBWF
MOVFP
SUBWFB
GOTO
ADDWF
MOVFP
ADDWFC
RLCF
i=i+1
endw
BTFSC
GOTO
MOVFP
ADDWF
MOVFP
ADDWFC
ACC+B1,LSB
UADD55#v(i)
REM+B1
BARG+B0,WREG
REM+B0
UOK55#v(i)
REM+B1
BARG+B0,WREG
REM+B0
ACC+B1
ACC+B1,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B0,LSB
UADD558
ACC+B1,W
REM+B1
REM+B0
BARG+B1,WREG
ACC+B1,LSB
UOK55
BARG+B1,WREG
REM+B1
BARG+B0,WREG
REM+B0
UOK55
endm
;_______________________________________________________________________
;
Extra 16 Bit Divide Macros
DIV1616
macro
;
Timing: restore = 16 clks, nonrestore = 13 clks
16*16 = 256 clks
variable i
i = 0
while i < 16
RLCF
AARG+B1
RLCF
AARG+B0
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
BTFSS
_C
GOTO
RS1616_#v( i )
BSF
AARG+B1,LSB
GOTO
OK1616_#v( i )
RS1616_#v( i ) MOVFP
BARG+B1,WREG
ADDWF
REM+B1
DS00544C-page 56
4-118
Math Routines
MOVFP
ADDWFC
BCF
BARG+B0,WREG
REM+B0
AARG+B1,LSB
OK1616_#v(i)
i=i+1
endw
endm
DIVMAC
macro
;
Timing: restore = 19 clks, nonrestore = 14 clks
16*19 = 304 clks
variable i
i = 0
while i < 16
RLCF
AARG+B1
RLCF
AARG+B0
RLCF
REM+B1
RLCF
REM+B0
MOVFP
BARG+B0,WREG
SUBWF
REM+B0,W
BTFSS
_Z
GOTO
notz#v( i )
MOVFP
BARG+B1,WREG
SUBWF
REM+B1,W
notz#v( i )
BTFSS
_C
GOTO
nosub#v( i )
MOVFP
BARG+B1,WREG
SUBWF
REM+B1
MOVFP
BARG+B0,WREG
SUBWFB
REM+B0
BSF
AARG+B1,LSB
GOTO
ok#v(i)
nosub#v(i)
BCF
AARG+B1,LSB
ok#v(i)
i=i+1
endw
endm
;**********************************************************************************************
;**********************************************************************************************
;
16/08 BIT Division Macros
SDIV1608
macro
;
Max Timing:
3+5+14*8+2 = 122 clks
;
Min Timing:
3+5+14*8+2 = 122 clks
;
PM: 3+5+14*8+2 = 122
DM: 4
variable i
MOVFP
BARG+B0,WREG
SUBWF
REM+B0
RLCF
ACC+B0
RLCF
ACC+B0,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
ADDWF
REM+B0
RLCF
ACC+B0
i = 2
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
BTFSC
ACC+B0,LSB
SUBWF
REM+B0
BTFSS
ACC+B0,LSB
ADDWF
REM+B0
RLCF
ACC+B0
i=i+1
endw
RLCF
ACC+B1,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
BTFSC
ACC+B0,LSB
SUBWF
REM+B0
BTFSS
ACC+B0,LSB
DS00544C-page 57
4-119
4
3
Math Routines
ADDWF
RLCF
i = 9
while i < 16
RLCF
RLCF
MOVFP
BTFSC
SUBWF
BTFSS
ADDWF
RLCF
i=i+1
endw
BTFSS
ADDWF
endm
REM+B0
ACC+B1
ACC+B1,W
REM+B0
BARG+B0,WREG
ACC+B1,LSB
REM+B0
ACC+B1,LSB
REM+B0
ACC+B1
ACC+B1,LSB
REM+B0
UDIV1608 macro
;
restore = 9/15 clks, nonrestore = 8/11 clks
;
Max Timing: 8*9+1+8*15 = 193 clks
max
;
Min Timing: 8*8+1+8*11 = 153 clks
min
;
PM: 8*9+1+8*15 = 193
DM: 4
variable
i
i = 0
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
SUBWF
REM+B0
BTFSC
_C
GOTO
UOK68#v(i)
ADDWF
REM+B0
BCF
_C
UOK68#v(i)
RLCF
ACC+B0
i=i+1
endw
CLRF
TEMP
i = 8
while i < 16
RLCF
ACC+B1,W
RLCF
REM+B0
RLCF
TEMP
MOVFP
BARG+B0,WREG
SUBWF
REM+B0
CLRF
WREG
SUBWFB
TEMP
BTFSC
_C
GOTO
UOK68#v(i)
MOVFP
BARG+B0,WREG
ADDWF
REM+B0
CLRF
WREG
ADDWFC
TEMP
BCF
_C
UOK68#v(i)
RLCF
ACC+B1
i=i+1
endw
endm
NDIV1608
macro
;
Max Timing:
7+15*12+3 = 190 clks
;
Min Timing: 7+15*11+3 = 175 clks
;
PM: 7+15*14+3 = 220
DM: 5
variable i
RLCF
ACC+B0,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
SUBWF
REM+B0
CLRF
TEMP,W
SUBWFB
TEMP
RLCF
ACC+B0
DS00544C-page 58
4-120
Math Routines
NADD68#v(i)
NOK68#v(i)
NADD688
NOK688
NADD68#v(i)
i = 1
while i < 8
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
CLRF
SUBWFB
GOTO
ADDWF
CLRF
ADDWFC
RLCF
i=i+1
endw
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
CLRF
SUBWFB
GOTO
ADDWF
CLRF
ADDWFC
RLCF
i = 9
while i < 16
RLCF
RLCF
RLCF
MOVFP
BTFSS
GOTO
SUBWF
CLRF
SUBWFB
GOTO
ADDWF
CLRF
ADDWFC
ACC+B0,W
REM+B0
TEMP
BARG+B0,WREG
ACC+B0,LSB
NADD68#v(i)
REM+B0
WREG
TEMP
NOK68#v(i)
REM+B0
WREG
TEMP
ACC+B0
ACC+B1,W
REM+B0
TEMP
BARG+B0,WREG
ACC+B0,LSB
NADD688
REM+B0
WREG
TEMP
NOK688
REM+B0
WREG
TEMP
ACC+B1
4
3
ACC+B1,W
REM+B0
TEMP
BARG+B0,WREG
ACC+B1,LSB
NADD68#v(i)
REM+B0
WREG
TEMP
NOK68#v(i)
REM+B0
WREG
TEMP
NOK68#v(i)
RLCF
ACC+B1
i=i+1
endw
BTFSS
ACC+B1,LSB
MOVFP
BARG+B0,WREG
ADDWF
REM+B0
endm
UDIV1607
macro
;
Max Timing:
5+15*8+2 = 127 clks
;
Min Timing:
5+15*8+2 = 127 clks
;
PM: 5+15*8+2 = 127
DM: 4
variable i
RLCF
ACC+B0,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
SUBWF
REM+B0
RLCF
ACC+B0
i = 1
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B0
DS00544C-page 59
4-121
Math Routines
MOVFP
BTFSC
SUBWF
BTFSS
ADDWF
RLCF
BARG+B0,WREG
ACC+B0,LSB
REM+B0
ACC+B0,LSB
REM+B0
ACC+B0
i=i+1
endw
RLCF
ACC+B1,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
BTFSC
ACC+B0,LSB
SUBWF
REM+B0
BTFSS
ACC+B0,LSB
ADDWF
REM+B0
RLCF
ACC+B1
i = 9
while i < 16
RLCF
ACC+B1,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
BTFSC
ACC+B1,LSB
SUBWF
REM+B0
BTFSS
ACC+B1,LSB
ADDWF
REM+B0
RLCF
ACC+B1
i=i+1
endw
BTFSS
ACC+B1,LSB
ADDWF
REM+B0
endm
UDIV1507
macro
;
Max Timing:
3+5+14*8+2 = 122 clks
;
Min Timing:
3+5+14*8+2 = 122 clks
;
PM: 3+5+14*8+2 = 122
DM: 4
variable i
MOVFP
BARG+B0,WREG
SUBWF
REM+B0
RLCF
ACC+B0
RLCF
ACC+B0,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
ADDWF
REM+B0
RLCF
ACC+B0
i = 2
while i < 8
RLCF
ACC+B0,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
BTFSC
ACC+B0,LSB
SUBWF
REM+B0
BTFSS
ACC+B0,LSB
ADDWF
REM+B0
RLCF
ACC+B0
i=i+1
endw
RLCF
ACC+B1,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
BTFSC
ACC+B0,LSB
SUBWF
REM+B0
BTFSS
ACC+B0,LSB
ADDWF
REM+B0
RLCF
ACC+B1
i = 9
while i < 16
RLCF
ACC+B1,W
RLCF
REM+B0
MOVFP
BARG+B0,WREG
DS00544C-page 60
4-122
Math Routines
BTFSC
ACC+B1,LSB
SUBWF
REM+B0
BTFSS
ACC+B1,LSB
ADDWF
REM+B0
RLCF
ACC+B1
i=i+1
endw
BTFSS
ACC+B1,LSB
ADDWF
REM+B0
endm
;**********************************************************************************************
;**********************************************************************************************
;
32/16 Bit Signed Fixed Point Divide 32/16 -> 32.16
;
Input: 32 bit signed fixed point dividend in AARG+B0, AARG+B1,AARG+B2,AARG+B3
;
16 bit unsigned fixed point divisor in BARG+B0, BARG+B1
;
Use:
CALL
FXD3216S
;
Output: 32 bit signed fixed point quotient in AARG+B0, AARG+B1,AARG+B2,AARG+B3
;
16 bit fixed point remainder in REM+B0, REM+B1
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
11+379+3 = 393 clks
A > 0, B > 0
;
14+379+17 = 410 clks
A > 0, B < 0
;
18+379+17 = 414 clks
A < 0, B > 0
;
21+379+3 = 403 clks
A < 0, B < 0
;
Min Timing:
11+349+3 = 363 clks
A > 0, B > 0
;
14+349+17 = 380 clks
A > 0, B < 0
;
18+349+17 = 384 clks
A < 0, B > 0
;
21+349+3 = 373 clks
A < 0, B < 0
;
PM: 21+439+16 = 476
DM: 9
FXD3216S
MOVFP
AARG+B0,WREG
XORWF
BARG+B0,W
MOVWF
SIGN
CLRF
REM+B0
CLRF
REM+B1,W
BTFSS
BARG+B0,MSB
; if MSB set go & negate BARG
GOTO
CA3216S
COMF
BARG+B1
COMF
BARG+B0
INCF
BARG+B1
ADDWFC
BARG+B0
CA3216S
BTFSS
AARG+B0,MSB
; if MSB set go & negate ACCa
GOTO
C3216S
COMF
AARG+B3
COMF
AARG+B2
COMF
AARG+B1
COMF
AARG+B0
INCF
AARG+B3
ADDWFC
AARG+B2
ADDWFC
AARG+B1
ADDWFC
AARG+B0
C3216S SDIV3216
BTFSS
SIGN,MSB
; negate (ACCc,ACCd)
RETLW
0x00
COMF
AARG+B3
COMF
AARG+B2
COMF
AARG+B1
COMF
AARG+B0
CLRF
WREG
INCF
AARG+B3
ADDWFC
AARG+B2
ADDWFC
AARG+B1
ADDWFC
AARG+B0
COMF
REM+B1
COMF
REM+B0
INCF
REM+B1
ADDWFC
REM+B0
RETLW
0x00
;**********************************************************************************************
;**********************************************************************************************
DS00544C-page 61
4-123
4
3
Math Routines
;
32/16 Bit Unsigned Fixed Point Divide 32/16 -> 32.16
;
Input: 32 bit unsigned fixed point dividend in AARG+B0, AARG+B1,AARG+B2,AARG+B3
;
16 bit unsigned fixed point divisor in BARG+B0, BARG+B1
;
Use:
CALL
FXD3216U
;
Output: 32 bit unsigned fixed point quotient in AARG+B0, AARG+B1AARG+B2,AARG+B3
;
16 bit unsigned fixed point remainder in REM+B0, REM+B1
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
2+481+2 = 485 clks
;
Min Timing:
2+450+2 = 459 clks
;
PM: 2+605+1 = 608
DM: 9
FXD3216U
CLRF
REM+B0
CLRF
REM+B1
NDIV3216
RETLW
0x00
;**********************************************************************************************
;**********************************************************************************************
;
32/15 Bit Unsigned Fixed Point Divide 32/15 -> 32.15
;
Input: 32 bit unsigned fixed point dividend in AARG+B0, AARG+B1,AARG+B2,AARG+B3
;
15 bit unsigned fixed point divisor in BARG+B0, BARG+B1
;
Use:
CALL
FXD3215U
;
Output: 32 bit unsigned fixed point quotient in AARG+B0, AARG+B1
;
15 bit unsigned fixed point remainder in REM+B0, REM+B1
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
2+386+2 = 390 clks
;
Min Timing:
2+355+2 = 359 clks
;
PM: 2+448+1 = 451
DM: 8
FXD3215U
CLRF
REM+B0
CLRF
REM+B1
UDIV3215
RETLW
0x00
;**********************************************************************************************
;**********************************************************************************************
;
31/15 Bit Unsigned Fixed Point Divide 31/15 -> 31.15
;
Input: 31 bit unsigned fixed point dividend in AARG+B0, AARG+B1,AARG+B2,AARG+B3
;
15 bit unsigned fixed point divisor in BARG+B0, BARG+B1
;
Use:
CALL
FXD3115U
;
Output: 31 bit unsigned fixed point quotient in AARG+B0, AARG+B1
;
15 bit unsigned fixed point remainder in REM+B0, REM+B1
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
2+379+2 = 383 clks
;
Min Timing:
2+349+2 = 353 clks
;
PM: 2+439+1 = 442
DM: 8
FXD3115U
CLRF
REM+B0
CLRF
REM+B1
UDIV3115
RETLW
0x00
;**********************************************************************************************
;**********************************************************************************************
;
16/16 Bit Signed Fixed Point Divide 16/16 -> 16.16
;
Input: 16 bit fixed point dividend in AARG+B0, AARG+B1
;
16 bit fixed point divisor in BARG+B0, BARG+B1
;
Use:
CALL
FXD1616S
;
Output: 16 bit fixed point quotient in AARG+B0, AARG+B1
;
16 bit fixed point remainder in REM+B0, REM+B1
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
11+187+3 = 201 clks
A > 0, B > 0
;
14+187+13 = 214 clks
A > 0, B < 0
;
14+187+13 = 214 clks
A < 0, B > 0
;
17+187+3 = 207 clks
A < 0, B < 0
;
Min Timing:
11+173+3 = 187 clks
A > 0, B > 0
;
14+173+13 = 200 clks
A > 0, B < 0
;
14+173+13 = 200 clks
A < 0, B > 0
;
17+173+3 = 193 clks
A < 0, B < 0
;
PM: 14+215+12 = 241
DM: 7
FXD1616S
MOVFP
AARG+B0,WREG
XORWF
BARG+B0,W
MOVWF
SIGN
CLRF
REM+B0
CLRF
REM+B1,W
DS00544C-page 62
4-124
Math Routines
BTFSS
GOTO
BARG+B0,MSB
CA1616S
COMF
BARG+B1
COMF
BARG+B0
INCF
BARG+B1
ADDWFC
BARG+B0
CA1616S
BTFSS
AARG+B0,MSB
; if MSB set go & negate ACCa
GOTO
C1616S
COMF
AARG+B1
COMF
AARG+B0
INCF
AARG+B1
ADDWFC
AARG+B0
C1616S SDIV1616
BTFSS
SIGN,MSB
; negate (ACCc,ACCd)
RETLW
0x00
COMF
AARG+B1
COMF
AARG+B0
CLRF
WREG
INCF
AARG+B1
ADDWFC
AARG+B0
COMF
REM+B1
COMF
REM+B0
INCF
REM+B1
ADDWFC
REM+B0
RETLW
0x00
;**********************************************************************************************
;**********************************************************************************************
;
16/16 Bit Unsigned Fixed Point Divide 16/16 -> 16.16
;
Input: 16 bit unsigned fixed point dividend in AARG+B0, AARG+B1
;
16 bit unsigned fixed point divisor in BARG+B0, BARG+B1
;
Use:
CALL
FXD1616U
;
Output: 16 bit unsigned fixed point quotient in AARG+B0, AARG+B1
;
16 bit unsigned fixed point remainder in REM+B0, REM+B1
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
2+240+2 = 244 clks
;
Min Timing:
2+176+2 = 180 clks
;
PM: 2+240+1 = 243
DM: 6
FXD1616U
CLRF
REM+B0
CLRF
REM+B1
UDIV1616
RETLW
0x00
;**********************************************************************************************
;**********************************************************************************************
;
16/15 Bit Unsigned Fixed Point Divide 16/15 -> 16.15
;
Input: 16 bit unsigned fixed point dividend in AARG+B0, AARG+B1
;
15 bit unsigned fixed point divisor in BARG+B0, BARG+B1
;
Use:
CALL
FXD1615U
;
Output: 16 bit unsigned fixed point quotient in AARG+B0, AARG+B1
;
15 bit unsigned fixed point remainder in REM+B0, REM+B1
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
2+193+2 = 197 clks
;
Min Timing:
2+178+2 = 182 clks
;
PM: 2+213+1 = 216
DM: 6
FXD1615U
CLRF
REM+B0
CLRF
REM+B1
UDIV1615
RETLW
0x00
;**********************************************************************************************
;**********************************************************************************************
;
15/15 Bit Unsigned Fixed Point Divide 15/15 -> 15.15
;
Input: 15 bit unsigned fixed point dividend in AARG+B0, AARG+B1
;
15 bit unsigned fixed point divisor in BARG+B0, BARG+B1
;
Use:
CALL
FXD1515U
;
Output: 15 bit unsigned fixed point quotient in AARG+B0, AARG+B1
;
15 bit unsigned fixed point remainder in REM+B0, REM+B1
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
2+187+2 = 191 clks
;
Min Timing:
2+173+2 = 177 clks
DS00544C-page 63
4-125
4
3
Math Routines
;
PM: 2+215+1 = 218
DM: 6
FXD1515U
CLRF
REM+B0
CLRF
REM+B1
UDIV1515
RETLW
0x00
;**********************************************************************************************
;**********************************************************************************************
;
16/8 Bit Signed Fixed Point Divide 16/08 -> 16.08
;
Input: 16 bit fixed point dividend in AARG+B0, AARG+B1
;
8 bit fixed point divisor in BARG+B0
;
Use:
CALL
FXD1608S
;
Output: 16 bit fixed point quotient in AARG+B0, AARG+B1
;
8 bit fixed point remainder in REM+B0
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
10+122+3 = 135 clks
A > 0, B > 0
;
11+122+11 = 144 clks
A > 0, B < 0
;
13+122+11 = 146 clks
A < 0, B > 0
;
14+122+3 = 139 clks
A < 0, B < 0
;
Min Timing:
10+122+3 = 135 clks
A > 0, B > 0
;
11+122+11 = 144 clks
A > 0, B < 0
;
13+122+11 = 146 clks
A < 0, B > 0
;
14+122+3 = 139 clks
A < 0, B < 0
;
PM: 14+122+10 = 146
DM: 5
FXD1608S
MOVFP
AARG+B0,WREG
XORWF
BARG+B0,W
MOVWF
SIGN
CLRF
REM+B0,W
BTFSS
BARG+B0,MSB
; if MSB set go & negate BARG
GOTO
CA1608S
COMF
BARG+B0
INCF
BARG+B0
CA1608S
BTFSS
AARG+B0,MSB
; if MSB set go & negate ACCa
GOTO
C1608S
COMF
AARG+B1
COMF
AARG+B0
INCF
AARG+B1
ADDWFC
AARG+B0
C1608S SDIV1608
BTFSS
SIGN,MSB
; negate (ACCc,ACCd)
RETLW
0x00
COMF
AARG+B1
COMF
AARG+B0
CLRF
WREG
INCF
AARG+B1
ADDWFC
AARG+B0
COMF
REM+B0
INCF
REM+B0
RETLW
0x00
;**********************************************************************************************
;**********************************************************************************************
;
16/8 Bit Unsigned Fixed Point Divide 16/08 -> 16.08
;
Input: 16 bit unsigned fixed point dividend in AARG+B0, AARG+B1
;
8 bit unsigned fixed point divisor in BARG+B0
;
Use:
CALL
FXD1608U
;
Output: 16 bit unsigned fixed point quotient in AARG+B0, AARG+B1
;
8 bit unsigned fixed point remainder in REM+B0
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
1+193+2 = 196 clks
;
Min Timing:
1+153+2 = 156 clks
;
PM: 1+193+1 = 195
DM: 4
FXD1608U
CLRF
REM+B0
UDIV1608
RETLW
0x00
;**********************************************************************************************
;**********************************************************************************************
;
16/7 Bit Unsigned Fixed Point Divide 16/07 -> 16.07
;
Input: 16 bit unsigned fixed point dividend in AARG+B0, AARG+B1
;
7 bit unsigned fixed point divisor in BARG+B0
;
Use:
CALL
FXD1607U
DS00544C-page 64
4-126
Math Routines
;
Output: 16 bit unsigned fixed point quotient in AARG+B0, AARG+B1
;
7 bit unsigned fixed point remainder in REM+B0
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
1+127+2 = 130 clks
;
Min Timing:
1+127+2 = 130 clks
;
PM: 1+127+1 = 129
DM: 4
FXD1607U
CLRF
REM+B0
UDIV1607
RETLW
0x00
;**********************************************************************************************
;**********************************************************************************************
;
15/7 Bit Unsigned Fixed Point Divide 15/07 -> 15.07
;
Input: 15 bit unsigned fixed point dividend in AARG+B0, AARG+B1
;
7 bit unsigned fixed point divisor in BARG+B0
;
Use:
CALL
FXD1507U
;
Output: 15 bit unsigned fixed point quotient in AARG+B0, AARG+B1
;
7 bit unsigned fixed point remainder in REM+B0
;
Result: AARG, REM < AARG / BARG
;
Max Timing:
1+122+2 = 125 clks
;
Min Timing:
1+122+2 = 125 clks
;
PM: 1+122+1 = 124
DM: 4
FXD1507U
CLRF
REM+B0
UDIV1507
RETLW
0x00
END
;**********************************************************************************************
;**********************************************************************************************
DS00544C-page 65
4-127
4
3
Math Routines
DS00544C-page 66
4-128
AMERICAS (continued)
EUROPE
Corporate Office
Microchip Technology Inc.
2355 West Chandler Blvd.
Chandler, AZ 85224-6199
Tel: 602 786-7200 Fax: 602 786-7277
Technical Support: 602 786-7627
Web: http://www.mchip.com/microhip
Atlanta
Microchip Technology Inc.
500 Sugar Mill Road, Suite 200B
Atlanta, GA 30350
Tel: 770 640-0034 Fax: 770 640-0307
Boston
Microchip Technology Inc.
5 Mount Royal Avenue
Marlborough, MA 01752
Tel: 508 480-9990
Fax: 508 480-8575
Chicago
Microchip Technology Inc.
333 Pierce Road, Suite 180
Itasca, IL 60143
Tel: 708 285-0071 Fax: 708 285-0075
Dallas
Microchip Technology Inc.
14651 Dallas Parkway, Suite 816
Dallas, TX 75240-8809
Tel: 214 991-7177 Fax: 214 991-8588
Dayton
Microchip Technology Inc.
35 Rockridge Road
Englewood, OH 45322
Tel: 513 832-2543 Fax: 513 832-2841
Los Angeles
Microchip Technology Inc.
18201 Von Karman, Suite 455
Irvine, CA 92715
Tel: 714 263-1888 Fax: 714 263-1338
New York
Microchip Technology Inc.
150 Motor Parkway, Suite 416
Hauppauge, NY 11788
Tel: 516 273-5305 Fax: 516 273-5335
San Jose
Microchip Technology Inc.
2107 North First Street, Suite 590
San Jose, CA 95131
Tel: 408 436-7950 Fax: 408 436-7955
United Kingdom
Arizona Microchip Technology Ltd.
Unit 6, The Courtyard
Meadow Bank, Furlong Road
Bourne End, Buckinghamshire SL8 5AJ
Tel: 44 0 1628 851077 Fax: 44 0 1628 850259
France
Arizona Microchip Technology SARL
2 Rue du Buisson aux Fraises
91300 Massy - France
Tel: 33 1 69 53 63 20 Fax: 33 1 69 30 90 79
Germany
Arizona Microchip Technology GmbH
Gustav-Heinemann-Ring 125
D-81739 Muenchen, Germany
Tel: 49 89 627 144 0 Fax: 49 89 627 144 44
Italy
Arizona Microchip Technology SRL
Centro Direzionale Colleoni
Palazzo Pegaso Ingresso No. 2
Via Paracelso 23, 20041
Agrate Brianza (MI) Italy
Tel: 39 039 689 9939 Fax: 39 039 689 9883
ASIA/PACIFIC
Hong Kong
Microchip Technology
Unit No. 3002-3004, Tower 1
Metroplaza
223 Hing Fong Road
Kwai Fong, N.T. Hong Kong
Tel: 852 2 401 1200 Fax: 852 2 401 3431
Korea
Microchip Technology
168-1, Youngbo Bldg. 3 Floor
Samsung-Dong, Kangnam-Ku,
Seoul, Korea
Tel: 82 2 554 7200 Fax: 82 2 558 5934
Singapore
Microchip Technology
200 Middle Road
#10-03 Prime Centre
Singapore 188980
Tel: 65 334 8870 Fax: 65 334 8850
Taiwan
Microchip Technology
10F-1C 207
Tung Hua North Road
Taipei, Taiwan, ROC
Tel: 886 2 717 7175 Fax: 886 2 545 0139
JAPAN
Microchip Technology Intl. Inc.
Benex S-1 6F
3-18-20, Shin Yokohama
Kohoku-Ku, Yokohama
Kanagawa 222 Japan
Tel: 81 45 471 6166 Fax: 81 45 471 6122
9/22/95