Divide 48 bit int by 23 bit int to 48 bit int
by Nikolai Golovchenko
Dividend DS 6
Divisor DS 3
Temp DS 3
BitCount DS 1
;**********************************************************************
;
;48 BY 23 BIT UNSIGNED DIVISION (Non-restoring method)
;
;**********************************************************************
;
; Input: Dividend, 6 bytes (Dividend+0 MSB, ... , Dividend+5 LSB)
; Divisor, 3 bytes (Divisor+0 MSB, ... , Divisor+2 LSB)
;
; Output: Dividend, 6 bytes (Dividend = Dividend / Divisor)
; Z - division by zero
; NZ - okay
;
; Temporary: Temp, 3 bytes - remainder
; BitCount, 1 byte - counter
;
; Size: 52 instructions
;
;Max timing: 3+5+6+28*48-2+7+3=1366 cycles
;
;**********************************************************************
DIVIDE_48by23
; Test for zero division
mov W, Divisor
or W, Divisor+1
or W, Divisor+2
snz
ret ; divisor = zero, not possible to calculate -
; return with set zero flag (Z)
; clear remainder
clr Temp
clr Temp+1
clr Temp+2
mov W, #48 ; initialize bit counter
mov BitCount, W
stc ; set carry to perform subtraction
; first in the following loop
DIVIDE_LOOP_48by23
; shift in next result bit and
; shift out next bit of dividend
rl Dividend+5
rl Dividend+4
rl Dividend+3
rl Dividend+2
rl Dividend+1
rl Dividend
; shift in highest bit from dividend through carry in temp
rl Temp+2
rl Temp+1
rl Temp
mov W, Divisor+2 ; load w with LSB of divisor
; to use it in subtraction or
; addition afterwards
; If previous result bit was set (subtraction was performed
; without borrow or addition made the remainder positive),
; subtract divisor from remainder,
; else add divisor to remainder
sb Dividend+5.0
jmp Div48by23_add
; subtract 23 bit divisor from 24 bit temp,
; divisor LSB is in w
sub Temp+2, W ; subtract LSB
mov W, Divisor+1 ; get middle byte
sc ; if overflow ( from prev. subtraction )
movsz W, ++Divisor+1 ; incresase source
sub Temp+1, W ; and subtract from dest.
mov W, Divisor ; get top byte
sc ; if overflow ( from prev. subtraction )
movsz W, ++Divisor ; increase source
sub Temp, W ; and subtract from dest.
jmp DIVIDE_NEXT_48by23 ; jump to loop end
Div48by23_add
; add 23 bit divisor to 24 bit temp
; divisor LSB is in w
add Temp+2, W ; add LSB
mov W, Divisor+1 ; middle byte
snc ; check carry for overflow from previous addition
movsz W, ++Divisor+1 ; if carry set we add 1 to the source
add Temp+1, W ; and add it if not zero
mov W, Divisor ; MSB byte
snc ; check carry for overflow from previous addition
movsz W, ++Divisor
add Temp, W ; add
DIVIDE_NEXT_48by23
; carry contains next result bit
decsz BitCount ; decrement loop counter (carry not influenced)
jmp DIVIDE_LOOP_48by23 ; another run
; finally shift in the last carry
rl Dividend+5
rl Dividend+4
rl Dividend+3
rl Dividend+2
rl Dividend+1
rl Dividend
clz ; done, clear zero flag (NZ) and
ret ; return
;**********************************************************************
file: /Techref/scenix/lib/math/div/48by23ng_sx.htm, 3KB, , updated: 2004/6/10 13:40, local time: 2024/12/25 23:47,
owner: NG--944,
|
| ©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? <A HREF="http://linistepper.com/techref/scenix/lib/math/div/48by23ng_sx.htm"> SX Microcontroller Math Method - Divide 48 bit int by 23 bit int to 48 bit int</A> |
Did you find what you needed?
|