?? arith.asm
字號:
#define PAGE EJECT
TITLE "General Purpose Math Routines For PIC17C42 : Ver 1.0"
LIST columns=120, WRAP, L=0
;
include "17c42.h"
;
;*******************************************************************
; Define RAM Locations necessary For the "ARITH.ASM"
; RAM locations should be defined before calling the library math
; routines
;*******************************************************************
;
MODE_FAST equ TRUE
SIGNED equ FALSE
;
;*******************************************************************
;
#if MODE_FAST
CBLOCK 0x18
ACCaLO, ACCaHI, ACCbLO, ACCbHI ; Ram Locations for Arithmetic
ACCcLO, ACCcHI, ACCdLO, ACCdHI ; Routines
ENDC
#else
CBLOCK 0x20
ACCaLO, ACCaHI, ACCbLO, ACCbHI
ACCcLO, ACCcHI, ACCdLO, ACCdHI
ENDC
#endif
;
CBLOCK
tempLo, tempHi, count, sign
ENDC
CBLOCK
NumLo, NumHi
iterCnt
ENDC
;
CBLOCK ; RAM locations for "Diff" routine
XnLo, XnHi, Xn_1_Lo
Xn_1_Hi, Xn_2_Lo, Xn_2_Hi
DiffKLo, DiffKHi ; DiffK = h = Step Size
DiffLo, DiffHi
ENDC
;
CBLOCK ; RAM Locations for "Integrate"
X0Lo, X0Hi, X1Lo, X1Hi ; Routine
X2Lo, X2Hi, X3Lo, X3Hi
IntgKLo, IntgKHi ; INTEGRATE CONST = 3*h/8
IntgLo, IntgHi
ENDC
;
;*******************************************************************
;
mulcnd equ ACCaLO
mulplr equ ACCaHI
L_byte equ ACCbLO
H_byte equ ACCbHI
;
_LUPCNT equ 10 ; Set Desired Number of iterations
SqrtLo equ ACCdLO ; for Square Root Routine(NEWTON Iterations)
SqrtHi equ ACCdHI
;
; Define RAM locations for the Random Number Generators
;
RandLo equ ACCaLO
RandHi equ ACCaHI ; 16 bit Pseudo Random Number
GaussHi equ ACCbHI
GaussLo equ ACCbLO ; 16 bit Gaussian distributed number
GaussTmp equ tempLo
;
PAGE
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 locations
; ; 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
;
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
;
PAGE
;*******************************************************************
; 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
;
PAGE
;*******************************************************************
; 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
movfp ACCaLO,wreg
addwf ACCbLO ;addwf lsb
movfp ACCaHI,wreg
addwfc ACCbHI ;addwf msb with carry
return
;
PAGE
;*******************************************************************
; Double Precision Subtraction
;
; Subtraction : 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_sub
; (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_sub
movfp ACCaLO,wreg
subwf ACCbLO
movfp ACCaHI,wreg
subwfb ACCbHI
return
;
PAGE
;*******************************************************************
; Function to negate a 16 bit integer
; The two 8 bit integers are assumed to be in 2 consecutive
; locations. Before calling this routine, FSR0 should be loaded with
; the address of the lower byte.
; Assume that ALUSTA register is set for no autoincrement of
; FSR0.
;*******************************************************************
;
negateAlt
movfp indf0,wreg
bcf _fs1
negw indf0
bsf _fs1
movfp indf0,wreg
clrf indf0
subwfb indf0
return
;
negate
comf indf0
bcf _fs1
incf indf0
bsf _fs1
btfsc _z
decf indf0
comf indf0
return
;
PAGE
;*******************************************************************
; Double Precision Multiplication
;
; ( Optimized for Code : Looped 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_mpyS
; (d) The 32 bit result is in location ( ACCdHI,ACCdLO,ACCdHI,ACCdLO )
;
; 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 msb's) and ACCc(16 lsb's)
;
#if SIGNED
CALL S_SIGN
#endif
;
clrf count
bsf 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
comf ACCdLO
btfsc _z
decf ACCdHI
comf ACCdHI
return
#else
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
;
PAGE
;*******************************************************************
; 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)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -