Main page

Multiplication and Division Routines to PIC18 processor
    LIST p=18F2320, r=DEC    ;processor PIC18F2320, radix decimal

    #include    "P18F2320.INC"   

;register file definition example
C0     equ    0
C1     equ    1
C2     equ    2
C3     equ    3
ACCUH  equ    4
ACCUL  equ    5
EXT_H  equ    8
EXT_L  equ    9
WRD_H  equ    10
WRD_L  equ    11
LUK_H  equ    12
LUK_L  equ    13

;Multiplication 16bit * 16bit -> 32bit
;WRD * LUK -> EXTWRD
;detailed: WRD_H:WRD_L * LUK_H:LUK_L -> EXT_H:EXT_L:WRD_H:WRD_L
;LUK value remains. Affected registers: temp reg C3
MULW:  movf    WRD_H,w
       mulwf   LUK_H    ; LUK_H * WRD_H
       movff   PRODH,EXT_H
       movff   PRODL,EXT_L
       movf    WRD_L,w
       mulwf   LUK_L    ; LUK_L * WRD_L
       movff   PRODH,C3
       movff   PRODL,WRD_L
       mulwf   LUK_H    ; LUK_H * WRD_L
       movf    PRODL,w
       addwf   C3,f    ; Add cross
       movf    PRODH,w    ; products
       addwfc  EXT_L,f
       clrf    WREG
       addwfc  EXT_H,f
       movf    WRD_H,w
       mulwf   LUK_L    ; LUK_L * WRD_H
       movf    PRODL,w    ;
       addwf   C3,w    ; Add cross
       movwf   WRD_H
       movf    PRODH,w    ; products
       addwfc  EXT_L,f
       clrf    WREG
       addwfc  EXT_H,f
       return

;Unsigned Division  32bit / 16bit -> 16bit
;EXTWRD / LUK -> WRD, remainder -> EXT
;detailed EXT_H:EXT_L:WRD_H:WRD_L / LUK_H:LUK_L -> WRD_H:WRD_L
;On overflow or divide by zero: FFFFh -> WRD, FFFFh -> EXT
;LUK value remains. Affected registers: temp reg C0, C1, C2, C3
DIV32:  clrf   C0    ;TEMP
        clrf   C1
        clrf   C2
        movlw  -32    ;LOOPS
        movwf  C3   
        ;
        ;SHIFT R8R6R4<<1
DIV322: bcf    STATUS,C
        rlcf   WRD_L,f
        rlcf   WRD_H,f
        rlcf   EXT_L,f
        rlcf   EXT_H,f
        rlcf   C2,f
        rlcf   C1,f
        rlcf   C0,f
        ;update C12=C12-LUK if remains positive
        movf   LUK_L,w
        subwf  C2,f
        movf   LUK_H,w
        subwfb C1,w
        bc     DIV324    ;borrow = !carry
        ;16 bit subtraction < 0
        tstfsz C0
        bra    DIV323    ;borrow from C0
        ;24 bit subtraction < 0
        ;restore C2 (C1 is already unghanged)
        movf   LUK_L,w
        addwf  C2,f
        bra    DIV325
        ;
DIV323: decf   C0,f    ;update C0
DIV324: movwf  C1    ;update C1 (C2 is already updated)
        bsf    WRD_L,0   
        btfss  C3,4    ;>=16 counts remaining?
        bra    DIV326    ;overflow
        ;
        ;next loop
DIV325: incfsz C3,f
        bra    DIV322
        ;
        ;ready, result ok
        movff  C2,EXT_L  ;remainder
        movff  C1,EXT_H   
        return
        ;
        ;overflow
DIV326: movlw  0FFh
        movwf  WRD_H
        movwf  WRD_L
        movwf  EXT_H
        movwf  EXT_L
        return