PIC Microcontoller Math Method

Multiply 16x16 bit from Ravi Pailoor

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: