Posted to PICList Mon, 3 Jul 2000 00:04:54 -0400
LIST P = 16C54, n = 66
;
;*******************************************************************
; Double Precision Multiplication
;
; ( Optimized for Speed : straight Line Code )
;
;*******************************************************************;
; Multiplication : ACCb(16 bits) * ACCa(16 bits) -> ACCb,ACCc (32bits )
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16bits )
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16bits )
; (c) CALL D_mpy
; (d) The 32 bit result is in location (ACCbHI,ACCbLO,ACCcHI,ACCcLO )
;
; Performance :
; Program Memory : 240
; Clock Cycles : 233 (282)
;
; 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 ").
;
; Program: DBL_MPYF.ASM
; Revision Date:
; 1-13-97 Compatibility with MPASMWIN 1.40
;
;*******************************************************************;
;
ACCaLO equ 10
ACCaHI equ 11
ACCbLO equ 12
ACCbHI equ 13
ACCcLO equ 14
ACCcHI equ 15
ACCdLO equ 16
ACCdHI equ 17
temp equ 18
sign equ 19
;----------------------
; Inserted by RAVI PAILOOR
loopctr equ 1A
;----------------------
;
include "p16c5x.inc"
PIC54 equ 1FFH ; Define Reset Vector
TRUE equ 1
FALSE equ 0
org 0
;*******************************************************************
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.
;*******************************************************************
; multiplication macro
;
mulMac MACRO
LOCAL NO_ADD
;
rrf ACCdHI, F ;rotate d right
rrf ACCdLO, F
btfss STATUS,C ;need to add?
goto NO_ADD ; no addition necessary
movf ACCaLO,W ; Addition ( ACCb + ACCa -> ACCb )
addwf ACCbLO, F ;add lsb
btfsc STATUS,C ;add in carry
incf ACCbHI, F
movf ACCaHI,W
addwf ACCbHI, F ;add msb
NO_ADD rrf ACCbHI, F
rrf ACCbLO, F
rrf ACCcHI, F
rrf ACCcLO, F
;
ENDM
;
;*******************************************************************;
; 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_mpyF ;results in ACCb(16 msb's) and
ACCc(16
lsb's)
;
IF SIGNED
CALL S_SIGN
ENDIF
;
call setup
;
; use the mulMac macro 16 times
;
;----------------------
; inserted by RAVI PAILOOR
movlw .16
movwf loopctr
;----------------------
loop mulMac
;----------------------
; inserted by RAVI PAILOOR
decfsz loopctr,f
goto loop
;----------------------
ORIGNAL
; mulMac
; mulMac
; mulMac
; mulMac
; mulMac
; mulMac
; mulMac
; mulMac
; mulMac
; mulMac
; mulMac
; mulMac
; mulMac
; mulMac
; mulMac
IF SIGNED
btfss sign,MSB
retlw 0
comf ACCcLO ; negate ACCa ( -ACCa -> ACCa )
incf ACCcLO
btfsc STATUS,Z
decf ACCcHI
comf ACCcHI
btfsc STATUS,Z
neg_B comf ACCbLO ; negate ACCb
incf ACCbLO
btfsc STATUS,Z
decf ACCbHI
comf ACCbHI
retlw 0
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, F ; negate ACCa ( -ACCa -> ACCa )
incf ACCaLO, F
btfsc STATUS,Z
decf ACCaHI, F
comf ACCaHI, F
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 STATUS,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
;
loadAB movlw 1
movwf ACCaHI
movlw 0FF ; loads ACCa = 01FF
movwf ACCaLO
;
movlw 07F
movwf ACCbHI
movlw 0FF ; loads ACCb = 7FFF
movwf ACCbLO
retlw 0
;
main nop
;
call loadAB ; result of multiplying
ACCb*ACCa->(ACCb,ACCc)
call D_mpyF ; Here (ACCb,ACCc) = 00FF 7E01
;
self goto self
;
org PIC54
goto main
END
;****************************************************************
--
Ravi Pailoor
Comments: