## Let x1 = y / z (division) Let x2 = y // z (division, remainder)

divides one 16-bit value into another 16-bit value to compute a 16-bit result and remainder.

PBASIC allows you to divide any two variables--bits, bytes, words, or a mixture--to get a 16-bit result or remainder.

This routine duplicates that capability in assembly language. It uses a binary interpretation of the long-division method you were probably taught in school. It shifts the divisor left until there is a 1 in the msb. It then attempts to subtract this number from the dividend.

If the result of the subtraction is positive, the routine puts a 1 into the lsb of the quotient, shifts the quotient left, shifts the divisor right, and repeats the operation on what remains of the dividend. If the result of the subtraction is negative, the routine undoes the subtraction by adding the divisor and dividend back together, puts a 0 into the lsb of the quotient, shifts the quotient left, shifts the divisor right, and repeats the operation.

It may require a walk through the routine with paper and pencil (or the simulator) to grasp how this works. When the routine finishes, the 16-bit variable consisting of qH and qL holds the quotient or result of the division. The variable consisting of topH and topL holds the remainder.

Division by 0 is illegal, so the routine starts by checking for this. If division by 0 is attempted, the routine aborts and returns the error code 0FFh (255) in the w register. Otherwise, it returns with 0 in w. Your program should either prevent division by 0 or be prepared to act on the error code.

#### Demonstrating Divide.

To see Divide in operation, either run the program with the PSIM simulator, or connect the circuit below to an erasable PIC or PIC emulator, such as the Parallax downloader. Assemble and run DIVIDE.SRC. When you apply power to the PIC, the LEDs will light up in the binary pattern of the answer to the math problem 330Ah/00A3h, which is 50h with a remainder of 1Ah. So the quotient (50h) displays the following binary pattern on the LEDs:

```0000 0000 0101 0000
```

Try dividing various values to see different results. Also, modify the program to display remainders (stored in the variables topH and topL) on the LEDs.

```;
; ***************************************************************************
; ***  Bubble Software Parallax to PIC Source Converter. Copyright 1999.  ***
; ***  http://www.bubblesoftonline.com                 email: sales@picnpoke.com  ***
; ***************************************************************************
;
; DIVIDE
; Divide one 16-bit number into another, returning the 16-bit result and
; the remainder. Upon entry, the top of the division fraction (the dividend)
; must be in topH and topL, and the bottom (divisor) in btmH and btmL.
; If division by zero is attempted, the routine will return immediately with
; the error code of 0FFh in w. Otherwise, it will perform the division, leaving
; the remainder in topH and topL and the result (quotient) in qH and qL.
; Upon return from a successful division, w contains 0.

; Device data and reset vector
P = pic16c55
#include <16c55.inc>   ; processor assembler definitions
_CONFIG _xt_osc & _wdt_off & _protect_off
reset   start

org     8
topH    Res      d'1'       ; MSB of top of fraction.
topL    Res      d'1'       ; LSB of top of fraction.
btmH    Res      d'1'       ; MSB of bottom of fraction.
btmL    Res      d'1'       ; LSB of bottom of fraction.
qH      Res      d'1'       ; MSB of quotient.
qL      Res      d'1'       ; LSB of quotient.
count   Res      d'1'       ; temporary counter
index   Res      d'1'       ; temporary counter

org     0
start        MOVLW d'0'                 ; Set to outputs to display
TRIS 6h
MOVLW d'0'                 ; results on LEDs.
TRIS 7h
MOVLW 0x33                 ; Problem: divide
MOVWF topH
MOVLW 0x0A                 ; 330Ah by 00A3h.
MOVWF topL
MOVLW 0x00
MOVWF btmH
MOVLW 0x00A3
MOVWF btmL
CALL divide
MOVF qL,w                  ; Display quotient in binary
MOVWF 6h
MOVF qH,w                  ; on LEDs connected to rb and rc.
MOVWF 7h
GOTO \$                     ; Endless loop

Divide       MOVF btmH,w                ; Check for division by 0.
IORWF btmL,w
BTFSC status,z
RETLW d'255'               ; Error code= 255: return.
MOVLW d'1'                 ; Otherwise, initialize variables
MOVWF count
CLRF index                 ; for the division.
CLRF qH
CLRF qL

Divide_sh_loop  BTFSC btmH,d'7'         ; Shift divisor left
GOTO Divide_d1
BCF status,c               ; until msb is in
RLF btmL                   ; btmH.7.
RLF btmH                   ; count = no. of shifts+1.
INCF count
GOTO Divide_sh_loop
Divide_d1    BCF status,c
RLF qL                     ; Shift quotient left.
RLF qH
MOVF btmL,w                ; top = top - btm.
SUBWF topL
BTFSC status,c             ; If top - btm < 0 then
GOTO Divide_d2
MOVLW d'1'                 ; top = top + btm
SUBWF topH
BTFSC status,c             ; The idea is to do the
GOTO Divide_d2
INCF topH                  ; the subtraction and comparison
MOVF btmL,w                ; (top > btm?) in one step.
goto Divide_reentr		; Then, if btm > top, undo <Microchip instruction>
Divide_d2    MOVF btmH,w                ; the subtraction by adding
SUBWF topH
BTFSS status,c             ; top and btm back together
goto Divide_less      	; <Microchip instruction>
BSF qL,d'0'
Divide_reentr
BCF status,c
RRF btmH
RRF btmL
DECFSZ count
GOTO Divide_d1
RETLW 0h                   ; Return w/ remainder in top
; and result in q.
Divide_less  MOVF btmL,w                ; btm > top, so
BTFSC status,c             ; undo the subtraction by
INCF topH                  ; adding them back together.
MOVF btmH,w
goto    Divide_reentr    	; <Microchip instruction>

end

```

