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