;------------------------------------------------------------------ ; Mult 24 x 24 out 48 (max) ; Fred Maher 3rd Nov 2002 ;------------------------------------------------------------------ ; This routine is "slow" with 1.the big numbers and acceptable with ; a 2. small x big multiplication. ; Typical times ; 1. FFFFFF*EEDDCC = EEDDCB112234 1750 cycles 330usec ; 2. FFFFFF* F7 = F6FFFF09 650 cycles 130usec LIST P=16F628 ; 16F628 Runs at 20 MHz INCLUDE "p16F628.inc" __CONFIG _CP_OFF & _WDT_OFF & _HS_OSC & _PWRTE_ON & _LVP_OFF & _BODEN_OFF ERRORLEVEL -224 ; suppress annoying message because of tris ERRORLEVEL -302 ; suppress message because of page change CBLOCK 20H top1 top2 top3 top4 top5 top6 bot1 bot2 bot3 res1 res2 res3 res4 res5 res6 count temp c1 c2 ENDC movlw 0xF7 movwf top1 movlw 0x00 movwf top2 movlw 0x00 movwf top3 movlw 0x00 movwf top4 movlw 0x00 movwf top5 movlw 0x00 movwf top6 movlw 0xFF movwf bot1 movlw 0xFF movwf bot2 movlw 0xFF movwf bot3 clrf res1 clrf res2 clrf res3 clrf res4 clrf res5 clrf res6 ;----------------------------------------------------------------------- ; Mult24 is the main mult routine start point ;------------------------------------------------------------------------ Mult24: ; bcf STATUS,DC call Regcomp ; Puts smaller number into multiplier and finds count minimum. nop incf count,f clrf res1 clrf res2 clrf res3 call X24 ; main 24 x 24 mult Mult24end: ; here back to principal program with return, 2 lines below goto Mult24end ; dummy instruction for testing that it multiplies ; return ; restore when using with main program ;-------------------------------------------------------------------------- ; End of multiply 24 x 24 ; out 48, routine ;-------------------------------------------------------------------------- Regcomp: ; compare top and bot regs 3 2 1 to decide if we need to swap. bcf STATUS,2 bcf STATUS,1 bcf STATUS,0 Test33: movf bot3,w subwf top3,w btfsc STATUS,C ; goto $+ 3 ; top is equal or bigger call Swap goto Leftbit ; find leftmost 1 for count. ; end case top>bot clrw ; test top=0 (if top=0 then bot=0 (can't be minus)) xorwf top3,w btfsc STATUS,Z goto Test22 ; both zero, continue test with top2,bot2 goto Leftbit Test22: movf bot2,w subwf top2,w btfsc STATUS,C ; goto $+ 3 ; top is equal or bigger call Swap goto Leftbit ; find leftmost 1 for count. ; end case top>bot clrw ; test top=0 (if top=0 then bot=0 (can't be minus)) xorwf top2,w btfsc STATUS,Z goto Test11 ; both zero, continue test with top2,bot2 goto Leftbit Test11: movf bot1,w subwf top1,w btfsc STATUS,C ; goto $+ 3 ; top is equal or bigger call Swap goto Leftbit ; find leftmost 1 for count. ; end case top>bot clrw ; test top=0 (if top=0 then bot=0 (can't be minus)) xorwf top1,w btfsc STATUS,Z goto Test11 ; both zero, continue test with top2,bot2 movf bot1,w ;put bot in temp movwf temp movlw d'08' ; bot is smaller so set count to 24 movwf count ; do Leftbit goto Leftbit Swap: movf top3,w movwf res3 movf bot3,w movwf top3 movf res3,w movwf bot3 movf top2,w movwf res2 movf bot2,w movwf top2 movf res2,w movwf bot2 movf top1,w movwf res1 movf bot1,w movwf top1 movf res1,w movwf bot1 return Leftbit: ;Now find in bot3,2,1 that which is not zero, find leftmost ONE clrw xorwf bot3,w btfsc STATUS, Z goto $+6 movf bot3,w movwf temp movlw d'24' movwf count goto Oneloop clrw xorwf bot2,w btfsc STATUS, Z goto $+6 movf bot2,w movwf temp movlw d'16' movwf count goto Oneloop clrw xorwf bot1,w btfsc STATUS, Z goto $+4 movf bot1,w movwf temp movlw d'08' movwf count goto Oneloop Oneloop: ; We move through the 8 bits of temp from 8 to 1 btfsc temp,7 return decf count,f rlf temp,f goto Oneloop return ; to main mult ;---------------------------------------------------------------- ; End of the compare / count routine ;---------------------------------------------------------------- X24: ; mult loop proper starts here with entered values Step1: ; To add or not to add? that is the question. btfss bot1,0 goto Step3 ; 0... don't add top to res goto Step2 ; 1... add top to res Step2: ; Adding top to res ;Note all credit to ****Dwayne Reid**** for this add routine ;much shorter and more elegant than my one. movfw top1 addwf res1,f movfw top2 skpnc incfsz top2,w addwf res2,f movfw top3 skpnc incfsz top3,w addwf res3,f movfw top4 skpnc incfsz top4,w addwf res4,f movfw top5 skpnc incfsz top5,w addwf res5,f movfw top6 skpnc incfsz top6,w addwf res6,f Step3: ; Left shifting top ; This looks the same as an add but it is different bcf STATUS,C rlf top6,f btfsc STATUS,C nop bcf STATUS,C rlf top5,f btfsc STATUS,C incf top6,f bcf STATUS,C rlf top4,f btfsc STATUS,C incf top5,f bcf STATUS,C rlf top3,f btfsc STATUS,C incf top4,f bcf STATUS,C rlf top2,f btfsc STATUS,C incf top3,f bcf STATUS,C rlf top1,f btfsc STATUS,C incf top2,f bcf STATUS,C Stepend: nop Step4: ;Right shifting bottom and terminate loop for count = MAX, here 24. decf count,f ; we start with count =24 OR speeded up count clrw xorwf count,w btfsc STATUS,Z RETURN ; count finished ; count not finished, continue Step4 rrf bot1,f bcf STATUS,C rrf bot2,f btfss STATUS,C goto $ + 4 ; there was no carry, jump forward 4 movlw 0x80 addwf bot1,f bcf STATUS,C rrf bot3,f btfss STATUS,C goto $ + 4 ; there was no carry, jump forward 4 movlw 0x80 addwf bot2,f bcf STATUS,C goto Step1 ;--------------------------------------------------------------------- ; End of reg multiplication ;--------------------------------------------------------------------- end ;------------------------------------------------------------------ ; End Mult 24 x 24 ;------------------------------------------------------------------
Comments: