; void _DivUnsArrByUnsArr(c, a, m, b, n, rf) ; ; ARGUMENT ; unsigned a[], b[], c[]; ; int m, n; ; int rf; ; ; DESCRIPTION ; Divides an m-word integer a by an n-integer word b, storing the result ; in c. a and b must both be positive, and m >= n. The quotient is ; rounded when rf is set, otherwise is it truncated. ; ; SIDE EFFECTS ; None. ; ; RETURNS ; None. ; ; AUTHOR ; Jared Levy 7/9/89 ; Copyright (C) 1989-90 Greenleaf Software Inc. All Rights Reserved. ; ; MODIFICATIONS ; ; ; include model.h include prologue.h include gm.equ dseg dmbyn acopm2 dw 1 dup(?) acop dw 12 dup(?) diga dw 1 dup(?) bcopm2 dw 1 dup(?) bcop dw 6 dup(?) digb dw 1 dup(?) digb2 dw 1 dup(?) digbp1 dw 1 dup(?) numquot dw 1 dup(?) firstb dw 1 dup(?) dstplc dw 1 dup(?) partpr dw 6 dup (?) quotdig dw 1 dup(?) endds pseg dmbyn cproc _DivUnsArrByUnsArr,,_dmbyn ; load parameters if _LDATA push es les si, parm6_ ; get source pointer b mov bx, parm8_ ; get # of digits in b else mov ax, ds mov es, ax mov si, parm4_ ; get source pointer b mov bx, parm5_ ; get # of digits in b endif ; copy b mov digb, bx ; store # digits of b mov digbp1, bx inc digbp1 ; store 1 + # digits of b sal bx, 1 mov digb2, bx ; store twice # digits of b mov word ptr bcop[bx], 0 ; store 0 in extra word loopcb: dec bx ; next word dec bx mov ax, word ptr es:[si+bx] ; copy element of b mov word ptr bcop[bx], ax jnz loopcb if _LDATA les si, parm3_ ; get source pointer a mov bx, parm5_ ; get # of digits in a else mov si, parm2_ ; get source pointer a mov bx, parm3_ ; get # of digits in a endif ; copy a mov diga, bx ; store # digits of a sal bx, 1 xor ax, ax mov acop[bx], ax ; store zero in extra word loopca: dec bx ; next word dec bx mov ax, word ptr es:[si+bx] ; copy element of a mov word ptr acop[bx], ax jnz loopca ; rotate b and a left until high bit of b is set mov bx, digb2 mov ax, bcopm2[bx] ; get high word of b mov firstb, ax rcl ax,1 ; see if high bit set jc noshift xor dx,dx shwb: xor bx,bx ; start shifting at low digit mov cx,digb clc shblp: rcl bcop[bx],1 ; rotate digit left inc bx ; next digit inc bx loop shblp inc dx ; keep track of # of shifts mov ax, bcopm2[bx] ; get high word of b rcl ax,1 ; see if high bit set jnc shwb mov ax, bcopm2[bx] ; get first digit of b mov firstb, ax ; & store shwa: xor bx,bx ; start shifting at low digit mov cx,diga inc cx ; shift extra digit of a clc shalp: rcl acop[bx],1 ; rotate digit left inc bx ; next digit inc bx loop shalp dec dx jnz shwa noshift: ; set up source and destination pointers if _LDATA les di, parm1_ ; get destination pointer c else mov di, parm1_ ; get destination pointer c endif ; zero destination mov bx, 8d xor ax, ax zerocl: mov word ptr es:[di+bx], ax dec bx dec bx jns zerocl mov ax, diga ; find location to store digits sub ax, digb ; highest digit stored in word # diga - digb jns nxtline ; if b has more digits than a, done jmp done nxtline: mov numquot, ax inc numquot ; compute number of quotient digits sal ax, 1 add di, ax ; where highest quotient digit stored mov dstplc, di mov di, ax ; place to begin first subtraction mov ax, diga sal ax, 1 mov si, ax ; place to begin first compare ; if first digit of b is larger than first digit of a, ; first digit of quotient is 0 mov ax, 0 cmp ax, acop[si] jne firstn0 mov ax, firstb ; get high digit of b cmp ax, acopm2[si] ; compare to high digit of a jbe firstn0 ; first quot. digit non-zero dec numquot ; otherwise, one less quotient digit jnz nline2 ; if a a, quotient too big dec bx ; if equal compare next digit dec bx jns cmplp ; if b=a, compare remaining digits jmp short worksout ; if exactly equal quotient right toolarge: ; when quotient too large, decrease quotient & adjust partial product dec quotdig ; lower quotient by 1 mov bx, 0 ; subtract b from partial prod. clc mov cx, digbp1 subtllp: mov ax, bcop[bx] ; get dig of b sbb partpr[bx], ax ; subtract from partial prod. inc bx ; next digit inc bx loop subtllp dec bx ; bx must have right value for cmp dec bx jmp short cmplp worksout: ; store quotient digit mov bx, dstplc mov ax, quotdig mov es:[bx], ax ; subtract number mov cx, digbp1 ; set counter for number of subtractions xor bx, bx clc sloop: mov ax, partpr[bx] ; subtract a digit at a time sbb acop[di+bx], ax inc bx inc bx loop sloop dec numquot jz done jmp wordloop done: ; handle rounding if _LDATA mov ax, parm9_ ; get rounding flag else mov ax, parm6_ ; get rounding flag endif cmp ax, 0 ; check if rounding flag set je noround ; see if r >= b/2 mov cx, digbp1 mov si, 0 clc dloop: rcl word ptr acop[si], 1 ; double remainder inc si inc si loop dloop ; compare 2*r & b mov bx, digb2 comrl: mov ax, acop[bx] cmp ax, bcop[bx] ; compare digit ja round ; a>b/2 jb noround ; a