```; DIVIDE
; Divide one 16-bit number into another, returning the 16-bit result and
; the remainder. Upon entry, the top of the division fraction (the dividend)
; must be in topH and topL, and the bottom (divisor) in btmH and btmL.
; If division by zero is attempted, the routine will return immediately with
; the error code of 0FFh in w. Otherwise, it will perform the division, leaving
; the remainder in topH and topL and the result (quotient) in qH and qL.
; Upon return from a successful division, w contains 0.

org     8
topH    ds      1       ; MSB of top of fraction.
topL    ds      1       ; LSB of top of fraction.
btmH    ds      1       ; MSB of bottom of fraction.
btmL    ds      1       ; LSB of bottom of fraction.
qH      ds      1       ; MSB of quotient.
qL      ds      1       ; LSB of quotient.
count   ds      1       ; temporary counter
index   ds      1       ; temporary counter

; Device data and reset vector
device  pic16c55,xt_osc,wdt_off,protect_off
reset   start
org     0
start   mov     !rb,#0  ; Set to outputs to display
mov     !rc,#0  ; results on LEDs.
mov     topH,#33h       ; Problem: divide
mov     topL,#0Ah       ; 330Ah by 00A3h.
mov     btmH,#0h
mov     btmL,#0A3h
call    divide
mov     rb,qL   ; Display quotient in binary
mov     rc,qH   ; on LEDs connected to rb and rc.
jmp     \$       ; Endless loop

Divide  mov     w,btmH  ; Check for division by 0.
OR      w,btmL
snz
retw    255     ; Error code= 255: return.
mov     count,#1        ; Otherwise, initialize variables
clr     index   ; for the division.
clr     qH
clr     qL

:sh_loop        jb      btmH.7,:d1      ; Shift divisor left
clc             ; until msb is in
rl      btmL    ; btmH.7.
rl      btmH    ; count = no. of shifts+1.
inc     count
jmp     :sh_loop
:d1     clc
rl      qL      ; Shift quotient left.
rl      qH
sub     topL,btmL       ; top = top - btm.
jc      :d2     ; If top - btm < 0 then
sub     topH,#1 ; top = top + btm
jc      :d2     ; The idea is to do the
inc     topH    ; the subtraction and comparison
add     topL,btmL       ; (top > btm?) in one step.
goto    :reentr ; Then, if btm > top, undo
:d2     sub     topH,btmH       ; the subtraction by adding
sc              ; top and btm back together
goto    :less
setb    qL.0
:reentr clc
rr      btmH
rr      btmL
djnz    count,:d1
ret             ; Return w/ remainder in top
; and result in q.
:less   ADD     topL,btmL       ; btm > top, so
snc             ; undo the subtraction by
inc     topH    ; adding them back together.
goto    :reentr
```

 file: /Techref/microchip/seepicsrc/psbpix/division.htm, 14KB, , updated: 2001/5/25 14:48, local time: 2024/8/14 19:35, TOP NEW HELP FIND:  3.236.247.200:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?Please DO link to this page! Digg it! / MAKE! microchip seepicsrc psbpix division

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.

Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
 Did you find what you needed? "No. I'm looking for: " "No. Take me to the search page." "No. Take me to the top so I can drill down by catagory" "No. I'm willing to pay for help, please refer me to a qualified consultant"

### Welcome to sxlist.com!

Site supported by
& kind contributors
just like you!

(here's why

Copies of the site on CD
are available at minimal cost.

.