📄 float1.asm
字号:
#define PAGE EJECT
TITLE "Binary Floating Arithmetic Routines For PIC17C42 : Ver 1.0"
LIST columns=120, WRAP, L=0
;
include "17c42.h"
;
;*******************************************************************
; Binary Floating Point Addition, Subtraction And
; Multiplication Routines
;
; Mantissa = 16 bits
; Exponent = 8 bits ( exponent is binary and not decimal)
; i.e a number ABCD EXP(X) = 0xABCD * (2**X)
;
; Before calling any of the following floating point routines,
; it is required to set Indirect Register 0 ( FSR0 ) for
; No-Autoincrement ( i.e. Set bits FS0 & FS1 in ALUSTA to 1s)
;
;*******************************************************************;
;
CBLOCK 0x20
ACCaLO, ACCaHI, EXPa
ACCbLO, ACCbHI, EXPb
ACCcLO, ACCcHI
ACCdLO, ACCdHI
temp, sign
ENDC
;
Mode16 equ TRUE ; Change this to FALSE for 32 bit product
PAGE
;
ORG 0x0000
;
;*******************************************************************
; Floating Point Routines Test Program
;*******************************************************************
;
main
;
bsf _fs0 ; set FSR0 for no autoincrement
bsf _fs1
;
call loadAB ; result of adding ACCb(EXPb)+ACCa(EXPa)->ACCb(EXPb)
call F_add ; Here Accb = 403F, EXPb = 07
;
call loadAB ; result of subtracting ACCb(EXPb)-ACCa(EXPa)->ACCb(EXPb)
call F_sub ; Here Accb = 7F7F, EXPb = 06
;
call loadAB ; result of multiplying ACCb(EXPb) * ACCa(EXPa)->ACCb(EXPb)
call F_mpy ; Here ACCb = FF7E, EXPb = 12
;
self goto self
;
; Load constant values to (ACCa, EXPa) & (ACCb, EXPb) for testing
;
loadAB
movlw 0x01
movwf ACCaHI
movlw 0xff ; loads ACCa = 01FF EXP(4)
movwf ACCaLO
movlw 0x04
movwf EXPa
;
movlw 0x7f
movwf ACCbHI
movlw 0xff ; loads ACCb = 7fff EXP(6)
movwf ACCbLO
movlw 0x06
movwf EXPb
return
;
PAGE
;*******************************************************************
; Floating Point Subtraction ( ACCb - ACCa -> ACCb )
;
; Subtraction : ACCb(16 bits) - ACCa(16 bits) -> ACCb(16 bits)
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits ) with
; the 8 bit exponent in EXPa .
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits ) with
; the 8 bit exponent in EXPb .
; (c) CALL F_sub
; (d) The result is in location ACCbLO & ACCbHI ( 16 bits ) with
; the 8 bit exponent in EXPb.
;
;*******************************************************************;
;
F_sub
movlw ACCaLO
movwf fsr0
call negate ; At first negate ACCa; Then addwf
;
;*******************************************************************
; Floating Point Addition ( ACCb + ACCa -> ACCb )
;
; Addition : ACCb(16 bits) + ACCa(16 bits) -> ACCb(16 bits)
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits ) with
; the 8 bit exponent in EXPa.
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits ) with
; the 8 bit exponent in EXPb.
; (c) CALL F_add
; (d) The result is in location ACCbLO & ACCbHI ( 16 bits ) with
; the 8 bit exponent in EXPb
;
;*******************************************************************
;
F_add
movfp EXPa,wreg
cpfseq EXPb
goto Lbl1
goto noAddNorm ; if exponents are equal
Lbl1
cpfslt EXPb
call F_swap ; if B > A then swap ( A<->B )
movfp EXPa,wreg
subwf EXPb
scloop
call addNorm
incfsz EXPb
goto scloop
movfp EXPa,wreg
movwf EXPb
noAddNorm
movfp ACCaHI,wreg
iorwf ACCbHI,w
movwf sign ; save the sign ( MSB states)
call D_add ; compute double precision integer addwf
btfss sign,MSB
btfss ACCbHI,MSB
return
incf EXPb
bcf _carry
goto shftR
;
addNorm
bcf _carry
btfsc ACCbHI,MSB
bsf _carry ; set carry if < 0
shftR
rrcf ACCbHI
rrcf ACCbLO
return
;
PAGE
;*******************************************************************
; Double Precision Addition
;
D_add
movfp ACCaLO,wreg
addwf ACCbLO ;addwf lsb
movfp ACCaHI,wreg
addwfc ACCbHI ;addwf msb with carry
return
;
PAGE
;*******************************************************************
; Binary Floating Point Multiplication
;
; Multiplication :
; ACCb(16 bits)EXP(b) * ACCa(16 bits)EXPa -> ACCb(16 bits)EXPb
; where, EXP(x) represents an 8 bit exponent.
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits ) with
; an 8 bit exponent in location EXPa
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits ) with
; an 8 bit exponent in location EXPb
; (c) CALL F_mpy
; (d) The 16 bit result overwrites ACCb(ACCbLO & ACCbHI). The exponent
; is stored in EXPb and the results are normalized.
;
; NOTE : If one needs to get a 32 bit product( & an 8 bit exponent ),
; re assemble the program after changing the line " Mode16 equ TRUE"
; to " Mode16 equ FALSE ".
; If this option is chosen, then the 32 bit result is returned in
; ( ACCbHI, ACCbLO, ACCcHI, ACCcLO ) and the 8 bit exponent in EXPb.
; This method ( with " Mode16 equ FALSE " ) is NOT Recommended.
;
; If a 32 bit mantissa is desired, set MODE16 equ FALSE
;*******************************************************************
;
F_mpy
call S_SIGN
call setup
mloop
bcf _carry
rrcf ACCdHI ;rotate d right
rrcf ACCdLO
btfsc _carry
call D_add
rrcf ACCbHI
rrcf ACCbLO
rrcf ACCcHI
rrcf ACCcLO
decfsz temp ;loop until all bits checked
goto mloop
;
movfp EXPa,wreg
addwf EXPb
;
#if Mode16
tstfsz ACCbHI
goto finup ; if ACCbHI != 0
tstfsz ACCbLO
goto Shft08 ; if ACCbLO != 0 && ACCbHI == 0
;
movfp ACCcHI,wreg
movwf ACCbHI ; if ACCb == 0, then move ACCc to ACCb
movfp ACCcLO,wreg
movwf ACCbLO
movlw 16
addwf EXPb
goto finup
;
Shft08
movfp ACCbLO,wreg
movwf ACCbHI
movfp ACCcHI,wreg
movwf ACCbLO
movlw 8
addwf EXPb
;
#endif ; matching endif for IF Mode16
;
finup
btfss sign,MSB
goto F_norm
;
movlw ACCcLO
movwf fsr0
call negate
movlw ACCbLO
movwf fsr0
call negate
goto F_norm ; normalize floating point
;
;*******************************************************************
;
setup
clrf temp
bsf temp,4 ; set temp = 16
movfp ACCbHI,wreg ;move ACCb to ACCd
movwf ACCdHI
movfp ACCbLO,wreg
movwf ACCdLO
clrf ACCbHI
clrf ACCbLO ; clear ACCb ( ACCbLO & ACCbHI )
return
;
PAGE
;*******************************************************************
; Double Precision Negate Routines
;
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
;*******************************************************************
; Check Sign of the Number, if so negate and set the SIGN flag
;
S_SIGN
movfp ACCaHI,wreg
xorwf ACCbHI,w
movwf sign
btfss ACCbHI,MSB ; if MSB set go & negate ACCb
goto chek_A
;
movlw ACCbLO
movwf fsr0
call negate
;
chek_A
btfss ACCaHI,MSB ; if MSB set go & negate ACCa
return
movlw ACCaLO
movwf fsr0
call negate
return
;
PAGE
;*******************************************************************
; Normalize Routine
; Normalizes ACCb for use in floating point calculations.
; Call this routine as often as possible to minimize the loss
; of precission. This routine normalizes ACCb so that the
; mantissa is maximized and the exponent minimized.
;
;*******************************************************************
;
F_norm ; normalize ACCb
tstfsz ACCbHI
goto C_norm
tstfsz ACCbLO
goto C_norm
return
;
C_norm
btfsc ACCbHI,MSB-1
return
call shftSL
decf EXPb
goto C_norm
;
shftSL
bcf _carry
;
#if Mode16
rlcf ACCcLO
rlcf ACCcHI
#endif
;
rlcf ACCbLO
rlcf ACCbHI
bcf ACCbHI,MSB
btfsc _carry
bsf ACCbHI,MSB
return
;
;*******************************************************************
; Swap ACCa & ACCb [ (ACCa,EXPa) <--> (ACCb,EXPb) ]
;
F_swap
movfp ACCaHI,wreg
movwf temp
movfp ACCbHI,wreg ; ACCaHI <--> ACCbHI
movwf ACCaHI
movfp temp,wreg
movwf ACCbHI
;
movfp ACCaLO,wreg
movwf temp
movfp ACCbLO,wreg ; ACCaLO <--> ACCbLO
movwf ACCaLO
movfp temp,wreg
movwf ACCbLO
;
movfp EXPb,wreg
movwf temp
movfp EXPa,wreg ; EXPa <--> EXPb
movwf EXPb
movfp temp,wreg
movwf EXPa
return
;
;*****************************************************************
; Normalizes A Floating Point Number
; The number is assumed to be (LowByte, HighByte, Exp) in
; consecutive locations. Before calling this routine, the address
; of the LowByte should be loaded into FSR0 (indirect register ptr)
;*****************************************************************
;
Normalize
incf fsr0
tstfsz indf0
goto NextNorm1
decf fsr0
tstfsz indf0
goto NextNorm2
return
NextNorm2
incf fsr0
NextNorm1
btfsc indf0,MSB-1
return
call shiftNorm
incf fsr0
decf indf0
decf fsr0
goto NextNorm1
;
shiftNorm
bcf _carry
incf fsr0
rlcf indf0
incf fsr0
rlcf indf0
decf fsr0
decf fsr0
decf fsr0
rlcf indf0
incf fsr0
rlcf indf0
bcf indf0,MSB
btfsc _carry
bsf indf0,MSB
return
;
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -