PIC Microcontoller Math Method

Divide 24 bits by the constant value 10 for PIC18F

From: VegiPete gmail

;******************************************************************************
;DivideTen
;Divide result48:6 by ten, puts answer back in result48:6 (low byte in low memory)
;Uses temp:6 for working space
;Uses PRODL as a temporary loop counter
;
;Based on "Reciprocal Multiplication, a tutorial"
;by Douglas W. Jones
;The University of Iowa Department of Computer Science 
;<http://www.divms.uiowa.edu/~jones/bcd/divide.html>
;
;modified (ever so slightly) by Vegipete for 48 bits and
;translated to PIC18 code.
;Spot tested successfully.
;Routine does not appear to round the result.
;For example, for 9,999,999 input, the output is 999,999
;******************************************************************************
DivideTen:
	bcf	STATUS,C
	rrcf	result+5,w
	movwf	temp+5
	rrcf	result+4,w
	movwf	temp+4
	rrcf	result+3,w
	movwf	temp+3
	rrcf	result+2,w
	movwf	temp+2
	rrcf	result+1,w
	movwf	temp+1
	rrcf	result+0,w
	movwf	temp+0
	rcall	ShiftRightTemp		;second right shift

	rcall	AddResultToTemp		;possible carry set
	rcall	ShiftRightTempUseC	;roll carry back into number
;now temp = result * 0.101
;	movlw	3			;magic number for 16 bits
;	movlw	7			;magic number for 32 bits
	movlw	11			;magic number for 48 bits
	movwf	PRODL			;temp storage
DivLoop
	rcall	AddResultToTemp		;possible carry set
	rcall	ShiftRightTempUseC	;roll carry back into number
	rcall	ShiftRightTemp		;second right shift
	rcall	ShiftRightTemp		;third right shift
;after 1st pass, temp = result * 0.001101

	rcall	AddResultToTemp		;possible carry set
	rcall	ShiftRightTempUseC	;roll carry back into number
;after 1st pass, temp = result * 0.1001101

	decf	PRODL,f
	bnz	DivLoop
;after  3 passes, temp = result * 0.100110011001101
;after  7 passes, temp = result * 0.1001100110011001100110011001101
;after 11 passes, temp = result * 0.10011001100110011001100110011001100110011001101

	rcall	AddResultToTemp		;possible carry set
	rcall	ShiftRightTempUseC	;roll carry back into number
	rcall	ShiftRightTemp		;second right shift
	rcall	ShiftRightTemp		;third right shift
	rcall	ShiftRightTemp		;fourth right shift and exit
;now temp =  result * 0.0001<previous result>
	movff	temp+5,result+5		;copy answer back to source
	movff	temp+4,result+4
	movff	temp+3,result+3
	movff	temp+2,result+2
	movff	temp+1,result+1
	movff	temp+0,result+0
	return

;Shift temp:6 right once, two entries, depending on significance of carry
ShiftRightTemp
	bcf	STATUS,C
ShiftRightTempUseC
	rrcf	temp+5,f	;second entry takes carry as extra bit
	rrcf	temp+4,f
	rrcf	temp+3,f
	rrcf	temp+2,f
	rrcf	temp+1,f
	rrcf	temp+0,f
	return

;Add result:6 to temp:6, carry could be set on exit
AddResultToTemp
	movf	result+0,w
	addwf	temp+0,f
	movf	result+1,w
	addwfc	temp+1,f
	movf	result+2,w
	addwfc	temp+2,f
	movf	result+3,w
	addwfc	temp+3,f
	movf	result+4,w
	addwfc	temp+4,f
	movf	result+5,w
	addwfc	temp+5,f	;there could be a carry here
	return