> Does any one know where i can get a 32/16->16 Divide ASM source > for PIC16, that i easy can include in my project. > please mail me on jorgen.tapani@nacka.mail.telia.com > > // Jorgen Tapani > Here is a 32/16->32 rem 32 routine. I wrote this a year or so back for a rev counter (actually it was a 24/19 routine). I don't think it is as fast as it can be - there must be a better way to handle the borrows in the subctract routine - but I know it works. Niki steenkmp@firga.sun.ac.za LIST P=16C54 #INCLUDE P16C5X.INC __FUSES _WDT_OFF & _CP_OFF & _HS_OSC RADIX DEC ;========================================================================= ;VARIAHBLE DEFINITIONS ;========================================================================= RTCC EQU 01h C1 EQU 08h ;COUNTER USED IN DIVIDE ROUTINE ;VARIABLES USED BY THE DIVISION ROUTINES ;ALL NUMBERS ARE STORED LEAST SIGNIFICANT BYTE FIRST. X EQU 09h ;USES 4 BYTES - DIVIDEND B EQU 0Dh ;USES 4 BYTES - REMAINDER T EQU 11h ;USES 4 BYTES - TEMPORARY STORAGE Y EQU 15h ;TWO BYTE - DIVISOR FLAGS EQU 17h ;========================================================================= ;FLAGS DEFINITIONS NEG EQU 2 ;TEPORARY FLAG USED BY SUBTRACT ROUTINE ;========================================================================= ;MACROS ;========================================================================= ;THIS MACRO SHIFTS A 32 BIT VARIABLE ONE BIT TO THE LEFT. Z IS THE ;LEAST SIGNIFICANT BYTE OF THE VARIABLE. ;AT THE END OF THE MACRO, C CONTAINS THE MOST SIGNIFICANT OF THE 32 BIT ;VARIABLE SHIFT_LEFT MACRO Z, DESTINATION RLF Z,DESTINATION RLF Z+1,DESTINATION RLF Z+2,DESTINATION RLF Z+3,DESTINATION ENDM ;THIS MACRO SUBTRACTS A 16 BIT NUMBER IN Y FROM A 32 BIT NUMBER ;IN B. AFTER THE SUBTRACTION, THE CARRY BIT IS CLEARED IF ;THE RESULT IS NEGATIVE, OR SET IF THE RESULT IS POSITIVE. THE RESULT IS ;STORED IN T SUB16_32 MACRO MOVF B,W ;TRANSFER B TO T MOVWF T MOVF B+1,W MOVWF T+1 MOVF B+2,W MOVWF T+2 MOVF B+3,W MOVWF T+3 BCF FLAGS,NEG MOVF Y,W ;DO LEAST SIGNIFICANT BYTE SUBTRACTION SUBWF T,F MOVLW 01h ;PRELOAD W WITH 1 BTFSS STATUS,C ;TEST IF BORROW WAS MADE SUBWF T+1,F ;IF SO, SUBTRACT THE BORROW BTFSS STATUS,C ;TEST IF THIS CAUSED ANOTHER BORROW SUBWF T+2,F ;SUBTRACT THAT AS WELL BTFSS STATUS,C ;TEST IF THIS CAUSED ANOTHER BORROW SUBWF T+3,F ;SUBTRACT THAT AS WELL BTFSS STATUS,C ;TEST IF THIS CAUSED ANOTHER BORROW BSF FLAGS,NEG ;RESULT IS NEGATIVE MOVF Y+1,W ;DO MOST SIGNIFICANT ORDER SUBTRACTION SUBWF T+1,F MOVLW 01h BTFSS STATUS,C ;TEST IF BORROW WAS MADE SUBWF T+2,F ;SUBTRACT BORROW BTFSS STATUS,C ;TEST IF THIS CAUSED ANOTHER BORROW SUBWF T+3,F ;SUBTRACT BORROW BTFSS STATUS,C ;TEST IF THIS CAUSED ANOTHER BORROW BSF FLAGS,NEG ;RESULT IS NEGATIVE BSF STATUS,C BTFSC FLAGS,NEG ;LOOK AT TEMPORARY FLAG BCF STATUS,C ;TO DETERMINE IF ANSWER IS NEGATIVE ENDM ;========================================================================= ;CODE ;========================================================================= ORG 1FFh GOTO START ORG 0h START: CLRF FLAGS ;DIVIDE 87799BF2h (2272893938) BY 0B28h (2856). MOVLW 0F2h MOVWF X MOVLW 09Bh MOVWF X+1 MOVLW 079h MOVWF X+2 MOVLW 087h MOVWF X+3 MOVLW 028h MOVWF Y MOVLW 00Bh MOVWF Y+1 CALL DIVIDE GOTO $ ;========================================================================= ;DIVIDES A 32 BIT NUMBER IN X,X+1,X+2,X+3 BY THE 16 NUMBER IN Y,Y+1 ;GIVING THE ANSWER IN X,X+1,X+2,X+3 ;AND THE REMAINDER IN B,B+1,B+2,B+3. DIVIDE: MOVLW 32 ;REPEAT FOR 32 BITS MOVWF C1 CLRF B CLRF B+1 CLRF B+2 CLRF B+3 BIT_LOOP: BCF STATUS,C ;DEFAULT TO A ZERO BEING SHIFTED IN SHIFT_LEFT X,F ;SHIFT MSBIT OUT OF X SHIFT_LEFT B,F ;SHIFT CARRY INTO B SUB16_32 ;SUB Y FROM B BTFSC STATUS,C ;WAS Y >= B OR NOT? GOTO GOES_IN ;Y >= B DECFSZ C1,F ;NEXT BIT GOTO BIT_LOOP ;DO IT AGAIN GOTO END_DIV GOES_IN: BSF X,0 ;SET BIT 0 IF X. THE DEFAULT 0 THAT ;WAS SHIFTED IN, SHOULD HAVE BEEN ;A 1. MOVF T,W ;WORK FURTHER WITH THE REMAINDER MOVWF B MOVF T+1,W MOVWF B+1 MOVF T+2,W MOVWF B+2 MOVF T+3,W MOVWF B+3 DECFSZ C1,F ;NEXT BIT GOTO BIT_LOOP END_DIV: RETLW 0 END