📄 pm_math.asm
字号:
;********************************************************************
; mpy_S
; 8x8 multiply routine
; ON ENTRY: ACCaHI=multiplicand, ACCaLO=multiplier
; RETURNS: result in ACCbHI & ACCbLO
; REGS DESTROYED: ACCbHI,ACCbLO,ACCaHI,ACCaLO,count
;********************************************************************
Same equ 1
mpy_S clrf ACCbHI ; SUBPROGRAM ENTRY
clrf ACCbLO
movlw 8
movwf count
movf ACCaHI,w ; 8-bit multiplicand
bcf _carry ; Clear the carry bit in the status Reg.
loop rrf ACCaLO ; 8-bit multiplier
btfsc _carry
addwf ACCbHI,Same
rrf ACCbHI,Same
rrf ACCbLO,Same
decfsz count
goto loop
retlw 0
;********************************************************************
; B2_BCD
; ON ENTRY: 16bit value in ACCbHI & ACCbLO
; RETURNS: BCD bytes (msb) ACCdLO, ACCaHI, ACCaLO (lsb)
; REGS DESTROYED: ACCdLO, ACCa,count,temp
;********************************************************************
B2_BCD bcf _carry ; SUBPROGRAM ENTRY
; clear the carry bit
movlw .16
movwf count
clrf ACCdLO
clrf ACCaHI
clrf ACCaLO
loop16 rlf ACCbLO
rlf ACCbHI
rlf ACCaLO
rlf ACCaHI
rlf ACCdLO
;
decfsz count
goto adjDEC
RETLW 0
;
adjDEC movlw ACCaLO
movwf _fsr
call adjBCD
;
movlw ACCaHI
movwf _fsr
call adjBCD
;
movlw ACCdLO
movwf _fsr
call adjBCD
;
goto loop16
;
adjBCD movlw 3
addwf 0,W
movwf temp
btfsc temp,3 ; test if result > 7
movwf 0
movlw 30
addwf 0,W
movwf temp
btfsc temp,7 ; test if result > 7
movwf 0 ; save as MSD
RETLW 0
;*******************************************************************
; Double Precision Division
;
; ( Optimized for Code Size : 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 : 037
; Clock Cycles : 310
;
; NOTE :
; The performance specs are for Unsigned arithmetic ( i.e,
; with "SIGNED equ FALSE ").
;
;*******************************************************************;
;
;
;*******************************************************************
SIGNED equ FALSE ; Set This To 'TRUE' if the routines
; ; for Multiplication & Division needs
; ; to be assembled as Signed Integer
; ; Routines. If 'FALSE' the above two
; ; routines ( D_mpy & D_div ) use
; ; unsigned arithmetic.
;*******************************************************************
; 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_divS
;
IF SIGNED
CALL S_SIGN
ENDIF
;
call setup
clrf ACCcHI
clrf ACCcLO
dloop bcf _carry
rlf ACCdLO
rlf ACCdHI
rlf ACCcLO
rlf ACCcHI
movf ACCaHI,w
subwf ACCcHI,w ;check if a>c
btfss _z
goto nochk
movf ACCaLO,w
subwf ACCcLO,w ;if msb equal then check lsb
nochk btfss _carry ;carry set if c>a
goto nogo
movf ACCaLO,w ;c-a into c
subwf ACCcLO
btfss _carry
decf ACCcHI
movf ACCaHI,w
subwf ACCcHI
bsf _carry ;shift a 1 into b (result)
nogo rlf ACCbLO
rlf ACCbHI
decfsz temp ;loop untill all bits checked
goto dloop
;
IF SIGNED
btfss sign,MSB ; check sign if negative
retlw 0
goto neg_B ; negate ACCa ( -ACCa -> ACCa )
ELSE
retlw 0
ENDIF
;
;*******************************************************************
;
setup movlw .16 ; for 16 shifts
movwf temp
movf ACCbHI,w ;move ACCb to ACCd
movwf ACCdHI
movf ACCbLO,w
movwf ACCdLO
clrf ACCbHI
clrf ACCbLO
retlw 0
;
;*******************************************************************
;
neg_A comf ACCaLO ; negate ACCa ( -ACCa -> ACCa )
incf ACCaLO
btfsc _z
decf ACCaHI
comf ACCaHI
retlw 0
;
;*******************************************************************
; Assemble this section only if Signed Arithmetic Needed
;
IF SIGNED
;
S_SIGN movf ACCaHI,W
xorwf ACCbHI,W
movwf sign
btfss ACCbHI,MSB ; if MSB set go & negate ACCb
goto chek_A
;
comf ACCbLO ; negate ACCb
incf ACCbLO
btfsc _z
decf ACCbHI
comf ACCbHI
;
chek_A btfss ACCaHI,MSB ; if MSB set go & negate ACCa
retlw 0
goto neg_A
;
ENDIF
;
;*******************************************************************
; Test Program
;*******************************************************************
; Load constant values to ACCa & ACCb for testing
;
test1 movlw 1
movwf ACCaHI
movlw 0FF ; loads ACCa = 01FF
movwf ACCaLO
;
movlw 07F
movwf ACCbHI
movlw 0FF ; loads ACCb = 7FFF
movwf ACCbLO
;
call D_divS ; remainder in ACCc. Here ACCb =0040 & ACCc=003F
;
self1 goto self1
;
;*******************************************************************
; Double Precision Multiplication
;
; ( Optimized for Code Size : Looped Code )
;
;*******************************************************************;
; Multiplication : ACCb(16 bits) * ACCa(16 bits) -> ACCb,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 ( ACCbHI,ACCbLO,ACCcHI,ACCcLO )
;
; Performance :
; Program Memory : 033
; Clock Cycles : 333
;
; 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 ").
;
;*******************************************************************;
; 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
; (t) The result is in location ACCbLO & ACCbHI ( 16 bits )
;
; Performance :
; Program Memory : 07
; Clock Cycles : 08
;*******************************************************************;
; 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
; (t) The result is in location ACCbLO & ACCbHI ( 16 bits )
;
; Performance :
; Program Memory : 14
; Clock Cycles : 17
;*******************************************************************;
; Double Precision Subtraction ( ACCb - ACCa -> ACCb )
;
D_sub call neg_A ; At first negate ACCa; Then add
;
;*******************************************************************
; Double Precision Addition ( ACCb + ACCa -> ACCb )
D_add movf ACCaLO,w ; Addition ( ACCb + ACCa -> ACCb )
addwf ACCbLO ;add lsb
btfsc _carry ;add in carry
incf ACCbHI
movf ACCaHI,w
addwf ACCbHI ;add msb
retlw 0
;*******************************************************************
; Double Precision Multiply ( 16x16 -> 32 )
; ( ACCb*ACCa -> ACCb,ACCc ) : 32 bit output with high word
; in ACCb ( ACCbHI,ACCbLO ) and low word in ACCc ( ACCcHI,ACCcLO ).
;
D_mpyS ;results in ACCb(16 msb's) and ACCc(16 lsb's)
;
IF SIGNED
CALL S_SIGN
ENDIF
;
call setup
mloop rrf ACCdHI ;rotate d right
rrf ACCdLO
btfsc _carry ;need to add?
call D_add
rrf ACCbHI
rrf ACCbLO
rrf ACCcHI
rrf ACCcLO
decfsz temp ;loop until all bits checked
goto mloop
;
IF SIGNED
btfss sign,MSB
retlw 0
comf ACCcLO ; negate ACCa ( -ACCa -> ACCa )
incf ACCcLO
btfsc _z
decf ACCcHI
comf ACCcHI
btfsc _z
neg_B comf ACCbLO ; negate ACCb
incf ACCbLO
btfsc _z
decf ACCbHI
comf ACCbHI
retlw 0
ELSE
retlw 0
ENDIF
;
;*******************************************************************
; Assemble this section only if Signed Arithmetic Needed
;
IF SIGNED
;
S_SIGN movf ACCaHI,W
xorwf ACCbHI,W
movwf sign
btfss ACCbHI,MSB ; if MSB set go & negate ACCb
goto chek_A
;
comf ACCbLO ; negate ACCb
incf ACCbLO
btfsc _z
decf ACCbHI
comf ACCbHI
;
chek_A btfss ACCaHI,MSB ; if MSB set go & negate ACCa
retlw 0
goto neg_A
;
ENDIF
;
;*******************************************************************
; Test Program
;*******************************************************************
; Load constant values to ACCa & ACCb for testing
;
test2 movlw 1
movwf ACCaHI
movlw 0FF ; loads ACCa = 01FF
movwf ACCaLO
;
movlw 07F
movwf ACCbHI
movlw 0FF ; loads ACCb = 7FFF
movwf ACCbLO
;
call D_mpyS ; Here (ACCb,ACCc) = 00FF 7E01
;
self2 goto self2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -