Full Version : Zher's 16-by-8 Divide Routine (PIC ASM)
avr >>PIC 8051 ZILOG ARM TI H8 ETC >>Zher's 16-by-8 Divide Routine (PIC ASM)


Admin3- 04-18-2006
Divide 16 bit int by 8 bit int to 8 bit int and remainder


CODE
#define bf_carry 3, 0
#define bf_zero 3, 2

#define same 1
#define wreg 0

#define stc bsf bf_carry
#define clc bcf bf_carry

;-[ Div ]--------------------------------------------------------------
; Call w/: Number in f_divhi:f_divlo, divisor in W.
; Returns: Quotient in f_divlo, remainder in f_divhi. W preserved.
;          Carry set if error. Z if divide by zero, NZ if divide overflow.
; Notes:   Works by left shifted subtraction.
;          Size = 29, Speed(w/ call&ret) = 7 cycles if div by zero
;          Speed = 94 minimum, 129 maximum cycles

Div;
   addlw 0         ; w+=0 (to test for div by zero)
   stc             ; set carry in case of error
   btfsc bf_zero   ; if zero
    return         ;   return (error C,Z)

   call DivSkipHiShift
iDivRepeat = 8
while iDivRepeat

   call DivCode

iDivRepeat--
endw

   rlf f_divlo, same; C << lo << C

  ; If the first subtract didn't underflow, and the carry was shifted
  ; into the quotient, then it will be shifted back off the end by this
  ; last RLF. This will automatically raise carry to indicate an error.
  ; The divide will be accurate to quotients of 9-bits, but past that
  ; the quotient and remainder will be bogus and carry will be set.

   bcf bf_zero ; NZ (in case of overflow error)
   return      ; we are done!

DivCode
   rlf f_divlo, same   ; C << lo << C
   rlf f_divhi, same   ; C << hi << C
   btfss bf_carry      ; if Carry
    goto DivSkipHiShift;
   subwf f_divhi, same ;   hi-=w
   stc                 ;   ignore carry
   return              ;   done
                       ; endif
DivSkipHiShift
   subwf f_divhi, same ; hi-=w
   btfsc bf_carry      ; if carry set
    return             ;   done
   addwf f_divhi, same ; hi+=w
   clc                 ; clear carry
   return              ; done


QUOTE
pic@canadaspeaks.com asks: " what language is this? it looks like mostly asm, but x = y and while loops are not assembly instructions."

QUOTE

James Newton replies: That is pseudo code that should be translated into the equvilent ASM code before the code is used. Please consider posting a complete version if you get the code to work.



Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.