From: Tony Nixon
; ------------------------------------------ ; SUBROUTINE - 24 BIT DIVISION ; numerator: nratorH nratorM nratorL ; denominator: denomH denomM denomL ; ; result: nratorH nratorM nratorL ; remainder: remainH remainM remainL ; divizn movlw .24 movwf BCount movf nratorH,w movwf shiftH movf nratorM,w movwf shiftM movf nratorL,w movwf shiftL clrf nratorH clrf nratorM clrf nratorL ; clrf remainH clrf remainM clrf remainL dloop bcf status,carry rlf shiftL rlf shiftM rlf shiftH rlf remainL rlf remainM rlf remainH movf denomH,w subwf remainH,w btfss status,z goto nochk ; movf denomM,w subwf remainM,w btfss status,z goto nochk ; movf denomL,w subwf remainL,w nochk btfss status,carry goto nogo ; movf denomL,w subwf remainL btfss status,carry decf remainM movf remainM,w xorlw 0xff btfsc status,z decf remainH movf denomM,w subwf remainM btfss status,carry decf remainH movf denomH,w subwf remainH bsf status,carry nogo rlf nratorL rlf nratorM rlf nratorH decfsz BCount goto dloop ; return Thanks Fred... I posted your version under Tony's... I wish I had time to test and debug all the code on the site, but I simply can't.. I depend on people like you who find problems, fix them and share the result. In short: THANK YOU! <GRIN> --- James Newton, webhost piclist.com (former Admin #3) jamesnewton at piclist,com 1-619-652-0593 fax:1-208-279-8767 PIC/PICList FAQ: http://www.piclist.com or .org -----Original Message----- From: Fred Maher [mailto: FREDFMAH at terra,es] Sent: Saturday, September 28, 2002 10:59 PM To: webmaster at piclist,com Subject: I need someone to help me with:24/24 Dear webmaster, Looking for a routine that works..... In the PIC list , the only one I could get working and that produced a useable result was Tony Nixons.... Even so it needed tweaking First compile with MPLAB gave more than 30 errors plus warnings. 1 Things not defined initially 2 default warnings 3 Errors like status should be STATUS These are the things that leave us newbies on the floor. Having said all this this code is quite quick and the ONLY ONE that is easy to get working in the PICLIST !!!!!!!!!!!!!! The tweaked code follows:--------------------------------------- ;--------------------------------------------------------------------- ;------- HEADER ---------- ;--------------------------------------------------------------------- ; FredMaher Madrid 30 Sept 02 fredfmah@terra.es ; Tony Newton's 24÷24 routine with worked example ; LCD MESSAGES ; position at beginning of 1st line col 0 movlw H'80 ; position at beginning of second line movlw H'C0' 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 ;__FUSES _PWRTE_ON & _CP_OFF & _WDT_ON & _HS_OSC & _LVP_OFF & _MCLRE_OFF & _BODEN_OFF ; Define Information #DEFINE RS PORTA, 2 #DEFINE E PORTA, 3 ;#DEFINE TOGGLESW PORTB, 6 ; not used at the moment ;#DEFINE LED PORTB, 5 ; Macro Bank0 macro bcf STATUS, RP0 ;Select memory bank 0 bcf STATUS, RP1 endm Bank1 macro bsf STATUS, RP0 ;Select memory bank 1 bcf STATUS, RP1 endm ;--------------------------------------------------------------- CBLOCK 20H ; from 20C to 7F = 67 ;Note. Careful with memory pages ; until you get some practice. ;--------------------------------------------------------------- ; MATH ROUTINES ; 24 / 24 Div --> 24 ; TONY NIXON's Algorithm starts here + my retouching ; SUBROUTINE - 24 BIT DIVISION ; numerator: nratorH nratorM nratorL ; denominator: denomH denomM denomL ; ; result: nratorH nratorM nratorL ; remainder: remainH remainM remainL nratorH nratorM nratorL denomH denomM denomL remainH remainM remainL shiftH shiftM shiftL BCount ;------------------------------------------------------------------- ENDC ; end of definition block ;------------------------------------------------------------------- ORG 0 ; start at location 0 goto Main ; jump over to main routine Main: call Div24 Homesweethome: nop goto Homesweethome Div24: ; Example 1000000/16960 = F4240 / 4240 =58.962 ( remainder... remain/denom gives the decimal correctly... = Dec 0.962) movlw 0x0F ; using Tony's notation movwf nratorH movlw 0x42 movwf nratorM movlw 0x40 movwf nratorL movlw 0x00 movwf denomH movlw 0x42 movwf denomM movlw 0x40 movwf denomL divizn movlw .24 movwf BCount movf nratorH,w movwf shiftH movf nratorM,w movwf shiftM movf nratorL,w movwf shiftL clrf nratorH clrf nratorM clrf nratorL ; clrf remainH clrf remainM clrf remainL dloop bcf STATUS,C rlf shiftL,f rlf shiftM,f rlf shiftH,f rlf remainL,f rlf remainM,f rlf remainH,f movf denomH,w subwf remainH,w btfss STATUS,Z goto nochk ; movf denomM,w subwf remainM,w btfss STATUS,Z goto nochk ; movf denomL,w subwf remainL,w nochk btfss STATUS,C goto nogo ; movf denomL,w subwf remainL,f btfss STATUS,C decf remainM,f movf remainM,w xorlw 0xff btfsc STATUS,Z decf remainH,f movf denomM,w subwf remainM,f btfss STATUS,C decf remainH,f movf denomH,w subwf remainH,f bsf STATUS,C nogo: rlf nratorL,f rlf nratorM,f rlf nratorH,f decfsz BCount,f goto dloop ; Return end ;--------------------------------------------------------------------------------------------------------------------------------- ; End of 24/24 division routine by Tony Nixon ;---------------------------------------------------------------------------------------------------------------------------------- Cheers Fred Maher Madrid Spain
Code:
Correcting High byte remainder error and added comments to Tony Nixon Code and Fred Mahers update to the 24bit by 24bit divide routine. Thank you all for the USEFUL Code references and comments here. note Nikolai Golovchenko and Zet P. Fred Finster 3/15/2005 Error Corrected Numerator Denominator Remainder Answer Divisor Remainder FFFFFF FFFFFE FF0001 000001 FFFFFE 000001 8FFFFF 8FFFFE FF0001 000001 8FFFFE 000001 2FFFFF 2FFFFE FF0001 000001 2FFFFE 000001 2FFFFE 2FFFFE 000001 2FFFFE 000000 2FFFFD 2FFFFE 000000 2FFFFE 2FFFFD 0F4240 004240 00003A 004240 003FC0 ;----------------------------------------------------- ; Here is the changed code, that corrects the HIGH byte remainder error ; btfsc STATUS, C ; Carry Set? Then execute fixup code for when a borrow is generated ; goto nodec_remainM ; when no borrow bit is needed from the higher byte positions. ; ; ;-------------------------------------------------------------------- ; SUBROUTINE - 24 BIT DIVISION from TONY NIXON ; numerator: nratorH nratorM nratorL ; denominator: denomH denomM denomL ; ; result: nratorH nratorM nratorL ; remainder: remainH remainM remainL ; Divide_24x24: movlw .24 ; set decimal 24 loop count movwf BCount movf nratorH,w ; copy Numerator into Shift Holding ram registers movwf shiftH movf nratorM,w movwf shiftM movf nratorL,w movwf shiftL clrf nratorH ; clear final Answer Numerator Ram locations clrf nratorM clrf nratorL ; clrf remainH ; clear final Answer Remainder Ram locations clrf remainM clrf remainL dloop: bcf STATUS, C ; bit clear Carry Flag in STATUS register rlf shiftL, f ; Shift numerator(dividend) Left to move rlf shiftM, f ; next bit to remainder rlf shiftH, f ; and shift in next bit of result rlf remainL, f ; shift carry (next Dividend bit) into remainder rlf remainM, f rlf remainH, f movf denomH,w subwf remainH,w ; subtract divsor(denomH) from(newly shifted left) Remainder HIGH byte. btfss STATUS, Z goto nochk ; skip if result was ZERO from good subtraction result ; movf denomM,w subwf remainM,w ; subtract divsor(denomM) from(newly shifted left) Remainder MIDDLE byte. btfss STATUS, Z goto nochk ; skip if result was ZERO from good subtraction result ; movf denomL,w subwf remainL,w ; subtract divsor(denomL) from(newly shifted left) Remainder LOW byte. nochk: btfss STATUS, C ; Carry SET? then denom is larger than reemainder goto nogo ; movf denomL,w subwf remainL, f ; Subtract denominator from remainder value in Low Byte btfsc STATUS, C ; Carry Set? Then execute fixup code for when a borrow is generated goto nodec_remainM ; when no borrow bit is needed from the higher byte positions. decf remainM, f ; Decrement to Borrow from Middle Byte, because carry was SET. movf remainM,w xorlw 0xff ; Check if rollover from Borrow occurred. remainM value went from 0 to 0xFF btfsc STATUS, Z decf remainH, f ; ZERO bit set, yes rollover, so Decrement to Borrow from High Byte, too! nodec_remainM: movf denomM,w subwf remainM, f ; Subtract denominator from remainder value in Middle Byte btfss STATUS, C decf remainH ,f ; Decrement High Byte, to borrow 1 bit movf denomH,w subwf remainH, f ; Subtract denominator from remainder value in High Byte bsf STATUS, C ; set CARRY bit to rotate in Numerator Result next. nogo: rlf nratorL, f ; rotate Numerator result left 1 bit rlf nratorM, f rlf nratorH, f decfsz BCount, f ; decrement the Loop Bit Counter goto dloop ; return ; all done