;------------------------------------------------------------------
;                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: