;------------------------------------------------------------------------------- ; U08DIV5 v.20110117 By Ihsan V. TORE ; ; 8 bit unsigned integer divide by 5 ; Calculated by subtracting 160:80:40:20:10: 5 from the byte successively, and ; adding result 32:16: 8: 4: 2: 1 respectively if subtractions are positive. ; ; Code : 26 instructions ; Time : 26 cycles ; Ram : 1 bytes ; ; Args : W : u08 : dividend ; Retv : result : u08 : x DIV 5 ; W : u08 : x MOD 5 ; ; Note : Heavily optimized for speed. ; Lic. : MIT. ;------------------------------------------------------------------------------- U08DIV5: clrf result ; result = 0 addlw .256-.160 ; W -= 160 rlf result, f ; load cf to result bit btfss result, 0 ; skip if positive (CF == 1) addlw .160 ; else reload W (CF == 0) addlw .256-.80 ; W -= 80 rlf result, f ; load cf to result bit btfss result, 0 ; skip if positive (CF == 1) addlw .80 ; else reload W (CF == 0) addlw .256-.40 ; W -= 40 rlf result, f ; load cf to result bit btfss result, 0 ; skip if positive (CF == 1) addlw .40 ; else reload W (CF == 0) addlw .256-.20 ; W -= 20 rlf result, f ; load cf to result bit btfss result, 0 ; skip if positive (CF == 1) addlw .20 ; else reload W (CF == 0) addlw .256-.10 ; W -= 10 rlf result, f ; load cf to result bit btfss result, 0 ; skip if positive (CF == 1) addlw .10 ; else reload W (CF == 0) addlw .256-.5 ; W -= 5 rlf result, f ; load cf to result bit btfss result, 0 ; skip if positive (CF == 1) addlw .5 ; else reload W (CF == 0) return ; return the result ;------------------------------------------------------------------------------- ; Here is the version optimized for size if code space is more important ;------------------------------------------------------------------------------- ; U08DIV5 v.20110116 By Ihsan V. TORE ; ; 8 bit unsigned integer divide by 5 ; Calculated by subtracting 160:80:40:20:10: 5 from the byte successively, and ; adding result 32:16: 8: 4: 2: 1 respectively if subtractions are positive. ; ; Code : 12 instructions ; Time : 61 cycles ; Ram : 2 bytes ; ; Args : dividend : u08 : dividend ; Retv : result : u08 : x DIV 5 ; dividend : u08 : x MOD 5 ; ; Note : Heavily optimized for size. ; Lic. : MIT. ;------------------------------------------------------------------------------- U08DIV5: clrf result ; prelude :) movlw .160 ; W = subtract = 160 movwf subtract U08DIV5_LOOP: subwf dividend, W ; W = dividend - subtract skpnc ; skip if negative (CF == 0) movwf dividend ; else dividend = W (CF == 1) rlf result, F ; load CF to corresponding result bit U08DIV5_NEXT: ; CF == 0 here always rrf subtract, F ; subtract /= 2 skpnc ; if carry return return movfw subtract ; W = subtract goto U08DIV5_LOOP ; loop
Ihsan Volkan Tore Says:
This might easily be "reinventing the wheel". I have not seen any routine like this before (probably because I did not sought enough) :). But I think this will be wellcome by all lazy coders like me when needed. Please note that, the first version without the loop can be useful for divisions by 10,20,40 and 80. You can accomplish this by returning after the reloader addlw instructions of respective subtractions. You can omit the last btfss and addlw instructions if you do not need the modulo. Cut paste run and have fun...
Ihsan Volkan Tore Says: " Yes, digging into piclist, I've found that this algorithm is called kenyan method. I reinvented the wheel...again... :) "