64-bit division


Results 1 to 16 of 16

Thread: 64-bit division

Threaded View

  1. #8
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Getting your installation right will save you headaches later

    Quote Originally Posted by Manfred View Post
    This whole thing is getting too problematic. I had hoped that someone could propose a simple PBP routine, using the 16-bit math provided in PBP, to do this 64-bit division. I will better continue in that line, rather than setting up a new programming environment, learning to use it, perhaps reformat and repartition my hard disk, to be able to use that assembly library!
    Darrel's N-Bit math is the only simple PBP routine I know of. 64 bits on an 8 bit device is not so simple. Most program examples and includes on this site, all require mpasm, so you will probably eventually want to go there anyway. Why not install PBP as the manual suggests (on page 5) and put PBP in a folder on the C drive. Make your life easier, not harder.

    If you want a routine, you can follow the links on Darrel's http://www.picbasic.co.uk/forum/cont...153-N-Bit_MATH and retrieve assembly code to your liking. http://avtanski.net/projects/math/

    Here is the bare assembly 64 bit division:
    Code:
    #include 
              ; remove this if not necessary
    
    #define PRECISION 64             ; byte size for registers
    
    M_STOR_STATUS macro WHERE
        movf    STATUS,w
        movwf   WHERE
        endm
    
    M_RETR_STATUS macro WHERE
        movf    WHERE,w
        movwf   STATUS
        endm
    
        cblock 0x20
        REG_X:PRECISION
        REG_Y:PRECISION
        REG_Z:PRECISION
        REG_COUNTER
        REG_STATUS
        REG_T1
        REG_T2
        REG_ROT_COUNTER
        endc
    
    
        org 0x00
        goto    M_TEST
        org 0x04
        goto    M_TEST
    
    
        org 0x0c
    M_TEST                          ; Test subroutine
        movlw   REG_X
        call    M_CLR               ; clear register X
    
        movlw   REG_Y
        call    M_CLR               ; clear register Y
    
        movlw   REG_Z
        call    M_CLR               ; clear register Z
    
        movlw   0x8A
        movwf   REG_X               ; set register X (lowest byte)
    
        movlw   0xFC
        movwf   REG_Z               ; set register Z (lowest byte)
    
        call    M_ADD               ; adds X and Z, result in Z
    
        movlw   0x05                ; set regiester X (lowest byte)
        movwf   REG_X
    
        call    M_DIV               ; divide Z by X, result in Y, remainder in Z
        sleep                       ; end of test
    
    
    M_CLR                           ; clear a register
        movwf   FSR
        movlw   PRECISION
        movwf   REG_COUNTER
    M_CLR_loop
        clrf    INDF
        incf    FSR,f
        decf    REG_COUNTER,f
        btfss   STATUS,Z
        goto    M_CLR_loop
        return
    
    M_INC                           ; increment a register
        movwf   FSR
        movlw   PRECISION
        movwf   REG_COUNTER
    M_INC_loop
        incf    INDF,f
        btfss   STATUS,Z
        return
        incf    FSR,f
        decf    REG_COUNTER,f
        btfss   STATUS,Z
        goto    M_INC_loop
        return
    
    
    M_DEC                           ; decrement a register
        movwf   FSR
        movlw   PRECISION
        movwf   REG_COUNTER
    M_DEC_loop
        decf    INDF,f
        movlw   0xFF
        subwf   INDF,w
        btfss   STATUS,Z
        return
        incf    FSR,f
        decf    REG_COUNTER,f
        btfss   STATUS,Z
        goto    M_DEC_loop
        return
    
    
    M_ROL                           ; rotate a register to the left
        movwf   FSR
        M_STOR_STATUS REG_STATUS
        clrf    REG_COUNTER
    M_ROL_loop
        M_RETR_STATUS REG_STATUS
        rlf     INDF,f
        M_STOR_STATUS REG_STATUS
        incf    FSR,f
        incf    REG_COUNTER,f
        movlw   PRECISION
        subwf   REG_COUNTER,w
        btfss   STATUS,Z
        goto    M_ROL_loop
        return
    
    
    M_ROR                           ; rotates a register to the right
        movwf   FSR
        movlw   PRECISION-1
        addwf   FSR,f
        M_STOR_STATUS REG_STATUS
        clrf    REG_COUNTER
    M_ROR_loop
        M_RETR_STATUS REG_STATUS
        rrf     INDF,f
        M_STOR_STATUS REG_STATUS
        decf    FSR,f
        incf    REG_COUNTER,f
        movlw   PRECISION
        subwf   REG_COUNTER,w
        btfss   STATUS,Z
        goto    M_ROR_loop
        return
    
    
    M_CMP                           ; Z <=> X -> STATUS(C,Z)
                                    ; STATUS,C set if Z => X;
                                    ; STATUS,Z set if Z == X
        clrf    REG_COUNTER
    M_CMP_loop
        movf    REG_COUNTER,w
        sublw   REG_Z+PRECISION-1
        movwf   FSR
        movf    INDF,w
        movwf   REG_T1
        movf    REG_COUNTER,w
        sublw   REG_X+PRECISION-1
        movwf   FSR
        movf    INDF,w
        subwf   REG_T1,f
        btfss   STATUS,Z
        return
        incf    REG_COUNTER,f
        movlw   PRECISION
        subwf   REG_COUNTER,w
        btfss   STATUS,Z
        goto    M_CMP_loop
        return
    
    
    M_ADD                           ; Z + X -> Z
        bcf     STATUS,C
        clrf    REG_STATUS
        clrf    REG_COUNTER
    M_ADD_loop
        clrf    REG_T1
        btfsc   REG_STATUS,C
        incf    REG_T1,f
        clrf    REG_STATUS
        movlw   REG_X
        addwf   REG_COUNTER,w
        movwf   FSR
        movf    INDF,w
        addwf   REG_T1,f
        btfsc   STATUS,C
        bsf     REG_STATUS,C
        movlw   REG_Z
        addwf   REG_COUNTER,w
        movwf   FSR
        movf    INDF,w
        addwf   REG_T1,f
        btfsc   STATUS,C
        bsf     REG_STATUS,C
        movf    REG_T1,w
        movwf   INDF
        incf    REG_COUNTER,f
        movlw   PRECISION
        subwf   REG_COUNTER,w
        btfss   STATUS,Z
        goto    M_ADD_loop
        return
    
    
    M_SUB                           ; Z - X -> Z
        clrf    REG_COUNTER
        bsf     REG_STATUS,C
    M_SUB_loop
        bsf     REG_T2,C
        movlw   REG_Z
        addwf   REG_COUNTER,w
        movwf   FSR
        movf    INDF,w
        movwf   REG_T1
        movlw   REG_X
        addwf   REG_COUNTER,w
        movwf   FSR
        movf    INDF,w
        subwf   REG_T1,f
        btfss   STATUS,C
        bcf     REG_T2,C
        btfsc   REG_STATUS,C
        goto    M_SUB_no_carry
        movlw   0x01
        subwf   REG_T1,f
        btfss   STATUS,C
        bcf     REG_T2,C
    M_SUB_no_carry
        movlw   REG_Z
        addwf   REG_COUNTER,w
        movwf   FSR
        movf    REG_T1,w
        movwf   INDF
        bsf     REG_STATUS,C
        btfss   REG_T2,C
        bcf     REG_STATUS,C
        incf    REG_COUNTER,f
        movlw   PRECISION
        subwf   REG_COUNTER,w
        btfss   STATUS,Z
        goto    M_SUB_loop
        btfss   REG_STATUS,C
        bcf     STATUS,C
        return
    
    
    M_MUL                           ; X * Y -> Z
        movlw   REG_Z
        call    M_CLR
        movlw   PRECISION*8+1
        movwf   REG_ROT_COUNTER
    M_MUL_loop
        decf    REG_ROT_COUNTER,f
        btfsc   STATUS,Z
        return
        btfsc   REG_Y,0
        call    M_ADD
        bcf     STATUS,C
        movlw   REG_Y
        call    M_ROR
        bcf     STATUS,C
        movlw   REG_X
        call    M_ROL
        goto    M_MUL_loop
    
    
    M_DIV                           ; Z / X -> Y;  remainder -> Z
        movlw   REG_Y
        call    M_CLR
        movlw   PRECISION*8
        movwf   REG_ROT_COUNTER
    M_DIV_rot_loop
        btfsc   REG_X+PRECISION-1,7
        goto    M_DIV_loop
        movlw   REG_X
        bcf     STATUS,C
        call    M_ROL
        decf    REG_ROT_COUNTER,f
        btfss   STATUS,Z
        goto    M_DIV_rot_loop
        bsf     STATUS,Z
        return
    M_DIV_loop
        call    M_CMP
        M_STOR_STATUS REG_T2
        movlw   REG_Y
        call    M_ROL
        M_RETR_STATUS REG_T2
        btfsc   STATUS,C
        call    M_SUB
        bcf     STATUS,Z
        bcf     STATUS,C
        movlw   REG_X
        call    M_ROR
        incf    REG_ROT_COUNTER,f
        movlw   PRECISION*8+1
        subwf   REG_ROT_COUNTER,w
        btfss   STATUS,Z
        goto    M_DIV_loop
        return    
    
        END
    But I still think installing PBP right, and using Mpasm with Darrels N Bit Math is the way to go. Especially if you want easy. Once you get your program set up right, you will be able to easily add different include files.
    Last edited by ScaleRobotics; - 5th August 2010 at 17:29.
    http://www.scalerobotics.com

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts