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 |